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.unix(+value).toISOString();
129
+ return dayjs(value).toISOString();
130
130
  } else if (field._underlineType == 'varchar') {
131
- return dayjs.unix(+value).toISOString();
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
- // value is iso string now, convert to unix timestamp
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.unix(+value).toISOString();
130
+ return dayjs(value).toISOString();
131
131
  }
132
132
  else if (field._underlineType == 'varchar') {
133
- return dayjs.unix(+value).toISOString();
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
- // value is iso string now, convert to unix timestamp
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="allowDelete"
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 allowDelete = ref(false);
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
- allowDelete.value = data.options?.allowDelete;
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
- allowDelete?: boolean,
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adminforth",
3
- "version": "1.0.26",
3
+ "version": "1.0.27",
4
4
  "description": "OpenSource Vue3 powered forth-generation admin panel",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -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="allowDelete"
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 allowDelete = ref(false);
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
- allowDelete.value = data.options?.allowDelete;
436
-
436
+ allowedActions.value = data.options?.allowedActions;
437
+
437
438
 
438
439
  setTimeout(() => {
439
440
  initFlowbite();