@haiiro/docuflow 0.0.16 → 0.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/README.md +8 -2
  2. package/manifest.json +34 -19
  3. package/package.json +1 -1
  4. package/public/app/docflow-app.js +5 -5
  5. package/src/front-components/docflow-documents.front-component.mjs +1 -1
  6. package/src/front-components/docflow-processes.front-component.mjs +35 -35
  7. package/src/front-components/docflow-processes.front-component.tsx +187 -85
  8. package/src/front-components/docflow-tasks.front-component.mjs +24 -24
  9. package/src/front-components/launch-process.front-component.mjs +19 -19
  10. package/src/front-components/launch-process.front-component.tsx +36 -60
  11. package/src/front-components/process-steps.front-component.mjs +17 -17
  12. package/src/front-components/task-form.front-component.mjs +10 -10
  13. package/src/logic-functions/bitrix-app.logic-function.mjs +1 -1
  14. package/src/logic-functions/complete-task.logic-function.mjs +39 -8
  15. package/src/logic-functions/docflow-app.logic-function.mjs +1 -1
  16. package/src/logic-functions/hand-out-form-step.logic-function.mjs +71284 -11217
  17. package/src/logic-functions/hand-out-form-step.logic-function.ts +6 -1
  18. package/src/logic-functions/launch-process.logic-function.mjs +269 -33
  19. package/src/logic-functions/launch-process.logic-function.ts +42 -37
  20. package/src/logic-functions/on-task-updated.logic-function.mjs +39 -8
  21. package/src/logic-functions/on-workflow-run-updated.logic-function.mjs +48 -9
  22. package/src/logic-functions/on-workflow-run-updated.logic-function.ts +18 -3
  23. package/src/logic-functions/process-catalog.logic-function.mjs +119726 -0
  24. package/src/logic-functions/process-catalog.logic-function.ts +84 -0
  25. package/src/logic-functions/publish-process.logic-function.mjs +218 -16
  26. package/src/logic-functions/publish-process.logic-function.ts +13 -5
  27. package/src/logic-functions/save-launch-fields.logic-function.mjs +5 -2
  28. package/src/logic-functions/save-step-settings.logic-function.mjs +5 -2
@@ -10,38 +10,24 @@ import {
10
10
  import { IconPlayerPlay } from 'twenty-ui/icon';
11
11
  import { useTheme } from 'twenty-ui/theme';
12
12
 
13
- import { callAppRoute, getErrorMessage, listRecords } from 'src/front/api';
13
+ import { callAppRoute, getErrorMessage } from 'src/front/api';
14
14
  import { useAsync } from 'src/front/hooks/use-async';
15
15
  import { DocflowRoot, Message, pluralize, SectionTitle } from 'src/front/ui/components';
16
16
  import { FormFieldInputs } from 'src/front/ui/form-field-inputs';
17
17
  import { Button, MenuRow } from 'src/front/ui/kit';
18
- import { restAnd, restEq, restIn } from 'src/shared/api/rest-filter.util';
19
- import { DOCFLOW_SECTION, LAUNCH_RECORDS_LIMIT } from 'src/shared/docflow.constants';
18
+ import { LAUNCH_RECORDS_LIMIT } from 'src/shared/docflow.constants';
20
19
  import { type FormField, type FormValues } from 'src/shared/form/form-field.type';
21
20
  import { findMissingRequiredFields } from 'src/shared/form/form-fields.util';
22
21
  import { logDocflowError } from 'src/shared/log.util';
23
- import {
24
- buildLaunchParameters,
25
- isLaunchTrigger,
26
- parseLaunchFields,
27
- parseLaunchObject,
28
- } from 'src/shared/workflow/launch-step.util';
22
+ import { buildLaunchParameters } from 'src/shared/workflow/launch-step.util';
23
+ import { type CatalogProcess } from 'src/shared/workflow/process-catalog.type';
29
24
  import { type WorkflowTrigger } from 'src/shared/workflow/workflow-run.type';
30
25
  import { LAUNCH_PROCESS_FRONT_COMPONENT_UNIVERSAL_IDENTIFIER } from 'src/universal-identifiers';
31
26
 
32
- const PROCESSES_LIMIT = 200;
33
27
  const RECORD_NOUN: [string, string, string] = ['запись', 'записи', 'записей'];
34
28
 
35
- type WorkflowRecord = {
36
- id: string;
37
- name?: string | null;
38
- smbLaunchFields?: unknown;
39
- smbLaunchObject?: string | null;
40
- };
41
- type WorkflowVersionRecord = { id: string; workflowId: string; trigger?: WorkflowTrigger | null };
42
-
43
29
  type LaunchableProcess = {
44
- workflowVersionId: string;
30
+ workflowId: string;
45
31
  name: string;
46
32
  launchFields: FormField[];
47
33
  // Launched on the selected records, or without a record
@@ -56,42 +42,32 @@ const isGlobalManualTrigger = (trigger: WorkflowTrigger | null | undefined) => {
56
42
  };
57
43
 
58
44
  // The published docflow processes this place can launch: on the selected
59
- // records the ones of their object, and everywhere the ones without a record.
45
+ // records the ones of their object, and everywhere the ones without a record
46
+ // (a webhook one, or a manual one offered everywhere).
60
47
  const loadLaunchableProcesses = async (objectName: string | undefined): Promise<LaunchableProcess[]> => {
61
- const { records: workflows } = await listRecords<WorkflowRecord>('workflows', {
62
- filter: restEq('smbSection', DOCFLOW_SECTION),
63
- order_by: 'name[AscNullsLast]',
64
- limit: PROCESSES_LIMIT,
65
- });
66
-
67
- if (workflows.length === 0) {
68
- return [];
69
- }
70
-
71
- const { records: versions } = await listRecords<WorkflowVersionRecord>('workflowVersions', {
72
- filter: restAnd(restEq('status', 'ACTIVE'), restIn('workflowId', workflows.map(({ id }) => id))),
73
- limit: PROCESSES_LIMIT,
48
+ const { processes: catalog } = await callAppRoute<{ processes: CatalogProcess[] }>('/docflow/processes/catalog', {
49
+ action: 'list',
74
50
  });
75
51
 
76
- const processes = workflows.flatMap((workflow): LaunchableProcess[] => {
77
- const active = versions.find((version) => version.workflowId === workflow.id);
78
- const launchObject = isLaunchTrigger(active?.trigger) ? parseLaunchObject(workflow.smbLaunchObject) : undefined;
79
- const isLaunchable =
80
- active !== undefined &&
81
- (isLaunchTrigger(active.trigger) || isGlobalManualTrigger(active.trigger)) &&
82
- (launchObject === undefined || launchObject === objectName);
83
-
84
- return isLaunchable
85
- ? [
86
- {
87
- workflowVersionId: active.id,
88
- name: workflow.name?.trim() || 'Без названия',
89
- launchFields: isLaunchTrigger(active.trigger) ? parseLaunchFields(workflow.smbLaunchFields) : [],
90
- isOnRecords: launchObject !== undefined,
91
- },
92
- ]
93
- : [];
94
- });
52
+ const processes = catalog
53
+ .sort((first, second) => first.name.localeCompare(second.name, 'ru'))
54
+ .flatMap((process): LaunchableProcess[] => {
55
+ const trigger = process.active?.trigger;
56
+ const isLaunchable =
57
+ (trigger?.type === 'WEBHOOK' || isGlobalManualTrigger(trigger)) &&
58
+ (process.launchObject === undefined || process.launchObject === objectName);
59
+
60
+ return isLaunchable
61
+ ? [
62
+ {
63
+ workflowId: process.workflowId,
64
+ name: process.name,
65
+ launchFields: trigger?.type === 'WEBHOOK' ? process.launchFields : [],
66
+ isOnRecords: process.launchObject !== undefined,
67
+ },
68
+ ]
69
+ : [];
70
+ });
95
71
 
96
72
  // The processes of the record come first
97
73
  return [...processes.filter(({ isOnRecords }) => isOnRecords), ...processes.filter(({ isOnRecords }) => !isOnRecords)];
@@ -127,7 +103,7 @@ const LaunchForm = ({
127
103
 
128
104
  try {
129
105
  const { workflowRunIds } = await callAppRoute<{ workflowRunIds: string[] }>('/docflow/processes/launch', {
130
- workflowVersionId: process.workflowVersionId,
106
+ workflowId: process.workflowId,
131
107
  values: parameters,
132
108
  recordIds: launchRecordIds,
133
109
  });
@@ -147,7 +123,7 @@ const LaunchForm = ({
147
123
  resetNavigationStack: true,
148
124
  });
149
125
  } catch (error) {
150
- logDocflowError('launch: failed', error, { workflowVersionId: process.workflowVersionId });
126
+ logDocflowError('launch: failed', error, { workflowId: process.workflowId });
151
127
  setErrorMessage(getErrorMessage(error, 'Не удалось запустить процесс'));
152
128
  setIsLaunching(false);
153
129
  }
@@ -203,13 +179,13 @@ const LaunchProcess = () => {
203
179
  const selectedRecordIds = useSelectedRecordIds();
204
180
  const selectedObject = useSelectedObjectMetadata();
205
181
  const objectName = selectedRecordIds.length > 0 ? selectedObject?.nameSingular : undefined;
206
- const [selectedVersionId, setSelectedVersionId] = useState<string | undefined>();
182
+ const [selectedWorkflowId, setSelectedWorkflowId] = useState<string | undefined>();
207
183
  const { data: processes, error, loading } = useAsync(
208
184
  () => loadLaunchableProcesses(objectName),
209
185
  [objectName],
210
186
  );
211
187
  const onlyProcess = processes?.length === 1 ? processes[0] : undefined;
212
- const selectedProcess = onlyProcess ?? processes?.find(({ workflowVersionId }) => workflowVersionId === selectedVersionId);
188
+ const selectedProcess = onlyProcess ?? processes?.find(({ workflowId }) => workflowId === selectedWorkflowId);
213
189
 
214
190
  return (
215
191
  <DocflowRoot>
@@ -228,17 +204,17 @@ const LaunchProcess = () => {
228
204
  )}
229
205
  {selectedProcess !== undefined ? (
230
206
  <LaunchForm
231
- key={selectedProcess.workflowVersionId}
207
+ key={selectedProcess.workflowId}
232
208
  process={selectedProcess}
233
209
  recordIds={selectedRecordIds}
234
- onBack={onlyProcess === undefined ? () => setSelectedVersionId(undefined) : undefined}
210
+ onBack={onlyProcess === undefined ? () => setSelectedWorkflowId(undefined) : undefined}
235
211
  />
236
212
  ) : (
237
213
  processes !== undefined &&
238
214
  processes.length > 0 && (
239
215
  <div style={{ display: 'flex', flexDirection: 'column', gap: theme.spacing[1] }}>
240
216
  {processes.map((process, index) => (
241
- <div key={process.workflowVersionId}>
217
+ <div key={process.workflowId}>
242
218
  {objectName !== undefined && index === processes.findIndex(({ isOnRecords }) => isOnRecords === process.isOnRecords) && (
243
219
  <SectionTitle>{process.isOnRecords ? 'На выбранной записи' : 'Без записи'}</SectionTitle>
244
220
  )}
@@ -250,7 +226,7 @@ const LaunchProcess = () => {
250
226
  ? `${process.launchFields.length} ${pluralize(process.launchFields.length, ['параметр', 'параметра', 'параметров'])}`
251
227
  : undefined
252
228
  }
253
- onClick={() => setSelectedVersionId(process.workflowVersionId)}
229
+ onClick={() => setSelectedWorkflowId(process.workflowId)}
254
230
  />
255
231
  </div>
256
232
  ))}