adminforth 1.1.31 → 1.1.32
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/plugins/AccessControl/index.js +56 -3
- package/dist/spa/index.html +2 -2
- package/dist/spa/package-lock.json +189 -1
- package/dist/spa/package.json +6 -1
- package/dist/spa/spa/src/App.vue +2 -0
- package/dist/spa/spa/src/components/ResourceForm.vue +1 -1
- package/dist/spa/src/App.vue +76 -57
- package/dist/spa/src/components/AcceptModal.vue +1 -1
- package/dist/spa/src/components/CustomDatePicker.vue +3 -3
- package/dist/spa/src/components/CustomDateRangePicker.vue +3 -3
- package/dist/spa/src/components/CustomRangePicker.vue +148 -0
- package/dist/spa/src/components/Dropdown.vue +13 -4
- package/dist/spa/src/components/Filters.vue +55 -22
- package/dist/spa/src/components/MenuLink.vue +2 -2
- package/dist/spa/src/components/ResourceForm.vue +157 -99
- package/dist/spa/src/components/ValueRenderer.vue +11 -1
- package/dist/spa/src/router/index.ts +3 -2
- package/dist/spa/src/stores/core.ts +22 -33
- package/dist/spa/src/utils.ts +5 -3
- package/dist/spa/src/views/CreateView.vue +15 -7
- package/dist/spa/src/views/EditView.vue +36 -8
- package/dist/spa/src/views/ListView.vue +35 -23
- package/dist/spa/src/views/LoginView.vue +1 -1
- package/dist/spa/src/views/ResourceParent.vue +1 -1
- package/dist/spa/src/views/ShowView.vue +20 -9
- package/dist/spa/tailwind.config.js +5 -2
- package/package.json +1 -1
- package/spa/src/App.vue +2 -0
- package/spa/src/components/ResourceForm.vue +1 -1
- package/dist/plugins/plugins/ForeignInlineListPlugin/custom/InlineList.vue +0 -248
- package/dist/spa/spa/src/components/ShowTableItem.vue +0 -14
- package/dist/spa/spa/src/views/HomeView.vue +0 -8
- package/dist/spa/src/views/HomeView.vue +0 -8
|
@@ -1,5 +1,15 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { AllowedActionsEnum } from "../../types/AdminForthConfig.js";
|
|
1
11
|
import AdminForthPlugin from "../base.js";
|
|
2
|
-
class
|
|
12
|
+
class AccessControlPlugin extends AdminForthPlugin {
|
|
3
13
|
constructor(options) {
|
|
4
14
|
super(options, import.meta.url);
|
|
5
15
|
this.options = options;
|
|
@@ -7,7 +17,50 @@ class AuditLogPlugin extends AdminForthPlugin {
|
|
|
7
17
|
modifyResourceConfig(adminforth, resourceConfig) {
|
|
8
18
|
super.modifyResourceConfig(adminforth, resourceConfig);
|
|
9
19
|
this.adminforth = adminforth;
|
|
20
|
+
if (!resourceConfig.hooks) {
|
|
21
|
+
resourceConfig.hooks = {};
|
|
22
|
+
}
|
|
23
|
+
const checkAccess = (adminUser, action, meta) => __awaiter(this, void 0, void 0, function* () {
|
|
24
|
+
const hasAccessOrError = yield this.options.hasAccess(adminUser, action, meta);
|
|
25
|
+
if (hasAccessOrError === true) {
|
|
26
|
+
return { ok: true };
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
return { ok: false, error: hasAccessOrError || AccessControlPlugin.defaultError };
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
const bindHookCheck = (action, hookName) => {
|
|
33
|
+
if (!resourceConfig.hooks[action]) {
|
|
34
|
+
resourceConfig.hooks[action] = {};
|
|
35
|
+
}
|
|
36
|
+
if (!resourceConfig.hooks[action][hookName]) {
|
|
37
|
+
resourceConfig.hooks[action][hookName] = [];
|
|
38
|
+
}
|
|
39
|
+
if (hookName === 'beforeDatasourceRequest') {
|
|
40
|
+
resourceConfig.hooks[action][hookName].unshift((_a) => __awaiter(this, [_a], void 0, function* ({ adminUser, query }) {
|
|
41
|
+
return checkAccess(adminUser, action, { query });
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
resourceConfig.hooks[action][hookName].unshift((_b) => __awaiter(this, [_b], void 0, function* ({ adminUser, record }) {
|
|
46
|
+
return checkAccess(adminUser, action, { record });
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
// List check
|
|
51
|
+
bindHookCheck(AllowedActionsEnum.list, 'beforeDatasourceRequest');
|
|
52
|
+
// Show check
|
|
53
|
+
bindHookCheck(AllowedActionsEnum.show, 'beforeDatasourceRequest');
|
|
54
|
+
// Edit check
|
|
55
|
+
bindHookCheck(AllowedActionsEnum.edit, 'beforeDatasourceRequest');
|
|
56
|
+
// create check
|
|
57
|
+
bindHookCheck(AllowedActionsEnum.create, 'beforeSave');
|
|
58
|
+
// edit check
|
|
59
|
+
bindHookCheck(AllowedActionsEnum.edit, 'beforeSave');
|
|
60
|
+
// delete check
|
|
61
|
+
bindHookCheck(AllowedActionsEnum.delete, 'beforeSave');
|
|
62
|
+
console.log('resourceConfig', resourceConfig);
|
|
10
63
|
}
|
|
11
64
|
}
|
|
12
|
-
|
|
13
|
-
export default
|
|
65
|
+
AccessControlPlugin.defaultError = 'Sorry, you do not have access to this resource.';
|
|
66
|
+
export default AccessControlPlugin;
|
package/dist/spa/index.html
CHANGED
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
</script> -->
|
|
17
17
|
|
|
18
18
|
</head>
|
|
19
|
-
<body>
|
|
20
|
-
<div id="app" class="min-h-screen dark:bg-gray-800"></div>
|
|
19
|
+
<body class=" ">
|
|
20
|
+
<div id="app" class="min-h-screen bg-html-bg dark:bg-gray-800"></div>
|
|
21
21
|
<script type="module" src="/src/main.ts"></script>
|
|
22
22
|
</body>
|
|
23
23
|
</html>
|
|
@@ -9,12 +9,17 @@
|
|
|
9
9
|
"version": "0.0.0",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@iconify-prerendered/vue-flowbite": "^0.23.1714023977",
|
|
12
|
+
"@unhead/vue": "^1.9.12",
|
|
13
|
+
"@vueuse/core": "^10.10.0",
|
|
12
14
|
"dayjs": "^1.11.11",
|
|
15
|
+
"debounce": "^2.1.0",
|
|
13
16
|
"flowbite": "^2.3.0",
|
|
14
17
|
"flowbite-datepicker": "^1.2.6",
|
|
15
18
|
"pinia": "^2.1.7",
|
|
19
|
+
"unhead": "^1.9.12",
|
|
16
20
|
"vue": "^3.4.21",
|
|
17
|
-
"vue-router": "^4.3.0"
|
|
21
|
+
"vue-router": "^4.3.0",
|
|
22
|
+
"vue-slider-component": "^4.1.0-beta.7"
|
|
18
23
|
},
|
|
19
24
|
"devDependencies": {
|
|
20
25
|
"@rushstack/eslint-patch": "^1.8.0",
|
|
@@ -950,6 +955,11 @@
|
|
|
950
955
|
"undici-types": "~5.26.4"
|
|
951
956
|
}
|
|
952
957
|
},
|
|
958
|
+
"node_modules/@types/web-bluetooth": {
|
|
959
|
+
"version": "0.0.20",
|
|
960
|
+
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz",
|
|
961
|
+
"integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow=="
|
|
962
|
+
},
|
|
953
963
|
"node_modules/@typescript-eslint/eslint-plugin": {
|
|
954
964
|
"version": "7.9.0",
|
|
955
965
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.9.0.tgz",
|
|
@@ -1141,6 +1151,58 @@
|
|
|
1141
1151
|
"integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
|
|
1142
1152
|
"dev": true
|
|
1143
1153
|
},
|
|
1154
|
+
"node_modules/@unhead/dom": {
|
|
1155
|
+
"version": "1.9.12",
|
|
1156
|
+
"resolved": "https://registry.npmjs.org/@unhead/dom/-/dom-1.9.12.tgz",
|
|
1157
|
+
"integrity": "sha512-3MY1TbZmEjGNZapi3wvJW0vWNS2CLKHt7/m57sScDHCNvNBe1mTwrIOhtZFDgAndhml2EVQ68RMa0Vhum/M+cw==",
|
|
1158
|
+
"dependencies": {
|
|
1159
|
+
"@unhead/schema": "1.9.12",
|
|
1160
|
+
"@unhead/shared": "1.9.12"
|
|
1161
|
+
},
|
|
1162
|
+
"funding": {
|
|
1163
|
+
"url": "https://github.com/sponsors/harlan-zw"
|
|
1164
|
+
}
|
|
1165
|
+
},
|
|
1166
|
+
"node_modules/@unhead/schema": {
|
|
1167
|
+
"version": "1.9.12",
|
|
1168
|
+
"resolved": "https://registry.npmjs.org/@unhead/schema/-/schema-1.9.12.tgz",
|
|
1169
|
+
"integrity": "sha512-ue2FKyIZKsuZDpWJBMlBGwMm4s+vFeU3NUWsNt8Z+2JkOUIqO/VG43LxNgY1M595bOS71Gdxk+G9VtzfKJ5uEA==",
|
|
1170
|
+
"dependencies": {
|
|
1171
|
+
"hookable": "^5.5.3",
|
|
1172
|
+
"zhead": "^2.2.4"
|
|
1173
|
+
},
|
|
1174
|
+
"funding": {
|
|
1175
|
+
"url": "https://github.com/sponsors/harlan-zw"
|
|
1176
|
+
}
|
|
1177
|
+
},
|
|
1178
|
+
"node_modules/@unhead/shared": {
|
|
1179
|
+
"version": "1.9.12",
|
|
1180
|
+
"resolved": "https://registry.npmjs.org/@unhead/shared/-/shared-1.9.12.tgz",
|
|
1181
|
+
"integrity": "sha512-72wlLXG3FP3sXUrwd42Uv8jYpHSg4R6IFJcsl+QisRjKM89JnjOFSw1DqWO4IOftW5xOxS4J5v7SQyJ4NJo7Bw==",
|
|
1182
|
+
"dependencies": {
|
|
1183
|
+
"@unhead/schema": "1.9.12"
|
|
1184
|
+
},
|
|
1185
|
+
"funding": {
|
|
1186
|
+
"url": "https://github.com/sponsors/harlan-zw"
|
|
1187
|
+
}
|
|
1188
|
+
},
|
|
1189
|
+
"node_modules/@unhead/vue": {
|
|
1190
|
+
"version": "1.9.12",
|
|
1191
|
+
"resolved": "https://registry.npmjs.org/@unhead/vue/-/vue-1.9.12.tgz",
|
|
1192
|
+
"integrity": "sha512-keE4EuswgzCqVU7zmZprU+ToMvNWc3s8NoLreH5AtJd2u0FgBygD8sxRVyEnZw1KwFYOJ2C7yD2TChSKZioPGQ==",
|
|
1193
|
+
"dependencies": {
|
|
1194
|
+
"@unhead/schema": "1.9.12",
|
|
1195
|
+
"@unhead/shared": "1.9.12",
|
|
1196
|
+
"hookable": "^5.5.3",
|
|
1197
|
+
"unhead": "1.9.12"
|
|
1198
|
+
},
|
|
1199
|
+
"funding": {
|
|
1200
|
+
"url": "https://github.com/sponsors/harlan-zw"
|
|
1201
|
+
},
|
|
1202
|
+
"peerDependencies": {
|
|
1203
|
+
"vue": ">=2.7 || >=3"
|
|
1204
|
+
}
|
|
1205
|
+
},
|
|
1144
1206
|
"node_modules/@vitejs/plugin-vue": {
|
|
1145
1207
|
"version": "5.0.4",
|
|
1146
1208
|
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz",
|
|
@@ -1330,6 +1392,89 @@
|
|
|
1330
1392
|
"integrity": "sha512-VcZK7MvpjuTPx2w6blwnwZAu5/LgBUtejFOi3pPGQFXQN5Ela03FUtd2Qtg4yWGGissVL0dr6Ro1LfOFh+PCuQ==",
|
|
1331
1393
|
"dev": true
|
|
1332
1394
|
},
|
|
1395
|
+
"node_modules/@vueuse/core": {
|
|
1396
|
+
"version": "10.10.0",
|
|
1397
|
+
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.10.0.tgz",
|
|
1398
|
+
"integrity": "sha512-vexJ/YXYs2S42B783rI95lMt3GzEwkxzC8Hb0Ndpd8rD+p+Lk/Za4bd797Ym7yq4jXqdSyj3JLChunF/vyYjUw==",
|
|
1399
|
+
"dependencies": {
|
|
1400
|
+
"@types/web-bluetooth": "^0.0.20",
|
|
1401
|
+
"@vueuse/metadata": "10.10.0",
|
|
1402
|
+
"@vueuse/shared": "10.10.0",
|
|
1403
|
+
"vue-demi": ">=0.14.7"
|
|
1404
|
+
},
|
|
1405
|
+
"funding": {
|
|
1406
|
+
"url": "https://github.com/sponsors/antfu"
|
|
1407
|
+
}
|
|
1408
|
+
},
|
|
1409
|
+
"node_modules/@vueuse/core/node_modules/vue-demi": {
|
|
1410
|
+
"version": "0.14.8",
|
|
1411
|
+
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.8.tgz",
|
|
1412
|
+
"integrity": "sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==",
|
|
1413
|
+
"hasInstallScript": true,
|
|
1414
|
+
"bin": {
|
|
1415
|
+
"vue-demi-fix": "bin/vue-demi-fix.js",
|
|
1416
|
+
"vue-demi-switch": "bin/vue-demi-switch.js"
|
|
1417
|
+
},
|
|
1418
|
+
"engines": {
|
|
1419
|
+
"node": ">=12"
|
|
1420
|
+
},
|
|
1421
|
+
"funding": {
|
|
1422
|
+
"url": "https://github.com/sponsors/antfu"
|
|
1423
|
+
},
|
|
1424
|
+
"peerDependencies": {
|
|
1425
|
+
"@vue/composition-api": "^1.0.0-rc.1",
|
|
1426
|
+
"vue": "^3.0.0-0 || ^2.6.0"
|
|
1427
|
+
},
|
|
1428
|
+
"peerDependenciesMeta": {
|
|
1429
|
+
"@vue/composition-api": {
|
|
1430
|
+
"optional": true
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
},
|
|
1434
|
+
"node_modules/@vueuse/metadata": {
|
|
1435
|
+
"version": "10.10.0",
|
|
1436
|
+
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.10.0.tgz",
|
|
1437
|
+
"integrity": "sha512-UNAo2sTCAW5ge6OErPEHb5z7NEAg3XcO9Cj7OK45aZXfLLH1QkexDcZD77HBi5zvEiLOm1An+p/4b5K3Worpug==",
|
|
1438
|
+
"funding": {
|
|
1439
|
+
"url": "https://github.com/sponsors/antfu"
|
|
1440
|
+
}
|
|
1441
|
+
},
|
|
1442
|
+
"node_modules/@vueuse/shared": {
|
|
1443
|
+
"version": "10.10.0",
|
|
1444
|
+
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.10.0.tgz",
|
|
1445
|
+
"integrity": "sha512-2aW33Ac0Uk0U+9yo3Ypg9s5KcR42cuehRWl7vnUHadQyFvCktseyxxEPBi1Eiq4D2yBGACOnqLZpx1eMc7g5Og==",
|
|
1446
|
+
"dependencies": {
|
|
1447
|
+
"vue-demi": ">=0.14.7"
|
|
1448
|
+
},
|
|
1449
|
+
"funding": {
|
|
1450
|
+
"url": "https://github.com/sponsors/antfu"
|
|
1451
|
+
}
|
|
1452
|
+
},
|
|
1453
|
+
"node_modules/@vueuse/shared/node_modules/vue-demi": {
|
|
1454
|
+
"version": "0.14.8",
|
|
1455
|
+
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.8.tgz",
|
|
1456
|
+
"integrity": "sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==",
|
|
1457
|
+
"hasInstallScript": true,
|
|
1458
|
+
"bin": {
|
|
1459
|
+
"vue-demi-fix": "bin/vue-demi-fix.js",
|
|
1460
|
+
"vue-demi-switch": "bin/vue-demi-switch.js"
|
|
1461
|
+
},
|
|
1462
|
+
"engines": {
|
|
1463
|
+
"node": ">=12"
|
|
1464
|
+
},
|
|
1465
|
+
"funding": {
|
|
1466
|
+
"url": "https://github.com/sponsors/antfu"
|
|
1467
|
+
},
|
|
1468
|
+
"peerDependencies": {
|
|
1469
|
+
"@vue/composition-api": "^1.0.0-rc.1",
|
|
1470
|
+
"vue": "^3.0.0-0 || ^2.6.0"
|
|
1471
|
+
},
|
|
1472
|
+
"peerDependenciesMeta": {
|
|
1473
|
+
"@vue/composition-api": {
|
|
1474
|
+
"optional": true
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
},
|
|
1333
1478
|
"node_modules/acorn": {
|
|
1334
1479
|
"version": "8.11.3",
|
|
1335
1480
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
|
|
@@ -1716,6 +1861,17 @@
|
|
|
1716
1861
|
"integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==",
|
|
1717
1862
|
"dev": true
|
|
1718
1863
|
},
|
|
1864
|
+
"node_modules/debounce": {
|
|
1865
|
+
"version": "2.1.0",
|
|
1866
|
+
"resolved": "https://registry.npmjs.org/debounce/-/debounce-2.1.0.tgz",
|
|
1867
|
+
"integrity": "sha512-OkL3+0pPWCqoBc/nhO9u6TIQNTK44fnBnzuVtJAbp13Naxw9R6u21x+8tVTka87AhDZ3htqZ2pSSsZl9fqL2Wg==",
|
|
1868
|
+
"engines": {
|
|
1869
|
+
"node": ">=18"
|
|
1870
|
+
},
|
|
1871
|
+
"funding": {
|
|
1872
|
+
"url": "https://github.com/sponsors/sindresorhus"
|
|
1873
|
+
}
|
|
1874
|
+
},
|
|
1719
1875
|
"node_modules/debug": {
|
|
1720
1876
|
"version": "4.3.4",
|
|
1721
1877
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
|
@@ -2369,6 +2525,11 @@
|
|
|
2369
2525
|
"he": "bin/he"
|
|
2370
2526
|
}
|
|
2371
2527
|
},
|
|
2528
|
+
"node_modules/hookable": {
|
|
2529
|
+
"version": "5.5.3",
|
|
2530
|
+
"resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
|
|
2531
|
+
"integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="
|
|
2532
|
+
},
|
|
2372
2533
|
"node_modules/ignore": {
|
|
2373
2534
|
"version": "5.3.1",
|
|
2374
2535
|
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
|
|
@@ -3812,6 +3973,20 @@
|
|
|
3812
3973
|
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
|
3813
3974
|
"dev": true
|
|
3814
3975
|
},
|
|
3976
|
+
"node_modules/unhead": {
|
|
3977
|
+
"version": "1.9.12",
|
|
3978
|
+
"resolved": "https://registry.npmjs.org/unhead/-/unhead-1.9.12.tgz",
|
|
3979
|
+
"integrity": "sha512-s6VxcTV45hy8c/IioKQOonFnAO+kBOSpgDfqEHhnU0YVSQYaRPEp9pzW1qSPf0lx+bg9RKeOQyNNbSGGUP26aQ==",
|
|
3980
|
+
"dependencies": {
|
|
3981
|
+
"@unhead/dom": "1.9.12",
|
|
3982
|
+
"@unhead/schema": "1.9.12",
|
|
3983
|
+
"@unhead/shared": "1.9.12",
|
|
3984
|
+
"hookable": "^5.5.3"
|
|
3985
|
+
},
|
|
3986
|
+
"funding": {
|
|
3987
|
+
"url": "https://github.com/sponsors/harlan-zw"
|
|
3988
|
+
}
|
|
3989
|
+
},
|
|
3815
3990
|
"node_modules/update-browserslist-db": {
|
|
3816
3991
|
"version": "1.0.16",
|
|
3817
3992
|
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz",
|
|
@@ -3970,6 +4145,11 @@
|
|
|
3970
4145
|
"vue": "^3.2.0"
|
|
3971
4146
|
}
|
|
3972
4147
|
},
|
|
4148
|
+
"node_modules/vue-slider-component": {
|
|
4149
|
+
"version": "4.1.0-beta.7",
|
|
4150
|
+
"resolved": "https://registry.npmjs.org/vue-slider-component/-/vue-slider-component-4.1.0-beta.7.tgz",
|
|
4151
|
+
"integrity": "sha512-Qb7K920ZG7PoQswoF6Ias+i3W2rd3k4fpk04JUl82kEUcN86Yg6et7bVSKWt/7VpQe8a5IT3BqCKSCOZ7AJgCA=="
|
|
4152
|
+
},
|
|
3973
4153
|
"node_modules/vue-template-compiler": {
|
|
3974
4154
|
"version": "2.7.16",
|
|
3975
4155
|
"resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz",
|
|
@@ -4153,6 +4333,14 @@
|
|
|
4153
4333
|
"funding": {
|
|
4154
4334
|
"url": "https://github.com/sponsors/sindresorhus"
|
|
4155
4335
|
}
|
|
4336
|
+
},
|
|
4337
|
+
"node_modules/zhead": {
|
|
4338
|
+
"version": "2.2.4",
|
|
4339
|
+
"resolved": "https://registry.npmjs.org/zhead/-/zhead-2.2.4.tgz",
|
|
4340
|
+
"integrity": "sha512-8F0OI5dpWIA5IGG5NHUg9staDwz/ZPxZtvGVf01j7vHqSyZ0raHY+78atOVxRqb73AotX22uV1pXt3gYSstGag==",
|
|
4341
|
+
"funding": {
|
|
4342
|
+
"url": "https://github.com/sponsors/harlan-zw"
|
|
4343
|
+
}
|
|
4156
4344
|
}
|
|
4157
4345
|
}
|
|
4158
4346
|
}
|
package/dist/spa/package.json
CHANGED
|
@@ -13,12 +13,17 @@
|
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@iconify-prerendered/vue-flowbite": "^0.23.1714023977",
|
|
16
|
+
"@unhead/vue": "^1.9.12",
|
|
17
|
+
"@vueuse/core": "^10.10.0",
|
|
16
18
|
"dayjs": "^1.11.11",
|
|
19
|
+
"debounce": "^2.1.0",
|
|
17
20
|
"flowbite": "^2.3.0",
|
|
18
21
|
"flowbite-datepicker": "^1.2.6",
|
|
19
22
|
"pinia": "^2.1.7",
|
|
23
|
+
"unhead": "^1.9.12",
|
|
20
24
|
"vue": "^3.4.21",
|
|
21
|
-
"vue-router": "^4.3.0"
|
|
25
|
+
"vue-router": "^4.3.0",
|
|
26
|
+
"vue-slider-component": "^4.1.0-beta.7"
|
|
22
27
|
},
|
|
23
28
|
"devDependencies": {
|
|
24
29
|
"@rushstack/eslint-patch": "^1.8.0",
|
package/dist/spa/spa/src/App.vue
CHANGED
|
@@ -70,6 +70,7 @@
|
|
|
70
70
|
{{ coreStore.config?.brandName }}
|
|
71
71
|
</span>
|
|
72
72
|
</div>
|
|
73
|
+
|
|
73
74
|
<ul class="space-y-2 font-medium">
|
|
74
75
|
<template v-for="(item, i) in coreStore.menu" :key="`menu-${i}`">
|
|
75
76
|
<div v-if="item.type === 'divider'" class="border-t border-nav-menu-devider dark:border-gray-700"></div>
|
|
@@ -241,6 +242,7 @@ async function loadMenu() {
|
|
|
241
242
|
|
|
242
243
|
coreStore.menu.forEach((item, i) => {
|
|
243
244
|
if (item.open) {
|
|
245
|
+
console.log(item)
|
|
244
246
|
opened.value.push(i);
|
|
245
247
|
}
|
|
246
248
|
});
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
single
|
|
49
49
|
v-if="column.foreignResource"
|
|
50
50
|
:options="columnOptions[column.name] || []"
|
|
51
|
-
:placeholder = "columnOptions[column.name]
|
|
51
|
+
:placeholder = "columnOptions[column.name]?.length || 'There are no options available'"
|
|
52
52
|
:modelValue="currentValues[column.name]"
|
|
53
53
|
@update:modelValue="setCurrentValue(column.name, $event)"
|
|
54
54
|
></Dropdown>
|
package/dist/spa/src/App.vue
CHANGED
|
@@ -1,88 +1,84 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<nav
|
|
3
3
|
v-if="loggedIn"
|
|
4
|
-
|
|
5
|
-
class="fixed h-14 top-0 z-50 w-full bg-white border-b border-gray-200 dark:bg-gray-800 dark:border-gray-700">
|
|
4
|
+
class="fixed h-14 top-0 z-40 w-full border-b shadow-sm bg-header-bg shadow-header-shadow dark:bg-header-bg-hover dark:border-nav-menu-devider">
|
|
6
5
|
<div class="px-3 py-3 lg:px-5 lg:pl-3">
|
|
7
6
|
<div class="flex items-center justify-between">
|
|
8
7
|
<div class="flex items-center justify-start rtl:justify-end">
|
|
9
|
-
<button data-drawer-target="logo-sidebar" data-drawer-toggle="logo-sidebar" aria-controls="logo-sidebar" type="button" class="inline-flex items-center p-2 text-sm
|
|
8
|
+
<button data-drawer-target="logo-sidebar" data-drawer-toggle="logo-sidebar" aria-controls="logo-sidebar" type="button" class="inline-flex items-center p-2 text-sm rounded-lg sm:hidden hover:bg-nav-menu-bg-hover focus:outline-none focus:ring-2 focus:ring-nav-menu-devider dark:text-nav-menu-icons dark:hover:bg-nav-menu-bg-hover dark:focus:ring-nav-menu-devider">
|
|
10
9
|
<span class="sr-only">Open sidebar</span>
|
|
11
10
|
<svg class="w-6 h-6" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
|
12
11
|
<path clip-rule="evenodd" fill-rule="evenodd" d="M2 4.75A.75.75 0 012.75 4h14.5a.75.75 0 010 1.5H2.75A.75.75 0 012 4.75zm0 10.5a.75.75 0 01.75-.75h7.5a.75.75 0 010 1.5h-7.5a.75.75 0 01-.75-.75zM2 10a.75.75 0 01.75-.75h14.5a.75.75 0 010 1.5H2.75A.75.75 0 012 10z"></path>
|
|
13
12
|
</svg>
|
|
14
13
|
</button>
|
|
15
|
-
|
|
16
|
-
<img src="https://flowbite.com/docs/images/logo.svg" class="h-8 me-3" alt="FlowBite Logo" />
|
|
17
|
-
<span class="self-center text-xl font-semibold sm:text-2xl whitespace-nowrap dark:text-white">
|
|
18
|
-
{{ coreStore.config?.brandName }}
|
|
19
|
-
</span>
|
|
20
|
-
</div>
|
|
14
|
+
|
|
21
15
|
</div>
|
|
22
16
|
<div class="flex items-center">
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
<
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
17
|
+
<div class="flex items-center ms-3 ">
|
|
18
|
+
<div>
|
|
19
|
+
<button type="button" class="flex text-sm bg-header-bg-hover rounded-full focus:ring-4 focus:ring-nav-menu-devider dark:focus:ring-nav-menu-devider dark:bg-header-bg-hover" aria-expanded="false" data-dropdown-toggle="dropdown-user">
|
|
20
|
+
<span class="sr-only">Open user menu</span>
|
|
21
|
+
<svg class="w-8 h-8 text-nav-menu-icons dark:text-header-icons" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 24 24">
|
|
22
|
+
<path fill-rule="evenodd" d="M12 20a7.966 7.966 0 0 1-5.002-1.756l.002.001v-.683c0-1.794 1.492-3.25 3.333-3.25h3.334c1.84 0 3.333 1.456 3.333 3.25v.683A7.966 7.966 0 0 1 12 20ZM2 12C2 6.477 6.477 2 12 2s10 4.477 10 10c0 5.5-4.44 9.963-9.932 10h-.138C6.438 21.962 2 17.5 2 12Zm10-5c-1.84 0-3.333 1.455-3.333 3.25S10.159 13.5 12 13.5c1.84 0 3.333-1.455 3.333-3.25S13.841 7 12 7Z" clip-rule="evenodd"/>
|
|
23
|
+
</svg>
|
|
24
|
+
</button>
|
|
25
|
+
</div>
|
|
26
|
+
<div class="z-50 hidden my-4 text-base list-none bg-white divide-y divide-gray-100 rounded shadow dark:shadow-black dark:bg-nav-menu-bg dark:divide-nav-menu-devider dark:shadow-black" id="dropdown-user">
|
|
27
|
+
<div class="px-4 py-3" role="none">
|
|
28
|
+
<p class="text-sm text-gray-900 dark:text-header-text" role="none" v-if="coreStore.userFullname">
|
|
29
|
+
{{ coreStore.userFullname }}
|
|
30
|
+
</p>
|
|
31
|
+
<p class="text-sm font-medium text-gray-900 truncate dark:text-nav-menu-text" role="none">
|
|
32
|
+
{{ coreStore.username }}
|
|
33
|
+
</p>
|
|
34
34
|
</div>
|
|
35
|
-
<
|
|
36
|
-
<
|
|
37
|
-
<
|
|
38
|
-
{{
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
</
|
|
43
|
-
</div>
|
|
44
|
-
<ul class="py-1" role="none">
|
|
45
|
-
<li>
|
|
46
|
-
<a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-600 dark:hover:text-white" role="menuitem">Dashboard</a>
|
|
47
|
-
</li>
|
|
48
|
-
<li >
|
|
49
|
-
<span @click="toggleTheme" class=" cursor-pointer flex items-center gap-1 block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-600 dark:hover:text-white" role="menuitem">
|
|
50
|
-
{{ theme === 'dark' ? 'Light' : 'Dark' }}
|
|
51
|
-
<IconMoonSolid class="w-5 h-5 text-blue-300
|
|
52
|
-
" v-if="theme !== 'dark'"/>
|
|
53
|
-
<IconSunSolid class="w-5 h-5 text-yellow-300
|
|
54
|
-
" v-else/>
|
|
55
|
-
mode
|
|
56
|
-
</span>
|
|
57
|
-
</li>
|
|
58
|
-
|
|
59
|
-
<li>
|
|
60
|
-
<button @click="logout" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-600 dark:hover:text-white" role="menuitem">Sign out</button>
|
|
35
|
+
<ul class="py-1" role="none">
|
|
36
|
+
<li>
|
|
37
|
+
<span @click="toggleTheme" class="cursor-pointer flex items-center gap-1 block px-4 py-2 text-sm text-black hover:bg-html-bg dark:text-nav-menu-text-hover dark:hover:bg-nav-menu-hover dark:hover:text-nav-menu-text-active" role="menuitem">
|
|
38
|
+
{{ theme === 'dark' ? 'Light' : 'Dark' }}
|
|
39
|
+
<IconMoonSolid class="w-5 h-5 text-blue-300" v-if="theme !== 'dark'" />
|
|
40
|
+
<IconSunSolid class="w-5 h-5 text-yellow-300" v-else />
|
|
41
|
+
mode
|
|
42
|
+
</span>
|
|
61
43
|
</li>
|
|
62
|
-
|
|
63
|
-
|
|
44
|
+
<li>
|
|
45
|
+
<button @click="logout" class="cursor-pointer flex items-center gap-1 block px-4 py-2 text-sm text-black hover:bg-html-bg dark:text-nav-menu-text-hover dark:hover:bg-nav-menu-hover dark:hover:text-nav-menu-text-active w-full" role="menuitem">Sign out</button>
|
|
46
|
+
</li>
|
|
47
|
+
</ul>
|
|
64
48
|
</div>
|
|
65
49
|
</div>
|
|
50
|
+
</div>
|
|
66
51
|
</div>
|
|
67
52
|
</div>
|
|
68
|
-
|
|
53
|
+
</nav>
|
|
54
|
+
|
|
55
|
+
|
|
69
56
|
|
|
70
57
|
<aside
|
|
71
58
|
v-if="loggedIn"
|
|
72
59
|
|
|
73
|
-
id="logo-sidebar" class="fixed top-0 left-0 z-
|
|
74
|
-
<div class="h-full px-3 pb-4 overflow-y-auto bg-
|
|
60
|
+
id="logo-sidebar" class="fixed border-none top-0 left-0 z-50 w-64 h-screen transition-transform -translate-x-full bg-nav-menu-bg border-r border- sm:translate-x-0 dark:bg-gray-800 dark:border-gray-700" aria-label="Sidebar">
|
|
61
|
+
<div class="h-full px-3 pb-4 overflow-y-auto bg-nav-menu-bg dark:bg-gray-800">
|
|
62
|
+
<div class="flex ms-2 md:me-24 m-4 ">
|
|
63
|
+
<img src="https://flowbite.com/docs/images/logo.svg" class="h-8 me-3" alt="FlowBite Logo" />
|
|
64
|
+
<span class="self-center text-header-text-size font-semibold sm:text-header-text-size whitespace-nowrap dark:text-header-text text-header-logo-color">
|
|
65
|
+
{{ coreStore.config?.brandName }}
|
|
66
|
+
</span>
|
|
67
|
+
</div>
|
|
75
68
|
<ul class="space-y-2 font-medium">
|
|
76
69
|
<template v-for="(item, i) in coreStore.menu" :key="`menu-${i}`">
|
|
77
|
-
<div v-if="item.type === 'divider'" class="border-t border-
|
|
70
|
+
<div v-if="item.type === 'divider'" class="border-t border-nav-menu-devider dark:border-gray-700"></div>
|
|
78
71
|
<div v-else-if="item.type === 'gap'" class="flex items-center justify-center h-8"></div>
|
|
72
|
+
<div v-else-if="item.type === 'heading'" class="flex items-center justify-left pl-2 h-8 text-gray-400 dark:text-gray-400
|
|
73
|
+
">{{ item.label }}</div>
|
|
74
|
+
|
|
79
75
|
|
|
80
76
|
<li v-else-if="item.children">
|
|
81
|
-
<button type="button" class="flex items-center w-full p-2 text-base text-
|
|
77
|
+
<button type="button" class="flex items-center w-full p-2 text-base text-nav-menu-text rounded-default transition duration-75 group hover:bg-nav-menu-bg-hover dark:text-white dark:hover:bg-gray-700"
|
|
82
78
|
:aria-controls="`dropdown-example${i}`"
|
|
83
79
|
:data-collapse-toggle="`dropdown-example${i}`"
|
|
84
80
|
>
|
|
85
|
-
<component v-if="item.icon" :is="getIcon(item.icon)" class="w-5 h-5 text-gray-500 transition duration-75 dark:text-gray-400
|
|
81
|
+
<component v-if="item.icon" :is="getIcon(item.icon)" class="w-5 h-5 text-gray-500 transition duration-75 dark:text-gray-400 dark:group-hover:text-white" ></component>
|
|
86
82
|
|
|
87
83
|
<span class="flex-1 ms-3 text-left rtl:text-right whitespace-nowrap">{{ item.label }}</span>
|
|
88
84
|
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6">
|
|
@@ -90,7 +86,7 @@
|
|
|
90
86
|
</svg>
|
|
91
87
|
</button>
|
|
92
88
|
|
|
93
|
-
<ul :id="`dropdown-example${i}`" role="none" class="
|
|
89
|
+
<ul :id="`dropdown-example${i}`" role="none" class="pt-1 space-y-1" :class="{ 'hidden': !item.open }">
|
|
94
90
|
<template v-for="(child, j) in item.children" :key="`menu-${i}-${j}`">
|
|
95
91
|
<li>
|
|
96
92
|
<MenuLink :item="child" isChild="true" />
|
|
@@ -112,7 +108,7 @@
|
|
|
112
108
|
</div>
|
|
113
109
|
</div>
|
|
114
110
|
|
|
115
|
-
<div v-else>
|
|
111
|
+
<div v-else-if="routerIsReady">
|
|
116
112
|
<RouterView/>
|
|
117
113
|
</div>
|
|
118
114
|
<AcceptModal />
|
|
@@ -132,10 +128,23 @@ import AcceptModal from './components/AcceptModal.vue';
|
|
|
132
128
|
import MenuLink from './components/MenuLink.vue';
|
|
133
129
|
import { useRoute, useRouter } from 'vue-router';
|
|
134
130
|
import { getIcon } from '@/utils';
|
|
131
|
+
import { useHead } from 'unhead'
|
|
132
|
+
import { createHead } from 'unhead'
|
|
133
|
+
// import { link } from 'fs';
|
|
134
|
+
const coreStore = useCoreStore();
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
createHead()
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
|
|
135
142
|
|
|
136
143
|
|
|
137
144
|
const route = useRoute();
|
|
138
145
|
const router = useRouter();
|
|
146
|
+
const title = ref('');
|
|
147
|
+
|
|
139
148
|
|
|
140
149
|
const routerIsReady = ref(false);
|
|
141
150
|
|
|
@@ -153,7 +162,6 @@ async function logout() {
|
|
|
153
162
|
router.push({ name: 'login' });
|
|
154
163
|
}
|
|
155
164
|
|
|
156
|
-
const coreStore = useCoreStore();
|
|
157
165
|
|
|
158
166
|
|
|
159
167
|
|
|
@@ -167,6 +175,17 @@ onMounted(async () => {
|
|
|
167
175
|
initRouter();
|
|
168
176
|
initFlowbite();
|
|
169
177
|
await coreStore.fetchMenuAndResource();
|
|
178
|
+
title.value = coreStore.config.title || 'Admin Forth';
|
|
179
|
+
useHead({
|
|
180
|
+
title: title.value,
|
|
181
|
+
link: [
|
|
182
|
+
{
|
|
183
|
+
rel: 'icon',
|
|
184
|
+
href: coreStore.config.favicon || '/favicon.ico',
|
|
185
|
+
},
|
|
186
|
+
],
|
|
187
|
+
|
|
188
|
+
})
|
|
170
189
|
})
|
|
171
190
|
|
|
172
191
|
</script>
|
|
@@ -16,7 +16,7 @@ const modalStore = useModalStore();
|
|
|
16
16
|
<Teleport to="body">
|
|
17
17
|
<div v-if="modalStore.isOpened" class="bg-gray-900/50 dark:bg-gray-900/80 overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full">
|
|
18
18
|
<div class="relative p-4 w-full max-w-md max-h-full top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 " >
|
|
19
|
-
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
|
|
19
|
+
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700 dark:shadow-black">
|
|
20
20
|
<button type="button"@click="modalStore.togleModal" class="absolute top-3 end-2.5 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white" >
|
|
21
21
|
<svg class="w-3 h-3" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
|
|
22
22
|
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<label for="start-time" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">{{ label }}</label>
|
|
6
6
|
|
|
7
7
|
<div class="relative">
|
|
8
|
-
<div class="absolute inset-y-0 end-0 top-0 flex items-center pe-3.5">
|
|
8
|
+
<div class="absolute inset-y-0 end-0 top-0 flex items-center pe-3.5 pointer-events-none">
|
|
9
9
|
<IconCalendar class="w-4 h-4 text-gray-500 dark:text-gray-400"/>
|
|
10
10
|
</div>
|
|
11
11
|
|
|
@@ -97,7 +97,7 @@ const start = computed(() => {
|
|
|
97
97
|
})
|
|
98
98
|
|
|
99
99
|
function updateFromProps() {
|
|
100
|
-
if (props.valueStart
|
|
100
|
+
if (!props.valueStart) {
|
|
101
101
|
datepickerStartEl.value.value = '';
|
|
102
102
|
startTime.value = '';
|
|
103
103
|
}
|
|
@@ -157,5 +157,5 @@ onMounted(() => {
|
|
|
157
157
|
|
|
158
158
|
onBeforeUnmount(() => {
|
|
159
159
|
removeChangeDateListener();
|
|
160
|
-
})
|
|
160
|
+
});
|
|
161
161
|
</script>
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
<div class="mx-auto grid grid-cols-2 gap-4 mb-2" :class="{hidden: !showTimeInputs}">
|
|
27
27
|
<div>
|
|
28
28
|
<div class="relative">
|
|
29
|
-
<div class="absolute inset-y-0 end-0 top-0 flex items-center pe-3.5">
|
|
29
|
+
<div class="absolute inset-y-0 end-0 top-0 flex items-center pe-3.5 pointer-events-none">
|
|
30
30
|
<IconTime class="w-4 h-4 text-gray-500 dark:text-gray-400 bg-white dark:bg-gray-700"/>
|
|
31
31
|
</div>
|
|
32
32
|
|
|
@@ -132,11 +132,11 @@ const end = computed(() => {
|
|
|
132
132
|
})
|
|
133
133
|
|
|
134
134
|
function updateFromProps() {
|
|
135
|
-
if (props.valueStart
|
|
135
|
+
if (!props.valueStart) {
|
|
136
136
|
datepickerStartEl.value.value = '';
|
|
137
137
|
startTime.value = '';
|
|
138
138
|
}
|
|
139
|
-
if (props.valueEnd
|
|
139
|
+
if (!props.valueEnd) {
|
|
140
140
|
datepickerEndEl.value.value = '';
|
|
141
141
|
endTime.value = '';
|
|
142
142
|
}
|