@fishawack/lab-velocity 2.0.0-beta.27 → 2.0.0-beta.28
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 +2 -0
- package/_Build/vue/modules/AuthModule/js/router.js +8 -0
- package/_Build/vue/modules/AuthModule/routes/PCompanies/resource.js +85 -31
- package/_Build/vue/modules/AuthModule/routes/PTeams/resource.js +258 -0
- package/_Build/vue/modules/AuthModule/routes/PUsers/resource.js +6 -4
- package/_Build/vue/modules/resource/Children/edit.vue +1 -1
- package/_Build/vue/modules/resource/Children/show.vue +46 -13
- package/_Build/vue/modules/resource/index.js +40 -32
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -187,6 +187,8 @@ There are two different set of sass imports for the admin and the frontend route
|
|
|
187
187
|
@import "@fishawack/lab-velocity/components/sidebar";
|
|
188
188
|
@import "@fishawack/lab-velocity/components/menu";
|
|
189
189
|
@import "@fishawack/lab-velocity/components/layout";
|
|
190
|
+
@import "element-plus/theme-chalk/el-tabs";
|
|
191
|
+
@import "element-plus/theme-chalk/el-tab-pane";
|
|
190
192
|
```
|
|
191
193
|
|
|
192
194
|
Lastly for the admin layout & navigation import & apply the Layout component to the app.vue within your project.
|
|
@@ -9,12 +9,14 @@ import { routes as resourceRoutes } from "../../resource/index.js";
|
|
|
9
9
|
|
|
10
10
|
import userResource from "../routes/PUsers/resource.js";
|
|
11
11
|
import companyResource from "../routes/PCompanies/resource.js";
|
|
12
|
+
import teamResource from "../routes/PTeams/resource.js";
|
|
12
13
|
|
|
13
14
|
// Admin routes export - minimal auth flow (headless login only)
|
|
14
15
|
export function adminRoutes(node, overrides = {}) {
|
|
15
16
|
const {
|
|
16
17
|
userResource: overrideUserResource = {},
|
|
17
18
|
companyResource: overrideCompanyResource = {},
|
|
19
|
+
teamResource: overrideTeamResource = {},
|
|
18
20
|
} = overrides;
|
|
19
21
|
|
|
20
22
|
return [
|
|
@@ -58,6 +60,12 @@ export function adminRoutes(node, overrides = {}) {
|
|
|
58
60
|
...resourceRoutes(
|
|
59
61
|
node,
|
|
60
62
|
...merge(companyResource, [undefined, overrideCompanyResource]),
|
|
63
|
+
[
|
|
64
|
+
...resourceRoutes(
|
|
65
|
+
node,
|
|
66
|
+
...merge(teamResource, [undefined, overrideTeamResource]),
|
|
67
|
+
),
|
|
68
|
+
],
|
|
61
69
|
),
|
|
62
70
|
];
|
|
63
71
|
}
|
|
@@ -6,6 +6,7 @@ import VelTableSorter from "../../../../components/layout/TableSorter.vue";
|
|
|
6
6
|
import VelRoleLegend from "../../../../components/layout/RoleLegend.vue";
|
|
7
7
|
import component from "./form.vue";
|
|
8
8
|
import userResource from "../PUsers/resource.js";
|
|
9
|
+
import teamResource from "../PTeams/resource.js";
|
|
9
10
|
import { defaultResource, meta } from "../../../resource/index.js";
|
|
10
11
|
|
|
11
12
|
import { ElNotification } from "element-plus";
|
|
@@ -17,7 +18,7 @@ export default [
|
|
|
17
18
|
{
|
|
18
19
|
api: {
|
|
19
20
|
params: {
|
|
20
|
-
show: { include: "primary_contact" },
|
|
21
|
+
show: () => ({ include: "primary_contact" }),
|
|
21
22
|
},
|
|
22
23
|
},
|
|
23
24
|
permissions: {
|
|
@@ -151,53 +152,106 @@ export default [
|
|
|
151
152
|
],
|
|
152
153
|
layout: [
|
|
153
154
|
...defaultResource.show.layout,
|
|
154
|
-
({ model }) =>
|
|
155
|
-
|
|
155
|
+
({ model }) => ({
|
|
156
|
+
label: "Access control",
|
|
157
|
+
component: h(VelFormRole, {
|
|
156
158
|
overrides: model.overrides_roles_and_permissions,
|
|
157
159
|
form: { roles: model.roles.map((d) => d.id) },
|
|
158
160
|
readonly: true,
|
|
159
161
|
}),
|
|
160
|
-
|
|
162
|
+
}),
|
|
163
|
+
({ model, $store, $router, $route, ...rest }) => {
|
|
164
|
+
const resource = meta(...teamResource);
|
|
165
|
+
|
|
166
|
+
const props = {
|
|
167
|
+
model,
|
|
168
|
+
$store,
|
|
169
|
+
$router,
|
|
170
|
+
$route,
|
|
171
|
+
...rest,
|
|
172
|
+
resource,
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
return {
|
|
176
|
+
label: "Teams",
|
|
177
|
+
component: h("div", [
|
|
178
|
+
h("div", { class: "flex justify-end items-end" }, [
|
|
179
|
+
resource.permissions.create(props) &&
|
|
180
|
+
h(
|
|
181
|
+
VelButton,
|
|
182
|
+
{
|
|
183
|
+
tag: "a",
|
|
184
|
+
type: "primary",
|
|
185
|
+
size: "large",
|
|
186
|
+
onClick: () => {
|
|
187
|
+
$router.push({
|
|
188
|
+
name: `${resource.slug}.create`,
|
|
189
|
+
});
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
() => [
|
|
193
|
+
h(resolveComponent("GIcon"), {
|
|
194
|
+
class: "fill-0 mr-0.5 icon--0.5",
|
|
195
|
+
name: "icon-plus",
|
|
196
|
+
embed: true,
|
|
197
|
+
artboard: true,
|
|
198
|
+
}),
|
|
199
|
+
`Create ${resource.singular}`,
|
|
200
|
+
],
|
|
201
|
+
),
|
|
202
|
+
]),
|
|
203
|
+
h(VelTableSorter, resource.index.structure(props)),
|
|
204
|
+
]),
|
|
205
|
+
};
|
|
206
|
+
},
|
|
207
|
+
({ model, $store, $router, $route, ...rest }) => {
|
|
161
208
|
const resource = meta(...userResource);
|
|
162
209
|
|
|
163
|
-
resource.api.params.index
|
|
210
|
+
resource.api.params.index = ({ $route }) => ({
|
|
211
|
+
include: "company",
|
|
212
|
+
"filter[company_id]": $route.params.companiesId,
|
|
213
|
+
});
|
|
164
214
|
|
|
165
215
|
const props = {
|
|
166
216
|
model,
|
|
167
217
|
$store,
|
|
168
218
|
$router,
|
|
219
|
+
$route,
|
|
169
220
|
...rest,
|
|
170
221
|
resource,
|
|
171
222
|
};
|
|
172
223
|
|
|
173
|
-
return
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
224
|
+
return {
|
|
225
|
+
label: "Users",
|
|
226
|
+
component: h("div", [
|
|
227
|
+
h("div", { class: "flex justify-end items-end" }, [
|
|
228
|
+
resource.permissions.create(props) &&
|
|
229
|
+
h(
|
|
230
|
+
VelButton,
|
|
231
|
+
{
|
|
232
|
+
tag: "a",
|
|
233
|
+
type: "primary",
|
|
234
|
+
size: "large",
|
|
235
|
+
onClick: () => {
|
|
236
|
+
$router.push({
|
|
237
|
+
name: `${resource.slug}.create`,
|
|
238
|
+
});
|
|
239
|
+
},
|
|
186
240
|
},
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
241
|
+
() => [
|
|
242
|
+
h(resolveComponent("GIcon"), {
|
|
243
|
+
class: "fill-0 mr-0.5 icon--0.5",
|
|
244
|
+
name: "icon-plus",
|
|
245
|
+
embed: true,
|
|
246
|
+
artboard: true,
|
|
247
|
+
}),
|
|
248
|
+
`Create ${resource.singular}`,
|
|
249
|
+
],
|
|
250
|
+
),
|
|
251
|
+
]),
|
|
252
|
+
h(VelTableSorter, resource.index.structure(props)),
|
|
198
253
|
]),
|
|
199
|
-
|
|
200
|
-
]);
|
|
254
|
+
};
|
|
201
255
|
},
|
|
202
256
|
],
|
|
203
257
|
},
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import { merge } from "lodash";
|
|
2
|
+
import { h, resolveComponent } from "vue";
|
|
3
|
+
import axios from "axios";
|
|
4
|
+
import { throttle } from "lodash";
|
|
5
|
+
|
|
6
|
+
import { columns } from "../../../resource/index.js";
|
|
7
|
+
import userResource from "../PUsers/resource.js";
|
|
8
|
+
import { defaultResource, meta } from "../../../resource/index.js";
|
|
9
|
+
|
|
10
|
+
import VelTableSorter from "../../../../components/layout/TableSorter.vue";
|
|
11
|
+
import VelButton from "../../../../components/basic/Button.vue";
|
|
12
|
+
import VelCheckbox from "../../../../components/form/Checkbox.vue";
|
|
13
|
+
|
|
14
|
+
export default [
|
|
15
|
+
"teams",
|
|
16
|
+
{
|
|
17
|
+
icon: `icon-account-circle`,
|
|
18
|
+
api: {
|
|
19
|
+
params: {
|
|
20
|
+
index: ({ $route }) => ({
|
|
21
|
+
include: "company",
|
|
22
|
+
"filter[company_id]": $route.params.companiesId,
|
|
23
|
+
}),
|
|
24
|
+
show: () => ({
|
|
25
|
+
include: "company",
|
|
26
|
+
}),
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
permissions: {
|
|
30
|
+
create: ({ $store }) => $store.getters.can("write teams"),
|
|
31
|
+
edit: ({ $store }) => $store.getters.can("write teams"),
|
|
32
|
+
delete: ({ $store }) => $store.getters.can("delete teams"),
|
|
33
|
+
},
|
|
34
|
+
...merge(
|
|
35
|
+
columns([
|
|
36
|
+
{
|
|
37
|
+
key: "name",
|
|
38
|
+
sortable: true,
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
key: "description",
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
key: "company_id",
|
|
45
|
+
label: "Company",
|
|
46
|
+
class: "hidden",
|
|
47
|
+
render: {
|
|
48
|
+
read: ({ model }) => h("span", model.company.name),
|
|
49
|
+
},
|
|
50
|
+
initial: ({ $route, model }) =>
|
|
51
|
+
model?.company_id || $route.params.companiesId || null,
|
|
52
|
+
},
|
|
53
|
+
]),
|
|
54
|
+
{
|
|
55
|
+
show: {
|
|
56
|
+
layout: [
|
|
57
|
+
...defaultResource.show.layout,
|
|
58
|
+
(props) => {
|
|
59
|
+
const { model, $store, $router, $route, ...rest } =
|
|
60
|
+
props;
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
label: "Members",
|
|
64
|
+
component: h({
|
|
65
|
+
data: () => ({
|
|
66
|
+
scoped: true,
|
|
67
|
+
}),
|
|
68
|
+
mounted() {
|
|
69
|
+
this.emitter.on("reload-teams", () => {
|
|
70
|
+
this.reload();
|
|
71
|
+
});
|
|
72
|
+
},
|
|
73
|
+
beforeUnmount() {
|
|
74
|
+
this.emitter.off("reload-teams");
|
|
75
|
+
},
|
|
76
|
+
methods: {
|
|
77
|
+
reload: throttle(function () {
|
|
78
|
+
this.$refs.members.reload();
|
|
79
|
+
this.$refs.users.reload();
|
|
80
|
+
}, 1000),
|
|
81
|
+
},
|
|
82
|
+
render() {
|
|
83
|
+
return h("div", [
|
|
84
|
+
h("h3", "Members"),
|
|
85
|
+
(() => {
|
|
86
|
+
const resource = meta(
|
|
87
|
+
...userResource,
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
resource.api.params.index = ({
|
|
91
|
+
$route,
|
|
92
|
+
}) => ({
|
|
93
|
+
include: "company",
|
|
94
|
+
"filter[teams.id]":
|
|
95
|
+
$route.params.teamsId,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
resource.table.actions = [
|
|
99
|
+
({ model }) =>
|
|
100
|
+
h({
|
|
101
|
+
data: () => ({
|
|
102
|
+
loading: false,
|
|
103
|
+
}),
|
|
104
|
+
render() {
|
|
105
|
+
return h(
|
|
106
|
+
VelButton,
|
|
107
|
+
{
|
|
108
|
+
tag: "a",
|
|
109
|
+
size: "small",
|
|
110
|
+
type: "warning",
|
|
111
|
+
loading:
|
|
112
|
+
this
|
|
113
|
+
.loading,
|
|
114
|
+
onClick:
|
|
115
|
+
async () => {
|
|
116
|
+
this.loading = true;
|
|
117
|
+
|
|
118
|
+
await axios.delete(
|
|
119
|
+
`api/teams/${$route.params.teamsId}/users/${model.id}`,
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
this.emitter.emit(
|
|
123
|
+
"reload-teams",
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
this.loading = false;
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
"Remove",
|
|
130
|
+
);
|
|
131
|
+
},
|
|
132
|
+
}),
|
|
133
|
+
];
|
|
134
|
+
|
|
135
|
+
const props = {
|
|
136
|
+
model,
|
|
137
|
+
$store,
|
|
138
|
+
$router,
|
|
139
|
+
$route,
|
|
140
|
+
...rest,
|
|
141
|
+
resource,
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
return h(
|
|
145
|
+
VelTableSorter,
|
|
146
|
+
merge(
|
|
147
|
+
resource.index.structure(
|
|
148
|
+
props,
|
|
149
|
+
),
|
|
150
|
+
{
|
|
151
|
+
ref: "members",
|
|
152
|
+
},
|
|
153
|
+
),
|
|
154
|
+
);
|
|
155
|
+
})(),
|
|
156
|
+
h("h3", "Users"),
|
|
157
|
+
h(VelCheckbox, {
|
|
158
|
+
label: "Only show users from this company",
|
|
159
|
+
class: "mt-2",
|
|
160
|
+
modelValue: this.scoped,
|
|
161
|
+
"onUpdate:modelValue": (
|
|
162
|
+
value,
|
|
163
|
+
) => {
|
|
164
|
+
this.scoped = value;
|
|
165
|
+
this.$nextTick(() => {
|
|
166
|
+
this.$refs.users.reload();
|
|
167
|
+
});
|
|
168
|
+
},
|
|
169
|
+
}),
|
|
170
|
+
(() => {
|
|
171
|
+
const resource = meta(
|
|
172
|
+
...userResource,
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
resource.api.params.index = ({
|
|
176
|
+
$route,
|
|
177
|
+
}) => ({
|
|
178
|
+
include: "company",
|
|
179
|
+
"filter[company_id]": this
|
|
180
|
+
.scoped
|
|
181
|
+
? $route.params
|
|
182
|
+
.companiesId
|
|
183
|
+
: null,
|
|
184
|
+
"filter[teams.id]": `!${$route.params.teamsId}`,
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
resource.table.actions = [
|
|
188
|
+
({ model }) =>
|
|
189
|
+
h({
|
|
190
|
+
data: () => ({
|
|
191
|
+
loading: false,
|
|
192
|
+
}),
|
|
193
|
+
render() {
|
|
194
|
+
return h(
|
|
195
|
+
VelButton,
|
|
196
|
+
{
|
|
197
|
+
tag: "a",
|
|
198
|
+
size: "small",
|
|
199
|
+
type: "primary",
|
|
200
|
+
loading:
|
|
201
|
+
this
|
|
202
|
+
.loading,
|
|
203
|
+
onClick:
|
|
204
|
+
async () => {
|
|
205
|
+
this.loading = true;
|
|
206
|
+
|
|
207
|
+
await axios.post(
|
|
208
|
+
`api/teams/${$route.params.teamsId}/users`,
|
|
209
|
+
{
|
|
210
|
+
id: model.id,
|
|
211
|
+
},
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
this.emitter.emit(
|
|
215
|
+
"reload-teams",
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
this.loading = false;
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
"Add",
|
|
222
|
+
);
|
|
223
|
+
},
|
|
224
|
+
}),
|
|
225
|
+
];
|
|
226
|
+
|
|
227
|
+
const props = {
|
|
228
|
+
model,
|
|
229
|
+
$store,
|
|
230
|
+
$router,
|
|
231
|
+
$route,
|
|
232
|
+
...rest,
|
|
233
|
+
resource,
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
return h(
|
|
237
|
+
VelTableSorter,
|
|
238
|
+
merge(
|
|
239
|
+
resource.index.structure(
|
|
240
|
+
props,
|
|
241
|
+
),
|
|
242
|
+
{
|
|
243
|
+
ref: "users",
|
|
244
|
+
},
|
|
245
|
+
),
|
|
246
|
+
);
|
|
247
|
+
})(),
|
|
248
|
+
]);
|
|
249
|
+
},
|
|
250
|
+
}),
|
|
251
|
+
};
|
|
252
|
+
},
|
|
253
|
+
],
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
),
|
|
257
|
+
},
|
|
258
|
+
];
|
|
@@ -26,8 +26,8 @@ export default [
|
|
|
26
26
|
{
|
|
27
27
|
api: {
|
|
28
28
|
params: {
|
|
29
|
-
index: { include: "company" },
|
|
30
|
-
show: { include: "company" },
|
|
29
|
+
index: () => ({ include: "company" }),
|
|
30
|
+
show: () => ({ include: "company" }),
|
|
31
31
|
},
|
|
32
32
|
},
|
|
33
33
|
searchable: {
|
|
@@ -201,12 +201,14 @@ export default [
|
|
|
201
201
|
show: {
|
|
202
202
|
layout: [
|
|
203
203
|
...defaultResource.show.layout,
|
|
204
|
-
({ model }) =>
|
|
205
|
-
|
|
204
|
+
({ model }) => ({
|
|
205
|
+
label: "Access control",
|
|
206
|
+
component: h(VelFormRole, {
|
|
206
207
|
overrides: model.overrides_roles_and_permissions,
|
|
207
208
|
form: { roles: model.roles.map((d) => d.id) },
|
|
208
209
|
readonly: true,
|
|
209
210
|
}),
|
|
211
|
+
}),
|
|
210
212
|
],
|
|
211
213
|
},
|
|
212
214
|
},
|
|
@@ -14,23 +14,42 @@
|
|
|
14
14
|
:title="`${model.name ?? model.id} ${model.last_name ?? ''}`"
|
|
15
15
|
>
|
|
16
16
|
<template
|
|
17
|
-
v-for="(
|
|
17
|
+
v-for="(rendered, index) in renderedActions"
|
|
18
18
|
:key="index"
|
|
19
19
|
>
|
|
20
|
-
<component :is="
|
|
20
|
+
<component :is="rendered" />
|
|
21
21
|
</template>
|
|
22
22
|
</VelPageHeader>
|
|
23
|
+
|
|
23
24
|
<hr class="my-3 hr-muted" />
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
25
|
+
|
|
26
|
+
<el-tabs v-model="active" type="card">
|
|
27
|
+
<template
|
|
28
|
+
v-for="(rendered, index) in renderedLayout"
|
|
29
|
+
:key="index"
|
|
30
|
+
>
|
|
31
|
+
<el-tab-pane :name="index">
|
|
32
|
+
<template #label>
|
|
33
|
+
<span class="align-middle-dive">
|
|
34
|
+
<GIcon
|
|
35
|
+
v-if="rendered.icon"
|
|
36
|
+
class="icon icon--0.5 mr-0.5"
|
|
37
|
+
:name="rendered.icon"
|
|
38
|
+
asis
|
|
39
|
+
embed
|
|
40
|
+
/>
|
|
41
|
+
<span>{{
|
|
42
|
+
rendered.label ||
|
|
43
|
+
`Tab ${index + 1}`
|
|
44
|
+
}}</span>
|
|
45
|
+
</span>
|
|
46
|
+
</template>
|
|
47
|
+
<component
|
|
48
|
+
:is="rendered.component || rendered"
|
|
49
|
+
/>
|
|
50
|
+
</el-tab-pane>
|
|
51
|
+
</template>
|
|
52
|
+
</el-tabs>
|
|
34
53
|
</div>
|
|
35
54
|
</template>
|
|
36
55
|
<div v-else class="absolute transform-center text-center">
|
|
@@ -45,6 +64,7 @@
|
|
|
45
64
|
import axios from "axios";
|
|
46
65
|
import VelSpinner from "../../../components/form/Spinner.vue";
|
|
47
66
|
import VelButton from "../../../components/basic/Button.vue";
|
|
67
|
+
import { ElTabs, ElTabPane } from "element-plus";
|
|
48
68
|
|
|
49
69
|
export default {
|
|
50
70
|
components: {
|
|
@@ -52,6 +72,8 @@ export default {
|
|
|
52
72
|
.default,
|
|
53
73
|
VelSpinner,
|
|
54
74
|
VelButton,
|
|
75
|
+
ElTabs,
|
|
76
|
+
ElTabPane,
|
|
55
77
|
},
|
|
56
78
|
|
|
57
79
|
props: {
|
|
@@ -72,6 +94,7 @@ export default {
|
|
|
72
94
|
data() {
|
|
73
95
|
return {
|
|
74
96
|
model: null,
|
|
97
|
+
active: 0,
|
|
75
98
|
};
|
|
76
99
|
},
|
|
77
100
|
|
|
@@ -80,6 +103,16 @@ export default {
|
|
|
80
103
|
deepestRoute() {
|
|
81
104
|
return this.depth === this.$route.matched.length;
|
|
82
105
|
},
|
|
106
|
+
|
|
107
|
+
// Compute rendered layout once
|
|
108
|
+
renderedLayout() {
|
|
109
|
+
return this.resource.show.layout.map((render) => render(this));
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
// Compute rendered actions once
|
|
113
|
+
renderedActions() {
|
|
114
|
+
return this.resource.show.actions.map((render) => render(this));
|
|
115
|
+
},
|
|
83
116
|
},
|
|
84
117
|
|
|
85
118
|
mounted() {
|
|
@@ -91,7 +124,7 @@ export default {
|
|
|
91
124
|
.get(
|
|
92
125
|
`${this.resource.api.endpoint(this)}/${this.$route.params[`${this.resource.slug}Id`]}`,
|
|
93
126
|
{
|
|
94
|
-
params: this.resource.api.params.show,
|
|
127
|
+
params: this.resource.api.params.show(this),
|
|
95
128
|
},
|
|
96
129
|
)
|
|
97
130
|
.then((res) => {
|
|
@@ -35,8 +35,8 @@ export function meta(name = "default", properties = {}) {
|
|
|
35
35
|
api: {
|
|
36
36
|
endpoint: () => `/api/${properties.slug || kebabCase(name)}`,
|
|
37
37
|
params: {
|
|
38
|
-
index: {},
|
|
39
|
-
show: {},
|
|
38
|
+
index: () => ({}),
|
|
39
|
+
show: () => ({}),
|
|
40
40
|
},
|
|
41
41
|
},
|
|
42
42
|
permissions: {
|
|
@@ -197,7 +197,7 @@ export function meta(name = "default", properties = {}) {
|
|
|
197
197
|
),
|
|
198
198
|
api: resource.api.endpoint(props),
|
|
199
199
|
},
|
|
200
|
-
apiParams: resource.api.params.index,
|
|
200
|
+
apiParams: resource.api.params.index(props),
|
|
201
201
|
idKey: resource.id,
|
|
202
202
|
"fixed-height": false,
|
|
203
203
|
displayActions: false,
|
|
@@ -324,35 +324,43 @@ export function meta(name = "default", properties = {}) {
|
|
|
324
324
|
(props) => {
|
|
325
325
|
const { resource, model } = props;
|
|
326
326
|
|
|
327
|
-
return
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
item.
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
327
|
+
return {
|
|
328
|
+
label: "Details",
|
|
329
|
+
component: h(
|
|
330
|
+
ElDescriptions,
|
|
331
|
+
{
|
|
332
|
+
border: true,
|
|
333
|
+
column: 1,
|
|
334
|
+
},
|
|
335
|
+
() =>
|
|
336
|
+
resource.description.structure.map(
|
|
337
|
+
(item, index) =>
|
|
338
|
+
h(
|
|
339
|
+
ElDescriptionsItem,
|
|
340
|
+
{
|
|
341
|
+
key: index,
|
|
342
|
+
labelWidth: "20%",
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
label: () =>
|
|
346
|
+
item.label ||
|
|
347
|
+
item.key[0].toUpperCase() +
|
|
348
|
+
item.key.slice(1),
|
|
349
|
+
default: () =>
|
|
350
|
+
item.render
|
|
351
|
+
? h(
|
|
352
|
+
item.render(
|
|
353
|
+
props,
|
|
354
|
+
),
|
|
355
|
+
)
|
|
356
|
+
: model?.[
|
|
357
|
+
item.key
|
|
358
|
+
] || "",
|
|
359
|
+
},
|
|
360
|
+
),
|
|
361
|
+
),
|
|
362
|
+
),
|
|
363
|
+
};
|
|
356
364
|
},
|
|
357
365
|
],
|
|
358
366
|
},
|