@drax/crud-vue 2.11.0 → 3.1.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.11.0",
6
+ "version": "3.1.0",
7
7
  "type": "module",
8
8
  "main": "./src/index.ts",
9
9
  "module": "./src/index.ts",
@@ -24,10 +24,10 @@
24
24
  "format": "prettier --write src/"
25
25
  },
26
26
  "dependencies": {
27
- "@drax/common-front": "^2.11.0",
28
- "@drax/crud-front": "^2.11.0",
29
- "@drax/crud-share": "^2.11.0",
30
- "@drax/media-vue": "^2.2.1"
27
+ "@drax/common-front": "^3.0.0",
28
+ "@drax/crud-front": "^3.0.0",
29
+ "@drax/crud-share": "^3.1.0",
30
+ "@drax/media-vue": "^3.1.0"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "pinia": "^3.0.4",
@@ -50,5 +50,5 @@
50
50
  "vue-tsc": "^3.2.4",
51
51
  "vuetify": "^3.11.8"
52
52
  },
53
- "gitHead": "8919d31d4d9512e48ac461b0876dc85a5849daea"
53
+ "gitHead": "262ea8f861c84ca1ad4d555545c5a94b95dbf25e"
54
54
  }
package/src/EntityCrud.ts CHANGED
@@ -209,6 +209,10 @@ class EntityCrud implements IEntityCrud {
209
209
  return false
210
210
  }
211
211
 
212
+ get isFilterable(){
213
+ return true
214
+ }
215
+
212
216
  get dialogFullscreen() {
213
217
  return false
214
218
  }
@@ -7,9 +7,9 @@ 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
+ import {useDynamicFilters} from "../composables/UseDynamicFilters";
11
11
 
12
- const {t, te} = useI18n()
12
+ const {t} = useI18n()
13
13
  const valueModel = defineModel({type: [Object]})
14
14
  const {hasPermission} = useAuth()
15
15
  const {filterIcon} = useFilterIcon()
@@ -65,6 +65,30 @@ function onUpdateValue() {
65
65
  }
66
66
  }
67
67
 
68
+ function numericIndex(index: string | number) {
69
+ return typeof index === 'number' ? index : Number(index)
70
+ }
71
+
72
+ function getDynamicFilter(index: string | number) {
73
+ return dynamicFilter.value(numericIndex(index))
74
+ }
75
+
76
+ function updateDynamicField(index: string | number, resetOperator = false) {
77
+ onUpdateField(numericIndex(index), resetOperator)
78
+ }
79
+
80
+ function getDynamicOperations(index: string | number) {
81
+ return getOperations.value(numericIndex(index))
82
+ }
83
+
84
+ function dynamicValueRequired(index: string | number) {
85
+ return isValueRequired.value(numericIndex(index))
86
+ }
87
+
88
+ function deleteFilter(index: string | number) {
89
+ removeFilter(numericIndex(index))
90
+ }
91
+
68
92
 
69
93
 
70
94
  const emit = defineEmits(['applyFilter', 'clearFilter'])
@@ -81,31 +105,31 @@ const emit = defineEmits(['applyFilter', 'clearFilter'])
81
105
  <v-col cols="12" sm="4">
82
106
  <v-select
83
107
  :items="selectableFields"
84
- v-model="dynamicFilter(index)!.name"
108
+ v-model="getDynamicFilter(index)!.name"
85
109
  :label="t('crud.field')"
86
110
  density="compact"
87
111
  variant="outlined"
88
112
  hide-details
89
- @update:modelValue="(v:string) => onUpdateField(index, true)"
113
+ @update:modelValue="(_v:string) => updateDynamicField(index, true)"
90
114
  />
91
115
  </v-col>
92
116
  <v-col cols="12" sm="3">
93
117
  <v-select
94
- :items="getOperations(index)"
95
- v-model="dynamicFilter(index)!.operator"
118
+ :items="getDynamicOperations(index)"
119
+ v-model="getDynamicFilter(index)!.operator"
96
120
  :label="t('crud.operator')"
97
121
  density="compact"
98
122
  variant="outlined"
99
123
  hide-details
100
- @update:modelValue="(v:string) => onUpdateField(index)"
124
+ @update:modelValue="(_v:string) => updateDynamicField(index)"
101
125
  />
102
126
  </v-col>
103
127
  <v-col cols="10" sm="4">
104
128
  <crud-form-field
105
- v-if="isValueRequired(index)"
129
+ v-if="dynamicValueRequired(index)"
106
130
  :field="filter"
107
131
  :entity="entity"
108
- v-model="dynamicFilter(index)!.value"
132
+ v-model="getDynamicFilter(index)!.value"
109
133
  :clearable="true"
110
134
  density="compact"
111
135
  variant="outlined"
@@ -115,7 +139,7 @@ const emit = defineEmits(['applyFilter', 'clearFilter'])
115
139
  />
116
140
  </v-col>
117
141
  <v-col cols="2" sm="1">
118
- <v-btn @click="removeFilter(index)"
142
+ <v-btn @click="deleteFilter(index)"
119
143
  icon="mdi-delete"
120
144
  class="mr-1"
121
145
  variant="text"
@@ -9,9 +9,14 @@ import {useI18n} from "vue-i18n";
9
9
  import {useCrudStore} from "../stores/UseCrudStore";
10
10
  import {VDateInput} from 'vuetify/labs/VDateInput'
11
11
  import type {IEntityCrud, IEntityCrudField, IEntityCrudFilter} from "@drax/crud-share";
12
- import {MediaField, MediaFullField} from "@drax/media-vue";
13
12
  import {useAuth} from "@drax/identity-vue";
14
13
 
14
+ //TODO: Ver si esto no puede traer problemas...
15
+ import MediaField from "@drax/media-vue/src/components/MediaField.vue";
16
+ import MediaFullField from "@drax/media-vue/src/components/MediaFullField.vue";
17
+
18
+
19
+
15
20
  const {t, te} = useI18n()
16
21
 
17
22
  const {hasPermission} = useAuth()
@@ -11,6 +11,7 @@ import CrudDeleteButton from "./buttons/CrudDeleteButton.vue";
11
11
  import CrudViewButton from "./buttons/CrudViewButton.vue";
12
12
  import CrudGroupByButton from "./buttons/CrudGroupByButton.vue";
13
13
  import CrudColumnsButton from "./buttons/CrudColumnsButton.vue";
14
+ import CrudFilterButton from "./buttons/CrudFilterButton.vue";
14
15
  import CrudExportList from "./CrudExportList.vue";
15
16
  import type {IEntityCrud} from "@drax/crud-share";
16
17
  import {useI18n} from "vue-i18n";
@@ -19,6 +20,7 @@ import { useCrudColumns } from "../composables/UseCrudColumns";
19
20
  import CrudFiltersDynamic from "./CrudFiltersDynamic.vue";
20
21
  import CrudFiltersAction from "./CrudFiltersAction.vue";
21
22
 
23
+
22
24
  const {t, te} = useI18n()
23
25
  const {hasPermission} = useAuth()
24
26
 
@@ -90,7 +92,6 @@ defineEmits(['import', 'export', 'create', 'update', 'delete', 'view', 'edit'])
90
92
  <v-spacer></v-spacer>
91
93
 
92
94
  <slot name="toolbar">
93
-
94
95
  </slot>
95
96
 
96
97
  <crud-import-button
@@ -108,6 +109,10 @@ defineEmits(['import', 'export', 'create', 'update', 'delete', 'view', 'edit'])
108
109
  :entity="entity"
109
110
  />
110
111
 
112
+
113
+ <crud-filter-button
114
+ :entity="entity" />
115
+
111
116
  <crud-columns-button
112
117
  v-if="entity.isColumnSelectable"
113
118
  :entity="entity"
@@ -19,6 +19,7 @@ import CrudFilters from "./CrudFilters.vue";
19
19
  import {useCrudColumns} from "../composables/UseCrudColumns";
20
20
  import CrudFiltersDynamic from "./CrudFiltersDynamic.vue";
21
21
  import CrudFiltersAction from "./CrudFiltersAction.vue";
22
+ import CrudFilterButton from "./buttons/CrudFilterButton.vue";
22
23
 
23
24
  const {t, te} = useI18n()
24
25
  const {hasPermission} = useAuth()
@@ -29,7 +30,8 @@ const {entity} = defineProps({
29
30
 
30
31
  const {
31
32
  loading, itemsPerPage, page, search, totalItems, items,
32
- doPaginate, filters, applyFilters, clearFilters, paginationError
33
+ doPaginate, filters, applyFilters, clearFilters, paginationError,
34
+ isDynamicFiltersEnable
33
35
  } = useCrud(entity)
34
36
 
35
37
  // Usar el composable de columnas
@@ -51,40 +53,50 @@ onMounted(() => {
51
53
  <template>
52
54
  <div v-if="hasPermission(entity.permissions.view)" class="d-flex flex-column h-100 pb-4">
53
55
  <!-- Toolbar -->
54
- <v-toolbar :class="entity.toolbarClass" :density="entity.toolbarDensity">
56
+ <v-toolbar :class="entity.toolbarClass" :density="entity.toolbarDensity" extended>
55
57
  <v-toolbar-title>
56
58
  {{ te(`${entity.name.toLowerCase()}.crud`) ? t(`${entity.name.toLowerCase()}.crud`) : entity.name }}
57
59
  </v-toolbar-title>
58
60
  <v-spacer></v-spacer>
61
+ <template v-slot:extension>
59
62
 
60
- <slot name="toolbar">
61
- </slot>
63
+ <v-row justify="end" class="px-2 border-t-sm" >
64
+ <slot name="toolbar">
65
+ </slot>
62
66
 
63
- <crud-import-button
64
- :entity="entity"
65
- @import="(v:any) => $emit('import', v)"
66
- />
67
+ <crud-import-button
68
+ :entity="entity"
69
+ @import="(v:any) => $emit('import', v)"
70
+ />
67
71
 
68
- <crud-export-button
69
- :entity="entity"
70
- @export="(v:any) => $emit('export',v)"
71
- />
72
+ <crud-export-button
73
+ :entity="entity"
74
+ @export="(v:any) => $emit('export',v)"
75
+ />
72
76
 
73
- <crud-group-by-button
74
- v-if="entity.isGroupable"
75
- :entity="entity"
76
- />
77
+ <crud-group-by-button
78
+ v-if="entity.isGroupable"
79
+ :entity="entity"
80
+ />
81
+
82
+ <crud-filter-button
83
+ :entity="entity" />
84
+
85
+ <crud-columns-button
86
+ v-if="entity.isColumnSelectable"
87
+ :entity="entity"
88
+ />
89
+
90
+ <crud-create-button
91
+ v-if="entity.isCreatable"
92
+ :entity="entity"
93
+ @click="$emit('create')"
94
+ />
95
+ </v-row>
96
+
97
+ </template>
77
98
 
78
- <crud-columns-button
79
- v-if="entity.isColumnSelectable"
80
- :entity="entity"
81
- />
82
99
 
83
- <crud-create-button
84
- v-if="entity.isCreatable"
85
- :entity="entity"
86
- @click="$emit('create')"
87
- />
88
100
  </v-toolbar>
89
101
 
90
102
  <crud-export-list
@@ -124,7 +136,7 @@ onMounted(() => {
124
136
  </crud-filters>
125
137
 
126
138
  <crud-filters-dynamic
127
- v-if="entity.dynamicFiltersEnable"
139
+ v-if="isDynamicFiltersEnable"
128
140
  :entity="entity"
129
141
  v-model="filters"
130
142
  :auto-filter="!entity.filterButtons"
@@ -18,6 +18,7 @@ import CrudFilters from "./CrudFilters.vue";
18
18
  import { useCrudColumns } from "../composables/UseCrudColumns";
19
19
  import CrudFiltersDynamic from "./CrudFiltersDynamic.vue";
20
20
  import CrudFiltersAction from "./CrudFiltersAction.vue";
21
+ import CrudFilterButton from "./buttons/CrudFilterButton.vue";
21
22
 
22
23
  const {t, te} = useI18n()
23
24
  const {hasPermission} = useAuth()
@@ -28,7 +29,8 @@ const {entity} = defineProps({
28
29
 
29
30
  const {
30
31
  loading, itemsPerPage, page, sortBy, search, totalItems, items,
31
- doPaginate, filters, applyFilters, clearFilters, paginationError
32
+ doPaginate, filters, applyFilters, clearFilters, paginationError,
33
+ isDynamicFiltersEnable
32
34
  } = useCrud(entity)
33
35
 
34
36
  // Usar el composable de columnas
@@ -108,6 +110,9 @@ defineEmits(['import', 'export', 'create', 'update', 'delete', 'view', 'edit'])
108
110
  :entity="entity"
109
111
  />
110
112
 
113
+ <crud-filter-button
114
+ :entity="entity" />
115
+
111
116
  <crud-columns-button
112
117
  v-if="entity.isColumnSelectable"
113
118
  :entity="entity"
@@ -158,7 +163,7 @@ defineEmits(['import', 'export', 'create', 'update', 'delete', 'view', 'edit'])
158
163
  </crud-filters>
159
164
 
160
165
  <crud-filters-dynamic
161
- v-if="entity.dynamicFiltersEnable"
166
+ v-if="isDynamicFiltersEnable"
162
167
  :entity="entity"
163
168
  v-model="filters"
164
169
  :auto-filter="!entity.filterButtons"
@@ -0,0 +1,42 @@
1
+ <script setup lang="ts">
2
+ import {useI18n} from "vue-i18n";
3
+ import {computed} from "vue";
4
+ import type {PropType} from "vue";
5
+ import type {IEntityCrud} from "@drax/crud-share";
6
+ import {useCrudStore} from "../../stores/UseCrudStore";
7
+
8
+ const {entity} = defineProps({
9
+ entity: {type: Object as PropType<IEntityCrud>, required: true},
10
+ })
11
+
12
+ const store = useCrudStore(entity?.name)
13
+
14
+ let dynamicFiltersEnable = computed({
15
+ get: () => store.dynamicFiltersEnable,
16
+ set: (value: boolean) => store.setDynamicFiltersEnable(value)
17
+ })
18
+
19
+ const {t} = useI18n()
20
+ </script>
21
+
22
+ <template>
23
+ <div v-if="entity.isFilterable">
24
+ <v-tooltip location="top">
25
+ <template v-slot:activator="{ props }">
26
+ <v-btn
27
+ v-bind="{ ...$attrs, ...props }"
28
+ :icon="dynamicFiltersEnable ? 'mdi-filter-off' : 'mdi-filter' "
29
+ class="mr-1"
30
+ variant="text"
31
+ @click="dynamicFiltersEnable = !dynamicFiltersEnable"
32
+ >
33
+ </v-btn>
34
+ </template>
35
+ {{ t('action.filters') }}
36
+ </v-tooltip>
37
+ </div>
38
+ </template>
39
+
40
+ <style scoped>
41
+
42
+ </style>
@@ -19,6 +19,10 @@ export function useCrud(entity: IEntityCrud) {
19
19
 
20
20
  const {t: $t, te: $te} = useI18n()
21
21
 
22
+ const isDynamicFiltersEnable = computed(() => {
23
+ return entity.dynamicFiltersEnable && store.dynamicFiltersEnable
24
+ })
25
+
22
26
  const exportError = computed({
23
27
  get() {
24
28
  return store.exportError
@@ -477,7 +481,8 @@ export function useCrud(entity: IEntityCrud) {
477
481
  loading, itemsPerPage, page, sortBy, search, totalItems, items,
478
482
  prepareFilters, filters, clearFilters, applyFilters,
479
483
  exportFiles, exportLoading, exportListVisible, exportError,
480
- cloneItem, cast, prepareEdit
484
+ cloneItem, cast, prepareEdit,
485
+ isDynamicFiltersEnable
481
486
  }
482
487
 
483
488
  }
package/src/index.ts CHANGED
@@ -4,6 +4,8 @@ import CrudForm from "./components/CrudForm.vue";
4
4
  import CrudFormField from "./components/CrudFormField.vue";
5
5
  import CrudFormList from "./components/CrudFormList.vue";
6
6
  import CrudList from "./components/CrudList.vue";
7
+ import CrudListTable from "./components/CrudListTable.vue";
8
+ import CrudListGallery from "./components/CrudListGallery.vue";
7
9
  import CrudFilters from "./components/CrudFilters.vue";
8
10
  import CrudNotify from "./components/CrudNotify.vue";
9
11
  import CrudSearch from "./components/CrudSearch.vue";
@@ -25,6 +27,8 @@ export {
25
27
  CrudFormField,
26
28
  CrudFormList,
27
29
  CrudList,
30
+ CrudListTable,
31
+ CrudListGallery,
28
32
  CrudNotify,
29
33
  CrudSearch,
30
34
  CrudAutocomplete,
@@ -1,5 +1,5 @@
1
1
  import {defineStore} from "pinia";
2
- import type {IEntityCrudOperation, IDraxFieldFilter} from "@drax/crud-share";
2
+ import type {IEntityCrudOperation, IDraxFieldFilter, IEntityCrudFilter} from "@drax/crud-share";
3
3
 
4
4
  export const useCrudStore = (id: string = 'entity') => defineStore('CrudStore'+id, {
5
5
  state: () => (
@@ -13,7 +13,16 @@ export const useCrudStore = (id: string = 'entity') => defineStore('CrudStore'+i
13
13
  error: '' as string,
14
14
  paginationError: '' as string,
15
15
  filters: [] as IDraxFieldFilter[],
16
- dynamicFilters: [] as IDraxFieldFilter[],
16
+ dynamicFilters: [{
17
+ default: undefined,
18
+ label: "",
19
+ name: "",
20
+ operator: "eq",
21
+ type: "string",
22
+ permission: "",
23
+ value: ""
24
+ }] as IEntityCrudFilter[],
25
+ dynamicFiltersEnable: false as boolean,
17
26
  items: [] as any[],
18
27
  totalItems: 0 as number,
19
28
  itemsPerPage: 10 as number,
@@ -150,6 +159,9 @@ export const useCrudStore = (id: string = 'entity') => defineStore('CrudStore'+i
150
159
  this.dynamicFilters[index].value = value
151
160
  }
152
161
  },
162
+ setDynamicFiltersEnable(enable: boolean) {
163
+ this.dynamicFiltersEnable = enable
164
+ },
153
165
  setVisibleColumns(columns: string[]) {
154
166
  this.visibleColumns = columns
155
167
  },