display groups as tiles on list page w/ burnettk

This commit is contained in:
jasquat 2022-11-18 12:42:08 -05:00
parent 358b54df0a
commit d393683794
6 changed files with 107 additions and 62 deletions

View File

@ -445,7 +445,6 @@ paths:
description: For filtering - indicates the user has manually entered a query description: For filtering - indicates the user has manually entered a query
schema: schema:
type: boolean type: boolean
# process_instance_list
get: get:
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_list operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_list
summary: Returns a list of process instances for a given process model summary: Returns a list of process instances for a given process model

View File

@ -55,13 +55,24 @@ class ProcessGroupSchema(Schema):
"""Meta.""" """Meta."""
model = ProcessGroup model = ProcessGroup
fields = ["id", "display_name", "display_order", "admin", "process_models"] fields = [
"id",
"display_name",
"display_order",
"admin",
"process_models",
"description",
"process_groups",
]
process_models = marshmallow.fields.List( process_models = marshmallow.fields.List(
marshmallow.fields.Nested( marshmallow.fields.Nested(
"ProcessModelInfoSchema", dump_only=True, required=False "ProcessModelInfoSchema", dump_only=True, required=False
) )
) )
process_groups = marshmallow.fields.List(
marshmallow.fields.Nested("ProcessGroupSchema", dump_only=True, required=False)
)
@post_load @post_load
def make_process_group( def make_process_group(

View File

@ -188,3 +188,47 @@ h1.with-icons {
padding-right: 5px; padding-right: 5px;
padding-left: 5px; padding-left: 5px;
} }
.cds--tile.tile-process-group {
padding: 0px;
margin: 16px;
width: 354px;
height: 264px;
background: #F4F4F4;
order: 1;
float: left;
}
.tile-process-group-content-container {
width: 354px;
height: 264px;
padding: 1em;
position: relative;
}
.tile-process-group-display-name {
margin-top: 2em;
margin-bottom: 1em;
font-size: 20px;
line-height: 28px;
color: #161616;
order: 0;
}
.tile-process-group-description {
font-size: 14px;
line-height: 20px;
letter-spacing: 0.16px;
color: #161616;
order: 1;
}
.tile-process-group-children-count {
font-size: 14px;
line-height: 20px;
letter-spacing: 0.16px;
color: #161616;
order: 1;
position: absolute;
bottom: 1em;
}

View File

@ -11,12 +11,6 @@ export interface RecentProcessModel {
processModelDisplayName: string; processModelDisplayName: string;
} }
export interface ProcessGroup {
id: string;
display_name: string;
description?: string | null;
}
export interface ProcessReference { export interface ProcessReference {
id: string; // The unique id of the process or decision table. id: string; // The unique id of the process or decision table.
name: string; // The process or decision Display name. name: string; // The process or decision Display name.
@ -50,6 +44,14 @@ export interface ProcessModel {
files: ProcessFile[]; files: ProcessFile[];
} }
export interface ProcessGroup {
id: string;
display_name: string;
description?: string | null;
process_models?: ProcessModel[];
process_groups?: ProcessGroup[];
}
// tuple of display value and URL // tuple of display value and URL
export type HotCrumbItem = [displayValue: string, url?: string]; export type HotCrumbItem = [displayValue: string, url?: string];

View File

@ -1,35 +1,36 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { Link, useNavigate, useSearchParams } from 'react-router-dom'; import { useNavigate, useSearchParams } from 'react-router-dom';
import {
ArrowRight,
// @ts-ignore
} from '@carbon/icons-react';
import { import {
Button, Button,
Table, ClickableTile,
// @ts-ignore // @ts-ignore
} from '@carbon/react'; } from '@carbon/react';
import { Can } from '@casl/react'; import { Can } from '@casl/react';
import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
import PaginationForTable from '../components/PaginationForTable';
import HttpService from '../services/HttpService'; import HttpService from '../services/HttpService';
import { import { modifyProcessModelPath, truncateString } from '../helpers';
getPageInfoFromSearchParams,
modifyProcessModelPath,
} from '../helpers';
import { import {
CarbonComboBoxSelection, CarbonComboBoxSelection,
PermissionsToCheck, PermissionsToCheck,
ProcessGroup, ProcessGroup,
} from '../interfaces'; } from '../interfaces';
import ProcessModelSearch from '../components/ProcessModelSearch';
import { useUriListForPermissions } from '../hooks/UriListForPermissions'; import { useUriListForPermissions } from '../hooks/UriListForPermissions';
import { usePermissionFetcher } from '../hooks/PermissionService'; import { usePermissionFetcher } from '../hooks/PermissionService';
import ProcessModelSearch from '../components/ProcessModelSearch';
// Example process group json // Example process group json
// {'process_group_id': 'sure', 'display_name': 'Test Workflows', 'id': 'test_process_group'} // {'process_group_id': 'sure', 'display_name': 'Test Workflows', 'id': 'test_process_group'}
export default function ProcessGroupList() { export default function ProcessGroupList() {
const navigate = useNavigate();
const [searchParams] = useSearchParams(); const [searchParams] = useSearchParams();
const navigate = useNavigate();
const [processGroups, setProcessGroups] = useState([]); const [processGroups, setProcessGroups] = useState<ProcessGroup[] | null>(
const [pagination, setPagination] = useState(null); null
);
const [processModelAvailableItems, setProcessModelAvailableItems] = useState( const [processModelAvailableItems, setProcessModelAvailableItems] = useState(
[] []
); );
@ -43,7 +44,6 @@ export default function ProcessGroupList() {
useEffect(() => { useEffect(() => {
const setProcessGroupsFromResult = (result: any) => { const setProcessGroupsFromResult = (result: any) => {
setProcessGroups(result.results); setProcessGroups(result.results);
setPagination(result.pagination);
}; };
const processResultForProcessModels = (result: any) => { const processResultForProcessModels = (result: any) => {
const selectionArray = result.results.map((item: any) => { const selectionArray = result.results.map((item: any) => {
@ -54,10 +54,9 @@ export default function ProcessGroupList() {
setProcessModelAvailableItems(selectionArray); setProcessModelAvailableItems(selectionArray);
}; };
const { page, perPage } = getPageInfoFromSearchParams(searchParams);
// for browsing // for browsing
HttpService.makeCallToBackend({ HttpService.makeCallToBackend({
path: `/process-groups?per_page=${perPage}&page=${page}`, path: `/process-groups?per_page=1000`,
successCallback: setProcessGroupsFromResult, successCallback: setProcessGroupsFromResult,
}); });
// for search box // for search box
@ -67,48 +66,38 @@ export default function ProcessGroupList() {
}); });
}, [searchParams]); }, [searchParams]);
const buildTable = () => { const processGroupDirectChildrenCount = (processGroup: ProcessGroup) => {
const rows = processGroups.map((row: ProcessGroup) => {
return ( return (
<tr key={(row as any).id}> (processGroup.process_models || []).length +
<td> (processGroup.process_groups || []).length
<Link
to={`/admin/process-groups/${(row as any).id}`}
title={(row as any).id}
>
{(row as any).display_name}
</Link>
</td>
</tr>
);
});
return (
<Table striped bordered>
<thead>
<tr>
<th>Process Group</th>
</tr>
</thead>
<tbody>{rows}</tbody>
</Table>
); );
}; };
const processGroupsDisplayArea = () => { const processGroupsDisplayArea = () => {
const { page, perPage } = getPageInfoFromSearchParams(searchParams);
let displayText = null; let displayText = null;
if (processGroups?.length > 0) { if (processGroups && processGroups.length > 0) {
displayText = ( displayText = (processGroups || []).map((row: ProcessGroup) => {
<> return (
<h3>Browse</h3> <ClickableTile
<PaginationForTable id="tile-1"
page={page} className="tile-process-group"
perPage={perPage} href={`/admin/process-groups/${row.id}`}
pagination={pagination as any} >
tableToDisplay={buildTable()} <div className="tile-process-group-content-container">
/> <ArrowRight />
</> <div className="tile-process-group-display-name">
{row.display_name}
</div>
<p className="tile-process-group-description">
{truncateString(row.description || '', 25)}
</p>
<p className="tile-process-group-children-count">
Total Sub Items: {processGroupDirectChildrenCount(row)}
</p>
</div>
</ClickableTile>
); );
});
} else { } else {
displayText = <p>No Groups To Display</p>; displayText = <p>No Groups To Display</p>;
} }
@ -131,7 +120,7 @@ export default function ProcessGroupList() {
); );
}; };
if (pagination) { if (processGroups) {
return ( return (
<> <>
<ProcessBreadcrumb hotCrumbs={[['Process Groups']]} /> <ProcessBreadcrumb hotCrumbs={[['Process Groups']]} />
@ -142,6 +131,7 @@ export default function ProcessGroupList() {
<br /> <br />
<br /> <br />
</Can> </Can>
<br />
{processModelSearchArea()} {processModelSearchArea()}
<br /> <br />
{processGroupsDisplayArea()} {processGroupsDisplayArea()}

View File

@ -368,7 +368,6 @@ export default function ProcessModelShow() {
return constructedTag; return constructedTag;
}); });
// return <ul>{tags}</ul>;
const headers = ['Name', 'Actions']; const headers = ['Name', 'Actions'];
return ( return (
<Table size="lg" useZebraStyles={false}> <Table size="lg" useZebraStyles={false}>