Working on the create activity page
This commit is contained in:
parent
6f328afbf2
commit
156d822cf5
@ -37,6 +37,7 @@
|
||||
"ConfirmEmailResent": "Confirm e-mail resent",
|
||||
"ConfirmPassword": "Confirm Password",
|
||||
"Continuous": "Continuous",
|
||||
"CreateActivity": "Create Activity",
|
||||
"Created": "Created",
|
||||
"CustomField": "Custom Field",
|
||||
"CustomFieldEdited": "Custom Field edited",
|
||||
|
||||
19
src/App.tsx
19
src/App.tsx
@ -46,6 +46,7 @@ import SsoProviderDetails from "./modules/manager/ssoManager/SsoProviderDetails"
|
||||
import { Namespaces } from "./i18n/i18n";
|
||||
import WorkflowTemplateManager from "./modules/manager/workflowTemplates/WorkflowTemplateManager";
|
||||
import WorkflowTemplateDetails from "./modules/manager/workflowTemplates/WorkflowTemplateDetails";
|
||||
import CreateActivity from "./modules/manager/activity/CreateActivity";
|
||||
|
||||
function GetSecureRoutes() {
|
||||
const { t } = useTranslation(Namespaces.Common);
|
||||
@ -84,7 +85,6 @@ function GetSecureRoutes() {
|
||||
</Mainframe>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/specifications/:organisationId/:siteId/add"
|
||||
element={
|
||||
@ -109,7 +109,6 @@ function GetSecureRoutes() {
|
||||
</Mainframe>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/site/:organisationId/add"
|
||||
element={
|
||||
@ -135,7 +134,6 @@ function GetSecureRoutes() {
|
||||
}
|
||||
/>
|
||||
<Route path="/site/" element={<Navigate replace to="/404" />} />
|
||||
|
||||
<Route
|
||||
path="/organisations"
|
||||
element={
|
||||
@ -160,7 +158,6 @@ function GetSecureRoutes() {
|
||||
</Mainframe>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route path="/glossaries/add/" element={<Navigate replace to="/404" />} />
|
||||
<Route
|
||||
path="/glossaries/add/:glossaryId"
|
||||
@ -198,7 +195,6 @@ function GetSecureRoutes() {
|
||||
</Mainframe>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/forms/add"
|
||||
element={
|
||||
@ -223,7 +219,6 @@ function GetSecureRoutes() {
|
||||
</Mainframe>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/customfields/add"
|
||||
element={
|
||||
@ -248,7 +243,6 @@ function GetSecureRoutes() {
|
||||
</Mainframe>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/sequence/add"
|
||||
element={
|
||||
@ -273,7 +267,6 @@ function GetSecureRoutes() {
|
||||
</Mainframe>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/domains/add"
|
||||
element={
|
||||
@ -322,7 +315,6 @@ function GetSecureRoutes() {
|
||||
</Mainframe>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/users/add"
|
||||
element={
|
||||
@ -347,7 +339,6 @@ function GetSecureRoutes() {
|
||||
</Mainframe>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/ssoManager"
|
||||
element={
|
||||
@ -388,6 +379,14 @@ function GetSecureRoutes() {
|
||||
</Mainframe>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/activity/createActivity"
|
||||
element={
|
||||
<Mainframe title={t("CreateActivity")}>
|
||||
<CreateActivity />
|
||||
</Mainframe>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/workflowTemplates"
|
||||
element={
|
||||
|
||||
@ -25,6 +25,7 @@ import Expando from "./expando";
|
||||
import ErrorBlock from "./ErrorBlock";
|
||||
import SsoProviderPicker from "../pickers/SsoProviderPicker";
|
||||
import { FormData, FormError } from "./useForm";
|
||||
import WorkflowTemplatePicker from "../pickers/WorkflowTemplatePicker";
|
||||
|
||||
export const renderButton = (
|
||||
label: string,
|
||||
@ -575,6 +576,28 @@ export const renderTemplatePicker = (
|
||||
);
|
||||
};
|
||||
|
||||
export const renderWorkflowTemplatePicker = (
|
||||
includeLabel: boolean,
|
||||
name: string,
|
||||
label: string,
|
||||
data: FormData,
|
||||
errors: FormError,
|
||||
onChange?: (name: string, value: GeneralIdRef) => void,
|
||||
) => {
|
||||
const templateValue: GeneralIdRef = data[name] as any as GeneralIdRef;
|
||||
|
||||
return (
|
||||
<WorkflowTemplatePicker
|
||||
includeLabel={includeLabel}
|
||||
name={name}
|
||||
label={label}
|
||||
value={templateValue}
|
||||
error={errors[name]}
|
||||
onChange={onChange}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const renderUserPicker = (
|
||||
name: string,
|
||||
label: string,
|
||||
|
||||
@ -87,6 +87,10 @@ interface UseFormReturn {
|
||||
) => void;
|
||||
handleTemplateFormPickerChange: (name: string, value: GeneralIdRef) => void;
|
||||
handleUserPickerChange: (name: string, value: GeneralIdRef) => void;
|
||||
handleWorkflowTemplatePickerChange: (
|
||||
name: string,
|
||||
value: GeneralIdRef,
|
||||
) => void;
|
||||
handleSsoProviderPickerChange: (name: string, value: GeneralIdRef) => void;
|
||||
handleToggleChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
setState: (updates: Partial<FormState>) => void;
|
||||
@ -529,6 +533,17 @@ export const useForm = (initialState: FormState): UseFormReturn => {
|
||||
[state.data, validate, setState],
|
||||
);
|
||||
|
||||
const handleWorkflowTemplatePickerChange = useCallback(
|
||||
(name: string, value: GeneralIdRef) => {
|
||||
const data: FormData = { ...state.data };
|
||||
data[name] = value;
|
||||
const errors = validate(data);
|
||||
|
||||
setState({ data, errors });
|
||||
},
|
||||
[state.data, validate, setState],
|
||||
);
|
||||
|
||||
const handleUserPickerChange = useCallback(
|
||||
(name: string, value: GeneralIdRef) => {
|
||||
const data: FormData = { ...state.data };
|
||||
@ -663,6 +678,7 @@ export const useForm = (initialState: FormState): UseFormReturn => {
|
||||
handleTemplateFormPickerChange,
|
||||
handleUserPickerChange,
|
||||
handleSsoProviderPickerChange,
|
||||
handleWorkflowTemplatePickerChange,
|
||||
handleToggleChange,
|
||||
handleTasksChange,
|
||||
setState,
|
||||
@ -693,6 +709,7 @@ export const useForm = (initialState: FormState): UseFormReturn => {
|
||||
handleTemplateFormPickerChange,
|
||||
handleUserPickerChange,
|
||||
handleSsoProviderPickerChange,
|
||||
handleWorkflowTemplatePickerChange,
|
||||
handleToggleChange,
|
||||
handleTasksChange,
|
||||
setState,
|
||||
|
||||
83
src/components/pickers/WorkflowTemplatePicker.tsx
Normal file
83
src/components/pickers/WorkflowTemplatePicker.tsx
Normal file
@ -0,0 +1,83 @@
|
||||
import React, { useEffect, useState, useCallback } from "react";
|
||||
import Select from "../common/Select";
|
||||
import Option from "../common/option";
|
||||
import { GeneralIdRef, MakeGeneralIdRef } from "../../utils/GeneralIdRef";
|
||||
import templateVersionsService from "../../modules/manager/workflowTemplates/services/WorkflowTemplateService";
|
||||
import ErrorBlock from "../common/ErrorBlock";
|
||||
|
||||
interface WorkflowTemplatePickerProps {
|
||||
includeLabel?: boolean;
|
||||
name: string;
|
||||
label: string;
|
||||
error?: string;
|
||||
value?: GeneralIdRef;
|
||||
onChange?: (name: string, value: GeneralIdRef) => void;
|
||||
}
|
||||
|
||||
export default function WorkflowTemplatePicker({
|
||||
includeLabel,
|
||||
name,
|
||||
label,
|
||||
error,
|
||||
value,
|
||||
onChange,
|
||||
}: WorkflowTemplatePickerProps) {
|
||||
const [options, setOptions] = useState<Option[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
async function load() {
|
||||
const workflowTemplates = await templateVersionsService.getTemplates(
|
||||
0,
|
||||
10,
|
||||
"name",
|
||||
true,
|
||||
);
|
||||
if (workflowTemplates) {
|
||||
const opts: Option[] = (workflowTemplates.data as any[]).map((x) => ({
|
||||
_id: x.id,
|
||||
name: x.workflowName,
|
||||
}));
|
||||
setOptions(opts);
|
||||
}
|
||||
}
|
||||
|
||||
load();
|
||||
}, []);
|
||||
|
||||
const doOnChange = useCallback(
|
||||
(n: string, v: bigint) => {
|
||||
const generalIdRef = MakeGeneralIdRef(v);
|
||||
if (onChange) onChange(n, generalIdRef);
|
||||
},
|
||||
[onChange],
|
||||
);
|
||||
|
||||
const handleChange = useCallback(
|
||||
(e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
const input = e.currentTarget;
|
||||
doOnChange(input.name, BigInt(input.value));
|
||||
},
|
||||
[doOnChange],
|
||||
);
|
||||
|
||||
let id = "";
|
||||
if (value !== undefined && !Number.isNaN(value.id)) {
|
||||
id = String(value.id);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Select
|
||||
includeLabel={includeLabel}
|
||||
name={name}
|
||||
label={label}
|
||||
error={error}
|
||||
value={id}
|
||||
options={options}
|
||||
includeBlankFirstEntry={true}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
<ErrorBlock error={error}></ErrorBlock>
|
||||
</>
|
||||
);
|
||||
}
|
||||
92
src/modules/manager/activity/CreateActivity.tsx
Normal file
92
src/modules/manager/activity/CreateActivity.tsx
Normal file
@ -0,0 +1,92 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Namespaces } from "../../../i18n/i18n";
|
||||
import { useFormWithGuard } from "../../../components/common/useFormRouter";
|
||||
import Joi from "joi";
|
||||
import { useEffect, useState } from "react";
|
||||
import {
|
||||
renderInput,
|
||||
renderWorkflowTemplatePicker,
|
||||
} from "../../../components/common/formHelpers";
|
||||
import { InputType } from "../../../components/common/Input";
|
||||
import templateVersionsService from "../workflowTemplates/services/WorkflowTemplateService";
|
||||
|
||||
const CreateActivity: React.FC = () => {
|
||||
const { t } = useTranslation(Namespaces.Common);
|
||||
const [selectedWorkflowTemplateName, setSelectedWorkflowTemplateName] =
|
||||
useState<string>();
|
||||
|
||||
const form = useFormWithGuard({
|
||||
loaded: true,
|
||||
data: {
|
||||
workflowTemplate: undefined,
|
||||
},
|
||||
errors: {},
|
||||
redirect: "",
|
||||
});
|
||||
|
||||
form.schema = {
|
||||
workflowTemplate: Joi.object().required().label(t("WorkflowTemplate")),
|
||||
activityName: Joi.string().max(450).label(t("ActivityName")),
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const loadData = async () => {
|
||||
form.setState({ loaded: true });
|
||||
};
|
||||
|
||||
loadData();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const workflowTemplate = form.state.data.workflowTemplate as
|
||||
| { id?: bigint }
|
||||
| undefined;
|
||||
|
||||
if (workflowTemplate?.id === undefined || workflowTemplate.id === 0n) {
|
||||
setSelectedWorkflowTemplateName(undefined);
|
||||
return;
|
||||
}
|
||||
|
||||
const loadWorkflowTemplateName = async () => {
|
||||
const templateVersion = await templateVersionsService.getTemplateVersion(
|
||||
workflowTemplate.id!,
|
||||
);
|
||||
setSelectedWorkflowTemplateName(templateVersion?.workflowName);
|
||||
};
|
||||
|
||||
loadWorkflowTemplateName();
|
||||
}, [form.state.data.workflowTemplate]);
|
||||
|
||||
const now = new Date();
|
||||
const datePrefix = `${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, "0")}${String(now.getDate()).padStart(2, "0")} ${String(now.getHours()).padStart(2, "0")}${String(now.getMinutes()).padStart(2, "0")}${String(now.getSeconds()).padStart(2, "0")}`;
|
||||
const defaultActivityName = `${datePrefix} ${selectedWorkflowTemplateName ?? "New Activity"}`;
|
||||
|
||||
return (
|
||||
<form>
|
||||
{renderWorkflowTemplatePicker(
|
||||
true,
|
||||
"workflowTemplate",
|
||||
t("WorkflowTemplate"),
|
||||
form.state.data,
|
||||
form.state.errors,
|
||||
form.handleWorkflowTemplatePickerChange,
|
||||
)}
|
||||
{renderInput(
|
||||
"activityName",
|
||||
t("ActivityName"),
|
||||
form.state.data,
|
||||
form.state.errors,
|
||||
InputType.text,
|
||||
false,
|
||||
"",
|
||||
defaultActivityName,
|
||||
0,
|
||||
true,
|
||||
undefined,
|
||||
form.handleChange,
|
||||
)}
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
export default CreateActivity;
|
||||
@ -126,6 +126,11 @@ const WotkflowTemplateManager: React.FC = () => {
|
||||
{t("Add")}
|
||||
</Button>
|
||||
</Permission>
|
||||
<Permission privilegeKey="CreateActivity">
|
||||
<Button buttonType={ButtonType.primary} to="/activity/createActivity">
|
||||
{t("CreateActivity")}
|
||||
</Button>
|
||||
</Permission>
|
||||
<hr />
|
||||
<WorkflowTemplateManagerTable
|
||||
data={pagedData}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user