@eturnity/eturnity_reusable_components 8.16.2--EPDM-14330.5 → 8.16.2--EPDM-14330.7

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 (103) hide show
  1. package/package.json +1 -1
  2. package/src/assets/svgIcons/ac_power.svg +4 -0
  3. package/src/assets/svgIcons/arrow_long_left.svg +3 -0
  4. package/src/assets/svgIcons/arrow_long_right.svg +3 -0
  5. package/src/assets/svgIcons/chassis_ground_symbol.svg +27 -0
  6. package/src/assets/svgIcons/dc_power.svg +8 -0
  7. package/src/assets/svgIcons/double_arrow_long.svg +4 -0
  8. package/src/assets/svgIcons/ed_ac.svg +3 -0
  9. package/src/assets/svgIcons/ed_acgrid.svg +4 -0
  10. package/src/assets/svgIcons/ed_arrow_both.svg +7 -0
  11. package/src/assets/svgIcons/ed_arrow_left.svg +7 -0
  12. package/src/assets/svgIcons/ed_arrow_right.svg +7 -0
  13. package/src/assets/svgIcons/ed_battery.svg +10 -0
  14. package/src/assets/svgIcons/ed_batteryacinverter.svg +16 -0
  15. package/src/assets/svgIcons/ed_batteryintegratedinverter.svg +19 -0
  16. package/src/assets/svgIcons/ed_cirquitbreaker.svg +4 -0
  17. package/src/assets/svgIcons/ed_cirquitbreaker_magnetic.svg +6 -0
  18. package/src/assets/svgIcons/ed_cirquitbreaker_thermal.svg +4 -0
  19. package/src/assets/svgIcons/ed_cirquitbreaker_thermal_magnetic.svg +5 -0
  20. package/src/assets/svgIcons/ed_consumption.svg +3 -0
  21. package/src/assets/svgIcons/ed_dc.svg +6 -0
  22. package/src/assets/svgIcons/ed_disconnector.svg +4 -0
  23. package/src/assets/svgIcons/ed_disconnector_fuse.svg +4 -0
  24. package/src/assets/svgIcons/ed_disconnector_fuse_switch.svg +4 -0
  25. package/src/assets/svgIcons/ed_disconnector_loadbreak switch.svg +4 -0
  26. package/src/assets/svgIcons/ed_disconnector_switch.svg +4 -0
  27. package/src/assets/svgIcons/ed_disconnector_switch_auto_release.svg +5 -0
  28. package/src/assets/svgIcons/ed_energymanagement_rectangle.svg +3 -0
  29. package/src/assets/svgIcons/ed_evcharger.svg +19 -0
  30. package/src/assets/svgIcons/ed_flexiblecomponent_circle.svg +3 -0
  31. package/src/assets/svgIcons/ed_flexiblecomponent_square.svg +3 -0
  32. package/src/assets/svgIcons/ed_fuse.svg +3 -0
  33. package/src/assets/svgIcons/ed_ground.svg +5 -0
  34. package/src/assets/svgIcons/ed_heatpump.svg +4 -0
  35. package/src/assets/svgIcons/ed_icon_battery.svg +9 -0
  36. package/src/assets/svgIcons/ed_icon_circle.svg +3 -0
  37. package/src/assets/svgIcons/ed_icon_heatpump.svg +3 -0
  38. package/src/assets/svgIcons/ed_icon_inverter.svg +8 -0
  39. package/src/assets/svgIcons/ed_icon_optimizer.svg +11 -0
  40. package/src/assets/svgIcons/ed_integratedbatteryinverter.svg +10 -0
  41. package/src/assets/svgIcons/ed_inverter-blank.svg +3 -0
  42. package/src/assets/svgIcons/ed_mainsconnection.svg +3 -0
  43. package/src/assets/svgIcons/ed_meter_arrowleft.svg +4 -0
  44. package/src/assets/svgIcons/ed_meter_arrowright.svg +4 -0
  45. package/src/assets/svgIcons/ed_meter_bidirectional.svg +5 -0
  46. package/src/assets/svgIcons/ed_networkandsystemprotection_double.svg +14 -0
  47. package/src/assets/svgIcons/ed_networkandsystemprotection_single.svg +7 -0
  48. package/src/assets/svgIcons/ed_pvpanel.svg +7 -0
  49. package/src/assets/svgIcons/ed_rcd.svg +5 -0
  50. package/src/assets/svgIcons/ed_rcd_simple.svg +3 -0
  51. package/src/assets/svgIcons/ed_spd.svg +6 -0
  52. package/src/assets/svgIcons/ed_stringwithoptimizer.svg +33 -0
  53. package/src/assets/svgIcons/ed_stringwithoutoptimizer.svg +17 -0
  54. package/src/assets/svgIcons/ed_transformer.svg +3 -0
  55. package/src/assets/svgIcons/filter.svg +3 -0
  56. package/src/assets/svgIcons/ground_symbol.svg +28 -0
  57. package/src/assets/svgIcons/move_left.svg +3 -0
  58. package/src/assets/svgIcons/move_right.svg +3 -0
  59. package/src/assets/svgIcons/rectangle.svg +3 -0
  60. package/src/assets/svgIcons/refresh.svg +3 -0
  61. package/src/assets/svgIcons/text_icon.svg +3 -0
  62. package/src/assets/theme.js +17 -1
  63. package/src/components/banner/infoBanner/InfoBanner.spec.js +29 -42
  64. package/src/components/barchart/BottomFields.vue +253 -0
  65. package/src/components/barchart/ChartControls.vue +113 -0
  66. package/src/components/barchart/SelectionBox.vue +150 -0
  67. package/src/components/barchart/composables/index.js +5 -0
  68. package/src/components/barchart/composables/useAxisCalculations.js +104 -0
  69. package/src/components/barchart/composables/useChartData.js +114 -0
  70. package/src/components/barchart/composables/useChartScroll.js +61 -0
  71. package/src/components/barchart/composables/useSelection.js +75 -0
  72. package/src/components/barchart/composables/useTooltip.js +100 -0
  73. package/src/components/barchart/index.vue +385 -0
  74. package/src/components/barchart/styles/bottomFields.js +66 -0
  75. package/src/components/barchart/styles/chart.js +272 -0
  76. package/src/components/barchart/styles/chartControls.js +59 -0
  77. package/src/components/buttons/buttonIcon/index.vue +35 -1
  78. package/src/components/buttons/splitButtons/index.vue +86 -0
  79. package/src/components/collapsableInfoText/index.vue +2 -2
  80. package/src/components/errorMessage/errorMessage.spec.js +34 -0
  81. package/src/components/errorMessage/errorMessage.stories.js +35 -0
  82. package/src/components/filter/filterSettings.vue +2 -0
  83. package/src/components/filterComponent/viewFilter.vue +589 -0
  84. package/src/components/filterComponent/viewSettings.vue +63 -2
  85. package/src/components/filterComponent/viewSort.vue +18 -5
  86. package/src/components/icon/index.vue +32 -9
  87. package/src/components/infoText/index.vue +2 -2
  88. package/src/components/infoText/infoText.spec.js +6 -1
  89. package/src/components/inputs/inputNumber/index.vue +14 -2
  90. package/src/components/inputs/searchInput/index.vue +19 -3
  91. package/src/components/inputs/select/index.vue +108 -19
  92. package/src/components/inputs/select/option/index.vue +5 -0
  93. package/src/components/modals/actionModal/actionModal.spec.js +52 -0
  94. package/src/components/modals/actionModal/actionModal.stories.js +53 -0
  95. package/src/components/modals/actionModal/index.vue +6 -6
  96. package/src/components/modals/infoModal/index.vue +49 -19
  97. package/src/components/modals/infoModal/infoModal.spec.js +55 -0
  98. package/src/components/modals/infoModal/infoModal.stories.js +47 -0
  99. package/src/components/modals/modal/index.vue +16 -5
  100. package/src/components/pageSubtitle/PageSubtitle.stories.js +0 -1
  101. package/src/helpers/isObjectEqual.js +22 -0
  102. package/src/helpers/translateLang.js +95 -24
  103. package/src/main.js +1 -0
@@ -0,0 +1,589 @@
1
+ <template>
2
+ <PageContainer>
3
+ <ButtonIcon
4
+ ref="buttonIcon"
5
+ class="button-icon"
6
+ fill-type="stroke"
7
+ icon-name="filter"
8
+ :number-count="getNumberCount()"
9
+ :text="$gettext('filter')"
10
+ type="filter"
11
+ @click="toggleOptions"
12
+ />
13
+ <ButtonWrapper v-if="isOptionsVisible">
14
+ <BoxContainer ref="boxContainer" class="box-container">
15
+ <BoxTitle>{{ $gettext('filter') }}</BoxTitle>
16
+ <SortOptionsContainer>
17
+ <template v-if="selectedSort.length > 0">
18
+ <SortDropdownContainer
19
+ v-for="(item, index) in selectedSort"
20
+ :key="index"
21
+ >
22
+ <LeadingText>{{ $gettext('where') }}</LeadingText>
23
+ <SelectComponent
24
+ ref="selectSortDropdown"
25
+ align-items="vertical"
26
+ class="sort-dropdown"
27
+ :dropdown-auto-close="false"
28
+ select-height="40px"
29
+ @click.stop
30
+ @input-change="
31
+ onSelectFilter({
32
+ type: 'column',
33
+ value: $event,
34
+ index: index,
35
+ })
36
+ "
37
+ >
38
+ <template #selector>
39
+ <SelectedText>{{
40
+ getSelectedLabel({
41
+ type: 'column',
42
+ value: item.column,
43
+ index,
44
+ }) || $gettext('category')
45
+ }}</SelectedText>
46
+ </template>
47
+ <template #dropdown>
48
+ <SelectOption
49
+ v-for="category in filterCategories"
50
+ :key="category.name"
51
+ :value="category.name"
52
+ >
53
+ {{ $gettext(category.text) }}
54
+ </SelectOption>
55
+ </template>
56
+ </SelectComponent>
57
+ <SelectComponent
58
+ ref="selectSortDropdown"
59
+ align-items="vertical"
60
+ class="sort-dropdown"
61
+ :disabled="!item.column"
62
+ :dropdown-auto-close="false"
63
+ select-height="40px"
64
+ @click.stop
65
+ @input-change="
66
+ onSelectFilter({
67
+ type: 'constraint',
68
+ value: $event,
69
+ index: index,
70
+ })
71
+ "
72
+ >
73
+ <template #selector>
74
+ <SelectedText>{{
75
+ getSelectedLabel({
76
+ type: 'constraint',
77
+ value: item.constraint,
78
+ index,
79
+ }) || $gettext('constraint')
80
+ }}</SelectedText>
81
+ </template>
82
+ <template #dropdown>
83
+ <SelectOption
84
+ v-for="(item, index) in constraintOptions(index)"
85
+ :key="item.value"
86
+ :value="item.value"
87
+ >
88
+ {{ item.label }}
89
+ </SelectOption>
90
+ </template>
91
+ </SelectComponent>
92
+ <template v-if="item.column === 'updated'">
93
+ <DatePickerContainer>
94
+ <VueDatePicker
95
+ :auto-apply="true"
96
+ :clearable="true"
97
+ :disabled="!item.constraint"
98
+ :enable-time-picker="false"
99
+ :format="datePickerFormat"
100
+ :input-class-name="'dp-input'"
101
+ :locale="datePickerLocale"
102
+ model-type="format"
103
+ :model-value="item.selectedDate"
104
+ :placeholder="$gettext('Select')"
105
+ :range="false"
106
+ :single-picker="true"
107
+ text-input
108
+ @update:model-value="
109
+ onSelectFilter({
110
+ type: 'selectedDate',
111
+ value: $event,
112
+ index: index,
113
+ constraint: item.constraint,
114
+ })
115
+ "
116
+ />
117
+ </DatePickerContainer>
118
+ </template>
119
+ <SelectComponent
120
+ v-else
121
+ ref="selectSortDropdown"
122
+ align-items="vertical"
123
+ class="sort-dropdown"
124
+ :disabled="!item.column || !item.constraint"
125
+ :dropdown-auto-close="false"
126
+ :is-searchable="false"
127
+ option-width="max-content"
128
+ select-height="40px"
129
+ @click.stop
130
+ @input-change="
131
+ onSelectFilter({
132
+ type: 'selectedOptions',
133
+ value: $event,
134
+ index: index,
135
+ })
136
+ "
137
+ >
138
+ <template #selector>
139
+ <SelectedText>{{
140
+ getSelectedLabel({
141
+ type: 'selectedOptions',
142
+ value: item.constraint,
143
+ index,
144
+ }) || $gettext('Options')
145
+ }}</SelectedText>
146
+ </template>
147
+ <template #dropdown>
148
+ <OptionsContainer class="options-container">
149
+ <SelectOption
150
+ v-for="option in optionsList(index)"
151
+ :key="option.value"
152
+ :value="option.value"
153
+ @click="
154
+ onSelectFilter({
155
+ type: 'selectedOptions',
156
+ value: option.value,
157
+ index: index,
158
+ })
159
+ "
160
+ >
161
+ <RcCheckbox
162
+ :is-checked="
163
+ selectedSort[index].selectedOptions?.includes(
164
+ option.value
165
+ )
166
+ "
167
+ :label="$gettext(option.label)"
168
+ size="small"
169
+ @on-event-handler="
170
+ onSelectFilter({
171
+ type: 'selectedOptions',
172
+ value: option.value,
173
+ index: index,
174
+ })
175
+ "
176
+ />
177
+ </SelectOption>
178
+ </OptionsContainer>
179
+ </template>
180
+ </SelectComponent>
181
+ <IconContainer>
182
+ <RCIcon
183
+ :color="theme.semanticColors.teal[800]"
184
+ cursor="pointer"
185
+ name="close"
186
+ size="14px"
187
+ @click.stop="removeItem(index)"
188
+ />
189
+ </IconContainer>
190
+ </SortDropdownContainer>
191
+ </template>
192
+ <template v-else>
193
+ <SortDropdownContainer>
194
+ <LeadingText>{{ $gettext('where') }}</LeadingText>
195
+ <SelectComponent
196
+ ref="selectSortDropdown"
197
+ align-items="vertical"
198
+ class="sort-dropdown"
199
+ :dropdown-auto-close="false"
200
+ select-height="40px"
201
+ @click.stop
202
+ @input-change="
203
+ onSelectFilter({
204
+ type: 'column',
205
+ value: $event,
206
+ index: 0,
207
+ })
208
+ "
209
+ >
210
+ <template #selector>
211
+ <SelectedText>{{ $gettext('category') }}</SelectedText>
212
+ </template>
213
+ <template #dropdown>
214
+ <SelectOption
215
+ v-for="item in filterCategories"
216
+ :key="item.name"
217
+ :value="item.name"
218
+ >
219
+ {{ $gettext(item.text) }}
220
+ </SelectOption>
221
+ </template>
222
+ </SelectComponent>
223
+ <SelectComponent
224
+ ref="selectSortDropdown"
225
+ align-items="vertical"
226
+ class="sort-dropdown"
227
+ :disabled="true"
228
+ :dropdown-auto-close="false"
229
+ select-height="40px"
230
+ @click.stop
231
+ >
232
+ <template #selector>
233
+ <SelectedText>{{ $gettext('constraint') }}</SelectedText>
234
+ </template>
235
+ </SelectComponent>
236
+ <SelectComponent
237
+ ref="selectSortDropdown"
238
+ align-items="vertical"
239
+ class="sort-dropdown"
240
+ :disabled="true"
241
+ :dropdown-auto-close="false"
242
+ select-height="40px"
243
+ @click.stop
244
+ >
245
+ <template #selector>
246
+ <SelectedText>{{ $gettext('Options') }}</SelectedText>
247
+ </template>
248
+ </SelectComponent>
249
+ </SortDropdownContainer>
250
+ </template>
251
+ </SortOptionsContainer>
252
+ <BottomContainer>
253
+ <PlaceholderText>{{ $gettext('where') }}</PlaceholderText>
254
+ <ButtonIcon
255
+ icon-name="plus_button"
256
+ :text="$gettext('add_filter')"
257
+ type="ghost"
258
+ @click="onAddFilter"
259
+ />
260
+ </BottomContainer>
261
+ </BoxContainer>
262
+ </ButtonWrapper>
263
+ </PageContainer>
264
+ </template>
265
+
266
+ <script>
267
+ import styled from 'vue3-styled-components'
268
+ import theme from '../../assets/theme'
269
+ import ButtonIcon from '../buttons/buttonIcon/index.vue'
270
+ import SelectComponent from '../inputs/select/index.vue'
271
+ import SelectOption from '../inputs/select/option/index.vue'
272
+ import RcCheckbox from '../inputs/checkbox/index.vue'
273
+ import RCIcon from '../icon'
274
+ import VueDatePicker from '@vuepic/vue-datepicker'
275
+ import { datePickerLang, getDateFormat } from '../../helpers/translateLang'
276
+
277
+ const PageContainer = styled.div``
278
+
279
+ const ButtonWrapper = styled.div`
280
+ position: relative;
281
+ `
282
+
283
+ const BoxContainer = styled.div`
284
+ position: absolute;
285
+ z-index: 99;
286
+ top: 8px;
287
+ left: 50%;
288
+ transform: translateX(-50%);
289
+ width: max-content;
290
+ max-width: calc(100vw - 32px);
291
+ background-color: ${(props) => props.theme.colors.white};
292
+ border: 1px solid ${(props) => props.theme.semanticColors.grey[300]};
293
+ border-radius: 4px;
294
+ padding: 24px;
295
+ `
296
+
297
+ const BoxTitle = styled.div`
298
+ font-size: 14px;
299
+ font-weight: 500;
300
+ color: ${(props) => props.theme.semanticColors.teal[800]};
301
+ margin-bottom: 16px;
302
+ `
303
+
304
+ const SortOptionsContainer = styled.div`
305
+ display: flex;
306
+ flex-direction: column;
307
+ gap: 16px;
308
+ white-space: nowrap;
309
+ `
310
+
311
+ const SortDropdownContainer = styled.div`
312
+ display: grid;
313
+ grid-template-columns: auto repeat(3, 1fr) auto;
314
+ grid-gap: 8px;
315
+ align-items: center;
316
+ `
317
+
318
+ const SelectedText = styled.div`
319
+ font-size: 14px;
320
+ font-weight: 400;
321
+ color: ${(props) => props.theme.semanticColors.grey[800]};
322
+ `
323
+
324
+ const IconContainer = styled.div`
325
+ margin-left: 12px;
326
+ `
327
+
328
+ const LeadingText = styled.div`
329
+ font-size: 14px;
330
+ font-weight: 400;
331
+ color: ${(props) => props.theme.semanticColors.teal[800]};
332
+ `
333
+
334
+ const BottomContainer = styled.div`
335
+ display: flex;
336
+ margin-top: 16px;
337
+ `
338
+
339
+ const PlaceholderText = styled.div`
340
+ visibility: hidden;
341
+ `
342
+
343
+ const OptionsContainer = styled.div`
344
+ width: max-content;
345
+ display: flex;
346
+ flex-direction: column;
347
+ `
348
+
349
+ const DatePickerContainer = styled.div`
350
+ height: 40px;
351
+ display: flex;
352
+ align-items: center;
353
+ min-width: 150px;
354
+ `
355
+
356
+ export default {
357
+ name: 'ViewSettings',
358
+ components: {
359
+ PageContainer,
360
+ ButtonIcon,
361
+ ButtonWrapper,
362
+ BoxContainer,
363
+ BoxTitle,
364
+ SortOptionsContainer,
365
+ SortDropdownContainer,
366
+ SelectComponent,
367
+ SelectOption,
368
+ SelectedText,
369
+ RCIcon,
370
+ IconContainer,
371
+ LeadingText,
372
+ BottomContainer,
373
+ PlaceholderText,
374
+ RcCheckbox,
375
+ OptionsContainer,
376
+ VueDatePicker,
377
+ DatePickerContainer,
378
+ },
379
+ props: {
380
+ sortOptions: {
381
+ type: Array,
382
+ required: true,
383
+ },
384
+ selectedSort: {
385
+ type: Array,
386
+ required: true,
387
+ },
388
+ filterCategories: {
389
+ type: Array,
390
+ required: true,
391
+ },
392
+ activeLanguage: {
393
+ type: String,
394
+ required: false,
395
+ default: 'en-us',
396
+ },
397
+ },
398
+ data() {
399
+ return {
400
+ isOptionsVisible: false,
401
+ }
402
+ },
403
+ computed: {
404
+ theme() {
405
+ return theme
406
+ },
407
+ datePickerLocale() {
408
+ return datePickerLang(this.activeLanguage)
409
+ },
410
+ datePickerFormat() {
411
+ return getDateFormat(this.activeLanguage)
412
+ },
413
+ },
414
+ beforeUnmount() {
415
+ document.removeEventListener('click', this.handleClickOutside)
416
+ },
417
+ methods: {
418
+ handleClickOutside(event) {
419
+ const isClickInSelect =
420
+ event.target.closest('.sort-dropdown') ||
421
+ event.target.closest('.rc-select-dropdown') ||
422
+ event.target.closest('.select-button') ||
423
+ event.target.closest('.caret_dropdown')
424
+
425
+ if (
426
+ !this.$refs.buttonIcon.$el.contains(event.target) &&
427
+ !this.$refs.boxContainer.$el.contains(event.target) &&
428
+ !isClickInSelect
429
+ ) {
430
+ this.isOptionsVisible = false
431
+ document.removeEventListener('click', this.handleClickOutside)
432
+ }
433
+ },
434
+ toggleOptions() {
435
+ this.isOptionsVisible = !this.isOptionsVisible
436
+ if (this.isOptionsVisible) {
437
+ document.addEventListener('click', this.handleClickOutside)
438
+ } else {
439
+ document.removeEventListener('click', this.handleClickOutside)
440
+ }
441
+ },
442
+ getNumberCount() {
443
+ return this.selectedSort.filter((item) => {
444
+ const hasColumn = !!item.column
445
+ const hasConstraint = !!item.constraint
446
+ const hasSelectedOptions =
447
+ item.column === 'updated'
448
+ ? !!item.selectedDate
449
+ : !!item.selectedOptions?.length
450
+ return hasColumn && hasConstraint && hasSelectedOptions
451
+ }).length
452
+ },
453
+ constraintOptions(index) {
454
+ const generalOptions = [
455
+ {
456
+ value: 'contains_any',
457
+ label: this.$gettext('contains_any'),
458
+ },
459
+ {
460
+ value: 'contains_all',
461
+ label: this.$gettext('contains_all'),
462
+ },
463
+ {
464
+ value: 'contains_none',
465
+ label: this.$gettext('contains_none'),
466
+ },
467
+ ]
468
+
469
+ const dateOptions = [
470
+ {
471
+ value: 'is_before',
472
+ label: this.$gettext('is_before'),
473
+ },
474
+ {
475
+ value: 'is_before_or_on',
476
+ label: this.$gettext('is_before_or_on'),
477
+ },
478
+ {
479
+ value: 'is_after',
480
+ label: this.$gettext('is_after'),
481
+ },
482
+ {
483
+ value: 'is_after_or_on',
484
+ label: this.$gettext('is_after_or_on'),
485
+ },
486
+ ]
487
+ if (this.selectedSort?.[index]?.column === 'updated') {
488
+ return dateOptions
489
+ }
490
+
491
+ return generalOptions
492
+ },
493
+ getSelectedLabel({ type, value, index }) {
494
+ if (!value) return
495
+ if (type === 'column') {
496
+ const categoryName = this.filterCategories.find(
497
+ (option) => option.name === value
498
+ ).text
499
+ return this.$gettext(categoryName) || '-'
500
+ } else if (type === 'constraint') {
501
+ return this.constraintOptions(index).find(
502
+ (option) => option.value === value
503
+ ).label
504
+ } else if (type === 'selectedOptions') {
505
+ const selectedOptions =
506
+ this.selectedSort[index]?.selectedOptions || []
507
+ if (selectedOptions.length === 0) return this.$gettext('Options')
508
+
509
+ const optionsList = this.optionsList(index)
510
+ const selectedLabels = selectedOptions
511
+ .map((optionValue) => {
512
+ const option = optionsList.find(
513
+ (opt) => opt.value === optionValue
514
+ )
515
+ return option ? option.label : optionValue
516
+ })
517
+ .join(', ')
518
+
519
+ return selectedLabels.length > 15
520
+ ? `${selectedLabels.substring(0, 15)}...`
521
+ : selectedLabels
522
+ }
523
+ },
524
+ onSelectFilter({ type, value, index, constraint }) {
525
+ if (
526
+ type === 'constraint' &&
527
+ (value === 'contains_all' || value === 'contains_none')
528
+ ) {
529
+ const options = this.optionsList(index)
530
+ const allValues = options.map((option) => option.value)
531
+
532
+ this.$emit('on-filter-change', {
533
+ type: 'selectedOptions',
534
+ value: value === 'contains_all' ? allValues : [],
535
+ index,
536
+ })
537
+ }
538
+
539
+ this.$emit('on-filter-change', {
540
+ type,
541
+ value,
542
+ index,
543
+ constraint,
544
+ })
545
+ if (type === 'column') {
546
+ this.$emit('on-filter-change', {
547
+ type: 'constraint',
548
+ value: '',
549
+ index,
550
+ })
551
+ }
552
+ this.isOptionsVisible = true
553
+ },
554
+ removeItem(index) {
555
+ this.$emit('on-filter-change', {
556
+ type: 'remove',
557
+ index,
558
+ })
559
+ },
560
+ onAddFilter() {
561
+ this.$emit('on-add-filter', {
562
+ type: 'add',
563
+ index: this.selectedSort.length,
564
+ })
565
+ },
566
+ optionsList(index) {
567
+ if (!this.selectedSort[index].column) return []
568
+ const findIndex = this.filterCategories.findIndex(
569
+ (category) => category.name === this.selectedSort[index].column
570
+ )
571
+ const selectedItem = this.filterCategories[findIndex]
572
+ return this.filterCategories[findIndex].options.choices.map(
573
+ (option) => ({
574
+ ...option,
575
+ value: option[selectedItem.valueSelector],
576
+ label: option[selectedItem.labelSelector],
577
+ })
578
+ )
579
+ },
580
+ },
581
+ }
582
+ </script>
583
+
584
+ <style>
585
+ .dp-input {
586
+ height: 40px !important;
587
+ min-width: 150px !important;
588
+ }
589
+ </style>
@@ -42,6 +42,34 @@
42
42
  @on-toggle-change="$emit(option.onToggle, $event)"
43
43
  />
44
44
  </ToggleContainer>
45
+ <LineSeparator />
46
+ <SelectedContainer>
47
+ <SectionTitle>{{ $gettext('Shown') }}</SectionTitle>
48
+ <SelectComponent
49
+ ref="selectSortDropdown"
50
+ align-items="vertical"
51
+ class="sort-dropdown"
52
+ :dropdown-auto-close="true"
53
+ select-height="40px"
54
+ @click.stop
55
+ @input-change="onPageSizeChange($event)"
56
+ >
57
+ <template #selector>
58
+ <SelectedText>{{
59
+ pageSize + ' ' + $gettext('projects')
60
+ }}</SelectedText>
61
+ </template>
62
+ <template #dropdown>
63
+ <RcOption
64
+ v-for="option in shownOptions"
65
+ :key="option.label"
66
+ :value="option.value"
67
+ >
68
+ {{ $gettext(option.label) }}
69
+ </RcOption>
70
+ </template>
71
+ </SelectComponent>
72
+ </SelectedContainer>
45
73
  </BoxContainer>
46
74
  </ButtonWrapper>
47
75
  </PageContainer>
@@ -52,6 +80,8 @@
52
80
  import ButtonIcon from '../buttons/buttonIcon/index.vue'
53
81
  import MainButton from '../buttons/mainButton/index.vue'
54
82
  import RCToggle from '../inputs/toggle/index.vue'
83
+ import SelectComponent from '../inputs/select/index.vue'
84
+ import RcOption from '../inputs/select/option/index.vue'
55
85
 
56
86
  const PageContainer = styled.div``
57
87
 
@@ -138,6 +168,18 @@
138
168
  gap: 8px;
139
169
  `
140
170
 
171
+ const SelectedText = styled.div`
172
+ font-size: 14px;
173
+ font-weight: 400;
174
+ color: ${(props) => props.theme.semanticColors.grey[800]};
175
+ `
176
+
177
+ const SelectedContainer = styled.div`
178
+ display: inline-flex;
179
+ gap: 8px;
180
+ flex-direction: column;
181
+ `
182
+
141
183
  export default {
142
184
  name: 'ViewSettings',
143
185
  components: {
@@ -154,6 +196,10 @@
154
196
  LineSeparator,
155
197
  RCToggle,
156
198
  ToggleContainer,
199
+ SelectComponent,
200
+ RcOption,
201
+ SelectedText,
202
+ SelectedContainer,
157
203
  },
158
204
  props: {
159
205
  columnsData: {
@@ -164,6 +210,11 @@
164
210
  type: Array,
165
211
  required: false,
166
212
  },
213
+ pageSize: {
214
+ type: Number,
215
+ required: false,
216
+ default: 20,
217
+ },
167
218
  },
168
219
  emits: ['onSelectColumn', 'onSelectAllColumns'],
169
220
  data() {
@@ -171,8 +222,14 @@
171
222
  isOptionsVisible: false,
172
223
  }
173
224
  },
174
- mounted() {
175
- // Remove the mounted event listener since we now handle it in toggleOptions
225
+ computed: {
226
+ shownOptions() {
227
+ return [
228
+ { label: '20' + ' ' + this.$gettext('projects'), value: 20 },
229
+ { label: '50' + ' ' + this.$gettext('projects'), value: 50 },
230
+ { label: '100' + ' ' + this.$gettext('projects'), value: 100 },
231
+ ]
232
+ },
176
233
  },
177
234
  beforeUnmount() {
178
235
  document.removeEventListener('click', this.handleClickOutside)
@@ -215,6 +272,10 @@
215
272
  document.removeEventListener('click', this.handleClickOutside)
216
273
  }
217
274
  },
275
+ onPageSizeChange(value) {
276
+ console.log('value', value)
277
+ this.$emit('onPageSizeChange', value)
278
+ },
218
279
  },
219
280
  }
220
281
  </script>