evui 3.4.2 → 3.4.5

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.
@@ -0,0 +1,282 @@
1
+ <template>
2
+ <template v-if="isShowFilterSetting">
3
+ <teleport to="#ev-grid-column-setting-modal">
4
+ <section
5
+ v-clickoutside="() => { isShowFilterSetting = false }"
6
+ class="ev-grid-filter-setting"
7
+ :style="{
8
+ top: $props.position.top,
9
+ left: $props.position.left,
10
+ }"
11
+ >
12
+ <div class="ev-grid-filter-setting__header">
13
+ <ev-icon icon="ev-icon-filter-list"></ev-icon>
14
+ <span class="header-title"> Filter ({{$props.column.caption}}) </span>
15
+ </div>
16
+ <div class="ev-grid-filter-setting__content">
17
+ <div
18
+ v-for="(item, idx) in filteringItems"
19
+ :key="idx"
20
+ class="ev-grid-filter-setting__row">
21
+ <ev-select
22
+ v-model="item.operator"
23
+ class="ev-grid-filter-setting__row--operator"
24
+ :items="items1"
25
+ :disabled="idx > 1"
26
+ :style="{
27
+ visibility: idx > 0 ? 'visible' : 'hidden',
28
+ }"
29
+ @change="changeOperator"
30
+ />
31
+ <ev-select
32
+ v-model="item.comparison"
33
+ class="ev-grid-filter-setting__row--comparison"
34
+ :items="items2"
35
+ @change="changeComparison(item.comparison, idx)"
36
+ />
37
+ <ev-text-field
38
+ v-model="item.value"
39
+ class="ev-grid-filter-setting__row--value"
40
+ :disabled="item.comparison === 'isEmpty' || item.comparison === 'isNotEmpty'"
41
+ />
42
+ <div
43
+ class="ev-grid-filter-setting__row--button"
44
+ >
45
+ <ev-icon
46
+ icon="ev-icon-trash2"
47
+ @click="removeRow(idx)"
48
+ />
49
+ </div>
50
+ </div>
51
+ <div class="ev-grid-filter-setting__row--button add">
52
+ <ev-icon
53
+ icon="ev-icon-add"
54
+ @click="addRow"
55
+ />
56
+ </div>
57
+ </div>
58
+ <div class="ev-grid-filter-setting__footer">
59
+ <ev-button
60
+ type="primary"
61
+ @click="applyFiltering"
62
+ >
63
+ OK
64
+ </ev-button>
65
+ </div>
66
+ </section>
67
+ </teleport>
68
+ </template>
69
+ </template>
70
+
71
+ <script>
72
+ import { clickoutside } from '@/directives/clickoutside';
73
+ import { computed, ref, watch } from 'vue';
74
+
75
+ export default {
76
+ name: 'EVGridFilterSetting',
77
+ directives: {
78
+ clickoutside,
79
+ },
80
+ props: {
81
+ isShow: {
82
+ type: Boolean,
83
+ default: false,
84
+ },
85
+ position: {
86
+ type: Object,
87
+ default: () => ({
88
+ top: 0,
89
+ left: 0,
90
+ }),
91
+ },
92
+ column: {
93
+ type: Object,
94
+ default: () => ({}),
95
+ },
96
+ items: {
97
+ type: Object,
98
+ default: () => ({}),
99
+ },
100
+ },
101
+ emits: {
102
+ 'update:isShow': null,
103
+ 'apply-filtering': null,
104
+ },
105
+ setup(props, { emit }) {
106
+ const filteringItems = ref([]);
107
+ const columnField = computed(() => props.column?.field);
108
+ const items1 = [
109
+ { name: 'AND', value: 'and' },
110
+ { name: 'OR', value: 'or' },
111
+ ];
112
+ const numberItems = [
113
+ { name: '=', value: '=' },
114
+ { name: '!=', value: '!=' },
115
+ { name: '<', value: '<' },
116
+ { name: '>', value: '>' },
117
+ { name: '<=', value: '<=' },
118
+ { name: '>=', value: '>=' },
119
+ ];
120
+ const stringItems = [
121
+ { name: 's%', value: 's%' }, // starts with
122
+ { name: '%s', value: '%s' }, // ends with
123
+ { name: '%s%', value: '%s%' }, // contains
124
+ { name: 'Not Like', value: 'notLike' }, // does not contains
125
+ { name: '=', value: '=' }, // is
126
+ { name: '!=', value: '!=' }, // is not
127
+ ];
128
+ const commonItems = [
129
+ { name: 'Is empty', value: 'isEmpty' },
130
+ { name: 'Is not empty', value: 'isNotEmpty' },
131
+ ];
132
+ const getComparisonItems = (columnType) => {
133
+ if (columnType === 'string' || columnType === 'stringNumber') {
134
+ return [...stringItems, ...commonItems];
135
+ } else if (columnType === 'number' || columnType === 'float') {
136
+ return [...numberItems, ...commonItems];
137
+ } else if (columnType === 'boolean') {
138
+ return [
139
+ { name: 'Is', value: 'is' },
140
+ ];
141
+ }
142
+ return [];
143
+ };
144
+ const items2 = computed(() => getComparisonItems(props.column.type));
145
+ const isShowFilterSetting = computed({
146
+ get: () => props.isShow,
147
+ set: val => emit('update:isShow', val),
148
+ });
149
+ const addRow = () => {
150
+ const operator = filteringItems.value.length > 2 ? filteringItems.value[2].operator : 'and';
151
+ filteringItems.value.push({
152
+ comparison: '=',
153
+ operator,
154
+ value: '',
155
+ });
156
+ };
157
+ const removeRow = (idx) => {
158
+ if (filteringItems.value.length > 1) {
159
+ filteringItems.value.splice(idx, 1);
160
+ } else if (idx === 0) {
161
+ filteringItems.value[0].comparison = '=';
162
+ filteringItems.value[0].value = '';
163
+ }
164
+ };
165
+ const changeComparison = (comparison, idx) => {
166
+ if (comparison === 'isEmpty' || comparison === 'isNotEmpty') {
167
+ filteringItems.value[idx].value = '';
168
+ }
169
+ };
170
+ const changeOperator = (val) => {
171
+ filteringItems.value = filteringItems.value.map(item => ({ ...item, operator: val }));
172
+ };
173
+ const applyFiltering = () => {
174
+ emit(
175
+ 'apply-filtering',
176
+ columnField.value,
177
+ filteringItems.value.filter(item => item.value
178
+ || item.comparison === 'isEmpty' || item.comparison === 'isNotEmpty'),
179
+ );
180
+ };
181
+ watch(
182
+ () => props.isShow,
183
+ (isShow) => {
184
+ const rowList = [];
185
+ if (isShow && columnField.value) {
186
+ if (!props.items[columnField.value]?.length) {
187
+ rowList.push({
188
+ comparison: '=',
189
+ operator: 'and',
190
+ value: '',
191
+ });
192
+ } else {
193
+ props.items[columnField.value].forEach((row) => {
194
+ rowList.push(row);
195
+ });
196
+ }
197
+ filteringItems.value = rowList;
198
+ }
199
+ },
200
+ );
201
+
202
+ return {
203
+ filteringItems,
204
+ isShowFilterSetting,
205
+ items1,
206
+ items2,
207
+ addRow,
208
+ removeRow,
209
+ changeOperator,
210
+ applyFiltering,
211
+ changeComparison,
212
+ };
213
+ },
214
+ };
215
+ </script>
216
+
217
+ <style lang="scss">
218
+ .ev-grid-filter-setting {
219
+ position: absolute;
220
+ width: auto;
221
+ border: 1px solid #D0D0D0;
222
+ background: #FFFFFF;
223
+ font-size: 12px;
224
+ z-index: 1;
225
+ &__header {
226
+ padding: 10px;
227
+
228
+ .ev-text-field {
229
+ margin-top: 10px;
230
+ }
231
+ }
232
+ &__row {
233
+ display: flex;
234
+ width: 100%;
235
+ padding: 6px 0;
236
+ gap: 5px;
237
+ .ev-select__wrapper {
238
+ width: inherit;
239
+ }
240
+ &--operator {
241
+ width: 80px;
242
+ }
243
+ &--comparison {
244
+ width: 120px;
245
+ }
246
+ &--value {
247
+ width: 120px;
248
+ }
249
+ &--button {
250
+ display: flex;
251
+ justify-content: center;
252
+ align-items: center;
253
+ &.add {
254
+ padding: 6px 0;
255
+ justify-content: end;
256
+ }
257
+ i {
258
+ font-size: 22px;
259
+ margin-left: 8px;
260
+ &:hover {
261
+ opacity: 0.6;
262
+ cursor: pointer;
263
+ }
264
+ }
265
+ }
266
+ }
267
+ &__content {
268
+ padding: 0 10px;
269
+ border-top: 1px solid #CED4DA;
270
+ border-bottom: 1px solid #CED4DA;
271
+ }
272
+
273
+ &__footer {
274
+ display: flex;
275
+ padding: 5px 10px;
276
+
277
+ .ev-button {
278
+ margin-left: auto;
279
+ }
280
+ }
281
+ }
282
+ </style>
@@ -32,6 +32,10 @@
32
32
  border-bottom: 2px solid #7F7F7F !important;
33
33
  }
34
34
  }
35
+ .row-contextmenu__btn {
36
+ display: none;
37
+ vertical-align: middle;
38
+ }
35
39
  }
36
40
 
37
41
  .column-list {
@@ -54,16 +58,16 @@
54
58
  vertical-align: top;
55
59
  user-select: none;
56
60
 
57
- @include evThemify() {
58
- border-right: 1px solid evThemed('grid-bottom-border');
59
- background: evThemed('background-base');
60
- }
61
- &:nth-last-child(1) {
62
- border-right: 0;
63
- }
61
+ //@include evThemify() {
62
+ // border-right: 1px solid evThemed('grid-bottom-border');
63
+ //}
64
+ //&:nth-last-child(1) {
65
+ // border-right: 0;
66
+ //}
64
67
  .column-sort__icon {
65
68
  position: absolute;
66
69
  top: 50%;
70
+ right: 0;
67
71
  width: 24px;
68
72
  height: 24px;
69
73
  background-size: contain;
@@ -141,7 +145,6 @@
141
145
  white-space: nowrap;
142
146
 
143
147
  @include evThemify() {
144
- background: evThemed('background-base');
145
148
  border-bottom: 1px solid evThemed('grid-bottom-border');
146
149
  }
147
150
  &.selected {
@@ -157,7 +160,11 @@
157
160
  }
158
161
  &:hover {
159
162
  .row-contextmenu__btn {
160
- visibility: visible;
163
+ display: grid;
164
+ &:hover {
165
+ cursor: pointer;
166
+ opacity: 0.6;
167
+ }
161
168
  }
162
169
  }
163
170
  }
@@ -165,25 +172,19 @@
165
172
  .cell {
166
173
  display: inline-block;
167
174
  padding: 0 10px;
168
- background: inherit;
169
175
  text-align: center;
170
176
  max-width: 100%;
171
177
  white-space: nowrap;
172
178
  text-overflow: ellipsis;
173
179
 
174
- @include evThemify() {
175
- border-right: 1px solid evThemed('grid-bottom-border');
176
- }
180
+ //@include evThemify() {
181
+ // border-right: 1px solid evThemed('grid-bottom-border');
182
+ //}
177
183
  div {
178
184
  white-space: nowrap;
179
185
  overflow: hidden;
180
186
  text-overflow: ellipsis;
181
187
  }
182
- .row-contextmenu__btn {
183
- visibility: hidden;
184
- vertical-align: middle;
185
- cursor: pointer;
186
- }
187
188
  &.row-checkbox {
188
189
  display: inline-flex;
189
190
  justify-content: center;
@@ -215,9 +216,9 @@
215
216
  justify-content: flex-end;
216
217
  }
217
218
  }
218
- &:last-child {
219
- border-right: 0;
220
- }
219
+ //&:last-child {
220
+ // border-right: 0;
221
+ //}
221
222
  }
222
223
  }
223
224
 
@@ -252,3 +253,68 @@
252
253
  height: 30px;
253
254
  text-align: center;
254
255
  }
256
+
257
+ .filtering-items {
258
+ display: flex;
259
+ flex-flow: row wrap;
260
+ gap: 10px;
261
+ position: absolute;
262
+ padding: 8px;
263
+ flex-direction: row;
264
+ align-items: center;
265
+ z-index: 1;
266
+ border-radius: 4px;
267
+ &-expand {
268
+ &:hover {
269
+ cursor: pointer;
270
+ color: #0077FF;
271
+ }
272
+ }
273
+ &__item {
274
+ padding: 4px;
275
+ border-radius: 4px;
276
+ background: #EAF2FA;
277
+ &:hover {
278
+ cursor: pointer;
279
+ border: 1px solid #198FFF;
280
+ }
281
+ &--title {
282
+ color: #0077FF;
283
+ margin-right: 6px;
284
+ vertical-align: middle;
285
+ }
286
+ &--value {
287
+ display: inline-block;
288
+ max-width: 80px;
289
+ text-overflow: ellipsis;
290
+ overflow: hidden;
291
+ vertical-align: middle;
292
+ white-space: nowrap;
293
+ }
294
+ &--remove {
295
+ vertical-align: middle;
296
+ margin-left: 6px;
297
+ &:hover {
298
+ opacity: 0.6;
299
+ }
300
+ }
301
+ &.non-display {
302
+ display: none;
303
+ }
304
+ }
305
+ }
306
+ .ev-grid-filtering-items {
307
+ display: flex;
308
+ flex-flow: row wrap;
309
+ gap: 10px;
310
+ position: relative;
311
+ padding: 10px;
312
+ align-items: center;
313
+ border: 1px solid #CED4DA;
314
+ background: #FFFFFF;
315
+ border-radius: 4px;
316
+ overflow: auto;
317
+ max-width: 500px;
318
+ max-height: 100px;
319
+ }
320
+