adminforth 1.1.32 → 1.1.33

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.
Files changed (98) hide show
  1. package/dist/index.js +9 -0
  2. package/dist/modules/codeInjector.js +19 -7
  3. package/dist/modules/styles.js +2 -2
  4. package/dist/spa/index.html +2 -2
  5. package/dist/spa/package-lock.json +17 -4
  6. package/dist/spa/package.json +2 -1
  7. package/dist/spa/src/App.vue +125 -45
  8. package/dist/spa/src/assets/logo.svg +19 -1
  9. package/dist/spa/src/components/AcceptModal.vue +2 -9
  10. package/dist/spa/src/components/BreadcrumbsWithButtons.vue +1 -1
  11. package/dist/spa/src/components/CustomDatePicker.vue +16 -3
  12. package/dist/spa/src/components/CustomDateRangePicker.vue +11 -2
  13. package/dist/spa/src/components/Dropdown.vue +6 -1
  14. package/dist/spa/src/components/Filters.vue +40 -19
  15. package/dist/spa/src/components/ResourceForm.vue +26 -24
  16. package/dist/spa/src/components/ValueRenderer.vue +14 -8
  17. package/dist/spa/src/main.ts +1 -1
  18. package/dist/spa/src/router/index.ts +30 -20
  19. package/dist/spa/src/stores/core.ts +48 -31
  20. package/dist/spa/src/stores/modal.ts +13 -3
  21. package/dist/spa/src/utils.ts +62 -7
  22. package/dist/spa/src/views/CreateView.vue +67 -15
  23. package/dist/spa/src/views/EditView.vue +45 -11
  24. package/dist/spa/src/views/ListView.vue +82 -366
  25. package/dist/spa/src/views/LoginView.vue +16 -4
  26. package/dist/spa/src/views/ShowView.vue +105 -21
  27. package/dist/spa/tailwind.config.js +1 -1
  28. package/dist/spa/vite.config.ts +6 -0
  29. package/index.ts +11 -0
  30. package/modules/codeInjector.ts +19 -1
  31. package/modules/styles.ts +2 -2
  32. package/package.json +1 -1
  33. package/spa/index.html +1 -1
  34. package/spa/src/App.vue +2 -3
  35. package/types/AdminForthConfig.ts +15 -0
  36. package/dist/plugins/AccessControl/index.js +0 -66
  37. package/dist/plugins/AccessControl/types.js +0 -1
  38. package/dist/spa/public/favicon.ico +0 -0
  39. package/dist/spa/spa/.eslintrc.cjs +0 -14
  40. package/dist/spa/spa/.vscode/extensions.json +0 -6
  41. package/dist/spa/spa/README.md +0 -39
  42. package/dist/spa/spa/env.d.ts +0 -1
  43. package/dist/spa/spa/index.html +0 -23
  44. package/dist/spa/spa/package-lock.json +0 -4359
  45. package/dist/spa/spa/package.json +0 -47
  46. package/dist/spa/spa/postcss.config.js +0 -6
  47. package/dist/spa/spa/public/favicon.ico +0 -0
  48. package/dist/spa/spa/src/App.vue +0 -272
  49. package/dist/spa/spa/src/assets/base.css +0 -0
  50. package/dist/spa/spa/src/assets/logo.svg +0 -19
  51. package/dist/spa/spa/src/components/AcceptModal.vue +0 -45
  52. package/dist/spa/spa/src/components/Breadcrumbs.vue +0 -40
  53. package/dist/spa/spa/src/components/BreadcrumbsWithButtons.vue +0 -26
  54. package/dist/spa/spa/src/components/CustomDatePicker.vue +0 -174
  55. package/dist/spa/spa/src/components/CustomDateRangePicker.vue +0 -218
  56. package/dist/spa/spa/src/components/CustomRangePicker.vue +0 -148
  57. package/dist/spa/spa/src/components/Dropdown.vue +0 -168
  58. package/dist/spa/spa/src/components/Filters.vue +0 -211
  59. package/dist/spa/spa/src/components/HelloWorld.vue +0 -17
  60. package/dist/spa/spa/src/components/MenuLink.vue +0 -24
  61. package/dist/spa/spa/src/components/ResourceForm.vue +0 -265
  62. package/dist/spa/spa/src/components/SingleSkeletLoader.vue +0 -13
  63. package/dist/spa/spa/src/components/ValueRenderer.vue +0 -60
  64. package/dist/spa/spa/src/components/icons/IconCalendar.vue +0 -5
  65. package/dist/spa/spa/src/components/icons/IconCommunity.vue +0 -7
  66. package/dist/spa/spa/src/components/icons/IconDocumentation.vue +0 -7
  67. package/dist/spa/spa/src/components/icons/IconEcosystem.vue +0 -7
  68. package/dist/spa/spa/src/components/icons/IconSupport.vue +0 -7
  69. package/dist/spa/spa/src/components/icons/IconTime.vue +0 -5
  70. package/dist/spa/spa/src/components/icons/IconTooling.vue +0 -19
  71. package/dist/spa/spa/src/index.scss +0 -26
  72. package/dist/spa/spa/src/main.ts +0 -18
  73. package/dist/spa/spa/src/router/index.ts +0 -64
  74. package/dist/spa/spa/src/stores/core.ts +0 -144
  75. package/dist/spa/spa/src/stores/modal.ts +0 -48
  76. package/dist/spa/spa/src/utils.ts +0 -101
  77. package/dist/spa/spa/src/views/CreateView.vue +0 -163
  78. package/dist/spa/spa/src/views/EditView.vue +0 -165
  79. package/dist/spa/spa/src/views/ListView.vue +0 -257
  80. package/dist/spa/spa/src/views/LoginView.vue +0 -134
  81. package/dist/spa/spa/src/views/ResourceParent.vue +0 -18
  82. package/dist/spa/spa/src/views/ShowView.vue +0 -188
  83. package/dist/spa/spa/tailwind.config.js +0 -15
  84. package/dist/spa/spa/tsconfig.app.json +0 -14
  85. package/dist/spa/spa/tsconfig.json +0 -11
  86. package/dist/spa/spa/tsconfig.node.json +0 -19
  87. package/dist/spa/spa/vite.config.ts +0 -49
  88. package/dist/types.js +0 -30
  89. /package/dist/spa/{spa/public → public/assets}/favicon.png +0 -0
  90. /package/dist/spa/{spa/src → src}/components/ResourceListTable.vue +0 -0
  91. /package/dist/spa/{spa/src → src}/components/Toast.vue +0 -0
  92. /package/dist/spa/{spa/src → src}/composables/useFrontendApi.ts +0 -0
  93. /package/dist/spa/{spa/src → src}/composables/useStores.ts +0 -0
  94. /package/dist/spa/{spa/src → src}/spa_types/core.ts +0 -0
  95. /package/dist/spa/{spa/src → src}/stores/filters.ts +0 -0
  96. /package/dist/spa/{spa/src → src}/stores/toast.ts +0 -0
  97. /package/dist/spa/{spa/src → src}/stores/user.ts +0 -0
  98. /package/spa/public/{favicon.png → assets/favicon.png} +0 -0
@@ -1,21 +1,38 @@
1
1
  <template>
2
2
  <div class="relative">
3
+ <component
4
+ v-for="c in coreStore?.resourceOptions?.pageInjections?.show?.beforeBreadcrumbs || []"
5
+ :is="getCustomComponent(c)"
6
+ :meta="c.meta"
7
+ :record="coreStore.record"
8
+ :resource="coreStore.resource"
9
+ :adminUser="coreStore.adminUser"
10
+ />
3
11
  <BreadcrumbsWithButtons>
4
- <RouterLink :to="{ name: 'resource-edit', params: { resourceId: $route.params.resourceId, primaryKey: $route.params.primaryKey } }"
5
- class="flex items-center py-1 px-3 me-2 mb-2 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded border border-gray-300 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700"
12
+ <RouterLink v-if="coreStore?.resourceOptions?.allowedActions?.edit" :to="{ name: 'resource-edit', params: { resourceId: $route.params.resourceId, primaryKey: $route.params.primaryKey } }"
13
+ class="flex items-center py-1 px-3 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-default border border-gray-300 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700"
6
14
  >
7
15
  <IconPenSolid class="w-4 h-4" />
8
16
  Edit
9
17
  </RouterLink>
10
18
 
11
- <button @click="deleteRecord"
12
- class="flex items-center py-1 px-3 mb-2 text-sm font-medium text-red-600 focus:outline-none bg-white rounded border border-gray-300 hover:bg-gray-100 hover:text-red-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-red-500 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700"
19
+ <button v-if="coreStore?.resourceOptions?.allowedActions?.delete" @click="deleteRecord"
20
+ class="flex items-center py-1 px-3 text-sm font-medium rounded-default text-red-600 focus:outline-none bg-white border border-gray-300 hover:bg-gray-100 hover:text-red-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-red-500 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700"
13
21
  >
14
22
  <IconTrashBinSolid class="w-4 h-4" />
15
23
  Delete
16
24
  </button>
17
25
  </BreadcrumbsWithButtons>
18
26
 
27
+ <component
28
+ v-for="c in coreStore?.resourceOptions?.pageInjections?.show?.afterBreadcrumbs || []"
29
+ :is="getCustomComponent(c)"
30
+ :meta="c.meta"
31
+ :record="coreStore.record"
32
+ :resource="coreStore.resource"
33
+ :adminUser="coreStore.adminUser"
34
+ />
35
+
19
36
  <div v-if="loading" role="status" class="max-w-sm animate-pulse">
20
37
  <div class="h-2.5 bg-gray-200 rounded-full dark:bg-gray-700 w-48 mb-4"></div>
21
38
  <div class="h-2 bg-gray-200 rounded-full dark:bg-gray-700 max-w-[360px] mb-2.5"></div>
@@ -29,7 +46,7 @@
29
46
  v-else
30
47
  class="relative overflow-x-auto shadow-resourse-form-shadow "
31
48
  >
32
- <table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
49
+ <table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400 rounded-default">
33
50
  <thead class="text-xs text-gray-700 uppercase bg-form-view-heading dark:bg-gray-700 dark:text-gray-400">
34
51
  <tr>
35
52
  <th scope="col" class="px-6 py-3">
@@ -41,23 +58,49 @@
41
58
  </tr>
42
59
  </thead>
43
60
  <tbody>
44
- <tr v-for="column in coreStore.resourceColumns?.filter(c => c.showIn.includes('show'))" :key="column.name"
61
+ <tr v-for="column in coreStore.resource?.columns.filter(c => c.showIn.includes('show'))" :key="column.name"
45
62
  class="bg-form-view-bg odd:dark:bg-gray-900 even:dark:bg-gray-800 border-b dark:border-gray-700"
46
63
  >
47
- <td class="px-6 py-4 whitespace-nowrap">
48
- {{ column.label }}
64
+ <component
65
+ v-if="column.components?.showRow"
66
+ :is="getCustomComponent(column.components.showRow)"
67
+ :meta="column.components.showRow.meta"
68
+ :column="column"
69
+ :resource="coreStore.resource"
70
+ :record="coreStore.record"
71
+ />
72
+ <template v-else>
73
+ <td class="px-6 py-4 whitespace-nowrap "> <!--align-top-->
74
+ {{ column.label }}
49
75
  </td>
50
76
  <td class="px-6 py-4 whitespace-nowrap whitespace-pre-wrap">
51
- <component
52
- :is="showComponentsPerColumn[column.name] || ValueRenderer"
53
- :column="column"
54
- :row="coreStore.record"
55
- />
77
+ <component
78
+ v-if="showComponentsPerColumn[column.name]"
79
+ :is="showComponentsPerColumn[column.name]"
80
+ :resource="coreStore.resource"
81
+ :meta="column.components.show.meta"
82
+ :column="column"
83
+ :record="coreStore.record"
84
+ />
85
+ <ValueRenderer v-else
86
+ :column="column"
87
+ :record="coreStore.record"
88
+ />
56
89
  </td>
90
+ </template>
57
91
  </tr>
58
-
59
92
  </tbody>
60
93
  </table>
94
+
95
+ <component
96
+ v-for="c in coreStore?.resourceOptions?.pageInjections?.show?.bottom || []"
97
+ :is="getCustomComponent(c)"
98
+ :meta="c.meta"
99
+ :column="column"
100
+ :record="coreStore.record"
101
+ :resource="coreStore.resource"
102
+ :adminUser="coreStore.adminUser"
103
+ />
61
104
  </div>
62
105
 
63
106
 
@@ -68,37 +111,78 @@
68
111
  <script setup>
69
112
 
70
113
  import BreadcrumbsWithButtons from '@/components/BreadcrumbsWithButtons.vue';
114
+
71
115
  import ValueRenderer from '@/components/ValueRenderer.vue';
72
116
  import { useCoreStore } from '@/stores/core';
73
- import { getCustomComponent } from '@/utils';
117
+ import { useModalStore } from '@/stores/modal';
118
+ import { getCustomComponent, checkAcessByAllowedActions } from '@/utils';
74
119
  import { IconPenSolid, IconTrashBinSolid } from '@iconify-prerendered/vue-flowbite';
75
120
  import { onMounted, ref } from 'vue';
76
- import { useRoute } from 'vue-router';
121
+ import { useRoute,useRouter } from 'vue-router';
122
+ import {callAdminForthApi} from '@/utils';
123
+ import {showSuccesTost} from '@/composables/useFrontendApi';
77
124
 
78
125
 
79
126
  const item = ref(null);
80
127
  const route = useRoute();
128
+ const router = useRouter();
81
129
  const loading = ref(false);
82
130
  let showComponentsPerColumn = {};
83
131
 
132
+ console.log(route.params,'showWiev');
133
+
134
+
84
135
  const coreStore = useCoreStore();
136
+ const modalStore = useModalStore();
85
137
 
86
138
  onMounted(async () => {
87
139
  loading.value = true;
88
- await coreStore.fetchColumns({
140
+ await coreStore.fetchResourceFull({
89
141
  resourceId: route.params.resourceId
90
142
  });
91
143
  await coreStore.fetchRecord({
92
144
  resourceId: route.params.resourceId,
93
145
  primaryKey: route.params.primaryKey,
94
146
  });
95
- showComponentsPerColumn = coreStore.resourceColumns.reduce((acc, column) => {
96
- if (column.component?.show) {
97
- acc[column.name] = getCustomComponent(column.component.show);
147
+ checkAcessByAllowedActions(coreStore.resourceOptions.allowedActions,'show');
148
+
149
+ showComponentsPerColumn = coreStore.resource.columns.reduce((acc, column) => {
150
+ if (column.components?.show) {
151
+ acc[column.name] = getCustomComponent(column.components.show);
98
152
  }
99
153
  return acc;
100
- }, {});
154
+ }, {});
101
155
  loading.value = false;
102
156
  });
103
157
 
158
+ async function deleteRecord(row) {
159
+ const data = await window.adminforth.confirm({
160
+ message: 'Are you sure you want to delete this item?',
161
+ yes: 'Delete',
162
+ no: 'Cancel',
163
+ });
164
+ if (data) {
165
+ try {
166
+ const res = await callAdminForthApi({
167
+ path: '/delete_record',
168
+ method: 'POST',
169
+ body: {
170
+ resourceId: route.params.resourceId,
171
+ primaryKey: route.params.primaryKey,
172
+ }});
173
+ if (!res.error){
174
+ router.push({ name: 'resource-list', params: { resourceId: route.params.resourceId } });
175
+ showSuccesTost('Record deleted successfully')
176
+ } else {
177
+ console.error(res.error)
178
+ }
179
+
180
+ } catch (e) {
181
+ console.error(e);
182
+ };
183
+ }
184
+
185
+
186
+ }
187
+
104
188
  </script>
@@ -1,6 +1,6 @@
1
1
  /** @type {import('tailwindcss').Config} */
2
2
  export default {
3
- content: ["./src/**/*.{vue, js}","./src/*.{vue, js}", "./index.html", "./node_modules/flowbite/**/*.js"],
3
+ content: ["./src/**/*.{vue, js, ts, tsx}","./src/*.{vue, js, ts, tsx}", "./index.html", "./node_modules/flowbite/**/*.js"],
4
4
  theme: {
5
5
  extend: {
6
6
  /* IMPORTANT:ADMINFORTH TAILWIND STYLES */
@@ -11,6 +11,12 @@ const customLogger = {
11
11
  console.log(msg);
12
12
  }
13
13
  },
14
+ warnOnce(msg: string) {
15
+ console.warn('warn once', msg);
16
+ if (!this.hasWarned) {
17
+ this.hasWarned = true;
18
+ }
19
+ },
14
20
  warn(msg: string) {
15
21
  console.warn(msg);
16
22
  },
package/index.ts CHANGED
@@ -49,6 +49,8 @@ class AdminForth implements AdminForthClass {
49
49
  runningHotReload: boolean;
50
50
  activatedPlugins: Array<AdminForthPlugin>;
51
51
 
52
+ baseUrlSlashed: string;
53
+
52
54
  statuses: {
53
55
  dbDiscover?: 'running' | 'done',
54
56
  }
@@ -159,6 +161,11 @@ class AdminForth implements AdminForthClass {
159
161
  if (!this.config.baseUrl) {
160
162
  this.config.baseUrl = '';
161
163
  }
164
+ if (!this.config.baseUrl.endsWith('/')) {
165
+ this.baseUrlSlashed = this.config.baseUrl + '/';
166
+ } else {
167
+ this.baseUrlSlashed = this.config.baseUrl;
168
+ }
162
169
  if (!this.config?.customization.brandName) {
163
170
  this.config.customization.brandName = 'AdminForth';
164
171
  }
@@ -166,6 +173,10 @@ class AdminForth implements AdminForthClass {
166
173
  errors.push(...this.checkCustomFileExists(this.config.customization.brandLogo));
167
174
  }
168
175
 
176
+ if (!this.config.customization.favicon) {
177
+ errors.push(...this.checkCustomFileExists(this.config.customization.favicon));
178
+ }
179
+
169
180
  if (!this.config.customization.datesFormat) {
170
181
  this.config.customization.datesFormat = 'MMM D, YYYY HH:mm:ss';
171
182
  }
@@ -209,6 +209,18 @@ class CodeInjector implements CodeInjectorType {
209
209
  this.srcFoldersToSync[this.adminforth.config.customization.customComponentsDir] = './'
210
210
  }
211
211
 
212
+ // if this.adminforth.config.customization.favicon is set, copy it to assets
213
+ const customFav = this.adminforth.config.customization?.favicon;
214
+ if (customFav) {
215
+
216
+ const faviconPath = path.join(this.adminforth.config.customization?.customComponentsDir, customFav.replace('@@/', ''));
217
+ const dest = path.join(CodeInjector.SPA_TMP_PATH, 'public', 'assets', customFav.replace('@@/', ''));
218
+ // make sure all folders in dest exist
219
+ await fsExtra.ensureDir(path.dirname(dest));
220
+
221
+ await fsExtra.copy(faviconPath, dest);
222
+ }
223
+
212
224
  for (const [src, dest] of Object.entries(this.srcFoldersToSync)) {
213
225
  const to = path.join(CodeInjector.SPA_TMP_PATH, 'src', 'custom', dest);
214
226
  if (process.env.HEAVY_DEBUG) {
@@ -343,7 +355,6 @@ class CodeInjector implements CodeInjectorType {
343
355
  await fs.promises.writeFile(tailwindConfigPath, tailwindConfigContent);
344
356
  }
345
357
 
346
-
347
358
  const routerVuePath = path.join(CodeInjector.SPA_TMP_PATH, 'src', 'router', 'index.ts');
348
359
 
349
360
  let routerVueContent = await fs.promises.readFile(routerVuePath, 'utf-8');
@@ -353,6 +364,13 @@ class CodeInjector implements CodeInjectorType {
353
364
  const indexHtmlPath = path.join(CodeInjector.SPA_TMP_PATH, 'index.html');
354
365
  let indexHtmlContent = await fs.promises.readFile(indexHtmlPath, 'utf-8');
355
366
  indexHtmlContent = indexHtmlContent.replace('/* IMPORTANT:ADMINFORTH TITLE */', `${this.adminforth.config.customization.title || 'AdminForth'}`);
367
+
368
+ indexHtmlContent = indexHtmlContent.replace(
369
+ '/* IMPORTANT:ADMINFORTH FAVICON */',
370
+ this.adminforth.config.customization.favicon?.replace('@@/', `${this.adminforth.baseUrlSlashed}assets/`)
371
+ ||
372
+ `${this.adminforth.baseUrlSlashed}assets/favicon.png`
373
+ );
356
374
  await fs.promises.writeFile(indexHtmlPath, indexHtmlContent);
357
375
 
358
376
 
package/modules/styles.ts CHANGED
@@ -27,10 +27,10 @@ export const styles = () => `
27
27
 
28
28
  "list-view-bg": "#FFFFFF", // White background
29
29
  "list-view-table-bg": "#FFFFFF", // White table background
30
- "list-view-table-heading": "#F5F5F5", // Very light grey heading
30
+ "list-view-table-heading": "rgb(249 250 251)", // Very light grey heading
31
31
  "list-view-table-heading-text": "#333333", // Dark grey heading text
32
32
  "list-view-table-text": "#333333", // Dark grey text
33
- "list-view-table-row-hover": "#F0F0F0", // Very light grey row hover
33
+ "list-view-table-row-hover": "rgb(249 250 251)", // Very light grey row hover
34
34
  "list-view-bread-crumbs-text": "#666666", // Medium grey bread crumbs
35
35
  "list-view-border-color": "#DDDDDD", // Light grey border
36
36
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adminforth",
3
- "version": "1.1.32",
3
+ "version": "1.1.33",
4
4
  "description": "OpenSource Vue3 powered forth-generation admin panel",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/spa/index.html CHANGED
@@ -2,7 +2,7 @@
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
- <link rel="icon" href="/favicon.png">
5
+ <link rel="icon" href="/* IMPORTANT:ADMINFORTH FAVICON */">
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
7
  <title>/* IMPORTANT:ADMINFORTH TITLE */</title>
8
8
  <!--
package/spa/src/App.vue CHANGED
@@ -59,11 +59,11 @@
59
59
 
60
60
  v-if="loggedIn && routerIsReady && loginRedirectCheckIsReady"
61
61
 
62
- id="logo-sidebar" class="fixed border-none top-0 left-0 z-20 w-64 h-screen transition-transform bg-nav-menu-bg border-r border-nav-menu-border sm:translate-x-0 dark:bg-gray-800 dark:border-gray-700"
62
+ id="logo-sidebar" class="fixed border-none top-0 left-0 z-20 w-64 h-screen transition-transform border-r border-nav-menu-border sm:translate-x-0 dark:bg-gray-800 dark:border-gray-700"
63
63
  :class="{ '-translate-x-full': !sideBarOpen, 'transform-none': sideBarOpen }"
64
64
  aria-label="Sidebar"
65
65
  >
66
- <div class="h-full px-3 pb-4 overflow-y-auto bg-nav-menu-bg dark:bg-gray-800 border-r">
66
+ <div class="h-full px-3 pb-4 overflow-y-auto bg-white dark:bg-gray-800 border-r">
67
67
  <div class="flex ms-2 md:me-24 m-4 ">
68
68
  <img :src="loadFile(coreStore.config?.brandLogo || '@/assets/logo.svg')" :alt="`${ coreStore.config?.brandName } Logo`" class="h-8 me-3" />
69
69
  <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">
@@ -242,7 +242,6 @@ async function loadMenu() {
242
242
 
243
243
  coreStore.menu.forEach((item, i) => {
244
244
  if (item.open) {
245
- console.log(item)
246
245
  opened.value.push(i);
247
246
  }
248
247
  });
@@ -742,6 +742,21 @@ export type AdminForthConfig = {
742
742
  */
743
743
  brandLogo?: string,
744
744
 
745
+ /**
746
+ * Path to your app favicon
747
+ *
748
+ * Example:
749
+ * Place file `favicon.png` to `./custom` folder and set this option:
750
+ *
751
+ * ```ts
752
+ * favicon: '@@/favicon.png',
753
+ * ```
754
+ */
755
+ favicon?: string,
756
+
757
+ /**
758
+ favicon?: string,
759
+
745
760
  /**
746
761
  * DayJS format string for all dates in the app
747
762
  */
@@ -1,66 +0,0 @@
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";
11
- import AdminForthPlugin from "../base.js";
12
- class AccessControlPlugin extends AdminForthPlugin {
13
- constructor(options) {
14
- super(options, import.meta.url);
15
- this.options = options;
16
- }
17
- modifyResourceConfig(adminforth, resourceConfig) {
18
- super.modifyResourceConfig(adminforth, resourceConfig);
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);
63
- }
64
- }
65
- AccessControlPlugin.defaultError = 'Sorry, you do not have access to this resource.';
66
- export default AccessControlPlugin;
@@ -1 +0,0 @@
1
- export {};
Binary file
@@ -1,14 +0,0 @@
1
- /* eslint-env node */
2
- require('@rushstack/eslint-patch/modern-module-resolution')
3
-
4
- module.exports = {
5
- root: true,
6
- 'extends': [
7
- 'plugin:vue/vue3-essential',
8
- 'eslint:recommended',
9
- '@vue/eslint-config-typescript'
10
- ],
11
- parserOptions: {
12
- ecmaVersion: 'latest'
13
- }
14
- }
@@ -1,6 +0,0 @@
1
- {
2
- "recommendations": [
3
- "Vue.volar",
4
- "dbaeumer.vscode-eslint"
5
- ]
6
- }
@@ -1,39 +0,0 @@
1
- # spa
2
-
3
- This template should help get you started developing with Vue 3 in Vite.
4
-
5
- ## Recommended IDE Setup
6
-
7
- [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
8
-
9
- ## Type Support for `.vue` Imports in TS
10
-
11
- TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types.
12
-
13
- ## Customize configuration
14
-
15
- See [Vite Configuration Reference](https://vitejs.dev/config/).
16
-
17
- ## Project Setup
18
-
19
- ```sh
20
- npm install
21
- ```
22
-
23
- ### Compile and Hot-Reload for Development
24
-
25
- ```sh
26
- npm run dev
27
- ```
28
-
29
- ### Type-Check, Compile and Minify for Production
30
-
31
- ```sh
32
- npm run build
33
- ```
34
-
35
- ### Lint with [ESLint](https://eslint.org/)
36
-
37
- ```sh
38
- npm run lint
39
- ```
@@ -1 +0,0 @@
1
- /// <reference types="vite/client" />
@@ -1,23 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <link rel="icon" href="/favicon.png">
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <title>/* IMPORTANT:ADMINFORTH TITLE */</title>
8
- <!--
9
- <script>
10
- // On page load or when changing themes, best to add inline in `head` to avoid FOUC
11
- if (localStorage.getItem('color-theme') === 'dark' || (!('color-theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
12
- document.documentElement.classList.add('dark');
13
- } else {
14
- document.documentElement.classList.remove('dark')
15
- }
16
- </script> -->
17
-
18
- </head>
19
- <body class=" ">
20
- <div id="app" class="min-h-screen bg-html-bg dark:bg-gray-800"></div>
21
- <script type="module" src="/src/main.ts"></script>
22
- </body>
23
- </html>