@haiiro/docuflow 0.0.12 → 0.0.15
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 +41 -9
- package/bin/install.mjs +69 -3
- package/manifest.json +114 -18
- package/package.json +6 -3
- package/public/app/docflow-app.css +2 -0
- package/public/app/docflow-app.js +95 -0
- package/src/front-components/docflow-documents.front-component.mjs +41 -41
- package/src/front-components/docflow-documents.front-component.tsx +49 -32
- package/src/front-components/docflow-processes.front-component.mjs +34 -34
- package/src/front-components/docflow-processes.front-component.tsx +24 -11
- package/src/front-components/docflow-tasks.front-component.mjs +40 -39
- package/src/front-components/docflow-tasks.front-component.tsx +19 -14
- 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 +26 -26
- package/src/front-components/process-steps.front-component.tsx +56 -10
- package/src/front-components/task-form.front-component.mjs +45 -44
- package/src/front-components/task-form.front-component.tsx +12 -1
- package/src/logic-functions/bitrix-app.logic-function.mjs +186 -88
- package/src/logic-functions/bitrix-app.logic-function.ts +24 -61
- package/src/logic-functions/bitrix-event.logic-function.mjs +22 -1
- package/src/logic-functions/bitrix-event.logic-function.ts +2 -2
- package/src/logic-functions/bitrix-install.logic-function.mjs +26 -12
- package/src/logic-functions/bitrix-install.logic-function.ts +2 -5
- package/src/logic-functions/complete-task.logic-function.mjs +22 -1
- package/src/logic-functions/complete-task.logic-function.ts +2 -2
- package/src/logic-functions/docflow-app-session.logic-function.mjs +60064 -0
- package/src/logic-functions/docflow-app-session.logic-function.ts +54 -0
- package/src/logic-functions/docflow-app.logic-function.mjs +60149 -0
- package/src/logic-functions/docflow-app.logic-function.ts +38 -0
- package/src/logic-functions/launch-process.logic-function.mjs +134 -40
- package/src/logic-functions/launch-process.logic-function.ts +85 -24
- package/src/logic-functions/publish-process.logic-function.mjs +32 -11
- package/src/logic-functions/publish-process.logic-function.ts +8 -4
- package/src/logic-functions/save-launch-fields.logic-function.mjs +194 -17
- package/src/logic-functions/save-launch-fields.logic-function.ts +26 -8
- package/src/logic-functions/save-step-settings.logic-function.mjs +24 -2
- package/src/logic-functions/save-step-settings.logic-function.ts +2 -2
- package/src/logic-functions/save-task-form.logic-function.mjs +22 -1
- package/src/logic-functions/save-task-form.logic-function.ts +2 -2
|
@@ -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;
|
|
@@ -1759,6 +1819,7 @@ var readRestRecord = (response) => {
|
|
|
1759
1819
|
var DOCFLOW_LAUNCH_PARAMETERS_KEY = "smbDocflowParameters";
|
|
1760
1820
|
var LAUNCH_PARAMETERS_STEP_INPUT = `{{trigger.${DOCFLOW_LAUNCH_PARAMETERS_KEY}}}`;
|
|
1761
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";
|
|
1762
1823
|
var FORM_FIELD_ROLE_SETTING = "smbRole";
|
|
1763
1824
|
var TRIGGER_STEP_ID = "trigger";
|
|
1764
1825
|
|
|
@@ -1801,6 +1862,8 @@ var isLaunchParametersStep = (step) => {
|
|
|
1801
1862
|
var isLaunchTrigger = (trigger) => trigger?.type === "WEBHOOK" && trigger.name === LAUNCH_TRIGGER_NAME;
|
|
1802
1863
|
var findLaunchParametersStep = (steps) => (steps ?? []).find(isLaunchParametersStep);
|
|
1803
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;
|
|
1804
1867
|
|
|
1805
1868
|
// src/shared/form/form-field-builder.util.ts
|
|
1806
1869
|
var OUTPUT_LEAF_TYPES = {
|
|
@@ -1831,6 +1894,96 @@ var buildFieldsExpectedBody = (fields) => Object.fromEntries(
|
|
|
1831
1894
|
])
|
|
1832
1895
|
);
|
|
1833
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
|
+
|
|
1834
1987
|
// node_modules/twenty-client-sdk/dist/chunk-Dqa2HsxW.mjs
|
|
1835
1988
|
var e = Object.create;
|
|
1836
1989
|
var t = Object.defineProperty;
|
|
@@ -61230,7 +61383,7 @@ var MANUAL_TRIGGER = {
|
|
|
61230
61383
|
},
|
|
61231
61384
|
nextStepIds: []
|
|
61232
61385
|
};
|
|
61233
|
-
var buildLaunchTrigger = (base, fields) => ({
|
|
61386
|
+
var buildLaunchTrigger = (base, fields, launchObject) => ({
|
|
61234
61387
|
name: LAUNCH_TRIGGER_NAME,
|
|
61235
61388
|
type: "WEBHOOK",
|
|
61236
61389
|
position: base.position ?? { x: 0, y: 0 },
|
|
@@ -61238,12 +61391,19 @@ var buildLaunchTrigger = (base, fields) => ({
|
|
|
61238
61391
|
settings: {
|
|
61239
61392
|
httpMethod: "POST",
|
|
61240
61393
|
authentication: "API_KEY",
|
|
61241
|
-
expectedBody:
|
|
61242
|
-
|
|
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
|
+
}
|
|
61243
61402
|
}
|
|
61244
61403
|
});
|
|
61245
61404
|
var buildManualTrigger = (base) => ({
|
|
61246
61405
|
...MANUAL_TRIGGER,
|
|
61406
|
+
...base.type === "MANUAL" ? { name: base.name ?? MANUAL_TRIGGER.name, settings: base.settings } : {},
|
|
61247
61407
|
position: base.position ?? MANUAL_TRIGGER.position,
|
|
61248
61408
|
nextStepIds: base.nextStepIds ?? []
|
|
61249
61409
|
});
|
|
@@ -61298,7 +61458,8 @@ var removeLegacyLaunchStep = async (draft) => {
|
|
|
61298
61458
|
};
|
|
61299
61459
|
var syncLaunchTrigger = async ({
|
|
61300
61460
|
workflowId,
|
|
61301
|
-
fields
|
|
61461
|
+
fields,
|
|
61462
|
+
launchObject
|
|
61302
61463
|
}) => {
|
|
61303
61464
|
const draft = await findOrCreateDraft(workflowId);
|
|
61304
61465
|
if (draft === void 0) {
|
|
@@ -61315,7 +61476,7 @@ var syncLaunchTrigger = async ({
|
|
|
61315
61476
|
variables: {
|
|
61316
61477
|
input: {
|
|
61317
61478
|
workflowVersionId: draft.id,
|
|
61318
|
-
trigger: fields.length > 0 ? buildLaunchTrigger(trigger, fields) : buildManualTrigger(trigger)
|
|
61479
|
+
trigger: fields.length > 0 || launchObject !== void 0 ? buildLaunchTrigger(trigger, fields, launchObject) : buildManualTrigger(trigger)
|
|
61319
61480
|
}
|
|
61320
61481
|
}
|
|
61321
61482
|
});
|
|
@@ -119595,13 +119756,6 @@ var AL = class {
|
|
|
119595
119756
|
}
|
|
119596
119757
|
};
|
|
119597
119758
|
|
|
119598
|
-
// src/server/http-response.ts
|
|
119599
|
-
var jsonResponse = (status, body) => new AL(JSON.stringify(body), {
|
|
119600
|
-
status,
|
|
119601
|
-
headers: { "content-type": "application/json; charset=utf-8" }
|
|
119602
|
-
});
|
|
119603
|
-
var readJsonBody = (body) => typeof body === "object" && body !== null && !Array.isArray(body) ? body : {};
|
|
119604
|
-
|
|
119605
119759
|
// src/shared/log.util.ts
|
|
119606
119760
|
var PREFIX = "[docflow]";
|
|
119607
119761
|
var describeError = (error) => {
|
|
@@ -119614,6 +119768,23 @@ var describeError = (error) => {
|
|
|
119614
119768
|
var logDocflow = (event, details) => console.info(PREFIX, event, details ?? "");
|
|
119615
119769
|
var logDocflowError = (event, error, details) => console.error(PREFIX, event, describeError(error), details ?? "");
|
|
119616
119770
|
|
|
119771
|
+
// src/server/http-response.ts
|
|
119772
|
+
var jsonResponse = (status, body) => new AL(JSON.stringify(body), {
|
|
119773
|
+
status,
|
|
119774
|
+
headers: { "content-type": "application/json; charset=utf-8" }
|
|
119775
|
+
});
|
|
119776
|
+
var readJsonBody = (body) => typeof body === "object" && body !== null && !Array.isArray(body) ? body : {};
|
|
119777
|
+
var withRouteErrors = (name, handler2) => async (...args) => {
|
|
119778
|
+
try {
|
|
119779
|
+
return await handler2(...args);
|
|
119780
|
+
} catch (error) {
|
|
119781
|
+
logDocflowError(`${name}: unexpected error`, error);
|
|
119782
|
+
return jsonResponse(500, {
|
|
119783
|
+
message: `\u041E\u0448\u0438\u0431\u043A\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u043E\u0431\u043E\u0440\u043E\u0442\u0430: ${error instanceof Error ? error.message : String(error)}`
|
|
119784
|
+
});
|
|
119785
|
+
}
|
|
119786
|
+
};
|
|
119787
|
+
|
|
119617
119788
|
// src/universal-identifiers.ts
|
|
119618
119789
|
var SAVE_LAUNCH_FIELDS_LOGIC_FUNCTION_UNIVERSAL_IDENTIFIER = "d2cce9f2-6ba4-415c-aa3d-5d9aba6ae89c";
|
|
119619
119790
|
|
|
@@ -119622,23 +119793,29 @@ var handler = async (event) => {
|
|
|
119622
119793
|
const body = readJsonBody(event.body);
|
|
119623
119794
|
const workflowId = body.workflowId;
|
|
119624
119795
|
const fields = parseLaunchFields(body.fields);
|
|
119796
|
+
const launchObjectName = parseLaunchObject(body.launchObject);
|
|
119625
119797
|
if (typeof workflowId !== "string" || workflowId.length === 0 || !Array.isArray(body.fields)) {
|
|
119626
119798
|
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" });
|
|
119627
119799
|
}
|
|
119628
|
-
const fieldsError = getFormFieldsError(fields);
|
|
119800
|
+
const fieldsError = getFormFieldsError(fields) ?? (launchObjectName !== void 0 ? getLaunchFieldsError(fields) : void 0);
|
|
119629
119801
|
if (fieldsError !== void 0) {
|
|
119630
119802
|
return jsonResponse(422, { message: fieldsError });
|
|
119631
119803
|
}
|
|
119804
|
+
const launchObject = launchObjectName !== void 0 ? (await listLaunchObjects()).find(({ nameSingular }) => nameSingular === launchObjectName) : void 0;
|
|
119805
|
+
if (launchObjectName !== void 0 && launchObject === void 0) {
|
|
119806
|
+
return jsonResponse(422, { message: `\u041E\u0431\u044A\u0435\u043A\u0442 \xAB${launchObjectName}\xBB \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D` });
|
|
119807
|
+
}
|
|
119632
119808
|
const workflow = readRestRecord(
|
|
119633
119809
|
await restClient("person").patch(`/rest/workflows/${workflowId}`, {
|
|
119634
|
-
smbLaunchFields: fields.length > 0 ? fields : null
|
|
119810
|
+
smbLaunchFields: fields.length > 0 ? fields : null,
|
|
119811
|
+
smbLaunchObject: launchObject?.nameSingular ?? null
|
|
119635
119812
|
})
|
|
119636
119813
|
);
|
|
119637
119814
|
if (workflow === void 0) {
|
|
119638
119815
|
return jsonResponse(404, { message: "\u041F\u0440\u043E\u0446\u0435\u0441\u0441 \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D" });
|
|
119639
119816
|
}
|
|
119640
119817
|
try {
|
|
119641
|
-
const result = await syncLaunchTrigger({ workflowId, fields });
|
|
119818
|
+
const result = await syncLaunchTrigger({ workflowId, fields, launchObject });
|
|
119642
119819
|
logDocflow("launch fields: draft synced", { workflowId, result });
|
|
119643
119820
|
if (result?.status === "NOT_MANUAL") {
|
|
119644
119821
|
return jsonResponse(409, {
|
|
@@ -119656,9 +119833,9 @@ var handler = async (event) => {
|
|
|
119656
119833
|
var save_launch_fields_logic_function_default = defineLogicFunction({
|
|
119657
119834
|
universalIdentifier: SAVE_LAUNCH_FIELDS_LOGIC_FUNCTION_UNIVERSAL_IDENTIFIER,
|
|
119658
119835
|
name: "docflow-save-launch-fields",
|
|
119659
|
-
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",
|
|
119836
|
+
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",
|
|
119660
119837
|
timeoutSeconds: 30,
|
|
119661
|
-
handler,
|
|
119838
|
+
handler: withRouteErrors("save-launch-fields", handler),
|
|
119662
119839
|
httpRouteTriggerSettings: {
|
|
119663
119840
|
path: "/docflow/processes/launch-fields",
|
|
119664
119841
|
httpMethod: "POST",
|
|
@@ -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
|
-
import { jsonResponse, readJsonBody } from 'src/server/http-response';
|
|
14
|
+
import { jsonResponse, readJsonBody, withRouteErrors } 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,9 +85,9 @@ 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
|
-
handler,
|
|
90
|
+
handler: withRouteErrors('save-launch-fields', handler),
|
|
73
91
|
httpRouteTriggerSettings: {
|
|
74
92
|
path: '/docflow/processes/launch-fields',
|
|
75
93
|
httpMethod: 'POST',
|
|
@@ -119312,12 +119312,33 @@ var AL = class {
|
|
|
119312
119312
|
}
|
|
119313
119313
|
};
|
|
119314
119314
|
|
|
119315
|
+
// src/shared/log.util.ts
|
|
119316
|
+
var PREFIX = "[docflow]";
|
|
119317
|
+
var describeError = (error) => {
|
|
119318
|
+
if (error instanceof Error) {
|
|
119319
|
+
const { status, body } = error;
|
|
119320
|
+
return { name: error.name, message: error.message, status, body };
|
|
119321
|
+
}
|
|
119322
|
+
return error;
|
|
119323
|
+
};
|
|
119324
|
+
var logDocflowError = (event, error, details) => console.error(PREFIX, event, describeError(error), details ?? "");
|
|
119325
|
+
|
|
119315
119326
|
// src/server/http-response.ts
|
|
119316
119327
|
var jsonResponse = (status, body) => new AL(JSON.stringify(body), {
|
|
119317
119328
|
status,
|
|
119318
119329
|
headers: { "content-type": "application/json; charset=utf-8" }
|
|
119319
119330
|
});
|
|
119320
119331
|
var readJsonBody = (body) => typeof body === "object" && body !== null && !Array.isArray(body) ? body : {};
|
|
119332
|
+
var withRouteErrors = (name, handler2) => async (...args) => {
|
|
119333
|
+
try {
|
|
119334
|
+
return await handler2(...args);
|
|
119335
|
+
} catch (error) {
|
|
119336
|
+
logDocflowError(`${name}: unexpected error`, error);
|
|
119337
|
+
return jsonResponse(500, {
|
|
119338
|
+
message: `\u041E\u0448\u0438\u0431\u043A\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u043E\u0431\u043E\u0440\u043E\u0442\u0430: ${error instanceof Error ? error.message : String(error)}`
|
|
119339
|
+
});
|
|
119340
|
+
}
|
|
119341
|
+
};
|
|
119321
119342
|
|
|
119322
119343
|
// src/shared/api/rest-response.util.ts
|
|
119323
119344
|
var readDataValue = (response) => {
|
|
@@ -119427,7 +119448,8 @@ var applyStepSettings = ({
|
|
|
119427
119448
|
createId
|
|
119428
119449
|
}) => {
|
|
119429
119450
|
const ordinaryFields = fields.filter((field) => getFormFieldRole(field) === void 0).map((field) => {
|
|
119430
|
-
const
|
|
119451
|
+
const rest = { ...field.settings };
|
|
119452
|
+
delete rest[FORM_FIELD_REQUIRED_SETTING];
|
|
119431
119453
|
const isRequired = settings.requiredFieldIds.includes(field.id);
|
|
119432
119454
|
return {
|
|
119433
119455
|
...field,
|
|
@@ -119517,7 +119539,7 @@ var save_step_settings_logic_function_default = defineLogicFunction({
|
|
|
119517
119539
|
name: "docflow-save-step-settings",
|
|
119518
119540
|
description: "\u0421\u043E\u0445\u0440\u0430\u043D\u044F\u0435\u0442 \u0438\u0441\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044F, \u0441\u0440\u043E\u043A \u0438 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u044B\u0435 \u043F\u043E\u043B\u044F \u0448\u0430\u0433\u0430 \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u0430",
|
|
119519
119541
|
timeoutSeconds: 15,
|
|
119520
|
-
handler,
|
|
119542
|
+
handler: withRouteErrors("save-step-settings", handler),
|
|
119521
119543
|
httpRouteTriggerSettings: {
|
|
119522
119544
|
path: "/docflow/processes/step-settings",
|
|
119523
119545
|
httpMethod: "POST",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineLogicFunction } from 'twenty-sdk/define';
|
|
2
2
|
import { type RoutePayload } from 'twenty-sdk/logic-function';
|
|
3
3
|
|
|
4
|
-
import { jsonResponse, readJsonBody } from 'src/server/http-response';
|
|
4
|
+
import { jsonResponse, readJsonBody, withRouteErrors } from 'src/server/http-response';
|
|
5
5
|
import { restClient, type WorkflowVersionRecord } from 'src/server/records';
|
|
6
6
|
import { callCoreGraphql, UPDATE_WORKFLOW_VERSION_STEP_MUTATION } from 'src/shared/api/core-graphql.util';
|
|
7
7
|
import { readRestRecord } from 'src/shared/api/rest-response.util';
|
|
@@ -81,7 +81,7 @@ export default defineLogicFunction({
|
|
|
81
81
|
name: 'docflow-save-step-settings',
|
|
82
82
|
description: 'Сохраняет исполнителя, срок и обязательные поля шага процесса',
|
|
83
83
|
timeoutSeconds: 15,
|
|
84
|
-
handler,
|
|
84
|
+
handler: withRouteErrors('save-step-settings', handler),
|
|
85
85
|
httpRouteTriggerSettings: {
|
|
86
86
|
path: '/docflow/processes/step-settings',
|
|
87
87
|
httpMethod: 'POST',
|
|
@@ -119339,12 +119339,33 @@ var AL = class {
|
|
|
119339
119339
|
}
|
|
119340
119340
|
};
|
|
119341
119341
|
|
|
119342
|
+
// src/shared/log.util.ts
|
|
119343
|
+
var PREFIX = "[docflow]";
|
|
119344
|
+
var describeError = (error) => {
|
|
119345
|
+
if (error instanceof Error) {
|
|
119346
|
+
const { status, body } = error;
|
|
119347
|
+
return { name: error.name, message: error.message, status, body };
|
|
119348
|
+
}
|
|
119349
|
+
return error;
|
|
119350
|
+
};
|
|
119351
|
+
var logDocflowError = (event, error, details) => console.error(PREFIX, event, describeError(error), details ?? "");
|
|
119352
|
+
|
|
119342
119353
|
// src/server/http-response.ts
|
|
119343
119354
|
var jsonResponse = (status, body) => new AL(JSON.stringify(body), {
|
|
119344
119355
|
status,
|
|
119345
119356
|
headers: { "content-type": "application/json; charset=utf-8" }
|
|
119346
119357
|
});
|
|
119347
119358
|
var readJsonBody = (body) => typeof body === "object" && body !== null && !Array.isArray(body) ? body : {};
|
|
119359
|
+
var withRouteErrors = (name, handler2) => async (...args) => {
|
|
119360
|
+
try {
|
|
119361
|
+
return await handler2(...args);
|
|
119362
|
+
} catch (error) {
|
|
119363
|
+
logDocflowError(`${name}: unexpected error`, error);
|
|
119364
|
+
return jsonResponse(500, {
|
|
119365
|
+
message: `\u041E\u0448\u0438\u0431\u043A\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u043E\u0431\u043E\u0440\u043E\u0442\u0430: ${error instanceof Error ? error.message : String(error)}`
|
|
119366
|
+
});
|
|
119367
|
+
}
|
|
119368
|
+
};
|
|
119348
119369
|
|
|
119349
119370
|
// src/shared/api/rest-response.util.ts
|
|
119350
119371
|
var readDataValue = (response) => {
|
|
@@ -119414,7 +119435,7 @@ var save_task_form_logic_function_default = defineLogicFunction({
|
|
|
119414
119435
|
name: "docflow-save-task-form",
|
|
119415
119436
|
description: "\u0421\u043E\u0445\u0440\u0430\u043D\u044F\u0435\u0442 \u043F\u043E\u043B\u044F \u0437\u0430\u0434\u0430\u043D\u0438\u044F \u0438 \u0438\u0445 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F",
|
|
119416
119437
|
timeoutSeconds: 15,
|
|
119417
|
-
handler,
|
|
119438
|
+
handler: withRouteErrors("save-task-form", handler),
|
|
119418
119439
|
httpRouteTriggerSettings: {
|
|
119419
119440
|
path: "/docflow/tasks/form",
|
|
119420
119441
|
httpMethod: "POST",
|
|
@@ -2,7 +2,7 @@ import { defineLogicFunction } from 'twenty-sdk/define';
|
|
|
2
2
|
import { type RoutePayload } from 'twenty-sdk/logic-function';
|
|
3
3
|
|
|
4
4
|
import { getFormFieldsError, parseFormFields, parseFormValues } from 'src/shared/form/form-fields.util';
|
|
5
|
-
import { jsonResponse, readJsonBody } from 'src/server/http-response';
|
|
5
|
+
import { jsonResponse, readJsonBody, withRouteErrors } from 'src/server/http-response';
|
|
6
6
|
import { getTask, updateTask } from 'src/server/records';
|
|
7
7
|
import { isProcessTask } from 'src/server/task-completion';
|
|
8
8
|
import { SAVE_TASK_FORM_LOGIC_FUNCTION_UNIVERSAL_IDENTIFIER } from 'src/universal-identifiers';
|
|
@@ -53,7 +53,7 @@ export default defineLogicFunction({
|
|
|
53
53
|
name: 'docflow-save-task-form',
|
|
54
54
|
description: 'Сохраняет поля задания и их значения',
|
|
55
55
|
timeoutSeconds: 15,
|
|
56
|
-
handler,
|
|
56
|
+
handler: withRouteErrors('save-task-form', handler),
|
|
57
57
|
httpRouteTriggerSettings: {
|
|
58
58
|
path: '/docflow/tasks/form',
|
|
59
59
|
httpMethod: 'POST',
|