mirror of
https://github.com/sartography/spiff-arena.git
synced 2025-01-13 02:54:27 +00:00
Feature/pi short link (#503)
* moved adminroutes to homepage to get rid of /admin from urls * removed admin prefix from urls * moved top level base routes to their own routes file w/ burnettk * added ability to get and use a short link to the process instance show page w/ burnettk * give the person some feedback * move about page to baseroutes so it acts like the other pages * use the normal notificaiton component for the copied link notification * added 404 page and backend is down page w/ burnettk --------- Co-authored-by: jasquat <jasquat@users.noreply.github.com> Co-authored-by: burnettk <burnettk@users.noreply.github.com>
This commit is contained in:
parent
00158df03d
commit
ff83b8c801
@ -14,7 +14,6 @@ export default function App() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ability = defineAbility(() => {});
|
const ability = defineAbility(() => {});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="cds--white">
|
<div className="cds--white">
|
||||||
{/* @ts-ignore */}
|
{/* @ts-ignore */}
|
||||||
|
@ -4,10 +4,6 @@ import React, { useEffect, useState } from 'react';
|
|||||||
import { ErrorBoundary } from 'react-error-boundary';
|
import { ErrorBoundary } from 'react-error-boundary';
|
||||||
import NavigationBar from './components/NavigationBar';
|
import NavigationBar from './components/NavigationBar';
|
||||||
|
|
||||||
import HomePageRoutes from './routes/HomePageRoutes';
|
|
||||||
import About from './routes/About';
|
|
||||||
import AdminRoutes from './routes/AdminRoutes';
|
|
||||||
|
|
||||||
import ScrollToTop from './components/ScrollToTop';
|
import ScrollToTop from './components/ScrollToTop';
|
||||||
import EditorRoutes from './routes/EditorRoutes';
|
import EditorRoutes from './routes/EditorRoutes';
|
||||||
import Extension from './routes/Extension';
|
import Extension from './routes/Extension';
|
||||||
@ -20,8 +16,11 @@ import {
|
|||||||
} from './extension_ui_schema_interfaces';
|
} from './extension_ui_schema_interfaces';
|
||||||
import HttpService from './services/HttpService';
|
import HttpService from './services/HttpService';
|
||||||
import { ErrorBoundaryFallback } from './ErrorBoundaryFallack';
|
import { ErrorBoundaryFallback } from './ErrorBoundaryFallack';
|
||||||
|
import BaseRoutes from './routes/BaseRoutes';
|
||||||
|
import BackendIsDown from './routes/BackendIsDown';
|
||||||
|
|
||||||
export default function ContainerForExtensions() {
|
export default function ContainerForExtensions() {
|
||||||
|
const [backendIsUp, setBackendIsUp] = useState<boolean | null>(null);
|
||||||
const [extensionUxElements, setExtensionNavigationItems] = useState<
|
const [extensionUxElements, setExtensionNavigationItems] = useState<
|
||||||
UiSchemaUxElement[] | null
|
UiSchemaUxElement[] | null
|
||||||
>(null);
|
>(null);
|
||||||
@ -40,10 +39,6 @@ export default function ContainerForExtensions() {
|
|||||||
|
|
||||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!permissionsLoaded) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const processExtensionResult = (processModels: ProcessModel[]) => {
|
const processExtensionResult = (processModels: ProcessModel[]) => {
|
||||||
const eni: UiSchemaUxElement[] = processModels
|
const eni: UiSchemaUxElement[] = processModels
|
||||||
.map((processModel: ProcessModel) => {
|
.map((processModel: ProcessModel) => {
|
||||||
@ -72,13 +67,57 @@ export default function ContainerForExtensions() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getExtensions = () => {
|
||||||
|
if (!permissionsLoaded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setBackendIsUp(true);
|
||||||
if (ability.can('GET', targetUris.extensionListPath)) {
|
if (ability.can('GET', targetUris.extensionListPath)) {
|
||||||
HttpService.makeCallToBackend({
|
HttpService.makeCallToBackend({
|
||||||
path: targetUris.extensionListPath,
|
path: targetUris.extensionListPath,
|
||||||
successCallback: processExtensionResult,
|
successCallback: processExtensionResult,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [targetUris.extensionListPath, permissionsLoaded, ability]);
|
};
|
||||||
|
|
||||||
|
HttpService.makeCallToBackend({
|
||||||
|
path: targetUris.statusPath,
|
||||||
|
successCallback: getExtensions,
|
||||||
|
failureCallback: () => setBackendIsUp(false),
|
||||||
|
});
|
||||||
|
}, [
|
||||||
|
targetUris.extensionListPath,
|
||||||
|
targetUris.statusPath,
|
||||||
|
permissionsLoaded,
|
||||||
|
ability,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const routeComponents = () => {
|
||||||
|
return (
|
||||||
|
<Routes>
|
||||||
|
<Route
|
||||||
|
path="/*"
|
||||||
|
element={<BaseRoutes extensionUxElements={extensionUxElements} />}
|
||||||
|
/>
|
||||||
|
<Route path="/editor/*" element={<EditorRoutes />} />
|
||||||
|
<Route path="/extensions/:page_identifier" element={<Extension />} />
|
||||||
|
</Routes>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const backendIsDownPage = () => {
|
||||||
|
return <BackendIsDown />;
|
||||||
|
};
|
||||||
|
|
||||||
|
const innerComponents = () => {
|
||||||
|
if (backendIsUp === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (backendIsUp) {
|
||||||
|
return routeComponents();
|
||||||
|
}
|
||||||
|
return backendIsDownPage();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -86,22 +125,7 @@ export default function ContainerForExtensions() {
|
|||||||
<Content className={contentClassName}>
|
<Content className={contentClassName}>
|
||||||
<ScrollToTop />
|
<ScrollToTop />
|
||||||
<ErrorBoundary FallbackComponent={ErrorBoundaryFallback}>
|
<ErrorBoundary FallbackComponent={ErrorBoundaryFallback}>
|
||||||
<Routes>
|
{innerComponents()}
|
||||||
<Route path="/*" element={<HomePageRoutes />} />
|
|
||||||
<Route path="/about" element={<About />} />
|
|
||||||
<Route path="/tasks/*" element={<HomePageRoutes />} />
|
|
||||||
<Route
|
|
||||||
path="/admin/*"
|
|
||||||
element={
|
|
||||||
<AdminRoutes extensionUxElements={extensionUxElements} />
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Route path="/editor/*" element={<EditorRoutes />} />
|
|
||||||
<Route
|
|
||||||
path="/extensions/:page_identifier"
|
|
||||||
element={<Extension />}
|
|
||||||
/>
|
|
||||||
</Routes>
|
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
</Content>
|
</Content>
|
||||||
</>
|
</>
|
||||||
|
@ -1,24 +1,7 @@
|
|||||||
import { Button, Content } from '@carbon/react';
|
import { Button } from '@carbon/react';
|
||||||
import { Routes, Route } from 'react-router-dom';
|
import React from 'react';
|
||||||
import React, { useEffect, useState } from 'react';
|
import { useErrorBoundary } from 'react-error-boundary';
|
||||||
import { ErrorBoundary, useErrorBoundary } from 'react-error-boundary';
|
|
||||||
import NavigationBar from './components/NavigationBar';
|
|
||||||
|
|
||||||
import HomePageRoutes from './routes/HomePageRoutes';
|
|
||||||
import About from './routes/About';
|
|
||||||
import AdminRoutes from './routes/AdminRoutes';
|
|
||||||
|
|
||||||
import ScrollToTop from './components/ScrollToTop';
|
|
||||||
import EditorRoutes from './routes/EditorRoutes';
|
|
||||||
import Extension from './routes/Extension';
|
|
||||||
import { useUriListForPermissions } from './hooks/UriListForPermissions';
|
|
||||||
import { PermissionsToCheck, ProcessFile, ProcessModel } from './interfaces';
|
|
||||||
import { usePermissionFetcher } from './hooks/PermissionService';
|
|
||||||
import {
|
|
||||||
ExtensionUiSchema,
|
|
||||||
UiSchemaUxElement,
|
|
||||||
} from './extension_ui_schema_interfaces';
|
|
||||||
import HttpService from './services/HttpService';
|
|
||||||
import { Notification } from './components/Notification';
|
import { Notification } from './components/Notification';
|
||||||
|
|
||||||
type ErrorProps = {
|
type ErrorProps = {
|
||||||
@ -44,90 +27,3 @@ export function ErrorBoundaryFallback({ error }: ErrorProps) {
|
|||||||
</Notification>
|
</Notification>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ContainerForExtensions() {
|
|
||||||
const [extensionUxElements, setExtensionNavigationItems] = useState<
|
|
||||||
UiSchemaUxElement[] | null
|
|
||||||
>(null);
|
|
||||||
|
|
||||||
let contentClassName = 'main-site-body-centered';
|
|
||||||
if (window.location.pathname.startsWith('/editor/')) {
|
|
||||||
contentClassName = 'no-center-stuff';
|
|
||||||
}
|
|
||||||
const { targetUris } = useUriListForPermissions();
|
|
||||||
const permissionRequestData: PermissionsToCheck = {
|
|
||||||
[targetUris.extensionListPath]: ['GET'],
|
|
||||||
};
|
|
||||||
const { ability, permissionsLoaded } = usePermissionFetcher(
|
|
||||||
permissionRequestData
|
|
||||||
);
|
|
||||||
|
|
||||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
||||||
useEffect(() => {
|
|
||||||
if (!permissionsLoaded) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const processExtensionResult = (processModels: ProcessModel[]) => {
|
|
||||||
const eni: UiSchemaUxElement[] = processModels
|
|
||||||
.map((processModel: ProcessModel) => {
|
|
||||||
const extensionUiSchemaFile = processModel.files.find(
|
|
||||||
(file: ProcessFile) => file.name === 'extension_uischema.json'
|
|
||||||
);
|
|
||||||
if (extensionUiSchemaFile && extensionUiSchemaFile.file_contents) {
|
|
||||||
try {
|
|
||||||
const extensionUiSchema: ExtensionUiSchema = JSON.parse(
|
|
||||||
extensionUiSchemaFile.file_contents
|
|
||||||
);
|
|
||||||
if (extensionUiSchema.ux_elements) {
|
|
||||||
return extensionUiSchema.ux_elements;
|
|
||||||
}
|
|
||||||
} catch (jsonParseError: any) {
|
|
||||||
console.error(
|
|
||||||
`Unable to get navigation items for ${processModel.id}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return [] as UiSchemaUxElement[];
|
|
||||||
})
|
|
||||||
.flat();
|
|
||||||
if (eni) {
|
|
||||||
setExtensionNavigationItems(eni);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (ability.can('GET', targetUris.extensionListPath)) {
|
|
||||||
HttpService.makeCallToBackend({
|
|
||||||
path: targetUris.extensionListPath,
|
|
||||||
successCallback: processExtensionResult,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [targetUris.extensionListPath, permissionsLoaded, ability]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<NavigationBar extensionUxElements={extensionUxElements} />
|
|
||||||
<Content className={contentClassName}>
|
|
||||||
<ScrollToTop />
|
|
||||||
<ErrorBoundary fallback={<h1>Something went wrong.</h1>}>
|
|
||||||
<Routes>
|
|
||||||
<Route path="/*" element={<HomePageRoutes />} />
|
|
||||||
<Route path="/about" element={<About />} />
|
|
||||||
<Route path="/tasks/*" element={<HomePageRoutes />} />
|
|
||||||
<Route
|
|
||||||
path="/admin/*"
|
|
||||||
element={
|
|
||||||
<AdminRoutes extensionUxElements={extensionUxElements} />
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Route path="/editor/*" element={<EditorRoutes />} />
|
|
||||||
<Route
|
|
||||||
path="/extensions/:page_identifier"
|
|
||||||
element={<Extension />}
|
|
||||||
/>
|
|
||||||
</Routes>
|
|
||||||
</ErrorBoundary>
|
|
||||||
</Content>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
@ -100,7 +100,7 @@ export default function MessageInstanceList({ processInstanceId }: OwnProps) {
|
|||||||
instanceLink = (
|
instanceLink = (
|
||||||
<Link
|
<Link
|
||||||
data-qa="process-instance-show-link"
|
data-qa="process-instance-show-link"
|
||||||
to={`/admin/process-instances/${modifyProcessIdentifierForPathParam(
|
to={`/process-instances/${modifyProcessIdentifierForPathParam(
|
||||||
row.process_model_identifier
|
row.process_model_identifier
|
||||||
)}/${row.process_instance_id}`}
|
)}/${row.process_instance_id}`}
|
||||||
>
|
>
|
||||||
@ -167,7 +167,7 @@ export default function MessageInstanceList({ processInstanceId }: OwnProps) {
|
|||||||
},
|
},
|
||||||
[
|
[
|
||||||
`Process Instance: ${searchParams.get('process_instance_id')}`,
|
`Process Instance: ${searchParams.get('process_instance_id')}`,
|
||||||
`/admin/process-instances/${searchParams.get(
|
`/process-instances/${searchParams.get(
|
||||||
'process_model_id'
|
'process_model_id'
|
||||||
)}/${searchParams.get('process_instance_id')}`,
|
)}/${searchParams.get('process_instance_id')}`,
|
||||||
],
|
],
|
||||||
|
@ -11,7 +11,7 @@ export function FormatProcessModelDisplayName(
|
|||||||
} = instanceObject;
|
} = instanceObject;
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
to={`/admin/process-models/${modifyProcessIdentifierForPathParam(
|
to={`/process-models/${modifyProcessIdentifierForPathParam(
|
||||||
processModelIdentifier
|
processModelIdentifier
|
||||||
)}`}
|
)}`}
|
||||||
title={processModelIdentifier}
|
title={processModelIdentifier}
|
||||||
|
@ -76,19 +76,17 @@ export default function NavigationBar({ extensionUxElements }: OwnProps) {
|
|||||||
const versionInfo = appVersionInfo();
|
const versionInfo = appVersionInfo();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let newActiveKey = '/admin/process-groups';
|
let newActiveKey = '/process-groups';
|
||||||
if (location.pathname.match(/^\/admin\/messages\b/)) {
|
if (location.pathname.match(/^\/messages\b/)) {
|
||||||
newActiveKey = '/admin/messages';
|
newActiveKey = '/messages';
|
||||||
} else if (
|
} else if (location.pathname.match(/^\/process-instances\/reports\b/)) {
|
||||||
location.pathname.match(/^\/admin\/process-instances\/reports\b/)
|
newActiveKey = '/process-instances/reports';
|
||||||
) {
|
} else if (location.pathname.match(/^\/process-instances\b/)) {
|
||||||
newActiveKey = '/admin/process-instances/reports';
|
newActiveKey = '/process-instances';
|
||||||
} else if (location.pathname.match(/^\/admin\/process-instances\b/)) {
|
} else if (location.pathname.match(/^\/configuration\b/)) {
|
||||||
newActiveKey = '/admin/process-instances';
|
newActiveKey = '/configuration';
|
||||||
} else if (location.pathname.match(/^\/admin\/configuration\b/)) {
|
} else if (location.pathname.match(/^\/data-stores\b/)) {
|
||||||
newActiveKey = '/admin/configuration';
|
newActiveKey = '/data-stores';
|
||||||
} else if (location.pathname.match(/^\/admin\/data-stores\b/)) {
|
|
||||||
newActiveKey = '/admin/data-stores';
|
|
||||||
} else if (location.pathname === '/') {
|
} else if (location.pathname === '/') {
|
||||||
newActiveKey = '/';
|
newActiveKey = '/';
|
||||||
} else if (location.pathname.match(/^\/tasks\b/)) {
|
} else if (location.pathname.match(/^\/tasks\b/)) {
|
||||||
@ -205,8 +203,8 @@ export default function NavigationBar({ extensionUxElements }: OwnProps) {
|
|||||||
if (secretAllowed || authenticationAllowed) {
|
if (secretAllowed || authenticationAllowed) {
|
||||||
return (
|
return (
|
||||||
<HeaderMenuItem
|
<HeaderMenuItem
|
||||||
href="/admin/configuration"
|
href="/configuration"
|
||||||
isCurrentPage={isActivePage('/admin/configuration')}
|
isCurrentPage={isActivePage('/configuration')}
|
||||||
>
|
>
|
||||||
Configuration
|
Configuration
|
||||||
</HeaderMenuItem>
|
</HeaderMenuItem>
|
||||||
@ -249,8 +247,8 @@ export default function NavigationBar({ extensionUxElements }: OwnProps) {
|
|||||||
</HeaderMenuItem>
|
</HeaderMenuItem>
|
||||||
<Can I="GET" a={targetUris.processGroupListPath} ability={ability}>
|
<Can I="GET" a={targetUris.processGroupListPath} ability={ability}>
|
||||||
<HeaderMenuItem
|
<HeaderMenuItem
|
||||||
href="/admin/process-groups"
|
href="/process-groups"
|
||||||
isCurrentPage={isActivePage('/admin/process-groups')}
|
isCurrentPage={isActivePage('/process-groups')}
|
||||||
data-qa="header-nav-processes"
|
data-qa="header-nav-processes"
|
||||||
>
|
>
|
||||||
Processes
|
Processes
|
||||||
@ -262,24 +260,24 @@ export default function NavigationBar({ extensionUxElements }: OwnProps) {
|
|||||||
ability={ability}
|
ability={ability}
|
||||||
>
|
>
|
||||||
<HeaderMenuItem
|
<HeaderMenuItem
|
||||||
href="/admin/process-instances"
|
href="/process-instances"
|
||||||
isCurrentPage={isActivePage('/admin/process-instances')}
|
isCurrentPage={isActivePage('/process-instances')}
|
||||||
>
|
>
|
||||||
Process Instances
|
Process Instances
|
||||||
</HeaderMenuItem>
|
</HeaderMenuItem>
|
||||||
</Can>
|
</Can>
|
||||||
<Can I="GET" a={targetUris.messageInstanceListPath} ability={ability}>
|
<Can I="GET" a={targetUris.messageInstanceListPath} ability={ability}>
|
||||||
<HeaderMenuItem
|
<HeaderMenuItem
|
||||||
href="/admin/messages"
|
href="/messages"
|
||||||
isCurrentPage={isActivePage('/admin/messages')}
|
isCurrentPage={isActivePage('/messages')}
|
||||||
>
|
>
|
||||||
Messages
|
Messages
|
||||||
</HeaderMenuItem>
|
</HeaderMenuItem>
|
||||||
</Can>
|
</Can>
|
||||||
<Can I="GET" a={targetUris.dataStoreListPath} ability={ability}>
|
<Can I="GET" a={targetUris.dataStoreListPath} ability={ability}>
|
||||||
<HeaderMenuItem
|
<HeaderMenuItem
|
||||||
href="/admin/data-stores"
|
href="/data-stores"
|
||||||
isCurrentPage={isActivePage('/admin/data-stores')}
|
isCurrentPage={isActivePage('/data-stores')}
|
||||||
>
|
>
|
||||||
Data Stores
|
Data Stores
|
||||||
</HeaderMenuItem>
|
</HeaderMenuItem>
|
||||||
|
@ -15,6 +15,8 @@ type OwnProps = {
|
|||||||
type?: string;
|
type?: string;
|
||||||
hideCloseButton?: boolean;
|
hideCloseButton?: boolean;
|
||||||
allowTogglingFullMessage?: boolean;
|
allowTogglingFullMessage?: boolean;
|
||||||
|
timeout?: number;
|
||||||
|
withBottomMargin?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function Notification({
|
export function Notification({
|
||||||
@ -24,6 +26,8 @@ export function Notification({
|
|||||||
type = 'success',
|
type = 'success',
|
||||||
hideCloseButton = false,
|
hideCloseButton = false,
|
||||||
allowTogglingFullMessage = false,
|
allowTogglingFullMessage = false,
|
||||||
|
timeout,
|
||||||
|
withBottomMargin = true,
|
||||||
}: OwnProps) {
|
}: OwnProps) {
|
||||||
const [showMessage, setShowMessage] = useState<boolean>(
|
const [showMessage, setShowMessage] = useState<boolean>(
|
||||||
!allowTogglingFullMessage
|
!allowTogglingFullMessage
|
||||||
@ -33,11 +37,19 @@ export function Notification({
|
|||||||
iconComponent = <Error className="notification-icon" />;
|
iconComponent = <Error className="notification-icon" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (timeout && onClose) {
|
||||||
|
setTimeout(() => {
|
||||||
|
onClose();
|
||||||
|
}, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
let classes = `cds--inline-notification cds--inline-notification--low-contrast cds--inline-notification--${type}`;
|
||||||
|
if (withBottomMargin) {
|
||||||
|
classes = `${classes} with-bottom-margin`;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div role="status" className={classes}>
|
||||||
role="status"
|
|
||||||
className={`with-bottom-margin cds--inline-notification cds--inline-notification--low-contrast cds--inline-notification--${type}`}
|
|
||||||
>
|
|
||||||
<div className="cds--inline-notification__details">
|
<div className="cds--inline-notification__details">
|
||||||
<div className="cds--inline-notification__text-wrapper">
|
<div className="cds--inline-notification__text-wrapper">
|
||||||
{iconComponent}
|
{iconComponent}
|
||||||
|
@ -58,7 +58,7 @@ export default function ProcessBreadcrumb({ hotCrumbs }: OwnProps) {
|
|||||||
) {
|
) {
|
||||||
const breadcrumbs = processEntity.parent_groups.map(
|
const breadcrumbs = processEntity.parent_groups.map(
|
||||||
(parentGroup: ProcessGroupLite) => {
|
(parentGroup: ProcessGroupLite) => {
|
||||||
const fullUrl = `/admin/process-groups/${modifyProcessIdentifierForPathParam(
|
const fullUrl = `/process-groups/${modifyProcessIdentifierForPathParam(
|
||||||
parentGroup.id
|
parentGroup.id
|
||||||
)}`;
|
)}`;
|
||||||
return (
|
return (
|
||||||
@ -70,10 +70,10 @@ export default function ProcessBreadcrumb({ hotCrumbs }: OwnProps) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (crumb.linkLastItem) {
|
if (crumb.linkLastItem) {
|
||||||
let apiBase = '/admin/process-groups';
|
let apiBase = '/process-groups';
|
||||||
let dataQaTag = '';
|
let dataQaTag = '';
|
||||||
if (crumb.entityType.startsWith('process-model')) {
|
if (crumb.entityType.startsWith('process-model')) {
|
||||||
apiBase = '/admin/process-models';
|
apiBase = '/process-models';
|
||||||
dataQaTag = 'process-model-breadcrumb-link';
|
dataQaTag = 'process-model-breadcrumb-link';
|
||||||
}
|
}
|
||||||
const fullUrl = `${apiBase}/${modifyProcessIdentifierForPathParam(
|
const fullUrl = `${apiBase}/${modifyProcessIdentifierForPathParam(
|
||||||
|
@ -27,7 +27,7 @@ export default function ProcessGroupForm({
|
|||||||
const navigateToProcessGroup = (_result: any) => {
|
const navigateToProcessGroup = (_result: any) => {
|
||||||
if (newProcessGroupId) {
|
if (newProcessGroupId) {
|
||||||
navigate(
|
navigate(
|
||||||
`/admin/process-groups/${modifyProcessIdentifierForPathParam(
|
`/process-groups/${modifyProcessIdentifierForPathParam(
|
||||||
newProcessGroupId
|
newProcessGroupId
|
||||||
)}`
|
)}`
|
||||||
);
|
);
|
||||||
|
@ -56,7 +56,7 @@ export default function ProcessGroupListTiles({
|
|||||||
<ClickableTile
|
<ClickableTile
|
||||||
id={`process-group-tile-${row.id}`}
|
id={`process-group-tile-${row.id}`}
|
||||||
className="tile-process-group"
|
className="tile-process-group"
|
||||||
href={`/admin/process-groups/${modifyProcessIdentifierForPathParam(
|
href={`/process-groups/${modifyProcessIdentifierForPathParam(
|
||||||
row.id
|
row.id
|
||||||
)}`}
|
)}`}
|
||||||
>
|
>
|
||||||
|
@ -123,6 +123,7 @@ export default function ProcessInstanceListTable({
|
|||||||
headerElement,
|
headerElement,
|
||||||
tableHtmlId,
|
tableHtmlId,
|
||||||
}: OwnProps) {
|
}: OwnProps) {
|
||||||
|
// eslint-disable-next-line sonarjs/no-duplicate-string
|
||||||
let processInstanceApiSearchPath = '/process-instances/for-me';
|
let processInstanceApiSearchPath = '/process-instances/for-me';
|
||||||
if (variant === 'all') {
|
if (variant === 'all') {
|
||||||
processInstanceApiSearchPath = '/process-instances';
|
processInstanceApiSearchPath = '/process-instances';
|
||||||
@ -177,13 +178,9 @@ export default function ProcessInstanceListTable({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const processInstanceListPathPrefix =
|
const processInstanceListPathPrefix =
|
||||||
variant === 'all'
|
variant === 'all' ? '/process-instances/all' : '/process-instances/for-me';
|
||||||
? '/admin/process-instances/all'
|
|
||||||
: '/admin/process-instances/for-me';
|
|
||||||
const processInstanceShowPathPrefix =
|
const processInstanceShowPathPrefix =
|
||||||
variant === 'all'
|
variant === 'all' ? '/process-instances' : '/process-instances/for-me';
|
||||||
? '/admin/process-instances'
|
|
||||||
: '/admin/process-instances/for-me';
|
|
||||||
|
|
||||||
const [processStatusAllOptions, setProcessStatusAllOptions] = useState<any[]>(
|
const [processStatusAllOptions, setProcessStatusAllOptions] = useState<any[]>(
|
||||||
[]
|
[]
|
||||||
@ -1834,7 +1831,7 @@ export default function ProcessInstanceListTable({
|
|||||||
hasIconOnly
|
hasIconOnly
|
||||||
size="md"
|
size="md"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
navigate(`/admin/process-instances?report_hash=${reportHash}`)
|
navigate(`/process-instances?report_hash=${reportHash}`)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</Column>
|
</Column>
|
||||||
|
@ -32,7 +32,7 @@ export default function ProcessInstanceListTabs({ variant }: OwnProps) {
|
|||||||
title="Only show process instances for the current user."
|
title="Only show process instances for the current user."
|
||||||
data-qa="process-instance-list-for-me"
|
data-qa="process-instance-list-for-me"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
navigate('/admin/process-instances/for-me');
|
navigate('/process-instances/for-me');
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
For Me
|
For Me
|
||||||
@ -42,7 +42,7 @@ export default function ProcessInstanceListTabs({ variant }: OwnProps) {
|
|||||||
title="Show all process instances for all users."
|
title="Show all process instances for all users."
|
||||||
data-qa="process-instance-list-all"
|
data-qa="process-instance-list-all"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
navigate('/admin/process-instances/all');
|
navigate('/process-instances/all');
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
All
|
All
|
||||||
@ -52,7 +52,7 @@ export default function ProcessInstanceListTabs({ variant }: OwnProps) {
|
|||||||
title="Search for a process instance by id."
|
title="Search for a process instance by id."
|
||||||
data-qa="process-instance-list-find-by-id"
|
data-qa="process-instance-list-find-by-id"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
navigate('/admin/process-instances/find-by-id');
|
navigate('/process-instances/find-by-id');
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Find By Id
|
Find By Id
|
||||||
|
@ -78,9 +78,9 @@ export default function ProcessInstanceLogList({
|
|||||||
shouldDisplayClearButton = true;
|
shouldDisplayClearButton = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let processInstanceShowPageBaseUrl = `/admin/process-instances/for-me/${processModelId}`;
|
let processInstanceShowPageBaseUrl = `/process-instances/for-me/${processModelId}`;
|
||||||
if (variant === 'all') {
|
if (variant === 'all') {
|
||||||
processInstanceShowPageBaseUrl = `/admin/process-instances/${processModelId}`;
|
processInstanceShowPageBaseUrl = `/process-instances/${processModelId}`;
|
||||||
}
|
}
|
||||||
const taskNameHeader = isEventsView ? 'Task name' : 'Milestone';
|
const taskNameHeader = isEventsView ? 'Task name' : 'Milestone';
|
||||||
const tableType = isEventsView ? 'events' : 'milestones';
|
const tableType = isEventsView ? 'events' : 'milestones';
|
||||||
|
@ -98,7 +98,7 @@ export default function ProcessInstanceRun({
|
|||||||
const onProcessInstanceRun = (processInstance: any) => {
|
const onProcessInstanceRun = (processInstance: any) => {
|
||||||
const processInstanceId = (processInstance as any).id;
|
const processInstanceId = (processInstance as any).id;
|
||||||
navigate(
|
navigate(
|
||||||
`/admin/process-instances/for-me/${modifyProcessIdentifierForPathParam(
|
`/process-instances/for-me/${modifyProcessIdentifierForPathParam(
|
||||||
processModel.id
|
processModel.id
|
||||||
)}/${processInstanceId}/interstitial`
|
)}/${processInstanceId}/interstitial`
|
||||||
);
|
);
|
||||||
|
@ -42,7 +42,7 @@ export default function ProcessModelForm({
|
|||||||
if ('id' in result) {
|
if ('id' in result) {
|
||||||
const modifiedProcessModelPathFromResult =
|
const modifiedProcessModelPathFromResult =
|
||||||
modifyProcessIdentifierForPathParam(result.id);
|
modifyProcessIdentifierForPathParam(result.id);
|
||||||
navigate(`/admin/process-models/${modifiedProcessModelPathFromResult}`);
|
navigate(`/process-models/${modifiedProcessModelPathFromResult}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ export default function ProcessModelListTiles({
|
|||||||
onClose={() => setProcessInstance(null)}
|
onClose={() => setProcessInstance(null)}
|
||||||
>
|
>
|
||||||
<Link
|
<Link
|
||||||
to={`/admin/process-instances/${modifyProcessIdentifierForPathParam(
|
to={`/process-instances/${modifyProcessIdentifierForPathParam(
|
||||||
processInstance.process_model_identifier
|
processInstance.process_model_identifier
|
||||||
)}/${processInstance.id}`}
|
)}/${processInstance.id}`}
|
||||||
data-qa="process-instance-show-link"
|
data-qa="process-instance-show-link"
|
||||||
@ -83,7 +83,7 @@ export default function ProcessModelListTiles({
|
|||||||
<a
|
<a
|
||||||
title={row.id}
|
title={row.id}
|
||||||
data-qa="process-model-show-link"
|
data-qa="process-model-show-link"
|
||||||
href={`/admin/process-models/${modifyProcessIdentifierForPathParam(
|
href={`/process-models/${modifyProcessIdentifierForPathParam(
|
||||||
row.id
|
row.id
|
||||||
)}`}
|
)}`}
|
||||||
>
|
>
|
||||||
|
@ -632,7 +632,7 @@ export default function ReactDiagramEditor({
|
|||||||
<li>
|
<li>
|
||||||
<Link
|
<Link
|
||||||
size="lg"
|
size="lg"
|
||||||
href={`/admin/process-models/${modifyProcessIdentifierForPathParam(
|
href={`/process-models/${modifyProcessIdentifierForPathParam(
|
||||||
ref.process_model_id
|
ref.process_model_id
|
||||||
)}`}
|
)}`}
|
||||||
>
|
>
|
||||||
@ -704,7 +704,7 @@ export default function ReactDiagramEditor({
|
|||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
navigate(
|
navigate(
|
||||||
`/admin/process-models/${processModelId}/form/${fileName}`
|
`/process-models/${processModelId}/form/${fileName}`
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import UserService from '../services/UserService';
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
roles: string[];
|
|
||||||
children: React.ReactNode;
|
|
||||||
};
|
|
||||||
|
|
||||||
function RenderOnRole({ roles, children }: Props) {
|
|
||||||
return UserService.hasRole(roles) ? children : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default RenderOnRole;
|
|
@ -214,7 +214,7 @@ export default function TaskListTable({
|
|||||||
<td>
|
<td>
|
||||||
<Link
|
<Link
|
||||||
data-qa="process-instance-show-link-id"
|
data-qa="process-instance-show-link-id"
|
||||||
to={`/admin/process-instances/for-me/${modifiedProcessModelIdentifier}/${processInstanceTask.process_instance_id}`}
|
to={`/process-instances/for-me/${modifiedProcessModelIdentifier}/${processInstanceTask.process_instance_id}`}
|
||||||
title={`View process instance ${processInstanceTask.process_instance_id}`}
|
title={`View process instance ${processInstanceTask.process_instance_id}`}
|
||||||
>
|
>
|
||||||
{processInstanceTask.process_instance_id}
|
{processInstanceTask.process_instance_id}
|
||||||
@ -239,7 +239,7 @@ export default function TaskListTable({
|
|||||||
<td>
|
<td>
|
||||||
<Link
|
<Link
|
||||||
data-qa="process-model-show-link"
|
data-qa="process-model-show-link"
|
||||||
to={`/admin/process-models/${modifiedProcessModelIdentifier}`}
|
to={`/process-models/${modifiedProcessModelIdentifier}`}
|
||||||
title={processInstanceTask.process_model_identifier}
|
title={processInstanceTask.process_model_identifier}
|
||||||
>
|
>
|
||||||
{processInstanceTask.process_model_display_name}
|
{processInstanceTask.process_model_display_name}
|
||||||
|
@ -6,6 +6,7 @@ export const useUriListForPermissions = () => {
|
|||||||
const targetUris = useMemo(() => {
|
const targetUris = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
authenticationListPath: `/v1.0/authentications`,
|
authenticationListPath: `/v1.0/authentications`,
|
||||||
|
statusPath: `/v1.0/status`,
|
||||||
messageInstanceListPath: '/v1.0/messages',
|
messageInstanceListPath: '/v1.0/messages',
|
||||||
dataStoreListPath: '/v1.0/data-stores',
|
dataStoreListPath: '/v1.0/data-stores',
|
||||||
extensionListPath: '/v1.0/extensions',
|
extensionListPath: '/v1.0/extensions',
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { Table } from '@carbon/react';
|
import { Table } from '@carbon/react';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import ErrorDisplay from '../components/ErrorDisplay';
|
|
||||||
import appVersionInfo from '../helpers/appVersionInfo';
|
import appVersionInfo from '../helpers/appVersionInfo';
|
||||||
import { ObjectWithStringKeysAndValues } from '../interfaces';
|
import { ObjectWithStringKeysAndValues } from '../interfaces';
|
||||||
import HttpService from '../services/HttpService';
|
import HttpService from '../services/HttpService';
|
||||||
@ -58,7 +57,6 @@ export default function About() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<ErrorDisplay />
|
|
||||||
<h1>About</h1>
|
<h1>About</h1>
|
||||||
{versionInfoFromDict('Frontend version information', frontendVersionInfo)}
|
{versionInfoFromDict('Frontend version information', frontendVersionInfo)}
|
||||||
{versionInfoFromDict('Backend version information', backendVersionInfo)}
|
{versionInfoFromDict('Backend version information', backendVersionInfo)}
|
||||||
|
@ -1,151 +0,0 @@
|
|||||||
import { Routes, Route, useLocation } from 'react-router-dom';
|
|
||||||
|
|
||||||
import React, { useEffect } from 'react';
|
|
||||||
import ProcessGroupList from './ProcessGroupList';
|
|
||||||
import ProcessGroupShow from './ProcessGroupShow';
|
|
||||||
import ProcessGroupNew from './ProcessGroupNew';
|
|
||||||
import ProcessGroupEdit from './ProcessGroupEdit';
|
|
||||||
import ProcessModelShow from './ProcessModelShow';
|
|
||||||
import ProcessInstanceList from './ProcessInstanceList';
|
|
||||||
import ProcessModelNew from './ProcessModelNew';
|
|
||||||
import ProcessModelEdit from './ProcessModelEdit';
|
|
||||||
import ProcessInstanceShow from './ProcessInstanceShow';
|
|
||||||
import UserService from '../services/UserService';
|
|
||||||
import ProcessInstanceReportList from './ProcessInstanceReportList';
|
|
||||||
import ProcessInstanceReportNew from './ProcessInstanceReportNew';
|
|
||||||
import ProcessInstanceReportEdit from './ProcessInstanceReportEdit';
|
|
||||||
import ReactFormEditor from './ReactFormEditor';
|
|
||||||
import Configuration from './Configuration';
|
|
||||||
import JsonSchemaFormBuilder from './JsonSchemaFormBuilder';
|
|
||||||
import ProcessModelNewExperimental from './ProcessModelNewExperimental';
|
|
||||||
import ProcessInstanceFindById from './ProcessInstanceFindById';
|
|
||||||
import ProcessInterstitialPage from './ProcessInterstitialPage';
|
|
||||||
import MessageListPage from './MessageListPage';
|
|
||||||
import DataStorePage from './DataStorePage';
|
|
||||||
import ErrorDisplay from '../components/ErrorDisplay';
|
|
||||||
import { UiSchemaUxElement } from '../extension_ui_schema_interfaces';
|
|
||||||
|
|
||||||
type OwnProps = {
|
|
||||||
extensionUxElements?: UiSchemaUxElement[] | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function AdminRoutes({ extensionUxElements }: OwnProps) {
|
|
||||||
const location = useLocation();
|
|
||||||
|
|
||||||
useEffect(() => {}, [location]);
|
|
||||||
|
|
||||||
if (UserService.hasRole(['admin'])) {
|
|
||||||
return (
|
|
||||||
<div className="fixed-width-container">
|
|
||||||
<ErrorDisplay />
|
|
||||||
<Routes>
|
|
||||||
<Route path="/" element={<ProcessGroupList />} />
|
|
||||||
<Route path="process-groups" element={<ProcessGroupList />} />
|
|
||||||
<Route
|
|
||||||
path="process-groups/:process_group_id"
|
|
||||||
element={<ProcessGroupShow />}
|
|
||||||
/>
|
|
||||||
<Route path="process-groups/new" element={<ProcessGroupNew />} />
|
|
||||||
<Route
|
|
||||||
path="process-groups/:process_group_id/edit"
|
|
||||||
element={<ProcessGroupEdit />}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Route
|
|
||||||
path="process-models/:process_group_id/new"
|
|
||||||
element={<ProcessModelNew />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="process-models/:process_group_id/new-e"
|
|
||||||
element={<ProcessModelNewExperimental />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="process-models/:process_model_id"
|
|
||||||
element={<ProcessModelShow />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="process-models/:process_model_id/edit"
|
|
||||||
element={<ProcessModelEdit />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="process-instances/for-me/:process_model_id/:process_instance_id"
|
|
||||||
element={<ProcessInstanceShow variant="for-me" />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="process-instances/for-me/:process_model_id/:process_instance_id/:to_task_guid"
|
|
||||||
element={<ProcessInstanceShow variant="for-me" />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="process-instances/for-me/:process_model_id/:process_instance_id/interstitial"
|
|
||||||
element={<ProcessInterstitialPage variant="for-me" />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="process-instances/:process_model_id/:process_instance_id/interstitial"
|
|
||||||
element={<ProcessInterstitialPage variant="all" />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="process-instances/:process_model_id/:process_instance_id"
|
|
||||||
element={<ProcessInstanceShow variant="all" />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="process-instances/:process_model_id/:process_instance_id/:to_task_guid"
|
|
||||||
element={<ProcessInstanceShow variant="all" />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="process-instances/reports"
|
|
||||||
element={<ProcessInstanceReportList />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="process-instances/reports/new"
|
|
||||||
element={<ProcessInstanceReportNew />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="process-instances/reports/:report_identifier/edit"
|
|
||||||
element={<ProcessInstanceReportEdit />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="process-models/:process_model_id/form"
|
|
||||||
element={<ReactFormEditor />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="process-models/:process_model_id/form/:file_name"
|
|
||||||
element={<ReactFormEditor />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="process-instances"
|
|
||||||
element={<ProcessInstanceList variant="for-me" />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="process-instances/for-me"
|
|
||||||
element={<ProcessInstanceList variant="for-me" />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="process-instances/all"
|
|
||||||
element={<ProcessInstanceList variant="all" />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="configuration/*"
|
|
||||||
element={
|
|
||||||
<Configuration extensionUxElements={extensionUxElements} />
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="process-models/:process_model_id/form-builder"
|
|
||||||
element={<JsonSchemaFormBuilder />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
path="process-instances/find-by-id"
|
|
||||||
element={<ProcessInstanceFindById />}
|
|
||||||
/>
|
|
||||||
<Route path="messages" element={<MessageListPage />} />
|
|
||||||
<Route path="data-stores" element={<DataStorePage />} />
|
|
||||||
</Routes>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<main>
|
|
||||||
<h1>404</h1>
|
|
||||||
</main>
|
|
||||||
);
|
|
||||||
}
|
|
12
spiffworkflow-frontend/src/routes/BackendIsDown.tsx
Normal file
12
spiffworkflow-frontend/src/routes/BackendIsDown.tsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
export default function BackendIsDown() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>Server error</h1>
|
||||||
|
<p>
|
||||||
|
We are sorry, but our service is temporarily unavailable due to
|
||||||
|
technical difficulties. Please bear with us while we work to resolve the
|
||||||
|
issue. If the problem persists, please contact the site administrator.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
44
spiffworkflow-frontend/src/routes/BaseRoutes.tsx
Normal file
44
spiffworkflow-frontend/src/routes/BaseRoutes.tsx
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import { Route, Routes } from 'react-router-dom';
|
||||||
|
import Configuration from './Configuration';
|
||||||
|
import MessageListPage from './MessageListPage';
|
||||||
|
import DataStorePage from './DataStorePage';
|
||||||
|
import { UiSchemaUxElement } from '../extension_ui_schema_interfaces';
|
||||||
|
import HomeRoutes from './HomeRoutes';
|
||||||
|
import ProcessGroupRoutes from './ProcessGroupRoutes';
|
||||||
|
import ProcessModelRoutes from './ProcessModelRoutes';
|
||||||
|
import ProcessInstanceRoutes from './ProcessInstanceRoutes';
|
||||||
|
import ErrorDisplay from '../components/ErrorDisplay';
|
||||||
|
import ProcessInstanceShortLink from './ProcessInstanceShortLink';
|
||||||
|
import About from './About';
|
||||||
|
import Page404 from './Page404';
|
||||||
|
|
||||||
|
type OwnProps = {
|
||||||
|
extensionUxElements?: UiSchemaUxElement[] | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function BaseRoutes({ extensionUxElements }: OwnProps) {
|
||||||
|
return (
|
||||||
|
<div className="fixed-width-container">
|
||||||
|
<ErrorDisplay />
|
||||||
|
<Routes>
|
||||||
|
<Route path="/" element={<HomeRoutes />} />
|
||||||
|
<Route path="tasks/*" element={<HomeRoutes />} />
|
||||||
|
<Route path="process-groups/*" element={<ProcessGroupRoutes />} />
|
||||||
|
<Route path="process-models/*" element={<ProcessModelRoutes />} />
|
||||||
|
<Route path="process-instances/*" element={<ProcessInstanceRoutes />} />
|
||||||
|
<Route
|
||||||
|
path="i/:process_instance_id"
|
||||||
|
element={<ProcessInstanceShortLink />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="configuration/*"
|
||||||
|
element={<Configuration extensionUxElements={extensionUxElements} />}
|
||||||
|
/>
|
||||||
|
<Route path="messages" element={<MessageListPage />} />
|
||||||
|
<Route path="data-stores" element={<DataStorePage />} />
|
||||||
|
<Route path="about" element={<About />} />
|
||||||
|
<Route path="/*" element={<Page404 />} />
|
||||||
|
</Routes>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -39,7 +39,7 @@ export default function Configuration({ extensionUxElements }: OwnProps) {
|
|||||||
removeError();
|
removeError();
|
||||||
setPageTitle(['Configuration']);
|
setPageTitle(['Configuration']);
|
||||||
let newSelectedTabIndex = 0;
|
let newSelectedTabIndex = 0;
|
||||||
if (location.pathname.match(/^\/admin\/configuration\/authentications\b/)) {
|
if (location.pathname.match(/^\/configuration\/authentications\b/)) {
|
||||||
newSelectedTabIndex = 1;
|
newSelectedTabIndex = 1;
|
||||||
}
|
}
|
||||||
setSelectedTabIndex(newSelectedTabIndex);
|
setSelectedTabIndex(newSelectedTabIndex);
|
||||||
@ -49,7 +49,7 @@ export default function Configuration({ extensionUxElements }: OwnProps) {
|
|||||||
uxElement: UiSchemaUxElement,
|
uxElement: UiSchemaUxElement,
|
||||||
uxElementIndex: number
|
uxElementIndex: number
|
||||||
) => {
|
) => {
|
||||||
const navItemPage = `/admin/configuration/extension${uxElement.page}`;
|
const navItemPage = `/configuration/extension${uxElement.page}`;
|
||||||
|
|
||||||
let pagesToCheck = [uxElement.page];
|
let pagesToCheck = [uxElement.page];
|
||||||
if (
|
if (
|
||||||
@ -60,7 +60,7 @@ export default function Configuration({ extensionUxElements }: OwnProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pagesToCheck.forEach((pageToCheck: string) => {
|
pagesToCheck.forEach((pageToCheck: string) => {
|
||||||
const pageToCheckNavItem = `/admin/configuration/extension${pageToCheck}`;
|
const pageToCheckNavItem = `/configuration/extension${pageToCheck}`;
|
||||||
if (pageToCheckNavItem === location.pathname) {
|
if (pageToCheckNavItem === location.pathname) {
|
||||||
setSelectedTabIndex(uxElementIndex + 2);
|
setSelectedTabIndex(uxElementIndex + 2);
|
||||||
}
|
}
|
||||||
@ -80,14 +80,12 @@ export default function Configuration({ extensionUxElements }: OwnProps) {
|
|||||||
<Tabs selectedIndex={selectedTabIndex}>
|
<Tabs selectedIndex={selectedTabIndex}>
|
||||||
<TabList aria-label="List of tabs">
|
<TabList aria-label="List of tabs">
|
||||||
<Can I="GET" a={targetUris.secretListPath} ability={ability}>
|
<Can I="GET" a={targetUris.secretListPath} ability={ability}>
|
||||||
<Tab onClick={() => navigate('/admin/configuration/secrets')}>
|
<Tab onClick={() => navigate('/configuration/secrets')}>
|
||||||
Secrets
|
Secrets
|
||||||
</Tab>
|
</Tab>
|
||||||
</Can>
|
</Can>
|
||||||
<Can I="GET" a={targetUris.authenticationListPath} ability={ability}>
|
<Can I="GET" a={targetUris.authenticationListPath} ability={ability}>
|
||||||
<Tab
|
<Tab onClick={() => navigate('/configuration/authentications')}>
|
||||||
onClick={() => navigate('/admin/configuration/authentications')}
|
|
||||||
>
|
|
||||||
Authentications
|
Authentications
|
||||||
</Tab>
|
</Tab>
|
||||||
</Can>
|
</Can>
|
||||||
|
@ -2,7 +2,6 @@ import { Routes, Route, useLocation } from 'react-router-dom';
|
|||||||
|
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import ProcessModelEditDiagram from './ProcessModelEditDiagram';
|
import ProcessModelEditDiagram from './ProcessModelEditDiagram';
|
||||||
import UserService from '../services/UserService';
|
|
||||||
import ErrorDisplay from '../components/ErrorDisplay';
|
import ErrorDisplay from '../components/ErrorDisplay';
|
||||||
|
|
||||||
export default function EditorRoutes() {
|
export default function EditorRoutes() {
|
||||||
@ -10,7 +9,6 @@ export default function EditorRoutes() {
|
|||||||
|
|
||||||
useEffect(() => {}, [location]);
|
useEffect(() => {}, [location]);
|
||||||
|
|
||||||
if (UserService.hasRole(['admin'])) {
|
|
||||||
return (
|
return (
|
||||||
<div className="full-width-container no-center-stuff">
|
<div className="full-width-container no-center-stuff">
|
||||||
<ErrorDisplay />
|
<ErrorDisplay />
|
||||||
@ -27,9 +25,3 @@ export default function EditorRoutes() {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (
|
|
||||||
<main>
|
|
||||||
<h1>404</h1>
|
|
||||||
</main>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
@ -7,9 +7,8 @@ import CompletedInstances from './CompletedInstances';
|
|||||||
import CreateNewInstance from './CreateNewInstance';
|
import CreateNewInstance from './CreateNewInstance';
|
||||||
import InProgressInstances from './InProgressInstances';
|
import InProgressInstances from './InProgressInstances';
|
||||||
import OnboardingView from './OnboardingView';
|
import OnboardingView from './OnboardingView';
|
||||||
import ErrorDisplay from '../components/ErrorDisplay';
|
|
||||||
|
|
||||||
export default function HomePageRoutes() {
|
export default function HomeRoutes() {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const [selectedTabIndex, setSelectedTabIndex] = useState<number>(0);
|
const [selectedTabIndex, setSelectedTabIndex] = useState<number>(0);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -49,8 +48,7 @@ export default function HomePageRoutes() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="fixed-width-container">
|
<>
|
||||||
<ErrorDisplay />
|
|
||||||
<OnboardingView />
|
<OnboardingView />
|
||||||
{renderTabs()}
|
{renderTabs()}
|
||||||
<Routes>
|
<Routes>
|
||||||
@ -61,6 +59,6 @@ export default function HomePageRoutes() {
|
|||||||
<Route path="completed-instances" element={<CompletedInstances />} />
|
<Route path="completed-instances" element={<CompletedInstances />} />
|
||||||
<Route path="create-new-instance" element={<CreateNewInstance />} />
|
<Route path="create-new-instance" element={<CreateNewInstance />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</div>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -296,7 +296,7 @@ export default function JsonSchemaFormBuilder() {
|
|||||||
const httpMethod = 'DELETE';
|
const httpMethod = 'DELETE';
|
||||||
|
|
||||||
const navigateToProcessModelShow = (_httpResult: any) => {
|
const navigateToProcessModelShow = (_httpResult: any) => {
|
||||||
navigate(`/admin/process-models/${modifiedProcessModelId}`);
|
navigate(`/process-models/${modifiedProcessModelId}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpService.makeCallToBackend({
|
HttpService.makeCallToBackend({
|
||||||
@ -339,7 +339,7 @@ export default function JsonSchemaFormBuilder() {
|
|||||||
<Button
|
<Button
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
navigate(
|
navigate(
|
||||||
`/admin/process-models/${
|
`/process-models/${
|
||||||
params.process_model_id
|
params.process_model_id
|
||||||
}/form/${searchParams.get('file_name')}`
|
}/form/${searchParams.get('file_name')}`
|
||||||
)
|
)
|
||||||
|
@ -61,7 +61,7 @@ export default function MyTasks() {
|
|||||||
onClose={() => setProcessInstance(null)}
|
onClose={() => setProcessInstance(null)}
|
||||||
>
|
>
|
||||||
<Link
|
<Link
|
||||||
to={`/admin/process-instances/${modifyProcessIdentifierForPathParam(
|
to={`/process-instances/${modifyProcessIdentifierForPathParam(
|
||||||
processInstance.process_model_identifier
|
processInstance.process_model_identifier
|
||||||
)}/${processInstance.id}`}
|
)}/${processInstance.id}`}
|
||||||
data-qa="process-instance-show-link"
|
data-qa="process-instance-show-link"
|
||||||
@ -91,7 +91,7 @@ export default function MyTasks() {
|
|||||||
<td>
|
<td>
|
||||||
<Link
|
<Link
|
||||||
data-qa="process-model-show-link"
|
data-qa="process-model-show-link"
|
||||||
to={`/admin/process-models/${modifiedProcessModelIdentifier}`}
|
to={`/process-models/${modifiedProcessModelIdentifier}`}
|
||||||
>
|
>
|
||||||
{rowToUse.process_model_display_name}
|
{rowToUse.process_model_display_name}
|
||||||
</Link>
|
</Link>
|
||||||
@ -99,7 +99,7 @@ export default function MyTasks() {
|
|||||||
<td>
|
<td>
|
||||||
<Link
|
<Link
|
||||||
data-qa="process-instance-show-link"
|
data-qa="process-instance-show-link"
|
||||||
to={`/admin/process-instances/${modifiedProcessModelIdentifier}/${rowToUse.process_instance_id}`}
|
to={`/process-instances/${modifiedProcessModelIdentifier}/${rowToUse.process_instance_id}`}
|
||||||
>
|
>
|
||||||
{rowToUse.process_instance_id}
|
{rowToUse.process_instance_id}
|
||||||
</Link>
|
</Link>
|
||||||
@ -158,7 +158,7 @@ export default function MyTasks() {
|
|||||||
<td>
|
<td>
|
||||||
<Link
|
<Link
|
||||||
data-qa="process-model-show-link"
|
data-qa="process-model-show-link"
|
||||||
to={`/admin/process-models/${modifiedProcessModelId}`}
|
to={`/process-models/${modifiedProcessModelId}`}
|
||||||
>
|
>
|
||||||
{row.processModelDisplayName}
|
{row.processModelDisplayName}
|
||||||
</Link>
|
</Link>
|
||||||
|
8
spiffworkflow-frontend/src/routes/Page404.tsx
Normal file
8
spiffworkflow-frontend/src/routes/Page404.tsx
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export default function Page404() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>404 not found</h1>
|
||||||
|
<p>This page does not exist. Please check the url.</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -49,7 +49,7 @@ export default function ProcessGroupList() {
|
|||||||
const processModelSearchOnChange = (selection: CarbonComboBoxSelection) => {
|
const processModelSearchOnChange = (selection: CarbonComboBoxSelection) => {
|
||||||
const processModel = selection.selectedItem;
|
const processModel = selection.selectedItem;
|
||||||
navigate(
|
navigate(
|
||||||
`/admin/process-models/${modifyProcessIdentifierForPathParam(
|
`/process-models/${modifyProcessIdentifierForPathParam(
|
||||||
processModel.id
|
processModel.id
|
||||||
)}`
|
)}`
|
||||||
);
|
);
|
||||||
@ -68,7 +68,7 @@ export default function ProcessGroupList() {
|
|||||||
<>
|
<>
|
||||||
<ProcessBreadcrumb hotCrumbs={[['Process Groups']]} />
|
<ProcessBreadcrumb hotCrumbs={[['Process Groups']]} />
|
||||||
<Can I="POST" a={targetUris.processGroupListPath} ability={ability}>
|
<Can I="POST" a={targetUris.processGroupListPath} ability={ability}>
|
||||||
<Button kind="secondary" href="/admin/process-groups/new">
|
<Button kind="secondary" href="/process-groups/new">
|
||||||
Add a process group
|
Add a process group
|
||||||
</Button>
|
</Button>
|
||||||
<br />
|
<br />
|
||||||
|
16
spiffworkflow-frontend/src/routes/ProcessGroupRoutes.tsx
Normal file
16
spiffworkflow-frontend/src/routes/ProcessGroupRoutes.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { Route, Routes } from 'react-router-dom';
|
||||||
|
import ProcessGroupList from './ProcessGroupList';
|
||||||
|
import ProcessGroupShow from './ProcessGroupShow';
|
||||||
|
import ProcessGroupNew from './ProcessGroupNew';
|
||||||
|
import ProcessGroupEdit from './ProcessGroupEdit';
|
||||||
|
|
||||||
|
export default function ProcessGroupRoutes() {
|
||||||
|
return (
|
||||||
|
<Routes>
|
||||||
|
<Route path="/" element={<ProcessGroupList />} />
|
||||||
|
<Route path="/:process_group_id" element={<ProcessGroupShow />} />
|
||||||
|
<Route path="new" element={<ProcessGroupNew />} />
|
||||||
|
<Route path=":process_group_id/edit" element={<ProcessGroupEdit />} />
|
||||||
|
</Routes>
|
||||||
|
);
|
||||||
|
}
|
@ -86,7 +86,7 @@ export default function ProcessGroupShow() {
|
|||||||
// <tr key={row.id}>
|
// <tr key={row.id}>
|
||||||
// <td>
|
// <td>
|
||||||
// <Link
|
// <Link
|
||||||
// to={`/admin/process-models/${modifiedProcessModelId}`}
|
// to={`/process-models/${modifiedProcessModelId}`}
|
||||||
// data-qa="process-model-show-link"
|
// data-qa="process-model-show-link"
|
||||||
// >
|
// >
|
||||||
// {row.id}
|
// {row.id}
|
||||||
@ -113,7 +113,7 @@ export default function ProcessGroupShow() {
|
|||||||
// };
|
// };
|
||||||
|
|
||||||
const navigateToProcessGroups = (_result: any) => {
|
const navigateToProcessGroups = (_result: any) => {
|
||||||
navigate(`/admin/process-groups`);
|
navigate(`/process-groups`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteProcessGroup = () => {
|
const deleteProcessGroup = () => {
|
||||||
@ -155,7 +155,7 @@ export default function ProcessGroupShow() {
|
|||||||
renderIcon={Edit}
|
renderIcon={Edit}
|
||||||
iconDescription="Edit Process Group"
|
iconDescription="Edit Process Group"
|
||||||
hasIconOnly
|
hasIconOnly
|
||||||
href={`/admin/process-groups/${modifiedProcessGroupId}/edit`}
|
href={`/process-groups/${modifiedProcessGroupId}/edit`}
|
||||||
>
|
>
|
||||||
Edit process group
|
Edit process group
|
||||||
</Button>
|
</Button>
|
||||||
@ -178,7 +178,7 @@ export default function ProcessGroupShow() {
|
|||||||
<Stack orientation="horizontal" gap={3}>
|
<Stack orientation="horizontal" gap={3}>
|
||||||
<Can I="POST" a={targetUris.processGroupListPath} ability={ability}>
|
<Can I="POST" a={targetUris.processGroupListPath} ability={ability}>
|
||||||
<Button
|
<Button
|
||||||
href={`/admin/process-groups/new?parentGroupId=${processGroup.id}`}
|
href={`/process-groups/new?parentGroupId=${processGroup.id}`}
|
||||||
>
|
>
|
||||||
Add a process group
|
Add a process group
|
||||||
</Button>
|
</Button>
|
||||||
@ -188,9 +188,7 @@ export default function ProcessGroupShow() {
|
|||||||
a={targetUris.processModelCreatePath}
|
a={targetUris.processModelCreatePath}
|
||||||
ability={ability}
|
ability={ability}
|
||||||
>
|
>
|
||||||
<Button
|
<Button href={`/process-models/${modifiedProcessGroupId}/new`}>
|
||||||
href={`/admin/process-models/${modifiedProcessGroupId}/new`}
|
|
||||||
>
|
|
||||||
Add a process model
|
Add a process model
|
||||||
</Button>
|
</Button>
|
||||||
</Can>
|
</Can>
|
||||||
|
@ -16,7 +16,7 @@ export default function ProcessInstanceFindById() {
|
|||||||
|
|
||||||
const handleProcessInstanceNavigation = (result: any) => {
|
const handleProcessInstanceNavigation = (result: any) => {
|
||||||
const processInstance: ProcessInstance = result.process_instance;
|
const processInstance: ProcessInstance = result.process_instance;
|
||||||
let path = '/admin/process-instances/';
|
let path = '/process-instances/';
|
||||||
if (result.uri_type === 'for-me') {
|
if (result.uri_type === 'for-me') {
|
||||||
path += 'for-me/';
|
path += 'for-me/';
|
||||||
}
|
}
|
||||||
|
@ -23,11 +23,11 @@ export default function ProcessInstanceReportEdit() {
|
|||||||
const [filterBy, setFilterBy] = useState('');
|
const [filterBy, setFilterBy] = useState('');
|
||||||
|
|
||||||
const navigateToProcessInstanceReport = (_result: any) => {
|
const navigateToProcessInstanceReport = (_result: any) => {
|
||||||
navigate(`/admin/process-instances/reports/${params.report_identifier}`);
|
navigate(`/process-instances/reports/${params.report_identifier}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const navigateToProcessInstanceReports = (_result: any) => {
|
const navigateToProcessInstanceReports = (_result: any) => {
|
||||||
navigate(`/admin/process-instances/reports`);
|
navigate(`/process-instances/reports`);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -31,7 +31,7 @@ export default function ProcessInstanceReportList() {
|
|||||||
return (
|
return (
|
||||||
<tr key={(row as any).id}>
|
<tr key={(row as any).id}>
|
||||||
<td>
|
<td>
|
||||||
<Link to={`/admin/process-instances?report_id=${rowToUse.id}`}>
|
<Link to={`/process-instances?report_id=${rowToUse.id}`}>
|
||||||
{rowToUse.identifier}
|
{rowToUse.identifier}
|
||||||
</Link>
|
</Link>
|
||||||
</td>
|
</td>
|
||||||
@ -54,7 +54,7 @@ export default function ProcessInstanceReportList() {
|
|||||||
<>
|
<>
|
||||||
<h1>Process Instance Perspectives</h1>
|
<h1>Process Instance Perspectives</h1>
|
||||||
<Can I="POST" a={targetUris.processInstanceListPath} ability={ability}>
|
<Can I="POST" a={targetUris.processInstanceListPath} ability={ability}>
|
||||||
<Button href="/admin/process-instances/reports/new">
|
<Button href="/process-instances/reports/new">
|
||||||
Add a process instance perspective
|
Add a process instance perspective
|
||||||
</Button>
|
</Button>
|
||||||
</Can>
|
</Can>
|
||||||
|
@ -12,7 +12,7 @@ export default function ProcessInstanceReportNew() {
|
|||||||
const [filterBy, setFilterBy] = useState('');
|
const [filterBy, setFilterBy] = useState('');
|
||||||
|
|
||||||
const navigateToNewProcessInstance = (_result: any) => {
|
const navigateToNewProcessInstance = (_result: any) => {
|
||||||
navigate(`/admin/process-instances/reports/${identifier}`);
|
navigate(`/process-instances/reports/${identifier}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const addProcessInstanceReport = (event: any) => {
|
const addProcessInstanceReport = (event: any) => {
|
||||||
|
49
spiffworkflow-frontend/src/routes/ProcessInstanceRoutes.tsx
Normal file
49
spiffworkflow-frontend/src/routes/ProcessInstanceRoutes.tsx
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import { Route, Routes } from 'react-router-dom';
|
||||||
|
import ProcessInstanceList from './ProcessInstanceList';
|
||||||
|
import ProcessInstanceShow from './ProcessInstanceShow';
|
||||||
|
import ProcessInstanceReportList from './ProcessInstanceReportList';
|
||||||
|
import ProcessInstanceReportNew from './ProcessInstanceReportNew';
|
||||||
|
import ProcessInstanceReportEdit from './ProcessInstanceReportEdit';
|
||||||
|
import ProcessInstanceFindById from './ProcessInstanceFindById';
|
||||||
|
import ProcessInterstitialPage from './ProcessInterstitialPage';
|
||||||
|
|
||||||
|
export default function ProcessInstanceRoutes() {
|
||||||
|
return (
|
||||||
|
<Routes>
|
||||||
|
<Route path="/" element={<ProcessInstanceList variant="for-me" />} />
|
||||||
|
<Route path="for-me" element={<ProcessInstanceList variant="for-me" />} />
|
||||||
|
<Route path="all" element={<ProcessInstanceList variant="all" />} />
|
||||||
|
<Route
|
||||||
|
path="for-me/:process_model_id/:process_instance_id"
|
||||||
|
element={<ProcessInstanceShow variant="for-me" />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="for-me/:process_model_id/:process_instance_id/:to_task_guid"
|
||||||
|
element={<ProcessInstanceShow variant="for-me" />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="for-me/:process_model_id/:process_instance_id/interstitial"
|
||||||
|
element={<ProcessInterstitialPage variant="for-me" />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path=":process_model_id/:process_instance_id/interstitial"
|
||||||
|
element={<ProcessInterstitialPage variant="all" />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path=":process_model_id/:process_instance_id"
|
||||||
|
element={<ProcessInstanceShow variant="all" />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path=":process_model_id/:process_instance_id/:to_task_guid"
|
||||||
|
element={<ProcessInstanceShow variant="all" />}
|
||||||
|
/>
|
||||||
|
<Route path="reports" element={<ProcessInstanceReportList />} />
|
||||||
|
<Route path="reports/new" element={<ProcessInstanceReportNew />} />
|
||||||
|
<Route
|
||||||
|
path="reports/:report_identifier/edit"
|
||||||
|
element={<ProcessInstanceReportEdit />}
|
||||||
|
/>
|
||||||
|
<Route path="find-by-id" element={<ProcessInstanceFindById />} />
|
||||||
|
</Routes>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
|
import { modifyProcessIdentifierForPathParam } from '../helpers';
|
||||||
|
import HttpService from '../services/HttpService';
|
||||||
|
import { ProcessInstance } from '../interfaces';
|
||||||
|
|
||||||
|
export default function ProcessInstanceShortLink() {
|
||||||
|
const params = useParams();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleProcessInstanceNavigation = (result: any) => {
|
||||||
|
const processInstance: ProcessInstance = result.process_instance;
|
||||||
|
let path = '/process-instances/';
|
||||||
|
if (result.uri_type === 'for-me') {
|
||||||
|
path += 'for-me/';
|
||||||
|
}
|
||||||
|
path += `${modifyProcessIdentifierForPathParam(
|
||||||
|
processInstance.process_model_identifier
|
||||||
|
)}/${processInstance.id}`;
|
||||||
|
navigate(path);
|
||||||
|
};
|
||||||
|
|
||||||
|
HttpService.makeCallToBackend({
|
||||||
|
path: `/process-instances/find-by-id/${params.process_instance_id}`,
|
||||||
|
successCallback: handleProcessInstanceNavigation,
|
||||||
|
});
|
||||||
|
}, [params.process_instance_id, navigate]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
@ -21,6 +21,7 @@ import {
|
|||||||
StopOutline,
|
StopOutline,
|
||||||
TrashCan,
|
TrashCan,
|
||||||
Warning,
|
Warning,
|
||||||
|
Link as LinkIcon,
|
||||||
} from '@carbon/icons-react';
|
} from '@carbon/icons-react';
|
||||||
import {
|
import {
|
||||||
Accordion,
|
Accordion,
|
||||||
@ -117,6 +118,8 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||||||
>(null);
|
>(null);
|
||||||
|
|
||||||
const [selectedTabIndex, setSelectedTabIndex] = useState<number>(0);
|
const [selectedTabIndex, setSelectedTabIndex] = useState<number>(0);
|
||||||
|
const [copiedShortLinkToClipboard, setCopiedShortLinkToClipboard] =
|
||||||
|
useState<boolean>(false);
|
||||||
|
|
||||||
const { addError, removeError } = useAPIError();
|
const { addError, removeError } = useAPIError();
|
||||||
const unModifiedProcessModelId = unModifyProcessIdentifierForPathParam(
|
const unModifiedProcessModelId = unModifyProcessIdentifierForPathParam(
|
||||||
@ -151,12 +154,12 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||||||
|
|
||||||
const navigateToProcessInstances = (_result: any) => {
|
const navigateToProcessInstances = (_result: any) => {
|
||||||
navigate(
|
navigate(
|
||||||
`/admin/process-instances?process_model_identifier=${unModifiedProcessModelId}`
|
`/process-instances?process_model_identifier=${unModifiedProcessModelId}`
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
let processInstanceShowPageBaseUrl = `/admin/process-instances/for-me/${params.process_model_id}/${params.process_instance_id}`;
|
let processInstanceShowPageBaseUrl = `/process-instances/for-me/${params.process_model_id}/${params.process_instance_id}`;
|
||||||
const processInstanceShowPageBaseUrlAllVariant = `/admin/process-instances/${params.process_model_id}/${params.process_instance_id}`;
|
const processInstanceShowPageBaseUrlAllVariant = `/process-instances/${params.process_model_id}/${params.process_instance_id}`;
|
||||||
if (variant === 'all') {
|
if (variant === 'all') {
|
||||||
processInstanceShowPageBaseUrl = processInstanceShowPageBaseUrlAllVariant;
|
processInstanceShowPageBaseUrl = processInstanceShowPageBaseUrlAllVariant;
|
||||||
}
|
}
|
||||||
@ -427,7 +430,7 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||||||
<dd>
|
<dd>
|
||||||
<Link
|
<Link
|
||||||
data-qa="go-to-current-diagram-process-model"
|
data-qa="go-to-current-diagram-process-model"
|
||||||
to={`/admin/process-models/${modifyProcessIdentifierForPathParam(
|
to={`/process-models/${modifyProcessIdentifierForPathParam(
|
||||||
processInstance.process_model_with_diagram_identifier || ''
|
processInstance.process_model_with_diagram_identifier || ''
|
||||||
)}`}
|
)}`}
|
||||||
>
|
>
|
||||||
@ -475,6 +478,14 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const copyProcessInstanceShortLink = () => {
|
||||||
|
if (processInstance) {
|
||||||
|
const piShortLink = `${window.location.origin}/i/${processInstance.id}`;
|
||||||
|
navigator.clipboard.writeText(piShortLink);
|
||||||
|
setCopiedShortLinkToClipboard(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const terminateButton = () => {
|
const terminateButton = () => {
|
||||||
if (
|
if (
|
||||||
processInstance &&
|
processInstance &&
|
||||||
@ -518,6 +529,19 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||||||
return <div />;
|
return <div />;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const copyProcessInstanceShortLinkButton = () => {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
onClick={copyProcessInstanceShortLink}
|
||||||
|
kind="ghost"
|
||||||
|
renderIcon={LinkIcon}
|
||||||
|
iconDescription="Copy short link for sharing"
|
||||||
|
hasIconOnly
|
||||||
|
size="lg"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const resumeButton = () => {
|
const resumeButton = () => {
|
||||||
if (processInstance && processInstance.status === 'suspended') {
|
if (processInstance && processInstance.status === 'suspended') {
|
||||||
return (
|
return (
|
||||||
@ -1314,6 +1338,7 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const elements = [];
|
const elements = [];
|
||||||
|
elements.push(copyProcessInstanceShortLinkButton());
|
||||||
if (ability.can('POST', `${targetUris.processInstanceTerminatePath}`)) {
|
if (ability.can('POST', `${targetUris.processInstanceTerminatePath}`)) {
|
||||||
elements.push(terminateButton());
|
elements.push(terminateButton());
|
||||||
}
|
}
|
||||||
@ -1326,6 +1351,20 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||||||
if (ability.can('DELETE', targetUris.processInstanceActionPath)) {
|
if (ability.can('DELETE', targetUris.processInstanceActionPath)) {
|
||||||
elements.push(deleteButton());
|
elements.push(deleteButton());
|
||||||
}
|
}
|
||||||
|
let toast = null;
|
||||||
|
if (copiedShortLinkToClipboard) {
|
||||||
|
toast = (
|
||||||
|
<Notification
|
||||||
|
onClose={() => setCopiedShortLinkToClipboard(false)}
|
||||||
|
type="success"
|
||||||
|
title="Copied link to clipboard"
|
||||||
|
timeout={3000}
|
||||||
|
hideCloseButton
|
||||||
|
withBottomMargin={false}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
elements.push(toast);
|
||||||
|
}
|
||||||
return elements;
|
return elements;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,9 +10,9 @@ type OwnProps = {
|
|||||||
|
|
||||||
export default function ProcessInterstitialPage({ variant }: OwnProps) {
|
export default function ProcessInterstitialPage({ variant }: OwnProps) {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
let processInstanceShowPageUrl = `/admin/process-instances/for-me/${params.process_model_id}/${params.process_instance_id}`;
|
let processInstanceShowPageUrl = `/process-instances/for-me/${params.process_model_id}/${params.process_instance_id}`;
|
||||||
if (variant === 'all') {
|
if (variant === 'all') {
|
||||||
processInstanceShowPageUrl = `/admin/process-instances/${params.process_model_id}/${params.process_instance_id}`;
|
processInstanceShowPageUrl = `/process-instances/${params.process_model_id}/${params.process_instance_id}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -266,7 +266,7 @@ export default function ProcessModelEditDiagram() {
|
|||||||
const httpMethod = 'DELETE';
|
const httpMethod = 'DELETE';
|
||||||
|
|
||||||
const navigateToProcessModelShow = (_httpResult: any) => {
|
const navigateToProcessModelShow = (_httpResult: any) => {
|
||||||
navigate(`/admin/process-models/${modifiedProcessModelId}`);
|
navigate(`/process-models/${modifiedProcessModelId}`);
|
||||||
};
|
};
|
||||||
HttpService.makeCallToBackend({
|
HttpService.makeCallToBackend({
|
||||||
path: url,
|
path: url,
|
||||||
|
@ -20,7 +20,7 @@ export default function ProcessModelNewExperimental() {
|
|||||||
if ('id' in result) {
|
if ('id' in result) {
|
||||||
const modifiedProcessModelPathFromResult =
|
const modifiedProcessModelPathFromResult =
|
||||||
modifyProcessIdentifierForPathParam(result.id);
|
modifyProcessIdentifierForPathParam(result.id);
|
||||||
navigate(`/admin/process-models/${modifiedProcessModelPathFromResult}`);
|
navigate(`/process-models/${modifiedProcessModelPathFromResult}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
30
spiffworkflow-frontend/src/routes/ProcessModelRoutes.tsx
Normal file
30
spiffworkflow-frontend/src/routes/ProcessModelRoutes.tsx
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { Route, Routes } from 'react-router-dom';
|
||||||
|
import JsonSchemaFormBuilder from './JsonSchemaFormBuilder';
|
||||||
|
import ProcessModelEdit from './ProcessModelEdit';
|
||||||
|
import ProcessModelNew from './ProcessModelNew';
|
||||||
|
import ProcessModelNewExperimental from './ProcessModelNewExperimental';
|
||||||
|
import ProcessModelShow from './ProcessModelShow';
|
||||||
|
import ReactFormEditor from './ReactFormEditor';
|
||||||
|
|
||||||
|
export default function ProcessModelRoutes() {
|
||||||
|
return (
|
||||||
|
<Routes>
|
||||||
|
<Route path=":process_group_id/new" element={<ProcessModelNew />} />
|
||||||
|
<Route
|
||||||
|
path=":process_group_id/new-e"
|
||||||
|
element={<ProcessModelNewExperimental />}
|
||||||
|
/>
|
||||||
|
<Route path=":process_model_id" element={<ProcessModelShow />} />
|
||||||
|
<Route path=":process_model_id/edit" element={<ProcessModelEdit />} />
|
||||||
|
<Route path=":process_model_id/form" element={<ReactFormEditor />} />
|
||||||
|
<Route
|
||||||
|
path=":process_model_id/form/:file_name"
|
||||||
|
element={<ReactFormEditor />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path=":process_model_id/form-builder"
|
||||||
|
element={<JsonSchemaFormBuilder />}
|
||||||
|
/>
|
||||||
|
</Routes>
|
||||||
|
);
|
||||||
|
}
|
@ -128,7 +128,7 @@ export default function ProcessModelShow() {
|
|||||||
onClose={() => setProcessInstance(null)}
|
onClose={() => setProcessInstance(null)}
|
||||||
>
|
>
|
||||||
<Link
|
<Link
|
||||||
to={`/admin/process-instances/for-me/${modifiedProcessModelId}/${processInstance.id}`}
|
to={`/process-instances/for-me/${modifiedProcessModelId}/${processInstance.id}`}
|
||||||
data-qa="process-instance-show-link"
|
data-qa="process-instance-show-link"
|
||||||
>
|
>
|
||||||
view
|
view
|
||||||
@ -211,7 +211,7 @@ export default function ProcessModelShow() {
|
|||||||
return `/editor/process-models/${modifiedProcessModelId}/files/${processModelFile.name}`;
|
return `/editor/process-models/${modifiedProcessModelId}/files/${processModelFile.name}`;
|
||||||
}
|
}
|
||||||
if (processModelFile.name.match(/\.(json|md)$/)) {
|
if (processModelFile.name.match(/\.(json|md)$/)) {
|
||||||
return `/admin/process-models/${modifiedProcessModelId}/form/${processModelFile.name}`;
|
return `/process-models/${modifiedProcessModelId}/form/${processModelFile.name}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -219,9 +219,7 @@ export default function ProcessModelShow() {
|
|||||||
|
|
||||||
const navigateToProcessModels = (_result: any) => {
|
const navigateToProcessModels = (_result: any) => {
|
||||||
navigate(
|
navigate(
|
||||||
`/admin/process-groups/${getGroupFromModifiedModelId(
|
`/process-groups/${getGroupFromModifiedModelId(modifiedProcessModelId)}`
|
||||||
modifiedProcessModelId
|
|
||||||
)}`
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -561,11 +559,11 @@ export default function ProcessModelShow() {
|
|||||||
);
|
);
|
||||||
} else if (a.selectedItem.text === 'New JSON File') {
|
} else if (a.selectedItem.text === 'New JSON File') {
|
||||||
navigate(
|
navigate(
|
||||||
`/admin/process-models/${modifiedProcessModelId}/form?file_ext=json`
|
`/process-models/${modifiedProcessModelId}/form?file_ext=json`
|
||||||
);
|
);
|
||||||
} else if (a.selectedItem.text === 'New Markdown File') {
|
} else if (a.selectedItem.text === 'New Markdown File') {
|
||||||
navigate(
|
navigate(
|
||||||
`/admin/process-models/${modifiedProcessModelId}/form?file_ext=md`
|
`/process-models/${modifiedProcessModelId}/form?file_ext=md`
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
console.log('a.selectedItem.text', a.selectedItem.text);
|
console.log('a.selectedItem.text', a.selectedItem.text);
|
||||||
@ -760,7 +758,7 @@ export default function ProcessModelShow() {
|
|||||||
renderIcon={Edit}
|
renderIcon={Edit}
|
||||||
iconDescription="Edit Process Model"
|
iconDescription="Edit Process Model"
|
||||||
hasIconOnly
|
hasIconOnly
|
||||||
href={`/admin/process-models/${modifiedProcessModelId}/edit`}
|
href={`/process-models/${modifiedProcessModelId}/edit`}
|
||||||
/>
|
/>
|
||||||
</Can>
|
</Can>
|
||||||
<Can I="DELETE" a={targetUris.processModelShowPath} ability={ability}>
|
<Can I="DELETE" a={targetUris.processModelShowPath} ability={ability}>
|
||||||
|
@ -111,7 +111,7 @@ export default function ReactFormEditor() {
|
|||||||
const fileNameWithExtension =
|
const fileNameWithExtension =
|
||||||
defaultFileName ?? `${newFileName}.${fileExtension}`;
|
defaultFileName ?? `${newFileName}.${fileExtension}`;
|
||||||
navigate(
|
navigate(
|
||||||
`/admin/process-models/${modifiedProcessModelId}/form/${fileNameWithExtension}`
|
`/process-models/${modifiedProcessModelId}/form/${fileNameWithExtension}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -160,7 +160,7 @@ export default function ReactFormEditor() {
|
|||||||
const httpMethod = 'DELETE';
|
const httpMethod = 'DELETE';
|
||||||
|
|
||||||
const navigateToProcessModelShow = (_httpResult: any) => {
|
const navigateToProcessModelShow = (_httpResult: any) => {
|
||||||
navigate(`/admin/process-models/${modifiedProcessModelId}`);
|
navigate(`/process-models/${modifiedProcessModelId}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpService.makeCallToBackend({
|
HttpService.makeCallToBackend({
|
||||||
@ -308,7 +308,7 @@ export default function ReactFormEditor() {
|
|||||||
<Button
|
<Button
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
navigate(
|
navigate(
|
||||||
`/admin/process-models/${params.process_model_id}/form-builder${formBuildFileParam}`
|
`/process-models/${params.process_model_id}/form-builder${formBuildFileParam}`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
variant="danger"
|
variant="danger"
|
||||||
|
@ -36,7 +36,7 @@ export default function SecretList() {
|
|||||||
!ability.can('GET', targetUris.secretListPath) &&
|
!ability.can('GET', targetUris.secretListPath) &&
|
||||||
ability.can('GET', targetUris.authenticationListPath)
|
ability.can('GET', targetUris.authenticationListPath)
|
||||||
) {
|
) {
|
||||||
navigate('/admin/configuration/authentications');
|
navigate('/configuration/authentications');
|
||||||
} else {
|
} else {
|
||||||
const { page, perPage } = getPageInfoFromSearchParams(searchParams);
|
const { page, perPage } = getPageInfoFromSearchParams(searchParams);
|
||||||
HttpService.makeCallToBackend({
|
HttpService.makeCallToBackend({
|
||||||
@ -71,12 +71,12 @@ export default function SecretList() {
|
|||||||
return (
|
return (
|
||||||
<tr key={(row as any).key}>
|
<tr key={(row as any).key}>
|
||||||
<td>
|
<td>
|
||||||
<Link to={`/admin/configuration/secrets/${(row as any).key}`}>
|
<Link to={`/configuration/secrets/${(row as any).key}`}>
|
||||||
{(row as any).id}
|
{(row as any).id}
|
||||||
</Link>
|
</Link>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<Link to={`/admin/configuration/secrets/${(row as any).key}`}>
|
<Link to={`/configuration/secrets/${(row as any).key}`}>
|
||||||
{(row as any).key}
|
{(row as any).key}
|
||||||
</Link>
|
</Link>
|
||||||
</td>
|
</td>
|
||||||
@ -125,7 +125,7 @@ export default function SecretList() {
|
|||||||
<div>
|
<div>
|
||||||
<h1>Secrets</h1>
|
<h1>Secrets</h1>
|
||||||
{SecretsDisplayArea()}
|
{SecretsDisplayArea()}
|
||||||
<Button href="/admin/configuration/secrets/new">Add a secret</Button>
|
<Button href="/configuration/secrets/new">Add a secret</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -11,11 +11,11 @@ export default function SecretNew() {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const navigateToSecret = (_result: any) => {
|
const navigateToSecret = (_result: any) => {
|
||||||
navigate(`/admin/configuration/secrets/${key}`);
|
navigate(`/configuration/secrets/${key}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const navigateToSecrets = () => {
|
const navigateToSecrets = () => {
|
||||||
navigate(`/admin/configuration/secrets`);
|
navigate(`/configuration/secrets`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const addSecret = (event: any) => {
|
const addSecret = (event: any) => {
|
||||||
|
@ -46,7 +46,7 @@ export default function SecretShow() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const navigateToSecrets = (_result: any) => {
|
const navigateToSecrets = (_result: any) => {
|
||||||
navigate(`/admin/configuration/secrets`);
|
navigate(`/configuration/secrets`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteSecret = () => {
|
const deleteSecret = () => {
|
||||||
|
@ -54,7 +54,7 @@ export default function TaskShow() {
|
|||||||
setGuestConfirmationText('Thank you!');
|
setGuestConfirmationText('Thank you!');
|
||||||
} else {
|
} else {
|
||||||
navigate(
|
navigate(
|
||||||
`/admin/process-instances/for-me/${modifyProcessIdentifierForPathParam(
|
`/process-instances/for-me/${modifyProcessIdentifierForPathParam(
|
||||||
myTask.process_model_identifier
|
myTask.process_model_identifier
|
||||||
)}/${myTask.process_instance_id}/interstitial`
|
)}/${myTask.process_instance_id}/interstitial`
|
||||||
);
|
);
|
||||||
@ -378,7 +378,7 @@ export default function TaskShow() {
|
|||||||
hotCrumbs={[
|
hotCrumbs={[
|
||||||
[
|
[
|
||||||
`Process Instance Id: ${params.process_instance_id}`,
|
`Process Instance Id: ${params.process_instance_id}`,
|
||||||
`/admin/process-instances/for-me/${modifyProcessIdentifierForPathParam(
|
`/process-instances/for-me/${modifyProcessIdentifierForPathParam(
|
||||||
basicTask.process_model_identifier
|
basicTask.process_model_identifier
|
||||||
)}/${params.process_instance_id}`,
|
)}/${params.process_instance_id}`,
|
||||||
],
|
],
|
||||||
|
@ -115,10 +115,6 @@ const loginIfNeeded = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const hasRole = (_roles: string[]): boolean => {
|
|
||||||
return isLoggedIn();
|
|
||||||
};
|
|
||||||
|
|
||||||
const UserService = {
|
const UserService = {
|
||||||
authenticationDisabled,
|
authenticationDisabled,
|
||||||
doLogin,
|
doLogin,
|
||||||
@ -126,7 +122,6 @@ const UserService = {
|
|||||||
getAccessToken,
|
getAccessToken,
|
||||||
getPreferredUsername,
|
getPreferredUsername,
|
||||||
getUserEmail,
|
getUserEmail,
|
||||||
hasRole,
|
|
||||||
isLoggedIn,
|
isLoggedIn,
|
||||||
loginIfNeeded,
|
loginIfNeeded,
|
||||||
onlyGuestTaskCompletion,
|
onlyGuestTaskCompletion,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user