@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.
- package/README.md +23 -20
- package/manifest.json +30 -36
- package/package.json +1 -1
- package/src/front-components/docflow-documents.front-component.mjs +35 -35
- package/src/front-components/docflow-documents.front-component.tsx +90 -300
- package/src/front-components/docflow-processes.front-component.mjs +19 -19
- package/src/front-components/docflow-processes.front-component.tsx +43 -12
- package/src/front-components/docflow-tasks.front-component.mjs +20 -20
- package/src/front-components/docflow-tasks.front-component.tsx +24 -4
- package/src/front-components/process-steps.front-component.mjs +18 -18
- package/src/front-components/process-steps.front-component.tsx +4 -3
- package/src/front-components/task-form.front-component.mjs +26 -26
- package/src/logic-functions/capture-file.logic-function.mjs +15 -1
- package/src/logic-functions/launch-parameters-step.logic-function.mjs +1 -1
- package/src/logic-functions/launch-process.logic-function.mjs +1 -0
- package/src/logic-functions/save-launch-fields.logic-function.mjs +33 -2
- package/src/logic-functions/save-launch-fields.logic-function.ts +1 -1
|
@@ -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 [
|
|
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
|
-
//
|
|
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
|
|
176
|
-
|
|
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={() =>
|
|
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={() =>
|
|
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="
|
|
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={
|
|
272
|
+
onRowClick={(workflowVersionId) => setPanel({ kind: 'process', workflowVersionId })}
|
|
242
273
|
rows={processes.map((process) => {
|
|
243
274
|
const parameterCount = process.launchFields.length;
|
|
244
275
|
|