@drax/crud-vue 2.8.0 → 2.11.0

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 CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "2.8.0",
6
+ "version": "2.11.0",
7
7
  "type": "module",
8
8
  "main": "./src/index.ts",
9
9
  "module": "./src/index.ts",
@@ -24,9 +24,9 @@
24
24
  "format": "prettier --write src/"
25
25
  },
26
26
  "dependencies": {
27
- "@drax/common-front": "^2.8.0",
28
- "@drax/crud-front": "^2.0.0",
29
- "@drax/crud-share": "^2.8.0",
27
+ "@drax/common-front": "^2.11.0",
28
+ "@drax/crud-front": "^2.11.0",
29
+ "@drax/crud-share": "^2.11.0",
30
30
  "@drax/media-vue": "^2.2.1"
31
31
  },
32
32
  "peerDependencies": {
@@ -50,5 +50,5 @@
50
50
  "vue-tsc": "^3.2.4",
51
51
  "vuetify": "^3.11.8"
52
52
  },
53
- "gitHead": "3adeb31ee60eb83c92137dc28162f9226cab06c1"
53
+ "gitHead": "8919d31d4d9512e48ac461b0876dc85a5849daea"
54
54
  }
@@ -7,6 +7,7 @@ import {useAuth} from "@drax/identity-vue";
7
7
  import {useFilterIcon} from "../composables/UseFilterIcon";
8
8
  import {useCrudStore} from "../stores/UseCrudStore";
9
9
  import {useEntityStore} from "../stores/UseEntityStore";
10
+ import {useDynamicFilters} from "../composables/UseDynamicFilters.ts";
10
11
 
11
12
  const {t, te} = useI18n()
12
13
  const valueModel = defineModel({type: [Object]})
@@ -28,12 +29,26 @@ const aFields = computed(() => {
28
29
  .filter((field: IEntityCrudFilter) => !field.permission || hasPermission(field.permission))
29
30
  })
30
31
 
31
- const dynamicFilter = computed(() => {
32
- return (index: string | number) => {
33
- return store.dynamicFilters[index]
34
- }
32
+
33
+ const filtersRef = computed({
34
+ get: () => store.dynamicFilters,
35
+ set: v => store.dynamicFilters = v
35
36
  })
36
37
 
38
+ const {
39
+ dynamicFilter,
40
+ selectableFields,
41
+ getOperations,
42
+ isValueRequired,
43
+ onUpdateField,
44
+ addFilter,
45
+ removeFilter
46
+ } = useDynamicFilters(
47
+ computed(() => entity.name),
48
+ computed(() => storeEntity?.fields || []),
49
+ filtersRef
50
+ )
51
+
37
52
  function filter() {
38
53
  emit('applyFilter')
39
54
  }
@@ -50,81 +65,6 @@ function onUpdateValue() {
50
65
  }
51
66
  }
52
67
 
53
- const fieldI18n = computed(() => {
54
- return (field: IEntityCrudFilter) => {
55
- return te(entity.name.toLowerCase() + ".field." + field.name) ? t(entity.name.toLowerCase() + ".field." + field.name) : field.label
56
- }
57
- })
58
-
59
- const selectableFields = computed(() => {
60
- return storeEntity ? storeEntity.fields
61
- .filter((f: any) => !['fullFile', 'object', 'array.object'].includes(f.type))
62
- .map((f: any) => ({title: fieldI18n.value(f), value: f.name})) : []
63
- })
64
-
65
- function normalizeFieldType(type: string) :string{
66
- if (type === 'array.ref') return 'ref';
67
- if (type === 'array.string') return 'string';
68
- if (type === 'longString') return 'string';
69
- if (type === 'array.number') return 'number';
70
- if (type === 'array.enum') return 'enum';
71
- return type;
72
- }
73
-
74
- function onUpdateField(index: string | number, val: string){
75
-
76
- const field = storeEntity.fields.find((e: any) => e.name === val)
77
- dynamicFilter.value(index).value = null
78
-
79
- if (!field) return
80
-
81
- if(field.ref){
82
- dynamicFilter.value(index).ref = field.ref
83
- }
84
- if(field.refDisplay){
85
- dynamicFilter.value(index).refDisplay = field.refDisplay
86
- }
87
- if(field.enum){
88
- dynamicFilter.value(index).enum = field.enum
89
- }
90
- if(field.type){
91
- dynamicFilter.value(index).type = normalizeFieldType(field.type)
92
-
93
- if(field.type === 'boolean'){
94
- dynamicFilter.value(index).value = false
95
- }
96
-
97
- }
98
- }
99
-
100
- const operations = [
101
- {title: t('operation.equals'), value: 'eq'},
102
- {title: t('operation.notEquals'), value: 'ne'},
103
- {title: t('operation.contains'), value: 'like'},
104
- {title: t('operation.greaterThan'), value: 'gt'},
105
- {title: t('operation.lessThan'), value: 'lt'},
106
- {title: t('operation.greaterThanOrEqual'), value: 'gte'},
107
- {title: t('operation.lessThanOrEqual'), value: 'lte'},
108
- // {title: t('operation.in'), value: 'in'},
109
- // {title: t('operation.notIn'), value: 'nin'},
110
- ]
111
-
112
- function removeFilter(index: string | number){
113
- store.removeDynamicFilter(index)
114
- }
115
-
116
- function addFilter() {
117
- const filter: IEntityCrudFilter = {
118
- default: undefined,
119
- label: "",
120
- name: '',
121
- operator: 'eq',
122
- type: 'string',
123
- permission: '',
124
- value: ''
125
- }
126
- store.addDynamicFilter(filter)
127
- }
128
68
 
129
69
 
130
70
  const emit = defineEmits(['applyFilter', 'clearFilter'])
@@ -141,29 +81,31 @@ const emit = defineEmits(['applyFilter', 'clearFilter'])
141
81
  <v-col cols="12" sm="4">
142
82
  <v-select
143
83
  :items="selectableFields"
144
- v-model="dynamicFilter(index).name"
84
+ v-model="dynamicFilter(index)!.name"
145
85
  :label="t('crud.field')"
146
86
  density="compact"
147
87
  variant="outlined"
148
88
  hide-details
149
- @update:modelValue="(v:string) => onUpdateField(index, v)"
89
+ @update:modelValue="(v:string) => onUpdateField(index, true)"
150
90
  />
151
91
  </v-col>
152
92
  <v-col cols="12" sm="3">
153
93
  <v-select
154
- :items="operations"
155
- v-model="dynamicFilter(index).operator"
94
+ :items="getOperations(index)"
95
+ v-model="dynamicFilter(index)!.operator"
156
96
  :label="t('crud.operator')"
157
97
  density="compact"
158
98
  variant="outlined"
159
99
  hide-details
100
+ @update:modelValue="(v:string) => onUpdateField(index)"
160
101
  />
161
102
  </v-col>
162
103
  <v-col cols="10" sm="4">
163
104
  <crud-form-field
105
+ v-if="isValueRequired(index)"
164
106
  :field="filter"
165
107
  :entity="entity"
166
- v-model="dynamicFilter(index).value"
108
+ v-model="dynamicFilter(index)!.value"
167
109
  :clearable="true"
168
110
  density="compact"
169
111
  variant="outlined"
@@ -0,0 +1,167 @@
1
+ import {computed} from "vue"
2
+ import type {Ref} from "vue"
3
+ import {useI18n} from "vue-i18n"
4
+ import type {
5
+ IEntityCrudFilter,
6
+ IEntityCrudFieldTypes
7
+ } from "@drax/crud-share"
8
+
9
+ export function useDynamicFilters(
10
+ entityName: Ref<string | undefined>,
11
+ entityFields: Ref<any[]>,
12
+ filters: Ref<IEntityCrudFilter[]>
13
+ ) {
14
+
15
+ const {t, te} = useI18n()
16
+
17
+ const dynamicFilter = computed(() => {
18
+ return (index: number) => filters.value[index]
19
+ })
20
+
21
+ const fieldI18n = computed(() => {
22
+ return (field: any) => {
23
+ const key = entityName.value?.toLowerCase() + ".field." + field.name
24
+ return te(key) ? t(key) : field.label
25
+ }
26
+ })
27
+
28
+ const selectableFields = computed(() => {
29
+ return entityFields.value
30
+ ?.filter((f: any) => !['fullFile', 'object', 'array.object'].includes(f.type))
31
+ .map((f: any) => ({
32
+ title: fieldI18n.value(f),
33
+ value: f.name
34
+ })) || []
35
+ })
36
+
37
+ function normalizeFieldType(type: string): IEntityCrudFieldTypes {
38
+ if (type === 'array.ref') return 'ref'
39
+ if (type === 'array.string') return 'string'
40
+ if (type === 'longString') return 'string'
41
+ if (type === 'array.number') return 'number'
42
+ if (type === 'array.enum') return 'enum'
43
+ return type as IEntityCrudFieldTypes
44
+ }
45
+
46
+ function onUpdateField(index: number, resetOperator = false) {
47
+
48
+ const filter = filters.value[index]
49
+ if (!filter) return
50
+
51
+ if(resetOperator){
52
+ filter.operator = 'eq'
53
+ }
54
+
55
+ let filterName = filter.name
56
+
57
+ const field = entityFields.value?.find((e: any) => e.name === filterName)
58
+
59
+ filter.value = null
60
+ if (!field) return
61
+
62
+ if (field.ref) filter.ref = field.ref
63
+ if (field.refDisplay) filter.refDisplay = field.refDisplay
64
+ if (field.enum) filter.enum = field.enum
65
+
66
+ if (field.type) {
67
+
68
+ filter.type = normalizeFieldType(field.type)
69
+
70
+ //aplico default false si type es boolean
71
+ if (field.type === "boolean") {
72
+ filter.value = false
73
+ }
74
+
75
+ }
76
+
77
+ //Convierto a multiple si operadores son in o nin
78
+ if (filter.operator && ['in','nin'].includes(filter.operator)) {
79
+
80
+ if (['ref', 'array.ref'].includes(field.type)) {
81
+ filter.type = 'array.ref'
82
+ }
83
+
84
+ if (['string', 'longString', 'array.string'].includes(field.type)) {
85
+ filter.type = 'array.string'
86
+ }
87
+
88
+ if (['enum', 'array.enum'].includes(field.type)) {
89
+ filter.type = 'array.enum'
90
+ }
91
+
92
+ }
93
+ }
94
+
95
+ function addFilter() {
96
+ const filter: IEntityCrudFilter = {
97
+ default: undefined,
98
+ label: "",
99
+ name: "",
100
+ operator: "eq",
101
+ type: "string",
102
+ permission: "",
103
+ value: ""
104
+ }
105
+
106
+ filters.value.push(filter)
107
+ }
108
+
109
+ function removeFilter(index: number) {
110
+ filters.value.splice(index, 1)
111
+ }
112
+
113
+ const operations = [
114
+ {title: t('operation.equals'), value: 'eq'},
115
+ {title: t('operation.contains'), value: 'like'},
116
+ {title: t('operation.empty'), value: 'empty'},
117
+ {title: t('operation.notEquals'), value: 'ne'},
118
+ {title: t('operation.greaterThan'), value: 'gt'},
119
+ {title: t('operation.lessThan'), value: 'lt'},
120
+ {title: t('operation.greaterThanOrEqual'), value: 'gte'},
121
+ {title: t('operation.lessThanOrEqual'), value: 'lte'},
122
+ {title: t('operation.in'), value: 'in'},
123
+ {title: t('operation.notIn'), value: 'nin'},
124
+ ]
125
+
126
+ const getOperations = computed(() => {
127
+ return (index: number) => {
128
+
129
+ const filter = filters.value[index]
130
+ if (!filter || !filter.type) return []
131
+
132
+ return operations.filter(op => {
133
+ if (['ref','array.ref'].includes(filter.type) && ['gt', 'gte', 'lt', 'lte', 'like'].includes(op.value)) {
134
+ return false
135
+ }
136
+ return true
137
+ })
138
+ }
139
+ })
140
+
141
+ const isValueRequired = computed(() => {
142
+ return (index: number) => {
143
+ const filter = filters.value[index]
144
+ if (!filter || !filter.operator){
145
+ return false
146
+ }
147
+ if (['empty'].includes(filter.operator)) {
148
+ return false
149
+ }
150
+ return true
151
+ }
152
+ })
153
+
154
+
155
+ return {
156
+ dynamicFilter,
157
+ selectableFields,
158
+ fieldI18n,
159
+ operations,
160
+ getOperations,
161
+ isValueRequired,
162
+ addFilter,
163
+ removeFilter,
164
+ onUpdateField,
165
+ normalizeFieldType
166
+ }
167
+ }