@fishawack/lab-velocity 2.0.0-beta.22 → 2.0.0-beta.24
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/_Build/vue/components/layout/TableSorter.vue +6 -2
- package/_Build/vue/modules/AuthModule/routes/PCompanies/resource.js +2 -0
- package/_Build/vue/modules/AuthModule/routes/PUsers/resource.js +14 -8
- package/_Build/vue/modules/resource/Children/create.vue +4 -10
- package/_Build/vue/modules/resource/Children/edit.vue +3 -24
- package/_Build/vue/modules/resource/Children/index.vue +4 -15
- package/_Build/vue/modules/resource/Children/show.vue +47 -45
- package/_Build/vue/modules/resource/index.js +39 -9
- package/_Build/vue/modules/resource/parent.vue +36 -14
- package/index.js +2 -0
- package/package.json +1 -1
|
@@ -67,13 +67,13 @@
|
|
|
67
67
|
:target-action="
|
|
68
68
|
(item) => ({
|
|
69
69
|
name: `${jsonData.slug}.show`,
|
|
70
|
-
params: {
|
|
70
|
+
params: { [idKey]: item.id },
|
|
71
71
|
})
|
|
72
72
|
"
|
|
73
73
|
:edit-action="
|
|
74
74
|
(item) => ({
|
|
75
75
|
name: `${jsonData.slug}.edit`,
|
|
76
|
-
params: {
|
|
76
|
+
params: { [idKey]: item.id },
|
|
77
77
|
})
|
|
78
78
|
"
|
|
79
79
|
:display-actions="displayActions"
|
|
@@ -149,6 +149,10 @@ export default {
|
|
|
149
149
|
type: Boolean,
|
|
150
150
|
default: true,
|
|
151
151
|
},
|
|
152
|
+
idKey: {
|
|
153
|
+
type: String,
|
|
154
|
+
default: "id",
|
|
155
|
+
},
|
|
152
156
|
},
|
|
153
157
|
|
|
154
158
|
data() {
|
|
@@ -150,6 +150,7 @@ export default [
|
|
|
150
150
|
}),
|
|
151
151
|
({ model, $store }) => {
|
|
152
152
|
const resource = meta(...userResource);
|
|
153
|
+
|
|
153
154
|
return h(VelTableSorter, {
|
|
154
155
|
key: "PIndex",
|
|
155
156
|
"json-data": {
|
|
@@ -157,6 +158,7 @@ export default [
|
|
|
157
158
|
tableStructure: resource.table.structure,
|
|
158
159
|
},
|
|
159
160
|
defaults: `include=company&filter[company_id]=${model.id}`,
|
|
161
|
+
idKey: resource.id,
|
|
160
162
|
"fixed-height": false,
|
|
161
163
|
"display-create-action":
|
|
162
164
|
$store.getters.can("write users"),
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import VelFormRole from "../../../../components/layout/FormRole.vue";
|
|
2
2
|
import Chip from "../../../../components/layout/Chip.vue";
|
|
3
3
|
import Chips from "../../../../components/layout/Chips.vue";
|
|
4
|
-
import VelTableSorter from "../../../../components/layout/TableSorter.vue";
|
|
5
4
|
import VelRoleLegend from "../../../../components/layout/RoleLegend.vue";
|
|
6
5
|
import component from "./form.vue";
|
|
7
|
-
import
|
|
6
|
+
import companyResource from "../PCompanies/resource.js";
|
|
7
|
+
import { defaultResource, meta } from "../../../resource/index.js";
|
|
8
8
|
|
|
9
9
|
import { ElMessageBox } from "element-plus";
|
|
10
10
|
import { ElNotification } from "element-plus";
|
|
@@ -34,7 +34,7 @@ export default [
|
|
|
34
34
|
delete: ({ $store }) => $store.getters.can("delete companies"),
|
|
35
35
|
},
|
|
36
36
|
form: {
|
|
37
|
-
async submit({ model, form, $router, $store, method }) {
|
|
37
|
+
async submit({ model, form, $router, $store, method, resource }) {
|
|
38
38
|
try {
|
|
39
39
|
if (method === "post") {
|
|
40
40
|
if (form.set_password) {
|
|
@@ -57,7 +57,7 @@ export default [
|
|
|
57
57
|
.then(() => {
|
|
58
58
|
$router.replace({
|
|
59
59
|
name: "users.show",
|
|
60
|
-
params: { id: res.data.id },
|
|
60
|
+
params: { [resource.id]: res.data.id },
|
|
61
61
|
});
|
|
62
62
|
})
|
|
63
63
|
.catch(() => {});
|
|
@@ -71,7 +71,7 @@ export default [
|
|
|
71
71
|
|
|
72
72
|
$router.replace({
|
|
73
73
|
name: "users.show",
|
|
74
|
-
params: { id: res.data.id },
|
|
74
|
+
params: { [resource.id]: res.data.id },
|
|
75
75
|
});
|
|
76
76
|
}
|
|
77
77
|
} else {
|
|
@@ -84,7 +84,7 @@ export default [
|
|
|
84
84
|
|
|
85
85
|
$router.replace({
|
|
86
86
|
name: "users.show",
|
|
87
|
-
params: { id: res.data.id },
|
|
87
|
+
params: { [resource.id]: res.data.id },
|
|
88
88
|
});
|
|
89
89
|
}
|
|
90
90
|
} catch (e) {
|
|
@@ -131,7 +131,10 @@ export default [
|
|
|
131
131
|
class: "underline",
|
|
132
132
|
to: {
|
|
133
133
|
name: "companies.show",
|
|
134
|
-
params: {
|
|
134
|
+
params: {
|
|
135
|
+
[meta(...companyResource).id]:
|
|
136
|
+
model.company_id,
|
|
137
|
+
},
|
|
135
138
|
},
|
|
136
139
|
text: model.company.name,
|
|
137
140
|
}),
|
|
@@ -171,7 +174,10 @@ export default [
|
|
|
171
174
|
class: "underline",
|
|
172
175
|
to: {
|
|
173
176
|
name: "companies.show",
|
|
174
|
-
params: {
|
|
177
|
+
params: {
|
|
178
|
+
[meta(...companyResource).id]:
|
|
179
|
+
model.company_id,
|
|
180
|
+
},
|
|
175
181
|
},
|
|
176
182
|
text: model.company.name,
|
|
177
183
|
}),
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<VBreadcrumbs :items="breadcrumbs" class="mb-8" container-classes="m-0" />
|
|
3
|
-
|
|
4
2
|
<div class="container px-6 tablet:px-4 mobile:px-2 mb-8 ml-0 mr-0">
|
|
5
3
|
<div class="grid__1/1">
|
|
6
4
|
<div class="grid__1/1 mb-4">
|
|
@@ -25,16 +23,10 @@ import Form from "form-backend-validation";
|
|
|
25
23
|
|
|
26
24
|
export default {
|
|
27
25
|
components: {
|
|
28
|
-
VBreadcrumbs: require("../../../components/layout/Breadcrumbs.vue")
|
|
29
|
-
.default,
|
|
30
26
|
XForm: require("./partials/form.vue").default,
|
|
31
27
|
},
|
|
32
28
|
|
|
33
29
|
props: {
|
|
34
|
-
breadcrumbs: {
|
|
35
|
-
type: Array,
|
|
36
|
-
required: true,
|
|
37
|
-
},
|
|
38
30
|
resource: {
|
|
39
31
|
type: Object,
|
|
40
32
|
required: true,
|
|
@@ -60,11 +52,13 @@ export default {
|
|
|
60
52
|
await this.resource.form.submit(this);
|
|
61
53
|
} else {
|
|
62
54
|
try {
|
|
63
|
-
let res = await this.form.post(
|
|
55
|
+
let res = await this.form.post(
|
|
56
|
+
`${this.resource.api(this)}`,
|
|
57
|
+
);
|
|
64
58
|
|
|
65
59
|
this.$router.replace({
|
|
66
60
|
name: `${this.resource.slug}.show`,
|
|
67
|
-
params: { id: res.data.id },
|
|
61
|
+
params: { [this.resource.id]: res.data.id },
|
|
68
62
|
});
|
|
69
63
|
} catch (e) {
|
|
70
64
|
console.log(e);
|
|
@@ -1,10 +1,4 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<VBreadcrumbs
|
|
3
|
-
:items="addBreadcrumbs"
|
|
4
|
-
class="mb-8"
|
|
5
|
-
container-classes="m-0"
|
|
6
|
-
/>
|
|
7
|
-
|
|
8
2
|
<div class="container px-6 tablet:px-4 mobile:px-2 mb-8 ml-0 mr-0">
|
|
9
3
|
<div class="grid__1/1">
|
|
10
4
|
<div class="grid__1/1 mb-4">
|
|
@@ -30,16 +24,10 @@ import Form from "form-backend-validation";
|
|
|
30
24
|
|
|
31
25
|
export default {
|
|
32
26
|
components: {
|
|
33
|
-
VBreadcrumbs: require("../../../components/layout/Breadcrumbs.vue")
|
|
34
|
-
.default,
|
|
35
27
|
XForm: require("./partials/form.vue").default,
|
|
36
28
|
},
|
|
37
29
|
|
|
38
30
|
props: {
|
|
39
|
-
breadcrumbs: {
|
|
40
|
-
type: Array,
|
|
41
|
-
required: true,
|
|
42
|
-
},
|
|
43
31
|
resource: {
|
|
44
32
|
type: Object,
|
|
45
33
|
required: true,
|
|
@@ -50,7 +38,6 @@ export default {
|
|
|
50
38
|
return {
|
|
51
39
|
form: null,
|
|
52
40
|
model: null,
|
|
53
|
-
addBreadcrumbs: [...this.$props.breadcrumbs],
|
|
54
41
|
method: "patch",
|
|
55
42
|
};
|
|
56
43
|
},
|
|
@@ -64,7 +51,7 @@ export default {
|
|
|
64
51
|
async mounted() {
|
|
65
52
|
window.axios
|
|
66
53
|
.get(
|
|
67
|
-
`${this.resource.api}/${this.$route.params.id}?${this.resource.defaults}`,
|
|
54
|
+
`${this.resource.api(this)}/${this.$route.params[this.resource.id]}?${this.resource.defaults}`,
|
|
68
55
|
)
|
|
69
56
|
.then((res) => {
|
|
70
57
|
this.model = res.data.data;
|
|
@@ -75,14 +62,6 @@ export default {
|
|
|
75
62
|
this.form[key] = value;
|
|
76
63
|
},
|
|
77
64
|
);
|
|
78
|
-
|
|
79
|
-
this.addBreadcrumbs.push({
|
|
80
|
-
href: {
|
|
81
|
-
name: `${this.resource.slug}.show`,
|
|
82
|
-
param: this.model.id,
|
|
83
|
-
},
|
|
84
|
-
text: this.model.name,
|
|
85
|
-
});
|
|
86
65
|
});
|
|
87
66
|
},
|
|
88
67
|
|
|
@@ -93,12 +72,12 @@ export default {
|
|
|
93
72
|
} else {
|
|
94
73
|
try {
|
|
95
74
|
let res = await this.form.patch(
|
|
96
|
-
`${this.resource.api}/${this.model.id}`,
|
|
75
|
+
`${this.resource.api(this)}/${this.model.id}`,
|
|
97
76
|
);
|
|
98
77
|
|
|
99
78
|
this.$router.replace({
|
|
100
79
|
name: `${this.resource.slug}.show`,
|
|
101
|
-
params: { id: res.data.id },
|
|
80
|
+
params: { [this.resource.id]: res.data.id },
|
|
102
81
|
});
|
|
103
82
|
} catch (e) {
|
|
104
83
|
console.log(e);
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<VBreadcrumbs :items="breadcrumbs" />
|
|
3
|
-
|
|
4
2
|
<div class="container px-6 tablet:px-4 mobile:px-2 mb-8 ml-0 mr-0">
|
|
5
3
|
<div class="grid__1/1">
|
|
6
|
-
<h2 class="h1 pb-4">
|
|
7
|
-
{{ breadcrumbs[breadcrumbs.length - 1].text }}
|
|
8
|
-
</h2>
|
|
9
|
-
|
|
10
4
|
<div class="flex gap items-center justify-end">
|
|
11
5
|
<template
|
|
12
6
|
v-for="(render, index) in resource.index.actions"
|
|
@@ -28,20 +22,15 @@
|
|
|
28
22
|
|
|
29
23
|
<script>
|
|
30
24
|
export default {
|
|
31
|
-
components: {
|
|
32
|
-
VBreadcrumbs: require("../../../components/layout/Breadcrumbs.vue")
|
|
33
|
-
.default,
|
|
34
|
-
},
|
|
35
|
-
|
|
36
25
|
props: {
|
|
37
|
-
breadcrumbs: {
|
|
38
|
-
type: Array,
|
|
39
|
-
required: true,
|
|
40
|
-
},
|
|
41
26
|
resource: {
|
|
42
27
|
type: Object,
|
|
43
28
|
required: true,
|
|
44
29
|
},
|
|
30
|
+
depth: {
|
|
31
|
+
type: Number,
|
|
32
|
+
required: true,
|
|
33
|
+
},
|
|
45
34
|
},
|
|
46
35
|
};
|
|
47
36
|
</script>
|
|
@@ -1,47 +1,44 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
/>
|
|
2
|
+
<!-- Render nested router view if this isn't the deepest route -->
|
|
3
|
+
<router-view v-if="!deepestRoute" v-slot="{ Component }">
|
|
4
|
+
<component :is="Component" :depth="depth + 1" />
|
|
5
|
+
</router-view>
|
|
7
6
|
|
|
8
|
-
<
|
|
9
|
-
<div class="
|
|
10
|
-
<
|
|
11
|
-
<
|
|
12
|
-
<
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
7
|
+
<template v-else>
|
|
8
|
+
<div class="container px-6 tablet:px-4 mobile:px-2 mb-8 ml-0 mr-0">
|
|
9
|
+
<div class="grid__1/1">
|
|
10
|
+
<template v-if="model">
|
|
11
|
+
<div class="bg-0 p-3 box-shadow-1 border-r-4 mb-6">
|
|
12
|
+
<VelPageHeader
|
|
13
|
+
:icon="resource.icon"
|
|
14
|
+
:title="`${model.name} ${model.last_name ?? ''}`"
|
|
15
|
+
>
|
|
16
|
+
<template
|
|
17
|
+
v-for="(render, index) in resource.show.actions"
|
|
18
|
+
:key="index"
|
|
19
|
+
>
|
|
20
|
+
<component :is="render(this)" />
|
|
21
|
+
</template>
|
|
22
|
+
</VelPageHeader>
|
|
23
|
+
<hr class="my-3 hr-muted" />
|
|
16
24
|
<template
|
|
17
|
-
v-for="(render, index) in resource.show.
|
|
25
|
+
v-for="(render, index) in resource.show.layout"
|
|
18
26
|
:key="index"
|
|
19
27
|
>
|
|
20
28
|
<component :is="render(this)" />
|
|
29
|
+
<hr
|
|
30
|
+
v-if="index < resource.show.layout.length - 1"
|
|
31
|
+
class="my-3 hr-muted"
|
|
32
|
+
/>
|
|
21
33
|
</template>
|
|
22
|
-
</
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
<template
|
|
27
|
-
v-for="(render, index) in resource.show.layout"
|
|
28
|
-
:key="index"
|
|
29
|
-
>
|
|
30
|
-
<component :is="render(this)" />
|
|
31
|
-
|
|
32
|
-
<hr
|
|
33
|
-
v-if="index < resource.show.layout.length - 1"
|
|
34
|
-
class="my-3 hr-muted"
|
|
35
|
-
/>
|
|
36
|
-
</template>
|
|
34
|
+
</div>
|
|
35
|
+
</template>
|
|
36
|
+
<div v-else class="absolute transform-center text-center">
|
|
37
|
+
<VelSpinner />
|
|
37
38
|
</div>
|
|
38
|
-
</template>
|
|
39
|
-
|
|
40
|
-
<div v-else class="absolute transform-center text-center">
|
|
41
|
-
<VelSpinner />
|
|
42
39
|
</div>
|
|
43
40
|
</div>
|
|
44
|
-
</
|
|
41
|
+
</template>
|
|
45
42
|
</template>
|
|
46
43
|
|
|
47
44
|
<script>
|
|
@@ -51,8 +48,6 @@ import VelButton from "../../../components/basic/Button.vue";
|
|
|
51
48
|
|
|
52
49
|
export default {
|
|
53
50
|
components: {
|
|
54
|
-
VBreadcrumbs: require("../../../components/layout/Breadcrumbs.vue")
|
|
55
|
-
.default,
|
|
56
51
|
VelPageHeader: require("../../../components/layout/PageHeader.vue")
|
|
57
52
|
.default,
|
|
58
53
|
VelSpinner,
|
|
@@ -68,29 +63,36 @@ export default {
|
|
|
68
63
|
type: Object,
|
|
69
64
|
required: true,
|
|
70
65
|
},
|
|
66
|
+
depth: {
|
|
67
|
+
type: Number,
|
|
68
|
+
required: true,
|
|
69
|
+
},
|
|
71
70
|
},
|
|
72
71
|
|
|
73
72
|
data() {
|
|
74
73
|
return {
|
|
75
74
|
model: null,
|
|
76
|
-
addBreadcrumbs: [...this.$props.breadcrumbs],
|
|
77
75
|
};
|
|
78
76
|
},
|
|
79
77
|
|
|
78
|
+
computed: {
|
|
79
|
+
// This boolean helps determine if we are the final depth of route being rendered
|
|
80
|
+
deepestRoute() {
|
|
81
|
+
return this.depth === this.$route.matched.length;
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
|
|
80
85
|
mounted() {
|
|
86
|
+
if (!this.deepestRoute) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
81
90
|
axios
|
|
82
91
|
.get(
|
|
83
|
-
`${this.resource.api}/${this.$route.params.
|
|
92
|
+
`${this.resource.api(this)}/${this.$route.params[`${this.resource.slug}Id`]}?${this.resource.defaults}`,
|
|
84
93
|
)
|
|
85
94
|
.then((res) => {
|
|
86
95
|
this.model = res.data.data;
|
|
87
|
-
this.addBreadcrumbs.push({
|
|
88
|
-
href: {
|
|
89
|
-
name: `${this.resource.slug}.show`,
|
|
90
|
-
param: this.model.id,
|
|
91
|
-
},
|
|
92
|
-
text: this.model.name,
|
|
93
|
-
});
|
|
94
96
|
});
|
|
95
97
|
},
|
|
96
98
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import { merge, kebabCase } from "lodash";
|
|
3
|
+
import { merge, kebabCase, cloneDeepWith } from "lodash";
|
|
4
4
|
import axios from "axios";
|
|
5
5
|
import { h, resolveComponent } from "vue";
|
|
6
6
|
|
|
@@ -12,6 +12,7 @@ export const defaultResource = meta();
|
|
|
12
12
|
|
|
13
13
|
export function meta(name = "default", properties = {}) {
|
|
14
14
|
const singular = properties.singular || name.slice(0, -1);
|
|
15
|
+
const slug = properties.slug || kebabCase(name);
|
|
15
16
|
|
|
16
17
|
return merge(
|
|
17
18
|
{
|
|
@@ -20,8 +21,9 @@ export function meta(name = "default", properties = {}) {
|
|
|
20
21
|
singular,
|
|
21
22
|
label: singular,
|
|
22
23
|
multiLabel: name,
|
|
23
|
-
slug
|
|
24
|
-
|
|
24
|
+
slug,
|
|
25
|
+
id: properties.id || `${slug}Id`,
|
|
26
|
+
api: () => `/api/${properties.slug || kebabCase(name)}`,
|
|
25
27
|
permissions: {
|
|
26
28
|
create: () => true,
|
|
27
29
|
edit: () => true,
|
|
@@ -61,8 +63,10 @@ export function meta(name = "default", properties = {}) {
|
|
|
61
63
|
"json-data": {
|
|
62
64
|
...resource,
|
|
63
65
|
tableStructure: resource.table.structure,
|
|
66
|
+
api: resource.api(props),
|
|
64
67
|
},
|
|
65
68
|
defaults: resource.defaults,
|
|
69
|
+
idKey: resource.id,
|
|
66
70
|
"fixed-height": false,
|
|
67
71
|
"display-create-action":
|
|
68
72
|
resource.permissions.create(props),
|
|
@@ -86,7 +90,9 @@ export function meta(name = "default", properties = {}) {
|
|
|
86
90
|
onClick: () => {
|
|
87
91
|
$router.push({
|
|
88
92
|
name: `${resource.slug}.edit`,
|
|
89
|
-
params: {
|
|
93
|
+
params: {
|
|
94
|
+
[resource.id]: model.id,
|
|
95
|
+
},
|
|
90
96
|
});
|
|
91
97
|
},
|
|
92
98
|
},
|
|
@@ -115,7 +121,7 @@ export function meta(name = "default", properties = {}) {
|
|
|
115
121
|
confirmButtonType: "danger",
|
|
116
122
|
onConfirm: async () => {
|
|
117
123
|
await axios.delete(
|
|
118
|
-
`${resource.api}/${model.id}`,
|
|
124
|
+
`${resource.api(props)}/${model.id}`,
|
|
119
125
|
);
|
|
120
126
|
|
|
121
127
|
$router.push({
|
|
@@ -228,18 +234,25 @@ export function columns(columns = []) {
|
|
|
228
234
|
}
|
|
229
235
|
|
|
230
236
|
// Export resource
|
|
231
|
-
export function routes(
|
|
237
|
+
export function routes(
|
|
238
|
+
node,
|
|
239
|
+
name,
|
|
240
|
+
properties = {},
|
|
241
|
+
children = [],
|
|
242
|
+
isChild = false,
|
|
243
|
+
) {
|
|
232
244
|
const resource = meta(name, properties);
|
|
233
245
|
|
|
234
246
|
return [
|
|
235
247
|
{
|
|
236
|
-
path:
|
|
248
|
+
path: `${isChild ? "" : "/"}${resource.slug}`,
|
|
237
249
|
component: node ? "" : require("../resource/parent.vue").default,
|
|
238
250
|
name,
|
|
239
251
|
meta: {
|
|
240
252
|
resource,
|
|
241
253
|
title: resource.title,
|
|
242
254
|
icon: resource.icon,
|
|
255
|
+
breadcrumb: () => resource.title,
|
|
243
256
|
},
|
|
244
257
|
children: [
|
|
245
258
|
{
|
|
@@ -257,18 +270,34 @@ export function routes(node, name, properties = {}) {
|
|
|
257
270
|
name: `${resource.slug}.create`,
|
|
258
271
|
},
|
|
259
272
|
{
|
|
260
|
-
path:
|
|
273
|
+
path: `:${resource.id}`,
|
|
261
274
|
component: node
|
|
262
275
|
? ""
|
|
263
276
|
: require("../resource/Children/show.vue").default,
|
|
264
277
|
name: `${resource.slug}.show`,
|
|
278
|
+
// Remove leading / for nested routes or they'll resolve to the root of the site
|
|
279
|
+
children: cloneDeepWith(children, (value, key) => {
|
|
280
|
+
if (
|
|
281
|
+
key === "path" &&
|
|
282
|
+
typeof value === "string" &&
|
|
283
|
+
value.startsWith("/")
|
|
284
|
+
) {
|
|
285
|
+
return value.slice(1);
|
|
286
|
+
}
|
|
287
|
+
}),
|
|
288
|
+
meta: {
|
|
289
|
+
breadcrumb: ({ $route }) => $route.params[resource.id],
|
|
290
|
+
},
|
|
265
291
|
},
|
|
266
292
|
{
|
|
267
|
-
path:
|
|
293
|
+
path: `:${resource.id}/edit`,
|
|
268
294
|
component: node
|
|
269
295
|
? ""
|
|
270
296
|
: require("../resource/Children/edit.vue").default,
|
|
271
297
|
name: `${resource.slug}.edit`,
|
|
298
|
+
meta: {
|
|
299
|
+
breadcrumb: ({ $route }) => $route.params[resource.id],
|
|
300
|
+
},
|
|
272
301
|
},
|
|
273
302
|
],
|
|
274
303
|
},
|
|
@@ -279,4 +308,5 @@ export default {
|
|
|
279
308
|
routes,
|
|
280
309
|
meta,
|
|
281
310
|
columns,
|
|
311
|
+
defaultResource,
|
|
282
312
|
};
|
|
@@ -1,19 +1,39 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
2
|
+
<!-- Only render title once at the shallowest route -->
|
|
3
|
+
<template v-if="depth === 1">
|
|
4
|
+
<VelPageTitle :title="resource.title" />
|
|
5
|
+
<VelBreadcrumbs
|
|
6
|
+
:items="breadcrumbs"
|
|
7
|
+
class="mb-8"
|
|
8
|
+
container-classes="m-0"
|
|
9
|
+
/>
|
|
10
|
+
</template>
|
|
3
11
|
|
|
4
12
|
<router-view
|
|
5
13
|
:key="$route.path"
|
|
14
|
+
v-slot="{ Component }"
|
|
6
15
|
:breadcrumbs="breadcrumbs"
|
|
7
16
|
:resource="resource"
|
|
8
|
-
|
|
17
|
+
>
|
|
18
|
+
<component :is="Component" :depth="depth + 1" />
|
|
19
|
+
</router-view>
|
|
9
20
|
</template>
|
|
10
21
|
|
|
11
22
|
<script>
|
|
12
|
-
import
|
|
23
|
+
import VelPageTitle from "../../components/layout/pageTitle.vue";
|
|
24
|
+
import VelBreadcrumbs from "../../components/layout/Breadcrumbs.vue";
|
|
13
25
|
|
|
14
26
|
export default {
|
|
15
27
|
components: {
|
|
16
|
-
|
|
28
|
+
VelPageTitle,
|
|
29
|
+
VelBreadcrumbs,
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
props: {
|
|
33
|
+
depth: {
|
|
34
|
+
type: Number,
|
|
35
|
+
default: 1,
|
|
36
|
+
},
|
|
17
37
|
},
|
|
18
38
|
|
|
19
39
|
computed: {
|
|
@@ -23,18 +43,20 @@ export default {
|
|
|
23
43
|
breadcrumbs() {
|
|
24
44
|
return [
|
|
25
45
|
{
|
|
26
|
-
href: {
|
|
27
|
-
name: "index",
|
|
28
|
-
},
|
|
29
46
|
text: "Home",
|
|
47
|
+
href: { name: "index" },
|
|
30
48
|
},
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
49
|
+
].concat(
|
|
50
|
+
this.$route.matched
|
|
51
|
+
.filter((route) => route.meta?.breadcrumb)
|
|
52
|
+
.map((route) => ({
|
|
53
|
+
text: route.meta.breadcrumb(this),
|
|
54
|
+
href: {
|
|
55
|
+
name: route.name,
|
|
56
|
+
params: this.$route.params,
|
|
57
|
+
},
|
|
58
|
+
})),
|
|
59
|
+
);
|
|
38
60
|
},
|
|
39
61
|
},
|
|
40
62
|
};
|
package/index.js
CHANGED
|
@@ -26,6 +26,8 @@ export { default as Wysiwyg2 } from "./_Build/vue/components/form/Wysiwyg2.vue";
|
|
|
26
26
|
export { default as Upload } from "./_Build/vue/components/form/Upload.vue";
|
|
27
27
|
export { default as InputNumber } from "./_Build/vue/components/form/InputNumber.vue";
|
|
28
28
|
|
|
29
|
+
export { default as RoleLegend } from "./_Build/vue/components/layout/RoleLegend.vue";
|
|
30
|
+
export { default as TableSorter } from "./_Build/vue/components/layout/TableSorter.vue";
|
|
29
31
|
export { default as Chip } from "./_Build/vue/components/layout/Chip.vue";
|
|
30
32
|
export { default as Chips } from "./_Build/vue/components/layout/Chips.vue";
|
|
31
33
|
export { default as SideBar } from "./_Build/vue/components/layout/SideBar.vue";
|