adminforth 1.0.51 → 1.0.52
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/modules/codeInjector.js +12 -3
- package/dist/spa/spa/index.html +2 -2
- package/dist/spa/spa/package-lock.json +18 -0
- package/dist/spa/spa/package.json +1 -0
- package/dist/spa/spa/src/App.vue +53 -51
- package/dist/spa/spa/src/components/Dropdown.vue +2 -1
- package/dist/spa/spa/src/components/MenuLink.vue +2 -2
- package/dist/spa/spa/src/components/ResourceForm.vue +3 -3
- package/dist/spa/spa/src/views/ListView.vue +5 -5
- package/dist/spa/spa/src/views/ShowView.vue +3 -3
- package/dist/spa/spa/tailwind.config.js +5 -2
- package/index.ts +5 -0
- package/modules/codeInjector.ts +11 -0
- package/package.json +1 -1
- package/spa/index.html +2 -2
- package/spa/package-lock.json +18 -0
- package/spa/package.json +1 -0
- package/spa/src/App.vue +53 -51
- package/spa/src/components/Dropdown.vue +2 -1
- package/spa/src/components/MenuLink.vue +2 -2
- package/spa/src/components/ResourceForm.vue +3 -3
- package/spa/src/views/ListView.vue +5 -5
- package/spa/src/views/ShowView.vue +3 -3
- package/spa/tailwind.config.js +5 -2
- package/types/AdminForthConfig.ts +2 -0
|
@@ -72,7 +72,7 @@ class CodeInjector {
|
|
|
72
72
|
}
|
|
73
73
|
prepareSources(_a) {
|
|
74
74
|
return __awaiter(this, arguments, void 0, function* ({ filesUpdated, verbose = false }) {
|
|
75
|
-
var _b, _c, _d, _e, _f, _g, _h;
|
|
75
|
+
var _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
76
76
|
// check SPA_TMP_PATH exists and create if not
|
|
77
77
|
try {
|
|
78
78
|
yield fs.promises.access(CodeInjector.SPA_TMP_PATH, fs.constants.F_OK);
|
|
@@ -213,13 +213,22 @@ class CodeInjector {
|
|
|
213
213
|
appVueContent = appVueContent.replace('/* IMPORTANT:ADMINFORTH CUSTOM USES */', 'addCustomUses(app);');
|
|
214
214
|
}
|
|
215
215
|
yield fs.promises.writeFile(appVuePath, appVueContent);
|
|
216
|
+
// generate tailwind extend styles
|
|
217
|
+
if ((_f = this.adminforth.config) === null || _f === void 0 ? void 0 : _f.styles) {
|
|
218
|
+
const tailwindStyles = (_g = this.adminforth.config) === null || _g === void 0 ? void 0 : _g.styles;
|
|
219
|
+
const stylesText = JSON.stringify(tailwindStyles, null, 2).slice(1, -1);
|
|
220
|
+
let tailwindConfigPath = path.join(CodeInjector.SPA_TMP_PATH, 'tailwind.config.js');
|
|
221
|
+
let tailwindConfigContent = yield fs.promises.readFile(tailwindConfigPath, 'utf-8');
|
|
222
|
+
tailwindConfigContent = tailwindConfigContent.replace('/* IMPORTANT:ADMINFORTH TAILWIND STYLES */', stylesText);
|
|
223
|
+
yield fs.promises.writeFile(tailwindConfigPath, tailwindConfigContent);
|
|
224
|
+
}
|
|
216
225
|
/* generate custom rotes */
|
|
217
226
|
const homepageMenuItem = this.adminforth.config.menu.find((mi) => mi.homepage);
|
|
218
227
|
let childrenHomePageMenuItem = this.adminforth.config.menu.find((mi) => { var _a; return mi.children && ((_a = mi.children) === null || _a === void 0 ? void 0 : _a.find((mi) => mi.homepage)); });
|
|
219
|
-
let childrenHomepage = (
|
|
228
|
+
let childrenHomepage = (_h = childrenHomePageMenuItem === null || childrenHomePageMenuItem === void 0 ? void 0 : childrenHomePageMenuItem.children) === null || _h === void 0 ? void 0 : _h.find((mi) => mi.homepage);
|
|
220
229
|
let homePagePath = (homepageMenuItem === null || homepageMenuItem === void 0 ? void 0 : homepageMenuItem.path) || `/resource/${childrenHomepage === null || childrenHomepage === void 0 ? void 0 : childrenHomepage.resourceId}`;
|
|
221
230
|
if (!homePagePath) {
|
|
222
|
-
homePagePath = ((
|
|
231
|
+
homePagePath = ((_j = this.adminforth.config.menu.filter((mi) => mi.path)[0]) === null || _j === void 0 ? void 0 : _j.path) || `/resource/${(_k = this.adminforth.config.menu.filter((mi) => mi.children)[0]) === null || _k === void 0 ? void 0 : _k.resourceId}`;
|
|
223
232
|
}
|
|
224
233
|
routes += `{
|
|
225
234
|
path: '/',
|
package/dist/spa/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,6 +9,7 @@
|
|
|
9
9
|
"version": "0.0.0",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@iconify-prerendered/vue-flowbite": "^0.23.1714023977",
|
|
12
|
+
"@unhead/vue": "^1.9.12",
|
|
12
13
|
"@vueuse/core": "^10.10.0",
|
|
13
14
|
"dayjs": "^1.11.11",
|
|
14
15
|
"debounce": "^2.1.0",
|
|
@@ -1185,6 +1186,23 @@
|
|
|
1185
1186
|
"url": "https://github.com/sponsors/harlan-zw"
|
|
1186
1187
|
}
|
|
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
|
+
},
|
|
1188
1206
|
"node_modules/@vitejs/plugin-vue": {
|
|
1189
1207
|
"version": "5.0.4",
|
|
1190
1208
|
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz",
|
package/dist/spa/spa/src/App.vue
CHANGED
|
@@ -1,89 +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
|
-
<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">
|
|
47
|
-
{{ theme === 'dark' ? 'Light' : 'Dark' }}
|
|
48
|
-
<IconMoonSolid class="w-5 h-5 text-blue-300
|
|
49
|
-
" v-if="theme !== 'dark'"/>
|
|
50
|
-
<IconSunSolid class="w-5 h-5 text-yellow-300
|
|
51
|
-
" v-else/>
|
|
52
|
-
mode
|
|
53
|
-
</span>
|
|
54
|
-
</li>
|
|
55
|
-
|
|
56
|
-
<li>
|
|
57
|
-
<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>
|
|
58
43
|
</li>
|
|
59
|
-
|
|
60
|
-
|
|
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>
|
|
61
48
|
</div>
|
|
62
49
|
</div>
|
|
50
|
+
</div>
|
|
63
51
|
</div>
|
|
64
52
|
</div>
|
|
65
|
-
|
|
53
|
+
</nav>
|
|
54
|
+
|
|
66
55
|
|
|
67
56
|
|
|
68
57
|
<aside
|
|
69
58
|
v-if="loggedIn"
|
|
70
59
|
|
|
71
|
-
id="logo-sidebar" class="fixed top-0 left-0 z-
|
|
72
|
-
<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-xl font-semibold sm:text-2xl whitespace-nowrap dark:text-header-text text-header-logo-color">
|
|
65
|
+
{{ coreStore.config?.brandName }}
|
|
66
|
+
</span>
|
|
67
|
+
</div>
|
|
73
68
|
<ul class="space-y-2 font-medium">
|
|
74
69
|
<template v-for="(item, i) in coreStore.menu" :key="`menu-${i}`">
|
|
75
|
-
<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>
|
|
76
71
|
<div v-else-if="item.type === 'gap'" class="flex items-center justify-center h-8"></div>
|
|
77
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
|
|
78
73
|
">{{ item.label }}</div>
|
|
79
74
|
|
|
80
75
|
|
|
81
76
|
<li v-else-if="item.children">
|
|
82
|
-
<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 transition duration-75 group hover:bg-nav-menu-bg-hover dark:text-white dark:hover:bg-gray-700"
|
|
83
78
|
:aria-controls="`dropdown-example${i}`"
|
|
84
79
|
:data-collapse-toggle="`dropdown-example${i}`"
|
|
85
80
|
>
|
|
86
|
-
<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>
|
|
87
82
|
|
|
88
83
|
<span class="flex-1 ms-3 text-left rtl:text-right whitespace-nowrap">{{ item.label }}</span>
|
|
89
84
|
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6">
|
|
@@ -135,6 +130,7 @@ import { useRoute, useRouter } from 'vue-router';
|
|
|
135
130
|
import { getIcon } from '@/utils';
|
|
136
131
|
import { useHead } from 'unhead'
|
|
137
132
|
import { createHead } from 'unhead'
|
|
133
|
+
// import { link } from 'fs';
|
|
138
134
|
const coreStore = useCoreStore();
|
|
139
135
|
|
|
140
136
|
|
|
@@ -182,6 +178,12 @@ onMounted(async () => {
|
|
|
182
178
|
title.value = coreStore.config.title || 'Admin Forth';
|
|
183
179
|
useHead({
|
|
184
180
|
title: title.value,
|
|
181
|
+
link: [
|
|
182
|
+
{
|
|
183
|
+
rel: 'icon',
|
|
184
|
+
href: coreStore.config.favicon || '/favicon.ico',
|
|
185
|
+
},
|
|
186
|
+
],
|
|
185
187
|
|
|
186
188
|
})
|
|
187
189
|
})
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
:placeholder="selectedItems.length ? '' : 'Select...'"
|
|
10
10
|
/>
|
|
11
11
|
<div class="absolute inset-y-0 left-2 flex items-center pr-2 flex-wrap">
|
|
12
|
-
|
|
12
|
+
{{ }}
|
|
13
|
+
<div v-for="item in selectedItems" :key="item?.name" class="bg-blue-100 text-blue-800 text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-blue-900 dark:text-blue-300">
|
|
13
14
|
<span>{{ item.label }}</span>
|
|
14
15
|
<button
|
|
15
16
|
type="button"
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<RouterLink
|
|
3
3
|
:to="{name: item.resourceId ? 'resource-list' : item.path, params: item.resourceId ? { resourceId: item.resourceId }: {}}"
|
|
4
|
-
class="flex items-center py-2 text-
|
|
4
|
+
class="flex items-center py-2 text-nav-menu-text hover:bg-nav-menu-bg-hover active:bg-nav-menu-bg-active" role="menuitem"
|
|
5
5
|
:class="{
|
|
6
6
|
'px-4': isChild,
|
|
7
7
|
'px-2': !isChild,
|
|
8
|
-
'bg-
|
|
8
|
+
'bg-nav-menu-bg-active dark:bg-gray-700': item.resourceId ?
|
|
9
9
|
($route.params.resourceId === item.resourceId && $route.name === 'resource-list') :
|
|
10
10
|
($route.name === item.path)
|
|
11
11
|
}"
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
<div>
|
|
3
3
|
|
|
4
4
|
<div
|
|
5
|
-
class="relative shadow-
|
|
5
|
+
class="relative shadow-resourse-form-shadow sm:rounded-lg dark:shadow-2xl dark:shadow-black"
|
|
6
6
|
>
|
|
7
7
|
<form autocomplete="off" @submit.prevent>
|
|
8
8
|
<table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
|
|
9
|
-
<thead class="text-xs text-gray-700 uppercase bg-
|
|
9
|
+
<thead class="text-xs text-gray-700 uppercase bg-form-view-heading dark:bg-gray-700 dark:text-gray-400">
|
|
10
10
|
<tr>
|
|
11
11
|
<th scope="col" class="px-6 py-3">
|
|
12
12
|
Field
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
</thead>
|
|
19
19
|
<tbody>
|
|
20
20
|
<tr v-for="column, i in editableColumns" :key="column.name"
|
|
21
|
-
class="
|
|
21
|
+
class="bg-form-view-bg dark:bg-gray-800 border-b dark:border-gray-700"
|
|
22
22
|
>
|
|
23
23
|
<!-- if column is in customComponentsPerColumn, use this component. If not, use this code -->
|
|
24
24
|
<template v-if="customComponentsPerColumn[column.name]">
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
</BreadcrumbsWithButtons>
|
|
66
66
|
|
|
67
67
|
<!-- table -->
|
|
68
|
-
<div class="relative overflow-x-auto shadow-
|
|
68
|
+
<div class="relative overflow-x-auto shadow-list-table-shadow dark:shadow-black dark:s">
|
|
69
69
|
|
|
70
70
|
|
|
71
71
|
<!-- skelet loader -->
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
</div>
|
|
91
91
|
|
|
92
92
|
<table v-else class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
|
|
93
|
-
<thead class="text-xs text-
|
|
93
|
+
<thead class="text-xs text-view-table-heading-text bg-list-view-table-heading dark:bg-gray-700 dark:text-gray-400">
|
|
94
94
|
<tr>
|
|
95
95
|
<th scope="col" class="p-4">
|
|
96
96
|
<div v-if="rows && rows.length" class="flex items-center">
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
</tr>
|
|
128
128
|
</thead>
|
|
129
129
|
<tbody>
|
|
130
|
-
<tr v-if="!rows" class="bg-
|
|
130
|
+
<tr v-if="!rows" class="bg-list-view-table-bg border-b dark:bg-gray-800 dark:border-gray-700">
|
|
131
131
|
<td :colspan="coreStore.resourceColumns.length + 2">
|
|
132
132
|
|
|
133
133
|
<div role="status"
|
|
@@ -171,7 +171,7 @@
|
|
|
171
171
|
</div>
|
|
172
172
|
</td>
|
|
173
173
|
</tr>
|
|
174
|
-
<tr v-else-if="rows.length === 0" class="bg-
|
|
174
|
+
<tr v-else-if="rows.length === 0" class="bg-list-view-table-bg border-b dark:bg-gray-800 dark:border-gray-700">
|
|
175
175
|
<td :colspan="coreStore.resourceColumns.length + 2">
|
|
176
176
|
|
|
177
177
|
<div id="toast-simple"
|
|
@@ -185,7 +185,7 @@
|
|
|
185
185
|
</tr>
|
|
186
186
|
|
|
187
187
|
<tr v-else v-for="(row, rowI) in rows" :key="row.id"
|
|
188
|
-
class="bg-
|
|
188
|
+
class="bg-list-view-table-bg border-b dark:bg-gray-800 border-list-view-border-color dark:border-gray-700 hover:bg-list-view-table-row-hover dark:hover:bg-gray-600">
|
|
189
189
|
<td class="w-4 p-4">
|
|
190
190
|
<div class="flex items center">
|
|
191
191
|
<input
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
</div>
|
|
28
28
|
<div
|
|
29
29
|
v-else
|
|
30
|
-
class="relative overflow-x-auto shadow-
|
|
30
|
+
class="relative overflow-x-auto shadow-resourse-form-shadow "
|
|
31
31
|
>
|
|
32
32
|
<table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
|
|
33
|
-
<thead class="text-xs text-gray-700 uppercase bg-
|
|
33
|
+
<thead class="text-xs text-gray-700 uppercase bg-form-view-heading dark:bg-gray-700 dark:text-gray-400">
|
|
34
34
|
<tr>
|
|
35
35
|
<th scope="col" class="px-6 py-3">
|
|
36
36
|
Field
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
</thead>
|
|
43
43
|
<tbody>
|
|
44
44
|
<tr v-for="column in coreStore.resourceColumns?.filter(c => c.showIn.includes('show'))" :key="column.name"
|
|
45
|
-
class="
|
|
45
|
+
class="bg-form-view-bg odd:dark:bg-gray-900 even:dark:bg-gray-800 border-b dark:border-gray-700"
|
|
46
46
|
>
|
|
47
47
|
<td class="px-6 py-4 whitespace-nowrap">
|
|
48
48
|
{{ column.label }}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
/** @type {import('tailwindcss').Config} */
|
|
2
2
|
export default {
|
|
3
|
-
content: ["./src/**/*.{vue, js}", "./node_modules/flowbite/**/*.js"],
|
|
3
|
+
content: ["./src/**/*.{vue, js}","./src/*.{vue, js}", "./index.html", "./node_modules/flowbite/**/*.js"],
|
|
4
4
|
theme: {
|
|
5
|
-
extend: {
|
|
5
|
+
extend: {
|
|
6
|
+
/* IMPORTANT:ADMINFORTH TAILWIND STYLES */
|
|
7
|
+
}
|
|
6
8
|
},
|
|
9
|
+
|
|
7
10
|
darkMode: 'class',
|
|
8
11
|
plugins: [
|
|
9
12
|
require('flowbite/plugin'),
|
package/index.ts
CHANGED
|
@@ -16,6 +16,11 @@ const AVAILABLE_SHOW_IN = ['list', 'edit', 'create', 'filter', 'show'];
|
|
|
16
16
|
const DEFAULT_ALLOWED_ACTIONS = {create: true, edit: true, show: true, delete: true};
|
|
17
17
|
|
|
18
18
|
|
|
19
|
+
type ValidationObject = {
|
|
20
|
+
regex: string,
|
|
21
|
+
message: string,
|
|
22
|
+
}
|
|
23
|
+
|
|
19
24
|
class AdminForth {
|
|
20
25
|
static Types = AdminForthTypes;
|
|
21
26
|
|
package/modules/codeInjector.ts
CHANGED
|
@@ -239,6 +239,17 @@ class CodeInjector {
|
|
|
239
239
|
}
|
|
240
240
|
await fs.promises.writeFile(appVuePath, appVueContent);
|
|
241
241
|
|
|
242
|
+
// generate tailwind extend styles
|
|
243
|
+
if(this.adminforth.config?.styles){
|
|
244
|
+
const tailwindStyles = this.adminforth.config?.styles
|
|
245
|
+
const stylesText = JSON.stringify(tailwindStyles, null, 2).slice(1, -1);
|
|
246
|
+
let tailwindConfigPath = path.join(CodeInjector.SPA_TMP_PATH, 'tailwind.config.js');
|
|
247
|
+
let tailwindConfigContent = await fs.promises.readFile(tailwindConfigPath, 'utf-8');
|
|
248
|
+
tailwindConfigContent = tailwindConfigContent.replace('/* IMPORTANT:ADMINFORTH TAILWIND STYLES */', stylesText);
|
|
249
|
+
await fs.promises.writeFile(tailwindConfigPath, tailwindConfigContent);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
|
|
242
253
|
|
|
243
254
|
/* generate custom rotes */
|
|
244
255
|
const homepageMenuItem = this.adminforth.config.menu.find((mi)=>mi.homepage);
|
package/package.json
CHANGED
package/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>
|
package/spa/package-lock.json
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"version": "0.0.0",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@iconify-prerendered/vue-flowbite": "^0.23.1714023977",
|
|
12
|
+
"@unhead/vue": "^1.9.12",
|
|
12
13
|
"@vueuse/core": "^10.10.0",
|
|
13
14
|
"dayjs": "^1.11.11",
|
|
14
15
|
"debounce": "^2.1.0",
|
|
@@ -1185,6 +1186,23 @@
|
|
|
1185
1186
|
"url": "https://github.com/sponsors/harlan-zw"
|
|
1186
1187
|
}
|
|
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
|
+
},
|
|
1188
1206
|
"node_modules/@vitejs/plugin-vue": {
|
|
1189
1207
|
"version": "5.0.4",
|
|
1190
1208
|
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz",
|
package/spa/package.json
CHANGED
package/spa/src/App.vue
CHANGED
|
@@ -1,89 +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
|
-
<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">
|
|
47
|
-
{{ theme === 'dark' ? 'Light' : 'Dark' }}
|
|
48
|
-
<IconMoonSolid class="w-5 h-5 text-blue-300
|
|
49
|
-
" v-if="theme !== 'dark'"/>
|
|
50
|
-
<IconSunSolid class="w-5 h-5 text-yellow-300
|
|
51
|
-
" v-else/>
|
|
52
|
-
mode
|
|
53
|
-
</span>
|
|
54
|
-
</li>
|
|
55
|
-
|
|
56
|
-
<li>
|
|
57
|
-
<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>
|
|
58
43
|
</li>
|
|
59
|
-
|
|
60
|
-
|
|
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>
|
|
61
48
|
</div>
|
|
62
49
|
</div>
|
|
50
|
+
</div>
|
|
63
51
|
</div>
|
|
64
52
|
</div>
|
|
65
|
-
|
|
53
|
+
</nav>
|
|
54
|
+
|
|
66
55
|
|
|
67
56
|
|
|
68
57
|
<aside
|
|
69
58
|
v-if="loggedIn"
|
|
70
59
|
|
|
71
|
-
id="logo-sidebar" class="fixed top-0 left-0 z-
|
|
72
|
-
<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-xl font-semibold sm:text-2xl whitespace-nowrap dark:text-header-text text-header-logo-color">
|
|
65
|
+
{{ coreStore.config?.brandName }}
|
|
66
|
+
</span>
|
|
67
|
+
</div>
|
|
73
68
|
<ul class="space-y-2 font-medium">
|
|
74
69
|
<template v-for="(item, i) in coreStore.menu" :key="`menu-${i}`">
|
|
75
|
-
<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>
|
|
76
71
|
<div v-else-if="item.type === 'gap'" class="flex items-center justify-center h-8"></div>
|
|
77
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
|
|
78
73
|
">{{ item.label }}</div>
|
|
79
74
|
|
|
80
75
|
|
|
81
76
|
<li v-else-if="item.children">
|
|
82
|
-
<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 transition duration-75 group hover:bg-nav-menu-bg-hover dark:text-white dark:hover:bg-gray-700"
|
|
83
78
|
:aria-controls="`dropdown-example${i}`"
|
|
84
79
|
:data-collapse-toggle="`dropdown-example${i}`"
|
|
85
80
|
>
|
|
86
|
-
<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>
|
|
87
82
|
|
|
88
83
|
<span class="flex-1 ms-3 text-left rtl:text-right whitespace-nowrap">{{ item.label }}</span>
|
|
89
84
|
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6">
|
|
@@ -135,6 +130,7 @@ import { useRoute, useRouter } from 'vue-router';
|
|
|
135
130
|
import { getIcon } from '@/utils';
|
|
136
131
|
import { useHead } from 'unhead'
|
|
137
132
|
import { createHead } from 'unhead'
|
|
133
|
+
// import { link } from 'fs';
|
|
138
134
|
const coreStore = useCoreStore();
|
|
139
135
|
|
|
140
136
|
|
|
@@ -182,6 +178,12 @@ onMounted(async () => {
|
|
|
182
178
|
title.value = coreStore.config.title || 'Admin Forth';
|
|
183
179
|
useHead({
|
|
184
180
|
title: title.value,
|
|
181
|
+
link: [
|
|
182
|
+
{
|
|
183
|
+
rel: 'icon',
|
|
184
|
+
href: coreStore.config.favicon || '/favicon.ico',
|
|
185
|
+
},
|
|
186
|
+
],
|
|
185
187
|
|
|
186
188
|
})
|
|
187
189
|
})
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
:placeholder="selectedItems.length ? '' : 'Select...'"
|
|
10
10
|
/>
|
|
11
11
|
<div class="absolute inset-y-0 left-2 flex items-center pr-2 flex-wrap">
|
|
12
|
-
|
|
12
|
+
{{ }}
|
|
13
|
+
<div v-for="item in selectedItems" :key="item?.name" class="bg-blue-100 text-blue-800 text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-blue-900 dark:text-blue-300">
|
|
13
14
|
<span>{{ item.label }}</span>
|
|
14
15
|
<button
|
|
15
16
|
type="button"
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<RouterLink
|
|
3
3
|
:to="{name: item.resourceId ? 'resource-list' : item.path, params: item.resourceId ? { resourceId: item.resourceId }: {}}"
|
|
4
|
-
class="flex items-center py-2 text-
|
|
4
|
+
class="flex items-center py-2 text-nav-menu-text hover:bg-nav-menu-bg-hover active:bg-nav-menu-bg-active" role="menuitem"
|
|
5
5
|
:class="{
|
|
6
6
|
'px-4': isChild,
|
|
7
7
|
'px-2': !isChild,
|
|
8
|
-
'bg-
|
|
8
|
+
'bg-nav-menu-bg-active dark:bg-gray-700': item.resourceId ?
|
|
9
9
|
($route.params.resourceId === item.resourceId && $route.name === 'resource-list') :
|
|
10
10
|
($route.name === item.path)
|
|
11
11
|
}"
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
<div>
|
|
3
3
|
|
|
4
4
|
<div
|
|
5
|
-
class="relative shadow-
|
|
5
|
+
class="relative shadow-resourse-form-shadow sm:rounded-lg dark:shadow-2xl dark:shadow-black"
|
|
6
6
|
>
|
|
7
7
|
<form autocomplete="off" @submit.prevent>
|
|
8
8
|
<table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
|
|
9
|
-
<thead class="text-xs text-gray-700 uppercase bg-
|
|
9
|
+
<thead class="text-xs text-gray-700 uppercase bg-form-view-heading dark:bg-gray-700 dark:text-gray-400">
|
|
10
10
|
<tr>
|
|
11
11
|
<th scope="col" class="px-6 py-3">
|
|
12
12
|
Field
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
</thead>
|
|
19
19
|
<tbody>
|
|
20
20
|
<tr v-for="column, i in editableColumns" :key="column.name"
|
|
21
|
-
class="
|
|
21
|
+
class="bg-form-view-bg dark:bg-gray-800 border-b dark:border-gray-700"
|
|
22
22
|
>
|
|
23
23
|
<!-- if column is in customComponentsPerColumn, use this component. If not, use this code -->
|
|
24
24
|
<template v-if="customComponentsPerColumn[column.name]">
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
</BreadcrumbsWithButtons>
|
|
66
66
|
|
|
67
67
|
<!-- table -->
|
|
68
|
-
<div class="relative overflow-x-auto shadow-
|
|
68
|
+
<div class="relative overflow-x-auto shadow-list-table-shadow dark:shadow-black dark:s">
|
|
69
69
|
|
|
70
70
|
|
|
71
71
|
<!-- skelet loader -->
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
</div>
|
|
91
91
|
|
|
92
92
|
<table v-else class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
|
|
93
|
-
<thead class="text-xs text-
|
|
93
|
+
<thead class="text-xs text-view-table-heading-text bg-list-view-table-heading dark:bg-gray-700 dark:text-gray-400">
|
|
94
94
|
<tr>
|
|
95
95
|
<th scope="col" class="p-4">
|
|
96
96
|
<div v-if="rows && rows.length" class="flex items-center">
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
</tr>
|
|
128
128
|
</thead>
|
|
129
129
|
<tbody>
|
|
130
|
-
<tr v-if="!rows" class="bg-
|
|
130
|
+
<tr v-if="!rows" class="bg-list-view-table-bg border-b dark:bg-gray-800 dark:border-gray-700">
|
|
131
131
|
<td :colspan="coreStore.resourceColumns.length + 2">
|
|
132
132
|
|
|
133
133
|
<div role="status"
|
|
@@ -171,7 +171,7 @@
|
|
|
171
171
|
</div>
|
|
172
172
|
</td>
|
|
173
173
|
</tr>
|
|
174
|
-
<tr v-else-if="rows.length === 0" class="bg-
|
|
174
|
+
<tr v-else-if="rows.length === 0" class="bg-list-view-table-bg border-b dark:bg-gray-800 dark:border-gray-700">
|
|
175
175
|
<td :colspan="coreStore.resourceColumns.length + 2">
|
|
176
176
|
|
|
177
177
|
<div id="toast-simple"
|
|
@@ -185,7 +185,7 @@
|
|
|
185
185
|
</tr>
|
|
186
186
|
|
|
187
187
|
<tr v-else v-for="(row, rowI) in rows" :key="row.id"
|
|
188
|
-
class="bg-
|
|
188
|
+
class="bg-list-view-table-bg border-b dark:bg-gray-800 border-list-view-border-color dark:border-gray-700 hover:bg-list-view-table-row-hover dark:hover:bg-gray-600">
|
|
189
189
|
<td class="w-4 p-4">
|
|
190
190
|
<div class="flex items center">
|
|
191
191
|
<input
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
</div>
|
|
28
28
|
<div
|
|
29
29
|
v-else
|
|
30
|
-
class="relative overflow-x-auto shadow-
|
|
30
|
+
class="relative overflow-x-auto shadow-resourse-form-shadow "
|
|
31
31
|
>
|
|
32
32
|
<table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
|
|
33
|
-
<thead class="text-xs text-gray-700 uppercase bg-
|
|
33
|
+
<thead class="text-xs text-gray-700 uppercase bg-form-view-heading dark:bg-gray-700 dark:text-gray-400">
|
|
34
34
|
<tr>
|
|
35
35
|
<th scope="col" class="px-6 py-3">
|
|
36
36
|
Field
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
</thead>
|
|
43
43
|
<tbody>
|
|
44
44
|
<tr v-for="column in coreStore.resourceColumns?.filter(c => c.showIn.includes('show'))" :key="column.name"
|
|
45
|
-
class="
|
|
45
|
+
class="bg-form-view-bg odd:dark:bg-gray-900 even:dark:bg-gray-800 border-b dark:border-gray-700"
|
|
46
46
|
>
|
|
47
47
|
<td class="px-6 py-4 whitespace-nowrap">
|
|
48
48
|
{{ column.label }}
|
package/spa/tailwind.config.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
/** @type {import('tailwindcss').Config} */
|
|
2
2
|
export default {
|
|
3
|
-
content: ["./src/**/*.{vue, js}", "./node_modules/flowbite/**/*.js"],
|
|
3
|
+
content: ["./src/**/*.{vue, js}","./src/*.{vue, js}", "./index.html", "./node_modules/flowbite/**/*.js"],
|
|
4
4
|
theme: {
|
|
5
|
-
extend: {
|
|
5
|
+
extend: {
|
|
6
|
+
/* IMPORTANT:ADMINFORTH TAILWIND STYLES */
|
|
7
|
+
}
|
|
6
8
|
},
|
|
9
|
+
|
|
7
10
|
darkMode: 'class',
|
|
8
11
|
plugins: [
|
|
9
12
|
require('flowbite/plugin'),
|
|
@@ -104,12 +104,14 @@ export type AdminForthConfig = {
|
|
|
104
104
|
customization?: {
|
|
105
105
|
customComponentsDir?: string,
|
|
106
106
|
vueUsesFile?: string,
|
|
107
|
+
customPublicDir?: string,
|
|
107
108
|
},
|
|
108
109
|
baseUrl?: string,
|
|
109
110
|
brandName?: string,
|
|
110
111
|
datesFormat?: string,
|
|
111
112
|
deleteConfirmation?: boolean,
|
|
112
113
|
title?: string,
|
|
114
|
+
styles?: Object,
|
|
113
115
|
}
|
|
114
116
|
|
|
115
117
|
export type AllowedActions = {
|