forked from github/plane
chore : dropdown loading state added and project card avatar fix (#2643)
* chore: project card avatar rendering fix * chore: state, assignee and label dropdown loading state added
This commit is contained in:
parent
ad558833af
commit
52395d0563
@ -47,11 +47,17 @@ export const IssuePropertyAssignee: React.FC<IIssuePropertyAssignee> = observer(
|
||||
|
||||
const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(null);
|
||||
const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);
|
||||
const [isLoading, setIsLoading] = useState<Boolean>(false);
|
||||
|
||||
const projectMembers = projectId ? projectStore?.members?.[projectId] : undefined;
|
||||
|
||||
const fetchProjectMembers = () =>
|
||||
workspaceSlug && projectId && projectStore.fetchProjectMembers(workspaceSlug, projectId);
|
||||
const fetchProjectMembers = () => {
|
||||
setIsLoading(true);
|
||||
if (workspaceSlug && projectId)
|
||||
workspaceSlug &&
|
||||
projectId &&
|
||||
projectStore.fetchProjectMembers(workspaceSlug, projectId).then(() => setIsLoading(false));
|
||||
};
|
||||
|
||||
const options = (projectMembers ?? [])?.map((member) => ({
|
||||
value: member.member.id,
|
||||
@ -128,7 +134,7 @@ export const IssuePropertyAssignee: React.FC<IIssuePropertyAssignee> = observer(
|
||||
className={`flex items-center justify-between gap-1 w-full text-xs ${
|
||||
disabled ? "cursor-not-allowed text-custom-text-200" : "cursor-pointer hover:bg-custom-background-80"
|
||||
} ${buttonClassName}`}
|
||||
onClick={() => fetchProjectMembers()}
|
||||
onClick={() => !projectMembers && fetchProjectMembers()}
|
||||
>
|
||||
{label}
|
||||
{!hideDropdownArrow && !disabled && <ChevronDown className="h-3 w-3" aria-hidden="true" />}
|
||||
@ -152,8 +158,9 @@ export const IssuePropertyAssignee: React.FC<IIssuePropertyAssignee> = observer(
|
||||
/>
|
||||
</div>
|
||||
<div className={`mt-2 space-y-1 max-h-48 overflow-y-scroll`}>
|
||||
{filteredOptions ? (
|
||||
filteredOptions.length > 0 ? (
|
||||
{isLoading ? (
|
||||
<p className="text-center text-custom-text-200">Loading...</p>
|
||||
) : filteredOptions.length > 0 ? (
|
||||
filteredOptions.map((option) => (
|
||||
<Combobox.Option
|
||||
key={option.value}
|
||||
@ -176,9 +183,6 @@ export const IssuePropertyAssignee: React.FC<IIssuePropertyAssignee> = observer(
|
||||
<span className="flex items-center gap-2 p-1">
|
||||
<p className="text-left text-custom-text-200 ">No matching results</p>
|
||||
</span>
|
||||
)
|
||||
) : (
|
||||
<p className="text-center text-custom-text-200">Loading...</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -51,11 +51,15 @@ export const IssuePropertyLabels: React.FC<IIssuePropertyLabels> = observer((pro
|
||||
|
||||
const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(null);
|
||||
const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);
|
||||
const [isLoading, setIsLoading] = useState<Boolean>(false);
|
||||
|
||||
const projectLabels = projectId && projectStore?.labels?.[projectId];
|
||||
|
||||
const fetchProjectLabels = () =>
|
||||
workspaceSlug && projectId && projectStore.fetchProjectLabels(workspaceSlug, projectId);
|
||||
const fetchProjectLabels = () => {
|
||||
setIsLoading(true);
|
||||
if (workspaceSlug && projectId)
|
||||
projectStore.fetchProjectLabels(workspaceSlug, projectId).then(() => setIsLoading(false));
|
||||
};
|
||||
|
||||
const options = (projectLabels ? projectLabels : []).map((label) => ({
|
||||
value: label.id,
|
||||
@ -161,7 +165,7 @@ export const IssuePropertyLabels: React.FC<IIssuePropertyLabels> = observer((pro
|
||||
? "cursor-pointer"
|
||||
: "cursor-pointer hover:bg-custom-background-80"
|
||||
} ${buttonClassName}`}
|
||||
onClick={() => fetchProjectLabels()}
|
||||
onClick={() => !projectLabels && fetchProjectLabels()}
|
||||
>
|
||||
{label}
|
||||
{!hideDropdownArrow && !disabled && <ChevronDown className="h-3 w-3" aria-hidden="true" />}
|
||||
@ -186,8 +190,9 @@ export const IssuePropertyLabels: React.FC<IIssuePropertyLabels> = observer((pro
|
||||
/>
|
||||
</div>
|
||||
<div className={`mt-2 space-y-1 max-h-48 overflow-y-scroll`}>
|
||||
{filteredOptions ? (
|
||||
filteredOptions.length > 0 ? (
|
||||
{isLoading ? (
|
||||
<p className="text-center text-custom-text-200">Loading...</p>
|
||||
) : filteredOptions.length > 0 ? (
|
||||
filteredOptions.map((option) => (
|
||||
<Combobox.Option
|
||||
key={option.value}
|
||||
@ -210,9 +215,6 @@ export const IssuePropertyLabels: React.FC<IIssuePropertyLabels> = observer((pro
|
||||
<span className="flex items-center gap-2 p-1">
|
||||
<p className="text-left text-custom-text-200 ">No matching results</p>
|
||||
</span>
|
||||
)
|
||||
) : (
|
||||
<p className="text-center text-custom-text-200">Loading...</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -47,14 +47,20 @@ export const IssuePropertyState: React.FC<IIssuePropertyState> = observer((props
|
||||
const [query, setQuery] = useState("");
|
||||
const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(null);
|
||||
const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);
|
||||
const [isLoading, setIsLoading] = useState<Boolean>(false);
|
||||
|
||||
const projectStates: IState[] = [];
|
||||
const projectStatesByGroup = projectId && projectStore?.states?.[projectId];
|
||||
if (projectStatesByGroup)
|
||||
for (const group in projectStatesByGroup) projectStates.push(...projectStatesByGroup[group]);
|
||||
|
||||
const fetchProjectStates = () =>
|
||||
workspaceSlug && projectId && projectStore.fetchProjectStates(workspaceSlug, projectId);
|
||||
const fetchProjectStates = () => {
|
||||
setIsLoading(true);
|
||||
if (workspaceSlug && projectId)
|
||||
workspaceSlug &&
|
||||
projectId &&
|
||||
projectStore.fetchProjectStates(workspaceSlug, projectId).then(() => setIsLoading(false));
|
||||
};
|
||||
|
||||
const dropdownOptions = projectStates?.map((state) => ({
|
||||
value: state.id,
|
||||
@ -113,7 +119,7 @@ export const IssuePropertyState: React.FC<IIssuePropertyState> = observer((props
|
||||
className={`flex items-center justify-between gap-1 w-full text-xs px-2.5 py-1 rounded border-[0.5px] border-custom-border-300 ${
|
||||
disabled ? "cursor-not-allowed text-custom-text-200" : "cursor-pointer hover:bg-custom-background-80"
|
||||
} ${buttonClassName}`}
|
||||
onClick={() => fetchProjectStates()}
|
||||
onClick={() => !projectStatesByGroup && fetchProjectStates()}
|
||||
>
|
||||
{label}
|
||||
{!hideDropdownArrow && !disabled && <ChevronDown className="h-3 w-3" aria-hidden="true" />}
|
||||
@ -137,8 +143,9 @@ export const IssuePropertyState: React.FC<IIssuePropertyState> = observer((props
|
||||
/>
|
||||
</div>
|
||||
<div className={`mt-2 space-y-1 max-h-48 overflow-y-scroll`}>
|
||||
{filteredOptions ? (
|
||||
filteredOptions.length > 0 ? (
|
||||
{isLoading ? (
|
||||
<p className="text-center text-custom-text-200">Loading...</p>
|
||||
) : filteredOptions.length > 0 ? (
|
||||
filteredOptions.map((option) => (
|
||||
<Combobox.Option
|
||||
key={option.value}
|
||||
@ -161,9 +168,6 @@ export const IssuePropertyState: React.FC<IIssuePropertyState> = observer((props
|
||||
<span className="flex items-center gap-2 p-1">
|
||||
<p className="text-left text-custom-text-200 ">No matching results</p>
|
||||
</span>
|
||||
)
|
||||
) : (
|
||||
<p className="text-center text-custom-text-200">Loading...</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -181,7 +181,7 @@ export const ProjectCard: React.FC<ProjectCardProps> = observer((props) => {
|
||||
<div className="flex items-center cursor-pointer gap-2 text-custom-text-200">
|
||||
<AvatarGroup showTooltip={false}>
|
||||
{projectMembersIds.map((memberId) => {
|
||||
const member = project.members?.find((m) => m.id === memberId);
|
||||
const member = project.members?.find((m) => m.member_id === memberId);
|
||||
|
||||
if (!member) return null;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user