adminizer 5.0.0-build.9 → 5.1.0-build.24
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/assets/abnfDiagram-VCTEODGH-DFY3Pztx.js +1 -0
- package/assets/add-31tS-g4V.js +1 -0
- package/assets/add-group-Cf3zT7WE.js +1 -0
- package/assets/add-user-C62wOna-.js +1 -0
- package/assets/ai-assistant/agent.es.js +28464 -0
- package/assets/app-DPmI-MvN.css +1 -0
- package/assets/app-vdHbjOQX.js +138 -0
- package/assets/arc-DP4o1zz3.js +1 -0
- package/assets/architectureDiagram-5GKGNRK7-BjXW5Zu0.js +36 -0
- package/assets/asmcrypto-DZeQH0LC.js +1 -0
- package/assets/blockDiagram-I7D4REHJ-BUPnDwN0.js +129 -0
- package/assets/c4Diagram-7LVT6UL2-Cmb_dAhd.js +38 -0
- package/assets/{catalog-dk6a0I1u.js → catalog-C-y5rMaG.js} +3 -3
- package/assets/channel-CkJRUsq_.js +1 -0
- package/assets/chunk-2Q5K7J3B-CmS-dWwQ.js +1 -0
- package/assets/chunk-5VM5RSS4-Cqs2Ow64.js +15 -0
- package/assets/chunk-F27PBJKO-BoMCpJA1.js +1 -0
- package/assets/chunk-IMKFNOWR-DlDcPk1x.js +231 -0
- package/assets/chunk-JWPE2WC7-DzL_SU8s.js +1 -0
- package/assets/chunk-POPQ4Y6H-Cwq2-Vb8.js +1 -0
- package/assets/chunk-SVP7TREG-BfRHY5FU.js +88 -0
- package/assets/chunk-TICWLB2K-CRP7rHkW.js +206 -0
- package/assets/chunk-XXDRQBXY-Bg2jg-98.js +1 -0
- package/assets/classDiagram-ZZMXUADV-D4EF3HGj.js +1 -0
- package/assets/classDiagram-v2-VYDZK3BY-D4EF3HGj.js +1 -0
- package/assets/controls/ckeditor.es.js +9382 -9320
- package/assets/controls/handsontable.es.js +11971 -11938
- package/assets/controls/jsoneditor.es.js +10442 -10233
- package/assets/controls/toast-ui.es.js +1308 -1279
- package/assets/cose-bilkent-JH36ORCC-CCJ0SGyO.js +1 -0
- package/assets/cynefin-OW5HDTMX-B2Jx5fw3.js +166 -0
- package/assets/cynefinDiagram-5FMLGOSQ-DuK0Lb62.js +62 -0
- package/assets/cytoscape.esm-DzSz-X2X.js +321 -0
- package/assets/dagre-GXQ25YYZ-DnOYexET.js +4 -0
- package/assets/dashboard-X8k4X6Sw.js +3 -0
- package/assets/debounce-B3mXI_sx.js +1 -0
- package/assets/defaultLocale-DX6XiGOO.js +1 -0
- package/assets/diagram-S7CK7UJ4-DDgPBHsK.js +30 -0
- package/assets/diagram-UQ7AKVKN-qlL0GZs8.js +41 -0
- package/assets/diagram-VSXAHHWV-CQbiU1_c.js +3 -0
- package/assets/diagram-VX7I27RA-DFDI9_au.js +24 -0
- package/assets/diagram-Z3DM3KII-B5C9dtmJ.js +24 -0
- package/assets/docs-BiZOD7PP.js +1 -0
- package/assets/ebnfDiagram-PWID7BFC-CLMUsXEI.js +1 -0
- package/assets/erDiagram-RLTQ6QDP-ax9Xol5-.js +99 -0
- package/assets/flowDiagram-HODETNUW-CvaH7l3S.js +168 -0
- package/assets/ganttDiagram-EL5Y4UJY-Cga5U19j.js +292 -0
- package/assets/gitGraphDiagram-WWUBYQGX-B6o1T3-d.js +106 -0
- package/assets/history-CVBJUNSQ.js +1 -0
- package/assets/infoDiagram-27XIBGKW-BpWxgBCE.js +2 -0
- package/assets/init-Gi6I4Gst.js +1 -0
- package/assets/init-user-xSvnFTF0.js +1 -0
- package/assets/isObject-DL-BuaBl.js +1 -0
- package/assets/ishikawaDiagram-5VMMS53U-zE83db4H.js +70 -0
- package/assets/journeyDiagram-3NMN7TZE-DZNVFqrX.js +139 -0
- package/assets/kanban-definition-UXKFOSKX-CqxNgk27.js +89 -0
- package/assets/katex-HP8lGamR.js +257 -0
- package/assets/layout-CN3kt_jt.js +1 -0
- package/assets/linear-nvkaQ6BA.js +1 -0
- package/assets/{list-CcMtS4hD.js → list-CrIU2eZz.js} +2 -2
- package/assets/login-CX9xVjCn.js +1 -0
- package/assets/manifest.json +834 -58
- package/assets/media-manager-BfYftLIH.js +6 -0
- package/assets/mermaid.core-C0V1NaVJ.js +310 -0
- package/assets/mindmap-definition-YA3MSWOX-Bh7_d9f1.js +96 -0
- package/assets/module-DPEvnad3.js +1 -0
- package/assets/notification-Dqpt5AIZ.js +20 -0
- package/assets/ordinal-Cboi1Yqb.js +1 -0
- package/assets/pegDiagram-XKGWAZYB-DMnjm6Z1.js +1 -0
- package/assets/pieDiagram-E7YTZNPT-D-RWCgYb.js +39 -0
- package/assets/quadrantDiagram-AXDQQJYC-BNBGP7RM.js +7 -0
- package/assets/railroadDiagram-O6MQD6OU-BIjVPT01.js +1 -0
- package/assets/register-CF4KQ97e.js +1 -0
- package/assets/requirementDiagram-BXWQKSXE-VPrtGdjM.js +84 -0
- package/assets/ru-CFJ4fysR.js +1 -0
- package/assets/sankeyDiagram-P5KCCOFB-ct9mLF3U.js +40 -0
- package/assets/sequenceDiagram-WJ2MYXX4-TC06Mbmw.js +162 -0
- package/assets/sizeCapture-INFHLROL-BMMwriCf.js +1 -0
- package/assets/stateDiagram-D77RDMKH-DtwYRPCX.js +1 -0
- package/assets/stateDiagram-v2-MP3YSRHH-C1yB0O5U.js +1 -0
- package/assets/swimlanes-42K2YHIH-DE3hRbbr.js +1 -0
- package/assets/swimlanesDiagram-VR7AAH4N-Ce4l1sQD.js +8 -0
- package/assets/timeline-definition-24CTP7MA-N7s_hfjj.js +120 -0
- package/assets/toNumber-DZb-r9sy.js +1 -0
- package/assets/use-appearance-DYTIKpT2.js +1 -0
- package/assets/user-filters-list-fR0YNJ3l.js +1 -0
- package/assets/vennDiagram-4TSXK5OY-Dj5bFQkR.js +34 -0
- package/assets/wardleyDiagram-VM6X3IG4-83ax25Z6.js +78 -0
- package/assets/welcome-v11MTsRK.js +1 -0
- package/assets/with-app-layout-CH6RIib1.js +31 -0
- package/assets/xychartDiagram-S5SC5T6Z-CW9Br5Xp.js +7 -0
- package/controllers/access-rights/permissionOptions.d.ts +2 -0
- package/controllers/access-rights/permissionOptions.js +23 -0
- package/controllers/add.js +2 -2
- package/controllers/addGroup.js +15 -6
- package/controllers/ai/AiAgentController.d.ts +66 -0
- package/controllers/ai/AiAgentController.js +435 -0
- package/controllers/ai/AiAssistantController.d.ts +0 -4
- package/controllers/ai/AiAssistantController.js +4 -78
- package/controllers/catalog/FrontendCatalogAdapter.js +7 -8
- package/controllers/docs/index.d.ts +22 -0
- package/controllers/docs/index.js +126 -0
- package/controllers/edit.js +2 -2
- package/controllers/editGroup.js +15 -6
- package/controllers/filter-fields/savedFilters.js +1 -1
- package/controllers/history-actions/HistoryController.js +7 -7
- package/controllers/inlineUpdate.js +10 -3
- package/controllers/list.js +1 -1
- package/controllers/login.js +1 -1
- package/controllers/notifications/NotificationController.js +14 -8
- package/controllers/view.js +3 -3
- package/controllers/widgets/filterInfo.js +1 -1
- package/helpers/accessRightsHelper.d.ts +30 -3
- package/helpers/accessRightsHelper.js +140 -12
- package/helpers/assetVersionHelper.d.ts +14 -0
- package/helpers/assetVersionHelper.js +42 -0
- package/helpers/configHelper.js +19 -18
- package/helpers/controllerHelper.d.ts +1 -0
- package/helpers/controllerHelper.js +25 -15
- package/helpers/fieldsHelper.d.ts +2 -1
- package/helpers/fieldsHelper.js +11 -5
- package/helpers/inertiaActionsHelper.d.ts +1 -1
- package/helpers/inertiaActionsHelper.js +4 -5
- package/helpers/inertiaAddHelper.d.ts +1 -1
- package/helpers/inertiaAddHelper.js +7 -6
- package/helpers/inertiaGroupHelper.js +10 -2
- package/helpers/inertiaListHelper.d.ts +1 -1
- package/helpers/inertiaListHelper.js +7 -8
- package/helpers/inertiaMenuHelper.d.ts +7 -2
- package/helpers/inertiaMenuHelper.js +12 -27
- package/helpers/menuHelper.d.ts +11 -1
- package/helpers/menuHelper.js +12 -0
- package/helpers/modelResourceHelper.d.ts +9 -0
- package/helpers/modelResourceHelper.js +43 -0
- package/helpers/navigationAccessHelper.d.ts +13 -0
- package/helpers/navigationAccessHelper.js +45 -0
- package/index.d.ts +11 -0
- package/index.js +11 -0
- package/interfaces/adminpanelConfig.d.ts +160 -2
- package/interfaces/queryCriteria.d.ts +13 -0
- package/interfaces/types.d.ts +169 -0
- package/lib/Adminizer.d.ts +8 -0
- package/lib/Adminizer.js +29 -2
- package/lib/DataAccessor.d.ts +100 -3
- package/lib/DataAccessor.js +454 -245
- package/lib/access-graph/AccessGraphResolver.d.ts +136 -0
- package/lib/access-graph/AccessGraphResolver.js +605 -0
- package/lib/access-graph/RecordAccessCache.d.ts +23 -0
- package/lib/access-graph/RecordAccessCache.js +30 -0
- package/lib/access-graph/RecordAccessResolver.d.ts +83 -0
- package/lib/access-graph/RecordAccessResolver.js +295 -0
- package/lib/access-graph/shared.d.ts +60 -0
- package/lib/access-graph/shared.js +121 -0
- package/lib/admin-links/AdminLinkHandler.d.ts +72 -0
- package/lib/admin-links/AdminLinkHandler.js +183 -0
- package/lib/ai-assistant/AbstractAiConversationHistoryService.d.ts +39 -0
- package/lib/ai-assistant/AbstractAiConversationHistoryService.js +98 -0
- package/lib/ai-assistant/AbstractAiModelService.d.ts +139 -2
- package/lib/ai-assistant/AbstractAiModelService.js +154 -1
- package/lib/ai-assistant/AiAgentRunManager.d.ts +35 -0
- package/lib/ai-assistant/AiAgentRunManager.js +109 -0
- package/lib/ai-assistant/AiAssistantAgentSkillHandler.d.ts +61 -0
- package/lib/ai-assistant/AiAssistantAgentSkillHandler.js +90 -0
- package/lib/ai-assistant/AiAssistantHandler.d.ts +1 -0
- package/lib/ai-assistant/AiAssistantHandler.js +4 -0
- package/lib/ai-assistant/AiAssistantUiMethodHandler.d.ts +60 -0
- package/lib/ai-assistant/AiAssistantUiMethodHandler.js +144 -0
- package/lib/ai-assistant/builtinAgentSkills.d.ts +9 -0
- package/lib/ai-assistant/builtinAgentSkills.js +259 -0
- package/lib/ai-assistant/jsonSafe.d.ts +13 -0
- package/lib/ai-assistant/jsonSafe.js +81 -0
- package/lib/app-manager/AdminizerApp.d.ts +31 -2
- package/lib/app-manager/AppManager.js +43 -42
- package/lib/app-manager/ConfigLayerHandler.js +4 -0
- package/lib/docs/AbstractDocumentation.d.ts +100 -0
- package/lib/docs/AbstractDocumentation.js +108 -0
- package/lib/docs/DocumentationHandler.d.ts +100 -0
- package/lib/docs/DocumentationHandler.js +198 -0
- package/lib/docs/FileDocumentation.d.ts +47 -0
- package/lib/docs/FileDocumentation.js +189 -0
- package/lib/docs/docsAgentSkills.d.ts +10 -0
- package/lib/docs/docsAgentSkills.js +93 -0
- package/lib/filters/FilterService.js +4 -3
- package/lib/history-actions/AbstractHistoryAdapter.d.ts +26 -1
- package/lib/history-actions/AbstractHistoryAdapter.js +155 -25
- package/lib/media-manager/helpers/MediaManagerHelper.js +9 -7
- package/lib/model/AbstractModel.d.ts +48 -0
- package/lib/model/AbstractModel.js +14 -4
- package/lib/model/ModelHandler.d.ts +50 -2
- package/lib/model/ModelHandler.js +117 -8
- package/lib/model/adapter/sequelize.d.ts +40 -1
- package/lib/model/adapter/sequelize.js +243 -77
- package/lib/model/adapter/typeorm.d.ts +16 -0
- package/lib/model/adapter/typeorm.js +136 -9
- package/lib/notifications/GeneralNotificationService.js +6 -5
- package/lib/notifications/SystemNotificationService.js +1 -1
- package/lib/ui-i18n/uiTranslationKeys.d.ts +2 -1
- package/lib/ui-i18n/uiTranslationKeys.js +42 -1
- package/lib/widgets/widgetHandler.js +10 -6
- package/models/Group.d.ts +2 -1
- package/package.json +35 -23
- package/policies/authPolicies.js +6 -6
- package/policies/permissionResolvers.d.ts +1 -0
- package/policies/permissionResolvers.js +3 -0
- package/system/Router.js +21 -3
- package/system/bindAccessRights.js +13 -3
- package/system/bindDocs.d.ts +13 -0
- package/system/bindDocs.js +77 -0
- package/system/bindInertia.js +30 -7
- package/system/buildInternalModelAccess.d.ts +8 -0
- package/system/buildInternalModelAccess.js +36 -4
- package/system/defaults.js +7 -1
- package/system/validateSystemModels.js +29 -9
- package/assets/add-CBlLpLr0.js +0 -1
- package/assets/add-group-H0IKIsNm.js +0 -1
- package/assets/add-user-CoTLmxtF.js +0 -1
- package/assets/app-DNXiApCk.css +0 -1
- package/assets/app-layout-xxJpLAvb.js +0 -1
- package/assets/app.js +0 -138
- package/assets/dashboard-DVJS5EPP.js +0 -3
- package/assets/debounce-BMmXVQ06.js +0 -1
- package/assets/history-bWRuzbye.js +0 -1
- package/assets/init-user-8aUohVDq.js +0 -1
- package/assets/login-CO4laf6m.js +0 -1
- package/assets/media-manager-BDbpSSjH.js +0 -6
- package/assets/module-CqO_BKsH.js +0 -1
- package/assets/notification-B5l2wwmi.js +0 -20
- package/assets/register-DBYIMXGQ.js +0 -1
- package/assets/ru-rYKdQbWF.js +0 -1
- package/assets/use-appearance-_EbbjHTh.js +0 -1
- package/assets/user-filters-list-C7kMKN5f.js +0 -1
- package/assets/welcome-6z-7sXnQ.js +0 -1
|
@@ -6,23 +6,24 @@ export class GeneralNotificationService extends AbstractNotificationService {
|
|
|
6
6
|
icon = 'info';
|
|
7
7
|
iconColor = '#5987de';
|
|
8
8
|
async dispatchNotification(notification) {
|
|
9
|
+
const { userId, ...notificationData } = notification;
|
|
9
10
|
const fullNotification = {
|
|
10
|
-
...
|
|
11
|
+
...notificationData,
|
|
11
12
|
notificationClass: this.notificationClass
|
|
12
13
|
};
|
|
13
14
|
let notificationDB;
|
|
14
15
|
try {
|
|
15
16
|
notificationDB = await this.notificationModel().create(fullNotification);
|
|
16
|
-
if (
|
|
17
|
+
if (userId) {
|
|
17
18
|
// For specific user
|
|
18
|
-
await this.createUserNotification(notificationDB.id,
|
|
19
|
+
await this.createUserNotification(notificationDB.id, userId);
|
|
19
20
|
}
|
|
20
21
|
else {
|
|
21
22
|
// For all users
|
|
22
23
|
const users = await this.userModel().find({});
|
|
23
24
|
for (const user of users) {
|
|
24
25
|
try {
|
|
25
|
-
if (this.adminizer.accessRightsHelper.hasPermission(`notification-${this.notificationClass}`, user)) {
|
|
26
|
+
if (await this.adminizer.accessRightsHelper.hasPermission(`notification-${this.notificationClass}`, user)) {
|
|
26
27
|
await this.createUserNotification(notificationDB.id, user.id);
|
|
27
28
|
}
|
|
28
29
|
else {
|
|
@@ -45,7 +46,7 @@ export class GeneralNotificationService extends AbstractNotificationService {
|
|
|
45
46
|
},
|
|
46
47
|
},
|
|
47
48
|
notificationClass: this.notificationClass,
|
|
48
|
-
userId:
|
|
49
|
+
userId: userId ?? null
|
|
49
50
|
};
|
|
50
51
|
this.broadcast(event);
|
|
51
52
|
Adminizer.log.info(`[General] Notification dispatched: ${fullNotification.title}`);
|
|
@@ -19,7 +19,7 @@ export class SystemNotificationService extends AbstractNotificationService {
|
|
|
19
19
|
const users = await this.userModel().find({});
|
|
20
20
|
for (const user of users) {
|
|
21
21
|
try {
|
|
22
|
-
if (this.adminizer.accessRightsHelper.hasPermission(`notification-${this.notificationClass}`, user)) {
|
|
22
|
+
if (await this.adminizer.accessRightsHelper.hasPermission(`notification-${this.notificationClass}`, user)) {
|
|
23
23
|
await this.createUserNotification(notificationDB.id, user.id);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export declare const COMMON_UI_TRANSLATION_KEYS: readonly ["Delete", "Diff", "Preview", "Add", "Search", "Yes", "No", "On", "Off", "Hide", "Show", "No notifications found", "No notifications", "No widgets found", "Changes not found", "Old", "New", "Added", "Removed", "Updated", "changed type", "Error: Invalid field data", "Error: Fields data is invalid", "No fields to display", "Error: Some fields are missing required properties (name, type, label)", "Edit", "create", "Clean", "Are you sure?", "Select Item type", "Select Ids", "Open in a new window", "Visible", "Performing an action...", "Action completed", "Action failed", "Save", "First", "Last", "Previous", "Next", "Send feedback", "Feedback", "Title", "Description", "Attach files", "Send", "Sending...", "Feedback sent successfully", "Title is required", "File size exceeds the 5 MB limit", "Remove file", "Max 5 MB per file", "View All", "Make read", "Make all read", "Message", "Date", "Watch", "Current", "There is no history"];
|
|
1
|
+
export declare const COMMON_UI_TRANSLATION_KEYS: readonly ["Delete", "Diff", "Preview", "Add", "Search", "Yes", "No", "On", "Off", "Hide", "Show", "No notifications found", "No notifications", "No widgets found", "Changes not found", "Old", "New", "Added", "Removed", "Updated", "changed type", "Error: Invalid field data", "Error: Fields data is invalid", "No fields to display", "Error: Some fields are missing required properties (name, type, label)", "Edit", "create", "Clean", "Are you sure?", "Select Item type", "Select Ids", "Open in a new window", "Visible", "Performing an action...", "Action completed", "Action failed", "Save", "First", "Last", "Previous", "Next", "Send feedback", "Feedback", "Title", "Description", "Attach files", "Send", "Sending...", "Feedback sent successfully", "Title is required", "File size exceeds the 5 MB limit", "Remove file", "Max 5 MB per file", "View All", "Make read", "Make all read", "Message", "Date", "Watch", "Current", "There is no history", "Documentation", "Page documentation", "Knowledge base", "Schema", "Back to contents", "Open in knowledge base", "Send to assistant", "Failed to load documentation", "Loading...", "Nothing found", "Field", "Type", "Required", "Language"];
|
|
2
2
|
export declare const FILTER_UI_TRANSLATION_KEYS: readonly ["Filters", "Saved filters", "Active filter", "Add filter", "Reset filter", "Reset", "Equal", "Not equal", "Contains", "Not contains", "Starts with", "Ends with", "Is empty", "Is not empty", "Greater than", "Greater or equal", "Less than", "Less or equal", "Between", "After", "After or equal", "Before", "Before or equal", "In list", "Not in list", "Is null", "Is not null", "Yes", "No", "From", "To", "From...", "To...", "Date...", "Today", "Month", "Month range", "Year", "Year range", "Value...", "Select...", "selected", "Search...", "No results", "Error", "Model not found", "Error applying filter", "Enter filter name", "Temporary filter", "Error: model not found", "Error loading columns", "Network error", "Columns settings", "Available columns", "Visible columns", "Add all", "Hide all", "No available columns", "Move columns here", "Save changes", "Apply", "Save", "Back", "Cancel", "conditions", "modified", "Private filter", "For groups", "Public filter", "Only for you", "For selected groups", "For all users", "Visible only to you", "Visible only to your group", "API access (feed)", "Hide", "Show", "Regenerate", "copied to clipboard", "Failed to copy", "Loading filters...", "No saved filters", "Save current filter for quick access", "Someone else's private filter (owner:", "unknown)", "Owner", "Apply filter", "Delete filter", "No permission to delete filter", "Edit filter", "New filter", "Filter conditions", "Add condition", "Select field", "No conditions. Add a condition above.", "Name", "Description", "Icon", "Color", "Filter parameters", "Change filter conditions and parameters", "Configure filter conditions", "Specify name and parameters for saving", "Someone else's private filter", "You cannot change someone else's filter visibility", "Private", "Public", "Visibility", "Export", "Exporting...", "Export is only available with an active filter", "Export to", "completed", "Export error", "Data in JSON format", "Text format CSV", "Excel file", "Conditions", "Access for groups", "Selected groups", "Groups list", "Columns", "Saving...", "Error saving filter", "Column configuration", "Select and arrange columns to display in the table", "Loading columns...", "Use buttons", "to move and", "to change order", "Add", "Edit", "Save filter", "and", "Custom filtering", "Select a saved filter or create a new one", "Select a filter or create a new one", "Filter visibility", "Unknown", "JSON URL", "XML URL", "API key is not created", "The key is not created. Create it or contact an administrator.", "OK"];
|
|
3
3
|
export declare const HISTORY_UI_TRANSLATION_KEYS: readonly ["Models", "All", "Users", "Date", "Pick a date", "Search", "Reset", "Model", "Name", "Event", "User", "Diff", "The end of the list has been reached", "There are no records to display"];
|
|
4
4
|
export declare const HISTORY_TABLE_UI_TRANSLATION_KEYS: readonly ["Event", "Date", "User", "Watch", "Current", "There is no history", "Diff"];
|
|
5
5
|
export declare const NOTIFICATION_UI_TRANSLATION_KEYS: readonly ["Make read", "View All", "Search", "Make all read", "Title", "Message", "Date", "Diff", "No notifications", "No notifications found", "The end of the list has been reached"];
|
|
6
6
|
export declare const USER_FILTERS_UI_TRANSLATION_KEYS: readonly ["Loading...", "Search filters...", "All models", "No filters found", "Loading more...", "Filter Name", "Model", "Visibility", "API access (feed)", "Owner", "Private", "Public", "Groups", "Yes", "No", "You", "Unknown", "Reset", "found", "User Filters"];
|
|
7
|
+
export declare const DOCS_UI_TRANSLATION_KEYS: readonly ["Documentation", "Knowledge base", "Contents", "Search documentation", "Search", "Keywords", "Clear", "Nothing found", "There is no documentation yet", "Select a document to read", "Loading...", "Language", "Send to assistant", "Schema", "Related models", "Failed to load documentation", "Field", "Type", "Required", "No fields to display", "Previous", "Next", "Found", "In this document", "Document not found"];
|
|
@@ -59,7 +59,21 @@ export const COMMON_UI_TRANSLATION_KEYS = [
|
|
|
59
59
|
"Date",
|
|
60
60
|
"Watch",
|
|
61
61
|
"Current",
|
|
62
|
-
"There is no history"
|
|
62
|
+
"There is no history",
|
|
63
|
+
"Documentation",
|
|
64
|
+
"Page documentation",
|
|
65
|
+
"Knowledge base",
|
|
66
|
+
"Schema",
|
|
67
|
+
"Back to contents",
|
|
68
|
+
"Open in knowledge base",
|
|
69
|
+
"Send to assistant",
|
|
70
|
+
"Failed to load documentation",
|
|
71
|
+
"Loading...",
|
|
72
|
+
"Nothing found",
|
|
73
|
+
"Field",
|
|
74
|
+
"Type",
|
|
75
|
+
"Required",
|
|
76
|
+
"Language"
|
|
63
77
|
];
|
|
64
78
|
export const FILTER_UI_TRANSLATION_KEYS = [
|
|
65
79
|
"Filters",
|
|
@@ -267,3 +281,30 @@ export const USER_FILTERS_UI_TRANSLATION_KEYS = [
|
|
|
267
281
|
"found",
|
|
268
282
|
"User Filters"
|
|
269
283
|
];
|
|
284
|
+
export const DOCS_UI_TRANSLATION_KEYS = [
|
|
285
|
+
"Documentation",
|
|
286
|
+
"Knowledge base",
|
|
287
|
+
"Contents",
|
|
288
|
+
"Search documentation",
|
|
289
|
+
"Search",
|
|
290
|
+
"Keywords",
|
|
291
|
+
"Clear",
|
|
292
|
+
"Nothing found",
|
|
293
|
+
"There is no documentation yet",
|
|
294
|
+
"Select a document to read",
|
|
295
|
+
"Loading...",
|
|
296
|
+
"Language",
|
|
297
|
+
"Send to assistant",
|
|
298
|
+
"Schema",
|
|
299
|
+
"Related models",
|
|
300
|
+
"Failed to load documentation",
|
|
301
|
+
"Field",
|
|
302
|
+
"Type",
|
|
303
|
+
"Required",
|
|
304
|
+
"No fields to display",
|
|
305
|
+
"Previous",
|
|
306
|
+
"Next",
|
|
307
|
+
"Found",
|
|
308
|
+
"In this document",
|
|
309
|
+
"Document not found"
|
|
310
|
+
];
|
|
@@ -116,7 +116,11 @@ export class WidgetHandler {
|
|
|
116
116
|
const filterService = new FilterService(this.adminizer);
|
|
117
117
|
const result = [];
|
|
118
118
|
for (const modelName of modelNames) {
|
|
119
|
-
|
|
119
|
+
const readToken = `read-${modelName}-model`;
|
|
120
|
+
if (!this.adminizer.accessRightsHelper.hasToken(readToken)) {
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (!await this.adminizer.accessRightsHelper.hasPermission(readToken, user)) {
|
|
120
124
|
continue;
|
|
121
125
|
}
|
|
122
126
|
let filters = [];
|
|
@@ -163,7 +167,7 @@ export class WidgetHandler {
|
|
|
163
167
|
let id_key = 0;
|
|
164
168
|
for (const widget of this.widgets) {
|
|
165
169
|
if (widget.widgetType === 'switcher') {
|
|
166
|
-
if (this.adminizer.accessRightsHelper.hasPermission(this.resolveAccessRightsToken(widget), dashboardUser)) {
|
|
170
|
+
if (await this.adminizer.accessRightsHelper.hasPermission(this.resolveAccessRightsToken(widget), dashboardUser)) {
|
|
167
171
|
widgets.push({
|
|
168
172
|
id: `${widget.id}__${id_key}`,
|
|
169
173
|
type: widget.widgetType,
|
|
@@ -178,7 +182,7 @@ export class WidgetHandler {
|
|
|
178
182
|
}
|
|
179
183
|
}
|
|
180
184
|
else if (widget.widgetType === 'info') {
|
|
181
|
-
if (this.adminizer.accessRightsHelper.hasPermission(this.resolveAccessRightsToken(widget), dashboardUser)) {
|
|
185
|
+
if (await this.adminizer.accessRightsHelper.hasPermission(this.resolveAccessRightsToken(widget), dashboardUser)) {
|
|
182
186
|
widgets.push({
|
|
183
187
|
id: `${widget.id}__${id_key}`,
|
|
184
188
|
type: widget.widgetType,
|
|
@@ -195,7 +199,7 @@ export class WidgetHandler {
|
|
|
195
199
|
}
|
|
196
200
|
}
|
|
197
201
|
else if (widget.widgetType === 'action') {
|
|
198
|
-
if (this.adminizer.accessRightsHelper.hasPermission(this.resolveAccessRightsToken(widget), dashboardUser)) {
|
|
202
|
+
if (await this.adminizer.accessRightsHelper.hasPermission(this.resolveAccessRightsToken(widget), dashboardUser)) {
|
|
199
203
|
widgets.push({
|
|
200
204
|
id: `${widget.id}__${id_key}`,
|
|
201
205
|
type: widget.widgetType,
|
|
@@ -210,7 +214,7 @@ export class WidgetHandler {
|
|
|
210
214
|
}
|
|
211
215
|
}
|
|
212
216
|
else if (widget.widgetType === 'link') {
|
|
213
|
-
if (this.adminizer.accessRightsHelper.hasPermission(this.resolveAccessRightsToken(widget), dashboardUser)) {
|
|
217
|
+
if (await this.adminizer.accessRightsHelper.hasPermission(this.resolveAccessRightsToken(widget), dashboardUser)) {
|
|
214
218
|
let links_id_key = 0;
|
|
215
219
|
for (const link of widget.links) {
|
|
216
220
|
widgets.push({
|
|
@@ -229,7 +233,7 @@ export class WidgetHandler {
|
|
|
229
233
|
}
|
|
230
234
|
}
|
|
231
235
|
else if (widget.widgetType === 'custom') {
|
|
232
|
-
if (this.adminizer.accessRightsHelper.hasPermission(this.resolveAccessRightsToken(widget), dashboardUser)) {
|
|
236
|
+
if (await this.adminizer.accessRightsHelper.hasPermission(this.resolveAccessRightsToken(widget), dashboardUser)) {
|
|
233
237
|
widgets.push({
|
|
234
238
|
id: `${widget.id}_${id_key}`,
|
|
235
239
|
type: widget.widgetType,
|
package/models/Group.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adminizer",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "5.
|
|
4
|
+
"version": "5.1.0-build.24",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": "./index.js",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"dev:typeorm:no-seed": "cross-env ADMINIZER_ENV=dev NO_SEED_DATA=true ORM=typeorm tsx watch --tsconfig ./fixture/tsconfig.json ./fixture/index.ts",
|
|
22
22
|
"dev:no-seed-clean": "cross-env ADMINIZER_ENV=dev NO_SEED_DATA=true CLEAN_TMP=true ORM=sequelize tsx watch --tsconfig ./fixture/tsconfig.json ./fixture/index.ts",
|
|
23
23
|
"dev:cors": "cross-env ADMINIZER_ENV=dev NO_SEED_DATA=true ORM=sequelize FRONTEND_URL=http://localhost:8080 tsx watch --tsconfig ./fixture/tsconfig.json ./fixture/index.ts",
|
|
24
|
-
"build:assets": "vite build && vite build --config vite.config.controls.ts && vite build --config fixture/widgets/vite.config.widget.ts",
|
|
24
|
+
"build:assets": "vite build && vite build --config vite.config.controls.ts && vite build --config vite.config.ai-assistant.ts && vite build --config fixture/widgets/vite.config.widget.ts",
|
|
25
25
|
"build:controls": "vite build --config vite.config.controls.ts",
|
|
26
26
|
"compile:backend": "tsc -p src/tsconfig.json && node ./scripts/appendJsExtension.js",
|
|
27
27
|
"compile:ui": "tsc -p tsconfig.ui.json",
|
|
@@ -31,7 +31,10 @@
|
|
|
31
31
|
"build": "npm run copy:backend && npm run compile:backend && npm run compile:ui && npm run build:assets",
|
|
32
32
|
"build:catalog-modules": "cross-env CATALOG_COMPONENT=catalogAction vite build --config fixture/virtual-catalog/vite.config.module.ts && cross-env CATALOG_COMPONENT=Group vite build --config fixture/virtual-catalog/vite.config.module.ts",
|
|
33
33
|
"start:typeorm:seed": "cross-env ORM=typeorm tsx --tsconfig ./fixture/tsconfig.json ./fixture/index.ts",
|
|
34
|
-
"build:apps": "vite build --config fixture/apps/notification-sender/vite.config.module.ts && vite build --config fixture/apps/module-manager/vite.config.module.ts && vite build --config fixture/apps/navigation/vite.config.module.ts && vite build --config fixture/apps/quill-editor/vite.config.module.ts && vite build --config fixture/apps/widgets/vite.config.module.ts && vite build --config fixture/apps/handsontable-test/vite.config.module.ts && npm run build:catalog-modules"
|
|
34
|
+
"build:apps": "vite build --config fixture/apps/notification-sender/vite.config.module.ts && vite build --config fixture/apps/module-manager/vite.config.module.ts && vite build --config fixture/apps/navigation/vite.config.module.ts && vite build --config fixture/apps/quill-editor/vite.config.module.ts && vite build --config fixture/apps/widgets/vite.config.module.ts && vite build --config fixture/apps/handsontable-test/vite.config.module.ts && vite build --config fixture/apps/record-scope-test/vite.config.module.ts && npm run build:catalog-modules",
|
|
35
|
+
"build:ai-assistant": "vite build --config vite.config.ai-assistant.ts",
|
|
36
|
+
"lint": "eslint src",
|
|
37
|
+
"lint:async": "eslint src -c eslint.config.async.mjs"
|
|
35
38
|
},
|
|
36
39
|
"keywords": [],
|
|
37
40
|
"author": "Siziy Ivan <xziy88@gmail.com>",
|
|
@@ -59,41 +62,34 @@
|
|
|
59
62
|
"jsonwebtoken": "^9.0.3",
|
|
60
63
|
"multer": "^2.1.1",
|
|
61
64
|
"password-hash": "^1.2.2",
|
|
65
|
+
"serve-static": "^2.2.1",
|
|
62
66
|
"sharp": "^0.33.5",
|
|
63
67
|
"sprintf-js": "^1.1.3",
|
|
68
|
+
"sqlite3": "^5.1.7",
|
|
69
|
+
"typeorm": "^0.3.20",
|
|
64
70
|
"uuid": "^14.0.0",
|
|
65
71
|
"winston": "^3.17.0",
|
|
66
72
|
"xlsx": "^0.18.5",
|
|
67
|
-
"zod": "^4.1.11"
|
|
68
|
-
"sqlite3": "^5.1.7",
|
|
69
|
-
"typeorm": "^0.3.20"
|
|
73
|
+
"zod": "^4.1.11"
|
|
70
74
|
},
|
|
71
75
|
"devDependencies": {
|
|
72
|
-
"
|
|
73
|
-
"react-
|
|
74
|
-
"react-cropper": "^2.3.3",
|
|
75
|
-
"material-icons": "^1.13.14",
|
|
76
|
-
"next-themes": "^0.4.6",
|
|
77
|
-
"dotenv": "^17.4.2",
|
|
78
|
-
"date-fns": "^3.6.0",
|
|
79
|
-
"cmdk": "^1.1.1",
|
|
80
|
-
"@handsontable/react-wrapper": "^17.0.1",
|
|
81
|
-
"@minoru/react-dnd-treeview": "^3.5.2",
|
|
82
|
-
"@radix-ui/react-context-menu": "^2.2.15",
|
|
83
|
-
"@radix-ui/react-tabs": "^1.1.12",
|
|
84
|
-
"typescript": "^6.0.3",
|
|
76
|
+
"@assistant-ui/react": "^0.15.15",
|
|
77
|
+
"@assistant-ui/react-markdown": "^0.14.6",
|
|
85
78
|
"@babel/plugin-proposal-decorators": "^7.27.1",
|
|
86
79
|
"@ckeditor/ckeditor5-react": "^9.5.0",
|
|
87
80
|
"@dnd-kit/core": "^6.3.1",
|
|
88
81
|
"@dnd-kit/sortable": "^10.0.0",
|
|
89
82
|
"@eslint/compat": "^1.2.9",
|
|
90
83
|
"@faker-js/faker": "^9.7.0",
|
|
84
|
+
"@handsontable/react-wrapper": "^17.0.1",
|
|
91
85
|
"@inertiajs/react": "^3.0.3",
|
|
86
|
+
"@minoru/react-dnd-treeview": "^3.5.2",
|
|
92
87
|
"@monaco-editor/react": "^4.7.0",
|
|
93
88
|
"@openai/agents": "^0.3.2",
|
|
94
89
|
"@radix-ui/react-avatar": "^1.1.3",
|
|
95
90
|
"@radix-ui/react-checkbox": "^1.1.4",
|
|
96
91
|
"@radix-ui/react-collapsible": "^1.1.3",
|
|
92
|
+
"@radix-ui/react-context-menu": "^2.2.15",
|
|
97
93
|
"@radix-ui/react-dialog": "^1.1.7",
|
|
98
94
|
"@radix-ui/react-dropdown-menu": "^2.1.6",
|
|
99
95
|
"@radix-ui/react-label": "^2.1.2",
|
|
@@ -105,6 +101,7 @@
|
|
|
105
101
|
"@radix-ui/react-slider": "^1.2.3",
|
|
106
102
|
"@radix-ui/react-slot": "^1.2.0",
|
|
107
103
|
"@radix-ui/react-switch": "^1.2.4",
|
|
104
|
+
"@radix-ui/react-tabs": "^1.1.12",
|
|
108
105
|
"@radix-ui/react-tooltip": "^1.1.8",
|
|
109
106
|
"@tailwindcss/vite": "^4.0.15",
|
|
110
107
|
"@tanstack/react-table": "^8.21.2",
|
|
@@ -127,12 +124,17 @@
|
|
|
127
124
|
"@types/react-grid-layout": "^1.3.5",
|
|
128
125
|
"@types/sprintf-js": "^1.1.4",
|
|
129
126
|
"@types/uuid": "^10.0.0",
|
|
130
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
127
|
+
"@typescript-eslint/eslint-plugin": "^8.67.0",
|
|
128
|
+
"@typescript-eslint/parser": "^8.67.0",
|
|
131
129
|
"@vitejs/plugin-react": "^5.2.0",
|
|
130
|
+
"asmcrypto.js": "^0.22.0",
|
|
132
131
|
"ckeditor5": "^45.0.0",
|
|
133
132
|
"class-variance-authority": "^0.7.1",
|
|
134
133
|
"clsx": "^2.1.1",
|
|
134
|
+
"cmdk": "^1.1.1",
|
|
135
135
|
"cross-env": "^7.0.3",
|
|
136
|
+
"date-fns": "^3.6.0",
|
|
137
|
+
"dotenv": "^17.4.2",
|
|
136
138
|
"eslint": "^9.26.0",
|
|
137
139
|
"handsontable": "^17.0.1",
|
|
138
140
|
"isomorphic-webcrypto": "^2.3.8",
|
|
@@ -141,14 +143,22 @@
|
|
|
141
143
|
"leaflet-draw": "^1.0.4",
|
|
142
144
|
"lodash-es": "^4.17.21",
|
|
143
145
|
"lucide-react": "^0.485.0",
|
|
144
|
-
"
|
|
146
|
+
"material-icons": "^1.13.14",
|
|
147
|
+
"mermaid": "^11.17.0",
|
|
148
|
+
"next-themes": "^0.4.6",
|
|
149
|
+
"radix-ui": "^1.6.7",
|
|
150
|
+
"react": "19.2.8",
|
|
151
|
+
"react-cropper": "^2.3.3",
|
|
145
152
|
"react-day-picker": "^8.10.1",
|
|
146
|
-
"react-
|
|
153
|
+
"react-dnd": "^16.0.1",
|
|
154
|
+
"react-dom": "19.2.8",
|
|
147
155
|
"react-grid-layout": "^1.5.1",
|
|
148
156
|
"react-intersection-observer": "^9.16.0",
|
|
149
157
|
"react-leaflet": "^5.0.0",
|
|
150
158
|
"react-quill-new": "^3.4.6",
|
|
151
159
|
"react-simple-wysiwyg": "^3.2.2",
|
|
160
|
+
"reflect-metadata": "^0.2.2",
|
|
161
|
+
"remark-gfm": "^4.0.1",
|
|
152
162
|
"sequelize": "^6.37.7",
|
|
153
163
|
"sequelize-typescript": "^2.1.6",
|
|
154
164
|
"shelljs": "^0.9.2",
|
|
@@ -157,10 +167,12 @@
|
|
|
157
167
|
"tailwindcss": "^4.0.15",
|
|
158
168
|
"tsx": "^4.21.0",
|
|
159
169
|
"tw-animate-css": "^1.2.5",
|
|
170
|
+
"typescript": "^6.0.3",
|
|
160
171
|
"vanilla-jsoneditor": "^3.1.1",
|
|
161
172
|
"vite": "^7.3.2",
|
|
162
173
|
"vite-plugin-externals": "^0.6.2",
|
|
163
|
-
"vitest": "^3.0.7"
|
|
174
|
+
"vitest": "^3.0.7",
|
|
175
|
+
"zustand": "^5.0.14"
|
|
164
176
|
},
|
|
165
177
|
"overrides": {
|
|
166
178
|
"@toast-ui/react-editor": {
|
package/policies/authPolicies.js
CHANGED
|
@@ -20,7 +20,7 @@ function resolveToken(token, req) {
|
|
|
20
20
|
return token;
|
|
21
21
|
}
|
|
22
22
|
export function requireAuthEnabled() {
|
|
23
|
-
return (req, res, next) => {
|
|
23
|
+
return async (req, res, next) => {
|
|
24
24
|
if (!req.adminizer.config.auth.enable) {
|
|
25
25
|
return res.status(403).json({ error: "Auth is disabled" });
|
|
26
26
|
}
|
|
@@ -28,7 +28,7 @@ export function requireAuthEnabled() {
|
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
30
|
export function requireAuthUI() {
|
|
31
|
-
return (req, res, next) => {
|
|
31
|
+
return async (req, res, next) => {
|
|
32
32
|
if (req.adminizer.config.auth.enable && !req.user) {
|
|
33
33
|
unauthorized(req, res, "ui");
|
|
34
34
|
return;
|
|
@@ -64,7 +64,7 @@ export function requireAdmin(options = {}) {
|
|
|
64
64
|
}
|
|
65
65
|
export function requirePermission(token, options = {}) {
|
|
66
66
|
const mode = options.mode || "api";
|
|
67
|
-
return (req, res, next) => {
|
|
67
|
+
return async (req, res, next) => {
|
|
68
68
|
if (!req.adminizer.config.auth.enable) {
|
|
69
69
|
return next();
|
|
70
70
|
}
|
|
@@ -73,7 +73,7 @@ export function requirePermission(token, options = {}) {
|
|
|
73
73
|
return;
|
|
74
74
|
}
|
|
75
75
|
const tokenId = resolveToken(token, req);
|
|
76
|
-
const hasPermission = req.adminizer.accessRightsHelper.hasPermission(tokenId, req.user);
|
|
76
|
+
const hasPermission = await req.adminizer.accessRightsHelper.hasPermission(tokenId, req.user);
|
|
77
77
|
if (!hasPermission) {
|
|
78
78
|
forbidden(req, res, mode);
|
|
79
79
|
return;
|
|
@@ -83,7 +83,7 @@ export function requirePermission(token, options = {}) {
|
|
|
83
83
|
}
|
|
84
84
|
export function requireAnyPermission(tokens, options = {}) {
|
|
85
85
|
const mode = options.mode || "api";
|
|
86
|
-
return (req, res, next) => {
|
|
86
|
+
return async (req, res, next) => {
|
|
87
87
|
if (!req.adminizer.config.auth.enable) {
|
|
88
88
|
return next();
|
|
89
89
|
}
|
|
@@ -94,7 +94,7 @@ export function requireAnyPermission(tokens, options = {}) {
|
|
|
94
94
|
const tokenIds = tokens
|
|
95
95
|
.map((token) => resolveToken(token, req))
|
|
96
96
|
.filter((token) => Boolean(token));
|
|
97
|
-
const hasPermission = req.adminizer.accessRightsHelper.enoughPermissions(tokenIds, req.user);
|
|
97
|
+
const hasPermission = await req.adminizer.accessRightsHelper.enoughPermissions(tokenIds, req.user);
|
|
98
98
|
if (!hasPermission) {
|
|
99
99
|
forbidden(req, res, mode);
|
|
100
100
|
return;
|
|
@@ -8,5 +8,6 @@ export declare function widgetsToken(): string;
|
|
|
8
8
|
export declare function catalogToken(req: ReqType): string | undefined;
|
|
9
9
|
export declare function mediaManagerToken(req: ReqType): string | undefined;
|
|
10
10
|
export declare function aiModelToken(req: ReqType): string | undefined;
|
|
11
|
+
export declare function documentationToken(req: ReqType): string;
|
|
11
12
|
export declare function historyToken(req: ReqType): string;
|
|
12
13
|
export declare function groupFilterVisibilityToken(): string;
|
|
@@ -44,6 +44,9 @@ export function aiModelToken(req) {
|
|
|
44
44
|
const modelId = req.params?.modelId || (typeof req.body?.modelId === "string" ? req.body.modelId : undefined);
|
|
45
45
|
return modelId ? `ai-assistant-${modelId}` : undefined;
|
|
46
46
|
}
|
|
47
|
+
export function documentationToken(req) {
|
|
48
|
+
return req.adminizer.documentationHandler.baseToken;
|
|
49
|
+
}
|
|
47
50
|
export function historyToken(req) {
|
|
48
51
|
return `history-${req.adminizer.config.history?.adapter ?? "default"}`;
|
|
49
52
|
}
|
package/system/Router.js
CHANGED
|
@@ -11,6 +11,7 @@ import { getSavedFilters, saveFilter, deleteFilter, applyTemporaryFilter, getTem
|
|
|
11
11
|
import { getAllUserFilters } from "../controllers/filter-fields/getAllUserFilters.js";
|
|
12
12
|
import { getModelColumns, updateFilterColumns } from "../controllers/filter-fields/columns.js";
|
|
13
13
|
import { getAllGroups } from "../controllers/filter-fields/groups.js";
|
|
14
|
+
import { getPermissionOptions } from "../controllers/access-rights/permissionOptions.js";
|
|
14
15
|
import { ckEditorUpload } from "../controllers/ckeditorUpload.js";
|
|
15
16
|
import _exportData from "../controllers/exportData.js";
|
|
16
17
|
import _feed from "../controllers/feed.js";
|
|
@@ -30,6 +31,7 @@ import timezones from "../controllers/timezones.js";
|
|
|
30
31
|
import { NotificationController } from "../controllers/notifications/NotificationController.js";
|
|
31
32
|
import { HistoryController } from "../controllers/history-actions/HistoryController.js";
|
|
32
33
|
import { AiAssistantController } from "../controllers/ai/AiAssistantController.js";
|
|
34
|
+
import { AiAgentController } from "../controllers/ai/AiAgentController.js";
|
|
33
35
|
import listUserFilters from "../controllers/listUserFilters.js";
|
|
34
36
|
import { requireAnyPermission, requireAuthAPI, requireAuthEnabled, requireAuthUI, requirePermission } from "../policies/authPolicies.js";
|
|
35
37
|
import { aiModelToken, catalogToken, groupFilterVisibilityToken, historyToken, mediaManagerToken, modelCreateToken, modelDeleteToken, modelReadToken, modelUpdateToken, widgetToken, widgetsToken } from "../policies/permissionResolvers.js";
|
|
@@ -70,6 +72,7 @@ export default class Router {
|
|
|
70
72
|
const noCachePrefixes = [
|
|
71
73
|
'/api',
|
|
72
74
|
'/notifications/api',
|
|
75
|
+
'/docs/api',
|
|
73
76
|
'/history',
|
|
74
77
|
'/widgets-get-all',
|
|
75
78
|
'/widgets-get-all-db',
|
|
@@ -167,6 +170,7 @@ export default class Router {
|
|
|
167
170
|
/**
|
|
168
171
|
* List of records
|
|
169
172
|
*/
|
|
173
|
+
adminizer.app.get(`${adminizer.config.routePrefix}/access-rights/permission-options`, withPolicies(getPermissionOptions, requireAuthAPI(), requireAnyPermission(["create-Group-model", "update-Group-model"])));
|
|
170
174
|
adminizer.app.all(resourceRoute(), withPolicies(_list, requireAuthUI(), requirePermission(modelReadToken, { mode: "ui" })));
|
|
171
175
|
if (adminizer.config.filters?.enabled) {
|
|
172
176
|
/**
|
|
@@ -222,9 +226,23 @@ export default class Router {
|
|
|
222
226
|
* AI assistant — consumed by src/assets/js/contexts/AiAssistantContext.tsx
|
|
223
227
|
*/
|
|
224
228
|
adminizer.app.get(`${adminizer.config.routePrefix}/api/ai-assistant/models`, withPolicies(AiAssistantController.getModels, requireAuthAPI()));
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
229
|
+
/**
|
|
230
|
+
* Streaming agent transport — consumed by the assistant panel bundle
|
|
231
|
+
* (src/assets/js/ai-assistant). Model services that implement only
|
|
232
|
+
* `generateReply` are served through the same routes.
|
|
233
|
+
*/
|
|
234
|
+
const agentRoute = `${adminizer.config.routePrefix}/api/ai-assistant/agent/:modelId`;
|
|
235
|
+
adminizer.app.get(`${agentRoute}/status`, withPolicies(AiAgentController.getStatus, requireAuthAPI(), requirePermission(aiModelToken)));
|
|
236
|
+
adminizer.app.get(`${agentRoute}/limits`, withPolicies(AiAgentController.getLimits, requireAuthAPI(), requirePermission(aiModelToken)));
|
|
237
|
+
adminizer.app.get(`${agentRoute}/meta`, withPolicies(AiAgentController.getMeta, requireAuthAPI(), requirePermission(aiModelToken)));
|
|
238
|
+
adminizer.app.post(`${agentRoute}/model`, withPolicies(AiAgentController.setModel, requireAuthAPI(), requirePermission(aiModelToken)));
|
|
239
|
+
adminizer.app.get(`${agentRoute}/history`, withPolicies(AiAgentController.getHistory, requireAuthAPI(), requirePermission(aiModelToken)));
|
|
240
|
+
adminizer.app.get(`${agentRoute}/conversations`, withPolicies(AiAgentController.listConversations, requireAuthAPI(), requirePermission(aiModelToken)));
|
|
241
|
+
adminizer.app.post(`${agentRoute}/conversations`, withPolicies(AiAgentController.createConversation, requireAuthAPI(), requirePermission(aiModelToken)));
|
|
242
|
+
adminizer.app.post(`${agentRoute}/conversations/:conversationId/select`, withPolicies(AiAgentController.selectConversation, requireAuthAPI(), requirePermission(aiModelToken)));
|
|
243
|
+
adminizer.app.delete(`${agentRoute}/conversations/:conversationId`, withPolicies(AiAgentController.deleteConversation, requireAuthAPI(), requirePermission(aiModelToken)));
|
|
244
|
+
adminizer.app.post(`${agentRoute}/runs`, withPolicies(AiAgentController.startRun, requireAuthAPI(), requirePermission(aiModelToken)));
|
|
245
|
+
adminizer.app.get(`${agentRoute}/runs/:runId/stream`, withPolicies(AiAgentController.streamRun, requireAuthAPI(), requirePermission(aiModelToken)));
|
|
228
246
|
adminizer.app.get(`${adminizer.config.routePrefix}/get-timezones`, withPolicies(timezones, requireAuthUI()));
|
|
229
247
|
if (adminizer.config.models) {
|
|
230
248
|
for (let model in adminizer.config.models) {
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
import { GROUP_FILTER_VISIBILITY_TOKEN } from "../policies/permissionResolvers.js";
|
|
2
|
+
import { ownershipTransferToken } from "../lib/access-graph/shared.js";
|
|
2
3
|
export default async function bindAccessRights(adminizer) {
|
|
3
4
|
if (adminizer.config.models) {
|
|
4
5
|
let models = adminizer.config.models;
|
|
5
|
-
for (
|
|
6
|
-
const model = models[key];
|
|
6
|
+
for (const [resourceName, model] of Object.entries(models)) {
|
|
7
7
|
if (typeof model !== "boolean") {
|
|
8
|
-
adminizer.accessRightsHelper.registerModelTokens(
|
|
8
|
+
adminizer.accessRightsHelper.registerModelTokens(resourceName);
|
|
9
|
+
// Records of an access-restricted model are pinned to their owner; this token is the
|
|
10
|
+
// opt-in way back to the pre-scoping workflow of handing one over.
|
|
11
|
+
if (model && typeof model === "object" && model.userAccessRelation) {
|
|
12
|
+
adminizer.accessRightsHelper.registerToken({
|
|
13
|
+
id: ownershipTransferToken(resourceName),
|
|
14
|
+
name: "Transfer ownership",
|
|
15
|
+
description: "Allows setting the owner of a record explicitly instead of inheriting the current user's one",
|
|
16
|
+
department: `Model ${resourceName}`
|
|
17
|
+
});
|
|
18
|
+
}
|
|
9
19
|
}
|
|
10
20
|
}
|
|
11
21
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Adminizer } from '../lib/Adminizer.js';
|
|
2
|
+
/**
|
|
3
|
+
* The single wiring point of the documentation subsystem: the base token, the
|
|
4
|
+
* navigation entries, the assistant skills and the HTTP routes.
|
|
5
|
+
*
|
|
6
|
+
* It is run by `DocumentationHandler.activate()` — at most once, and only when
|
|
7
|
+
* the feature has both of its switches: `config.documentation.enabled` is
|
|
8
|
+
* `true` AND an implementation is registered. Either one missing means none of
|
|
9
|
+
* this exists; the feature is indistinguishable from absent. The implementation
|
|
10
|
+
* arrives after `init()`, so the routes are mounted late — the same way the
|
|
11
|
+
* feedback controller is.
|
|
12
|
+
*/
|
|
13
|
+
export default function bindDocs(adminizer: Adminizer): void;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { DOCUMENTATION_DEPARTMENT } from '../lib/docs/DocumentationHandler.js';
|
|
2
|
+
import { buildDocumentationAgentSkills } from '../lib/docs/docsAgentSkills.js';
|
|
3
|
+
import { docsContext, docsDoc, docsKeywords, docsList, docsPage, docsResolve, docsSchema, docsSearch } from '../controllers/docs';
|
|
4
|
+
import { requireAuthAPI, requireAuthUI, requirePermission } from '../policies/authPolicies.js';
|
|
5
|
+
import { documentationToken } from '../policies/permissionResolvers.js';
|
|
6
|
+
import { bindWithMiddlewares } from './routePolicies.js';
|
|
7
|
+
/**
|
|
8
|
+
* The single wiring point of the documentation subsystem: the base token, the
|
|
9
|
+
* navigation entries, the assistant skills and the HTTP routes.
|
|
10
|
+
*
|
|
11
|
+
* It is run by `DocumentationHandler.activate()` — at most once, and only when
|
|
12
|
+
* the feature has both of its switches: `config.documentation.enabled` is
|
|
13
|
+
* `true` AND an implementation is registered. Either one missing means none of
|
|
14
|
+
* this exists; the feature is indistinguishable from absent. The implementation
|
|
15
|
+
* arrives after `init()`, so the routes are mounted late — the same way the
|
|
16
|
+
* feedback controller is.
|
|
17
|
+
*/
|
|
18
|
+
export default function bindDocs(adminizer) {
|
|
19
|
+
adminizer.accessRightsHelper.registerToken({
|
|
20
|
+
id: adminizer.documentationHandler.baseToken,
|
|
21
|
+
name: 'Documentation',
|
|
22
|
+
description: 'Access to the built-in documentation (knowledge base)',
|
|
23
|
+
department: DOCUMENTATION_DEPARTMENT,
|
|
24
|
+
});
|
|
25
|
+
// The viewer in the navigation, and the per-document page as a template:
|
|
26
|
+
// the assistant discovers both through `list_admin_navigation` and can
|
|
27
|
+
// link a user straight to an article.
|
|
28
|
+
adminizer.adminLinkHandler.add({
|
|
29
|
+
id: 'documentation',
|
|
30
|
+
type: 'page',
|
|
31
|
+
name: 'Documentation',
|
|
32
|
+
title: 'Documentation',
|
|
33
|
+
link: `${adminizer.config.routePrefix}/docs`,
|
|
34
|
+
section: 'Platform',
|
|
35
|
+
accessRightsToken: adminizer.documentationHandler.baseToken,
|
|
36
|
+
});
|
|
37
|
+
adminizer.adminLinkHandler.addTemplate({
|
|
38
|
+
id: 'documentation-article',
|
|
39
|
+
title: 'Documentation article',
|
|
40
|
+
description: 'A single knowledge base article opened in the documentation viewer',
|
|
41
|
+
template: `${adminizer.config.routePrefix}/docs/:id`,
|
|
42
|
+
section: 'Platform',
|
|
43
|
+
accessRightsToken: adminizer.documentationHandler.baseToken,
|
|
44
|
+
params: [{ name: 'id', description: 'Document id as returned by the documentation skills' }],
|
|
45
|
+
});
|
|
46
|
+
// The assistant and the documentation are independent: skills are just
|
|
47
|
+
// registered; whether an agent picks them up is the assistant's business.
|
|
48
|
+
for (const skill of buildDocumentationAgentSkills(adminizer)) {
|
|
49
|
+
adminizer.aiAssistantAgentSkillHandler.add(skill);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* HTTP routes — a thin proxy over DocumentationHandler. Mounted routes
|
|
53
|
+
* cannot be unmounted, so after a runtime `unregister()` the API answers
|
|
54
|
+
* the same `404` an unknown path gets, not a 500.
|
|
55
|
+
*/
|
|
56
|
+
const requireDocsService = (req, res, next) => {
|
|
57
|
+
if (!req.adminizer.documentationHandler.isRegistered()) {
|
|
58
|
+
return res.status(404).json({ error: req.i18n?.__('Not found') || 'Not found' });
|
|
59
|
+
}
|
|
60
|
+
return next();
|
|
61
|
+
};
|
|
62
|
+
const middlewares = adminizer.config.middlewares ?? [];
|
|
63
|
+
const route = (action, ...policies) => bindWithMiddlewares(adminizer, middlewares, action, policies);
|
|
64
|
+
const prefix = adminizer.config.routePrefix;
|
|
65
|
+
adminizer.app.get(`${prefix}/docs/api/list`, route(docsList, requireDocsService, requireAuthAPI(), requirePermission(documentationToken)));
|
|
66
|
+
adminizer.app.get(`${prefix}/docs/api/keywords`, route(docsKeywords, requireDocsService, requireAuthAPI(), requirePermission(documentationToken)));
|
|
67
|
+
adminizer.app.get(`${prefix}/docs/api/search`, route(docsSearch, requireDocsService, requireAuthAPI(), requirePermission(documentationToken)));
|
|
68
|
+
adminizer.app.get(`${prefix}/docs/api/context`, route(docsContext, requireDocsService, requireAuthAPI(), requirePermission(documentationToken)));
|
|
69
|
+
adminizer.app.get(`${prefix}/docs/api/doc/:id`, route(docsDoc, requireDocsService, requireAuthAPI(), requirePermission(documentationToken)));
|
|
70
|
+
adminizer.app.get(`${prefix}/docs/api/resolve`, route(docsResolve, requireDocsService, requireAuthAPI(), requirePermission(documentationToken)));
|
|
71
|
+
adminizer.app.get(`${prefix}/docs/api/schema`, route(docsSchema, requireDocsService, requireAuthAPI(), requirePermission(documentationToken)));
|
|
72
|
+
// The viewer itself; registered after the API so that `/docs/api/...`
|
|
73
|
+
// never falls into `/docs/:id`. Without a service the page renders an
|
|
74
|
+
// empty knowledge base — the API behind it answers 404.
|
|
75
|
+
adminizer.app.get(`${prefix}/docs`, route(docsPage, requireAuthUI(), requirePermission(documentationToken, { mode: 'ui' })));
|
|
76
|
+
adminizer.app.get(`${prefix}/docs/:id`, route(docsPage, requireAuthUI(), requirePermission(documentationToken, { mode: 'ui' })));
|
|
77
|
+
}
|