easycomponentstools 1.0.0-dev.8 → 1.0.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.
Files changed (56) hide show
  1. package/.idea/vcs.xml +6 -0
  2. package/index.html +13 -0
  3. package/package.json +11 -6
  4. package/src/components/Form/types/map/CustomMapAutoComplete.vue +1 -1
  5. package/src/components/Modal/EasyConfirmationModal.vue +68 -0
  6. package/src/components/Table/Actions/ActionBtn.vue +30 -0
  7. package/src/components/Table/Actions/Menu.vue +43 -0
  8. package/src/components/Table/ColumnValue.vue +38 -0
  9. package/src/components/Table/EasyTable.vue +276 -0
  10. package/src/components/Table/Headers/DialogColumns.vue +147 -0
  11. package/src/components/Table/Headers/ExportData.vue +70 -0
  12. package/src/components/Table/Headers/Filters.vue +219 -0
  13. package/src/components/Table/Headers/Headers.vue +157 -0
  14. package/src/composables/removeMdiSet.ts +19 -0
  15. package/src/composables/useDataTableExport.ts +259 -0
  16. package/src/composables/useHeadersStorage.ts +49 -0
  17. package/src/dev.ts +114 -0
  18. package/src/lang/el/index.ts +2 -0
  19. package/src/lang/el/table.ts +14 -0
  20. package/src/lang/en/index.ts +2 -0
  21. package/src/lang/en/table.ts +14 -0
  22. package/src/main.ts +16 -1
  23. package/src/scss/app.scss +13 -0
  24. package/vite.config.ts +5 -0
  25. package/dist/easyComponents.es.js +0 -35624
  26. package/dist/easyComponents.umd.js +0 -27
  27. package/dist/easycomponents.css +0 -2
  28. package/dist/src/components/Form/EasyForm.vue.d.ts +0 -24
  29. package/dist/src/components/Form/MenuActions.vue.d.ts +0 -7
  30. package/dist/src/components/Form/types/DatePicker.vue.d.ts +0 -16
  31. package/dist/src/components/Form/types/FileInput.vue.d.ts +0 -16
  32. package/dist/src/components/Form/types/Gallery.vue.d.ts +0 -7
  33. package/dist/src/components/Form/types/Input.vue.d.ts +0 -12
  34. package/dist/src/components/Form/types/MapAutoComplete.vue.d.ts +0 -20
  35. package/dist/src/components/Form/types/Number.vue.d.ts +0 -12
  36. package/dist/src/components/Form/types/Password.vue.d.ts +0 -12
  37. package/dist/src/components/Form/types/RangeDatePicker.vue.d.ts +0 -16
  38. package/dist/src/components/Form/types/Selects.vue.d.ts +0 -16
  39. package/dist/src/components/Form/types/SelectsAutoComplete.vue.d.ts +0 -16
  40. package/dist/src/components/Form/types/Switch.vue.d.ts +0 -16
  41. package/dist/src/components/Form/types/Tags.vue.d.ts +0 -16
  42. package/dist/src/components/Form/types/TextArea.vue.d.ts +0 -12
  43. package/dist/src/components/Form/types/map/CustomMapAutoComplete.vue.d.ts +0 -7
  44. package/dist/src/composables/useHelpers.d.ts +0 -9
  45. package/dist/src/composables/useMap.d.ts +0 -41
  46. package/dist/src/lang/el/form.d.ts +0 -5
  47. package/dist/src/lang/el/index.d.ts +0 -7
  48. package/dist/src/lang/en/form.d.ts +0 -5
  49. package/dist/src/lang/en/index.d.ts +0 -7
  50. package/dist/src/main.d.ts +0 -6
  51. package/dist/src/stores/useInfo.d.ts +0 -7
  52. package/dist/src/types/form.d.ts +0 -48
  53. package/dist/src/types/gallery.d.ts +0 -4
  54. package/dist/src/types/map.d.ts +0 -32
  55. package/dist/src/types/plugins.d.ts +0 -14
  56. package/dist/src/types/table.d.ts +0 -79
@@ -0,0 +1,70 @@
1
+ <template>
2
+ <div>
3
+ <v-list-item :disabled="disabledComputed" @click="$useDataTableExport.exportData('pdf')">
4
+ <i class="icon icon-file-sliders" /> PDF
5
+ </v-list-item>
6
+ <v-list-item :disabled="disabledComputed" @click="$useDataTableExport.exportData('csv')">
7
+ <i class="icon icon-file-sliders" /> CSV
8
+ </v-list-item>
9
+ <v-list-item :disabled="disabledComputed" @click="$useDataTableExport.exportData('xlsx')">
10
+ <i class="icon icon-file-sliders" /> EXCEL
11
+ </v-list-item>
12
+ <v-list-item :disabled="disabledComputed" @click="$useDataTableExport.exportData('word')">
13
+ <i class="icon icon-file-sliders" /> WORD
14
+ </v-list-item>
15
+ <v-list-item :disabled="disabledComputed" @click="$useDataTableExport.exportData('print')">
16
+ <i class="icon icon-file-sliders" /> {{ $i18n.t('table.print') }}
17
+ </v-list-item>
18
+ </div>
19
+ </template>
20
+
21
+ <script setup lang="ts">
22
+ import useDataTableExport from '../../../composables/useDataTableExport'
23
+ import { useI18n } from 'vue-i18n'
24
+ import { computed, watch } from 'vue'
25
+ import { AdvancedFiltersDTO, HardFiltersDTO, HeaderDTO, SortDTO } from '../../../types/table'
26
+
27
+ const emit = defineEmits(['loading'])
28
+ const $i18n = useI18n()
29
+ const $useDataTableExport = useDataTableExport()
30
+ const disabledComputed = computed(
31
+ () => !$useDataTableExport.api.value || $useDataTableExport.total.value === 0
32
+ )
33
+
34
+ const setExportDataInfo = (
35
+ api: string,
36
+ headers: HeaderDTO[],
37
+ total: number,
38
+ sort: SortDTO | null,
39
+ filters: AdvancedFiltersDTO[],
40
+ hard_filters: HardFiltersDTO[]
41
+ ) => {
42
+ $useDataTableExport.setApi(api)
43
+ if (sort) $useDataTableExport.setSort({ ...sort })
44
+ $useDataTableExport.setFilters([...filters])
45
+ $useDataTableExport.setHardFilters([...hard_filters])
46
+ $useDataTableExport.setHeaders([...headers])
47
+ $useDataTableExport.setTotal(total)
48
+ }
49
+ const setHeaders = (headers: HeaderDTO[]) => {
50
+ $useDataTableExport.setHeaders([...headers])
51
+ }
52
+ const setFilters = (filters: AdvancedFiltersDTO[]) => {
53
+ $useDataTableExport.setFilters([...filters])
54
+ }
55
+ const setSort = (sort: SortDTO) => {
56
+ $useDataTableExport.setSort({ ...sort })
57
+ }
58
+ const setHardFilters = (HardFilters: HardFiltersDTO[]) => {
59
+ $useDataTableExport.setHardFilters([...HardFilters])
60
+ }
61
+ const setTotal = (total: number) => {
62
+ $useDataTableExport.setTotal(total)
63
+ }
64
+
65
+ watch($useDataTableExport.loading, (v) => emit('loading', v), { immediate: true })
66
+
67
+ defineExpose({ setExportDataInfo, setHeaders, setFilters, setSort, setHardFilters, setTotal })
68
+ </script>
69
+
70
+ <style scoped></style>
@@ -0,0 +1,219 @@
1
+ <template>
2
+ <div style="width: 100%">
3
+ <v-btn
4
+ v-if="active_filters.length !== 0"
5
+ color="primary"
6
+ width="45%"
7
+ class="mr-2"
8
+ @click="clear"
9
+ >
10
+ <i class="icon icon-funnel-x"></i>
11
+ </v-btn>
12
+ <v-btn
13
+ v-bind="props"
14
+ color="primary"
15
+ :width="active_filters.length === 0 ? '100%' : '50%'"
16
+ @click="dialog = true"
17
+ >
18
+ <i class="icon icon-funnel mr-1"></i> {{ $i18n.t('table.filters') }}
19
+ </v-btn>
20
+ <v-dialog v-model="dialog" width="600">
21
+ <v-card>
22
+ <v-card-title>
23
+ <v-row>
24
+ <v-col cols="11">
25
+ {{ $i18n.t('table.filters') }}
26
+ </v-col>
27
+ <v-col cols="1" class="d-flex justify-end">
28
+ <i
29
+ class="icon icon-x"
30
+ style="cursor: pointer"
31
+ @click="dialog = false"
32
+ ></i>
33
+ </v-col>
34
+ </v-row>
35
+ </v-card-title>
36
+ <v-card-text>
37
+ <v-row v-for="(filter, index) in allFilters" :key="index">
38
+ <v-col v-if="isFilterTypeInput(filter.type)" cols="12">
39
+ <v-text-field
40
+ v-model="allFilters[index].value"
41
+ :label="filter.label"
42
+ hide-details
43
+ variant="underlined"
44
+ ></v-text-field>
45
+ </v-col>
46
+ <v-col v-if="filter.type === 'selects'" cols="12">
47
+ <v-select
48
+ v-model="allFilters[index].value"
49
+ :label="filter.label"
50
+ :items="filter.items"
51
+ hide-details
52
+ variant="underlined"
53
+ ></v-select>
54
+ </v-col>
55
+ <v-col
56
+ v-if="filter.type === 'date' && Array.isArray(allFilters[index].value)"
57
+ cols="12"
58
+ >
59
+ <RangeDatePicker
60
+ v-model="allFilters[index].value"
61
+ :input="{ ...inputRangDatePicker, label: filter?.label ?? '' }"
62
+ />
63
+ </v-col>
64
+ <v-col
65
+ v-if="
66
+ filter.type === 'dateTime' && Array.isArray(allFilters[index].value)
67
+ "
68
+ cols="12"
69
+ >
70
+ <RangeDatePicker
71
+ v-model="allFilters[index].value"
72
+ :input="{ ...inputRangDateTimePicker, label: filter?.label ?? '' }"
73
+ />
74
+ </v-col>
75
+ <v-col
76
+ v-if="
77
+ isAdvancedFiltersComparisonDTO(filter.type, allFilters[index].value)
78
+ "
79
+ cols="12"
80
+ >
81
+ <v-row>
82
+ <v-col cols="2">
83
+ <v-select
84
+ v-model="allFilters[index].value.symbol"
85
+ hide-details
86
+ :items="['<', '<=', '=', '>', '>=']"
87
+ variant="underlined"
88
+ ></v-select>
89
+ </v-col>
90
+ <v-col cols="10">
91
+ <v-text-field
92
+ v-model.number="allFilters[index].value.value"
93
+ type="number"
94
+ hide-details
95
+ :label="filter.label"
96
+ variant="underlined"
97
+ ></v-text-field>
98
+ </v-col>
99
+ </v-row>
100
+ </v-col>
101
+ </v-row>
102
+ </v-card-text>
103
+ <v-card-actions class="ma-2">
104
+ <v-row>
105
+ <v-col class="d-flex justify-start">
106
+ <v-btn color="error" variant="flat" @click="dialog = false">
107
+ {{ $i18n.t('table.cancel') }}
108
+ </v-btn>
109
+ </v-col>
110
+ <v-col class="d-flex justify-end">
111
+ <v-btn color="success" variant="flat" @click="submit">
112
+ {{ $i18n.t('table.submit') }}
113
+ </v-btn>
114
+ </v-col>
115
+ </v-row>
116
+ </v-card-actions>
117
+ </v-card>
118
+ </v-dialog>
119
+ </div>
120
+ </template>
121
+
122
+ <script setup lang="ts">
123
+ import RangeDatePicker from '../../Form/types/RangeDatePicker.vue'
124
+ import { onMounted, Ref, ref } from 'vue'
125
+ import { useI18n } from 'vue-i18n'
126
+ import { AdvancedFiltersComparisonDTO, AdvancedFiltersDTO } from '../../../types/table'
127
+ import { InputDTO } from '../../../types/form'
128
+
129
+ type propsType = {
130
+ filters: AdvancedFiltersDTO[]
131
+ }
132
+
133
+ const emit = defineEmits(['search'])
134
+ const dialog: Ref<boolean> = ref(false)
135
+ const $i18n = useI18n()
136
+ const active_filters: Ref<AdvancedFiltersDTO[]> = ref([])
137
+ const allFilters: Ref<AdvancedFiltersDTO[]> = ref([])
138
+ const props = defineProps<propsType>()
139
+ const inputRangDateTimePicker: InputDTO = {
140
+ type: 'rangeDate',
141
+ key: 'inputRangDateTimePicker',
142
+ label: '',
143
+ options: {
144
+ enableTime: true,
145
+ },
146
+ }
147
+ const inputRangDatePicker: InputDTO = {
148
+ type: 'rangeDate',
149
+ key: 'inputRangDatePicker',
150
+ label: '',
151
+ options: {
152
+ enableTime: false,
153
+ },
154
+ }
155
+
156
+ function isAdvancedFiltersComparisonDTO(
157
+ type: string,
158
+ obj: any
159
+ ): obj is AdvancedFiltersComparisonDTO {
160
+ return (
161
+ type === 'comparison' &&
162
+ typeof obj === 'object' &&
163
+ obj !== null &&
164
+ 'symbol' in obj &&
165
+ 'value' in obj
166
+ )
167
+ }
168
+ function isFilterTypeInput(type: string) {
169
+ return type === 'input' || type === 'inArray' || type === 'likeInArray'
170
+ }
171
+ const submit = () => {
172
+ active_filters.value = []
173
+ props.filters.forEach((filter: AdvancedFiltersDTO) => {
174
+ let val = null
175
+ if (
176
+ isAdvancedFiltersComparisonDTO(filter.type, filter.value) ||
177
+ ((filter.type === 'date' || filter.type === 'dateTime') &&
178
+ Array.isArray(filter.value) &&
179
+ filter.value.length !== 0) ||
180
+ ((filter.type === 'input' ||
181
+ filter.type === 'inArray' ||
182
+ filter.type === 'likeInArray' ||
183
+ filter.type === 'selects') &&
184
+ filter.value)
185
+ ) {
186
+ val = filter.value
187
+ }
188
+ if (val) {
189
+ active_filters.value.push({
190
+ type: filter.type,
191
+ column: filter.column,
192
+ value: val,
193
+ })
194
+ }
195
+ })
196
+ emit('search', active_filters.value)
197
+ dialog.value = false
198
+ }
199
+ const clear = () => {
200
+ dialog.value = false
201
+ active_filters.value = []
202
+ emit('search', active_filters.value)
203
+ props.filters.forEach((filter) => {
204
+ if (filter.type === 'comparison') {
205
+ filter.value = { value: 0, symbol: '<' }
206
+ } else if (filter.type === 'date' || filter.type === 'dateTime') {
207
+ filter.value = []
208
+ } else if (filter.value) {
209
+ filter.value = ''
210
+ }
211
+ })
212
+ }
213
+
214
+ onMounted(() => {
215
+ allFilters.value = props.filters
216
+ })
217
+ </script>
218
+
219
+ <style scoped></style>
@@ -0,0 +1,157 @@
1
+ <template>
2
+ <v-row class="mb-2">
3
+ <v-col cols="12" md="12" lg="6" sm="12">
4
+ <h4 v-if="title">{{ title }}</h4>
5
+ <v-chip-group
6
+ v-model="active_hard_filters"
7
+ :multiple="multipleHardFilters"
8
+ filter
9
+ @update:model-value="updateHardFilters"
10
+ >
11
+ <v-chip
12
+ v-for="(hardFilter, index) in hardFilters"
13
+ :key="index"
14
+ :text="hardFilter?.label ?? ''"
15
+ :value="hardFilter.key"
16
+ ></v-chip>
17
+ </v-chip-group>
18
+ </v-col>
19
+ <v-col cols="12" md="12" lg="2" sm="12" class="d-flex justify-end">
20
+ <v-btn v-if="create" color="primary" width="100%" @click="create">
21
+ <i class="icon icon-plus" /> {{ $i18n.t('table.create') }}
22
+ </v-btn>
23
+ </v-col>
24
+ <v-col cols="12" md="12" lg="2" sm="12" class="d-flex justify-end">
25
+ <Filters :filters="advancedFilters" @search="search"></Filters>
26
+ </v-col>
27
+ <v-col cols="12" md="12" lg="2" sm="12" class="d-flex justify-end">
28
+ <v-menu eager>
29
+ <template #activator="{ props: propsMenu }">
30
+ <v-btn color="primary" v-bind="propsMenu" width="100%">
31
+ <v-icon>icon-menu</v-icon>
32
+ {{ $i18n.t('table.more') }}
33
+ </v-btn>
34
+ </template>
35
+ <v-list>
36
+ <v-list-item>
37
+ <DialogColumns
38
+ :headers="props.headers"
39
+ @submit="submitHeaders"
40
+ ></DialogColumns>
41
+ </v-list-item>
42
+ <slot name="moreActions"></slot>
43
+ <ExportData
44
+ v-if="showExportData"
45
+ ref="exportDataRef"
46
+ @loading="(v: boolean) => emit('loading', v)"
47
+ ></ExportData>
48
+ </v-list>
49
+ </v-menu>
50
+ </v-col>
51
+ </v-row>
52
+ <v-row
53
+ v-if="multipleDeletion && selected.length !== 0"
54
+ class="mb-2 d-flex justify-end multipleDeletion"
55
+ >
56
+ <v-col cols="12" md="12" lg="2" sm="12">
57
+ <v-btn color="error" width="100%" @click="multipleDelete">
58
+ <i class="icon icon-trash" /> {{ $i18n.t('table.delete') }}
59
+ </v-btn>
60
+ </v-col>
61
+ </v-row>
62
+ </template>
63
+
64
+ <script setup lang="ts">
65
+ import { AdvancedFiltersDTO, HardFiltersDTO, HeaderDTO, SortDTO } from '../../../types/table'
66
+ import { useI18n } from 'vue-i18n'
67
+ import { nextTick, onMounted, ref, Ref } from 'vue'
68
+ import useHeadersStorage from '../../../composables/useHeadersStorage'
69
+ import Filters from './Filters.vue'
70
+ import DialogColumns from './DialogColumns.vue'
71
+ import ExportData from './ExportData.vue'
72
+
73
+ type propsType = {
74
+ id: string
75
+ headers: HeaderDTO[]
76
+ create?: any
77
+ showExportData?: boolean
78
+ title?: string
79
+ multipleHardFilters?: boolean
80
+ multipleDeletion?: boolean
81
+ hardFilters: HardFiltersDTO[]
82
+ advancedFilters: AdvancedFiltersDTO[]
83
+ selected: any[]
84
+ }
85
+ const props = defineProps<propsType>()
86
+ const $i18n = useI18n()
87
+ const $useHeadersStorage = useHeadersStorage()
88
+ const emit = defineEmits(['loading', 'headers', 'search', 'hardFilters', 'multipleDelete'])
89
+ const active_hard_filters: Ref<any[]> = ref([])
90
+ const exportDataRef: any = ref(null)
91
+
92
+ const updateHardFilters = (hard_filters_keys: any) => {
93
+ const hard_filters: HardFiltersDTO[] = []
94
+ if (!Array.isArray(hard_filters_keys)) hard_filters_keys = [hard_filters_keys]
95
+ hard_filters_keys.forEach((key: string) => {
96
+ const hardFilter = props.hardFilters.filter((v) => v.key === key)
97
+ if (hardFilter.length !== 0) {
98
+ hard_filters.push({
99
+ type: hardFilter[0].type,
100
+ column: hardFilter[0].column,
101
+ })
102
+ }
103
+ })
104
+ exportDataRef.value?.setHardFilters(hard_filters)
105
+ emit('hardFilters', hard_filters)
106
+ }
107
+ const multipleDelete = () => {
108
+ emit('multipleDelete', true)
109
+ }
110
+ const search = (filters: AdvancedFiltersDTO[]) => {
111
+ exportDataRef.value?.setFilters(filters)
112
+ emit('search', filters)
113
+ }
114
+ const submitHeaders = (headers: HeaderDTO[]) => {
115
+ $useHeadersStorage.submitHeaders(headers, props.id)
116
+ const displayHeaders = headers.filter((v) => !v.hidden)
117
+ emit('headers', displayHeaders)
118
+ exportDataRef.value?.setHeaders(displayHeaders)
119
+ }
120
+ const updateExportSortData = (sort: SortDTO) => {
121
+ exportDataRef.value?.setSort(sort)
122
+ }
123
+ const updateExportDataTotal = (total: number) => {
124
+ exportDataRef.value?.setTotal(total)
125
+ }
126
+ const updateExportData = (
127
+ api: string,
128
+ headers: HeaderDTO[],
129
+ total: number,
130
+ sort: SortDTO | null,
131
+ filters: AdvancedFiltersDTO[],
132
+ hard_filters: HardFiltersDTO[]
133
+ ) => {
134
+ const displayHeaders = headers.filter((header: HeaderDTO) => !header.hidden)
135
+ nextTick(() => {
136
+ exportDataRef.value?.setExportDataInfo(
137
+ api,
138
+ displayHeaders,
139
+ total,
140
+ sort,
141
+ filters,
142
+ hard_filters
143
+ )
144
+ })
145
+ }
146
+
147
+ onMounted(() => {
148
+ active_hard_filters.value = props.hardFilters
149
+ .filter((item) => !!item.active)
150
+ .map((item) => item.column)
151
+ updateHardFilters(active_hard_filters.value)
152
+ })
153
+
154
+ defineExpose({ updateExportData, updateExportSortData, updateExportDataTotal })
155
+ </script>
156
+
157
+ <style scoped></style>
@@ -0,0 +1,19 @@
1
+ export const removeMdiSet = () => {
2
+ const run = () => {
3
+ setInterval(() => {
4
+ document.querySelectorAll('.v-icon')?.forEach((icon) => {
5
+ if (
6
+ [...icon.classList].some(
7
+ (cls) => cls.startsWith('icon-') || cls.startsWith('iconapp-')
8
+ )
9
+ ) {
10
+ icon.classList.remove('mdi')
11
+ }
12
+ })
13
+ }, 700)
14
+ }
15
+
16
+ return {
17
+ run,
18
+ }
19
+ }