@drax/crud-vue 0.4.0 → 0.5.1
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/package.json +5 -4
- package/src/EntityCrud.ts +56 -41
- package/src/components/Crud.vue +7 -3
- package/src/components/CrudAutocomplete.vue +32 -14
- package/src/components/CrudDialog.vue +5 -3
- package/src/components/CrudExportList.vue +55 -0
- package/src/components/CrudForm.vue +7 -6
- package/src/components/CrudFormField.vue +10 -7
- package/src/components/CrudFormList.vue +6 -7
- package/src/components/CrudList.vue +63 -36
- package/src/components/CrudSearch.vue +3 -1
- package/src/components/buttons/CrudCreateButton.vue +25 -0
- package/src/components/buttons/CrudDeleteButton.vue +25 -0
- package/src/components/buttons/CrudExportButton.vue +48 -0
- package/src/components/buttons/CrudImportButton.vue +39 -0
- package/src/components/buttons/CrudUpdateButton.vue +25 -0
- package/src/composables/UseCrud.ts +64 -19
- package/src/index.ts +0 -2
- package/src/stores/UseCrudStore.ts +17 -2
- package/src/interfaces/IEntityCrud.ts +0 -33
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.5.1",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "./src/index.ts",
|
|
9
9
|
"module": "./src/index.ts",
|
|
@@ -24,8 +24,9 @@
|
|
|
24
24
|
"format": "prettier --write src/"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@drax/common-front": "^0.
|
|
28
|
-
"@drax/
|
|
27
|
+
"@drax/common-front": "^0.5.1",
|
|
28
|
+
"@drax/crud-front": "^0.5.1",
|
|
29
|
+
"@drax/crud-share": "^0.5.1"
|
|
29
30
|
},
|
|
30
31
|
"peerDependencies": {
|
|
31
32
|
"pinia": "^2.2.2",
|
|
@@ -62,5 +63,5 @@
|
|
|
62
63
|
"vue-tsc": "^2.0.11",
|
|
63
64
|
"vuetify": "^3.7.1"
|
|
64
65
|
},
|
|
65
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "6f507c8b52e134f10839fd7698c2466ff65a3d08"
|
|
66
67
|
}
|
package/src/EntityCrud.ts
CHANGED
|
@@ -1,102 +1,99 @@
|
|
|
1
|
-
import type {IDraxCrud} from "@drax/common-share";
|
|
2
1
|
import type {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
ICrudRules,
|
|
8
|
-
ICrudField
|
|
9
|
-
} from "./interfaces/IEntityCrud";
|
|
2
|
+
IEntityCrud, IEntityCrudForm, IEntityCrudHeader, IEntityCrudRefs,
|
|
3
|
+
IEntityCrudRules, IEntityCrudField, IEntityCrudPermissions,
|
|
4
|
+
IDraxCrudProvider
|
|
5
|
+
} from "@drax/crud-share";
|
|
10
6
|
|
|
11
7
|
|
|
12
8
|
|
|
13
|
-
class EntityCrud{
|
|
9
|
+
class EntityCrud implements IEntityCrud{
|
|
14
10
|
|
|
15
11
|
name: string = ''
|
|
16
12
|
|
|
17
13
|
constructor() {
|
|
18
14
|
}
|
|
19
15
|
|
|
20
|
-
static get instance(){
|
|
16
|
+
static get instance():IEntityCrud{
|
|
21
17
|
throw new Error('EntityCrud instance not found')
|
|
22
18
|
}
|
|
23
19
|
|
|
24
20
|
|
|
25
|
-
get headers():
|
|
21
|
+
get headers():IEntityCrudHeader[]{
|
|
26
22
|
return [
|
|
27
23
|
{title: 'ID',key:'_id'},
|
|
28
24
|
]
|
|
29
25
|
}
|
|
30
26
|
|
|
31
|
-
get permissions():
|
|
27
|
+
get permissions(): IEntityCrudPermissions {
|
|
32
28
|
return {
|
|
33
29
|
manage: 'manage', view: 'view', create: 'create', update: 'update', delete: 'delete'
|
|
34
30
|
}
|
|
35
31
|
}
|
|
36
32
|
|
|
37
|
-
get provider():
|
|
33
|
+
get provider(): IDraxCrudProvider<any, any, any>{
|
|
38
34
|
throw new Error('provider not implemented')
|
|
39
35
|
}
|
|
40
36
|
|
|
41
|
-
get fields():
|
|
37
|
+
get fields():IEntityCrudField[]{
|
|
42
38
|
return [
|
|
43
39
|
{name: 'id', type: 'string', label: 'ID', default: '' },
|
|
44
40
|
]
|
|
45
41
|
}
|
|
46
42
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
})
|
|
60
|
-
}
|
|
61
|
-
return value
|
|
43
|
+
objectFields(field:IEntityCrudField){
|
|
44
|
+
let value:any = {}
|
|
45
|
+
if(field.objectFields){
|
|
46
|
+
field.objectFields.forEach(subField => {
|
|
47
|
+
if(subField.type === 'object'){
|
|
48
|
+
value[subField.name] = this.objectFields(subField)
|
|
49
|
+
}else{
|
|
50
|
+
value[subField.name] = subField.default
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
})
|
|
62
54
|
}
|
|
55
|
+
return value
|
|
56
|
+
}
|
|
63
57
|
|
|
64
|
-
|
|
58
|
+
get form():IEntityCrudForm{
|
|
65
59
|
|
|
60
|
+
const form = this.fields.reduce((acc, field) => {
|
|
66
61
|
let value = null
|
|
67
62
|
if(field.type === 'object'){
|
|
68
|
-
value = objectFields(field)
|
|
69
|
-
}
|
|
63
|
+
value = this.objectFields(field)
|
|
64
|
+
}else if(field.default != undefined){
|
|
70
65
|
value = field.default
|
|
71
66
|
}
|
|
72
67
|
|
|
73
68
|
return {...acc, [field.name]: value }
|
|
74
69
|
}, {})
|
|
75
70
|
|
|
76
|
-
console.log("Form: ", form)
|
|
71
|
+
//console.log("Form: ", form)
|
|
77
72
|
|
|
78
73
|
return form
|
|
79
74
|
|
|
80
75
|
}
|
|
81
76
|
|
|
82
|
-
get refs():{
|
|
77
|
+
get refs():IEntityCrudRefs{
|
|
83
78
|
return {}
|
|
84
79
|
}
|
|
85
80
|
|
|
86
|
-
getRef(ref: string):
|
|
81
|
+
getRef(ref: string):IEntityCrud{
|
|
87
82
|
if(!this.refs.hasOwnProperty(ref)) {
|
|
88
83
|
throw new Error("Ref not found: " + ref)
|
|
89
84
|
}
|
|
90
85
|
|
|
91
|
-
return this.refs[ref]
|
|
86
|
+
return this.refs[ref]
|
|
92
87
|
}
|
|
93
88
|
|
|
94
|
-
get rules():
|
|
89
|
+
get rules(): IEntityCrudRules{
|
|
95
90
|
return {}
|
|
96
91
|
}
|
|
97
92
|
|
|
98
|
-
get rule() {
|
|
99
|
-
return (field:string) =>
|
|
93
|
+
get rule(): (field:string|undefined) => Array<Function> {
|
|
94
|
+
return (field:string|undefined) => {
|
|
95
|
+
return field && this.rules[field] ? this.rules[field] : []
|
|
96
|
+
}
|
|
100
97
|
}
|
|
101
98
|
|
|
102
99
|
get isEditable(){
|
|
@@ -111,11 +108,29 @@ class EntityCrud{
|
|
|
111
108
|
return true
|
|
112
109
|
}
|
|
113
110
|
|
|
114
|
-
get
|
|
115
|
-
return
|
|
111
|
+
get isExportable(){
|
|
112
|
+
return true
|
|
116
113
|
}
|
|
117
114
|
|
|
115
|
+
get exportFormats(){
|
|
116
|
+
return ['CSV', 'JSON']
|
|
117
|
+
}
|
|
118
118
|
|
|
119
|
+
get exportHeaders(){
|
|
120
|
+
return ['_id']
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
get isImportable(){
|
|
124
|
+
return true
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
get importFormats(){
|
|
128
|
+
return ['CSV', 'JSON']
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
get dialogFullscreen(){
|
|
132
|
+
return false
|
|
133
|
+
}
|
|
119
134
|
|
|
120
135
|
|
|
121
136
|
}
|
package/src/components/Crud.vue
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type {PropType} from "vue";
|
|
3
|
-
import
|
|
3
|
+
import type {IEntityCrud} from "@drax/crud-share";
|
|
4
4
|
import CrudList from "./CrudList.vue";
|
|
5
5
|
import CrudForm from "./CrudForm.vue";
|
|
6
6
|
import CrudNotify from "./CrudNotify.vue";
|
|
7
7
|
import CrudDialog from "./CrudDialog.vue";
|
|
8
8
|
import {useCrud} from "../composables/UseCrud";
|
|
9
9
|
|
|
10
|
+
|
|
10
11
|
const {entity} = defineProps({
|
|
11
|
-
entity: {type: Object as PropType<
|
|
12
|
+
entity: {type: Object as PropType<IEntityCrud>, required: true},
|
|
12
13
|
})
|
|
13
14
|
|
|
14
15
|
const {
|
|
15
16
|
onCreate, onEdit, onDelete, onCancel, onSubmit,
|
|
16
|
-
operation, dialog, form,
|
|
17
|
+
operation, dialog, form, notify, error, message, doExport
|
|
17
18
|
} = useCrud(entity);
|
|
18
19
|
|
|
19
20
|
</script>
|
|
@@ -22,11 +23,14 @@ const {
|
|
|
22
23
|
<v-container fluid class="mt-5">
|
|
23
24
|
<v-card>
|
|
24
25
|
|
|
26
|
+
|
|
27
|
+
|
|
25
28
|
<crud-list
|
|
26
29
|
:entity="entity"
|
|
27
30
|
@create="onCreate"
|
|
28
31
|
@edit="onEdit"
|
|
29
32
|
@delete="onDelete"
|
|
33
|
+
@export="doExport"
|
|
30
34
|
>
|
|
31
35
|
<template v-for="header in entity.headers" :key="header.key" v-slot:[`item.${header.key}`]="{item, value}">
|
|
32
36
|
<slot :name="`item.${header.key}`" v-bind="{item, value}">
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import {debounce} from "@drax/common-front"
|
|
3
|
-
import type
|
|
3
|
+
import { type PropType, type Ref} from "vue";
|
|
4
4
|
import {ref, onBeforeMount} from "vue";
|
|
5
|
-
import
|
|
6
|
-
import type {ICrudField} from "@/interfaces/IEntityCrud";
|
|
5
|
+
import type {IEntityCrud, IEntityCrudField} from "@drax/crud-share";
|
|
7
6
|
|
|
8
|
-
const valueModel = defineModel({type: [String, Array], required: false})
|
|
7
|
+
const valueModel = defineModel<string | string[]>({type: [String, Array], required: false})
|
|
9
8
|
|
|
10
9
|
const {entity, multiple} = defineProps({
|
|
11
|
-
entity: {type: Object as PropType<
|
|
12
|
-
field: {type: Object as PropType<
|
|
10
|
+
entity: {type: Object as PropType<IEntityCrud|undefined>, required: true},
|
|
11
|
+
field: {type: Object as PropType<IEntityCrudField>, required: true},
|
|
13
12
|
multiple: {type: Boolean, default: false},
|
|
14
13
|
chips: {type: Boolean, default: false},
|
|
15
14
|
closableChips: {type: Boolean, default: true},
|
|
@@ -17,10 +16,14 @@ const {entity, multiple} = defineProps({
|
|
|
17
16
|
label: {type: String},
|
|
18
17
|
itemValue: {type: [String], default: '_id'},
|
|
19
18
|
itemTitle: {type: [String], default: 'name'},
|
|
20
|
-
rules: {type: Array<
|
|
19
|
+
rules: {type: Array as PropType<any>, default: []},
|
|
21
20
|
errorMessages: {type: Array as PropType<string[]>, default: []},
|
|
22
21
|
})
|
|
23
22
|
|
|
23
|
+
if(!entity){
|
|
24
|
+
throw new Error('entity is required')
|
|
25
|
+
}
|
|
26
|
+
|
|
24
27
|
const loading: Ref<boolean> = ref(false)
|
|
25
28
|
const items: Ref<Array<any>> = ref([])
|
|
26
29
|
|
|
@@ -28,19 +31,33 @@ const debouncedSearch = debounce(search, 300)
|
|
|
28
31
|
|
|
29
32
|
onBeforeMount(async () => {
|
|
30
33
|
if(valueModel.value && valueModel.value.length > 0){
|
|
34
|
+
|
|
31
35
|
if(multiple && Array.isArray(valueModel.value) ){
|
|
32
36
|
items.value = valueModel.value
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
|
|
38
|
+
// valueModel.value = valueModel.value.map((item:any) => item._id)
|
|
39
|
+
await findByIds(valueModel.value)
|
|
40
|
+
}else if(!Array.isArray(valueModel.value)){
|
|
41
|
+
// items.value = [valueModel.value]
|
|
42
|
+
await findByIds([valueModel.value])
|
|
37
43
|
}
|
|
38
44
|
|
|
45
|
+
|
|
46
|
+
|
|
39
47
|
}
|
|
40
48
|
})
|
|
41
49
|
|
|
42
|
-
async function findByIds(ids: Array<string>) {
|
|
50
|
+
async function findByIds(ids: Array<string> = []) {
|
|
43
51
|
try{
|
|
52
|
+
if(!entity){
|
|
53
|
+
throw new Error('Entity is required')
|
|
54
|
+
}
|
|
55
|
+
if(!entity.provider){
|
|
56
|
+
throw new Error('Provider is not defined')
|
|
57
|
+
}
|
|
58
|
+
if (typeof entity.provider.findByIds !== 'function') {
|
|
59
|
+
throw new Error('Provider does not have a findByIds method');
|
|
60
|
+
}
|
|
44
61
|
loading.value = true
|
|
45
62
|
items.value = await entity.provider.findByIds(ids)
|
|
46
63
|
}catch (e){
|
|
@@ -51,11 +68,12 @@ async function findByIds(ids: Array<string>) {
|
|
|
51
68
|
}
|
|
52
69
|
|
|
53
70
|
|
|
54
|
-
|
|
55
|
-
|
|
56
71
|
async function search(value: any) {
|
|
57
72
|
try{
|
|
58
73
|
loading.value = true
|
|
74
|
+
if(!entity){
|
|
75
|
+
throw new Error('Entity is required')
|
|
76
|
+
}
|
|
59
77
|
if(!entity.provider.search){
|
|
60
78
|
throw new Error('Provider does not have a search method')
|
|
61
79
|
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type {TOperation} from "../interfaces/TOperation";
|
|
3
3
|
import type {PropType} from "vue";
|
|
4
|
-
import
|
|
4
|
+
import type {IEntityCrud} from "@drax/crud-share";
|
|
5
5
|
const dialog = defineModel({type: Boolean, default: false})
|
|
6
|
+
import {useI18n} from "vue-i18n";
|
|
7
|
+
const {t,te} = useI18n()
|
|
6
8
|
|
|
7
9
|
defineProps({
|
|
8
|
-
entity: {type: Object as PropType<
|
|
10
|
+
entity: {type: Object as PropType<IEntityCrud>, required: true},
|
|
9
11
|
operation: {type: String as PropType<TOperation>}
|
|
10
12
|
})
|
|
11
13
|
|
|
@@ -19,7 +21,7 @@ defineEmits(
|
|
|
19
21
|
<v-dialog v-model="dialog" :fullscreen="entity.dialogFullscreen">
|
|
20
22
|
<v-card>
|
|
21
23
|
<v-toolbar>
|
|
22
|
-
<v-toolbar-title>{{entity.name}} {{
|
|
24
|
+
<v-toolbar-title>{{entity.name}} {{te('action.'+operation) ? t('action.'+operation) : operation}}</v-toolbar-title>
|
|
23
25
|
<v-spacer></v-spacer>
|
|
24
26
|
<v-btn icon @click="dialog = false"><v-icon>mdi-close</v-icon></v-btn>
|
|
25
27
|
</v-toolbar>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {useCrud} from "../composables/UseCrud";
|
|
3
|
+
import type {PropType} from "vue";
|
|
4
|
+
import type {IEntityCrud} from "@drax/crud-share";
|
|
5
|
+
import {useI18n} from "vue-i18n";
|
|
6
|
+
const {t} = useI18n()
|
|
7
|
+
const {entity} = defineProps({
|
|
8
|
+
entity: {type: Object as PropType<IEntityCrud>, required: true},
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
const {
|
|
12
|
+
exportFiles, exportListVisible, exportLoading
|
|
13
|
+
} = useCrud(entity);
|
|
14
|
+
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<template>
|
|
18
|
+
<v-card
|
|
19
|
+
v-if="exportListVisible"
|
|
20
|
+
:loading="exportLoading"
|
|
21
|
+
class="ma-3" density="compact" variant="outlined" color="secondary"
|
|
22
|
+
>
|
|
23
|
+
<v-card-title>
|
|
24
|
+
{{ t('action.exports') }}
|
|
25
|
+
|
|
26
|
+
</v-card-title>
|
|
27
|
+
<v-card-text>
|
|
28
|
+
<v-table density="compact">
|
|
29
|
+
<thead>
|
|
30
|
+
<tr>
|
|
31
|
+
<th>Link</th><th>Rows</th><th>Time</th>
|
|
32
|
+
</tr>
|
|
33
|
+
</thead>
|
|
34
|
+
<tbody>
|
|
35
|
+
<tr v-for="exportFile in exportFiles">
|
|
36
|
+
<td><a :href="exportFile.url" target="_blank">{{ exportFile.url }}</a></td>
|
|
37
|
+
<td>{{ exportFile.rowCount }}</td>
|
|
38
|
+
<td>{{ exportFile.time }}</td>
|
|
39
|
+
</tr>
|
|
40
|
+
</tbody>
|
|
41
|
+
</v-table>
|
|
42
|
+
|
|
43
|
+
</v-card-text>
|
|
44
|
+
|
|
45
|
+
<v-card-actions>
|
|
46
|
+
<v-spacer></v-spacer>
|
|
47
|
+
<v-btn @click="exportFiles = []" :loading="exportLoading">{{ t('action.clear') }}</v-btn>
|
|
48
|
+
<v-btn @click="exportListVisible=false">{{ t('action.close') }}</v-btn>
|
|
49
|
+
</v-card-actions>
|
|
50
|
+
</v-card>
|
|
51
|
+
</template>
|
|
52
|
+
|
|
53
|
+
<style scoped>
|
|
54
|
+
|
|
55
|
+
</style>
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type {PropType} from "vue";
|
|
3
3
|
import {ref} from "vue";
|
|
4
|
-
import EntityCrud from "../EntityCrud";
|
|
5
4
|
import CrudFormField from "./CrudFormField.vue";
|
|
6
5
|
import type {TOperation} from "../interfaces/TOperation";
|
|
7
|
-
|
|
6
|
+
import type {IEntityCrud} from "@drax/crud-share";
|
|
7
|
+
import {useI18n} from "vue-i18n";
|
|
8
|
+
const {t,te} = useI18n()
|
|
8
9
|
|
|
9
10
|
const valueModel = defineModel({type: [Object]})
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
const {entity} = defineProps({
|
|
13
|
-
entity: {type: Object as PropType<
|
|
14
|
+
entity: {type: Object as PropType<IEntityCrud>, required: true},
|
|
14
15
|
operation: {type: String as PropType<TOperation>, required: true},
|
|
15
16
|
readonly: {type: Boolean, default: false},
|
|
16
17
|
error: {type: String, required: false},
|
|
@@ -38,7 +39,7 @@ const emit = defineEmits(['submit', 'cancel'])
|
|
|
38
39
|
<v-form v-model="valid" ref="formRef" @submit.prevent >
|
|
39
40
|
<v-card flat>
|
|
40
41
|
<v-card-text v-if="error">
|
|
41
|
-
<v-alert color="error">{{
|
|
42
|
+
<v-alert color="error">{{ te(error) ? t(error) : error }}</v-alert>
|
|
42
43
|
</v-card-text>
|
|
43
44
|
<v-card-text>
|
|
44
45
|
<template v-for="field in entity.fields" :key="field.name">
|
|
@@ -52,9 +53,9 @@ const emit = defineEmits(['submit', 'cancel'])
|
|
|
52
53
|
|
|
53
54
|
<v-card-actions>
|
|
54
55
|
<v-spacer></v-spacer>
|
|
55
|
-
<v-btn variant="text" color="grey" @click="cancel">{{
|
|
56
|
+
<v-btn variant="text" color="grey" @click="cancel">{{ t('action.cancel') }}</v-btn>
|
|
56
57
|
<v-btn variant="flat" color="primary" @click="submit">
|
|
57
|
-
{{ operation ?
|
|
58
|
+
{{ operation ? t('action.' + operation) : t('action.sent') }}
|
|
58
59
|
</v-btn>
|
|
59
60
|
</v-card-actions>
|
|
60
61
|
</v-card>
|
|
@@ -1,26 +1,29 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import {computed} from "vue";
|
|
3
3
|
import type {PropType} from "vue";
|
|
4
|
-
import type {ICrudField} from "../interfaces/IEntityCrud";
|
|
5
4
|
import CrudFormList from "./CrudFormList.vue";
|
|
6
5
|
import CrudAutocomplete from "./CrudAutocomplete.vue";
|
|
7
|
-
import EntityCrud from "@/EntityCrud";
|
|
8
6
|
import {useI18n} from "vue-i18n";
|
|
9
7
|
import {useCrudStore} from "../stores/UseCrudStore";
|
|
10
8
|
import {VDateInput} from 'vuetify/labs/VDateInput'
|
|
9
|
+
import type {IEntityCrud, IEntityCrudField} from "@drax/crud-share";
|
|
11
10
|
const {t, te} = useI18n()
|
|
12
11
|
|
|
13
12
|
const store = useCrudStore()
|
|
14
13
|
|
|
15
|
-
const valueModel = defineModel({type: [String, Number, Boolean, Object, Array], default: false})
|
|
14
|
+
const valueModel = defineModel<any>({type: [String, Number, Boolean, Object, Array], default: false})
|
|
16
15
|
|
|
17
16
|
const {index, entity, field} = defineProps({
|
|
18
|
-
entity: {type: Object as PropType<
|
|
19
|
-
field: {type: Object as PropType<
|
|
17
|
+
entity: {type: Object as PropType<IEntityCrud>, required: true},
|
|
18
|
+
field: {type: Object as PropType<IEntityCrudField|undefined>, required: true},
|
|
20
19
|
readonly: {type: Boolean, default: false},
|
|
21
20
|
index: {type: Number, default: 0},
|
|
22
21
|
})
|
|
23
22
|
|
|
23
|
+
if(!field){
|
|
24
|
+
throw new Error("CrudFormField must be provided with a field object")
|
|
25
|
+
}
|
|
26
|
+
|
|
24
27
|
const name = computed(() => index > 0 ? `${field.name}_${index}` : field.name)
|
|
25
28
|
|
|
26
29
|
const label = computed(() => {
|
|
@@ -93,7 +96,7 @@ const inputErrors = computed(() =>
|
|
|
93
96
|
|
|
94
97
|
<crud-autocomplete
|
|
95
98
|
v-if="field.type === 'ref'"
|
|
96
|
-
:entity="entity.getRef(field.ref)
|
|
99
|
+
:entity="entity.getRef(field.ref)"
|
|
97
100
|
:field="field"
|
|
98
101
|
v-model="valueModel"
|
|
99
102
|
:label="label"
|
|
@@ -133,7 +136,7 @@ const inputErrors = computed(() =>
|
|
|
133
136
|
|
|
134
137
|
<crud-autocomplete
|
|
135
138
|
v-if="field.type === 'array.ref'"
|
|
136
|
-
:entity="entity.getRef(field.ref)
|
|
139
|
+
:entity="entity.getRef(field.ref)"
|
|
137
140
|
:field="field"
|
|
138
141
|
v-model="valueModel"
|
|
139
142
|
:multiple="true"
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type {PropType} from "vue";
|
|
3
|
-
import type {ICrudField} from "../interfaces/IEntityCrud";
|
|
4
3
|
import CrudFormField from "./CrudFormField.vue";
|
|
5
|
-
import
|
|
4
|
+
import type {IEntityCrud, IEntityCrudField} from "@drax/crud-share";
|
|
6
5
|
|
|
7
6
|
const valueModel = defineModel({type: Array, default: () => []});
|
|
8
7
|
|
|
9
8
|
const {field} = defineProps({
|
|
10
|
-
entity: {type: Object as PropType<
|
|
11
|
-
field: {type: Object as PropType<
|
|
9
|
+
entity: {type: Object as PropType<IEntityCrud>, required: true},
|
|
10
|
+
field: {type: Object as PropType<IEntityCrudField>, required: true},
|
|
12
11
|
readonly: {type: Boolean, default: false},
|
|
13
12
|
})
|
|
14
13
|
|
|
@@ -16,7 +15,7 @@ function newItem() {
|
|
|
16
15
|
return field.objectFields ? field.objectFields.reduce((acc, field) => ({...acc, [field.name]: field.default }), {}) : []
|
|
17
16
|
}
|
|
18
17
|
|
|
19
|
-
function getField(key: string):
|
|
18
|
+
function getField(key: string):IEntityCrudField|undefined {
|
|
20
19
|
return field.objectFields ? field.objectFields.find(field => field.name === key) : undefined;
|
|
21
20
|
}
|
|
22
21
|
|
|
@@ -43,12 +42,12 @@ function removeItem(index: number) {
|
|
|
43
42
|
<v-col cols="12" v-for="(item,index) in valueModel" :key="index" class="text-right">
|
|
44
43
|
<v-row dense align="center">
|
|
45
44
|
<v-col cols="11">
|
|
46
|
-
<template v-for="key in Object.keys(item)" :key="key">
|
|
45
|
+
<template v-for="key in Object.keys(item as Record<string, any>)" :key="key">
|
|
47
46
|
<crud-form-field
|
|
48
47
|
v-if="hasField(key)"
|
|
49
48
|
:entity="entity"
|
|
50
49
|
:field="getField(key)"
|
|
51
|
-
v-model="valueModel[index][key]"
|
|
50
|
+
v-model="(valueModel[index] as any)[key]"
|
|
52
51
|
:readonly="readonly"
|
|
53
52
|
:index="index"
|
|
54
53
|
/>
|
|
@@ -1,24 +1,34 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type {PropType} from 'vue'
|
|
3
3
|
import {useAuth} from '@drax/identity-vue'
|
|
4
|
-
import EntityCrud from "../EntityCrud";
|
|
5
4
|
import CrudSearch from "./CrudSearch.vue";
|
|
6
5
|
import {useCrud} from "../composables/UseCrud";
|
|
6
|
+
import CrudExportButton from "./buttons/CrudExportButton.vue";
|
|
7
|
+
import CrudImportButton from "./buttons/CrudImportButton.vue";
|
|
8
|
+
import CrudCreateButton from "./buttons/CrudCreateButton.vue";
|
|
9
|
+
import CrudUpdateButton from "./buttons/CrudUpdateButton.vue";
|
|
10
|
+
import CrudDeleteButton from "./buttons/CrudDeleteButton.vue";
|
|
11
|
+
import CrudExportList from "./CrudExportList.vue";
|
|
12
|
+
import type {IEntityCrud} from "@drax/crud-share";
|
|
7
13
|
import {useI18n} from "vue-i18n";
|
|
8
|
-
|
|
14
|
+
import type {IEntityCrudHeader} from "@drax/crud-share";
|
|
15
|
+
|
|
16
|
+
const {t} = useI18n()
|
|
9
17
|
const {hasPermission} = useAuth()
|
|
10
18
|
|
|
11
19
|
const {entity} = defineProps({
|
|
12
|
-
entity: {type: Object as PropType<
|
|
20
|
+
entity: {type: Object as PropType<IEntityCrud>, required: true},
|
|
13
21
|
})
|
|
14
22
|
|
|
15
|
-
const {
|
|
16
|
-
|
|
23
|
+
const {
|
|
24
|
+
loading, itemsPerPage, page, sortBy, search, totalItems, items,
|
|
25
|
+
loadItems
|
|
26
|
+
} = useCrud(entity)
|
|
17
27
|
|
|
18
|
-
const actions = [{title: t('action.actions'),key:'actions', sortable: false, align: '
|
|
19
|
-
const tHeaders = entity.headers.map(header => ({...header, title: t(`${entity.name}.fields.${header.title}`)}))
|
|
28
|
+
const actions: IEntityCrudHeader[] = [{title: t('action.actions'), key: 'actions', sortable: false, align: 'end', minWidth: '140px'}]
|
|
29
|
+
const tHeaders: IEntityCrudHeader[] = entity.headers.map(header => ({...header, title: t(`${entity.name}.fields.${header.title}`)}))
|
|
20
30
|
|
|
21
|
-
const headers = [...tHeaders, ...actions]
|
|
31
|
+
const headers: IEntityCrudHeader[] = [...tHeaders, ...actions]
|
|
22
32
|
|
|
23
33
|
|
|
24
34
|
defineExpose({
|
|
@@ -29,29 +39,46 @@ defineExpose({
|
|
|
29
39
|
|
|
30
40
|
<template>
|
|
31
41
|
<v-data-table-server
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
class="border"
|
|
43
|
+
v-if="hasPermission(entity.permissions.view)"
|
|
44
|
+
v-model:items-per-page="itemsPerPage"
|
|
45
|
+
:items-per-page-options="[5, 10, 20, 50]"
|
|
46
|
+
v-model:page="page"
|
|
47
|
+
v-model:sort-by="sortBy"
|
|
48
|
+
:headers="headers"
|
|
49
|
+
:items="items"
|
|
50
|
+
:items-length="totalItems"
|
|
51
|
+
:loading="loading"
|
|
52
|
+
:search="search"
|
|
53
|
+
:multi-sort="false"
|
|
54
|
+
item-value="name"
|
|
55
|
+
@update:options="loadItems"
|
|
46
56
|
>
|
|
47
57
|
<template v-slot:top>
|
|
48
|
-
<v-toolbar density="compact"
|
|
58
|
+
<v-toolbar density="compact">
|
|
49
59
|
<v-toolbar-title>{{ entity.name }}</v-toolbar-title>
|
|
50
60
|
<v-spacer></v-spacer>
|
|
51
|
-
|
|
52
|
-
|
|
61
|
+
|
|
62
|
+
<crud-import-button
|
|
63
|
+
:entity="entity"
|
|
64
|
+
@import="v => $emit('import', v)"
|
|
65
|
+
/>
|
|
66
|
+
|
|
67
|
+
<crud-export-button
|
|
68
|
+
:entity="entity"
|
|
69
|
+
@export="v => $emit('export',v)"
|
|
70
|
+
/>
|
|
71
|
+
|
|
72
|
+
<crud-create-button
|
|
73
|
+
v-if="entity.isCreatable"
|
|
74
|
+
:entity="entity"
|
|
75
|
+
@click="$emit('create')"
|
|
76
|
+
/>
|
|
77
|
+
|
|
53
78
|
</v-toolbar>
|
|
54
79
|
|
|
80
|
+
<crud-export-list :entity="entity"></crud-export-list>
|
|
81
|
+
|
|
55
82
|
<v-card>
|
|
56
83
|
<v-card-text>
|
|
57
84
|
<crud-search v-model="search"></crud-search>
|
|
@@ -62,21 +89,21 @@ defineExpose({
|
|
|
62
89
|
|
|
63
90
|
|
|
64
91
|
<template v-for="header in entity.headers" :key="header.key" v-slot:[`item.${header.key}`]="{item, value}">
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
92
|
+
<slot :name="`item.${header.key}`" v-bind="{item, value}">
|
|
93
|
+
{{ value }}
|
|
94
|
+
</slot>
|
|
68
95
|
</template>
|
|
69
96
|
|
|
70
97
|
|
|
71
98
|
<template v-slot:item.actions="{item}">
|
|
72
|
-
<
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
<
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
99
|
+
<crud-update-button
|
|
100
|
+
v-if="entity.isEditable && hasPermission(entity.permissions.update)"
|
|
101
|
+
@click="$emit('edit', item)"
|
|
102
|
+
/>
|
|
103
|
+
<crud-delete-button
|
|
104
|
+
v-if="entity.isDeletable && hasPermission(entity.permissions.delete)"
|
|
105
|
+
@click="$emit('delete', item)"
|
|
106
|
+
/>
|
|
80
107
|
</template>
|
|
81
108
|
|
|
82
109
|
</v-data-table-server>
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import {useI18n} from "vue-i18n";
|
|
3
|
+
const {t} = useI18n()
|
|
2
4
|
const model = defineModel<any>()
|
|
3
5
|
</script>
|
|
4
6
|
|
|
@@ -7,7 +9,7 @@ const model = defineModel<any>()
|
|
|
7
9
|
density="compact" class="mr-2"
|
|
8
10
|
variant="outlined"
|
|
9
11
|
append-inner-icon="mdi-magnify"
|
|
10
|
-
:label="
|
|
12
|
+
:label="t('action.search')"
|
|
11
13
|
single-line clearable @click:clear="() => model = ''"
|
|
12
14
|
/>
|
|
13
15
|
</template>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {useI18n} from "vue-i18n";
|
|
3
|
+
|
|
4
|
+
const {t} = useI18n()
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<template>
|
|
8
|
+
<v-tooltip location="top">
|
|
9
|
+
<template v-slot:activator="{ props }">
|
|
10
|
+
<v-btn
|
|
11
|
+
v-bind="{ ...$attrs, ...props }"
|
|
12
|
+
icon="mdi-plus"
|
|
13
|
+
class="mr-1"
|
|
14
|
+
variant="text"
|
|
15
|
+
color="primary"
|
|
16
|
+
>
|
|
17
|
+
</v-btn>
|
|
18
|
+
</template>
|
|
19
|
+
{{ t('action.create')}}
|
|
20
|
+
</v-tooltip>
|
|
21
|
+
</template>
|
|
22
|
+
|
|
23
|
+
<style scoped>
|
|
24
|
+
|
|
25
|
+
</style>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {useI18n} from "vue-i18n";
|
|
3
|
+
|
|
4
|
+
const {t} = useI18n()
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<template>
|
|
8
|
+
<v-tooltip location="top">
|
|
9
|
+
<template v-slot:activator="{ props}">
|
|
10
|
+
<v-btn
|
|
11
|
+
v-bind="{ ...$attrs, ...props }"
|
|
12
|
+
icon="mdi-delete"
|
|
13
|
+
class="mr-1"
|
|
14
|
+
variant="text"
|
|
15
|
+
color="red"
|
|
16
|
+
>
|
|
17
|
+
</v-btn>
|
|
18
|
+
</template>
|
|
19
|
+
{{ t('action.delete')}}
|
|
20
|
+
</v-tooltip>
|
|
21
|
+
</template>
|
|
22
|
+
|
|
23
|
+
<style scoped>
|
|
24
|
+
|
|
25
|
+
</style>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type {PropType} from "vue";
|
|
3
|
+
import EntityCrud from "../../EntityCrud";
|
|
4
|
+
import {useCrud} from "../../composables/UseCrud";
|
|
5
|
+
import {useI18n} from "vue-i18n";
|
|
6
|
+
|
|
7
|
+
const {t} = useI18n()
|
|
8
|
+
|
|
9
|
+
const {entity} = defineProps({
|
|
10
|
+
entity: {type: Object as PropType<EntityCrud>, required: true},
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
const {
|
|
14
|
+
exportLoading
|
|
15
|
+
} = useCrud(entity)
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<template>
|
|
19
|
+
<v-menu v-if="entity.isExportable">
|
|
20
|
+
<template v-slot:activator="{ props: mp }">
|
|
21
|
+
<v-tooltip location="top">
|
|
22
|
+
<template v-slot:activator="{ props: tp }">
|
|
23
|
+
<v-btn
|
|
24
|
+
v-bind="{...mp, ...tp}"
|
|
25
|
+
:disabled="exportLoading"
|
|
26
|
+
class="mr-1"
|
|
27
|
+
color="teal"
|
|
28
|
+
variant="text"
|
|
29
|
+
:loading="exportLoading"
|
|
30
|
+
icon="mdi-database-export-outline"
|
|
31
|
+
></v-btn>
|
|
32
|
+
</template>
|
|
33
|
+
{{ t('action.export')}}
|
|
34
|
+
</v-tooltip>
|
|
35
|
+
|
|
36
|
+
</template>
|
|
37
|
+
<v-list>
|
|
38
|
+
<v-list-item v-for="format in entity.exportFormats" @click="$emit('export', format)">
|
|
39
|
+
<v-list-item-title>{{format}}</v-list-item-title>
|
|
40
|
+
</v-list-item>
|
|
41
|
+
</v-list>
|
|
42
|
+
|
|
43
|
+
</v-menu>
|
|
44
|
+
</template>
|
|
45
|
+
|
|
46
|
+
<style scoped>
|
|
47
|
+
|
|
48
|
+
</style>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type {PropType} from "vue";
|
|
3
|
+
import EntityCrud from "../../EntityCrud";
|
|
4
|
+
import {useCrud} from "../../composables/UseCrud";
|
|
5
|
+
import {useI18n} from "vue-i18n";
|
|
6
|
+
|
|
7
|
+
const {t} = useI18n()
|
|
8
|
+
const {entity} = defineProps({
|
|
9
|
+
entity: {type: Object as PropType<EntityCrud>, required: true},
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
const {
|
|
13
|
+
exportLoading
|
|
14
|
+
} = useCrud(entity)
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<template>
|
|
18
|
+
<div v-if="entity.isImportable">
|
|
19
|
+
<v-tooltip location="top">
|
|
20
|
+
<template v-slot:activator="{ props }">
|
|
21
|
+
<v-btn
|
|
22
|
+
v-bind="props"
|
|
23
|
+
:disabled="exportLoading"
|
|
24
|
+
class="mr-1"
|
|
25
|
+
color="purple"
|
|
26
|
+
variant="text"
|
|
27
|
+
:loading="exportLoading"
|
|
28
|
+
icon="mdi-database-import-outline"
|
|
29
|
+
></v-btn>
|
|
30
|
+
</template>
|
|
31
|
+
{{ t('action.import')}}
|
|
32
|
+
</v-tooltip>
|
|
33
|
+
|
|
34
|
+
</div>
|
|
35
|
+
</template>
|
|
36
|
+
|
|
37
|
+
<style scoped>
|
|
38
|
+
|
|
39
|
+
</style>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {useI18n} from "vue-i18n";
|
|
3
|
+
const {t} = useI18n()
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<template>
|
|
7
|
+
<v-tooltip location="top">
|
|
8
|
+
<template v-slot:activator="{ props}">
|
|
9
|
+
<v-btn
|
|
10
|
+
v-bind="{ ...$attrs, ...props }"
|
|
11
|
+
icon="mdi-pencil"
|
|
12
|
+
class="mr-1"
|
|
13
|
+
variant="text"
|
|
14
|
+
color="primary"
|
|
15
|
+
slim
|
|
16
|
+
>
|
|
17
|
+
</v-btn>
|
|
18
|
+
</template>
|
|
19
|
+
{{ t('action.update')}}
|
|
20
|
+
</v-tooltip>
|
|
21
|
+
</template>
|
|
22
|
+
|
|
23
|
+
<style scoped>
|
|
24
|
+
|
|
25
|
+
</style>
|
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type {IDraxPaginateResult} from "@drax/common-share";
|
|
1
|
+
import type {IDraxPaginateResult, IEntityCrud} from "@drax/crud-share";
|
|
3
2
|
import {useCrudStore} from "../stores/UseCrudStore";
|
|
4
3
|
import {computed} from "vue";
|
|
5
|
-
import type {ICrudField} from "@/interfaces/IEntityCrud";
|
|
6
4
|
|
|
7
|
-
export function useCrud(entity:
|
|
5
|
+
export function useCrud(entity: IEntityCrud) {
|
|
8
6
|
|
|
9
7
|
const store = useCrudStore()
|
|
10
8
|
|
|
11
|
-
async function
|
|
9
|
+
async function doPaginate() {
|
|
12
10
|
store.setLoading(true)
|
|
13
11
|
try {
|
|
14
12
|
const r: IDraxPaginateResult<any> = await entity?.provider.paginate({
|
|
@@ -27,25 +25,68 @@ export function useCrud(entity: EntityCrud) {
|
|
|
27
25
|
}
|
|
28
26
|
}
|
|
29
27
|
|
|
30
|
-
function
|
|
28
|
+
async function doExport(format: 'JSON') {
|
|
29
|
+
store.setExportLoading(true)
|
|
30
|
+
store.setExportListVisible(true)
|
|
31
|
+
try {
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
item[field.name] = new Date(item[field.name])
|
|
36
|
-
}
|
|
37
|
-
})
|
|
33
|
+
if(!entity?.provider.export) {
|
|
34
|
+
throw new Error("exportCsv not implemented")
|
|
35
|
+
}
|
|
38
36
|
|
|
39
|
-
|
|
37
|
+
const headers: string = entity.exportHeaders.join(',')
|
|
38
|
+
|
|
39
|
+
const r: any = await entity?.provider.export({
|
|
40
|
+
format: format,
|
|
41
|
+
headers: headers,
|
|
42
|
+
separator: ";",
|
|
43
|
+
orderBy: store.sortBy[0]?.key,
|
|
44
|
+
order: store.sortBy[0]?.order,
|
|
45
|
+
search: store.search
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
if(r && r.url) {
|
|
49
|
+
store.addExportFile(r)
|
|
50
|
+
store.showMessage("Export successful")
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return r
|
|
54
|
+
|
|
55
|
+
} catch (e) {
|
|
56
|
+
console.error("Error exporting csv", e)
|
|
57
|
+
} finally {
|
|
58
|
+
store.setExportLoading(false)
|
|
59
|
+
}
|
|
40
60
|
}
|
|
41
61
|
|
|
42
62
|
|
|
63
|
+
|
|
64
|
+
|
|
43
65
|
function onCreate() {
|
|
44
66
|
store.setOperation("create")
|
|
45
67
|
store.setForm(entity.form)
|
|
46
68
|
store.setDialog(true)
|
|
47
69
|
}
|
|
48
70
|
|
|
71
|
+
function cast(item: any){
|
|
72
|
+
entity.fields.filter(field => field.type === 'date')
|
|
73
|
+
.forEach(field => {
|
|
74
|
+
item[field.name] = new Date(item[field.name])
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
entity.fields.filter(field => field.type === 'ref')
|
|
78
|
+
.forEach(field => {
|
|
79
|
+
item[field.name] = item[field.name]._id
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
entity.fields.filter(field => field.type === 'array.ref')
|
|
83
|
+
.forEach(field => {
|
|
84
|
+
item[field.name] = item[field.name].map(((i:any) => i._id))
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
return item
|
|
88
|
+
}
|
|
89
|
+
|
|
49
90
|
function onEdit(item: object) {
|
|
50
91
|
store.setOperation("edit")
|
|
51
92
|
store.setForm(cast({...item}))
|
|
@@ -83,7 +124,7 @@ export function useCrud(entity: EntityCrud) {
|
|
|
83
124
|
async function doCreate(formData: any) {
|
|
84
125
|
try {
|
|
85
126
|
await entity?.provider.create(formData)
|
|
86
|
-
await
|
|
127
|
+
await doPaginate()
|
|
87
128
|
store.setDialog(false)
|
|
88
129
|
store.showMessage("Entity created successfully!")
|
|
89
130
|
} catch (e: any) {
|
|
@@ -99,7 +140,7 @@ export function useCrud(entity: EntityCrud) {
|
|
|
99
140
|
async function doUpdate(formData: any) {
|
|
100
141
|
try {
|
|
101
142
|
await entity?.provider.update(formData._id, formData)
|
|
102
|
-
await
|
|
143
|
+
await doPaginate()
|
|
103
144
|
store.setDialog(false)
|
|
104
145
|
store.showMessage("Entity updated successfully!")
|
|
105
146
|
} catch (e: any) {
|
|
@@ -116,7 +157,7 @@ export function useCrud(entity: EntityCrud) {
|
|
|
116
157
|
async function doDelete(formData: any) {
|
|
117
158
|
try {
|
|
118
159
|
await entity?.provider.delete(formData._id)
|
|
119
|
-
await
|
|
160
|
+
await doPaginate()
|
|
120
161
|
store.setDialog(false)
|
|
121
162
|
store.showMessage("Entity deleted successfully!")
|
|
122
163
|
} catch (e: any) {
|
|
@@ -140,11 +181,15 @@ export function useCrud(entity: EntityCrud) {
|
|
|
140
181
|
const search = computed({get(){return store.search} , set(value){store.setSearch(value)}})
|
|
141
182
|
const totalItems = computed({get(){return store.totalItems} , set(value){store.setTotalItems(value)}})
|
|
142
183
|
const items = computed({get(){return store.items} , set(value){store.setItems(value)}})
|
|
184
|
+
const exportFiles = computed({get(){return store.exportFiles} , set(value){store.setExportFiles(value)}})
|
|
185
|
+
const exportLoading = computed({get(){return store.exportLoading} , set(value){store.setExportLoading(value)}})
|
|
186
|
+
const exportListVisible = computed({get(){return store.exportListVisible} , set(value){store.setExportListVisible(value)}})
|
|
143
187
|
|
|
144
188
|
return {
|
|
145
|
-
loadItems, onCreate, onEdit, onDelete, onCancel, onSubmit,
|
|
146
|
-
operation, dialog, form, notify, error, message,
|
|
147
|
-
loading, itemsPerPage, page, sortBy, search, totalItems, items
|
|
189
|
+
loadItems: doPaginate, doExport, onCreate, onEdit, onDelete, onCancel, onSubmit,
|
|
190
|
+
operation, dialog, form, notify, error, message, formValid,
|
|
191
|
+
loading, itemsPerPage, page, sortBy, search, totalItems, items,
|
|
192
|
+
exportFiles,exportLoading,exportListVisible
|
|
148
193
|
}
|
|
149
194
|
|
|
150
195
|
}
|
package/src/index.ts
CHANGED
|
@@ -10,8 +10,6 @@ import {useCrudStore} from "./stores/UseCrudStore";
|
|
|
10
10
|
import {useCrud} from "./composables/UseCrud";
|
|
11
11
|
import {EntityCrud} from "./EntityCrud";
|
|
12
12
|
|
|
13
|
-
import type {IFields, ICrudForm, ICrudHeaders, ICrudPermissions, ICrudRules} from "./interfaces/IEntityCrud";
|
|
14
|
-
export type {IFields, ICrudForm, ICrudHeaders, ICrudPermissions, ICrudRules}
|
|
15
13
|
|
|
16
14
|
export {
|
|
17
15
|
Crud,
|
|
@@ -9,8 +9,8 @@ export const useCrudStore = defineStore('CrudStore', {
|
|
|
9
9
|
form: {} as any,
|
|
10
10
|
formValid: {} as any,
|
|
11
11
|
notify: false as boolean,
|
|
12
|
-
error: '' as string,
|
|
13
12
|
message: '' as string,
|
|
13
|
+
error: '' as string,
|
|
14
14
|
items: [] as any[],
|
|
15
15
|
totalItems: 0 as number,
|
|
16
16
|
itemsPerPage: 5 as number,
|
|
@@ -18,7 +18,10 @@ export const useCrudStore = defineStore('CrudStore', {
|
|
|
18
18
|
search: '' as string,
|
|
19
19
|
sortBy: [] as any[],
|
|
20
20
|
loading: false,
|
|
21
|
-
inputErrors: null
|
|
21
|
+
inputErrors: null,
|
|
22
|
+
exportLoading: false,
|
|
23
|
+
exportFiles: [] as string[],
|
|
24
|
+
exportListVisible: false,
|
|
22
25
|
}
|
|
23
26
|
),
|
|
24
27
|
getters:{
|
|
@@ -80,6 +83,18 @@ export const useCrudStore = defineStore('CrudStore', {
|
|
|
80
83
|
},
|
|
81
84
|
setInputErrors(inputErrors: any) {
|
|
82
85
|
this.inputErrors = inputErrors
|
|
86
|
+
},
|
|
87
|
+
setExportFiles(exportFiles: string[]) {
|
|
88
|
+
this.exportFiles = exportFiles
|
|
89
|
+
},
|
|
90
|
+
addExportFile(exportFile: string) {
|
|
91
|
+
this.exportFiles.push(exportFile)
|
|
92
|
+
},
|
|
93
|
+
setExportLoading(exportLoading: boolean) {
|
|
94
|
+
this.exportLoading = exportLoading
|
|
95
|
+
},
|
|
96
|
+
setExportListVisible(exportListVisible: boolean) {
|
|
97
|
+
this.exportListVisible = exportListVisible
|
|
83
98
|
}
|
|
84
99
|
}
|
|
85
100
|
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
interface ICrudHeaders {
|
|
2
|
-
title: string
|
|
3
|
-
key: string
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
interface ICrudRules {
|
|
7
|
-
[key: string]: Array<Function>
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
interface ICrudField {
|
|
11
|
-
name: string
|
|
12
|
-
type: 'string' | 'number' | 'boolean' | 'date' | 'object' | 'ref' | 'array.string' | 'array.number' | 'array.object' | 'array.ref'
|
|
13
|
-
ref?: string
|
|
14
|
-
objectFields?: ICrudField[]
|
|
15
|
-
label: string,
|
|
16
|
-
default: any
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
interface ICrudForm {
|
|
20
|
-
[key: string]: string | number | boolean | Date | null
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
type IFields = ICrudField[]
|
|
24
|
-
|
|
25
|
-
interface ICrudPermissions {
|
|
26
|
-
manage: string
|
|
27
|
-
view: string
|
|
28
|
-
create: string
|
|
29
|
-
update: string
|
|
30
|
-
delete: string
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export type {ICrudHeaders, ICrudRules, ICrudField, IFields, ICrudForm, ICrudPermissions}
|