Skip to content

Commit

Permalink
Merge branch 'main' of github.com:PROCEED-Labs/proceed into ms2/xml-e…
Browse files Browse the repository at this point in the history
…ditor-improvements
  • Loading branch information
jjoderis committed Nov 16, 2023
2 parents 66eaee6 + c519254 commit ebaf7c7
Show file tree
Hide file tree
Showing 17 changed files with 223 additions and 113 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,12 @@ _Server version:_ If successful, this automatically starts a Chrome/Chromium bro
**Authentication & Authorization**

Wether you start the API with `yarn dev-ms-api` or `yarn dev-ms-api-auth0` you can log in with two default users just by typing their name in the 'Sign in with Development Users' section:
When you start the API with `yarn dev-ms-api`, you can log in with two default users just by typing their name in the 'Sign in with Development Users' section:

- Admin: With the username `admin`.
- John Doe: With the username `johndoe`.

If you start the API with `yarn dev-ms-api-auth0`, two users are created on the development Auth0 environment:
Additionaly, if you have set up the environments folder in `src/management-system/src/backend/server/environment-configurations/` and `useAuth0` is set to `true` these two default users are created in the development Auth0 environment.

- Admin: With the username `admin` and the password `ProceedAdm1n!`.
- John Doe: With the username `johndoe` and the password `JohnDoe1!`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const RolesPage: FC = () => {
width: 100,
render: (id: string, role: Role) =>
selectedRowKeys.length === 0 ? (
<AuthCan action="delete" resource={toCaslResource('Role', role) as any}>
<AuthCan action="delete" resource={toCaslResource('Role', role)}>
<Tooltip placement="top" title={'Delete'}>
<Popconfirm
title="Delete User"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const nextAuthOptions: AuthOptions = {
},
};

if (process.env.AUTH0_CLIENT_ID && process.env.AUTH0_CLIENT_SECRET && process.env.AUTH0_ISSUER) {
if (process.env.USE_AUTH0) {
nextAuthOptions.providers.push(
Auth0Provider({
clientId: process.env.AUTH0_CLIENT_ID as string,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { usePostAsset } from '@/lib/fetch-data';
import { createProcess } from '@/lib/helpers/processHelpers';

type ProcessCreationButtonProps = ButtonProps & {
createProcess?: (values: { name: string; description: string }) => any;
createProcess?: (values: { name: string; description?: string }) => any;
wrapperElement?: ReactNode;
};

Expand All @@ -26,7 +26,7 @@ const ProcessCreationButton: React.FC<ProcessCreationButtonProps> = ({
const [isProcessModalOpen, setIsProcessModalOpen] = useState(false);
const { mutateAsync: postProcess } = usePostAsset('/process');

const createNewProcess = async (values: { name: string; description: string }) => {
const createNewProcess = async (values: { name: string; description?: string }) => {
const { metaInfo, bpmn } = await createProcess(values);
try {
await postProcess({
Expand Down
80 changes: 80 additions & 0 deletions src/management-system-v2/components/process-edit-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
'use client';

import React, { ReactNode, useState } from 'react';

import { Button } from 'antd';
import type { ButtonProps } from 'antd';
import ProcessModal from './process-modal';
import { useGetAsset, usePutAsset } from '@/lib/fetch-data';

type ProcessEditButtonProps = ButtonProps & {
definitionId: string;
wrapperElement?: ReactNode;
onEdited?: () => any;
};

/**
* Button to edit Processes including a Modal for updating values. Alternatively, a custom wrapper element can be used instead of a button.
*/
const ProcessEditButton: React.FC<ProcessEditButtonProps> = ({
definitionId,
wrapperElement,
onEdited,
...props
}) => {
const [isProcessModalOpen, setIsProcessModalOpen] = useState(false);
const { data: processData } = useGetAsset('/process/{definitionId}', {
params: { path: { definitionId } },
});

const { mutateAsync: updateProcess } = usePutAsset('/process/{definitionId}');

const editProcess = async (values: { name: string; description?: string }) => {
try {
await updateProcess({
params: { path: { definitionId } },
body: { ...values },
});
onEdited && onEdited();
} catch (err) {
console.log(err);
}
};

return (
<>
{wrapperElement ? (
<div
onClick={() => {
setIsProcessModalOpen(true);
}}
>
{wrapperElement}
</div>
) : (
<Button
{...props}
onClick={() => {
setIsProcessModalOpen(true);
}}
></Button>
)}
<ProcessModal
initialProcessData={{
name: processData?.definitionName,
description: processData?.description,
}}
close={(values) => {
setIsProcessModalOpen(false);

if (values) {
editProcess(values);
}
}}
show={isProcessModalOpen}
></ProcessModal>
</>
);
};

export default ProcessEditButton;
18 changes: 18 additions & 0 deletions src/management-system-v2/components/process-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import React, {
import {
CopyOutlined,
ExportOutlined,
EditOutlined,
DeleteOutlined,
StarOutlined,
EyeOutlined,
Expand All @@ -36,6 +37,9 @@ import Preview from './previewProcess';
import useLastClickedStore from '@/lib/use-last-clicked-process-store';
import classNames from 'classnames';
import { generateDateString } from '@/lib/utils';
import ProcessEditButton from './process-edit-button';
import { AuthCan } from '@/lib/iamComponents';
import { toCaslResource } from '@/lib/ability/caslAbility';
import { ApiData, useDeleteAsset, useInvalidateAsset, usePostAsset } from '@/lib/fetch-data';
import { useUserPreferences } from '@/lib/user-preferences';
import ProcessDeleteSingleModal from './process-delete-single';
Expand Down Expand Up @@ -79,6 +83,7 @@ const ProcessList: FC<ProcessListProps> = ({
}) => {
const router = useRouter();

const invalidateProcesses = useInvalidateAsset('/process');
const refreshData = useInvalidateAsset('/process');

const [previewerOpen, setPreviewerOpen] = useState(false);
Expand Down Expand Up @@ -188,6 +193,19 @@ const ProcessList: FC<ProcessListProps> = ({
}}
/>
</Tooltip>
<AuthCan resource={toCaslResource('Process', record)} action="update">
<ProcessEditButton
definitionId={record.definitionId}
wrapperElement={
<Tooltip placement="top" title={'Edit'}>
<EditOutlined />
</Tooltip>
}
onEdited={() => {
invalidateProcesses();
}}
/>
</AuthCan>
{ability.can('delete', 'Process') && (
<Tooltip placement="top" title={'Delete'}>
<DeleteOutlined
Expand Down
87 changes: 57 additions & 30 deletions src/management-system-v2/components/process-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,77 +4,104 @@ import React, { useState } from 'react';

import { Button, Modal, Form, Input } from 'antd';

import { FormInstance } from 'antd/es/form';

const ModalSubmitButton = ({ form, onSubmit }: { form: FormInstance; onSubmit: Function }) => {
const [submittable, setSubmittable] = useState(false);

// Watch all values
const values = Form.useWatch([], form);

React.useEffect(() => {
form.validateFields({ validateOnly: true }).then(
() => {
setSubmittable(true);
},
() => {
setSubmittable(false);
},
);
}, [form, values]);

const ModalSubmitButton = ({
submittable,
onSubmit,
submitText,
}: {
submittable: boolean;
onSubmit: Function;
submitText: string;
}) => {
return (
<Button
type="primary"
htmlType="submit"
disabled={!submittable}
onClick={() => {
onSubmit(values);
form.resetFields();
onSubmit();
}}
>
Create Process
{submitText}
</Button>
);
};

type ProcessModalProps = {
show: boolean;
close: (values?: { name: string; description: string }) => void;
close: (values?: { name: string; description?: string }) => void;
initialProcessData?: { name?: string; description?: string };
};
const ProcessModal: React.FC<ProcessModalProps> = ({ show, close }) => {
const ProcessModal: React.FC<ProcessModalProps> = ({ show, close, initialProcessData }) => {
const [submittable, setSubmittable] = useState(false);
const [form] = Form.useForm();

// Watch all values
const values = Form.useWatch([], form);

React.useEffect(() => {
form.setFieldsValue(initialProcessData);
}, [form, initialProcessData]);

React.useEffect(() => {
// Only allow to submit in modal if any of the values was changed
const initialFieldValuesModified =
form.isFieldsTouched() &&
(form.getFieldValue('name') !== initialProcessData?.name ||
form.getFieldValue('description') !== initialProcessData?.description);

if (initialFieldValuesModified) {
form.validateFields({ validateOnly: true }).then(
() => {
setSubmittable(true);
},
() => {
setSubmittable(false);
},
);
} else {
setSubmittable(false);
}
}, [form, initialProcessData, values]);

return (
<Modal
title="Create new Process"
title={initialProcessData ? 'Edit Process' : 'Create new Process'}
open={show}
onCancel={() => {
close();
form.resetFields();
}}
footer={[
<Button
key="cancel"
onClick={() => {
close();
form.resetFields();
}}
>
Cancel
</Button>,
<ModalSubmitButton key="submit" form={form} onSubmit={close}></ModalSubmitButton>,
<ModalSubmitButton
key="submit"
submittable={submittable}
onSubmit={() => {
close(values);
form.resetFields();
}}
submitText={initialProcessData ? 'Edit Process' : 'Create Process'}
></ModalSubmitButton>,
]}
>
<Form form={form} name="name" wrapperCol={{ span: 24 }} autoComplete="off">
<Form.Item
name="name"
initialValue={initialProcessData?.name}
rules={[{ required: true, message: 'Please input the Process Name!' }]}
>
<Input placeholder="Process Name" />
</Form.Item>
<Form.Item
name="description"
rules={[{ required: true, message: 'Please input the Process Description!' }]}
>
<Form.Item name="description" initialValue={initialProcessData?.description}>
<Input.TextArea
showCount
maxLength={150}
Expand Down
7 changes: 1 addition & 6 deletions src/management-system-v2/components/processes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,26 @@

import styles from './processes.module.scss';
import React, { FC, useCallback, useEffect, useMemo, useState } from 'react';
import { Input, Space, Button, Col, Row, Tooltip } from 'antd';
import { Space, Button, Tooltip } from 'antd';
import { ApiData, useDeleteAsset, useGetAsset, usePostAsset } from '@/lib/fetch-data';
import {
CopyOutlined,
ExportOutlined,
DeleteOutlined,
UnorderedListOutlined,
AppstoreOutlined,
CloseOutlined,
} from '@ant-design/icons';
import cn from 'classnames';
import Fuse from 'fuse.js';
import IconView from './process-icon-list';
import ProcessList from './process-list';
import { Preferences, getPreferences, addUserPreference } from '@/lib/utils';
import MetaData from './process-info-card';
import { useQueryClient } from '@tanstack/react-query';
import ProcessExportModal from './process-export';
import Bar from './bar';
import { useUserPreferences } from '@/lib/user-preferences';
import { fetchProcessVersionBpmn } from '@/lib/process-queries';
import {
setDefinitionsId,
setDefinitionsName,
manipulateElementsByTagName,
generateDefinitionsId,
setTargetNamespace,
setDefinitionsVersionInformation,
Expand Down
2 changes: 1 addition & 1 deletion src/management-system-v2/components/scrollbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const ScrollBar: FC<ScrollBarType> = ({
setThumbHeight(newThumbHeight);
setScrollPosition(newScrollPosition);
}
}, [reachedEndCallBack, scrolledToTH, threshhold]);
}, [reachedEndCallBack, scrolledToTH, threshold]);

const handleScrollbarClick = useCallback((e: MouseEvent) => {
if (containerRef.current && thumbRef.current) {
Expand Down
2 changes: 1 addition & 1 deletion src/management-system-v2/components/version-toolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ const VersionToolbar: React.FC<VersionToolbarProps> = () => {
setIsConfirmationModalOpen(true);
};

const createNewProcess = async (values: { name: string; description: string }) => {
const createNewProcess = async (values: { name: string; description?: string }) => {
const saveXMLResult = await modeler?.saveXML({ format: true });
if (saveXMLResult?.xml) {
try {
Expand Down
5 changes: 3 additions & 2 deletions src/management-system-v2/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ try {

oauthProvidersConfig = {
NEXTAUTH_SECRET: environmentsContent.nextAuthSecret,
USE_AUTH0: environmentsContent.useAuth0,
AUTH0_CLIENT_ID: environmentsContent.clientID,
AUTH0_CLIENT_SECRET: environmentsContent.clientSecret,
AUTH0_clientCredentialScope: environmentsContent.clientCredentialScope,
Expand All @@ -33,8 +34,8 @@ const nextConfig = {
transpilePackages: ['antd'],
env: {
API_URL:
process.env.NODE_ENV === 'development' ? 'https://localhost:33080/api' : process.env.API_URL,
BACKEND_URL: process.env.NODE_ENV === 'development' ? 'https://localhost:33080' : 'FIXME',
process.env.NODE_ENV === 'development' ? 'http://localhost:33080/api' : process.env.API_URL,
BACKEND_URL: process.env.NODE_ENV === 'development' ? 'http://localhost:33080' : 'FIXME',
NEXT_PUBLIC_USE_AUTH: process.env.USE_AUTHORIZATION === 'true',
NEXTAUTH_SECRET:
process.env.NODE_ENV === 'development'
Expand Down
Loading

0 comments on commit ebaf7c7

Please sign in to comment.