The tasks page now display my assignments
This commit is contained in:
parent
4ed3545e42
commit
a456fbbdbc
65
src/modules/manager/tasks/components/tasksTable.tsx
Normal file
65
src/modules/manager/tasks/components/tasksTable.tsx
Normal file
@ -0,0 +1,65 @@
|
||||
import React, { useCallback, useMemo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Namespaces } from "../../../../i18n/i18n";
|
||||
import Column from "../../../../components/common/columns";
|
||||
import Table, {
|
||||
PublishedTableProps,
|
||||
} from "../../../../components/common/Table";
|
||||
import { GetMyAssignments } from "../services/tasksService";
|
||||
import TaskTypeAndNameDisplayPanel from "../../workflowTemplates/components/TaskTypeAndNameDisplayPanel";
|
||||
|
||||
export interface TasksTableProps extends PublishedTableProps<GetMyAssignments> {}
|
||||
|
||||
const TasksTable: React.FC<TasksTableProps> = ({
|
||||
data,
|
||||
sortColumn,
|
||||
onChangePage,
|
||||
onSearch,
|
||||
onDelete,
|
||||
onSort,
|
||||
}) => {
|
||||
const { t } = useTranslation(Namespaces.Common);
|
||||
|
||||
const columns: Column<GetMyAssignments>[] = useMemo(
|
||||
() => [
|
||||
{
|
||||
key: "taskName",
|
||||
label: t("Name"),
|
||||
content: (item) => {
|
||||
return (
|
||||
<TaskTypeAndNameDisplayPanel
|
||||
taskName={item.taskName}
|
||||
taskType={item.taskType}
|
||||
showValidationErrorIcon={false}
|
||||
allowWordWrap={false}
|
||||
reserveValidationErrorIconSpace={false}
|
||||
/>
|
||||
);
|
||||
},
|
||||
order: "asc",
|
||||
},
|
||||
{ key: "user", label: t("User"), order: "asc" },
|
||||
{ key: "role", label: t("Role"), order: "asc" },
|
||||
{ key: "startDateTime", label: t("StartDateTime"), order: "asc" },
|
||||
],
|
||||
[t],
|
||||
);
|
||||
|
||||
const raiseSort = (sortCol: Column<GetMyAssignments>) => {
|
||||
if (onSort !== undefined) onSort(sortCol);
|
||||
};
|
||||
|
||||
return (
|
||||
<Table
|
||||
data={data}
|
||||
keyName="id"
|
||||
columns={columns}
|
||||
sortColumn={sortColumn}
|
||||
onSort={raiseSort}
|
||||
onChangePage={onChangePage}
|
||||
onSearch={onSearch}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default TasksTable;
|
||||
@ -5,7 +5,16 @@ import MapToJson from "../../../../utils/MapToJson";
|
||||
|
||||
const apiEndpoint = "/Tasks";
|
||||
|
||||
export interface GetMyTasks {}
|
||||
export interface GetMyAssignments {
|
||||
Id: bigint;
|
||||
Guid: string;
|
||||
|
||||
taskType: string;
|
||||
taskName: string;
|
||||
user?: GeneralIdRef;
|
||||
role?: GeneralIdRef;
|
||||
startDateTime?: Date;
|
||||
}
|
||||
|
||||
export async function myTasks(
|
||||
page: number,
|
||||
@ -13,9 +22,9 @@ export async function myTasks(
|
||||
sortKey: string,
|
||||
sortAscending: boolean,
|
||||
filters?: Map<string, string> | undefined,
|
||||
): Promise<Paginated<GetMyTasks>> {
|
||||
): Promise<Paginated<GetMyAssignments>> {
|
||||
const filterString = MapToJson(filters);
|
||||
const response = await httpService.get<Paginated<GetMyTasks>>(
|
||||
const response = await httpService.get<Paginated<GetMyAssignments>>(
|
||||
apiEndpoint + "/myTasks",
|
||||
{
|
||||
params: {
|
||||
|
||||
@ -7,19 +7,20 @@ import Button, { ButtonType } from "../../../components/common/Button";
|
||||
import { toast } from "react-toastify";
|
||||
import Loading from "../../../components/common/Loading";
|
||||
import Permission from "../../../components/common/Permission";
|
||||
import tasksService, { GetMyTasks } from "./services/tasksService";
|
||||
import tasksService, { GetMyAssignments } from "./services/tasksService";
|
||||
import TasksTable from "./components/tasksTable";
|
||||
|
||||
const Tasks: React.FC = () => {
|
||||
const { t } = useTranslation(Namespaces.Common);
|
||||
const [loaded, setLoaded] = useState(false);
|
||||
const [pagedData, setPagedData] = useState<Paginated<GetMyTasks>>({
|
||||
const [pagedData, setPagedData] = useState<Paginated<GetMyAssignments>>({
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
count: 0,
|
||||
totalPages: 1,
|
||||
data: [],
|
||||
});
|
||||
const [sortColumn, setSortColumn] = useState<Column<GetMyTasks>>({
|
||||
const [sortColumn, setSortColumn] = useState<Column<GetMyAssignments>>({
|
||||
key: "displayName",
|
||||
label: t("Name"),
|
||||
order: "asc",
|
||||
@ -47,7 +48,7 @@ const Tasks: React.FC = () => {
|
||||
[filters, sortColumn.key, sortColumn.order],
|
||||
);
|
||||
|
||||
const onSort = async (newSortColumn: Column<GetMyTasks>) => {
|
||||
const onSort = async (newSortColumn: Column<GetMyAssignments>) => {
|
||||
const { page, pageSize } = pagedData;
|
||||
const data = await tasksService.myTasks(
|
||||
page,
|
||||
@ -114,18 +115,14 @@ const Tasks: React.FC = () => {
|
||||
{t("CreateActivity")}
|
||||
</Button>
|
||||
</Permission>
|
||||
<>My Tasks go here</>
|
||||
<Loading loaded={loaded}>
|
||||
My Tasks go here
|
||||
{/* <UsersTable
|
||||
data={pagedData}
|
||||
sortColumn={sortColumn}
|
||||
onChangePage={changePage}
|
||||
onSort={onSort}
|
||||
onSearch={onSearch}
|
||||
onDelete={onDelete}
|
||||
resendConfirmEmail={resentConfirmEmail}
|
||||
/> */}
|
||||
<TasksTable
|
||||
data={pagedData}
|
||||
sortColumn={sortColumn}
|
||||
onChangePage={changePage}
|
||||
onSort={onSort}
|
||||
onSearch={onSearch}
|
||||
/>
|
||||
</Loading>
|
||||
</>
|
||||
);
|
||||
|
||||
@ -1,99 +1,30 @@
|
||||
import { useEffect } from "react";
|
||||
import templateVersionsService, {
|
||||
TaskMetadata,
|
||||
TaskDefinition,
|
||||
} from "../services/WorkflowTemplateService";
|
||||
import React from "react";
|
||||
import FontAwesomeStringIcon from "../../../../components/common/FontAwesomeStringIcon";
|
||||
import ValidationErrorIcon from "../../../../components/validationErrorIcon";
|
||||
import { TaskDefinition } from "../services/WorkflowTemplateService";
|
||||
import TaskTypeAndNameDisplayPanel from "./TaskTypeAndNameDisplayPanel";
|
||||
|
||||
export interface TaskNameDisplayPanel {
|
||||
export interface TaskNameDisplayPanelProps {
|
||||
task: TaskDefinition;
|
||||
showValidationErrorIcon: boolean;
|
||||
allowWordWrap?: boolean;
|
||||
reserveValidationErrorIconSpace?: boolean;
|
||||
}
|
||||
|
||||
const TaskNameDisplayPanel: React.FC<TaskNameDisplayPanel> = ({
|
||||
const TaskNameDisplayPanel: React.FC<TaskNameDisplayPanelProps> = ({
|
||||
task,
|
||||
showValidationErrorIcon = false,
|
||||
allowWordWrap = false,
|
||||
reserveValidationErrorIconSpace = false,
|
||||
}) => {
|
||||
const [tasksMetadata, setTasksMetadata] = React.useState<TaskMetadata[]>([]);
|
||||
const [isNameTruncated, setIsNameTruncated] = React.useState(false);
|
||||
const taskNameRef = React.useRef<HTMLSpanElement | null>(null);
|
||||
const taskName = task.config.name as string;
|
||||
|
||||
useEffect(() => {
|
||||
const fetchTaskMetadata = async () => {
|
||||
const meta = await templateVersionsService.getTaskMetadata("GeneralTask");
|
||||
setTasksMetadata(meta);
|
||||
};
|
||||
|
||||
fetchTaskMetadata();
|
||||
}, []);
|
||||
|
||||
const taskMetadataByType = React.useMemo(() => {
|
||||
const map = new Map<string, TaskMetadata>();
|
||||
tasksMetadata.forEach((meta) => {
|
||||
map.set(meta.taskType, meta);
|
||||
});
|
||||
return map;
|
||||
}, [tasksMetadata]);
|
||||
|
||||
const meta = taskMetadataByType.get(task.type);
|
||||
const panelClassName = allowWordWrap
|
||||
? "task-name-display-panel task-name-display-panel--wrap"
|
||||
: "task-name-display-panel";
|
||||
|
||||
const updateTruncationState = React.useCallback(() => {
|
||||
const el = taskNameRef.current;
|
||||
|
||||
if (!el || allowWordWrap) {
|
||||
setIsNameTruncated(false);
|
||||
return;
|
||||
}
|
||||
|
||||
setIsNameTruncated(el.scrollWidth > el.clientWidth);
|
||||
}, [allowWordWrap]);
|
||||
|
||||
useEffect(() => {
|
||||
updateTruncationState();
|
||||
}, [taskName, allowWordWrap, updateTruncationState]);
|
||||
|
||||
useEffect(() => {
|
||||
const el = taskNameRef.current;
|
||||
if (!el || allowWordWrap || typeof ResizeObserver === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
const observer = new ResizeObserver(() => {
|
||||
updateTruncationState();
|
||||
});
|
||||
|
||||
observer.observe(el);
|
||||
|
||||
return () => {
|
||||
observer.disconnect();
|
||||
};
|
||||
}, [allowWordWrap, updateTruncationState]);
|
||||
|
||||
return (
|
||||
<div className={panelClassName}>
|
||||
<FontAwesomeStringIcon icon={meta?.icon} />
|
||||
<span
|
||||
ref={taskNameRef}
|
||||
className="task-name-display-panel__name"
|
||||
title={isNameTruncated ? taskName : undefined}
|
||||
>
|
||||
{taskName}
|
||||
</span>
|
||||
<ValidationErrorIcon
|
||||
visible={showValidationErrorIcon}
|
||||
reserveSpace={reserveValidationErrorIconSpace}
|
||||
/>
|
||||
</div>
|
||||
<TaskTypeAndNameDisplayPanel
|
||||
taskName={taskName}
|
||||
taskType={task.type}
|
||||
showValidationErrorIcon={showValidationErrorIcon}
|
||||
allowWordWrap={allowWordWrap}
|
||||
reserveValidationErrorIconSpace={reserveValidationErrorIconSpace}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -0,0 +1,101 @@
|
||||
import React, { useEffect } from "react";
|
||||
import templateVersionsService, {
|
||||
TaskMetadata,
|
||||
} from "../services/WorkflowTemplateService";
|
||||
import FontAwesomeStringIcon from "../../../../components/common/FontAwesomeStringIcon";
|
||||
import ValidationErrorIcon from "../../../../components/validationErrorIcon";
|
||||
|
||||
export interface TaskTypeAndNameDisplayPanelProps {
|
||||
taskName: string;
|
||||
taskType: string;
|
||||
showValidationErrorIcon: boolean;
|
||||
allowWordWrap?: boolean;
|
||||
reserveValidationErrorIconSpace?: boolean;
|
||||
}
|
||||
|
||||
const TaskTypeAndNameDisplayPanel: React.FC<
|
||||
TaskTypeAndNameDisplayPanelProps
|
||||
> = ({
|
||||
taskName,
|
||||
taskType,
|
||||
showValidationErrorIcon = false,
|
||||
allowWordWrap = false,
|
||||
reserveValidationErrorIconSpace = false,
|
||||
}) => {
|
||||
const [tasksMetadata, setTasksMetadata] = React.useState<TaskMetadata[]>([]);
|
||||
const [isNameTruncated, setIsNameTruncated] = React.useState(false);
|
||||
const taskNameRef = React.useRef<HTMLSpanElement | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchTaskMetadata = async () => {
|
||||
const meta = await templateVersionsService.getTaskMetadata("GeneralTask");
|
||||
setTasksMetadata(meta);
|
||||
};
|
||||
|
||||
fetchTaskMetadata();
|
||||
}, []);
|
||||
|
||||
const taskMetadataByType = React.useMemo(() => {
|
||||
const map = new Map<string, TaskMetadata>();
|
||||
tasksMetadata.forEach((meta) => {
|
||||
map.set(meta.taskType, meta);
|
||||
});
|
||||
return map;
|
||||
}, [tasksMetadata]);
|
||||
|
||||
const meta = taskMetadataByType.get(taskType);
|
||||
const panelClassName = allowWordWrap
|
||||
? "task-name-display-panel task-name-display-panel--wrap"
|
||||
: "task-name-display-panel";
|
||||
|
||||
const updateTruncationState = React.useCallback(() => {
|
||||
const el = taskNameRef.current;
|
||||
|
||||
if (!el || allowWordWrap) {
|
||||
setIsNameTruncated(false);
|
||||
return;
|
||||
}
|
||||
|
||||
setIsNameTruncated(el.scrollWidth > el.clientWidth);
|
||||
}, [allowWordWrap]);
|
||||
|
||||
useEffect(() => {
|
||||
updateTruncationState();
|
||||
}, [taskName, allowWordWrap, updateTruncationState]);
|
||||
|
||||
useEffect(() => {
|
||||
const el = taskNameRef.current;
|
||||
if (!el || allowWordWrap || typeof ResizeObserver === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
const observer = new ResizeObserver(() => {
|
||||
updateTruncationState();
|
||||
});
|
||||
|
||||
observer.observe(el);
|
||||
|
||||
return () => {
|
||||
observer.disconnect();
|
||||
};
|
||||
}, [allowWordWrap, updateTruncationState]);
|
||||
|
||||
return (
|
||||
<div className={panelClassName}>
|
||||
<FontAwesomeStringIcon icon={meta?.icon} />
|
||||
<span
|
||||
ref={taskNameRef}
|
||||
className="task-name-display-panel__name"
|
||||
title={isNameTruncated ? taskName : undefined}
|
||||
>
|
||||
{taskName}
|
||||
</span>
|
||||
<ValidationErrorIcon
|
||||
visible={showValidationErrorIcon}
|
||||
reserveSpace={reserveValidationErrorIconSpace}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TaskTypeAndNameDisplayPanel;
|
||||
Loading…
Reference in New Issue
Block a user