@eturnity/eturnity_reusable_components 1.2.83 → 1.2.85-EPDM-3013.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eturnity/eturnity_reusable_components",
3
- "version": "1.2.83",
3
+ "version": "1.2.85-EPDM-3013.1",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "dev": "vue-cli-service serve",
@@ -11,10 +11,13 @@
11
11
  },
12
12
  "dependencies": {
13
13
  "@vueform/slider": "1.0.5",
14
+ "html-loader": "0.5.5",
15
+ "postcss": "^8.4.25",
16
+ "v-click-outside": "2.1.4",
14
17
  "vue": "2.6.11",
15
18
  "vue-styled-components": "1.6.0",
16
- "html-loader": "0.5.5",
17
- "v-click-outside": "2.1.4"
19
+ "vue2-datepicker": "3.11.1",
20
+ "vuedraggable": "2.24.3"
18
21
  },
19
22
  "devDependencies": {
20
23
  "@storybook/addon-actions": "6.2.8",
@@ -0,0 +1,6 @@
1
+ module.exports = {
2
+ plugins: {
3
+ // Add your PostCSS plugins here
4
+ // Example: require('autoprefixer')
5
+ }
6
+ }
@@ -0,0 +1,551 @@
1
+ <template>
2
+ <container-wrapper>
3
+ <column-wrapper :numCols="filterData.length">
4
+ <column-container v-for="(item, idx) in filterData" :key="idx">
5
+ <column-title :showBorder="idx + 1 !== filterData.length">
6
+ {{ item.columnName }}
7
+ </column-title>
8
+ <row-container v-if="item.type === 'columns'">
9
+ <checkbox-container>
10
+ <draggable
11
+ @change="onDragChange({ data: item.dataOptions })"
12
+ handle=".drag-container"
13
+ style="display: contents"
14
+ ghost-class="ghost"
15
+ :setData="modifyDragItem"
16
+ v-model="item.dataOptions"
17
+ >
18
+ <checkbox-wrapper
19
+ v-for="column in item.dataOptions"
20
+ :key="column.choice"
21
+ >
22
+ <drag-container class="drag-container">
23
+ <icon :name="'duplicate-1'" size="12px" />
24
+ </drag-container>
25
+ <checkbox
26
+ :label="column.text"
27
+ :isChecked="column.selected"
28
+ @on-event-handler="
29
+ onChange({
30
+ dataType: item.type,
31
+ value: $event,
32
+ choice: column.choice
33
+ })
34
+ "
35
+ size="small"
36
+ :isDisabled="column.selected && isCheckboxDisabled"
37
+ />
38
+ </checkbox-wrapper>
39
+ </draggable>
40
+ </checkbox-container>
41
+ </row-container>
42
+ <row-container v-if="item.type === 'filter'">
43
+ <row-wrapper v-for="filter in item.dataOptions" :key="filter.field">
44
+ <select-component
45
+ v-if="isMultipleSelector(filter.filter_type)"
46
+ selectWidth="100%"
47
+ selectHeight="36px"
48
+ fontSize="13px"
49
+ :label="filter.label"
50
+ alignItems="vertical"
51
+ :disabled="!filter.choices.length"
52
+ >
53
+ <template #selector>
54
+ <option-title>
55
+ {{ filter.selectedText }}
56
+ </option-title>
57
+ </template>
58
+ <template #dropdown>
59
+ <dropdown-checkbox-container @click.stop>
60
+ <checkbox
61
+ v-for="filterOption in filter.choices"
62
+ :key="filterOption.choice"
63
+ :label="filterOption.text"
64
+ :isChecked="filterOption.selected"
65
+ @on-event-handler="
66
+ onChange({
67
+ dataType: item.type,
68
+ value: $event,
69
+ choice: filterOption.choice,
70
+ field: filter.field
71
+ })
72
+ "
73
+ size="small"
74
+ />
75
+ </dropdown-checkbox-container>
76
+ </template>
77
+ </select-component>
78
+ <select-component
79
+ v-else-if="isRangeSelector(filter.filter_type)"
80
+ selectWidth="100%"
81
+ selectHeight="36px"
82
+ fontSize="13px"
83
+ :label="filter.label"
84
+ alignItems="vertical"
85
+ >
86
+ <template #selector>
87
+ <option-title>
88
+ {{ filter.selectedText }}
89
+ </option-title>
90
+ </template>
91
+ <template #dropdown>
92
+ <dropdown-checkbox-container @click.stop>
93
+ <input-number
94
+ :placeholder="settingsTranslations.start"
95
+ :numberPrecision="0"
96
+ :value="filter.range.start"
97
+ @input-change="
98
+ onChange({
99
+ dataType: item.type,
100
+ value: $event,
101
+ choice: 'start',
102
+ field: filter.field
103
+ })
104
+ "
105
+ fontSize="13px"
106
+ :labelText="settingsTranslations.start"
107
+ />
108
+ <input-number
109
+ :placeholder="settingsTranslations.end"
110
+ :numberPrecision="0"
111
+ :value="filter.range.end"
112
+ @input-change="
113
+ onChange({
114
+ dataType: item.type,
115
+ value: $event,
116
+ choice: 'end',
117
+ field: filter.field
118
+ })
119
+ "
120
+ fontSize="13px"
121
+ :labelText="settingsTranslations.end"
122
+ />
123
+ </dropdown-checkbox-container>
124
+ </template>
125
+ </select-component>
126
+ <calendar-container v-else-if="isDateSelector(filter.filter_type)">
127
+ <row-label
128
+ v-if="settingsTranslations && settingsTranslations.start"
129
+ >{{ settingsTranslations.start }}</row-label
130
+ >
131
+ <date-picker-input
132
+ :placeholder="'-'"
133
+ :lang="getDatePickerLanguage()"
134
+ type="date"
135
+ :value="filter.range.start"
136
+ @change="
137
+ onChange({
138
+ dataType: item.type,
139
+ value: $event,
140
+ choice: 'start',
141
+ field: filter.field
142
+ })
143
+ "
144
+ @focus="onDatepickerFocus(filter.range)"
145
+ @close="onDatepickerBlur()"
146
+ format="YYYY-MM-DD"
147
+ valueType="format"
148
+ :disabled-date="disableFutureDates"
149
+ />
150
+ <row-label
151
+ :marginTop="true"
152
+ v-if="settingsTranslations && settingsTranslations.end"
153
+ >{{ settingsTranslations.end }}</row-label
154
+ >
155
+ <date-picker-input
156
+ :placeholder="'-'"
157
+ :lang="getDatePickerLanguage()"
158
+ type="date"
159
+ :value="filter.range.end"
160
+ @change="
161
+ onChange({
162
+ dataType: item.type,
163
+ value: $event,
164
+ choice: 'end',
165
+ field: filter.field
166
+ })
167
+ "
168
+ @focus="onDatepickerFocus(filter.range)"
169
+ @close="onDatepickerBlur()"
170
+ format="YYYY-MM-DD"
171
+ valueType="format"
172
+ :disabled-date="disablePastDates"
173
+ />
174
+ </calendar-container>
175
+ <select-component
176
+ v-else
177
+ selectWidth="100%"
178
+ selectHeight="36px"
179
+ fontSize="13px"
180
+ :label="filter.label"
181
+ alignItems="vertical"
182
+ :disabled="!filter.choices.length"
183
+ >
184
+ <template #selector="{ selectedValue }">
185
+ <option-title>
186
+ {{
187
+ getSelectedValue({
188
+ value: selectedValue,
189
+ options: filter.choices,
190
+ filter
191
+ })
192
+ }}
193
+ </option-title>
194
+ </template>
195
+ <template #dropdown>
196
+ <Option
197
+ v-for="filterOption in filter.choices"
198
+ :key="filterOption.choice"
199
+ :value="filterOption.choice"
200
+ >{{ filterOption.text }}</Option
201
+ >
202
+ </template>
203
+ </select-component>
204
+ </row-wrapper>
205
+ </row-container>
206
+ </column-container>
207
+ </column-wrapper>
208
+ <button-container>
209
+ <main-button
210
+ v-if="buttonText.save_view && hasActiveView"
211
+ type="primary"
212
+ :text="buttonText.save_view"
213
+ @click.native="$emit('on-save-current-view')"
214
+ />
215
+ <main-button
216
+ type="secondary"
217
+ v-if="buttonText.save_new_view"
218
+ :text="buttonText.save_new_view"
219
+ @click.native="$emit('on-save-new-view')"
220
+ />
221
+ <main-button
222
+ type="cancel"
223
+ v-if="buttonText.cancel"
224
+ :text="buttonText.cancel"
225
+ @click.native="$emit('on-cancel-view')"
226
+ />
227
+ </button-container>
228
+ </container-wrapper>
229
+ </template>
230
+
231
+ <script>
232
+ import styled from 'vue-styled-components'
233
+ import DatePicker from 'vue2-datepicker'
234
+ import SelectComponent from '../inputs/select'
235
+ import Option from '../inputs/select/option'
236
+ import InputNumber from '../inputs/inputNumber'
237
+ import MainButton from '../buttons/mainButton'
238
+ import Checkbox from '../inputs/checkbox'
239
+ import draggable from 'vuedraggable'
240
+ import Icon from '../icon'
241
+ import { datePickerLang } from '../../helpers/translateLang'
242
+ import 'vue2-datepicker/index.css'
243
+ import 'vue2-datepicker/locale/de'
244
+ import 'vue2-datepicker/locale/en'
245
+ import 'vue2-datepicker/locale/es'
246
+ import 'vue2-datepicker/locale/fr'
247
+ import 'vue2-datepicker/locale/it'
248
+
249
+ const ContainerWrapper = styled.div`
250
+ position: absolute;
251
+ margin-top: 4px;
252
+ background-color: ${(props) => props.theme.colors.white};
253
+ min-width: 100%;
254
+ width: max-content;
255
+ border: 1px solid ${(props) => props.theme.colors.grey4};
256
+ border-radius: 4px;
257
+ z-index: 9999;
258
+ font-size: 13px;
259
+ `
260
+
261
+ const ColAttrs = { numCols: Number }
262
+ const ColumnWrapper = styled('div', ColAttrs)`
263
+ display: grid;
264
+ grid-template-columns: repeat(${(props) => props.numCols}, auto);
265
+ `
266
+
267
+ const TitleAttrs = { showBorder: Boolean }
268
+ const ColumnTitle = styled('div', TitleAttrs)`
269
+ font-size: 14px;
270
+ font-weight: 700;
271
+ color: ${(props) => props.theme.colors.eturnityGrey};
272
+ padding: 14px;
273
+ border-bottom: 1px solid ${(props) => props.theme.colors.grey4};
274
+ ${({ showBorder, theme }) =>
275
+ showBorder &&
276
+ `
277
+ border-right: 1px solid ${theme.colors.grey4};
278
+ `}
279
+ `
280
+
281
+ const ButtonContainer = styled.div`
282
+ display: flex;
283
+ gap: 10px;
284
+ padding: 15px;
285
+ `
286
+
287
+ const ColumnContainer = styled.div``
288
+
289
+ const DragContainer = styled.div`
290
+ cursor: grab;
291
+
292
+ &:active {
293
+ cursor: grabbing;
294
+ }
295
+ `
296
+
297
+ const RowContainer = styled.div`
298
+ padding: 15px;
299
+ width: 260px;
300
+
301
+ .ghost {
302
+ opacity: 0.5;
303
+ background-color: #e5fcb4;
304
+ }
305
+ `
306
+
307
+ const OptionTitle = styled.div`
308
+ cursor: pointer !important;
309
+ `
310
+
311
+ const CheckboxContainer = styled.div`
312
+ display: grid;
313
+ gap: 6px;
314
+ `
315
+
316
+ const CheckboxWrapper = styled.div`
317
+ display: grid;
318
+ grid-template-columns: auto 1fr;
319
+ gap: 6px;
320
+ padding: 2px;
321
+ align-items: center;
322
+ `
323
+
324
+ const DropdownCheckboxContainer = styled.div`
325
+ display: grid;
326
+ gap: 6px;
327
+ width: 100%;
328
+ padding: 12px 10px;
329
+ `
330
+
331
+ const RowWrapper = styled.div`
332
+ margin-bottom: 12px;
333
+ `
334
+
335
+ const DatePickerInput = styled(DatePicker)`
336
+ border: 1px solid ${(props) => props.theme.colors.grey4};
337
+ border-radius: 4px;
338
+ padding: 7px 12px 7px 15px;
339
+ width: 100%;
340
+ position: relative;
341
+
342
+ &.mx-datepicker {
343
+ width: 100% !important;
344
+ max-width: 100%;
345
+ height: 36px;
346
+ align-self: flex-end;
347
+ }
348
+
349
+ .mx-input-wrapper {
350
+ position: unset;
351
+
352
+ input {
353
+ border: none;
354
+ height: auto;
355
+ padding: 0;
356
+ font-size: 13px;
357
+ box-shadow: none;
358
+ /* font-family: ${(props) => props.theme.fonts.mainFont}; */
359
+ color: #393939;
360
+ vertical-align: bottom;
361
+ }
362
+
363
+ .mx-input-append {
364
+ top: 1px;
365
+ }
366
+ }
367
+
368
+ .mx-input-append {
369
+ left: 0;
370
+ top: 5px;
371
+ height: auto;
372
+ cursor: pointer;
373
+ }
374
+ `
375
+
376
+ const LabelAttrs = {
377
+ marginTop: Boolean
378
+ }
379
+ const RowLabel = styled('div', LabelAttrs)`
380
+ font-weight: 700;
381
+ font-size: 13px;
382
+ margin-bottom: 8px;
383
+ margin-top: ${(props) => (props.marginTop ? '12px' : '0')};
384
+ `
385
+
386
+ export default {
387
+ name: 'filter-settings',
388
+ components: {
389
+ ContainerWrapper,
390
+ ColumnWrapper,
391
+ ColumnTitle,
392
+ ColumnContainer,
393
+ SelectComponent,
394
+ RowContainer,
395
+ OptionTitle,
396
+ Option,
397
+ ButtonContainer,
398
+ MainButton,
399
+ CheckboxContainer,
400
+ CheckboxWrapper,
401
+ Checkbox,
402
+ RowWrapper,
403
+ DropdownCheckboxContainer,
404
+ draggable,
405
+ Icon,
406
+ DragContainer,
407
+ InputNumber,
408
+ DatePickerInput,
409
+ RowLabel
410
+ },
411
+ props: {
412
+ filterData: {
413
+ required: true
414
+ },
415
+ hasActiveView: {
416
+ required: false
417
+ },
418
+ buttonText: {
419
+ required: true
420
+ // example:
421
+ // {
422
+ // 'save_new_view': '$gettext("save_new_view")',
423
+ // 'cancel': '$gettext("cancel")',
424
+ // 'save_view': '$gettext("save_view")'
425
+ // }
426
+ },
427
+ activeLanguage: {
428
+ required: false
429
+ },
430
+ settingsTranslations: {
431
+ required: false
432
+ }
433
+ },
434
+ data() {
435
+ return {
436
+ selectedDates: null,
437
+ value1: null,
438
+ dateStart: null,
439
+ dateEnd: null
440
+ }
441
+ },
442
+ methods: {
443
+ onChange({ dataType, value, choice, field }) {
444
+ if (
445
+ dataType === 'columns' &&
446
+ this.isCheckboxDisabled &&
447
+ value === false
448
+ ) {
449
+ return
450
+ }
451
+ const data = { dataType, value, choice, field }
452
+ this.$emit('on-filter-change', data)
453
+ },
454
+ onDatepickerFocus(range) {
455
+ this.dateStart = range.start
456
+ this.dateEnd = range.end
457
+ this.$emit('on-prevent-close', true)
458
+ },
459
+ onDatepickerBlur() {
460
+ this.$emit('on-prevent-close', false)
461
+ },
462
+ disablePastDates(date) {
463
+ const dateString = this.dateStart
464
+ if (!dateString) {
465
+ return
466
+ }
467
+ const dateParts = dateString.split('-')
468
+
469
+ const year = parseInt(dateParts[0])
470
+ const month = parseInt(dateParts[1]) - 1 // Subtract 1 since January is month 0
471
+ const day = parseInt(dateParts[2])
472
+
473
+ const currentDate = new Date(year, month, day)
474
+ const selectedDate = new Date(date)
475
+
476
+ // Disable dates that are greater than or equal to the current date
477
+ return selectedDate <= currentDate
478
+ },
479
+ disableFutureDates(date) {
480
+ const dateString = this.dateEnd
481
+ if (!dateString) {
482
+ return
483
+ }
484
+ const dateParts = dateString.split('-')
485
+
486
+ const year = parseInt(dateParts[0])
487
+ const month = parseInt(dateParts[1]) - 1 // Subtract 1 since January is month 0
488
+ const day = parseInt(dateParts[2])
489
+
490
+ const currentDate = new Date(year, month, day)
491
+ const selectedDate = new Date(date)
492
+
493
+ // Disable dates that are greater than or equal to the current date
494
+ return selectedDate >= currentDate
495
+ },
496
+ getDatePickerLanguage() {
497
+ return datePickerLang(this.activeLanguage)
498
+ },
499
+ onDragChange({ data }) {
500
+ this.$emit('on-drag-change', data)
501
+ },
502
+ modifyDragItem(dataTransfer) {
503
+ const isSafari = /^((?!chrome|android).)*safari/i.test(
504
+ navigator.userAgent
505
+ )
506
+ // prevents the dragged element from dragging the whole row as a "ghost"
507
+ // Safari fix because this does not work on Safari
508
+ let img = new Image()
509
+ if (!isSafari) {
510
+ dataTransfer.setDragImage(img, 0, 0)
511
+ } else {
512
+ img.src =
513
+ 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
514
+ dataTransfer.setDragImage(img, 0, 0)
515
+ }
516
+ },
517
+ getSelectedValue({ value, options, filter }) {
518
+ const foundItem = options.find((item) => item.choice === value)
519
+ return foundItem ? foundItem.text : value ? value : filter.selectedText
520
+ },
521
+ isMultipleSelector(type) {
522
+ return type === 'multi_select_integer' || type === 'multi_select_string'
523
+ },
524
+ isRangeSelector(type) {
525
+ return type === 'integer_range'
526
+ },
527
+ isDateSelector(type) {
528
+ return type === 'datetime'
529
+ }
530
+ },
531
+ computed: {
532
+ isCheckboxDisabled() {
533
+ // if only 1 item left, disable checkbox
534
+ let isDisabled = false
535
+ let columnsData = this.filterData.filter(
536
+ (item) => item.type === 'columns'
537
+ )
538
+ if (columnsData.length) {
539
+ columnsData = columnsData[0]
540
+ const filteredColumns = columnsData.dataOptions.filter(
541
+ (item) => item.selected
542
+ )
543
+ if (filteredColumns.length === 1) {
544
+ isDisabled = true
545
+ }
546
+ }
547
+ return isDisabled
548
+ }
549
+ }
550
+ }
551
+ </script>
@@ -0,0 +1,63 @@
1
+ <template>
2
+ <container-wrapper>
3
+ <list-item
4
+ v-for="(item, idx) in filterData"
5
+ :key="idx"
6
+ @click="$emit('on-select', item)"
7
+ >
8
+ <list-text>{{ item.name }}</list-text>
9
+ <delete-icon @click.native.stop="$emit('on-delete', item)" />
10
+ </list-item>
11
+ </container-wrapper>
12
+ </template>
13
+
14
+ <script>
15
+ import styled from 'vue-styled-components'
16
+ import DeleteIcon from '../deleteIcon'
17
+
18
+ const ContainerWrapper = styled.div`
19
+ position: absolute;
20
+ margin-top: 4px;
21
+ background-color: ${(props) => props.theme.colors.white};
22
+ min-width: 100%;
23
+ width: max-content;
24
+ border: 1px solid ${(props) => props.theme.colors.grey4};
25
+ border-radius: 4px;
26
+ z-index: 9999;
27
+ font-size: 13px;
28
+ `
29
+
30
+ const ListItem = styled.div`
31
+ display: grid;
32
+ grid-template-columns: 1fr auto;
33
+ align-items: center;
34
+ padding: 8px 14px;
35
+ gap: 6px;
36
+ font-size: 13px;
37
+ cursor: pointer;
38
+
39
+ &:hover {
40
+ background-color: ${(props) => props.theme.colors.grey5};
41
+ }
42
+ `
43
+
44
+ const ListText = styled.div``
45
+
46
+ export default {
47
+ name: 'filter-views',
48
+ components: {
49
+ ContainerWrapper,
50
+ ListItem,
51
+ ListText,
52
+ DeleteIcon
53
+ },
54
+ props: {
55
+ filterData: {
56
+ required: false,
57
+ default: () => {
58
+ '[]'
59
+ }
60
+ }
61
+ }
62
+ }
63
+ </script>