adminforth 1.3.54-next.9 → 1.3.55-next.2
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/auth.d.ts +31 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +42 -56
- package/dist/auth.js.map +1 -0
- package/dist/basePlugin.d.ts +18 -0
- package/dist/basePlugin.d.ts.map +1 -0
- package/dist/basePlugin.js +1 -0
- package/dist/basePlugin.js.map +1 -0
- package/dist/dataConnectors/baseConnector.d.ts +94 -0
- package/dist/dataConnectors/baseConnector.d.ts.map +1 -0
- package/dist/dataConnectors/baseConnector.js +108 -122
- package/dist/dataConnectors/baseConnector.js.map +1 -0
- package/dist/dataConnectors/clickhouse.d.ts +92 -0
- package/dist/dataConnectors/clickhouse.d.ts.map +1 -0
- package/dist/dataConnectors/clickhouse.js +132 -149
- package/dist/dataConnectors/clickhouse.js.map +1 -0
- package/dist/dataConnectors/mongo.d.ts +93 -0
- package/dist/dataConnectors/mongo.d.ts.map +1 -0
- package/dist/dataConnectors/mongo.js +75 -101
- package/dist/dataConnectors/mongo.js.map +1 -0
- package/dist/dataConnectors/postgres.d.ts +71 -0
- package/dist/dataConnectors/postgres.d.ts.map +1 -0
- package/dist/dataConnectors/postgres.js +124 -143
- package/dist/dataConnectors/postgres.js.map +1 -0
- package/dist/dataConnectors/sqlite.d.ts +67 -0
- package/dist/dataConnectors/sqlite.d.ts.map +1 -0
- package/dist/dataConnectors/sqlite.js +113 -130
- package/dist/dataConnectors/sqlite.js.map +1 -0
- package/dist/index.d.ts +92 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +197 -217
- package/dist/index.js.map +1 -0
- package/dist/modules/codeInjector.d.ts +35 -0
- package/dist/modules/codeInjector.d.ts.map +1 -0
- package/dist/modules/codeInjector.js +480 -486
- package/dist/modules/codeInjector.js.map +1 -0
- package/dist/modules/configValidator.d.ts +12 -0
- package/dist/modules/configValidator.d.ts.map +1 -0
- package/dist/modules/configValidator.js +31 -22
- package/dist/modules/configValidator.js.map +1 -0
- package/dist/modules/operationalResource.d.ts +17 -0
- package/dist/modules/operationalResource.d.ts.map +1 -0
- package/dist/modules/operationalResource.js +50 -70
- package/dist/modules/operationalResource.js.map +1 -0
- package/dist/modules/restApi.d.ts +10 -0
- package/dist/modules/restApi.d.ts.map +1 -0
- package/dist/modules/restApi.js +104 -116
- package/dist/modules/restApi.js.map +1 -0
- package/dist/modules/styleGenerator.d.ts +9 -0
- package/dist/modules/styleGenerator.d.ts.map +1 -0
- package/dist/modules/styleGenerator.js +1 -0
- package/dist/modules/styleGenerator.js.map +1 -0
- package/dist/modules/styles.d.ts +96 -0
- package/dist/modules/styles.d.ts.map +1 -0
- package/dist/modules/styles.js +1 -0
- package/dist/modules/styles.js.map +1 -0
- package/dist/modules/utils.d.ts +39 -0
- package/dist/modules/utils.d.ts.map +1 -0
- package/dist/modules/utils.js +1 -0
- package/dist/modules/utils.js.map +1 -0
- package/dist/plugins/audit-log/types.d.ts +35 -0
- package/dist/plugins/audit-log/types.d.ts.map +1 -0
- package/dist/plugins/audit-log/types.js +2 -0
- package/dist/plugins/audit-log/types.js.map +1 -0
- package/dist/plugins/chat-gpt/types.d.ts +82 -0
- package/dist/plugins/chat-gpt/types.d.ts.map +1 -0
- package/dist/plugins/chat-gpt/types.js +2 -0
- package/dist/plugins/chat-gpt/types.js.map +1 -0
- package/dist/plugins/email-password-reset/types.d.ts +28 -0
- package/dist/plugins/email-password-reset/types.d.ts.map +1 -0
- package/dist/plugins/email-password-reset/types.js +2 -0
- package/dist/plugins/email-password-reset/types.js.map +1 -0
- package/dist/plugins/foreign-inline-list/types.d.ts +19 -0
- package/dist/plugins/foreign-inline-list/types.d.ts.map +1 -0
- package/dist/plugins/foreign-inline-list/types.js +2 -0
- package/dist/plugins/foreign-inline-list/types.js.map +1 -0
- package/dist/plugins/import-export/types.d.ts +3 -0
- package/dist/plugins/import-export/types.d.ts.map +1 -0
- package/dist/plugins/import-export/types.js +2 -0
- package/dist/plugins/import-export/types.js.map +1 -0
- package/dist/plugins/rich-editor/custom/async-queue.d.ts +8 -0
- package/dist/plugins/rich-editor/custom/async-queue.d.ts.map +1 -0
- package/dist/plugins/rich-editor/custom/async-queue.js +29 -0
- package/dist/plugins/rich-editor/custom/async-queue.js.map +1 -0
- package/dist/plugins/rich-editor/dist/custom/async-queue.d.ts +8 -0
- package/dist/plugins/rich-editor/dist/custom/async-queue.d.ts.map +1 -0
- package/dist/plugins/rich-editor/dist/custom/async-queue.js +29 -0
- package/dist/plugins/rich-editor/dist/custom/async-queue.js.map +1 -0
- package/dist/plugins/rich-editor/types.d.ts +153 -0
- package/dist/plugins/rich-editor/types.d.ts.map +1 -0
- package/dist/plugins/rich-editor/types.js +16 -0
- package/dist/plugins/rich-editor/types.js.map +1 -0
- package/dist/plugins/two-factors-auth/types.d.ts +18 -0
- package/dist/plugins/two-factors-auth/types.d.ts.map +1 -0
- package/dist/plugins/two-factors-auth/types.js +2 -0
- package/dist/plugins/two-factors-auth/types.js.map +1 -0
- package/dist/plugins/upload/types.d.ts +132 -0
- package/dist/plugins/upload/types.d.ts.map +1 -0
- package/dist/plugins/upload/types.js +2 -0
- package/dist/plugins/upload/types.js.map +1 -0
- package/dist/servers/express.d.ts +18 -0
- package/dist/servers/express.d.ts.map +1 -0
- package/dist/servers/express.js +30 -42
- package/dist/servers/express.js.map +1 -0
- package/dist/spa/index.html +2 -2
- package/dist/spa/package-lock.json +87 -1
- package/dist/spa/package.json +4 -1
- package/dist/spa/src/App.vue +154 -50
- package/dist/spa/src/components/AcceptModal.vue +1 -1
- package/dist/spa/src/components/Breadcrumbs.vue +1 -1
- package/dist/spa/src/components/CustomDatePicker.vue +1 -1
- package/dist/spa/src/components/CustomDateRangePicker.vue +1 -1
- package/dist/spa/src/components/CustomRangePicker.vue +9 -5
- package/dist/spa/src/components/Dropdown.vue +4 -4
- package/dist/spa/src/components/Filters.vue +2 -2
- package/dist/spa/src/components/MenuLink.vue +3 -0
- package/dist/spa/src/components/ResourceForm.vue +67 -36
- package/dist/spa/src/components/ResourceListTable.vue +216 -144
- package/dist/spa/src/components/SkeleteLoader.vue +4 -4
- package/dist/spa/src/components/Toast.vue +3 -2
- package/dist/spa/src/components/ValueRenderer.vue +81 -6
- package/dist/spa/src/composables/useFrontendApi.ts +1 -1
- package/dist/spa/src/composables/useStores.ts +18 -14
- package/dist/spa/src/index.scss +4 -0
- package/{spa → dist/spa}/src/renderers/CompactUUID.vue +4 -4
- package/{spa → dist/spa}/src/renderers/CountryFlag.vue +2 -2
- package/dist/spa/src/router/index.ts +4 -8
- package/dist/spa/src/spa_types/core.ts +2 -0
- package/dist/spa/src/stores/core.ts +6 -2
- package/dist/spa/src/stores/filters.ts +15 -10
- package/dist/spa/src/stores/toast.ts +22 -6
- package/dist/spa/src/types/AdminForthConfig.ts +340 -55
- package/dist/spa/src/types/FrontendAPI.ts +52 -30
- package/dist/spa/src/utils.ts +59 -2
- package/dist/spa/src/views/CreateView.vue +15 -4
- package/dist/spa/src/views/EditView.vue +20 -7
- package/dist/spa/src/views/ListView.vue +132 -38
- package/dist/spa/src/views/LoginView.vue +50 -18
- package/dist/spa/src/views/ShowView.vue +25 -15
- package/dist/types/AdminForthConfig.d.ts +1619 -0
- package/dist/types/AdminForthConfig.d.ts.map +1 -0
- package/dist/types/AdminForthConfig.js +1 -0
- package/dist/types/AdminForthConfig.js.map +1 -0
- package/{types/FrontendAPI.ts → dist/types/FrontendAPI.d.ts} +27 -52
- package/dist/types/FrontendAPI.d.ts.map +1 -0
- package/dist/types/FrontendAPI.js +1 -0
- package/dist/types/FrontendAPI.js.map +1 -0
- package/package.json +16 -6
- package/auth.ts +0 -140
- package/basePlugin.ts +0 -70
- package/dataConnectors/baseConnector.ts +0 -216
- package/dataConnectors/clickhouse.ts +0 -338
- package/dataConnectors/mongo.ts +0 -202
- package/dataConnectors/postgres.ts +0 -306
- package/dataConnectors/sqlite.ts +0 -254
- package/index.ts +0 -428
- package/modules/codeInjector.ts +0 -736
- package/modules/configValidator.ts +0 -571
- package/modules/operationalResource.ts +0 -98
- package/modules/restApi.ts +0 -718
- package/modules/styleGenerator.ts +0 -55
- package/modules/styles.ts +0 -126
- package/modules/utils.ts +0 -472
- package/servers/express.ts +0 -259
- package/spa/.eslintrc.cjs +0 -14
- package/spa/README.md +0 -39
- package/spa/env.d.ts +0 -1
- package/spa/index.html +0 -23
- package/spa/package-lock.json +0 -4602
- package/spa/package.json +0 -51
- package/spa/postcss.config.js +0 -6
- package/spa/public/assets/favicon.png +0 -0
- package/spa/src/App.vue +0 -418
- package/spa/src/assets/base.css +0 -2
- package/spa/src/assets/logo.svg +0 -19
- package/spa/src/components/AcceptModal.vue +0 -45
- package/spa/src/components/Breadcrumbs.vue +0 -41
- package/spa/src/components/BreadcrumbsWithButtons.vue +0 -26
- package/spa/src/components/CustomDatePicker.vue +0 -176
- package/spa/src/components/CustomDateRangePicker.vue +0 -218
- package/spa/src/components/CustomRangePicker.vue +0 -156
- package/spa/src/components/Dropdown.vue +0 -168
- package/spa/src/components/Filters.vue +0 -222
- package/spa/src/components/HelloWorld.vue +0 -17
- package/spa/src/components/MenuLink.vue +0 -27
- package/spa/src/components/ResourceForm.vue +0 -290
- package/spa/src/components/ResourceListTable.vue +0 -466
- package/spa/src/components/SingleSkeletLoader.vue +0 -13
- package/spa/src/components/SkeleteLoader.vue +0 -23
- package/spa/src/components/Toast.vue +0 -78
- package/spa/src/components/ValueRenderer.vue +0 -114
- package/spa/src/components/icons/IconCalendar.vue +0 -5
- package/spa/src/components/icons/IconCommunity.vue +0 -7
- package/spa/src/components/icons/IconDocumentation.vue +0 -7
- package/spa/src/components/icons/IconEcosystem.vue +0 -7
- package/spa/src/components/icons/IconSupport.vue +0 -7
- package/spa/src/components/icons/IconTime.vue +0 -5
- package/spa/src/components/icons/IconTooling.vue +0 -19
- package/spa/src/composables/useFrontendApi.ts +0 -26
- package/spa/src/composables/useStores.ts +0 -131
- package/spa/src/index.scss +0 -31
- package/spa/src/main.ts +0 -18
- package/spa/src/router/index.ts +0 -59
- package/spa/src/spa_types/core.ts +0 -53
- package/spa/src/stores/core.ts +0 -148
- package/spa/src/stores/filters.ts +0 -27
- package/spa/src/stores/modal.ts +0 -48
- package/spa/src/stores/toast.ts +0 -31
- package/spa/src/stores/user.ts +0 -72
- package/spa/src/utils.ts +0 -160
- package/spa/src/views/CreateView.vue +0 -167
- package/spa/src/views/EditView.vue +0 -170
- package/spa/src/views/ListView.vue +0 -352
- package/spa/src/views/LoginView.vue +0 -192
- package/spa/src/views/ResourceParent.vue +0 -17
- package/spa/src/views/ShowView.vue +0 -186
- package/spa/tailwind.config.js +0 -17
- package/spa/tsconfig.app.json +0 -14
- package/spa/tsconfig.json +0 -11
- package/spa/tsconfig.node.json +0 -19
- package/spa/vite.config.ts +0 -56
- package/tsconfig.json +0 -112
- package/types/AdminForthConfig.ts +0 -1762
- /package/{spa → dist/spa}/src/components/ThreeDotsMenu.vue +0 -0
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<!-- table -->
|
|
3
|
-
<div class="relative overflow-x-auto shadow-listTableShadow dark:shadow-darkListTableShadow overflow-y-hidden
|
|
4
|
-
|
|
3
|
+
<div class="relative overflow-x-auto shadow-listTableShadow dark:shadow-darkListTableShadow overflow-y-hidden"
|
|
4
|
+
:class="{'rounded-default': !noRoundings}"
|
|
5
|
+
>
|
|
5
6
|
<!-- skelet loader -->
|
|
6
7
|
<div role="status" v-if="!resource || !resource.columns"
|
|
7
8
|
class="max-w p-4 space-y-4 divide-y divide-gray-200 rounded shadow animate-pulse dark:divide-gray-700 md:p-6 dark:border-gray-700">
|
|
8
|
-
|
|
9
|
+
|
|
10
|
+
<div role="status" class="max-w-sm animate-pulse">
|
|
11
|
+
<div class="h-2 bg-gray-200 rounded-full dark:bg-gray-700 max-w-[360px]"></div>
|
|
12
|
+
</div>
|
|
9
13
|
</div>
|
|
10
14
|
|
|
11
15
|
<table v-else class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400 rounded-default">
|
|
@@ -19,11 +23,11 @@
|
|
|
19
23
|
</div>
|
|
20
24
|
</th>
|
|
21
25
|
|
|
22
|
-
<th v-for="c in columnsListed" scope="col" class="px-6 py-3">
|
|
26
|
+
<th v-for="c in columnsListed" scope="col" class="px-2 md:px-3 lg:px-6 py-3">
|
|
23
27
|
|
|
24
|
-
<div @click="() => c.sortable && onSortButtonClick(c.name)"
|
|
28
|
+
<div @click="(evt) => c.sortable && onSortButtonClick(evt, c.name)"
|
|
29
|
+
class="flex items-center " :class="{'cursor-pointer':c.sortable}">
|
|
25
30
|
{{ c.label }}
|
|
26
|
-
|
|
27
31
|
|
|
28
32
|
<div v-if="c.sortable"
|
|
29
33
|
:style="{ 'color':ascArr.includes(c.name)?'green':descArr.includes(c.name)?'red':'currentColor'}">
|
|
@@ -54,122 +58,142 @@
|
|
|
54
58
|
</tr>
|
|
55
59
|
</thead>
|
|
56
60
|
<tbody>
|
|
57
|
-
<SkeleteLoader
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
<div
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
<tr @click="onClick($event,row)" v-else v-for="(row, rowI) in rows" :key="row.id"
|
|
72
|
-
class="bg-lightListTable dark:bg-darkListTable border-lightListBorder dark:border-gray-700 hover:bg-lightListTableRowHover dark:hover:bg-darkListTableRowHover cursor-pointer"
|
|
73
|
-
:class="{'border-b': rowI !== rows.length - 1}"
|
|
74
|
-
>
|
|
75
|
-
<td class="w-4 p-4 cursor-default" @click="(e)=>{e.stopPropagation()}">
|
|
76
|
-
<div class="flex items center ">
|
|
77
|
-
<input
|
|
78
|
-
@click="(e)=>{e.stopPropagation()}"
|
|
79
|
-
id="checkbox-table-search-1"
|
|
80
|
-
type="checkbox"
|
|
81
|
-
:checked="checkboxesInternal.includes(row.id)"
|
|
82
|
-
@change="(e)=>{addToCheckedValues(row.id)}"
|
|
83
|
-
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600 cursor-pointer">
|
|
84
|
-
<label for="checkbox-table-search-1" class="sr-only">checkbox</label>
|
|
85
|
-
</div>
|
|
86
|
-
</td>
|
|
87
|
-
<td v-for="c in columnsListed" class="px-6 py-4">
|
|
88
|
-
<!-- if c.name in listComponentsPerColumn, render it. If not, render ValueRenderer -->
|
|
89
|
-
<component
|
|
90
|
-
:is="c?.components?.list ? getCustomComponent(c.components.list) : ValueRenderer"
|
|
91
|
-
:meta="c?.components?.list?.meta"
|
|
92
|
-
:column="c"
|
|
93
|
-
:record="row"
|
|
94
|
-
:adminUser="coreStore.adminUser"
|
|
95
|
-
:resource="resource"
|
|
96
|
-
/>
|
|
97
|
-
</td>
|
|
98
|
-
<td class=" items-center px-6 py-4 cursor-default" @click="(e)=>{e.stopPropagation()}">
|
|
99
|
-
<div class="flex">
|
|
100
|
-
<RouterLink
|
|
101
|
-
v-if="resource.options?.allowedActions.show"
|
|
102
|
-
:to="{
|
|
103
|
-
name: 'resource-show',
|
|
104
|
-
params: {
|
|
105
|
-
resourceId: resource.resourceId,
|
|
106
|
-
primaryKey: row._primaryKeyValue,
|
|
107
|
-
}
|
|
108
|
-
}"
|
|
109
|
-
class="font-medium text-blue-600 dark:text-blue-500 hover:underline"
|
|
110
|
-
:data-tooltip-target="`tooltip-show-${rowI}`"
|
|
111
|
-
>
|
|
112
|
-
<IconEyeSolid class="w-5 h-5 me-2"/>
|
|
113
|
-
</RouterLink>
|
|
114
|
-
|
|
115
|
-
<div :id="`tooltip-show-${rowI}`"
|
|
116
|
-
role="tooltip"
|
|
117
|
-
class="absolute z-10 invisible inline-block px-3 py-2 text-sm font-medium text-white transition-opacity duration-300 bg-gray-900 rounded-lg shadow-sm opacity-0 tooltip dark:bg-gray-700">
|
|
118
|
-
Show item
|
|
119
|
-
<div class="tooltip-arrow" data-popper-arrow></div>
|
|
120
|
-
</div>
|
|
121
|
-
|
|
122
|
-
<RouterLink v-if="resource.options?.allowedActions.edit"
|
|
123
|
-
:to="{
|
|
124
|
-
name: 'resource-edit',
|
|
125
|
-
params: {
|
|
126
|
-
resourceId: resource.resourceId,
|
|
127
|
-
primaryKey: row._primaryKeyValue
|
|
128
|
-
}
|
|
129
|
-
}"
|
|
130
|
-
class="font-medium text-blue-600 dark:text-blue-500 hover:underline ms-3"
|
|
131
|
-
:data-tooltip-target="`tooltip-edit-${rowI}`"
|
|
132
|
-
>
|
|
133
|
-
<IconPenSolid class="w-5 h-5 me-2"/>
|
|
134
|
-
</RouterLink>
|
|
135
|
-
|
|
136
|
-
<div :id="`tooltip-edit-${rowI}`"
|
|
137
|
-
role="tooltip"
|
|
138
|
-
class="absolute z-10 invisible inline-block px-3 py-2 text-sm font-medium text-white transition-opacity duration-300 bg-gray-900 rounded-lg shadow-sm opacity-0 tooltip dark:bg-gray-700">
|
|
139
|
-
Edit
|
|
140
|
-
<div class="tooltip-arrow" data-popper-arrow></div>
|
|
141
|
-
</div>
|
|
61
|
+
<SkeleteLoader
|
|
62
|
+
v-if="!rows"
|
|
63
|
+
:columns="resource?.columns.filter(c => c.showIn.includes('list')).length + 2"
|
|
64
|
+
:rows="3"
|
|
65
|
+
/>
|
|
66
|
+
<tr v-else-if="rows.length === 0" class="bg-lightListTable dark:bg-darkListTable dark:border-darkListTableBorder">
|
|
67
|
+
<td :colspan="resource?.columns.length + 2">
|
|
68
|
+
|
|
69
|
+
<div id="toast-simple"
|
|
70
|
+
class=" mx-auto my-5 flex items-center w-full max-w-xs p-4 space-x-4 rtl:space-x-reverse text-gray-500 divide-x rtl:divide-x-reverse divide-gray-200 dark:text-gray-400 dark:divide-gray-700 space-x dark:bg-gray-800"
|
|
71
|
+
role="alert">
|
|
72
|
+
<IconInboxOutline class="w-6 h-6 text-gray-500 dark:text-gray-400"/>
|
|
73
|
+
<div class="ps-4 text-sm font-normal">No items here yet</div>
|
|
74
|
+
</div>
|
|
142
75
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
76
|
+
</td>
|
|
77
|
+
</tr>
|
|
78
|
+
|
|
79
|
+
<tr @click="onClick($event,row)"
|
|
80
|
+
v-else v-for="(row, rowI) in rows" :key="`row_${row._primaryKeyValue}`"
|
|
81
|
+
class="bg-lightListTable dark:bg-darkListTable border-lightListBorder dark:border-gray-700 hover:bg-lightListTableRowHover dark:hover:bg-darkListTableRowHover"
|
|
82
|
+
|
|
83
|
+
:class="{'border-b': rowI !== rows.length - 1, 'cursor-pointer': row._clickUrl !== null}"
|
|
84
|
+
>
|
|
85
|
+
<td class="w-4 p-4 cursor-default" @click="(e)=>{e.stopPropagation()}">
|
|
86
|
+
<div class="flex items center ">
|
|
87
|
+
<input
|
|
88
|
+
@click="(e)=>{e.stopPropagation()}"
|
|
89
|
+
id="checkbox-table-search-1"
|
|
90
|
+
type="checkbox"
|
|
91
|
+
:checked="checkboxesInternal.includes(row._primaryKeyValue)"
|
|
92
|
+
@change="(e)=>{addToCheckedValues(row._primaryKeyValue)}"
|
|
93
|
+
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 dark:focus:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600 cursor-pointer">
|
|
94
|
+
<label for="checkbox-table-search-1" class="sr-only">checkbox</label>
|
|
95
|
+
</div>
|
|
96
|
+
</td>
|
|
97
|
+
<td v-for="c in columnsListed" class="px-2 md:px-3 lg:px-6 py-4">
|
|
98
|
+
<!-- if c.name in listComponentsPerColumn, render it. If not, render ValueRenderer -->
|
|
99
|
+
<component
|
|
100
|
+
:is="c?.components?.list ? getCustomComponent(c.components.list) : ValueRenderer"
|
|
101
|
+
:meta="c?.components?.list?.meta"
|
|
102
|
+
:column="c"
|
|
103
|
+
:record="row"
|
|
104
|
+
:adminUser="coreStore.adminUser"
|
|
105
|
+
:resource="resource"
|
|
106
|
+
/>
|
|
107
|
+
</td>
|
|
108
|
+
<td class=" items-center px-2 md:px-3 lg:px-6 py-4 cursor-default" @click="(e)=>{e.stopPropagation()}">
|
|
109
|
+
<div class="flex">
|
|
110
|
+
<RouterLink
|
|
111
|
+
v-if="resource.options?.allowedActions.show"
|
|
112
|
+
:to="{
|
|
113
|
+
name: 'resource-show',
|
|
114
|
+
params: {
|
|
115
|
+
resourceId: resource.resourceId,
|
|
116
|
+
primaryKey: row._primaryKeyValue,
|
|
117
|
+
}
|
|
118
|
+
}"
|
|
119
|
+
class="font-medium text-lightPrimary dark:text-darkPrimary hover:underline"
|
|
120
|
+
:data-tooltip-target="`tooltip-show-${rowI}`"
|
|
121
|
+
>
|
|
122
|
+
<IconEyeSolid class="w-5 h-5 me-2"/>
|
|
123
|
+
</RouterLink>
|
|
124
|
+
|
|
125
|
+
<div :id="`tooltip-show-${rowI}`"
|
|
126
|
+
role="tooltip"
|
|
127
|
+
class="absolute z-10 invisible inline-block px-3 py-2 text-sm font-medium text-white transition-opacity duration-300 bg-gray-900 rounded-lg shadow-sm opacity-0 tooltip dark:bg-gray-700">
|
|
128
|
+
Show item
|
|
129
|
+
<div class="tooltip-arrow" data-popper-arrow></div>
|
|
130
|
+
</div>
|
|
131
|
+
|
|
132
|
+
<RouterLink v-if="resource.options?.allowedActions.edit"
|
|
133
|
+
:to="{
|
|
134
|
+
name: 'resource-edit',
|
|
135
|
+
params: {
|
|
136
|
+
resourceId: resource.resourceId,
|
|
137
|
+
primaryKey: row._primaryKeyValue
|
|
138
|
+
}
|
|
139
|
+
}"
|
|
140
|
+
class="font-medium text-lightPrimary dark:text-darkPrimary hover:underline ms-3"
|
|
141
|
+
:data-tooltip-target="`tooltip-edit-${rowI}`"
|
|
142
|
+
>
|
|
143
|
+
<IconPenSolid class="w-5 h-5 me-2"/>
|
|
144
|
+
</RouterLink>
|
|
145
|
+
|
|
146
|
+
<div :id="`tooltip-edit-${rowI}`"
|
|
147
|
+
role="tooltip"
|
|
148
|
+
class="absolute z-10 invisible inline-block px-3 py-2 text-sm font-medium text-white transition-opacity duration-300 bg-gray-900 rounded-lg shadow-sm opacity-0 tooltip dark:bg-gray-700">
|
|
149
|
+
Edit
|
|
150
|
+
<div class="tooltip-arrow" data-popper-arrow></div>
|
|
151
|
+
</div>
|
|
152
|
+
|
|
153
|
+
<button v-if="resource.options?.allowedActions.delete"
|
|
154
|
+
class="font-medium text-lightPrimary dark:text-darkPrimary hover:underline ms-3"
|
|
155
|
+
:data-tooltip-target="`tooltip-delete-${rowI}`"
|
|
156
|
+
@click="deleteRecord(row)"
|
|
157
|
+
>
|
|
158
|
+
<IconTrashBinSolid class="w-5 h-5 me-2"/>
|
|
159
|
+
</button>
|
|
160
|
+
|
|
161
|
+
<div :id="`tooltip-delete-${rowI}`"
|
|
162
|
+
role="tooltip"
|
|
163
|
+
class="absolute z-10 invisible inline-block px-3 py-2 text-sm font-medium text-white transition-opacity duration-300 bg-gray-900 rounded-lg shadow-sm opacity-0 tooltip dark:bg-gray-700">
|
|
164
|
+
Delete
|
|
165
|
+
<div class="tooltip-arrow" data-popper-arrow></div>
|
|
166
|
+
</div>
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
<template v-if="coreStore.resourceOptions?.pageInjections?.list?.customActionIcons">
|
|
170
|
+
<component
|
|
171
|
+
v-for="c in coreStore.resourceOptions?.pageInjections?.list?.customActionIcons"
|
|
172
|
+
:is="getCustomComponent(c)"
|
|
173
|
+
:meta="c.meta"
|
|
174
|
+
:resource="coreStore.resource"
|
|
175
|
+
:adminUser="coreStore.adminUser"
|
|
176
|
+
:record="row"
|
|
177
|
+
/>
|
|
178
|
+
</template>
|
|
179
|
+
</div>
|
|
180
|
+
</td>
|
|
181
|
+
</tr>
|
|
160
182
|
</tbody>
|
|
161
183
|
</table>
|
|
162
184
|
</div>
|
|
163
|
-
<!-- pagination
|
|
185
|
+
<!-- pagination
|
|
186
|
+
totalRows in v-if is used to not hide page input during loading when user puts cursor into it and edit directly (rows gets null there during edit)
|
|
187
|
+
-->
|
|
164
188
|
<div class="flex flex-col items-center mt-4 mb-4 xs:flex-row xs:justify-between xs:items-center"
|
|
165
|
-
v-if="rows && totalRows >= pageSize && totalRows > 0"
|
|
189
|
+
v-if="(rows || totalRows) && totalRows >= pageSize && totalRows > 0"
|
|
166
190
|
>
|
|
167
191
|
<!-- Help text -->
|
|
168
192
|
<span class="text-sm text-gray-700 dark:text-gray-400">
|
|
169
193
|
Showing <span class="font-semibold text-gray-900 dark:text-white">
|
|
170
|
-
{{ (page - 1) * pageSize + 1 }}
|
|
194
|
+
{{ ((page || 1) - 1) * pageSize + 1 }}
|
|
171
195
|
</span> to <span class="font-semibold text-gray-900 dark:text-white">
|
|
172
|
-
{{ Math.min(page * pageSize, totalRows) }}
|
|
196
|
+
{{ Math.min((page || 1) * pageSize, totalRows) }}
|
|
173
197
|
</span> of <span class="font-semibold text-gray-900 dark:text-white">{{
|
|
174
198
|
totalRows
|
|
175
199
|
}}</span> Entries
|
|
@@ -177,7 +201,7 @@
|
|
|
177
201
|
<div class="inline-flex mt-2 xs:mt-0">
|
|
178
202
|
<!-- Buttons -->
|
|
179
203
|
<button
|
|
180
|
-
class="flex items-center py-1 px-3 text-sm font-medium text-gray-900 focus:outline-none bg-white border-r-0 rounded-s border border-gray-300 hover:bg-gray-100 hover:text-
|
|
204
|
+
class="flex items-center py-1 px-3 text-sm font-medium text-gray-900 focus:outline-none bg-white border-r-0 rounded-s border border-gray-300 hover:bg-gray-100 hover:text-lightPrimary 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 disabled:opacity-50"
|
|
181
205
|
@click="page--" :disabled="page <= 1">
|
|
182
206
|
<svg class="w-3.5 h-3.5 me-2 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none"
|
|
183
207
|
viewBox="0 0 14 10">
|
|
@@ -187,24 +211,28 @@
|
|
|
187
211
|
Prev
|
|
188
212
|
</button>
|
|
189
213
|
<button
|
|
190
|
-
class="flex items-center py-1 px-3 text-sm font-medium text-gray-900 focus:outline-none bg-white border-r-0 border border-gray-300 hover:bg-gray-100 hover:text-
|
|
214
|
+
class="flex items-center py-1 px-3 text-sm font-medium text-gray-900 focus:outline-none bg-white border-r-0 border border-gray-300 hover:bg-gray-100 hover:text-lightPrimary 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 disabled:opacity-50"
|
|
191
215
|
@click="page = 1" :disabled="page <= 1">
|
|
192
216
|
<!-- <IconChevronDoubleLeftOutline class="w-4 h-4" /> -->
|
|
193
217
|
1
|
|
194
218
|
</button>
|
|
195
|
-
<
|
|
196
|
-
|
|
197
|
-
|
|
219
|
+
<div
|
|
220
|
+
contenteditable="true"
|
|
221
|
+
class="min-w-10 outline-none inline-block w-auto min-w-10 py-1.5 px-3 text-sm text-center text-gray-700 border border-gray-300 dark:border-gray-700 dark:text-gray-400 dark:bg-gray-800 z-10"
|
|
222
|
+
@input="page = parseInt($event.target.innerText) || ''"
|
|
223
|
+
>
|
|
224
|
+
{{ page }}
|
|
225
|
+
</div>
|
|
198
226
|
|
|
199
227
|
<button
|
|
200
|
-
class="flex items-center py-1 px-3 text-sm font-medium text-gray-900 focus:outline-none bg-white border-l-0 border border-gray-300 hover:bg-gray-100 hover:text-
|
|
228
|
+
class="flex items-center py-1 px-3 text-sm font-medium text-gray-900 focus:outline-none bg-white border-l-0 border border-gray-300 hover:bg-gray-100 hover:text-lightPrimary 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 disabled:opacity-50"
|
|
201
229
|
@click="page = totalPages" :disabled="page >= totalPages">
|
|
202
230
|
{{ totalPages }}
|
|
203
231
|
|
|
204
232
|
<!-- <IconChevronDoubleRightOutline class="w-4 h-4" /> -->
|
|
205
233
|
</button>
|
|
206
234
|
<button
|
|
207
|
-
class="flex items-center py-1 px-3 text-sm font-medium text-gray-900 focus:outline-none bg-white border-l-0 rounded-e border border-gray-300 hover:bg-gray-100 hover:text-
|
|
235
|
+
class="flex items-center py-1 px-3 text-sm font-medium text-gray-900 focus:outline-none bg-white border-l-0 rounded-e border border-gray-300 hover:bg-gray-100 hover:text-lightPrimary 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 disabled:opacity-50"
|
|
208
236
|
|
|
209
237
|
@click="page++" :disabled="page >= totalPages">
|
|
210
238
|
Next
|
|
@@ -222,10 +250,8 @@
|
|
|
222
250
|
<script setup>
|
|
223
251
|
|
|
224
252
|
|
|
225
|
-
import { initFlowbite } from 'flowbite';
|
|
226
253
|
import { computed, onMounted, ref, watch } from 'vue';
|
|
227
|
-
import {
|
|
228
|
-
import { callAdminForthApi, getIcon } from '@/utils';
|
|
254
|
+
import { callAdminForthApi } from '@/utils';
|
|
229
255
|
|
|
230
256
|
import ValueRenderer from '@/components/ValueRenderer.vue';
|
|
231
257
|
import { getCustomComponent } from '@/utils';
|
|
@@ -234,28 +260,27 @@ import { showSuccesTost, showErrorTost } from '@/composables/useFrontendApi';
|
|
|
234
260
|
import SkeleteLoader from '@/components/SkeleteLoader.vue';
|
|
235
261
|
|
|
236
262
|
import {
|
|
237
|
-
IconInboxOutline,
|
|
238
|
-
IconPlusOutline
|
|
263
|
+
IconInboxOutline,
|
|
239
264
|
} from '@iconify-prerendered/vue-flowbite';
|
|
240
265
|
|
|
241
266
|
import {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
IconPenSolid,
|
|
246
|
-
IconTrashBinSolid
|
|
267
|
+
IconEyeSolid,
|
|
268
|
+
IconPenSolid,
|
|
269
|
+
IconTrashBinSolid
|
|
247
270
|
} from '@iconify-prerendered/vue-flowbite';
|
|
248
271
|
import router from '@/router';
|
|
249
272
|
|
|
250
273
|
const coreStore = useCoreStore();
|
|
251
274
|
|
|
252
275
|
const props = defineProps([
|
|
276
|
+
'page',
|
|
253
277
|
'resource',
|
|
254
278
|
'rows',
|
|
255
279
|
'totalRows',
|
|
256
280
|
'pageSize',
|
|
257
281
|
'checkboxes',
|
|
258
|
-
'sort'
|
|
282
|
+
'sort',
|
|
283
|
+
'noRoundings'
|
|
259
284
|
])
|
|
260
285
|
|
|
261
286
|
// emits, update page
|
|
@@ -272,6 +297,7 @@ const page = ref(1);
|
|
|
272
297
|
const sort = ref([]);
|
|
273
298
|
|
|
274
299
|
|
|
300
|
+
|
|
275
301
|
watch(() => page.value, (newPage) => {
|
|
276
302
|
emits('update:page', newPage);
|
|
277
303
|
});
|
|
@@ -295,7 +321,12 @@ watch(() => props.sort, (newSort) => {
|
|
|
295
321
|
sort.value = newSort;
|
|
296
322
|
});
|
|
297
323
|
|
|
324
|
+
watch(() => props.page, (newPage) => {
|
|
325
|
+
page.value = newPage;
|
|
326
|
+
});
|
|
327
|
+
|
|
298
328
|
function addToCheckedValues(id) {
|
|
329
|
+
console.log('checking', checkboxesInternal.value, 'id', id)
|
|
299
330
|
if (checkboxesInternal.value.includes(id)) {
|
|
300
331
|
checkboxesInternal.value = checkboxesInternal.value.filter((item) => item !== id);
|
|
301
332
|
} else {
|
|
@@ -309,13 +340,13 @@ const columnsListed = computed(() => props.resource?.columns?.filter(c => c.show
|
|
|
309
340
|
async function selectAll(value) {
|
|
310
341
|
if (!allFromThisPageChecked.value) {
|
|
311
342
|
props.rows.forEach((r) => {
|
|
312
|
-
if (!checkboxesInternal.value.includes(r.
|
|
313
|
-
checkboxesInternal.value.push(r.
|
|
343
|
+
if (!checkboxesInternal.value.includes(r._primaryKeyValue)) {
|
|
344
|
+
checkboxesInternal.value.push(r._primaryKeyValue)
|
|
314
345
|
}
|
|
315
346
|
});
|
|
316
347
|
} else {
|
|
317
348
|
props.rows.forEach((r) => {
|
|
318
|
-
checkboxesInternal.value = checkboxesInternal.value.filter((item) => item !== r.
|
|
349
|
+
checkboxesInternal.value = checkboxesInternal.value.filter((item) => item !== r._primaryKeyValue);
|
|
319
350
|
});
|
|
320
351
|
}
|
|
321
352
|
checkboxesInternal.value = [ ...checkboxesInternal.value ];
|
|
@@ -325,16 +356,24 @@ const totalPages = computed(() => Math.ceil(props.totalRows / props.pageSize));
|
|
|
325
356
|
|
|
326
357
|
const allFromThisPageChecked = computed(() => {
|
|
327
358
|
if (!props.rows) return false;
|
|
328
|
-
return props.rows.every((r) => checkboxesInternal.value.includes(r.
|
|
359
|
+
return props.rows.every((r) => checkboxesInternal.value.includes(r._primaryKeyValue));
|
|
329
360
|
});
|
|
330
361
|
const ascArr = computed(() => sort.value.filter((s) => s.direction === 'asc').map((s) => s.field));
|
|
331
362
|
const descArr = computed(() => sort.value.filter((s) => s.direction === 'desc').map((s) => s.field));
|
|
332
363
|
|
|
333
364
|
|
|
334
|
-
function onSortButtonClick(field) {
|
|
365
|
+
function onSortButtonClick(event, field) {
|
|
366
|
+
// if ctrl key is pressed, add to sort otherwise sort by this field
|
|
367
|
+
// in any case if field is already in sort, toggle direction
|
|
368
|
+
|
|
335
369
|
const sortIndex = sort.value.findIndex((s) => s.field === field);
|
|
336
370
|
if (sortIndex === -1) {
|
|
337
|
-
|
|
371
|
+
// field is not in sort, add it
|
|
372
|
+
if (event.ctrlKey) {
|
|
373
|
+
sort.value = [...sort.value,{field, direction: 'asc'}];
|
|
374
|
+
} else {
|
|
375
|
+
sort.value = [{field, direction: 'asc'}];
|
|
376
|
+
}
|
|
338
377
|
} else {
|
|
339
378
|
const sortField = sort.value[sortIndex];
|
|
340
379
|
if (sortField.direction === 'asc') {
|
|
@@ -347,18 +386,51 @@ function onSortButtonClick(field) {
|
|
|
347
386
|
|
|
348
387
|
|
|
349
388
|
const clickTarget = ref(null);
|
|
389
|
+
|
|
350
390
|
async function onClick(e,row) {
|
|
351
391
|
if(clickTarget.value === e.target) return;
|
|
352
392
|
clickTarget.value = e.target;
|
|
353
|
-
await new Promise((resolve) => setTimeout(resolve,
|
|
393
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
354
394
|
if (window.getSelection().toString()) return;
|
|
355
|
-
else {
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
395
|
+
else {
|
|
396
|
+
if (row._clickUrl === null) {
|
|
397
|
+
// user asked to nothing on click
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
if (e.ctrlKey || e.metaKey || row._clickUrl?.includes('target=_blank')) {
|
|
401
|
+
|
|
402
|
+
if (row._clickUrl) {
|
|
403
|
+
window.open(row._clickUrl, '_blank');
|
|
404
|
+
} else {
|
|
405
|
+
window.open(
|
|
406
|
+
router.resolve({
|
|
407
|
+
name: 'resource-show',
|
|
408
|
+
params: {
|
|
409
|
+
resourceId: props.resource.resourceId,
|
|
410
|
+
primaryKey: row._primaryKeyValue,
|
|
411
|
+
},
|
|
412
|
+
}).fullPath,
|
|
413
|
+
'_blank'
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
} else {
|
|
417
|
+
if (row._clickUrl) {
|
|
418
|
+
if (row._clickUrl.startsWith('http')) {
|
|
419
|
+
document.location.href = row._clickUrl;
|
|
420
|
+
} else {
|
|
421
|
+
router.push(row._clickUrl);
|
|
422
|
+
}
|
|
423
|
+
} else {
|
|
424
|
+
router.push({
|
|
425
|
+
name: 'resource-show',
|
|
426
|
+
params: {
|
|
427
|
+
resourceId: props.resource.resourceId,
|
|
428
|
+
primaryKey: row._primaryKeyValue,
|
|
429
|
+
},
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
362
434
|
}
|
|
363
435
|
|
|
364
436
|
async function deleteRecord(row) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<tr v-for="c in new Array(props.
|
|
3
|
-
|
|
2
|
+
<tr v-for="c in new Array(props.rows)" class="bg-lightListTable border-b dark:bg-darkListTable dark:border-darkListBorder">
|
|
3
|
+
<td v-for="r in new Array(props.columns)" class="items-center px-6 py-8 cursor-default" >
|
|
4
4
|
<div role="status" class="max-w-sm animate-pulse">
|
|
5
5
|
<div class="h-2 bg-gray-200 rounded-full dark:bg-gray-700 max-w-[360px]"></div>
|
|
6
6
|
</div>
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
<script setup>
|
|
12
12
|
|
|
13
13
|
const props = defineProps({
|
|
14
|
-
columns:Number,
|
|
15
|
-
rows:Number
|
|
14
|
+
columns: Number,
|
|
15
|
+
rows: Number
|
|
16
16
|
});
|
|
17
17
|
|
|
18
18
|
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
<div
|
|
4
|
+
<div class="flex items-center w-full p-4 text-gray-500 rounded-lg shadow-lg dark:text-gray-400 dark:bg-gray-800 bg-white"
|
|
5
|
+
role="alert"
|
|
5
6
|
:class="
|
|
6
7
|
{
|
|
7
8
|
'danger': 'bg-red-100',
|
|
8
9
|
}[toast.variant]
|
|
9
10
|
"
|
|
10
11
|
>
|
|
11
|
-
<div v-if="toast.variant == 'info'" class="inline-flex items-center justify-center flex-shrink-0 w-8 h-8 text-
|
|
12
|
+
<div v-if="toast.variant == 'info'" class="inline-flex items-center justify-center flex-shrink-0 w-8 h-8 text-lightPrimary dark:text-darkPrimary bg-lightPrimaryOpacity rounded-lg dark:bg-blue-800 dark:text-blue-200">
|
|
12
13
|
<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 18 20">
|
|
13
14
|
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.147 15.085a7.159 7.159 0 0 1-6.189 3.307A6.713 6.713 0 0 1 3.1 15.444c-2.679-4.513.287-8.737.888-9.548A4.373 4.373 0 0 0 5 1.608c1.287.953 6.445 3.218 5.537 10.5 1.5-1.122 2.706-3.01 2.853-6.14 1.433 1.049 3.993 5.395 1.757 9.117Z"/>
|
|
14
15
|
</svg>
|