@haiiro/docuflow 0.0.12 → 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 +38 -8
- package/manifest.json +99 -13
- 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 +3 -3
- package/src/front-components/docflow-processes.front-component.mjs +19 -19
- package/src/front-components/docflow-processes.front-component.tsx +18 -2
- package/src/front-components/docflow-tasks.front-component.mjs +3 -3
- 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 +24 -24
- package/src/front-components/process-steps.front-component.tsx +54 -9
- package/src/front-components/task-form.front-component.mjs +21 -21
- package/src/logic-functions/bitrix-app.logic-function.mjs +160 -87
- package/src/logic-functions/bitrix-app.logic-function.ts +22 -59
- 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/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/launch-process.logic-function.mjs +113 -29
- package/src/logic-functions/launch-process.logic-function.ts +83 -22
- package/src/logic-functions/save-launch-fields.logic-function.mjs +176 -9
- package/src/logic-functions/save-launch-fields.logic-function.ts +24 -6
|
@@ -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,23 +119730,129 @@ 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.13",
|
|
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
|
+
|
|
119756
119856
|
// src/server/http-response.ts
|
|
119757
119857
|
var htmlResponse = (status, html) => new AL(html, {
|
|
119758
119858
|
status,
|
|
@@ -119763,29 +119863,7 @@ var htmlResponse = (status, html) => new AL(html, {
|
|
|
119763
119863
|
var BITRIX_APP_LOGIC_FUNCTION_UNIVERSAL_IDENTIFIER = "00fa5cea-d57b-4215-980a-c4bed9232a4f";
|
|
119764
119864
|
|
|
119765
119865
|
// 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) => {
|
|
119866
|
+
var handler = async (event, context) => {
|
|
119789
119867
|
const crmUrl = getCrmUrl();
|
|
119790
119868
|
if (!isBitrixConfigured()) {
|
|
119791
119869
|
return htmlResponse(
|
|
@@ -119794,7 +119872,6 @@ var handler = async (event) => {
|
|
|
119794
119872
|
title: "\u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u043E\u0431\u043E\u0440\u043E\u0442",
|
|
119795
119873
|
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
119874
|
crmUrl,
|
|
119797
|
-
tasks: [],
|
|
119798
119875
|
isInstall: false
|
|
119799
119876
|
})
|
|
119800
119877
|
);
|
|
@@ -119820,22 +119897,20 @@ var handler = async (event) => {
|
|
|
119820
119897
|
title: "\u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u043E\u0431\u043E\u0440\u043E\u0442",
|
|
119821
119898
|
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
119899
|
crmUrl,
|
|
119823
|
-
tasks: [],
|
|
119824
119900
|
isInstall: false
|
|
119825
119901
|
})
|
|
119826
119902
|
);
|
|
119827
119903
|
}
|
|
119828
|
-
|
|
119829
|
-
|
|
119830
|
-
|
|
119831
|
-
|
|
119832
|
-
|
|
119833
|
-
|
|
119834
|
-
|
|
119835
|
-
|
|
119836
|
-
|
|
119837
|
-
|
|
119838
|
-
);
|
|
119904
|
+
return renderDocflowAppPage({
|
|
119905
|
+
workspaceId: context.workspaceId,
|
|
119906
|
+
config: {
|
|
119907
|
+
mode: "bitrix",
|
|
119908
|
+
crmUrl: crmUrl ?? "",
|
|
119909
|
+
section: readDocflowAppSection(event.queryStringParameters.section),
|
|
119910
|
+
expectedWorkspaceMemberId: member.id,
|
|
119911
|
+
portalDomain: portal.portalDomain
|
|
119912
|
+
}
|
|
119913
|
+
});
|
|
119839
119914
|
} catch (error) {
|
|
119840
119915
|
if (error instanceof BitrixError) {
|
|
119841
119916
|
return htmlResponse(
|
|
@@ -119844,7 +119919,6 @@ var handler = async (event) => {
|
|
|
119844
119919
|
title: "\u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u043E\u0431\u043E\u0440\u043E\u0442",
|
|
119845
119920
|
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
119921
|
crmUrl,
|
|
119847
|
-
tasks: [],
|
|
119848
119922
|
isInstall: false
|
|
119849
119923
|
})
|
|
119850
119924
|
);
|
|
@@ -119855,7 +119929,6 @@ var handler = async (event) => {
|
|
|
119855
119929
|
title: "\u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u043E\u0431\u043E\u0440\u043E\u0442",
|
|
119856
119930
|
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
119931
|
crmUrl,
|
|
119858
|
-
tasks: [],
|
|
119859
119932
|
isInstall: false
|
|
119860
119933
|
})
|
|
119861
119934
|
);
|
|
@@ -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 { renderBitrixPage } from 'src/server/bitrix-page';
|
|
14
|
+
import { getCrmUrl } from 'src/server/crm-url';
|
|
15
|
+
import { renderDocflowAppPage } from 'src/server/docflow-app-page';
|
|
13
16
|
import { htmlResponse } from 'src/server/http-response';
|
|
14
|
-
import { restClient } from 'src/server/records';
|
|
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
|
);
|
|
@@ -119538,7 +119538,6 @@ var renderBitrixPage = ({
|
|
|
119538
119538
|
title,
|
|
119539
119539
|
message,
|
|
119540
119540
|
crmUrl,
|
|
119541
|
-
tasks,
|
|
119542
119541
|
isInstall
|
|
119543
119542
|
}) => `<!doctype html>
|
|
119544
119543
|
<html lang="ru">
|
|
@@ -119552,19 +119551,12 @@ var renderBitrixPage = ({
|
|
|
119552
119551
|
h1 { font-size: 20px; margin: 0 0 8px; }
|
|
119553
119552
|
p { color: #666; margin: 0 0 16px; }
|
|
119554
119553
|
a.button { display: inline-block; padding: 8px 16px; border-radius: 8px; background: #1961ed; color: #fff; text-decoration: none; }
|
|
119555
|
-
ul { list-style: none; padding: 0; margin: 16px 0 0; }
|
|
119556
|
-
li { padding: 8px 0; border-top: 1px solid #eee; display: flex; justify-content: space-between; gap: 16px; }
|
|
119557
|
-
li a { color: #1961ed; text-decoration: none; }
|
|
119558
|
-
.due { color: #999; white-space: nowrap; }
|
|
119559
119554
|
</style>
|
|
119560
119555
|
</head>
|
|
119561
119556
|
<body>
|
|
119562
119557
|
<h1>${escapeHtml(title)}</h1>
|
|
119563
119558
|
<p>${escapeHtml(message)}</p>
|
|
119564
119559
|
${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>` : ""}
|
|
119565
|
-
${tasks.length > 0 ? `<ul>${tasks.map(
|
|
119566
|
-
(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>`
|
|
119567
|
-
).join("")}</ul>` : ""}
|
|
119568
119560
|
${isInstall ? "<script>if (window.BX24) { BX24.init(function () { BX24.installFinish(); }); }</script>" : ""}
|
|
119569
119561
|
</body>
|
|
119570
119562
|
</html>`;
|
|
@@ -119586,7 +119578,6 @@ var handler = async (event) => {
|
|
|
119586
119578
|
renderBitrixPage({
|
|
119587
119579
|
title: "\u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u043E\u0431\u043E\u0440\u043E\u0442",
|
|
119588
119580
|
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.",
|
|
119589
|
-
tasks: [],
|
|
119590
119581
|
isInstall: false
|
|
119591
119582
|
})
|
|
119592
119583
|
);
|
|
@@ -119613,7 +119604,6 @@ var handler = async (event) => {
|
|
|
119613
119604
|
renderBitrixPage({
|
|
119614
119605
|
title: "\u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u043E\u0431\u043E\u0440\u043E\u0442 \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0451\u043D",
|
|
119615
119606
|
message: `\u041F\u043E\u0440\u0442\u0430\u043B ${portal.portalDomain} \u0441\u0432\u044F\u0437\u0430\u043D \u0441 CRM.`,
|
|
119616
|
-
tasks: [],
|
|
119617
119607
|
isInstall: true
|
|
119618
119608
|
})
|
|
119619
119609
|
);
|
|
@@ -119623,7 +119613,6 @@ var handler = async (event) => {
|
|
|
119623
119613
|
renderBitrixPage({
|
|
119624
119614
|
title: "\u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u043E\u0431\u043E\u0440\u043E\u0442",
|
|
119625
119615
|
message: error instanceof BitrixError ? `\u041F\u043E\u0440\u0442\u0430\u043B \u043D\u0435 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0451\u043D: ${error.message}` : "\u041F\u043E\u0440\u0442\u0430\u043B \u043D\u0435 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0451\u043D.",
|
|
119626
|
-
tasks: [],
|
|
119627
119616
|
isInstall: false
|
|
119628
119617
|
})
|
|
119629
119618
|
);
|
|
@@ -17,7 +17,6 @@ const handler = async (event: RoutePayload) => {
|
|
|
17
17
|
renderBitrixPage({
|
|
18
18
|
title: 'Документооборот',
|
|
19
19
|
message: 'В настройках приложения в CRM не указаны BITRIX_CLIENT_ID и BITRIX_CLIENT_SECRET.',
|
|
20
|
-
tasks: [],
|
|
21
20
|
isInstall: false,
|
|
22
21
|
}),
|
|
23
22
|
);
|
|
@@ -47,7 +46,6 @@ const handler = async (event: RoutePayload) => {
|
|
|
47
46
|
renderBitrixPage({
|
|
48
47
|
title: 'Документооборот подключён',
|
|
49
48
|
message: `Портал ${portal.portalDomain} связан с CRM.`,
|
|
50
|
-
tasks: [],
|
|
51
49
|
isInstall: true,
|
|
52
50
|
}),
|
|
53
51
|
);
|
|
@@ -60,7 +58,6 @@ const handler = async (event: RoutePayload) => {
|
|
|
60
58
|
error instanceof BitrixError
|
|
61
59
|
? `Портал не подтверждён: ${error.message}`
|
|
62
60
|
: 'Портал не подтверждён.',
|
|
63
|
-
tasks: [],
|
|
64
61
|
isInstall: false,
|
|
65
62
|
}),
|
|
66
63
|
);
|