@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
|
@@ -14,7 +14,18 @@ const TaskForm = () => {
|
|
|
14
14
|
|
|
15
15
|
return (
|
|
16
16
|
<DocflowRoot>
|
|
17
|
-
|
|
17
|
+
{/* The panel fills the tab so the task's actions sit at its bottom */}
|
|
18
|
+
<div
|
|
19
|
+
style={{
|
|
20
|
+
boxSizing: 'border-box',
|
|
21
|
+
display: 'flex',
|
|
22
|
+
flex: 1,
|
|
23
|
+
flexDirection: 'column',
|
|
24
|
+
minHeight: 0,
|
|
25
|
+
overflowY: 'auto',
|
|
26
|
+
padding: theme.spacing[3],
|
|
27
|
+
}}
|
|
28
|
+
>
|
|
18
29
|
{taskId === undefined ? <Message>Откройте задачу.</Message> : <TaskWorkPanel taskId={taskId} />}
|
|
19
30
|
</div>
|
|
20
31
|
</DocflowRoot>
|
|
@@ -1673,42 +1673,6 @@ var __anyHandler = {
|
|
|
1673
1673
|
var __anyStub = new Proxy(() => void 0, __anyHandler);
|
|
1674
1674
|
var defineLogicFunction = __defineFactoryStub;
|
|
1675
1675
|
|
|
1676
|
-
// src/shared/api/rest-filter.util.ts
|
|
1677
|
-
var UNSAFE_FILTER_CHARACTERS = /[()[\]'",]/g;
|
|
1678
|
-
var sanitizeFilterText = (text) => text.replace(UNSAFE_FILTER_CHARACTERS, " ").trim();
|
|
1679
|
-
var quote = (value) => `'${sanitizeFilterText(value)}'`;
|
|
1680
|
-
var restEq = (field, value) => `${field}[eq]:${quote(value)}`;
|
|
1681
|
-
var restNeq = (field, value) => `${field}[neq]:${quote(value)}`;
|
|
1682
|
-
var restIsNull = (field) => `${field}[is]:NULL`;
|
|
1683
|
-
var restAnd = (...conditions) => {
|
|
1684
|
-
const present = conditions.filter(
|
|
1685
|
-
(condition) => condition !== void 0
|
|
1686
|
-
);
|
|
1687
|
-
return present.length === 0 ? void 0 : `and(${present.join(",")})`;
|
|
1688
|
-
};
|
|
1689
|
-
var restOr = (...conditions) => `or(${conditions.join(",")})`;
|
|
1690
|
-
|
|
1691
|
-
// src/shared/api/rest-response.util.ts
|
|
1692
|
-
var readDataValue = (response) => {
|
|
1693
|
-
const data = response?.data;
|
|
1694
|
-
if (typeof data !== "object" || data === null) {
|
|
1695
|
-
return void 0;
|
|
1696
|
-
}
|
|
1697
|
-
return Object.values(data)[0];
|
|
1698
|
-
};
|
|
1699
|
-
var readRestList = (response) => {
|
|
1700
|
-
const value = readDataValue(response);
|
|
1701
|
-
return {
|
|
1702
|
-
records: Array.isArray(value) ? value : [],
|
|
1703
|
-
pageInfo: response?.pageInfo ?? {},
|
|
1704
|
-
totalCount: response?.totalCount
|
|
1705
|
-
};
|
|
1706
|
-
};
|
|
1707
|
-
var readRestRecord = (response) => {
|
|
1708
|
-
const value = readDataValue(response);
|
|
1709
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
1710
|
-
};
|
|
1711
|
-
|
|
1712
1676
|
// src/shared/bitrix/bitrix.util.ts
|
|
1713
1677
|
var BITRIX_OAUTH_TOKEN_URL = "https://oauth.bitrix.info/oauth/token/";
|
|
1714
1678
|
var BITRIX_PORTAL_KV_KEY = "bitrix:portal";
|
|
@@ -1844,15 +1808,42 @@ var callBitrix = async ({
|
|
|
1844
1808
|
return body.result;
|
|
1845
1809
|
};
|
|
1846
1810
|
|
|
1847
|
-
// src/shared/docflow.
|
|
1848
|
-
var
|
|
1849
|
-
var
|
|
1850
|
-
var
|
|
1851
|
-
var
|
|
1811
|
+
// src/shared/app/docflow-app.util.ts
|
|
1812
|
+
var DOCFLOW_APP_SECTIONS = ["tasks", "processes", "documents"];
|
|
1813
|
+
var readDocflowAppSection = (value) => DOCFLOW_APP_SECTIONS.find((section) => section === value) ?? "tasks";
|
|
1814
|
+
var SESSION_RENEW_BEFORE_MS = 10 * 60 * 1e3;
|
|
1815
|
+
var SESSION_EXPIRY_MARGIN_MS = 60 * 1e3;
|
|
1852
1816
|
|
|
1853
1817
|
// src/server/bitrix-member.ts
|
|
1854
1818
|
import { randomBytes } from "node:crypto";
|
|
1855
1819
|
|
|
1820
|
+
// src/shared/api/rest-filter.util.ts
|
|
1821
|
+
var UNSAFE_FILTER_CHARACTERS = /[()[\]'",]/g;
|
|
1822
|
+
var sanitizeFilterText = (text) => text.replace(UNSAFE_FILTER_CHARACTERS, " ").trim();
|
|
1823
|
+
var quote = (value) => `'${sanitizeFilterText(value)}'`;
|
|
1824
|
+
var restEq = (field, value) => `${field}[eq]:${quote(value)}`;
|
|
1825
|
+
|
|
1826
|
+
// src/shared/api/rest-response.util.ts
|
|
1827
|
+
var readDataValue = (response) => {
|
|
1828
|
+
const data = response?.data;
|
|
1829
|
+
if (typeof data !== "object" || data === null) {
|
|
1830
|
+
return void 0;
|
|
1831
|
+
}
|
|
1832
|
+
return Object.values(data)[0];
|
|
1833
|
+
};
|
|
1834
|
+
var readRestList = (response) => {
|
|
1835
|
+
const value = readDataValue(response);
|
|
1836
|
+
return {
|
|
1837
|
+
records: Array.isArray(value) ? value : [],
|
|
1838
|
+
pageInfo: response?.pageInfo ?? {},
|
|
1839
|
+
totalCount: response?.totalCount
|
|
1840
|
+
};
|
|
1841
|
+
};
|
|
1842
|
+
var readRestRecord = (response) => {
|
|
1843
|
+
const value = readDataValue(response);
|
|
1844
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
1845
|
+
};
|
|
1846
|
+
|
|
1856
1847
|
// src/shared/bitrix/bitrix-user.util.ts
|
|
1857
1848
|
var readText = (value) => typeof value === "string" ? value.trim() : "";
|
|
1858
1849
|
var readBitrixUserEmail = (user) => {
|
|
@@ -61229,6 +61220,10 @@ var u2 = class {
|
|
|
61229
61220
|
}
|
|
61230
61221
|
};
|
|
61231
61222
|
|
|
61223
|
+
// src/shared/docflow.constants.ts
|
|
61224
|
+
var DOCFLOW_LAUNCH_PARAMETERS_KEY = "smbDocflowParameters";
|
|
61225
|
+
var LAUNCH_PARAMETERS_STEP_INPUT = `{{trigger.${DOCFLOW_LAUNCH_PARAMETERS_KEY}}}`;
|
|
61226
|
+
|
|
61232
61227
|
// src/server/records.ts
|
|
61233
61228
|
var clients = {
|
|
61234
61229
|
person: new u2(),
|
|
@@ -119722,7 +119717,6 @@ var renderBitrixPage = ({
|
|
|
119722
119717
|
title,
|
|
119723
119718
|
message,
|
|
119724
119719
|
crmUrl,
|
|
119725
|
-
tasks,
|
|
119726
119720
|
isInstall
|
|
119727
119721
|
}) => `<!doctype html>
|
|
119728
119722
|
<html lang="ru">
|
|
@@ -119736,56 +119730,165 @@ var renderBitrixPage = ({
|
|
|
119736
119730
|
h1 { font-size: 20px; margin: 0 0 8px; }
|
|
119737
119731
|
p { color: #666; margin: 0 0 16px; }
|
|
119738
119732
|
a.button { display: inline-block; padding: 8px 16px; border-radius: 8px; background: #1961ed; color: #fff; text-decoration: none; }
|
|
119739
|
-
ul { list-style: none; padding: 0; margin: 16px 0 0; }
|
|
119740
|
-
li { padding: 8px 0; border-top: 1px solid #eee; display: flex; justify-content: space-between; gap: 16px; }
|
|
119741
|
-
li a { color: #1961ed; text-decoration: none; }
|
|
119742
|
-
.due { color: #999; white-space: nowrap; }
|
|
119743
119733
|
</style>
|
|
119744
119734
|
</head>
|
|
119745
119735
|
<body>
|
|
119746
119736
|
<h1>${escapeHtml(title)}</h1>
|
|
119747
119737
|
<p>${escapeHtml(message)}</p>
|
|
119748
119738
|
${crmUrl !== void 0 ? `<a class="button" href="${escapeHtml(crmUrl)}" target="_blank" rel="noopener">\u041E\u0442\u043A\u0440\u044B\u0442\u044C \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u043E\u0431\u043E\u0440\u043E\u0442</a>` : ""}
|
|
119749
|
-
${tasks.length > 0 ? `<ul>${tasks.map(
|
|
119750
|
-
(task) => `<li>${task.url !== void 0 ? `<a href="${escapeHtml(task.url)}" target="_blank" rel="noopener">${escapeHtml(task.title)}</a>` : escapeHtml(task.title)}<span class="due">${escapeHtml(task.dueAt ?? "")}</span></li>`
|
|
119751
|
-
).join("")}</ul>` : ""}
|
|
119752
119739
|
${isInstall ? "<script>if (window.BX24) { BX24.init(function () { BX24.installFinish(); }); }</script>" : ""}
|
|
119753
119740
|
</body>
|
|
119754
119741
|
</html>`;
|
|
119755
119742
|
|
|
119743
|
+
// src/server/crm-url.ts
|
|
119744
|
+
var getCrmUrl = () => {
|
|
119745
|
+
const value = process.env.CRM_PUBLIC_URL?.trim();
|
|
119746
|
+
return value !== void 0 && /^https?:\/\//.test(value) ? value.replace(/\/$/, "") : void 0;
|
|
119747
|
+
};
|
|
119748
|
+
|
|
119749
|
+
// package.json
|
|
119750
|
+
var package_default = {
|
|
119751
|
+
name: "@haiiro/docuflow",
|
|
119752
|
+
version: "0.0.15",
|
|
119753
|
+
description: "NorDiv \u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u043E\u0431\u043E\u0440\u043E\u0442: \u0437\u0430\u0434\u0430\u043D\u0438\u044F \u0441 \u043F\u043E\u043B\u044F\u043C\u0438, \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u044B \u0441 \u0437\u0430\u043F\u0443\u0441\u043A\u043E\u043C \u043F\u043E \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0430\u043C, \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u044B \u0441\u043E \u0432\u0441\u0435\u0445 \u0437\u0430\u043F\u0438\u0441\u0435\u0439, \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \u0411\u0438\u0442\u0440\u0438\u043A\u044124",
|
|
119754
|
+
license: "AGPL-3.0-only",
|
|
119755
|
+
publishConfig: {
|
|
119756
|
+
access: "public",
|
|
119757
|
+
registry: "https://registry.npmjs.org/"
|
|
119758
|
+
},
|
|
119759
|
+
bin: {
|
|
119760
|
+
"nordiv-docuflow": "bin/install.mjs"
|
|
119761
|
+
},
|
|
119762
|
+
files: [
|
|
119763
|
+
"bin/**/*",
|
|
119764
|
+
"manifest.json",
|
|
119765
|
+
"front-component-shared-dependencies.mjs",
|
|
119766
|
+
"yarn.lock",
|
|
119767
|
+
"src/**/*",
|
|
119768
|
+
"public/**/*",
|
|
119769
|
+
"README.md",
|
|
119770
|
+
"tsconfig.json",
|
|
119771
|
+
"tsconfig.spec.json",
|
|
119772
|
+
"vitest.unit.config.ts",
|
|
119773
|
+
".oxlintrc.json",
|
|
119774
|
+
".nvmrc",
|
|
119775
|
+
".yarnrc.yml",
|
|
119776
|
+
"!**/*.map",
|
|
119777
|
+
"!**/__tests__/**"
|
|
119778
|
+
],
|
|
119779
|
+
engines: {
|
|
119780
|
+
node: "^24.5.0",
|
|
119781
|
+
npm: "please-use-yarn",
|
|
119782
|
+
yarn: ">=4.0.2"
|
|
119783
|
+
},
|
|
119784
|
+
keywords: [
|
|
119785
|
+
"twenty-app"
|
|
119786
|
+
],
|
|
119787
|
+
packageManager: "yarn@4.13.0",
|
|
119788
|
+
scripts: {
|
|
119789
|
+
twenty: "twenty",
|
|
119790
|
+
app: "twenty",
|
|
119791
|
+
build: "yarn build:app && twenty dev:build",
|
|
119792
|
+
lint: "oxlint -c .oxlintrc.json .",
|
|
119793
|
+
"lint:fix": "oxlint --fix -c .oxlintrc.json .",
|
|
119794
|
+
typecheck: "tsc --noEmit -p tsconfig.spec.json",
|
|
119795
|
+
test: "vitest run --config vitest.unit.config.ts",
|
|
119796
|
+
"build:app": "vite build --config vite.app.config.ts"
|
|
119797
|
+
},
|
|
119798
|
+
devDependencies: {
|
|
119799
|
+
"@types/node": "^24.7.2",
|
|
119800
|
+
"@types/react": "^19.0.0",
|
|
119801
|
+
"@types/react-dom": "^19.0.0",
|
|
119802
|
+
oxlint: "^0.16.0",
|
|
119803
|
+
react: "^19.0.0",
|
|
119804
|
+
"react-dom": "^19.0.0",
|
|
119805
|
+
"twenty-client-sdk": "2.45.0",
|
|
119806
|
+
"twenty-sdk": "2.45.0",
|
|
119807
|
+
"twenty-ui": "2.45.0",
|
|
119808
|
+
typescript: "^5.9.3",
|
|
119809
|
+
vite: "^8.0.0",
|
|
119810
|
+
"vite-tsconfig-paths": "^4.2.1",
|
|
119811
|
+
vitest: "^4.0.0"
|
|
119812
|
+
},
|
|
119813
|
+
frontComponentSharedDependencies: [
|
|
119814
|
+
"react",
|
|
119815
|
+
"react-dom/client",
|
|
119816
|
+
"twenty-ui/primitives/input",
|
|
119817
|
+
"twenty-ui/primitives/data-display",
|
|
119818
|
+
"twenty-ui/theme",
|
|
119819
|
+
"twenty-ui/icon"
|
|
119820
|
+
]
|
|
119821
|
+
};
|
|
119822
|
+
|
|
119823
|
+
// src/server/docflow-app-page.ts
|
|
119824
|
+
var BX24_SDK_URL2 = "https://api.bitrix24.com/api/v1/";
|
|
119825
|
+
var buildAssetUrl = (workspaceId, file) => `/public-assets/${workspaceId}/${process.env.APPLICATION_ID ?? ""}/public/app/${file}?v=${encodeURIComponent(package_default.version)}`;
|
|
119826
|
+
var serializeConfig = (config) => JSON.stringify(config).replace(/</g, "\\u003c");
|
|
119827
|
+
var renderDocflowAppPage = ({
|
|
119828
|
+
workspaceId,
|
|
119829
|
+
config
|
|
119830
|
+
}) => new AL(
|
|
119831
|
+
`<!doctype html>
|
|
119832
|
+
<html lang="ru" class="dark">
|
|
119833
|
+
<head>
|
|
119834
|
+
<meta charset="utf-8">
|
|
119835
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
119836
|
+
<title>\u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u043E\u0431\u043E\u0440\u043E\u0442</title>
|
|
119837
|
+
<link rel="stylesheet" href="${escapeHtml(buildAssetUrl(workspaceId, "docflow-app.css"))}">
|
|
119838
|
+
<style>html, body, #root { height: 100%; margin: 0; } body { font-family: Inter, -apple-system, "Segoe UI", Roboto, sans-serif; }</style>
|
|
119839
|
+
${config.mode === "bitrix" ? `<script src="${BX24_SDK_URL2}"></script>` : ""}
|
|
119840
|
+
<script id="docflow-app-config" type="application/json">${serializeConfig(config)}</script>
|
|
119841
|
+
</head>
|
|
119842
|
+
<body>
|
|
119843
|
+
<div id="root"></div>
|
|
119844
|
+
<script src="${escapeHtml(buildAssetUrl(workspaceId, "docflow-app.js"))}"></script>
|
|
119845
|
+
</body>
|
|
119846
|
+
</html>`,
|
|
119847
|
+
{
|
|
119848
|
+
status: 200,
|
|
119849
|
+
headers: {
|
|
119850
|
+
"content-type": "text/html; charset=utf-8",
|
|
119851
|
+
"cache-control": "no-store"
|
|
119852
|
+
}
|
|
119853
|
+
}
|
|
119854
|
+
);
|
|
119855
|
+
|
|
119856
|
+
// src/shared/log.util.ts
|
|
119857
|
+
var PREFIX = "[docflow]";
|
|
119858
|
+
var describeError = (error) => {
|
|
119859
|
+
if (error instanceof Error) {
|
|
119860
|
+
const { status, body } = error;
|
|
119861
|
+
return { name: error.name, message: error.message, status, body };
|
|
119862
|
+
}
|
|
119863
|
+
return error;
|
|
119864
|
+
};
|
|
119865
|
+
var logDocflowError = (event, error, details) => console.error(PREFIX, event, describeError(error), details ?? "");
|
|
119866
|
+
|
|
119756
119867
|
// src/server/http-response.ts
|
|
119868
|
+
var jsonResponse = (status, body) => new AL(JSON.stringify(body), {
|
|
119869
|
+
status,
|
|
119870
|
+
headers: { "content-type": "application/json; charset=utf-8" }
|
|
119871
|
+
});
|
|
119757
119872
|
var htmlResponse = (status, html) => new AL(html, {
|
|
119758
119873
|
status,
|
|
119759
119874
|
headers: { "content-type": "text/html; charset=utf-8" }
|
|
119760
119875
|
});
|
|
119876
|
+
var withRouteErrors = (name, handler2) => async (...args) => {
|
|
119877
|
+
try {
|
|
119878
|
+
return await handler2(...args);
|
|
119879
|
+
} catch (error) {
|
|
119880
|
+
logDocflowError(`${name}: unexpected error`, error);
|
|
119881
|
+
return jsonResponse(500, {
|
|
119882
|
+
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)}`
|
|
119883
|
+
});
|
|
119884
|
+
}
|
|
119885
|
+
};
|
|
119761
119886
|
|
|
119762
119887
|
// src/universal-identifiers.ts
|
|
119763
119888
|
var BITRIX_APP_LOGIC_FUNCTION_UNIVERSAL_IDENTIFIER = "00fa5cea-d57b-4215-980a-c4bed9232a4f";
|
|
119764
119889
|
|
|
119765
119890
|
// src/logic-functions/bitrix-app.logic-function.ts
|
|
119766
|
-
var
|
|
119767
|
-
var getCrmUrl = () => {
|
|
119768
|
-
const value = process.env.CRM_PUBLIC_URL?.trim();
|
|
119769
|
-
return value !== void 0 && /^https?:\/\//.test(value) ? value.replace(/\/$/, "") : void 0;
|
|
119770
|
-
};
|
|
119771
|
-
var listOpenTasksForMember = async (memberId, crmUrl) => readRestList(
|
|
119772
|
-
await restClient("application").get("/rest/tasks", {
|
|
119773
|
-
query: {
|
|
119774
|
-
filter: restAnd(
|
|
119775
|
-
restEq("smbSection", DOCFLOW_SECTION),
|
|
119776
|
-
restEq("assigneeId", memberId),
|
|
119777
|
-
restOr(restNeq("status", TASK_DONE_STATUS), restIsNull("status"))
|
|
119778
|
-
),
|
|
119779
|
-
order_by: "dueAt[AscNullsLast]",
|
|
119780
|
-
limit: TASKS_SHOWN_IN_PORTAL
|
|
119781
|
-
}
|
|
119782
|
-
})
|
|
119783
|
-
).records.map((task) => ({
|
|
119784
|
-
title: task.title?.trim() || "\u0411\u0435\u0437 \u043D\u0430\u0437\u0432\u0430\u043D\u0438\u044F",
|
|
119785
|
-
url: crmUrl !== void 0 ? `${crmUrl}/object/task/${task.id}` : void 0,
|
|
119786
|
-
dueAt: typeof task.dueAt === "string" ? new Date(task.dueAt).toLocaleDateString("ru-RU") : void 0
|
|
119787
|
-
}));
|
|
119788
|
-
var handler = async (event) => {
|
|
119891
|
+
var handler = async (event, context) => {
|
|
119789
119892
|
const crmUrl = getCrmUrl();
|
|
119790
119893
|
if (!isBitrixConfigured()) {
|
|
119791
119894
|
return htmlResponse(
|
|
@@ -119794,7 +119897,6 @@ var handler = async (event) => {
|
|
|
119794
119897
|
title: "\u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u043E\u0431\u043E\u0440\u043E\u0442",
|
|
119795
119898
|
message: "\u0412 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430\u0445 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u0432 CRM \u043D\u0435 \u0443\u043A\u0430\u0437\u0430\u043D\u044B BITRIX_CLIENT_ID \u0438 BITRIX_CLIENT_SECRET.",
|
|
119796
119899
|
crmUrl,
|
|
119797
|
-
tasks: [],
|
|
119798
119900
|
isInstall: false
|
|
119799
119901
|
})
|
|
119800
119902
|
);
|
|
@@ -119820,22 +119922,20 @@ var handler = async (event) => {
|
|
|
119820
119922
|
title: "\u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u043E\u0431\u043E\u0440\u043E\u0442",
|
|
119821
119923
|
message: "\u0412 \u043F\u0440\u043E\u0444\u0438\u043B\u0435 \u0411\u0438\u0442\u0440\u0438\u043A\u044124 \u043D\u0435\u0442 \u043F\u043E\u0447\u0442\u044B \u2014 \u0431\u0435\u0437 \u043D\u0435\u0451 \u043D\u0435\u043B\u044C\u0437\u044F \u043D\u0430\u0439\u0442\u0438 \u0438\u043B\u0438 \u0441\u043E\u0437\u0434\u0430\u0442\u044C \u0441\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A\u0430 \u0432 CRM.",
|
|
119822
119924
|
crmUrl,
|
|
119823
|
-
tasks: [],
|
|
119824
119925
|
isInstall: false
|
|
119825
119926
|
})
|
|
119826
119927
|
);
|
|
119827
119928
|
}
|
|
119828
|
-
|
|
119829
|
-
|
|
119830
|
-
|
|
119831
|
-
|
|
119832
|
-
|
|
119833
|
-
|
|
119834
|
-
|
|
119835
|
-
|
|
119836
|
-
|
|
119837
|
-
|
|
119838
|
-
);
|
|
119929
|
+
return renderDocflowAppPage({
|
|
119930
|
+
workspaceId: context.workspaceId,
|
|
119931
|
+
config: {
|
|
119932
|
+
mode: "bitrix",
|
|
119933
|
+
crmUrl: crmUrl ?? "",
|
|
119934
|
+
section: readDocflowAppSection(event.queryStringParameters.section),
|
|
119935
|
+
expectedWorkspaceMemberId: member.id,
|
|
119936
|
+
portalDomain: portal.portalDomain
|
|
119937
|
+
}
|
|
119938
|
+
});
|
|
119839
119939
|
} catch (error) {
|
|
119840
119940
|
if (error instanceof BitrixError) {
|
|
119841
119941
|
return htmlResponse(
|
|
@@ -119844,7 +119944,6 @@ var handler = async (event) => {
|
|
|
119844
119944
|
title: "\u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u043E\u0431\u043E\u0440\u043E\u0442",
|
|
119845
119945
|
message: `\u0417\u0430\u043F\u0440\u043E\u0441 \u043F\u043E\u0440\u0442\u0430\u043B\u0430 \u043D\u0435 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0451\u043D: ${error.message}`,
|
|
119846
119946
|
crmUrl,
|
|
119847
|
-
tasks: [],
|
|
119848
119947
|
isInstall: false
|
|
119849
119948
|
})
|
|
119850
119949
|
);
|
|
@@ -119855,7 +119954,6 @@ var handler = async (event) => {
|
|
|
119855
119954
|
title: "\u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u043E\u0431\u043E\u0440\u043E\u0442",
|
|
119856
119955
|
message: error instanceof Error ? error.message : "\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u043E\u0442\u043A\u0440\u044B\u0442\u044C \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u043E\u0431\u043E\u0440\u043E\u0442 \u0434\u043B\u044F \u0432\u0430\u0448\u0435\u0433\u043E \u043F\u0440\u043E\u0444\u0438\u043B\u044F \u0411\u0438\u0442\u0440\u0438\u043A\u044124.",
|
|
119857
119956
|
crmUrl,
|
|
119858
|
-
tasks: [],
|
|
119859
119957
|
isInstall: false
|
|
119860
119958
|
})
|
|
119861
119959
|
);
|
|
@@ -119866,7 +119964,7 @@ var bitrix_app_logic_function_default = defineLogicFunction({
|
|
|
119866
119964
|
name: "docflow-bitrix-app",
|
|
119867
119965
|
description: "\u0421\u0442\u0440\u0430\u043D\u0438\u0446\u0430 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u043E\u0431\u043E\u0440\u043E\u0442\u0430 \u0432 \u043F\u043E\u0440\u0442\u0430\u043B\u0435 \u0411\u0438\u0442\u0440\u0438\u043A\u044124",
|
|
119868
119966
|
timeoutSeconds: 30,
|
|
119869
|
-
handler,
|
|
119967
|
+
handler: withRouteErrors("bitrix-app", handler),
|
|
119870
119968
|
httpRouteTriggerSettings: {
|
|
119871
119969
|
path: "/bitrix/app",
|
|
119872
119970
|
httpMethod: "POST",
|
|
@@ -1,57 +1,26 @@
|
|
|
1
1
|
import { defineLogicFunction } from 'twenty-sdk/define';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
type LogicFunctionExecutionContext,
|
|
4
|
+
type RoutePayload,
|
|
5
|
+
} from 'twenty-sdk/logic-function';
|
|
3
6
|
|
|
4
|
-
import { restAnd, restEq, restIsNull, restNeq, restOr } from 'src/shared/api/rest-filter.util';
|
|
5
|
-
import { readRestList } from 'src/shared/api/rest-response.util';
|
|
6
7
|
import { BitrixError, callBitrix, isBitrixConfigured } from 'src/shared/bitrix/bitrix-client';
|
|
7
8
|
import { type BitrixUserProfile } from 'src/shared/bitrix/bitrix-user.util';
|
|
8
9
|
import { parseBitrixRequest } from 'src/shared/bitrix/bitrix.util';
|
|
9
|
-
import {
|
|
10
|
+
import { readDocflowAppSection } from 'src/shared/app/docflow-app.util';
|
|
10
11
|
import { findOrCreateWorkspaceMemberFromBitrix } from 'src/server/bitrix-member';
|
|
11
12
|
import { proveAndLinkBitrixPortal } from 'src/server/bitrix-portal';
|
|
12
|
-
import { renderBitrixPage
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
13
|
+
import { renderBitrixPage } from 'src/server/bitrix-page';
|
|
14
|
+
import { getCrmUrl } from 'src/server/crm-url';
|
|
15
|
+
import { renderDocflowAppPage } from 'src/server/docflow-app-page';
|
|
16
|
+
import { htmlResponse, withRouteErrors } from 'src/server/http-response';
|
|
15
17
|
import { BITRIX_APP_LOGIC_FUNCTION_UNIVERSAL_IDENTIFIER } from 'src/universal-identifiers';
|
|
16
18
|
|
|
17
|
-
const TASKS_SHOWN_IN_PORTAL = 20;
|
|
18
|
-
|
|
19
|
-
const getCrmUrl = (): string | undefined => {
|
|
20
|
-
const value = process.env.CRM_PUBLIC_URL?.trim();
|
|
21
|
-
|
|
22
|
-
return value !== undefined && /^https?:\/\//.test(value)
|
|
23
|
-
? value.replace(/\/$/, '')
|
|
24
|
-
: undefined;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const listOpenTasksForMember = async (
|
|
28
|
-
memberId: string,
|
|
29
|
-
crmUrl: string | undefined,
|
|
30
|
-
): Promise<BitrixPageTask[]> =>
|
|
31
|
-
readRestList<{ id: string; title?: string | null; dueAt?: string | null }>(
|
|
32
|
-
await restClient('application').get('/rest/tasks', {
|
|
33
|
-
query: {
|
|
34
|
-
filter: restAnd(
|
|
35
|
-
restEq('smbSection', DOCFLOW_SECTION),
|
|
36
|
-
restEq('assigneeId', memberId),
|
|
37
|
-
restOr(restNeq('status', TASK_DONE_STATUS), restIsNull('status')),
|
|
38
|
-
),
|
|
39
|
-
order_by: 'dueAt[AscNullsLast]',
|
|
40
|
-
limit: TASKS_SHOWN_IN_PORTAL,
|
|
41
|
-
},
|
|
42
|
-
}),
|
|
43
|
-
).records.map((task) => ({
|
|
44
|
-
title: task.title?.trim() || 'Без названия',
|
|
45
|
-
url: crmUrl !== undefined ? `${crmUrl}/object/task/${task.id}` : undefined,
|
|
46
|
-
dueAt:
|
|
47
|
-
typeof task.dueAt === 'string'
|
|
48
|
-
? new Date(task.dueAt).toLocaleDateString('ru-RU')
|
|
49
|
-
: undefined,
|
|
50
|
-
}));
|
|
51
|
-
|
|
52
19
|
// "Путь вашего обработчика" of the local Bitrix24 application: the page a
|
|
53
|
-
// person sees when they open the app in the portal.
|
|
54
|
-
|
|
20
|
+
// person sees when they open the app in the portal. After the portal and the
|
|
21
|
+
// person are checked it is the standalone docflow page; it signs in to the
|
|
22
|
+
// CRM itself (the portal frame gets no CRM cookie).
|
|
23
|
+
const handler = async (event: RoutePayload, context: LogicFunctionExecutionContext) => {
|
|
55
24
|
const crmUrl = getCrmUrl();
|
|
56
25
|
|
|
57
26
|
if (!isBitrixConfigured()) {
|
|
@@ -61,7 +30,6 @@ const handler = async (event: RoutePayload) => {
|
|
|
61
30
|
title: 'Документооборот',
|
|
62
31
|
message: 'В настройках приложения в CRM не указаны BITRIX_CLIENT_ID и BITRIX_CLIENT_SECRET.',
|
|
63
32
|
crmUrl,
|
|
64
|
-
tasks: [],
|
|
65
33
|
isInstall: false,
|
|
66
34
|
}),
|
|
67
35
|
);
|
|
@@ -90,24 +58,21 @@ const handler = async (event: RoutePayload) => {
|
|
|
90
58
|
title: 'Документооборот',
|
|
91
59
|
message: 'В профиле Битрикс24 нет почты — без неё нельзя найти или создать сотрудника в CRM.',
|
|
92
60
|
crmUrl,
|
|
93
|
-
tasks: [],
|
|
94
61
|
isInstall: false,
|
|
95
62
|
}),
|
|
96
63
|
);
|
|
97
64
|
}
|
|
98
65
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}),
|
|
110
|
-
);
|
|
66
|
+
return renderDocflowAppPage({
|
|
67
|
+
workspaceId: context.workspaceId,
|
|
68
|
+
config: {
|
|
69
|
+
mode: 'bitrix',
|
|
70
|
+
crmUrl: crmUrl ?? '',
|
|
71
|
+
section: readDocflowAppSection(event.queryStringParameters.section),
|
|
72
|
+
expectedWorkspaceMemberId: member.id,
|
|
73
|
+
portalDomain: portal.portalDomain,
|
|
74
|
+
},
|
|
75
|
+
});
|
|
111
76
|
} catch (error) {
|
|
112
77
|
if (error instanceof BitrixError) {
|
|
113
78
|
return htmlResponse(
|
|
@@ -116,7 +81,6 @@ const handler = async (event: RoutePayload) => {
|
|
|
116
81
|
title: 'Документооборот',
|
|
117
82
|
message: `Запрос портала не подтверждён: ${error.message}`,
|
|
118
83
|
crmUrl,
|
|
119
|
-
tasks: [],
|
|
120
84
|
isInstall: false,
|
|
121
85
|
}),
|
|
122
86
|
);
|
|
@@ -131,7 +95,6 @@ const handler = async (event: RoutePayload) => {
|
|
|
131
95
|
? error.message
|
|
132
96
|
: 'Не удалось открыть документооборот для вашего профиля Битрикс24.',
|
|
133
97
|
crmUrl,
|
|
134
|
-
tasks: [],
|
|
135
98
|
isInstall: false,
|
|
136
99
|
}),
|
|
137
100
|
);
|
|
@@ -143,7 +106,7 @@ export default defineLogicFunction({
|
|
|
143
106
|
name: 'docflow-bitrix-app',
|
|
144
107
|
description: 'Страница документооборота в портале Битрикс24',
|
|
145
108
|
timeoutSeconds: 30,
|
|
146
|
-
handler,
|
|
109
|
+
handler: withRouteErrors('bitrix-app', handler),
|
|
147
110
|
httpRouteTriggerSettings: {
|
|
148
111
|
path: '/bitrix/app',
|
|
149
112
|
httpMethod: 'POST',
|
|
@@ -60049,11 +60049,32 @@ var loadBitrixPortal = () => kL.get(BITRIX_PORTAL_KV_KEY);
|
|
|
60049
60049
|
var saveBitrixPortal = (portal) => kL.set(BITRIX_PORTAL_KV_KEY, portal);
|
|
60050
60050
|
var forgetBitrixPortal = () => kL.delete(BITRIX_PORTAL_KV_KEY);
|
|
60051
60051
|
|
|
60052
|
+
// src/shared/log.util.ts
|
|
60053
|
+
var PREFIX = "[docflow]";
|
|
60054
|
+
var describeError = (error) => {
|
|
60055
|
+
if (error instanceof Error) {
|
|
60056
|
+
const { status, body } = error;
|
|
60057
|
+
return { name: error.name, message: error.message, status, body };
|
|
60058
|
+
}
|
|
60059
|
+
return error;
|
|
60060
|
+
};
|
|
60061
|
+
var logDocflowError = (event, error, details) => console.error(PREFIX, event, describeError(error), details ?? "");
|
|
60062
|
+
|
|
60052
60063
|
// src/server/http-response.ts
|
|
60053
60064
|
var jsonResponse = (status, body) => new AL(JSON.stringify(body), {
|
|
60054
60065
|
status,
|
|
60055
60066
|
headers: { "content-type": "application/json; charset=utf-8" }
|
|
60056
60067
|
});
|
|
60068
|
+
var withRouteErrors = (name, handler2) => async (...args) => {
|
|
60069
|
+
try {
|
|
60070
|
+
return await handler2(...args);
|
|
60071
|
+
} catch (error) {
|
|
60072
|
+
logDocflowError(`${name}: unexpected error`, error);
|
|
60073
|
+
return jsonResponse(500, {
|
|
60074
|
+
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)}`
|
|
60075
|
+
});
|
|
60076
|
+
}
|
|
60077
|
+
};
|
|
60057
60078
|
|
|
60058
60079
|
// src/universal-identifiers.ts
|
|
60059
60080
|
var BITRIX_EVENT_LOGIC_FUNCTION_UNIVERSAL_IDENTIFIER = "f27cfbdc-8e87-4e1a-ab37-fc2a8093946c";
|
|
@@ -60083,7 +60104,7 @@ var bitrix_event_logic_function_default = defineLogicFunction({
|
|
|
60083
60104
|
name: "docflow-bitrix-event",
|
|
60084
60105
|
description: "\u0421\u043E\u0431\u044B\u0442\u0438\u044F \u043F\u043E\u0440\u0442\u0430\u043B\u0430 \u0411\u0438\u0442\u0440\u0438\u043A\u044124 (\u0443\u0434\u0430\u043B\u0435\u043D\u0438\u0435 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F)",
|
|
60085
60106
|
timeoutSeconds: 15,
|
|
60086
|
-
handler,
|
|
60107
|
+
handler: withRouteErrors("bitrix-event", handler),
|
|
60087
60108
|
httpRouteTriggerSettings: {
|
|
60088
60109
|
path: "/bitrix/event",
|
|
60089
60110
|
httpMethod: "POST",
|
|
@@ -3,7 +3,7 @@ import { type RoutePayload } from 'twenty-sdk/logic-function';
|
|
|
3
3
|
|
|
4
4
|
import { parseBitrixRequest } from 'src/shared/bitrix/bitrix.util';
|
|
5
5
|
import { forgetBitrixPortal, loadBitrixPortal, saveBitrixPortal } from 'src/server/bitrix-portal';
|
|
6
|
-
import { jsonResponse } from 'src/server/http-response';
|
|
6
|
+
import { jsonResponse, withRouteErrors } from 'src/server/http-response';
|
|
7
7
|
import { BITRIX_EVENT_LOGIC_FUNCTION_UNIVERSAL_IDENTIFIER } from 'src/universal-identifiers';
|
|
8
8
|
|
|
9
9
|
// Events of the linked portal. An event must name the linked portal; the
|
|
@@ -45,7 +45,7 @@ export default defineLogicFunction({
|
|
|
45
45
|
name: 'docflow-bitrix-event',
|
|
46
46
|
description: 'События портала Битрикс24 (удаление приложения)',
|
|
47
47
|
timeoutSeconds: 15,
|
|
48
|
-
handler,
|
|
48
|
+
handler: withRouteErrors('bitrix-event', handler),
|
|
49
49
|
httpRouteTriggerSettings: {
|
|
50
50
|
path: '/bitrix/event',
|
|
51
51
|
httpMethod: 'POST',
|