@haiiro/docuflow 0.0.11 → 0.0.13
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 +45 -9
- package/manifest.json +117 -16
- package/package.json +6 -3
- package/public/app/docflow-app.css +2 -0
- package/public/app/docflow-app.js +94 -0
- package/src/front-components/docflow-documents.front-component.mjs +42 -42
- package/src/front-components/docflow-documents.front-component.tsx +336 -128
- package/src/front-components/docflow-processes.front-component.mjs +35 -35
- package/src/front-components/docflow-processes.front-component.tsx +527 -131
- package/src/front-components/docflow-tasks.front-component.mjs +46 -41
- package/src/front-components/docflow-tasks.front-component.tsx +489 -132
- package/src/front-components/launch-process.front-component.mjs +75 -0
- package/src/front-components/launch-process.front-component.tsx +270 -0
- package/src/front-components/process-steps.front-component.mjs +25 -25
- package/src/front-components/process-steps.front-component.tsx +55 -10
- package/src/front-components/task-form.front-component.mjs +46 -41
- package/src/logic-functions/bitrix-app.logic-function.mjs +424 -198
- package/src/logic-functions/bitrix-app.logic-function.ts +54 -82
- package/src/logic-functions/bitrix-install.logic-function.mjs +0 -11
- package/src/logic-functions/bitrix-install.logic-function.ts +0 -3
- package/src/logic-functions/capture-file.logic-function.mjs +2 -1
- package/src/logic-functions/docflow-app-session.logic-function.mjs +60043 -0
- package/src/logic-functions/docflow-app-session.logic-function.ts +54 -0
- package/src/logic-functions/docflow-app.logic-function.mjs +60122 -0
- package/src/logic-functions/docflow-app.logic-function.ts +37 -0
- package/src/logic-functions/hand-out-form-step.logic-function.mjs +2 -1
- package/src/logic-functions/launch-process.logic-function.mjs +113 -29
- package/src/logic-functions/launch-process.logic-function.ts +83 -22
- package/src/logic-functions/on-workflow-run-updated.logic-function.mjs +2 -1
- package/src/logic-functions/publish-process.logic-function.mjs +119519 -0
- package/src/logic-functions/publish-process.logic-function.ts +91 -0
- package/src/logic-functions/save-launch-fields.logic-function.mjs +178 -10
- package/src/logic-functions/save-launch-fields.logic-function.ts +24 -6
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { defineLogicFunction } from 'twenty-sdk/define';
|
|
2
|
+
import {
|
|
3
|
+
type LogicFunctionExecutionContext,
|
|
4
|
+
type RoutePayload,
|
|
5
|
+
} from 'twenty-sdk/logic-function';
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
ACTIVATE_WORKFLOW_VERSION_MUTATION,
|
|
9
|
+
callCoreGraphql,
|
|
10
|
+
CoreGraphqlError,
|
|
11
|
+
DEACTIVATE_WORKFLOW_VERSION_MUTATION,
|
|
12
|
+
} from 'src/shared/api/core-graphql.util';
|
|
13
|
+
import { DOCFLOW_SECTION } from 'src/shared/docflow.constants';
|
|
14
|
+
import { jsonResponse, readJsonBody } from 'src/server/http-response';
|
|
15
|
+
import { getWorkflow, listWorkflowVersions } from 'src/server/records';
|
|
16
|
+
import { logDocflow, logDocflowError } from 'src/shared/log.util';
|
|
17
|
+
import { PUBLISH_PROCESS_LOGIC_FUNCTION_UNIVERSAL_IDENTIFIER } from 'src/universal-identifiers';
|
|
18
|
+
|
|
19
|
+
// "Опубликовать" and "Снять с публикации" from the processes page, as the
|
|
20
|
+
// editor's "Активировать" and "Деактивировать": the draft becomes the version
|
|
21
|
+
// people launch, or the published version stops. Done as the person, so the
|
|
22
|
+
// "Workflows" permission decides.
|
|
23
|
+
const handler = async (event: RoutePayload, context: LogicFunctionExecutionContext) => {
|
|
24
|
+
if (context.workspaceMemberId === null) {
|
|
25
|
+
return jsonResponse(401, { message: 'Публиковать процессы может только сотрудник' });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const body = readJsonBody(event.body);
|
|
29
|
+
const workflowId = body.workflowId;
|
|
30
|
+
const isPublish = body.publish === true;
|
|
31
|
+
|
|
32
|
+
if (typeof workflowId !== 'string' || workflowId.length === 0) {
|
|
33
|
+
return jsonResponse(400, { message: 'Не указан процесс' });
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const workflow = await getWorkflow('person', workflowId);
|
|
37
|
+
|
|
38
|
+
if (workflow?.smbSection !== DOCFLOW_SECTION) {
|
|
39
|
+
return jsonResponse(404, { message: 'Процесс документооборота не найден' });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Newest first. A process taken off without a draft since is published
|
|
43
|
+
// again from the version that was taken off.
|
|
44
|
+
const versions = await listWorkflowVersions('person', workflowId);
|
|
45
|
+
const isActive = versions.some(({ status }) => status === 'ACTIVE');
|
|
46
|
+
const version = isPublish
|
|
47
|
+
? (versions.find(({ status }) => status === 'DRAFT') ??
|
|
48
|
+
(isActive ? undefined : versions.find(({ status }) => status === 'DEACTIVATED')))
|
|
49
|
+
: versions.find(({ status }) => status === 'ACTIVE');
|
|
50
|
+
|
|
51
|
+
if (version === undefined) {
|
|
52
|
+
return jsonResponse(409, {
|
|
53
|
+
message: isPublish ? 'Нечего публиковать: изменений после публикации нет' : 'Процесс не опубликован',
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
await callCoreGraphql({
|
|
59
|
+
query: isPublish ? ACTIVATE_WORKFLOW_VERSION_MUTATION : DEACTIVATE_WORKFLOW_VERSION_MUTATION,
|
|
60
|
+
variables: { workflowVersionId: version.id },
|
|
61
|
+
});
|
|
62
|
+
} catch (error) {
|
|
63
|
+
logDocflowError('publish: engine refused', error, { workflowId, isPublish });
|
|
64
|
+
|
|
65
|
+
return jsonResponse(422, {
|
|
66
|
+
message:
|
|
67
|
+
error instanceof CoreGraphqlError && error.userMessage !== undefined
|
|
68
|
+
? error.userMessage
|
|
69
|
+
: isPublish
|
|
70
|
+
? 'Процесс не опубликован: проверьте его шаги в редакторе'
|
|
71
|
+
: 'Не удалось снять процесс с публикации',
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
logDocflow('publish: done', { workflowId, workflowVersionId: version.id, isPublish });
|
|
76
|
+
|
|
77
|
+
return { status: isPublish ? 'PUBLISHED' : 'UNPUBLISHED' };
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export default defineLogicFunction({
|
|
81
|
+
universalIdentifier: PUBLISH_PROCESS_LOGIC_FUNCTION_UNIVERSAL_IDENTIFIER,
|
|
82
|
+
name: 'docflow-publish-process',
|
|
83
|
+
description: 'Публикует процесс документооборота или снимает его с публикации',
|
|
84
|
+
timeoutSeconds: 30,
|
|
85
|
+
handler,
|
|
86
|
+
httpRouteTriggerSettings: {
|
|
87
|
+
path: '/docflow/processes/publish',
|
|
88
|
+
httpMethod: 'POST',
|
|
89
|
+
isAuthRequired: true,
|
|
90
|
+
},
|
|
91
|
+
});
|
|
@@ -1734,6 +1734,66 @@ var CREATE_DRAFT_FROM_WORKFLOW_VERSION_MUTATION = `mutation CreateDraftFromWorkf
|
|
|
1734
1734
|
createDraftFromWorkflowVersion(input: $input) { id }
|
|
1735
1735
|
}`;
|
|
1736
1736
|
|
|
1737
|
+
// src/shared/api/object-summaries.ts
|
|
1738
|
+
import { MetadataApiClient } from "twenty-client-sdk/metadata";
|
|
1739
|
+
var OBJECTS_PAGE_SIZE = 100;
|
|
1740
|
+
var listLaunchObjects = async () => {
|
|
1741
|
+
const client = new MetadataApiClient();
|
|
1742
|
+
const launchObjects = [];
|
|
1743
|
+
let after;
|
|
1744
|
+
do {
|
|
1745
|
+
const { objects } = await client.query({
|
|
1746
|
+
objects: {
|
|
1747
|
+
__args: {
|
|
1748
|
+
paging: { first: OBJECTS_PAGE_SIZE, ...after !== void 0 ? { after } : {} },
|
|
1749
|
+
filter: { isActive: { is: true }, isSystem: { is: false } }
|
|
1750
|
+
},
|
|
1751
|
+
pageInfo: { hasNextPage: true, endCursor: true },
|
|
1752
|
+
edges: {
|
|
1753
|
+
node: {
|
|
1754
|
+
id: true,
|
|
1755
|
+
nameSingular: true,
|
|
1756
|
+
namePlural: true,
|
|
1757
|
+
labelSingular: true,
|
|
1758
|
+
icon: true,
|
|
1759
|
+
fieldsList: {
|
|
1760
|
+
id: true,
|
|
1761
|
+
name: true,
|
|
1762
|
+
label: true,
|
|
1763
|
+
type: true,
|
|
1764
|
+
icon: true,
|
|
1765
|
+
isActive: true,
|
|
1766
|
+
isSystem: true,
|
|
1767
|
+
relation: { type: true }
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
});
|
|
1773
|
+
for (const { node } of objects.edges) {
|
|
1774
|
+
launchObjects.push({
|
|
1775
|
+
id: node.id,
|
|
1776
|
+
nameSingular: node.nameSingular,
|
|
1777
|
+
namePlural: node.namePlural,
|
|
1778
|
+
labelSingular: node.labelSingular,
|
|
1779
|
+
icon: node.icon,
|
|
1780
|
+
fields: (node.fieldsList ?? []).map((field) => ({
|
|
1781
|
+
id: field.id,
|
|
1782
|
+
name: field.name,
|
|
1783
|
+
label: field.label,
|
|
1784
|
+
type: String(field.type),
|
|
1785
|
+
icon: field.icon,
|
|
1786
|
+
isActive: field.isActive,
|
|
1787
|
+
isSystem: field.isSystem,
|
|
1788
|
+
relationType: field.relation?.type ?? null
|
|
1789
|
+
}))
|
|
1790
|
+
});
|
|
1791
|
+
}
|
|
1792
|
+
after = objects.pageInfo.hasNextPage === true ? objects.pageInfo.endCursor ?? void 0 : void 0;
|
|
1793
|
+
} while (after !== void 0);
|
|
1794
|
+
return launchObjects;
|
|
1795
|
+
};
|
|
1796
|
+
|
|
1737
1797
|
// src/shared/api/rest-response.util.ts
|
|
1738
1798
|
var readDataValue = (response) => {
|
|
1739
1799
|
const data = response?.data;
|
|
@@ -1746,7 +1806,8 @@ var readRestList = (response) => {
|
|
|
1746
1806
|
const value = readDataValue(response);
|
|
1747
1807
|
return {
|
|
1748
1808
|
records: Array.isArray(value) ? value : [],
|
|
1749
|
-
pageInfo: response?.pageInfo ?? {}
|
|
1809
|
+
pageInfo: response?.pageInfo ?? {},
|
|
1810
|
+
totalCount: response?.totalCount
|
|
1750
1811
|
};
|
|
1751
1812
|
};
|
|
1752
1813
|
var readRestRecord = (response) => {
|
|
@@ -1758,6 +1819,7 @@ var readRestRecord = (response) => {
|
|
|
1758
1819
|
var DOCFLOW_LAUNCH_PARAMETERS_KEY = "smbDocflowParameters";
|
|
1759
1820
|
var LAUNCH_PARAMETERS_STEP_INPUT = `{{trigger.${DOCFLOW_LAUNCH_PARAMETERS_KEY}}}`;
|
|
1760
1821
|
var LAUNCH_TRIGGER_NAME = "\u0417\u0430\u043F\u0443\u0441\u043A \u0441 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0430\u043C\u0438";
|
|
1822
|
+
var LAUNCH_RECORD_KEY = "record";
|
|
1761
1823
|
var FORM_FIELD_ROLE_SETTING = "smbRole";
|
|
1762
1824
|
var TRIGGER_STEP_ID = "trigger";
|
|
1763
1825
|
|
|
@@ -1800,6 +1862,8 @@ var isLaunchParametersStep = (step) => {
|
|
|
1800
1862
|
var isLaunchTrigger = (trigger) => trigger?.type === "WEBHOOK" && trigger.name === LAUNCH_TRIGGER_NAME;
|
|
1801
1863
|
var findLaunchParametersStep = (steps) => (steps ?? []).find(isLaunchParametersStep);
|
|
1802
1864
|
var parseLaunchFields = (value) => getFillableFormFields(parseFormFields(value));
|
|
1865
|
+
var parseLaunchObject = (value) => typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
|
|
1866
|
+
var getLaunchFieldsError = (fields) => fields.some(({ name }) => name === LAUNCH_RECORD_KEY) ? `\u0418\u043C\u044F \u043F\u043E\u043B\u044F \xAB${LAUNCH_RECORD_KEY}\xBB \u0437\u0430\u043D\u044F\u0442\u043E: \u0442\u0430\u043A \u043F\u0440\u043E\u0446\u0435\u0441\u0441 \u043F\u043E\u043B\u0443\u0447\u0430\u0435\u0442 \u0437\u0430\u043F\u0438\u0441\u044C, \u043D\u0430 \u043A\u043E\u0442\u043E\u0440\u043E\u0439 \u0435\u0433\u043E \u0437\u0430\u043F\u0443\u0441\u0442\u0438\u043B\u0438` : void 0;
|
|
1803
1867
|
|
|
1804
1868
|
// src/shared/form/form-field-builder.util.ts
|
|
1805
1869
|
var OUTPUT_LEAF_TYPES = {
|
|
@@ -1830,6 +1894,96 @@ var buildFieldsExpectedBody = (fields) => Object.fromEntries(
|
|
|
1830
1894
|
])
|
|
1831
1895
|
);
|
|
1832
1896
|
|
|
1897
|
+
// src/shared/workflow/launch-record.util.ts
|
|
1898
|
+
var COMPOSITE_PARTS = {
|
|
1899
|
+
ACTOR: [["source", "SELECT"], ["workspaceMemberId", "UUID"], ["name", "TEXT"], ["context", "RAW_JSON"]],
|
|
1900
|
+
ADDRESS: [
|
|
1901
|
+
["addressStreet1", "TEXT"],
|
|
1902
|
+
["addressStreet2", "TEXT"],
|
|
1903
|
+
["addressCity", "TEXT"],
|
|
1904
|
+
["addressPostcode", "TEXT"],
|
|
1905
|
+
["addressState", "TEXT"],
|
|
1906
|
+
["addressCountry", "TEXT"],
|
|
1907
|
+
["addressLat", "NUMERIC"],
|
|
1908
|
+
["addressLng", "NUMERIC"]
|
|
1909
|
+
],
|
|
1910
|
+
CURRENCY: [["amountMicros", "NUMERIC"], ["currencyCode", "TEXT"]],
|
|
1911
|
+
EMAILS: [["primaryEmail", "TEXT"], ["additionalEmails", "RAW_JSON"]],
|
|
1912
|
+
FULL_NAME: [["firstName", "TEXT"], ["lastName", "TEXT"]],
|
|
1913
|
+
LINKS: [["primaryLinkLabel", "TEXT"], ["primaryLinkUrl", "TEXT"], ["secondaryLinks", "RAW_JSON"]],
|
|
1914
|
+
PHONES: [
|
|
1915
|
+
["primaryPhoneNumber", "TEXT"],
|
|
1916
|
+
["primaryPhoneCountryCode", "TEXT"],
|
|
1917
|
+
["primaryPhoneCallingCode", "TEXT"],
|
|
1918
|
+
["additionalPhones", "RAW_JSON"]
|
|
1919
|
+
],
|
|
1920
|
+
RICH_TEXT: [["blocknote", "TEXT"], ["markdown", "TEXT"]]
|
|
1921
|
+
};
|
|
1922
|
+
var EXCLUDED_SYSTEM_FIELDS = ["searchVector", "position"];
|
|
1923
|
+
var toTitleCase = (camelCase) => camelCase.replace(/([A-Z])/g, " $1").replace(/^./, (first) => first.toUpperCase());
|
|
1924
|
+
var buildFieldSchema = (field) => {
|
|
1925
|
+
const icon = field.icon ?? void 0;
|
|
1926
|
+
if (field.type === "RELATION") {
|
|
1927
|
+
return [
|
|
1928
|
+
[
|
|
1929
|
+
`${field.name}Id`,
|
|
1930
|
+
{
|
|
1931
|
+
isLeaf: true,
|
|
1932
|
+
icon,
|
|
1933
|
+
type: "UUID",
|
|
1934
|
+
label: toTitleCase(`${field.name}Id`),
|
|
1935
|
+
value: null,
|
|
1936
|
+
fieldMetadataId: field.id,
|
|
1937
|
+
isCompositeSubField: false
|
|
1938
|
+
}
|
|
1939
|
+
]
|
|
1940
|
+
];
|
|
1941
|
+
}
|
|
1942
|
+
const parts = COMPOSITE_PARTS[field.type];
|
|
1943
|
+
if (parts !== void 0) {
|
|
1944
|
+
return [
|
|
1945
|
+
[
|
|
1946
|
+
field.name,
|
|
1947
|
+
{
|
|
1948
|
+
isLeaf: false,
|
|
1949
|
+
icon,
|
|
1950
|
+
type: field.type,
|
|
1951
|
+
label: field.label,
|
|
1952
|
+
fieldMetadataId: field.id,
|
|
1953
|
+
value: Object.fromEntries(
|
|
1954
|
+
parts.map(([name, type]) => [
|
|
1955
|
+
name,
|
|
1956
|
+
{ isLeaf: true, type, label: toTitleCase(name), value: null, fieldMetadataId: field.id, isCompositeSubField: true }
|
|
1957
|
+
])
|
|
1958
|
+
)
|
|
1959
|
+
}
|
|
1960
|
+
]
|
|
1961
|
+
];
|
|
1962
|
+
}
|
|
1963
|
+
return [
|
|
1964
|
+
[
|
|
1965
|
+
field.name,
|
|
1966
|
+
{ isLeaf: true, icon, type: field.type, label: field.label, value: null, fieldMetadataId: field.id, isCompositeSubField: false }
|
|
1967
|
+
]
|
|
1968
|
+
];
|
|
1969
|
+
};
|
|
1970
|
+
var isRecordVariable = (field) => field.isActive !== false && !(field.isSystem === true && EXCLUDED_SYSTEM_FIELDS.includes(field.name)) && field.type !== "MORPH_RELATION" && (field.type !== "RELATION" || field.relationType === "MANY_TO_ONE");
|
|
1971
|
+
var buildLaunchRecordOutputSchema = (object) => ({
|
|
1972
|
+
isLeaf: false,
|
|
1973
|
+
icon: object.icon ?? void 0,
|
|
1974
|
+
label: object.labelSingular,
|
|
1975
|
+
value: {
|
|
1976
|
+
object: {
|
|
1977
|
+
icon: object.icon ?? void 0,
|
|
1978
|
+
label: object.labelSingular,
|
|
1979
|
+
objectMetadataId: object.id,
|
|
1980
|
+
fieldIdName: "id"
|
|
1981
|
+
},
|
|
1982
|
+
fields: Object.fromEntries(object.fields.filter(isRecordVariable).flatMap(buildFieldSchema)),
|
|
1983
|
+
_outputSchemaType: "RECORD"
|
|
1984
|
+
}
|
|
1985
|
+
});
|
|
1986
|
+
|
|
1833
1987
|
// node_modules/twenty-client-sdk/dist/chunk-Dqa2HsxW.mjs
|
|
1834
1988
|
var e = Object.create;
|
|
1835
1989
|
var t = Object.defineProperty;
|
|
@@ -61229,7 +61383,7 @@ var MANUAL_TRIGGER = {
|
|
|
61229
61383
|
},
|
|
61230
61384
|
nextStepIds: []
|
|
61231
61385
|
};
|
|
61232
|
-
var buildLaunchTrigger = (base, fields) => ({
|
|
61386
|
+
var buildLaunchTrigger = (base, fields, launchObject) => ({
|
|
61233
61387
|
name: LAUNCH_TRIGGER_NAME,
|
|
61234
61388
|
type: "WEBHOOK",
|
|
61235
61389
|
position: base.position ?? { x: 0, y: 0 },
|
|
@@ -61237,12 +61391,19 @@ var buildLaunchTrigger = (base, fields) => ({
|
|
|
61237
61391
|
settings: {
|
|
61238
61392
|
httpMethod: "POST",
|
|
61239
61393
|
authentication: "API_KEY",
|
|
61240
|
-
expectedBody:
|
|
61241
|
-
|
|
61394
|
+
expectedBody: {
|
|
61395
|
+
...buildFieldsExpectedBody(fields),
|
|
61396
|
+
...launchObject !== void 0 ? { [LAUNCH_RECORD_KEY]: { id: "" } } : {}
|
|
61397
|
+
},
|
|
61398
|
+
outputSchema: {
|
|
61399
|
+
...buildFieldsOutputSchema(fields),
|
|
61400
|
+
...launchObject !== void 0 ? { [LAUNCH_RECORD_KEY]: buildLaunchRecordOutputSchema(launchObject) } : {}
|
|
61401
|
+
}
|
|
61242
61402
|
}
|
|
61243
61403
|
});
|
|
61244
61404
|
var buildManualTrigger = (base) => ({
|
|
61245
61405
|
...MANUAL_TRIGGER,
|
|
61406
|
+
...base.type === "MANUAL" ? { name: base.name ?? MANUAL_TRIGGER.name, settings: base.settings } : {},
|
|
61246
61407
|
position: base.position ?? MANUAL_TRIGGER.position,
|
|
61247
61408
|
nextStepIds: base.nextStepIds ?? []
|
|
61248
61409
|
});
|
|
@@ -61297,7 +61458,8 @@ var removeLegacyLaunchStep = async (draft) => {
|
|
|
61297
61458
|
};
|
|
61298
61459
|
var syncLaunchTrigger = async ({
|
|
61299
61460
|
workflowId,
|
|
61300
|
-
fields
|
|
61461
|
+
fields,
|
|
61462
|
+
launchObject
|
|
61301
61463
|
}) => {
|
|
61302
61464
|
const draft = await findOrCreateDraft(workflowId);
|
|
61303
61465
|
if (draft === void 0) {
|
|
@@ -61314,7 +61476,7 @@ var syncLaunchTrigger = async ({
|
|
|
61314
61476
|
variables: {
|
|
61315
61477
|
input: {
|
|
61316
61478
|
workflowVersionId: draft.id,
|
|
61317
|
-
trigger: fields.length > 0 ? buildLaunchTrigger(trigger, fields) : buildManualTrigger(trigger)
|
|
61479
|
+
trigger: fields.length > 0 || launchObject !== void 0 ? buildLaunchTrigger(trigger, fields, launchObject) : buildManualTrigger(trigger)
|
|
61318
61480
|
}
|
|
61319
61481
|
}
|
|
61320
61482
|
});
|
|
@@ -119621,23 +119783,29 @@ var handler = async (event) => {
|
|
|
119621
119783
|
const body = readJsonBody(event.body);
|
|
119622
119784
|
const workflowId = body.workflowId;
|
|
119623
119785
|
const fields = parseLaunchFields(body.fields);
|
|
119786
|
+
const launchObjectName = parseLaunchObject(body.launchObject);
|
|
119624
119787
|
if (typeof workflowId !== "string" || workflowId.length === 0 || !Array.isArray(body.fields)) {
|
|
119625
119788
|
return jsonResponse(400, { message: "\u041D\u0435 \u0443\u043A\u0430\u0437\u0430\u043D \u043F\u0440\u043E\u0446\u0435\u0441\u0441 \u0438\u043B\u0438 \u043F\u043E\u043B\u044F" });
|
|
119626
119789
|
}
|
|
119627
|
-
const fieldsError = getFormFieldsError(fields);
|
|
119790
|
+
const fieldsError = getFormFieldsError(fields) ?? (launchObjectName !== void 0 ? getLaunchFieldsError(fields) : void 0);
|
|
119628
119791
|
if (fieldsError !== void 0) {
|
|
119629
119792
|
return jsonResponse(422, { message: fieldsError });
|
|
119630
119793
|
}
|
|
119794
|
+
const launchObject = launchObjectName !== void 0 ? (await listLaunchObjects()).find(({ nameSingular }) => nameSingular === launchObjectName) : void 0;
|
|
119795
|
+
if (launchObjectName !== void 0 && launchObject === void 0) {
|
|
119796
|
+
return jsonResponse(422, { message: `\u041E\u0431\u044A\u0435\u043A\u0442 \xAB${launchObjectName}\xBB \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D` });
|
|
119797
|
+
}
|
|
119631
119798
|
const workflow = readRestRecord(
|
|
119632
119799
|
await restClient("person").patch(`/rest/workflows/${workflowId}`, {
|
|
119633
|
-
smbLaunchFields: fields.length > 0 ? fields : null
|
|
119800
|
+
smbLaunchFields: fields.length > 0 ? fields : null,
|
|
119801
|
+
smbLaunchObject: launchObject?.nameSingular ?? null
|
|
119634
119802
|
})
|
|
119635
119803
|
);
|
|
119636
119804
|
if (workflow === void 0) {
|
|
119637
119805
|
return jsonResponse(404, { message: "\u041F\u0440\u043E\u0446\u0435\u0441\u0441 \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D" });
|
|
119638
119806
|
}
|
|
119639
119807
|
try {
|
|
119640
|
-
const result = await syncLaunchTrigger({ workflowId, fields });
|
|
119808
|
+
const result = await syncLaunchTrigger({ workflowId, fields, launchObject });
|
|
119641
119809
|
logDocflow("launch fields: draft synced", { workflowId, result });
|
|
119642
119810
|
if (result?.status === "NOT_MANUAL") {
|
|
119643
119811
|
return jsonResponse(409, {
|
|
@@ -119655,7 +119823,7 @@ var handler = async (event) => {
|
|
|
119655
119823
|
var save_launch_fields_logic_function_default = defineLogicFunction({
|
|
119656
119824
|
universalIdentifier: SAVE_LAUNCH_FIELDS_LOGIC_FUNCTION_UNIVERSAL_IDENTIFIER,
|
|
119657
119825
|
name: "docflow-save-launch-fields",
|
|
119658
|
-
description: "\u0421\u043E\u0445\u0440\u0430\u043D\u044F\u0435\u0442 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u0437\u0430\u043F\u0443\u0441\u043A\u0430 \u0438 \u0434\u0435\u043B\u0430\u0435\u0442 \u043F\u0435\u0440\u0432\u044B\u043C \u0431\u043B\u043E\u043A\u043E\u043C \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u0430 \xAB\u0417\u0430\u043F\u0443\u0441\u043A \u0441 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0430\u043C\u0438\xBB",
|
|
119826
|
+
description: "\u0421\u043E\u0445\u0440\u0430\u043D\u044F\u0435\u0442 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u0438 \u043E\u0431\u044A\u0435\u043A\u0442 \u0437\u0430\u043F\u0443\u0441\u043A\u0430 \u0438 \u0434\u0435\u043B\u0430\u0435\u0442 \u043F\u0435\u0440\u0432\u044B\u043C \u0431\u043B\u043E\u043A\u043E\u043C \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u0430 \xAB\u0417\u0430\u043F\u0443\u0441\u043A \u0441 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0430\u043C\u0438\xBB",
|
|
119659
119827
|
timeoutSeconds: 30,
|
|
119660
119828
|
handler,
|
|
119661
119829
|
httpRouteTriggerSettings: {
|
|
@@ -2,37 +2,55 @@ import { defineLogicFunction } from 'twenty-sdk/define';
|
|
|
2
2
|
import { type RoutePayload } from 'twenty-sdk/logic-function';
|
|
3
3
|
|
|
4
4
|
import { CoreGraphqlError } from 'src/shared/api/core-graphql.util';
|
|
5
|
+
import { listLaunchObjects } from 'src/shared/api/object-summaries';
|
|
5
6
|
import { readRestRecord } from 'src/shared/api/rest-response.util';
|
|
6
7
|
import { getFormFieldsError } from 'src/shared/form/form-fields.util';
|
|
7
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
getLaunchFieldsError,
|
|
10
|
+
parseLaunchFields,
|
|
11
|
+
parseLaunchObject,
|
|
12
|
+
} from 'src/shared/workflow/launch-step.util';
|
|
8
13
|
import { syncLaunchTrigger } from 'src/server/launch-step';
|
|
9
14
|
import { jsonResponse, readJsonBody } from 'src/server/http-response';
|
|
10
15
|
import { restClient } from 'src/server/records';
|
|
11
16
|
import { logDocflow, logDocflowError } from 'src/shared/log.util';
|
|
12
17
|
import { SAVE_LAUNCH_FIELDS_LOGIC_FUNCTION_UNIVERSAL_IDENTIFIER } from 'src/universal-identifiers';
|
|
13
18
|
|
|
14
|
-
// Saves the parameters of a process and
|
|
15
|
-
// "Запуск с параметрами" trigger, whose
|
|
19
|
+
// Saves the parameters of a process and the object it is launched on, and
|
|
20
|
+
// puts them into its draft as the "Запуск с параметрами" trigger, whose
|
|
21
|
+
// fields and record later steps read as variables.
|
|
16
22
|
const handler = async (event: RoutePayload) => {
|
|
17
23
|
const body = readJsonBody(event.body);
|
|
18
24
|
const workflowId = body.workflowId;
|
|
19
25
|
const fields = parseLaunchFields(body.fields);
|
|
26
|
+
const launchObjectName = parseLaunchObject(body.launchObject);
|
|
20
27
|
|
|
21
28
|
if (typeof workflowId !== 'string' || workflowId.length === 0 || !Array.isArray(body.fields)) {
|
|
22
29
|
return jsonResponse(400, { message: 'Не указан процесс или поля' });
|
|
23
30
|
}
|
|
24
31
|
|
|
25
|
-
const fieldsError =
|
|
32
|
+
const fieldsError =
|
|
33
|
+
getFormFieldsError(fields) ?? (launchObjectName !== undefined ? getLaunchFieldsError(fields) : undefined);
|
|
26
34
|
|
|
27
35
|
if (fieldsError !== undefined) {
|
|
28
36
|
return jsonResponse(422, { message: fieldsError });
|
|
29
37
|
}
|
|
30
38
|
|
|
39
|
+
const launchObject =
|
|
40
|
+
launchObjectName !== undefined
|
|
41
|
+
? (await listLaunchObjects()).find(({ nameSingular }) => nameSingular === launchObjectName)
|
|
42
|
+
: undefined;
|
|
43
|
+
|
|
44
|
+
if (launchObjectName !== undefined && launchObject === undefined) {
|
|
45
|
+
return jsonResponse(422, { message: `Объект «${launchObjectName}» не найден` });
|
|
46
|
+
}
|
|
47
|
+
|
|
31
48
|
// Written as the person: who may not change the process gets the refusal
|
|
32
49
|
// of the API, not a half-saved draft.
|
|
33
50
|
const workflow = readRestRecord<{ id: string }>(
|
|
34
51
|
await restClient('person').patch(`/rest/workflows/${workflowId}`, {
|
|
35
52
|
smbLaunchFields: fields.length > 0 ? fields : null,
|
|
53
|
+
smbLaunchObject: launchObject?.nameSingular ?? null,
|
|
36
54
|
}),
|
|
37
55
|
);
|
|
38
56
|
|
|
@@ -41,7 +59,7 @@ const handler = async (event: RoutePayload) => {
|
|
|
41
59
|
}
|
|
42
60
|
|
|
43
61
|
try {
|
|
44
|
-
const result = await syncLaunchTrigger({ workflowId, fields });
|
|
62
|
+
const result = await syncLaunchTrigger({ workflowId, fields, launchObject });
|
|
45
63
|
|
|
46
64
|
logDocflow('launch fields: draft synced', { workflowId, result });
|
|
47
65
|
|
|
@@ -67,7 +85,7 @@ const handler = async (event: RoutePayload) => {
|
|
|
67
85
|
export default defineLogicFunction({
|
|
68
86
|
universalIdentifier: SAVE_LAUNCH_FIELDS_LOGIC_FUNCTION_UNIVERSAL_IDENTIFIER,
|
|
69
87
|
name: 'docflow-save-launch-fields',
|
|
70
|
-
description: 'Сохраняет параметры запуска и делает первым блоком процесса «Запуск с параметрами»',
|
|
88
|
+
description: 'Сохраняет параметры и объект запуска и делает первым блоком процесса «Запуск с параметрами»',
|
|
71
89
|
timeoutSeconds: 30,
|
|
72
90
|
handler,
|
|
73
91
|
httpRouteTriggerSettings: {
|