@fishawack/lab-velocity 2.0.0-beta.16 → 2.0.0-beta.18
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/README.md
CHANGED
|
@@ -426,6 +426,7 @@ Structure arrays take objects. The objects require a key only but have other opt
|
|
|
426
426
|
Generally speaking the only different between admin routes tends to do the columns which within a model are shared. Because of this you can use the utility method `columns` to automatically build out the table, description & form fields using the following syntax.
|
|
427
427
|
|
|
428
428
|
```js
|
|
429
|
+
import { Resource } from "@fishawack/lab-velocity";
|
|
429
430
|
import { Checkbox as VelCheckbox } from "@fishawack/lab-velocity";
|
|
430
431
|
|
|
431
432
|
{
|
|
@@ -435,7 +436,7 @@ import { Checkbox as VelCheckbox } from "@fishawack/lab-velocity";
|
|
|
435
436
|
create: ({ $store }) => $store.getters.can("write personas"),
|
|
436
437
|
edit: ({ $store }) => $store.getters.can("write personas"),
|
|
437
438
|
},
|
|
438
|
-
...
|
|
439
|
+
...Resource.columns(
|
|
439
440
|
[
|
|
440
441
|
{
|
|
441
442
|
key: "name",
|
|
@@ -462,35 +463,14 @@ import { Checkbox as VelCheckbox } from "@fishawack/lab-velocity";
|
|
|
462
463
|
initial: ({ model }) =>
|
|
463
464
|
model?.nested.id ?? null,
|
|
464
465
|
},
|
|
466
|
+
{
|
|
467
|
+
key: "client_id",
|
|
468
|
+
label: "Client id",
|
|
469
|
+
filter: {
|
|
470
|
+
form: true
|
|
471
|
+
}
|
|
472
|
+
}
|
|
465
473
|
]
|
|
466
474
|
),
|
|
467
475
|
},
|
|
468
476
|
```
|
|
469
|
-
|
|
470
|
-
The columns also takes an optional array as second parameter which defines which values to display on the table view.
|
|
471
|
-
|
|
472
|
-
```js
|
|
473
|
-
import { Checkbox as VelCheckbox } from "@fishawack/lab-velocity";
|
|
474
|
-
|
|
475
|
-
const columns [
|
|
476
|
-
{
|
|
477
|
-
key: "id"
|
|
478
|
-
},
|
|
479
|
-
{
|
|
480
|
-
key: "name"
|
|
481
|
-
},
|
|
482
|
-
{
|
|
483
|
-
key: "description"
|
|
484
|
-
}
|
|
485
|
-
];
|
|
486
|
-
|
|
487
|
-
{
|
|
488
|
-
api: `/api/posts`,
|
|
489
|
-
icon: `icon-visibility`,
|
|
490
|
-
permissions: {
|
|
491
|
-
create: ({ $store }) => $store.getters.can("write personas"),
|
|
492
|
-
edit: ({ $store }) => $store.getters.can("write personas"),
|
|
493
|
-
},
|
|
494
|
-
...resourceColumns(columns, ["id", "name"]),
|
|
495
|
-
},
|
|
496
|
-
```
|
|
@@ -19,25 +19,6 @@
|
|
|
19
19
|
>
|
|
20
20
|
<component :is="render(this)" />
|
|
21
21
|
</template>
|
|
22
|
-
<VelButton
|
|
23
|
-
v-if="resource.permissions.edit(this)"
|
|
24
|
-
tag="a"
|
|
25
|
-
type="primary"
|
|
26
|
-
@click="
|
|
27
|
-
$router.push({
|
|
28
|
-
name: `${resource.name}.edit`,
|
|
29
|
-
param: model.id,
|
|
30
|
-
})
|
|
31
|
-
"
|
|
32
|
-
>
|
|
33
|
-
<GIcon
|
|
34
|
-
class="fill-0 mr-0.5 icon--0.5"
|
|
35
|
-
name="icon-edit"
|
|
36
|
-
embed
|
|
37
|
-
artboard
|
|
38
|
-
/>
|
|
39
|
-
Edit {{ resource.singular }}
|
|
40
|
-
</VelButton>
|
|
41
22
|
</VelPageHeader>
|
|
42
23
|
|
|
43
24
|
<hr class="my-3 hr-muted" />
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import { merge } from "lodash";
|
|
4
|
-
|
|
5
|
-
import { h } from "vue";
|
|
4
|
+
import axios from "axios";
|
|
5
|
+
import { h, resolveComponent } from "vue";
|
|
6
6
|
|
|
7
7
|
import VTableSorter from "../../components/layout/TableSorter.vue";
|
|
8
|
-
import { ElDescriptions, ElDescriptionsItem } from "element-plus";
|
|
8
|
+
import { ElDescriptions, ElDescriptionsItem, ElPopconfirm } from "element-plus";
|
|
9
|
+
import VelButton from "../../components/basic/Button.vue";
|
|
9
10
|
|
|
10
11
|
export const defaultResource = meta();
|
|
11
12
|
|
|
@@ -24,6 +25,7 @@ export function meta(name = "default", properties = {}) {
|
|
|
24
25
|
permissions: {
|
|
25
26
|
create: () => true,
|
|
26
27
|
edit: () => true,
|
|
28
|
+
delete: () => false,
|
|
27
29
|
},
|
|
28
30
|
searchable: {
|
|
29
31
|
value: "name",
|
|
@@ -69,7 +71,79 @@ export function meta(name = "default", properties = {}) {
|
|
|
69
71
|
],
|
|
70
72
|
},
|
|
71
73
|
show: {
|
|
72
|
-
actions: [
|
|
74
|
+
actions: [
|
|
75
|
+
(props) => {
|
|
76
|
+
const { resource, model, $router } = props;
|
|
77
|
+
|
|
78
|
+
if (resource.permissions.edit(props)) {
|
|
79
|
+
return h(
|
|
80
|
+
VelButton,
|
|
81
|
+
{
|
|
82
|
+
tag: "a",
|
|
83
|
+
type: "primary",
|
|
84
|
+
onClick: () => {
|
|
85
|
+
$router.push({
|
|
86
|
+
name: `${resource.name}.edit`,
|
|
87
|
+
params: { id: model.id },
|
|
88
|
+
});
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
() => [
|
|
92
|
+
h(resolveComponent("GIcon"), {
|
|
93
|
+
class: "fill-0 mr-0.5 icon--0.5",
|
|
94
|
+
name: "icon-edit",
|
|
95
|
+
embed: true,
|
|
96
|
+
artboard: true,
|
|
97
|
+
}),
|
|
98
|
+
`Edit ${resource.singular}`,
|
|
99
|
+
],
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
(props) => {
|
|
104
|
+
const { resource, model, $router } = props;
|
|
105
|
+
|
|
106
|
+
if (resource.permissions.delete(props)) {
|
|
107
|
+
return h(
|
|
108
|
+
ElPopconfirm,
|
|
109
|
+
{
|
|
110
|
+
title: `Are you sure you want to delete this ${resource.singular}?`,
|
|
111
|
+
confirmButtonText: "Delete",
|
|
112
|
+
cancelButtonText: "Cancel",
|
|
113
|
+
confirmButtonType: "danger",
|
|
114
|
+
onConfirm: async () => {
|
|
115
|
+
await axios.delete(
|
|
116
|
+
`${resource.api}/${model.id}`,
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
$router.push({
|
|
120
|
+
name: `${resource.name}.index`,
|
|
121
|
+
});
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
reference: () =>
|
|
126
|
+
h(
|
|
127
|
+
VelButton,
|
|
128
|
+
{
|
|
129
|
+
tag: "a",
|
|
130
|
+
type: "danger",
|
|
131
|
+
},
|
|
132
|
+
() => [
|
|
133
|
+
h(resolveComponent("GIcon"), {
|
|
134
|
+
class: "fill-0 mr-0.5 icon--0.5",
|
|
135
|
+
name: "icon-trash",
|
|
136
|
+
embed: true,
|
|
137
|
+
artboard: true,
|
|
138
|
+
}),
|
|
139
|
+
`Delete ${resource.singular}`,
|
|
140
|
+
],
|
|
141
|
+
),
|
|
142
|
+
},
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
],
|
|
73
147
|
layout: [
|
|
74
148
|
(props) => {
|
|
75
149
|
const { resource, model } = props;
|
|
@@ -80,25 +154,28 @@ export function meta(name = "default", properties = {}) {
|
|
|
80
154
|
border: true,
|
|
81
155
|
column: 1,
|
|
82
156
|
},
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
157
|
+
() =>
|
|
158
|
+
resource.description.structure.map(
|
|
159
|
+
(item, index) =>
|
|
160
|
+
h(
|
|
161
|
+
ElDescriptionsItem,
|
|
162
|
+
{
|
|
163
|
+
key: index,
|
|
164
|
+
labelWidth: "20%",
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
label: () =>
|
|
168
|
+
item.label ||
|
|
169
|
+
item.key[0].toUpperCase() +
|
|
170
|
+
item.key.slice(1),
|
|
171
|
+
default: () =>
|
|
172
|
+
item.render
|
|
173
|
+
? h(item.render(props))
|
|
174
|
+
: model?.[item.key] ||
|
|
175
|
+
"",
|
|
176
|
+
},
|
|
177
|
+
),
|
|
100
178
|
),
|
|
101
|
-
),
|
|
102
179
|
);
|
|
103
180
|
},
|
|
104
181
|
],
|
|
@@ -110,46 +187,57 @@ export function meta(name = "default", properties = {}) {
|
|
|
110
187
|
);
|
|
111
188
|
}
|
|
112
189
|
|
|
113
|
-
export function columns(columns =
|
|
190
|
+
export function columns(columns = []) {
|
|
114
191
|
return {
|
|
115
192
|
table: {
|
|
116
193
|
structure: columns
|
|
117
|
-
.filter((column) =>
|
|
194
|
+
.filter((column) => !column.filter?.table)
|
|
118
195
|
.map((column) => ({
|
|
119
196
|
...column,
|
|
120
|
-
render: column.render?.read,
|
|
197
|
+
render: column.render?.read || column.render?.table,
|
|
121
198
|
})),
|
|
122
199
|
},
|
|
123
200
|
description: {
|
|
124
|
-
structure: columns
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
201
|
+
structure: columns
|
|
202
|
+
.filter((column) => !column.filter?.description)
|
|
203
|
+
.map((column) => ({
|
|
204
|
+
...column,
|
|
205
|
+
render: column.render?.read || column.render?.description,
|
|
206
|
+
})),
|
|
128
207
|
},
|
|
129
208
|
form: {
|
|
130
209
|
fields: (props) =>
|
|
131
|
-
columns
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
210
|
+
columns
|
|
211
|
+
.filter((column) => !column.filter?.form)
|
|
212
|
+
.reduce((fields, column) => {
|
|
213
|
+
fields[column.key] = column.initial
|
|
214
|
+
? column.initial(props)
|
|
215
|
+
: (props.model?.[column.key] ?? null);
|
|
216
|
+
return fields;
|
|
217
|
+
}, {}),
|
|
218
|
+
structure: columns
|
|
219
|
+
.filter((column) => !column.filter?.form)
|
|
220
|
+
.map((column) => ({
|
|
221
|
+
...column,
|
|
222
|
+
render: column.render?.write || column.render?.form,
|
|
223
|
+
})),
|
|
141
224
|
},
|
|
142
225
|
};
|
|
143
226
|
}
|
|
144
227
|
|
|
145
228
|
// Export resource
|
|
146
229
|
export function routes(node, name, properties = {}) {
|
|
230
|
+
const resource = meta(name, properties);
|
|
231
|
+
|
|
147
232
|
return [
|
|
148
233
|
{
|
|
149
234
|
path: `/${name}`,
|
|
150
235
|
component: node ? "" : require("../resource/parent.vue").default,
|
|
236
|
+
name,
|
|
151
237
|
meta: {
|
|
152
|
-
resource
|
|
238
|
+
resource,
|
|
239
|
+
title: resource.title,
|
|
240
|
+
icon: resource.icon,
|
|
153
241
|
},
|
|
154
242
|
children: [
|
|
155
243
|
{
|
|
@@ -188,4 +276,5 @@ export function routes(node, name, properties = {}) {
|
|
|
188
276
|
export default {
|
|
189
277
|
routes,
|
|
190
278
|
meta,
|
|
279
|
+
columns,
|
|
191
280
|
};
|