The tasks page now shows the assignee
This commit is contained in:
parent
a456fbbdbc
commit
4cf4228eed
226
src/modules/manager/tasks/components/AssigneePanel.tsx
Normal file
226
src/modules/manager/tasks/components/AssigneePanel.tsx
Normal file
@ -0,0 +1,226 @@
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { GeneralIdRef } from "../../../../utils/GeneralIdRef";
|
||||
import { Namespaces } from "../../../../i18n/i18n";
|
||||
import roleService from "../../domains/serrvices/rolesService";
|
||||
import userService from "../../users/services/usersService";
|
||||
|
||||
export interface AssigneePanelProps {
|
||||
user?: GeneralIdRef;
|
||||
role?: GeneralIdRef;
|
||||
}
|
||||
|
||||
const roleNameCache = new Map<string, string | null>();
|
||||
const roleLookupInFlight = new Map<string, Promise<string | null>>();
|
||||
const userNameCache = new Map<string, string | null>();
|
||||
const userLookupInFlight = new Map<string, Promise<string | null>>();
|
||||
|
||||
function getRoleCacheKey(role?: GeneralIdRef): string | null {
|
||||
if (!role) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (role.guid) {
|
||||
return `guid:${role.guid}`;
|
||||
}
|
||||
|
||||
if (role.id !== undefined) {
|
||||
return `id:${role.id.toString()}`;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function getUserCacheKey(user?: GeneralIdRef): string | null {
|
||||
if (!user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (user.guid) {
|
||||
return `guid:${user.guid}`;
|
||||
}
|
||||
|
||||
if (user.id !== undefined) {
|
||||
return `id:${user.id.toString()}`;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
async function getCachedRoleName(role: GeneralIdRef): Promise<string | null> {
|
||||
const key = getRoleCacheKey(role);
|
||||
|
||||
if (!key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (roleNameCache.has(key)) {
|
||||
return roleNameCache.get(key) ?? null;
|
||||
}
|
||||
|
||||
const inFlight = roleLookupInFlight.get(key);
|
||||
if (inFlight) {
|
||||
return inFlight;
|
||||
}
|
||||
|
||||
const request = roleService
|
||||
.getRole(role.id, role.guid)
|
||||
.then((roleDetails) => {
|
||||
const name = roleDetails?.name ?? null;
|
||||
roleNameCache.set(key, name);
|
||||
return name;
|
||||
})
|
||||
.catch(() => {
|
||||
roleNameCache.set(key, null);
|
||||
return null;
|
||||
})
|
||||
.finally(() => {
|
||||
roleLookupInFlight.delete(key);
|
||||
});
|
||||
|
||||
roleLookupInFlight.set(key, request);
|
||||
return request;
|
||||
}
|
||||
|
||||
async function getCachedUserName(user: GeneralIdRef): Promise<string | null> {
|
||||
const key = getUserCacheKey(user);
|
||||
|
||||
if (!key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (userNameCache.has(key)) {
|
||||
return userNameCache.get(key) ?? null;
|
||||
}
|
||||
|
||||
const inFlight = userLookupInFlight.get(key);
|
||||
if (inFlight) {
|
||||
return inFlight;
|
||||
}
|
||||
|
||||
const request = userService
|
||||
.getUser(user.id, user.guid)
|
||||
.then((userDetails) => {
|
||||
const name = userDetails?.displayName ?? null;
|
||||
userNameCache.set(key, name);
|
||||
return name;
|
||||
})
|
||||
.catch(() => {
|
||||
userNameCache.set(key, null);
|
||||
return null;
|
||||
})
|
||||
.finally(() => {
|
||||
userLookupInFlight.delete(key);
|
||||
});
|
||||
|
||||
userLookupInFlight.set(key, request);
|
||||
return request;
|
||||
}
|
||||
|
||||
const AssigneePanel: React.FC<AssigneePanelProps> = ({ user, role }) => {
|
||||
const { t } = useTranslation(Namespaces.Common);
|
||||
const [resolvedUserName, setResolvedUserName] = React.useState<string | null>(
|
||||
null,
|
||||
);
|
||||
const [isUserLoading, setIsUserLoading] = React.useState(false);
|
||||
const [resolvedRoleName, setResolvedRoleName] = React.useState<string | null>(
|
||||
null,
|
||||
);
|
||||
const [isRoleLoading, setIsRoleLoading] = React.useState(false);
|
||||
|
||||
React.useEffect(() => {
|
||||
let isActive = true;
|
||||
|
||||
if (!user) {
|
||||
setResolvedUserName(null);
|
||||
setIsUserLoading(false);
|
||||
return () => {
|
||||
isActive = false;
|
||||
};
|
||||
}
|
||||
|
||||
setIsUserLoading(true);
|
||||
|
||||
getCachedUserName(user)
|
||||
.then((name) => {
|
||||
if (!isActive) {
|
||||
return;
|
||||
}
|
||||
setResolvedUserName(name);
|
||||
})
|
||||
.finally(() => {
|
||||
if (!isActive) {
|
||||
return;
|
||||
}
|
||||
setIsUserLoading(false);
|
||||
});
|
||||
|
||||
return () => {
|
||||
isActive = false;
|
||||
};
|
||||
}, [user?.id, user?.guid]);
|
||||
|
||||
React.useEffect(() => {
|
||||
let isActive = true;
|
||||
|
||||
if (!role) {
|
||||
setResolvedRoleName(null);
|
||||
setIsRoleLoading(false);
|
||||
return () => {
|
||||
isActive = false;
|
||||
};
|
||||
}
|
||||
|
||||
setIsRoleLoading(true);
|
||||
|
||||
getCachedRoleName(role)
|
||||
.then((name) => {
|
||||
if (!isActive) {
|
||||
return;
|
||||
}
|
||||
setResolvedRoleName(name);
|
||||
})
|
||||
.finally(() => {
|
||||
if (!isActive) {
|
||||
return;
|
||||
}
|
||||
setIsRoleLoading(false);
|
||||
});
|
||||
|
||||
return () => {
|
||||
isActive = false;
|
||||
};
|
||||
}, [role?.id, role?.guid]);
|
||||
|
||||
if (user) {
|
||||
if (isUserLoading) {
|
||||
return <span>{t("Loading")}...</span>;
|
||||
}
|
||||
|
||||
if (resolvedUserName) {
|
||||
return <span>{resolvedUserName}</span>;
|
||||
}
|
||||
|
||||
const userFallback = user.guid ?? user.id?.toString();
|
||||
|
||||
return <span>{userFallback}</span>;
|
||||
}
|
||||
|
||||
if (role) {
|
||||
if (isRoleLoading) {
|
||||
return <span>{t("Loading")}...</span>;
|
||||
}
|
||||
|
||||
if (resolvedRoleName) {
|
||||
return <span>{resolvedRoleName}</span>;
|
||||
}
|
||||
|
||||
const roleFallback = role.guid ?? role.id?.toString();
|
||||
|
||||
return <span>{roleFallback}</span>;
|
||||
}
|
||||
|
||||
return <span>{t("Unassigned")}</span>;
|
||||
};
|
||||
|
||||
export default AssigneePanel;
|
||||
@ -7,6 +7,7 @@ import Table, {
|
||||
} from "../../../../components/common/Table";
|
||||
import { GetMyAssignments } from "../services/tasksService";
|
||||
import TaskTypeAndNameDisplayPanel from "../../workflowTemplates/components/TaskTypeAndNameDisplayPanel";
|
||||
import AssigneePanel from "./AssigneePanel";
|
||||
|
||||
export interface TasksTableProps extends PublishedTableProps<GetMyAssignments> {}
|
||||
|
||||
@ -38,8 +39,13 @@ const TasksTable: React.FC<TasksTableProps> = ({
|
||||
},
|
||||
order: "asc",
|
||||
},
|
||||
{ key: "user", label: t("User"), order: "asc" },
|
||||
{ key: "role", label: t("Role"), order: "asc" },
|
||||
{
|
||||
key: "user",
|
||||
label: t("Assignee"),
|
||||
order: "asc",
|
||||
searchable: false,
|
||||
content: (item) => <AssigneePanel user={item.user} role={item.role} />,
|
||||
},
|
||||
{ key: "startDateTime", label: t("StartDateTime"), order: "asc" },
|
||||
],
|
||||
[t],
|
||||
|
||||
Loading…
Reference in New Issue
Block a user