@conduction/nextcloud-vue 2.79.0 → 2.80.0
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/dist/esm/components/CnActionButtons/CnActionButtons.vue2.js.map +1 -1
- package/dist/esm/components/CnActionButtons/CnActionButtons.vue3.js +3 -1
- package/dist/esm/components/CnActionButtons/CnActionButtons.vue3.js.map +1 -1
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js +32 -3
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js.map +1 -1
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js +10 -8
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js.map +1 -1
- package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js +39 -3
- package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js +79 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js +133 -96
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +1 -0
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +62 -4
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js +24 -0
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js +43 -4
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue.js +11 -0
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue.js.map +1 -0
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js +736 -0
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js +238 -0
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnFactsWidget/index.js +30 -0
- package/dist/esm/components/CnFactsWidget/index.js.map +1 -0
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue.js +10 -0
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue.js.map +1 -0
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue2.js +551 -0
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue3.js +183 -0
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnFieldListWidget/index.js +29 -0
- package/dist/esm/components/CnFieldListWidget/index.js.map +1 -0
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js +65 -17
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js.map +1 -1
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js +4 -4
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js.map +1 -1
- package/dist/esm/components/CnFormPage/CnFormPage.vue2.js +18 -3
- package/dist/esm/components/CnFormPage/CnFormPage.vue2.js.map +1 -1
- package/dist/esm/components/CnFormPage/CnFormPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +305 -72
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +31 -13
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue.js +10 -0
- package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue.js.map +1 -0
- package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue2.js +99 -0
- package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue2.js.map +1 -0
- package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue3.js +48 -0
- package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue3.js.map +1 -0
- package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue2.js +29 -1
- package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue2.js.map +1 -1
- package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue3.js.map +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +10 -0
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js.map +1 -0
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +387 -0
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js +169 -0
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnRecordListWidget/index.js +31 -0
- package/dist/esm/components/CnRecordListWidget/index.js.map +1 -0
- package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue.js +10 -0
- package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue.js.map +1 -0
- package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue2.js +351 -0
- package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue3.js +71 -0
- package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnSectionsWidget/index.js +35 -0
- package/dist/esm/components/CnSectionsWidget/index.js.map +1 -0
- package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js +81 -2
- package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js +1 -0
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +122 -7
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +84 -23
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +4 -0
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
- package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue2.js +106 -2
- package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue3.js +105 -53
- package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue3.js.map +1 -1
- package/dist/esm/composables/useFormDraft.js +140 -9
- package/dist/esm/composables/useFormDraft.js.map +1 -1
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue2.js +28 -20
- package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue3.js +9 -0
- package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/field-inspection.js +21 -0
- package/dist/esm/integrations/builtin/field-inspection.js.map +1 -1
- package/dist/esm/integrations/offline/checklistSubmission.js +141 -0
- package/dist/esm/integrations/offline/checklistSubmission.js.map +1 -0
- package/dist/esm/integrations/offline/fieldCollectionHelpers.js +70 -5
- package/dist/esm/integrations/offline/fieldCollectionHelpers.js.map +1 -1
- package/dist/esm/integrations/offline/index.js +2 -1
- package/dist/esm/integrations/offline/index.js.map +1 -1
- package/dist/esm/integrations/offline/offlineDb.js +6 -1
- package/dist/esm/integrations/offline/offlineDb.js.map +1 -1
- package/dist/esm/integrations/offline/syncReplayService.js +8 -2
- package/dist/esm/integrations/offline/syncReplayService.js.map +1 -1
- package/dist/esm/l10n/en.json.js +12 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +16 -2
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/nextcloud-vue.css +1000 -59
- package/dist/esm/utils/detailActionModel.js +60 -3
- package/dist/esm/utils/detailActionModel.js.map +1 -1
- package/dist/esm/utils/fillTemplate.js +114 -0
- package/dist/esm/utils/fillTemplate.js.map +1 -0
- package/dist/esm/utils/libraryWidgetKeys.js +4 -0
- package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
- package/dist/esm/utils/queryPresets.js +96 -0
- package/dist/esm/utils/queryPresets.js.map +1 -0
- package/dist/esm/utils/resolveFilterTokens.js +11 -0
- package/dist/esm/utils/resolveFilterTokens.js.map +1 -1
- package/dist/esm/utils/schema.js +21 -0
- package/dist/esm/utils/schema.js.map +1 -1
- package/dist/esm/utils/sentinelTokens.js +3 -3
- package/dist/esm/utils/sentinelTokens.js.map +1 -1
- package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/esm/utils/widgetDispatch.js +7 -1
- package/dist/esm/utils/widgetDispatch.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +12368 -7717
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +1000 -59
- package/l10n/en.json +12 -1
- package/l10n/nl.json +16 -2
- package/package.json +1 -1
- package/src/components/CnActionButtons/CnActionButtons.vue +2 -0
- package/src/components/CnActionsBar/CnActionsBar.md +4 -0
- package/src/components/CnActionsBar/CnActionsBar.vue +42 -10
- package/src/components/CnBannerWidget/CnBannerWidget.vue +39 -3
- package/src/components/CnCellRenderer/CnCellRenderer.vue +188 -1
- package/src/components/CnDataTable/CnDataTable.vue +1 -0
- package/src/components/CnDetailPage/CnDetailPage.md +1 -1
- package/src/components/CnDetailPage/CnDetailPage.vue +63 -3
- package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +66 -0
- package/src/components/CnFactsWidget/CnFactsWidget.vue +1050 -0
- package/src/components/CnFactsWidget/index.js +29 -0
- package/src/components/CnFieldListWidget/CnFieldListWidget.vue +746 -0
- package/src/components/CnFieldListWidget/index.js +28 -0
- package/src/components/CnFormDialog/CnFormDialog.md +9 -3
- package/src/components/CnFormDialog/CnFormDialog.vue +69 -21
- package/src/components/CnFormPage/CnFormPage.vue +18 -3
- package/src/components/CnIndexPage/CnIndexPage.vue +254 -6
- package/src/components/CnIndexPage/CnIndexPageWidgets.vue +169 -0
- package/src/components/CnPageRenderer/CnPageRenderer.vue +29 -1
- package/src/components/CnRecordListWidget/CnRecordListWidget.vue +603 -0
- package/src/components/CnRecordListWidget/index.js +30 -0
- package/src/components/CnSectionsWidget/CnSectionsWidget.vue +489 -0
- package/src/components/CnSectionsWidget/index.js +34 -0
- package/src/components/CnStagesWidget/CnStagesWidget.vue +81 -2
- package/src/components/CnStatWidget/CnStatWidget.vue +1 -1
- package/src/components/CnTabsWidget/CnTabsWidget.vue +184 -8
- package/src/components/CnWidgetGrid/registerDashboardWidgets.js +4 -0
- package/src/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue +188 -4
- package/src/components/index.js +4 -0
- package/src/composables/__tests__/useFormDraft.spec.js +69 -0
- package/src/composables/useFormDraft.js +139 -8
- package/src/css/form-field.css +14 -0
- package/src/css/index-page.css +71 -0
- package/src/css/kpi-card.css +32 -0
- package/src/css/look-board-detail.css +77 -0
- package/src/css/look-board-index.css +51 -0
- package/src/css/look-board.css +37 -2
- package/src/css/table.css +19 -0
- package/src/index.js +4 -0
- package/src/integrations/builtin/field-inspection/CnFieldInspectionCard.vue +35 -20
- package/src/integrations/builtin/field-inspection.js +21 -0
- package/src/integrations/offline/checklistSubmission.js +137 -0
- package/src/integrations/offline/fieldCollectionHelpers.js +69 -4
- package/src/integrations/offline/index.js +3 -0
- package/src/integrations/offline/offlineDb.js +6 -1
- package/src/integrations/offline/syncReplayService.js +8 -2
- package/src/schemas/app-manifest-v2.schema.json +104 -5
- package/src/utils/detailActionModel.js +59 -2
- package/src/utils/fillTemplate.js +110 -0
- package/src/utils/libraryWidgetKeys.js +4 -0
- package/src/utils/queryPresets.js +93 -0
- package/src/utils/resolveFilterTokens.js +11 -0
- package/src/utils/schema.js +21 -0
- package/src/utils/sentinelTokens.js +3 -3
- package/src/utils/validateManifestV2.compiled.js +3 -3
- package/src/utils/widgetDispatch.js +7 -1
|
@@ -36,7 +36,8 @@ function objectsUrl(register, schema) {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
|
-
* Replay one queued mutation against the OR object API
|
|
39
|
+
* Replay one queued mutation against the OR object API, or, for a row that
|
|
40
|
+
* names an `endpoint`, as one POST to that endpoint.
|
|
40
41
|
*
|
|
41
42
|
* @param {object} operation The queue operation row.
|
|
42
43
|
* @param {object} [offlineConfig] The leaf's offline config (`register`,
|
|
@@ -55,7 +56,12 @@ async function replayOperation(operation, offlineConfig = {}) {
|
|
|
55
56
|
|
|
56
57
|
try {
|
|
57
58
|
let response;
|
|
58
|
-
if (operation.
|
|
59
|
+
if (typeof operation.endpoint === 'string' && operation.endpoint !== '') {
|
|
60
|
+
// A run the app checks and stores itself (a completed task, say):
|
|
61
|
+
// one POST to its endpoint under the Nextcloud root. The endpoint
|
|
62
|
+
// decides access from what it has stored, as the object API does.
|
|
63
|
+
response = await axios__default.post(generateUrl(operation.endpoint), payload);
|
|
64
|
+
} else if (operation.operationType === 'create' || operation.operationType === 'upload') {
|
|
59
65
|
response = await axios__default.post(base, payload);
|
|
60
66
|
} else if (operation.operationType === 'update') {
|
|
61
67
|
response = await axios__default.put(`${base}/${operation.targetId}`, payload);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syncReplayService.js","sources":["../../../../src/integrations/offline/syncReplayService.js"],"sourcesContent":["/**\n * SPDX-FileCopyrightText: 2026 Conduction B.V. <info@conduction.nl>\n * SPDX-License-Identifier: EUPL-1.2\n *\n * Generic sync-replay glue for the offline data-collection core.\n *\n * Drains the device's queued mutations against the standard OpenRegister\n * object API on reconnect and applies the pure-engine status transition to each\n * queue row. Unlike procest's bespoke service this carries no app-specific\n * outcome callback: re-authorization happens inside OR's own object API (RBAC +\n * multitenancy on `/apps/openregister/api/objects/...`), so any consuming app\n * gets conflict marking, backoff and IDOR-safe replay for free.\n *\n * Browser-only (axios + IndexedDB + navigator.onLine). The decision logic it\n * calls is the pure {@link module:integrations/offline/syncQueueEngine}.\n *\n * @module integrations/offline/syncReplayService\n */\n\nimport axios from '@nextcloud/axios'\nimport { generateUrl } from '@nextcloud/router'\nimport { openDb, recordConflict } from './offlineDb.js'\nimport { nextState, orderForReplay } from './syncQueueEngine.js'\n\n/**\n * Build the OR object-collection URL for a register/schema.\n *\n * @param {string} register Register slug or id.\n * @param {string} schema Schema slug or id.\n *\n * @return {string} The generated collection URL.\n */\nfunction objectsUrl(register, schema) {\n\treturn generateUrl(`/apps/openregister/api/objects/${register}/${schema}`)\n}\n\n/**\n * Replay one queued mutation against the OR object API.\n *\n * @param {object} operation The queue operation row.\n * @param {object} [offlineConfig] The leaf's offline config (`register`,\n * `conflictSchema`).\n *\n * @return {Promise<object>} The applied patch from the engine.\n */\nexport async function replayOperation(operation, offlineConfig = {}) {\n\tconst db = await openDb()\n\tlet statusCode\n\tlet serverObject = null\n\tlet responseBody = null\n\n\tconst base = objectsUrl(operation.register, operation.schema)\n\tconst payload = operation.payload ?? {}\n\n\ttry {\n\t\tlet response\n\t\tif (operation.operationType === 'create' || operation.operationType === 'upload') {\n\t\t\tresponse = await axios.post(base, payload)\n\t\t} else if (operation.operationType === 'update') {\n\t\t\tresponse = await axios.put(`${base}/${operation.targetId}`, payload)\n\t\t} else if (operation.operationType === 'delete') {\n\t\t\tresponse = await axios.delete(`${base}/${operation.targetId}`)\n\t\t} else {\n\t\t\tresponse = await axios.post(base, payload)\n\t\t}\n\t\tstatusCode = response.status\n\t\tresponseBody = response.data ?? null\n\t} catch (error) {\n\t\tstatusCode = error?.response?.status ?? 0\n\t\tserverObject = error?.response?.data ?? null\n\t}\n\n\tconst { patch, conflictType } = nextState(operation, { statusCode, serverObject })\n\n\t// The id the server gave this object, kept so a later write can address it.\n\t// Without it a conflict record is write-once: the resolution somebody makes\n\t// an hour later has nowhere to go, and the register holds a collision with\n\t// no outcome, which answers neither of the questions it was filed for.\n\tconst serverObjectId = idOf(responseBody)\n\tif (patch.status === 'synced' && serverObjectId !== '') {\n\t\tpatch.serverObjectId = serverObjectId\n\t}\n\n\tawait db.mutationQueue.update(operation.id, patch)\n\n\t// A conflict is recorded where other people can see it, not only here.\n\t// `permission_lost` is recorded too: it lands as `failed` rather than\n\t// `conflict`, and it is precisely the case where the person holding the\n\t// capture can do nothing and somebody else must.\n\tif (conflictType !== null) {\n\t\tawait recordConflict({\n\t\t\toperation,\n\t\t\tconflictType,\n\t\t\tserverObject,\n\t\t\tregister: offlineConfig.register ?? '',\n\t\t\tconflictSchema: offlineConfig.conflictSchema ?? '',\n\t\t})\n\t}\n\n\treturn patch\n}\n\n/**\n * The id inside an OpenRegister object response, wherever it is carried.\n *\n * @param {object|null} body The response body.\n *\n * @return {string} The id, or an empty string.\n */\nfunction idOf(body) {\n\tif (body === null || typeof body !== 'object') {\n\t\treturn ''\n\t}\n\treturn String(body.id ?? body['@self']?.id ?? body.uuid ?? '')\n}\n\n/**\n * Drain the device's pending queue in FIFO order.\n *\n * @param {string} deviceId The owning device.\n * @param {object} [offlineConfig] The leaf's offline config; `register` and\n * `conflictSchema` decide where a conflict is\n * filed. Omitted, conflicts stay on the device\n * and the queue row says so.\n *\n * @return {Promise<{ processed: number, synced: number, conflicts: number, failed: number }>}\n */\nexport async function drainQueue(deviceId, offlineConfig = {}) {\n\tif (typeof navigator !== 'undefined' && navigator.onLine === false) {\n\t\treturn { processed: 0, synced: 0, conflicts: 0, failed: 0 }\n\t}\n\n\tconst db = await openDb()\n\tconst rows = await db.mutationQueue.where('deviceId').equals(deviceId).toArray()\n\tconst ordered = orderForReplay(rows)\n\n\tconst tally = { processed: 0, synced: 0, conflicts: 0, failed: 0 }\n\tfor (const operation of ordered) {\n\t\tconst patch = await replayOperation(operation, offlineConfig)\n\t\ttally.processed += 1\n\t\tif (patch.status === 'synced') {\n\t\t\ttally.synced += 1\n\t\t} else if (patch.status === 'conflict') {\n\t\t\ttally.conflicts += 1\n\t\t} else if (patch.status === 'failed') {\n\t\t\ttally.failed += 1\n\t\t}\n\t}\n\n\treturn tally\n}\n"],"names":["axios"],"mappings":";;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE;AACtC,CAAC,OAAO,WAAW,CAAC,CAAC,+BAA+B,EAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAC3E,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,eAAe,eAAe,CAAC,SAAS,EAAE,aAAa,GAAG,EAAE,EAAE;AACrE,CAAC,MAAM,EAAE,GAAG,MAAM,MAAM,GAAE;AAC1B,CAAC,IAAI,WAAU;AACf,CAAC,IAAI,YAAY,GAAG,KAAI;AACxB,CAAC,IAAI,YAAY,GAAG,KAAI;AACxB;AACA,CAAC,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,MAAM,EAAC;AAC9D,CAAC,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,IAAI,GAAE;AACxC;AACA,CAAC,IAAI;AACL,EAAE,IAAI,SAAQ;AACd,EAAE,IAAI,SAAS,CAAC,aAAa,KAAK,QAAQ,IAAI,SAAS,CAAC,aAAa,KAAK,QAAQ,EAAE;
|
|
1
|
+
{"version":3,"file":"syncReplayService.js","sources":["../../../../src/integrations/offline/syncReplayService.js"],"sourcesContent":["/**\n * SPDX-FileCopyrightText: 2026 Conduction B.V. <info@conduction.nl>\n * SPDX-License-Identifier: EUPL-1.2\n *\n * Generic sync-replay glue for the offline data-collection core.\n *\n * Drains the device's queued mutations against the standard OpenRegister\n * object API on reconnect and applies the pure-engine status transition to each\n * queue row. Unlike procest's bespoke service this carries no app-specific\n * outcome callback: re-authorization happens inside OR's own object API (RBAC +\n * multitenancy on `/apps/openregister/api/objects/...`), so any consuming app\n * gets conflict marking, backoff and IDOR-safe replay for free.\n *\n * Browser-only (axios + IndexedDB + navigator.onLine). The decision logic it\n * calls is the pure {@link module:integrations/offline/syncQueueEngine}.\n *\n * @module integrations/offline/syncReplayService\n */\n\nimport axios from '@nextcloud/axios'\nimport { generateUrl } from '@nextcloud/router'\nimport { openDb, recordConflict } from './offlineDb.js'\nimport { nextState, orderForReplay } from './syncQueueEngine.js'\n\n/**\n * Build the OR object-collection URL for a register/schema.\n *\n * @param {string} register Register slug or id.\n * @param {string} schema Schema slug or id.\n *\n * @return {string} The generated collection URL.\n */\nfunction objectsUrl(register, schema) {\n\treturn generateUrl(`/apps/openregister/api/objects/${register}/${schema}`)\n}\n\n/**\n * Replay one queued mutation against the OR object API, or, for a row that\n * names an `endpoint`, as one POST to that endpoint.\n *\n * @param {object} operation The queue operation row.\n * @param {object} [offlineConfig] The leaf's offline config (`register`,\n * `conflictSchema`).\n *\n * @return {Promise<object>} The applied patch from the engine.\n */\nexport async function replayOperation(operation, offlineConfig = {}) {\n\tconst db = await openDb()\n\tlet statusCode\n\tlet serverObject = null\n\tlet responseBody = null\n\n\tconst base = objectsUrl(operation.register, operation.schema)\n\tconst payload = operation.payload ?? {}\n\n\ttry {\n\t\tlet response\n\t\tif (typeof operation.endpoint === 'string' && operation.endpoint !== '') {\n\t\t\t// A run the app checks and stores itself (a completed task, say):\n\t\t\t// one POST to its endpoint under the Nextcloud root. The endpoint\n\t\t\t// decides access from what it has stored, as the object API does.\n\t\t\tresponse = await axios.post(generateUrl(operation.endpoint), payload)\n\t\t} else if (operation.operationType === 'create' || operation.operationType === 'upload') {\n\t\t\tresponse = await axios.post(base, payload)\n\t\t} else if (operation.operationType === 'update') {\n\t\t\tresponse = await axios.put(`${base}/${operation.targetId}`, payload)\n\t\t} else if (operation.operationType === 'delete') {\n\t\t\tresponse = await axios.delete(`${base}/${operation.targetId}`)\n\t\t} else {\n\t\t\tresponse = await axios.post(base, payload)\n\t\t}\n\t\tstatusCode = response.status\n\t\tresponseBody = response.data ?? null\n\t} catch (error) {\n\t\tstatusCode = error?.response?.status ?? 0\n\t\tserverObject = error?.response?.data ?? null\n\t}\n\n\tconst { patch, conflictType } = nextState(operation, { statusCode, serverObject })\n\n\t// The id the server gave this object, kept so a later write can address it.\n\t// Without it a conflict record is write-once: the resolution somebody makes\n\t// an hour later has nowhere to go, and the register holds a collision with\n\t// no outcome, which answers neither of the questions it was filed for.\n\tconst serverObjectId = idOf(responseBody)\n\tif (patch.status === 'synced' && serverObjectId !== '') {\n\t\tpatch.serverObjectId = serverObjectId\n\t}\n\n\tawait db.mutationQueue.update(operation.id, patch)\n\n\t// A conflict is recorded where other people can see it, not only here.\n\t// `permission_lost` is recorded too: it lands as `failed` rather than\n\t// `conflict`, and it is precisely the case where the person holding the\n\t// capture can do nothing and somebody else must.\n\tif (conflictType !== null) {\n\t\tawait recordConflict({\n\t\t\toperation,\n\t\t\tconflictType,\n\t\t\tserverObject,\n\t\t\tregister: offlineConfig.register ?? '',\n\t\t\tconflictSchema: offlineConfig.conflictSchema ?? '',\n\t\t})\n\t}\n\n\treturn patch\n}\n\n/**\n * The id inside an OpenRegister object response, wherever it is carried.\n *\n * @param {object|null} body The response body.\n *\n * @return {string} The id, or an empty string.\n */\nfunction idOf(body) {\n\tif (body === null || typeof body !== 'object') {\n\t\treturn ''\n\t}\n\treturn String(body.id ?? body['@self']?.id ?? body.uuid ?? '')\n}\n\n/**\n * Drain the device's pending queue in FIFO order.\n *\n * @param {string} deviceId The owning device.\n * @param {object} [offlineConfig] The leaf's offline config; `register` and\n * `conflictSchema` decide where a conflict is\n * filed. Omitted, conflicts stay on the device\n * and the queue row says so.\n *\n * @return {Promise<{ processed: number, synced: number, conflicts: number, failed: number }>}\n */\nexport async function drainQueue(deviceId, offlineConfig = {}) {\n\tif (typeof navigator !== 'undefined' && navigator.onLine === false) {\n\t\treturn { processed: 0, synced: 0, conflicts: 0, failed: 0 }\n\t}\n\n\tconst db = await openDb()\n\tconst rows = await db.mutationQueue.where('deviceId').equals(deviceId).toArray()\n\tconst ordered = orderForReplay(rows)\n\n\tconst tally = { processed: 0, synced: 0, conflicts: 0, failed: 0 }\n\tfor (const operation of ordered) {\n\t\tconst patch = await replayOperation(operation, offlineConfig)\n\t\ttally.processed += 1\n\t\tif (patch.status === 'synced') {\n\t\t\ttally.synced += 1\n\t\t} else if (patch.status === 'conflict') {\n\t\t\ttally.conflicts += 1\n\t\t} else if (patch.status === 'failed') {\n\t\t\ttally.failed += 1\n\t\t}\n\t}\n\n\treturn tally\n}\n"],"names":["axios"],"mappings":"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"}
|
package/dist/esm/l10n/en.json.js
CHANGED
|
@@ -66,6 +66,7 @@ var translations = {
|
|
|
66
66
|
"Follow this record to get its updates": "Follow this record to get its updates",
|
|
67
67
|
"You will see it under Following. This register sends no change notifications.": "You will see it under Following. This register sends no change notifications.",
|
|
68
68
|
"Since {date}": "Since {date}",
|
|
69
|
+
"since {date}": "since {date}",
|
|
69
70
|
"Remove {name} as a follower": "Remove {name} as a follower",
|
|
70
71
|
"Could not change following.": "Could not change following.",
|
|
71
72
|
"Could not add this colleague.": "Could not add this colleague.",
|
|
@@ -225,6 +226,7 @@ var translations = {
|
|
|
225
226
|
"Access URL": "Access URL",
|
|
226
227
|
Action: "Action",
|
|
227
228
|
Actions: "Actions",
|
|
229
|
+
optional: "optional",
|
|
228
230
|
Add: "Add",
|
|
229
231
|
"Add condition": "Add condition",
|
|
230
232
|
"Add enum value": "Add enum value",
|
|
@@ -299,6 +301,9 @@ var translations = {
|
|
|
299
301
|
Constant: "Constant",
|
|
300
302
|
Copy: "Copy",
|
|
301
303
|
Copied: "Copied",
|
|
304
|
+
Show: "Show",
|
|
305
|
+
"Copy {label}": "Copy {label}",
|
|
306
|
+
"Show {label}": "Show {label}",
|
|
302
307
|
"Copy item": "Copy item",
|
|
303
308
|
"Copy items": "Copy items",
|
|
304
309
|
"Copy of {name}": "Copy of {name}",
|
|
@@ -793,6 +798,7 @@ var translations = {
|
|
|
793
798
|
"View all ({total})": "View all ({total})",
|
|
794
799
|
"No items": "No items",
|
|
795
800
|
"Nothing here yet": "Nothing here yet",
|
|
801
|
+
"This list could not be loaded.": "This list could not be loaded.",
|
|
796
802
|
"No items match this filter": "No items match this filter",
|
|
797
803
|
"Could not load these records": "Could not load these records",
|
|
798
804
|
"No conversations yet": "No conversations yet",
|
|
@@ -1360,9 +1366,14 @@ var translations = {
|
|
|
1360
1366
|
"Quick filters": "Quick filters",
|
|
1361
1367
|
"{count} filters": "{count} filters",
|
|
1362
1368
|
"{count} more filters": "{count} more filters",
|
|
1363
|
-
"{label} — show the other filters": "{label} — show the other filters"
|
|
1369
|
+
"{label} — show the other filters": "{label} — show the other filters",
|
|
1370
|
+
"{view}: not available on this list": "{view}: not available on this list"
|
|
1364
1371
|
};
|
|
1365
1372
|
var plurals = {
|
|
1373
|
+
"{count} selected": [
|
|
1374
|
+
"{count} selected",
|
|
1375
|
+
"{count} selected"
|
|
1376
|
+
],
|
|
1366
1377
|
"%n year": [
|
|
1367
1378
|
"%n year",
|
|
1368
1379
|
"%n years"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/esm/l10n/nl.json.js
CHANGED
|
@@ -66,6 +66,7 @@ var translations = {
|
|
|
66
66
|
"Follow this record to get its updates": "Volg dit dossier om de wijzigingen te ontvangen",
|
|
67
67
|
"You will see it under Following. This register sends no change notifications.": "U ziet het onder Volgend. Dit register stuurt geen wijzigingsmeldingen.",
|
|
68
68
|
"Since {date}": "Sinds {date}",
|
|
69
|
+
"since {date}": "sinds {date}",
|
|
69
70
|
"Remove {name} as a follower": "{name} als volger verwijderen",
|
|
70
71
|
"Could not change following.": "Volgen kon niet worden gewijzigd.",
|
|
71
72
|
"Could not add this colleague.": "Deze collega kon niet worden toegevoegd.",
|
|
@@ -224,6 +225,7 @@ var translations = {
|
|
|
224
225
|
"Access URL": "Toegangs-URL",
|
|
225
226
|
Action: "Actie",
|
|
226
227
|
Actions: "Acties",
|
|
228
|
+
optional: "niet verplicht",
|
|
227
229
|
Add: "Toevoegen",
|
|
228
230
|
"Add condition": "Voorwaarde toevoegen",
|
|
229
231
|
"Add enum value": "Opsommingswaarde toevoegen",
|
|
@@ -298,6 +300,9 @@ var translations = {
|
|
|
298
300
|
Constant: "Constante",
|
|
299
301
|
Copy: "Kopiëren",
|
|
300
302
|
Copied: "Gekopieerd",
|
|
303
|
+
Show: "Tonen",
|
|
304
|
+
"Copy {label}": "{label} kopiëren",
|
|
305
|
+
"Show {label}": "{label} tonen",
|
|
301
306
|
"Copy item": "Item kopiëren",
|
|
302
307
|
"Copy items": "Items kopiëren",
|
|
303
308
|
"Copy of {name}": "Kopie van {name}",
|
|
@@ -568,6 +573,10 @@ var translations = {
|
|
|
568
573
|
Open: "Openen",
|
|
569
574
|
"Open access:": "Openbare toegang:",
|
|
570
575
|
"Open row": "Rij openen",
|
|
576
|
+
"Select all rows": "Alle rijen selecteren",
|
|
577
|
+
"Select row": "Rij selecteren",
|
|
578
|
+
"Scrollable table": "Scrollbare tabel",
|
|
579
|
+
"{title} — scrollable table": "{title}, scrollbare tabel",
|
|
571
580
|
Operator: "Operator",
|
|
572
581
|
Order: "Volgorde",
|
|
573
582
|
"Owner:": "Eigenaar:",
|
|
@@ -792,6 +801,7 @@ var translations = {
|
|
|
792
801
|
"View all ({total})": "Alles bekijken ({total})",
|
|
793
802
|
"No items": "Geen items",
|
|
794
803
|
"Nothing here yet": "Hier staat nog niets",
|
|
804
|
+
"This list could not be loaded.": "Deze lijst kon niet worden geladen.",
|
|
795
805
|
"No items match this filter": "Geen items voldoen aan dit filter",
|
|
796
806
|
"Could not load these records": "Deze gegevens konden niet worden geladen",
|
|
797
807
|
"No conversations yet": "Nog geen gesprekken",
|
|
@@ -1437,7 +1447,6 @@ var translations = {
|
|
|
1437
1447
|
"You cannot see this folder": "Je kunt deze map niet zien",
|
|
1438
1448
|
"{action} did not succeed": "{action} is niet gelukt",
|
|
1439
1449
|
"Error:": "Fout:",
|
|
1440
|
-
optional: "optioneel",
|
|
1441
1450
|
"Copy link": "Link kopiëren",
|
|
1442
1451
|
"Details and sharing": "Details en delen",
|
|
1443
1452
|
"Link copied": "Link gekopieerd",
|
|
@@ -1455,9 +1464,14 @@ var translations = {
|
|
|
1455
1464
|
"1 day left": "Nog 1 dag",
|
|
1456
1465
|
"{count} days left": "Nog {count} dagen",
|
|
1457
1466
|
"1 day overdue": "1 dag te laat",
|
|
1458
|
-
"{count} days overdue": "{count} dagen te laat"
|
|
1467
|
+
"{count} days overdue": "{count} dagen te laat",
|
|
1468
|
+
"{view}: not available on this list": "{view}: niet beschikbaar in deze lijst"
|
|
1459
1469
|
};
|
|
1460
1470
|
var plurals = {
|
|
1471
|
+
"{count} selected": [
|
|
1472
|
+
"{count} geselecteerd",
|
|
1473
|
+
"{count} geselecteerd"
|
|
1474
|
+
],
|
|
1461
1475
|
"%n year": [
|
|
1462
1476
|
"%n jaar",
|
|
1463
1477
|
"%n jaar"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nl.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"nl.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|