adminforth 1.0.26 → 1.0.27
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.
|
@@ -126,15 +126,14 @@ class PostgresConnector {
|
|
|
126
126
|
return null;
|
|
127
127
|
}
|
|
128
128
|
if (field._underlineType == 'timestamp' || field._underlineType == 'int') {
|
|
129
|
-
return dayjs
|
|
129
|
+
return dayjs(value).toISOString();
|
|
130
130
|
} else if (field._underlineType == 'varchar') {
|
|
131
|
-
return dayjs
|
|
131
|
+
return dayjs(value).toISOString();
|
|
132
132
|
} else {
|
|
133
133
|
throw new Error(`AdminForth does not support row type: ${field._underlineType} for timestamps, use VARCHAR (with iso strings) or TIMESTAMP/INT (with unix timestamps)`);
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
|
|
138
137
|
return value;
|
|
139
138
|
}
|
|
140
139
|
|
|
@@ -167,10 +166,8 @@ class PostgresConnector {
|
|
|
167
166
|
return null;
|
|
168
167
|
}
|
|
169
168
|
if (field._underlineType == 'timestamp' || field._underlineType == 'int') {
|
|
170
|
-
|
|
171
|
-
return dayjs(value).unix();
|
|
169
|
+
return dayjs(value);
|
|
172
170
|
} else if (field._underlineType == 'varchar') {
|
|
173
|
-
// value is iso string now, convert to unix timestamp
|
|
174
171
|
return dayjs(value).toISOString();
|
|
175
172
|
}
|
|
176
173
|
} else if (field.type == AdminForthTypes.BOOLEAN) {
|
|
@@ -127,10 +127,10 @@ class PostgresConnector {
|
|
|
127
127
|
return null;
|
|
128
128
|
}
|
|
129
129
|
if (field._underlineType == 'timestamp' || field._underlineType == 'int') {
|
|
130
|
-
return dayjs
|
|
130
|
+
return dayjs(value).toISOString();
|
|
131
131
|
}
|
|
132
132
|
else if (field._underlineType == 'varchar') {
|
|
133
|
-
return dayjs
|
|
133
|
+
return dayjs(value).toISOString();
|
|
134
134
|
}
|
|
135
135
|
else {
|
|
136
136
|
throw new Error(`AdminForth does not support row type: ${field._underlineType} for timestamps, use VARCHAR (with iso strings) or TIMESTAMP/INT (with unix timestamps)`);
|
|
@@ -167,11 +167,9 @@ class PostgresConnector {
|
|
|
167
167
|
return null;
|
|
168
168
|
}
|
|
169
169
|
if (field._underlineType == 'timestamp' || field._underlineType == 'int') {
|
|
170
|
-
|
|
171
|
-
return dayjs(value).unix();
|
|
170
|
+
return dayjs(value);
|
|
172
171
|
}
|
|
173
172
|
else if (field._underlineType == 'varchar') {
|
|
174
|
-
// value is iso string now, convert to unix timestamp
|
|
175
173
|
return dayjs(value).toISOString();
|
|
176
174
|
}
|
|
177
175
|
}
|
package/dist/index.js
CHANGED
|
@@ -24,6 +24,7 @@ import { v1 as uuid } from 'uuid';
|
|
|
24
24
|
import fs from 'fs';
|
|
25
25
|
import { AdminForthFilterOperators, AdminForthTypes } from './types.js';
|
|
26
26
|
const AVAILABLE_SHOW_IN = ['list', 'edit', 'create', 'filter', 'show'];
|
|
27
|
+
const DEFAULT_ALLOWED_ACTIONS = { create: true, edit: true, show: true, delete: true };
|
|
27
28
|
class AdminForth {
|
|
28
29
|
constructor(config) {
|
|
29
30
|
_AdminForth_defaultConfig.set(this, {
|
|
@@ -130,6 +131,9 @@ class AdminForth {
|
|
|
130
131
|
}
|
|
131
132
|
col.showIn = ((_b = col.showIn) === null || _b === void 0 ? void 0 : _b.map(c => c.toLowerCase())) || AVAILABLE_SHOW_IN;
|
|
132
133
|
});
|
|
134
|
+
if (!res.options) {
|
|
135
|
+
res.options = { bulkActions: [], allowedActions: {} };
|
|
136
|
+
}
|
|
133
137
|
//check if resource has bulkActions
|
|
134
138
|
if ((_b = res.options) === null || _b === void 0 ? void 0 : _b.bulkActions) {
|
|
135
139
|
let bulkActions = res.options.bulkActions;
|
|
@@ -155,6 +159,18 @@ class AdminForth {
|
|
|
155
159
|
});
|
|
156
160
|
bulkActions = newBulkActions;
|
|
157
161
|
}
|
|
162
|
+
//add default allowedActions to resources
|
|
163
|
+
if (res.options.allowedActions) {
|
|
164
|
+
//check if allowedActions is an object
|
|
165
|
+
if (typeof res.options.allowedActions !== 'object') {
|
|
166
|
+
errors.push(`Resource "${res.resourceId}" allowedActions must be an object`);
|
|
167
|
+
}
|
|
168
|
+
const userAllowedActions = res.options.allowedActions;
|
|
169
|
+
res.options.allowedActions = Object.assign({}, DEFAULT_ALLOWED_ACTIONS, userAllowedActions);
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
res.options.allowedActions = DEFAULT_ALLOWED_ACTIONS;
|
|
173
|
+
}
|
|
158
174
|
});
|
|
159
175
|
if (!this.config.menu) {
|
|
160
176
|
errors.push('No config.menu defined');
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
{{ `${action.label} (${checkboxes.length})` }}
|
|
43
43
|
</button>
|
|
44
44
|
|
|
45
|
-
<RouterLink
|
|
45
|
+
<RouterLink v-if="allowedActions.create"
|
|
46
46
|
:to="{ name: 'resource-create', params: { resourceId: $route.params.resourceId } }"
|
|
47
47
|
class="flex items-center py-1 px-3 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"
|
|
48
48
|
>
|
|
@@ -217,7 +217,7 @@
|
|
|
217
217
|
<div class="tooltip-arrow" data-popper-arrow></div>
|
|
218
218
|
</div>
|
|
219
219
|
|
|
220
|
-
<RouterLink
|
|
220
|
+
<RouterLink v-if="allowedActions.edit"
|
|
221
221
|
:to="{ name: 'resource-edit', params: { resourceId: $route.params.resourceId, primaryKey: row._primaryKeyValue } }"
|
|
222
222
|
class="font-medium text-blue-600 dark:text-blue-500 hover:underline ms-3"
|
|
223
223
|
:data-tooltip-target="`tooltip-edit-${rowI}`"
|
|
@@ -232,7 +232,7 @@
|
|
|
232
232
|
<div class="tooltip-arrow" data-popper-arrow></div>
|
|
233
233
|
</div>
|
|
234
234
|
|
|
235
|
-
<button v-if="
|
|
235
|
+
<button v-if="allowedActions.delete"
|
|
236
236
|
class="font-medium text-red-600 dark:text-red-500 hover:underline ms-3"
|
|
237
237
|
:data-tooltip-target="`tooltip-delete-${rowI}`"
|
|
238
238
|
@click="showDeleteModal(row)"
|
|
@@ -355,7 +355,8 @@ const fetchStatus = ref({pending: false, error: null, success: false});
|
|
|
355
355
|
const rows = ref(null);
|
|
356
356
|
const totalRows = ref(0);
|
|
357
357
|
const allCheckedActions = ref([]);
|
|
358
|
-
const
|
|
358
|
+
const allowedActions = ref({});
|
|
359
|
+
|
|
359
360
|
|
|
360
361
|
const DEFAULT_PAGE_SIZE = 10;
|
|
361
362
|
|
|
@@ -432,8 +433,8 @@ async function getList() {
|
|
|
432
433
|
});
|
|
433
434
|
totalRows.value = data.total;
|
|
434
435
|
allCheckedActions.value = data.options?.bulkActions || [];
|
|
435
|
-
|
|
436
|
-
|
|
436
|
+
allowedActions.value = data.options?.allowedActions;
|
|
437
|
+
|
|
437
438
|
|
|
438
439
|
setTimeout(() => {
|
|
439
440
|
initFlowbite();
|
package/index.ts
CHANGED
|
@@ -13,6 +13,7 @@ import fs from 'fs';
|
|
|
13
13
|
import { AdminForthFilterOperators, AdminForthTypes, AdminForthTypesValues } from './types.js';
|
|
14
14
|
|
|
15
15
|
const AVAILABLE_SHOW_IN = ['list', 'edit', 'create', 'filter', 'show'];
|
|
16
|
+
const DEFAULT_ALLOWED_ACTIONS = {create: true, edit: true, show: true, delete: true};
|
|
16
17
|
|
|
17
18
|
type AdminForthConfigMenuItem = {
|
|
18
19
|
label: string,
|
|
@@ -24,6 +25,7 @@ type AdminForthConfigMenuItem = {
|
|
|
24
25
|
children?: Array<AdminForthConfigMenuItem>,
|
|
25
26
|
}
|
|
26
27
|
|
|
28
|
+
|
|
27
29
|
type AdminForthResourceColumn = {
|
|
28
30
|
name: string,
|
|
29
31
|
label?: string,
|
|
@@ -67,7 +69,8 @@ type AdminForthResource = {
|
|
|
67
69
|
icon: string,
|
|
68
70
|
action: Function,
|
|
69
71
|
}>,
|
|
70
|
-
|
|
72
|
+
allowedActions?: AllowedActions,
|
|
73
|
+
|
|
71
74
|
},
|
|
72
75
|
}
|
|
73
76
|
|
|
@@ -102,6 +105,13 @@ type AdminForthConfig = {
|
|
|
102
105
|
deleteConfirmation?: boolean,
|
|
103
106
|
}
|
|
104
107
|
|
|
108
|
+
type AllowedActions = {
|
|
109
|
+
create: boolean,
|
|
110
|
+
edit: boolean,
|
|
111
|
+
show: boolean,
|
|
112
|
+
delete: boolean,
|
|
113
|
+
}
|
|
114
|
+
|
|
105
115
|
class AdminForth {
|
|
106
116
|
static Types = AdminForthTypes;
|
|
107
117
|
|
|
@@ -248,6 +258,10 @@ class AdminForth {
|
|
|
248
258
|
col.showIn = col.showIn?.map(c => c.toLowerCase()) || AVAILABLE_SHOW_IN;
|
|
249
259
|
})
|
|
250
260
|
|
|
261
|
+
if (!res.options) {
|
|
262
|
+
res.options = {bulkActions: [], allowedActions: {}};
|
|
263
|
+
}
|
|
264
|
+
|
|
251
265
|
|
|
252
266
|
//check if resource has bulkActions
|
|
253
267
|
if(res.options?.bulkActions){
|
|
@@ -276,7 +290,22 @@ class AdminForth {
|
|
|
276
290
|
});
|
|
277
291
|
bulkActions = newBulkActions;
|
|
278
292
|
}
|
|
279
|
-
|
|
293
|
+
|
|
294
|
+
//add default allowedActions to resources
|
|
295
|
+
if(res.options.allowedActions){
|
|
296
|
+
//check if allowedActions is an object
|
|
297
|
+
if(typeof res.options.allowedActions !== 'object'){
|
|
298
|
+
errors.push(`Resource "${res.resourceId}" allowedActions must be an object`);
|
|
299
|
+
}
|
|
300
|
+
const userAllowedActions = res.options.allowedActions
|
|
301
|
+
res.options.allowedActions = Object.assign({}, DEFAULT_ALLOWED_ACTIONS, userAllowedActions);
|
|
302
|
+
} else {
|
|
303
|
+
res.options.allowedActions = DEFAULT_ALLOWED_ACTIONS;
|
|
304
|
+
}
|
|
305
|
+
})
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
|
|
280
309
|
|
|
281
310
|
if (!this.config.menu) {
|
|
282
311
|
errors.push('No config.menu defined');
|
package/package.json
CHANGED
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
{{ `${action.label} (${checkboxes.length})` }}
|
|
43
43
|
</button>
|
|
44
44
|
|
|
45
|
-
<RouterLink
|
|
45
|
+
<RouterLink v-if="allowedActions.create"
|
|
46
46
|
:to="{ name: 'resource-create', params: { resourceId: $route.params.resourceId } }"
|
|
47
47
|
class="flex items-center py-1 px-3 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"
|
|
48
48
|
>
|
|
@@ -217,7 +217,7 @@
|
|
|
217
217
|
<div class="tooltip-arrow" data-popper-arrow></div>
|
|
218
218
|
</div>
|
|
219
219
|
|
|
220
|
-
<RouterLink
|
|
220
|
+
<RouterLink v-if="allowedActions.edit"
|
|
221
221
|
:to="{ name: 'resource-edit', params: { resourceId: $route.params.resourceId, primaryKey: row._primaryKeyValue } }"
|
|
222
222
|
class="font-medium text-blue-600 dark:text-blue-500 hover:underline ms-3"
|
|
223
223
|
:data-tooltip-target="`tooltip-edit-${rowI}`"
|
|
@@ -232,7 +232,7 @@
|
|
|
232
232
|
<div class="tooltip-arrow" data-popper-arrow></div>
|
|
233
233
|
</div>
|
|
234
234
|
|
|
235
|
-
<button v-if="
|
|
235
|
+
<button v-if="allowedActions.delete"
|
|
236
236
|
class="font-medium text-red-600 dark:text-red-500 hover:underline ms-3"
|
|
237
237
|
:data-tooltip-target="`tooltip-delete-${rowI}`"
|
|
238
238
|
@click="showDeleteModal(row)"
|
|
@@ -355,7 +355,8 @@ const fetchStatus = ref({pending: false, error: null, success: false});
|
|
|
355
355
|
const rows = ref(null);
|
|
356
356
|
const totalRows = ref(0);
|
|
357
357
|
const allCheckedActions = ref([]);
|
|
358
|
-
const
|
|
358
|
+
const allowedActions = ref({});
|
|
359
|
+
|
|
359
360
|
|
|
360
361
|
const DEFAULT_PAGE_SIZE = 10;
|
|
361
362
|
|
|
@@ -432,8 +433,8 @@ async function getList() {
|
|
|
432
433
|
});
|
|
433
434
|
totalRows.value = data.total;
|
|
434
435
|
allCheckedActions.value = data.options?.bulkActions || [];
|
|
435
|
-
|
|
436
|
-
|
|
436
|
+
allowedActions.value = data.options?.allowedActions;
|
|
437
|
+
|
|
437
438
|
|
|
438
439
|
setTimeout(() => {
|
|
439
440
|
initFlowbite();
|