diff --git a/src/helper-modules/bpmn-helper/customSchema.json b/src/helper-modules/bpmn-helper/customSchema.json index 4c0d3f732..24eec9dbe 100644 --- a/src/helper-modules/bpmn-helper/customSchema.json +++ b/src/helper-modules/bpmn-helper/customSchema.json @@ -327,11 +327,22 @@ ] }, { - "name": "templateId", + "name": "basedOnTemplateId", "extends": ["bpmn:Definitions"], "properties": [ { - "name": "templateId", + "name": "basedOnTemplateId", + "isAttr": true, + "type": "String" + } + ] + }, + { + "name": "basedOnTemplateVersion", + "extends": ["bpmn:Definitions"], + "properties": [ + { + "name": "basedOnTemplateVersion", "isAttr": true, "type": "String" } diff --git a/src/helper-modules/bpmn-helper/index.d.ts b/src/helper-modules/bpmn-helper/index.d.ts index 453bf272b..23730e566 100644 --- a/src/helper-modules/bpmn-helper/index.d.ts +++ b/src/helper-modules/bpmn-helper/index.d.ts @@ -24,6 +24,8 @@ declare const _exports: { validateCalledProcess(xml: string, processId: string): Promise; setDefinitionsId(bpmn: string | object, id: string): Promise; setDefinitionsName(bpmn: string | object, name: string): Promise; + setDefinitionsTemplateId(bpmn: string | object, id: string): Promise; + setDefinitionsTemplateVersion(bpmn: string | object, id: string): Promise; setDefinitionsVersionInformation( bpmn: string | object, { @@ -168,6 +170,8 @@ declare const _exports: { getIdentifyingInfos(bpmn: string | object): Promise<{ id: string; originalId?: string; + basedOnTemplateId: string; + basedOnTemplateVersion: string; processIds: string[]; name: string; description: string; diff --git a/src/helper-modules/bpmn-helper/src/getters.d.ts b/src/helper-modules/bpmn-helper/src/getters.d.ts index 501926d6c..e1d091c0e 100644 --- a/src/helper-modules/bpmn-helper/src/getters.d.ts +++ b/src/helper-modules/bpmn-helper/src/getters.d.ts @@ -11,6 +11,14 @@ export type DefinitionsInfos = { * - definitions original id */ originalId?: string; + /** + * - definitions template id + */ + basedOnTemplateId?: string; + /** + * - definitions template version + */ + basedOnTemplateVersion?: string; /** * - definitions name */ @@ -221,6 +229,8 @@ export function getDefinitionsName(bpmn: string | object): Promise } object containing the identifying information + * @returns { Promise.<{ id: string, originalId?: string, basedOnTemplateId: string, basedOnTemplateVersion: string, processIds: string[], name: string, description: string }> } object containing the identifying information */ export function getIdentifyingInfos(bpmn: string | object): Promise<{ id: string; originalId?: string; + basedOnTemplateId: string; + basedOnTemplateVersion: string; processIds: string[]; name: string; description: string; diff --git a/src/helper-modules/bpmn-helper/src/getters.js b/src/helper-modules/bpmn-helper/src/getters.js index 744acf01b..144ecff72 100644 --- a/src/helper-modules/bpmn-helper/src/getters.js +++ b/src/helper-modules/bpmn-helper/src/getters.js @@ -49,6 +49,30 @@ async function getOriginalDefinitionsId(bpmn) { return bpmnObj.originalId; } +/** + * Returns the value of the basedOnTemplateId attribute in the given process definition + * the basedOnTemplateId is the id the process has which was used as a template + * + * @param {(string|object)} bpmn - the process definition as XML string or BPMN-Moddle Object + * @returns {(Promise.)} The basedOnTemplateId stored in the definitions field of the given bpmn process + */ +async function getDefinitionsTemplateId(bpmn) { + const bpmnObj = typeof bpmn === 'string' ? await toBpmnObject(bpmn) : bpmn; + return bpmnObj.basedOnTemplateId; +} + +/** + * Returns the value of the basedOnTemplateVersion attribute in the given process definition + * the basedOnTemplateVersion is the id the process version has which was used as a template + * + * @param {(string|object)} bpmn - the process definition as XML string or BPMN-Moddle Object + * @returns {(Promise.)} The basedOnTemplateVersion stored in the definitions field of the given bpmn process + */ +async function getDefinitionsTemplateVersion(bpmn) { + const bpmnObj = typeof bpmn === 'string' ? await toBpmnObject(bpmn) : bpmn; + return bpmnObj.basedOnTemplateVersion; +} + /** * Returns the name of the given bpmn process definition * @@ -129,6 +153,8 @@ function getProcessDocumentationByObject(processObject) { * @type {object} * @property {string} id - definitions id * @property {string} [originalId] - definitions original id + * @property {string} [basedOnTemplateId] - definitions template id + * @property {string} [basedOnTemplateVersion] - definitions template version * @property {string} [name] - definitions name * @property {string} [exporter] - definitions exporter * @property {string} [exporterVersion] - definitions exporterVersion @@ -146,6 +172,8 @@ async function getDefinitionsInfos(bpmn) { return { id: await getDefinitionsId(bpmnObj), originalId: await getOriginalDefinitionsId(bpmnObj), + basedOnTemplateId: await getDefinitionsTemplateId(bpmnObj), + basedOnTemplateVersion: await getDefinitionsTemplateVersion(bpmnObj), name: await getDefinitionsName(bpmnObj), exporter: bpmnObj.exporter, exporterVersion: bpmnObj.exporterVersion, @@ -606,12 +634,13 @@ async function getProcessConstraints(bpmn) { * and its name and description for human identification * * @param {(string|object)} bpmn - the process definition as XML string or BPMN-Moddle Object - * @returns { Promise.<{ id: string, originalId?: string, processIds: string[], name: string, description: string }> } object containing the identifying information + * @returns { Promise.<{ id: string, originalId?: string, basedOnTemplateId: string, basedOnTemplateVersion: string, processIds: string[], name: string, description: string }> } object containing the identifying information */ async function getIdentifyingInfos(bpmn) { const bpmnObj = typeof bpmn === 'string' ? await toBpmnObject(bpmn) : bpmn; - const { id, originalId, name } = await getDefinitionsInfos(bpmnObj); + const { id, originalId, name, basedOnTemplateId, basedOnTemplateVersion } = + await getDefinitionsInfos(bpmnObj); const processes = getElementsByTagName(bpmnObj, 'bpmn:Process'); @@ -624,7 +653,15 @@ async function getIdentifyingInfos(bpmn) { description = ''; } - return { id, originalId, processIds, name, description }; + return { + id, + originalId, + basedOnTemplateId, + basedOnTemplateVersion, + processIds, + name, + description, + }; } /** diff --git a/src/helper-modules/bpmn-helper/src/setters.d.ts b/src/helper-modules/bpmn-helper/src/setters.d.ts index a0f083d83..90086de53 100644 --- a/src/helper-modules/bpmn-helper/src/setters.d.ts +++ b/src/helper-modules/bpmn-helper/src/setters.d.ts @@ -17,6 +17,26 @@ export function setDefinitionsId(bpmn: string | object, id: string): Promise} the modified BPMN process as bpmn-moddle object or XML string based on input */ export function setDefinitionsName(bpmn: string | object, name: string): Promise; +/** + * Sets basedOnTemplateId in definitions element to given id, + * @param {(string|object)} bpmn - the process definition as XML string or BPMN-Moddle Object + * @param {string} id - the id we want to set the definitions element to + * @returns {Promise} the modified BPMN process as bpmn-moddle object or XML string based on input + */ +export function setDefinitionsTemplateId( + bpmn: string | object, + id: string, +): Promise; +/** + * Sets basedOnTemplateId in definitions element to given id, + * @param {(string|object)} bpmn - the process definition as XML string or BPMN-Moddle Object + * @param {string} id - the id we want to set the definitions element to + * @returns {Promise} the modified BPMN process as bpmn-moddle object or XML string based on input + */ +export function setDefinitionsTemplateVersion( + bpmn: string | object, + id: string, +): Promise; /** * Will set a version in the definitions element * diff --git a/src/helper-modules/bpmn-helper/src/setters.js b/src/helper-modules/bpmn-helper/src/setters.js index 29eda2b73..1c553fccc 100644 --- a/src/helper-modules/bpmn-helper/src/setters.js +++ b/src/helper-modules/bpmn-helper/src/setters.js @@ -54,6 +54,30 @@ async function setDefinitionsName(bpmn, name) { }); } +/** + * Sets basedOnTemplateId in definitions element to given id, + * @param {(string|object)} bpmn - the process definition as XML string or BPMN-Moddle Object + * @param {string} id - the id we want to set the definitions element to + * @returns {Promise} the modified BPMN process as bpmn-moddle object or XML string based on input + */ +async function setDefinitionsTemplateId(bpmn, id) { + return await manipulateElementsByTagName(bpmn, 'bpmn:Definitions', (definitions) => { + definitions.basedOnTemplateId = id; + }); +} + +/** + * Sets basedOnTemplateId in definitions element to given id, + * @param {(string|object)} bpmn - the process definition as XML string or BPMN-Moddle Object + * @param {string} id - the id we want to set the definitions element to + * @returns {Promise} the modified BPMN process as bpmn-moddle object or XML string based on input + */ +async function setDefinitionsTemplateVersion(bpmn, id) { + return await manipulateElementsByTagName(bpmn, 'bpmn:Definitions', (definitions) => { + definitions.basedOnTemplateVersion = id; + }); +} + /** * Will set a version in the definitions element * @@ -578,6 +602,8 @@ async function removeColorFromAllElements(bpmn) { module.exports = { setDefinitionsId, setDefinitionsName, + setDefinitionsTemplateId, + setDefinitionsTemplateVersion, setDefinitionsVersionInformation, setProcessId, setTemplateId, diff --git a/src/management-system-v2/app/(auth)/signin/layout.tsx b/src/management-system-v2/app/(auth)/signin/layout.tsx index b80524ca8..2fdf85436 100644 --- a/src/management-system-v2/app/(auth)/signin/layout.tsx +++ b/src/management-system-v2/app/(auth)/signin/layout.tsx @@ -63,6 +63,7 @@ const SigninLayout: FC = ({ children }) => { createdBy: '', lastEditedOn: new Date(), environmentId: '', + category: 'process', }} /> diff --git a/src/management-system-v2/app/(dashboard)/[environmentId]/executions/deployments-modal.tsx b/src/management-system-v2/app/(dashboard)/[environmentId]/executions/deployments-modal.tsx index e58bb4ea9..046d7a184 100644 --- a/src/management-system-v2/app/(dashboard)/[environmentId]/executions/deployments-modal.tsx +++ b/src/management-system-v2/app/(dashboard)/[environmentId]/executions/deployments-modal.tsx @@ -182,6 +182,7 @@ const DeploymentsModal = ({ createdBy: '', lastEditedOn: null, environmentId: '', + category: 'process', }, ...initialProcesses, ]; @@ -234,13 +235,14 @@ const DeploymentsModal = ({ createdBy: '', lastEditedOn: new Date(), environmentId: '', + category: 'process', }, ...folderContents, ]); } else { setProcesses(folderContents); } - setFolder(folder); + setFolder(folder as Folder); }; const dropdownItems: MenuProps['items'] = [ diff --git a/src/management-system-v2/app/(dashboard)/[environmentId]/executions/page.tsx b/src/management-system-v2/app/(dashboard)/[environmentId]/executions/page.tsx index 021503dde..2f04b0ff5 100644 --- a/src/management-system-v2/app/(dashboard)/[environmentId]/executions/page.tsx +++ b/src/management-system-v2/app/(dashboard)/[environmentId]/executions/page.tsx @@ -41,7 +41,7 @@ async function Executions({ environmentId }: { environmentId: string }) { await Promise.all([ getUsersFavourites(), (async () => { - const rootFolder = await getRootFolder(activeEnvironment.spaceId, ability); + const rootFolder = await getRootFolder(activeEnvironment.spaceId, 'process', ability); const folder = await getFolderById(rootFolder.id); const folderContents = await getFolderContents(folder.id, ability); return [folder, folderContents]; diff --git a/src/management-system-v2/app/(dashboard)/[environmentId]/layout.tsx b/src/management-system-v2/app/(dashboard)/[environmentId]/layout.tsx index fdea5c597..04871ce80 100644 --- a/src/management-system-v2/app/(dashboard)/[environmentId]/layout.tsx +++ b/src/management-system-v2/app/(dashboard)/[environmentId]/layout.tsx @@ -75,7 +75,7 @@ const DashboardLayout = async ({ ...children, { key: 'processes-templates', - label: Templates, + label: Templates, icon: , }, ]; diff --git a/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/version-toolbar.tsx b/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/version-toolbar.tsx index efc001c23..63e85233b 100644 --- a/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/version-toolbar.tsx +++ b/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/version-toolbar.tsx @@ -43,6 +43,7 @@ const VersionToolbar = ({ processId }: VersionToolbarProps) => { ...values, originalId: processId as string, originalVersion: selectedVersionId, + type: 'process', }, ], environment.spaceId, diff --git a/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/wrapper.tsx b/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/wrapper.tsx index e705c1748..42cccbabe 100644 --- a/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/wrapper.tsx +++ b/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/wrapper.tsx @@ -140,7 +140,7 @@ const Wrapper = ({ - }> + }> Create new process diff --git a/src/management-system-v2/app/(dashboard)/[environmentId]/processes/folder/[folderId]/page.tsx b/src/management-system-v2/app/(dashboard)/[environmentId]/processes/folder/[folderId]/page.tsx index 5cf71169e..33c39d2e6 100644 --- a/src/management-system-v2/app/(dashboard)/[environmentId]/processes/folder/[folderId]/page.tsx +++ b/src/management-system-v2/app/(dashboard)/[environmentId]/processes/folder/[folderId]/page.tsx @@ -1,4 +1,4 @@ -import Processes from '@/components/processes'; +import Processes, { Template } from '@/components/processes'; import Content from '@/components/content'; import { Button, Space } from 'antd'; import { getCurrentEnvironment } from '@/components/auth'; @@ -16,6 +16,7 @@ import EllipsisBreadcrumb from '@/components/ellipsis-breadcrumb'; import { ComponentProps } from 'react'; import { spaceURL } from '@/lib/utils'; import { getFolderById, getRootFolder, getFolderContents } from '@/lib/data/db/folders'; +import { getReleasedProcessTemplates } from '@/lib/data/db/process'; export type ListItem = ProcessMetadata | (Folder & { type: 'folder' }); const ProcessesPage = async ({ @@ -27,14 +28,17 @@ const ProcessesPage = async ({ const favs = await getUsersFavourites(); - const rootFolder = await getRootFolder(activeEnvironment.spaceId, ability); + const rootFolderProcessPage = await getRootFolder(activeEnvironment.spaceId, 'process', ability); const folder = await getFolderById( - params.folderId ? decodeURIComponent(params.folderId) : rootFolder.id, + params.folderId ? decodeURIComponent(params.folderId) : rootFolderProcessPage.id, ); const folderContents = await getFolderContents(folder.id, ability); + const releasedTemplates = await getReleasedProcessTemplates(activeEnvironment.spaceId, ability); + + //folderContents.push(...templateFolderContents); const pathToFolder: ComponentProps['items'] = []; let currentFolder: Folder | null = folder; do { @@ -66,7 +70,12 @@ const ProcessesPage = async ({ } > - + diff --git a/src/management-system-v2/app/(dashboard)/[environmentId]/projects/page.tsx b/src/management-system-v2/app/(dashboard)/[environmentId]/projects/page.tsx index 894bbd498..42568653e 100644 --- a/src/management-system-v2/app/(dashboard)/[environmentId]/projects/page.tsx +++ b/src/management-system-v2/app/(dashboard)/[environmentId]/projects/page.tsx @@ -23,6 +23,7 @@ const Projects = async ({ params }: { params: { environmentId: string } }) => { createdBy: '', lastEditedOn: new Date(), environmentId: '', + category: 'process', }} /> diff --git a/src/management-system-v2/app/(dashboard)/[environmentId]/templates/_loading.tsx b/src/management-system-v2/app/(dashboard)/[environmentId]/templates/_loading.tsx new file mode 100644 index 000000000..381455e39 --- /dev/null +++ b/src/management-system-v2/app/(dashboard)/[environmentId]/templates/_loading.tsx @@ -0,0 +1,14 @@ +import Content from '@/components/content'; +import { Skeleton, Space } from 'antd'; + +const TemplatesSkeleton = () => { + return ( + + + + + + ); +}; + +export default TemplatesSkeleton; diff --git a/src/management-system-v2/app/(dashboard)/[environmentId]/templates/folder/[folderId]/not-logged-in-fallback.tsx b/src/management-system-v2/app/(dashboard)/[environmentId]/templates/folder/[folderId]/not-logged-in-fallback.tsx new file mode 100644 index 000000000..c7a2e12a2 --- /dev/null +++ b/src/management-system-v2/app/(dashboard)/[environmentId]/templates/folder/[folderId]/not-logged-in-fallback.tsx @@ -0,0 +1,20 @@ +'use client'; + +import { Button, Result } from 'antd'; +import { signIn } from 'next-auth/react'; +import { LoginOutlined } from '@ant-design/icons'; + +const NotLoggedInFallback = () => ( + } onClick={() => signIn()}> + Login + + } + /> +); + +export default NotLoggedInFallback; diff --git a/src/management-system-v2/app/(dashboard)/[environmentId]/templates/folder/[folderId]/page.tsx b/src/management-system-v2/app/(dashboard)/[environmentId]/templates/folder/[folderId]/page.tsx new file mode 100644 index 000000000..265c20235 --- /dev/null +++ b/src/management-system-v2/app/(dashboard)/[environmentId]/templates/folder/[folderId]/page.tsx @@ -0,0 +1,86 @@ +import Processes from '@/components/processes'; +import Content from '@/components/content'; +import { Button, Space } from 'antd'; +import { getCurrentEnvironment } from '@/components/auth'; +// This is a workaround to enable the Server Actions in that file to return any +// client components. This is not possible with the current nextjs compiler +// otherwise. It might be possible in the future with turbopack without this +// import. +import '@/lib/data/processes'; +import { getUsersFavourites } from '@/lib/data/users'; +import { ProcessMetadata } from '@/lib/data/process-schema'; +import { Folder } from '@/lib/data/folder-schema'; +import Link from 'next/link'; +import { LeftOutlined } from '@ant-design/icons'; +import EllipsisBreadcrumb from '@/components/ellipsis-breadcrumb'; +import { ComponentProps } from 'react'; +import { spaceURL } from '@/lib/utils'; +import { getFolderById, getRootFolder, getFolderContents } from '@/lib/data/db/folders'; +export type ListItem = ProcessMetadata | (Folder & { type: 'folder' }); + +const TemplatesPage = async ({ + params, +}: { + params: { environmentId: string; folderId?: string }; +}) => { + const { ability, activeEnvironment } = await getCurrentEnvironment(params.environmentId); + + const favs = await getUsersFavourites(); + + const rootFolder = await getRootFolder(activeEnvironment.spaceId, 'template', ability); + + const folder = await getFolderById( + params.folderId ? decodeURIComponent(params.folderId) : rootFolder.id, + ); + + const folderContents = await getFolderContents(folder.id, ability); + + const templateProcessesAndFolders = folderContents.filter( + (content) => + content.type === 'template' || content.type === 'folder' || content.isTemplate == true, + ); + + const pathToFolder: ComponentProps['items'] = []; + let currentFolder: Folder | null = folder; + do { + pathToFolder.push({ + title: ( + + {currentFolder.parentId ? currentFolder.name : 'Templates'} + + ), + }); + currentFolder = currentFolder.parentId ? await getFolderById(currentFolder.parentId) : null; + } while (currentFolder); + pathToFolder.reverse(); + + return ( + <> + + {folder.parentId && ( + + + + )} + + + } + > + + + + + + ); +}; + +export default TemplatesPage; diff --git a/src/management-system-v2/app/(dashboard)/[environmentId]/templates/page.tsx b/src/management-system-v2/app/(dashboard)/[environmentId]/templates/page.tsx new file mode 100644 index 000000000..3d21c60dc --- /dev/null +++ b/src/management-system-v2/app/(dashboard)/[environmentId]/templates/page.tsx @@ -0,0 +1,3 @@ +import Page from './folder/[folderId]/page'; + +export default Page; diff --git a/src/management-system-v2/app/shared-viewer/workspace-selection.tsx b/src/management-system-v2/app/shared-viewer/workspace-selection.tsx index 17be3b99d..e2caf7251 100644 --- a/src/management-system-v2/app/shared-viewer/workspace-selection.tsx +++ b/src/management-system-v2/app/shared-viewer/workspace-selection.tsx @@ -18,6 +18,8 @@ import { FolderTreeNode, getSpaceFolderTree } from '@/lib/data/folders'; import { useFileManager } from '@/lib/useFileManager'; import { EntityType } from '@/lib/helpers/fileManagerHelpers'; import { useSession } from '@/components/auth-can'; +import { Folder } from '@/lib/data/folder-schema'; +import { Process } from '@/lib/data/process-schema'; type WorkspaceSelectionProps = { processData: Awaited>; @@ -266,6 +268,7 @@ const WorkspaceSelectionModalButton: React.FC = ({ description: processData.description, originalId: processData.id, originalVersion: typeof versionInfo.id === 'number' ? `${versionInfo.id}` : undefined, + type: 'process' as 'template' | 'process', }, ]; diff --git a/src/management-system-v2/app/transfer-processes/server-actions.ts b/src/management-system-v2/app/transfer-processes/server-actions.ts index 4dd9e148c..83435b53c 100644 --- a/src/management-system-v2/app/transfer-processes/server-actions.ts +++ b/src/management-system-v2/app/transfer-processes/server-actions.ts @@ -28,8 +28,8 @@ export async function transferProcesses(referenceToken: string, callbackUrl: str // Processes and folders under root folder of guest space guet their folderId changed to the // root folder of the new owner space, for the rest we just update the environmentId - const userRootFolderId = (await getRootFolder(session.user.id)).id; - const guestRootFolderId = (await getRootFolder(guestId)).id; + const userRootFolderId = (await getRootFolder(session.user.id, 'process')).id; + const guestRootFolderId = (await getRootFolder(guestId, 'process')).id; // no ability check necessary, owners of personal spaces can do anything const guestProcesses = await getProcesses(guestId); diff --git a/src/management-system-v2/components/folder-creation.tsx b/src/management-system-v2/components/folder-creation.tsx index 854a1e85b..33c5c0916 100644 --- a/src/management-system-v2/components/folder-creation.tsx +++ b/src/management-system-v2/components/folder-creation.tsx @@ -10,7 +10,11 @@ import FolderModal from './folder-modal'; import { wrapServerCall } from '@/lib/wrap-server-call'; export const FolderCreationModal: FC< - Partial> & { open: boolean; close: () => void } + Partial> & { + open: boolean; + close: () => void; + type: 'process' | 'template'; + } > = (props) => { const { message } = App.useApp(); const router = useRouter(); @@ -21,7 +25,7 @@ export const FolderCreationModal: FC< const createFolder = (values: FolderUserInput) => { startTransition(async () => { await wrapServerCall({ - fn: async () => serverCreateFolder(values), + fn: async () => serverCreateFolder({ ...values, type: props.type }), onSuccess() { router.refresh(); message.open({ type: 'success', content: 'Folder Created' }); diff --git a/src/management-system-v2/components/process-creation-button.tsx b/src/management-system-v2/components/process-creation-button.tsx index 09f2b6781..bc7f6764f 100644 --- a/src/management-system-v2/components/process-creation-button.tsx +++ b/src/management-system-v2/components/process-creation-button.tsx @@ -12,18 +12,26 @@ export const ProcessCreationModal: React.FC< Partial> & { open: boolean; setOpen: (open: boolean) => void; - customAction?: (values: { name: string; description: string }) => Promise; + templates?: any[]; + customAction?: (values: { + name: string; + description: string; + templateId?: string; + }) => Promise; + type?: 'process' | 'template'; } -> = ({ open, setOpen, customAction, ...props }) => { +> = ({ open, setOpen, customAction, templates = [], type = 'process', ...props }) => { const router = useRouter(); const environment = useEnvironment(); const folderId = useParams<{ folderId: string }>().folderId ?? ''; - const createNewProcess = async (values: { name: string; description: string }[]) => { + const createNewProcess = async ( + values: { name: string; description: string; templateId?: string }[], + ) => { // Invoke the custom handler otherwise use the default server action. const process = await (customAction?.(values[0]) ?? addProcesses( - values.map((value) => ({ ...value, folderId })), + values.map((value) => ({ ...value, folderId, type })), environment.spaceId, ).then((res) => (Array.isArray(res) ? res[0] : res))); @@ -57,20 +65,24 @@ export const ProcessCreationModal: React.FC< return ( setOpen(false)} onSubmit={createNewProcess} + type={type} /> ); }; type ProcessCreationButtonProps = ButtonProps & { + templates?: any[]; customAction?: (values: { name: string; description: string }) => Promise; wrapperElement?: ReactNode; defaultOpen?: boolean; modalProps?: ModalProps; + type?: 'process' | 'template'; }; /** @@ -79,9 +91,11 @@ type ProcessCreationButtonProps = ButtonProps & { */ const ProcessCreationButton: React.FC = ({ wrapperElement, + templates = [], customAction, defaultOpen = false, modalProps, + type, ...props }) => { const [isProcessModalOpen, setIsProcessModalOpen] = useState(defaultOpen); @@ -94,10 +108,12 @@ const ProcessCreationButton: React.FC = ({