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";
|
} from "../../../../components/common/Table";
|
||||||
import { GetMyAssignments } from "../services/tasksService";
|
import { GetMyAssignments } from "../services/tasksService";
|
||||||
import TaskTypeAndNameDisplayPanel from "../../workflowTemplates/components/TaskTypeAndNameDisplayPanel";
|
import TaskTypeAndNameDisplayPanel from "../../workflowTemplates/components/TaskTypeAndNameDisplayPanel";
|
||||||
|
import AssigneePanel from "./AssigneePanel";
|
||||||
|
|
||||||
export interface TasksTableProps extends PublishedTableProps<GetMyAssignments> {}
|
export interface TasksTableProps extends PublishedTableProps<GetMyAssignments> {}
|
||||||
|
|
||||||
@ -38,8 +39,13 @@ const TasksTable: React.FC<TasksTableProps> = ({
|
|||||||
},
|
},
|
||||||
order: "asc",
|
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" },
|
{ key: "startDateTime", label: t("StartDateTime"), order: "asc" },
|
||||||
],
|
],
|
||||||
[t],
|
[t],
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user