@haiiro/docuflow 0.0.5 → 0.0.7

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.
@@ -12,6 +12,7 @@ import { restAnd, restEq, restIlike, restIn } from 'src/shared/api/rest-filter.u
12
12
  import { DOCFLOW_SECTION } from 'src/shared/docflow.constants';
13
13
  import { type FormField, type FormValues } from 'src/shared/form/form-field.type';
14
14
  import { findMissingRequiredFields } from 'src/shared/form/form-fields.util';
15
+ import { logDocflow, logDocflowError } from 'src/shared/log.util';
15
16
  import {
16
17
  buildLaunchParameters,
17
18
  isLaunchParametersStep,
@@ -22,6 +23,10 @@ import { PROCESSES_FRONT_COMPONENT_UNIVERSAL_IDENTIFIER } from 'src/universal-id
22
23
 
23
24
  const PROCESSES_LIMIT = 200;
24
25
  const SEARCH_DEBOUNCE_MS = 300;
26
+ const DRAFT_WAIT_ATTEMPTS = 10;
27
+ const DRAFT_WAIT_MS = 400;
28
+
29
+ type Panel = { kind: 'closed' } | { kind: 'process'; workflowVersionId: string };
25
30
 
26
31
  type WorkflowRecord = { id: string; name?: string | null; smbLaunchFields?: unknown };
27
32
  type WorkflowVersionRecord = {
@@ -153,18 +158,39 @@ const ProcessLaunchForm = ({
153
158
  );
154
159
  };
155
160
 
161
+ // The server gives a new workflow its first draft version right after the
162
+ // record; the launch step can only be put into an existing draft.
163
+ const waitForDraft = async (workflowId: string) => {
164
+ for (let attempt = 0; attempt < DRAFT_WAIT_ATTEMPTS; attempt++) {
165
+ const { records } = await listRecords<{ id: string }>('workflowVersions', {
166
+ filter: restEq('workflowId', workflowId),
167
+ limit: 1,
168
+ });
169
+
170
+ if (records.length > 0) {
171
+ return;
172
+ }
173
+
174
+ await new Promise((resolve) => setTimeout(resolve, DRAFT_WAIT_MS));
175
+ }
176
+ };
177
+
156
178
  const DocflowProcesses = () => {
157
179
  const theme = useTheme();
158
180
  const [searchInput, setSearchInput] = useState('');
159
181
  const searchQuery = useDebouncedValue(searchInput, SEARCH_DEBOUNCE_MS);
160
- const [selectedVersionId, setSelectedVersionId] = useState<string | undefined>();
182
+ const [panel, setPanel] = useState<Panel>({ kind: 'closed' });
161
183
  const [isCreating, setIsCreating] = useState(false);
162
184
  const { data: processes, loading, error } = useAsync(() => loadProcesses(searchQuery), [searchQuery]);
185
+ const selectedVersionId = panel.kind === 'process' ? panel.workflowVersionId : undefined;
163
186
  const selectedProcess = processes?.find((process) => process.workflowVersionId === selectedVersionId);
164
187
 
165
- // Created in the docflow section, then opened in the standard editor.
188
+ // As "Создать" of the standard list: a process with a manual trigger in the
189
+ // docflow section, opened in the editor. Launch parameters are set later
190
+ // with the process's "Параметры запуска" command.
166
191
  const handleCreate = async () => {
167
192
  setIsCreating(true);
193
+ logDocflow('process: create');
168
194
 
169
195
  try {
170
196
  const workflow = await createRecord<WorkflowRecord>('workflows', {
@@ -172,13 +198,18 @@ const DocflowProcesses = () => {
172
198
  smbSection: DOCFLOW_SECTION,
173
199
  });
174
200
 
175
- if (workflow !== undefined) {
176
- await navigate(AppPath.RecordShowPage, {
177
- objectNameSingular: 'workflow',
178
- objectRecordId: workflow.id,
179
- });
201
+ if (workflow === undefined) {
202
+ throw new Error('процесс создан, но сервер его не вернул');
180
203
  }
204
+
205
+ await waitForDraft(workflow.id);
206
+ await callAppRoute('/docflow/processes/launch-fields', { workflowId: workflow.id, fields: [] });
207
+ await navigate(AppPath.RecordShowPage, {
208
+ objectNameSingular: 'workflow',
209
+ objectRecordId: workflow.id,
210
+ });
181
211
  } catch (createError) {
212
+ logDocflowError('process: create failed', createError);
182
213
  await enqueueSnackbar({
183
214
  message: getErrorMessage(createError, 'Не удалось создать процесс'),
184
215
  variant: 'error',
@@ -192,13 +223,13 @@ const DocflowProcesses = () => {
192
223
  <DocflowRoot>
193
224
  <SplitView
194
225
  panelTitle={selectedProcess?.name}
195
- onClosePanel={() => setSelectedVersionId(undefined)}
226
+ onClosePanel={() => setPanel({ kind: 'closed' })}
196
227
  panel={
197
228
  selectedProcess !== undefined ? (
198
229
  <ProcessLaunchForm
199
230
  key={selectedProcess.workflowVersionId}
200
231
  process={selectedProcess}
201
- onLaunched={() => setSelectedVersionId(undefined)}
232
+ onLaunched={() => setPanel({ kind: 'closed' })}
202
233
  />
203
234
  ) : undefined
204
235
  }
@@ -214,7 +245,7 @@ const DocflowProcesses = () => {
214
245
  />
215
246
  </div>
216
247
  <div style={{ marginLeft: 'auto' }}>
217
- <Button variant="outline" size="sm" loading={isCreating} onClick={() => void handleCreate()}>
248
+ <Button variant="solid" size="sm" loading={isCreating} onClick={() => void handleCreate()}>
218
249
  Создать
219
250
  </Button>
220
251
  </div>
@@ -227,7 +258,7 @@ const DocflowProcesses = () => {
227
258
  {loading && processes === undefined && <Message>Загрузка…</Message>}
228
259
  {!loading && error === undefined && processes?.length === 0 && (
229
260
  <Message>
230
- Процессов для запуска нет. Здесь видны опубликованные процессы с ручным запуском и разделом «Документооборот». Параметры запуска задаются на вкладке процесса «Запуск и задания».
261
+ Процессов для запуска нет. Здесь видны опубликованные процессы с ручным запуском и разделом «Документооборот». Параметры запуска задаются кнопкой «Параметры запуска» вверху процесса.
231
262
  </Message>
232
263
  )}
233
264
  {processes !== undefined && processes.length > 0 && (
@@ -238,7 +269,7 @@ const DocflowProcesses = () => {
238
269
  { key: 'stages', label: 'Этапы' },
239
270
  ]}
240
271
  selectedRowId={selectedVersionId}
241
- onRowClick={setSelectedVersionId}
272
+ onRowClick={(workflowVersionId) => setPanel({ kind: 'process', workflowVersionId })}
242
273
  rows={processes.map((process) => {
243
274
  const parameterCount = process.launchFields.length;
244
275