@eturnity/eturnity_reusable_components 6.37.0-EPDM-8148.3 → 6.37.0-EPDM-8148.4

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": "6.37.0-EPDM-8148.3",
3
+ "version": "6.37.0-EPDM-8148.4",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "dev": "vue-cli-service serve",
@@ -11,11 +11,14 @@
11
11
  },
12
12
  "dependencies": {
13
13
  "@vueform/slider": "1.0.5",
14
- "core-js": "^3.31.1",
15
14
  "html-loader": "0.5.5",
15
+ "postcss": "^8.4.25",
16
16
  "v-click-outside": "2.1.4",
17
17
  "vue": "2.6.11",
18
- "vue-styled-components": "1.6.0"
18
+ "vue-styled-components": "1.6.0",
19
+ "vue2-datepicker": "3.11.1",
20
+ "vuedraggable": "2.24.3",
21
+ "core-js": "3.31.1"
19
22
  },
20
23
  "devDependencies": {
21
24
  "@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
+ }
package/src/App.vue CHANGED
@@ -1,107 +1,109 @@
1
1
  <template>
2
2
  <ThemeProvider :theme="getTheme()" :style="{ height: '100%' }">
3
3
  <page-container>
4
- <br />
5
4
 
6
- {{ alignItems }}
7
- <input-number
8
- :value="value"
9
- :minNumber="0"
10
- unitName="mm"
11
- :numberPrecision="0"
12
- backgroundColor="transparent"
13
- borderColor="eturnityGrey"
14
- inputHeight="34px"
15
- inputWidth="420px"
16
- textAlign="left"
17
- :isInteractive="true"
18
- :interactionStep="1"
19
- @on-input="value = $event"
20
- @input-change="changeHandler"
21
- @input-focus="focusHandler"
22
- @input-blur="blurHandler"
23
- >
24
- <template v-slot:label>
25
- <div>Interactive Label</div>
26
- </template>
27
- </input-number>
28
-
29
- <dropdown-component openingMode="hover" gap="30px">
30
- <template #trigger><i>Click Me</i></template>
31
- <template #dropdown>
32
- <div>
33
- <a href="">test1</a>
34
- <button href="">test2</button><br>
35
- <p>Text</p>
36
- </div>
37
- </template>
38
- </dropdown-component>
39
-
40
- <videoThumbnail src="https://musicart.xboxlive.com/6/cfaf1e9d-0000-0000-0000-000000000009/504/image.jpg?w=1920&h=1080"
41
- playIconColor="red"
42
- playIconSize="20px"
43
- width="400px"
44
- height="600px"
45
- />
5
+ <br/>
6
+ <input-number
7
+ :value="value"
8
+ :minNumber="0"
9
+ unitName="mm"
10
+ :numberPrecision="0"
11
+ backgroundColor="transparent"
12
+ borderColor="eturnityGrey"
13
+ inputHeight="34px"
14
+ inputWidth="420px"
15
+ textAlign="left"
16
+ :isInteractive="true"
17
+ :interactionStep="1"
18
+ @on-input="value = $event"
19
+ @input-change="changeHandler"
20
+ @input-focus="focusHandler"
21
+ @input-blur="blurHandler"
22
+ >
23
+ <template v-slot:label>
24
+ <div>Interactive Label</div>
25
+ </template>
26
+ </input-number>
27
+
28
+ <dropdown-component openingMode="hover" gap="30px">
29
+ <template #trigger><i>Click Me</i></template>
30
+ <template #dropdown>
31
+ <div>
32
+ <a href="">test1</a>
33
+ <button href="">test2</button>
34
+ <br>
35
+ <p>Text</p>
36
+ </div>
37
+ </template>
38
+ </dropdown-component>
39
+
40
+ <videoThumbnail
41
+ src="https://musicart.xboxlive.com/6/cfaf1e9d-0000-0000-0000-000000000009/504/image.jpg?w=1920&h=1080"
42
+ playIconColor="red"
43
+ playIconSize="20px"
44
+ width="400px"
45
+ height="600px"
46
+ />
46
47
 
47
- <SwitchField
48
- @on-switch-change="onInputChange($event)"
49
- :options="[
48
+ <SwitchField
49
+ @on-switch-change="onInputChange($event)"
50
+ :options="[
50
51
  { value: 0, content: 'zero' },
51
52
  { value: 1, content: 'one' },
52
53
  { value: 2, content: 'two' }
53
54
  ]"
54
- :value="value"
55
- label="label"
56
- toggleColor="red"
57
- size="large"
58
- backgroundColor="blue"
59
- labelAlign="left"
60
- fontColor="black"
61
- :disabled="false"
62
- />
63
- <icon
64
- name="opacity"
65
- color="red"
66
- hoveredColor="blue"
67
- size="60px"
68
- cursor="default"
69
- isStriked = "true"
70
- />
71
- <Select
72
- :value="value"
73
- selectWidth="100%"
74
- optionWidth="50%"
75
- label="that is a label"
76
- alignItems="vertical"
77
- colorMode="dark"
78
- isSearchable="true"
79
- @input-change="value = $event"
80
- @search-change="searchValue = $event"
55
+ :value="value"
56
+ label="label"
57
+ toggleColor="red"
58
+ size="large"
59
+ backgroundColor="blue"
60
+ labelAlign="left"
61
+ fontColor="black"
62
+ :disabled="false"
63
+ />
64
+ <icon
65
+ name="opacity"
66
+ color="red"
67
+ hoveredColor="blue"
68
+ size="60px"
69
+ cursor="default"
70
+ isStriked="true"
71
+ />
72
+ <Select
73
+ :value="value"
74
+ selectWidth="100%"
75
+ optionWidth="50%"
76
+ label="that is a label"
77
+ alignItems="vertical"
78
+ colorMode="dark"
79
+ isSearchable="true"
80
+ @input-change="value = $event"
81
+ @search-change="searchValue = $event"
82
+ >
83
+ <template #selector="{ selectedValue }">
84
+ value selected: {{ selectedValue }}
85
+ </template>
86
+ <template #dropdown>
87
+ <Option
88
+ v-for="opt in filteredOptionList"
89
+ :key="opt.id"
90
+ :value="opt.val"
91
+ >{{ opt.lookFor }}
92
+ </Option
81
93
  >
82
- <template #selector="{ selectedValue }">
83
- value selected: {{ selectedValue }}
84
- </template>
85
- <template #dropdown>
86
- <Option
87
- v-for="opt in filteredOptionList"
88
- :key="opt.id"
89
- :value="opt.val"
90
- >{{ opt.lookFor }}</Option
91
- >
92
- </template>
93
- </Select>
94
-
95
-
96
- {{ filteredOptionList }}
97
-
98
- <iconCollection color="red" />
94
+ </template>
95
+ </Select>
96
+
97
+
98
+ {{ filteredOptionList }}
99
+
100
+ <iconCollection color="red"/>
99
101
  </page-container>
100
102
  </ThemeProvider>
101
103
  </template>
102
104
 
103
105
  <script>
104
- import { ThemeProvider } from 'vue-styled-components'
106
+ import {ThemeProvider} from 'vue-styled-components'
105
107
  import theme from './assets/theme'
106
108
  import styled from 'vue-styled-components'
107
109
  import InputNumber from '@/components/inputs/inputNumber'
@@ -144,14 +146,14 @@ export default {
144
146
  value2: 42,
145
147
  companyName: 'toto',
146
148
  optionList: [
147
- { id: 'a', val: 'A', lookFor: 'babababa' },
148
- { id: 'b', val: 'B', lookFor: 'abab' },
149
- { id: 'c', val: 'C', lookFor: 'ccc' },
150
- { id: 'd', val: 'D', lookFor: 'ddd' },
151
- { id: 'e', val: 'E', lookFor: 'dddee' },
152
- { id: 'f', val: 'F', lookFor: 'ddfff' },
153
- { id: 'g', val: 'G', lookFor: 'dggg' },
154
- { id: 'h', val: 'H', lookFor: 'dddhhh' },
149
+ {id: 'a', val: 'A', lookFor: 'babababa'},
150
+ {id: 'b', val: 'B', lookFor: 'abab'},
151
+ {id: 'c', val: 'C', lookFor: 'ccc'},
152
+ {id: 'd', val: 'D', lookFor: 'ddd'},
153
+ {id: 'e', val: 'E', lookFor: 'dddee'},
154
+ {id: 'f', val: 'F', lookFor: 'ddfff'},
155
+ {id: 'g', val: 'G', lookFor: 'dggg'},
156
+ {id: 'h', val: 'H', lookFor: 'dddhhh'},
155
157
  ],
156
158
  searchValue: ''
157
159
  }
@@ -159,7 +161,7 @@ export default {
159
161
  computed: {
160
162
  filteredOptionList() {
161
163
  return this.optionList.filter((opt) =>
162
- opt.lookFor.includes(this.searchValue)
164
+ opt.lookFor.includes(this.searchValue)
163
165
  )
164
166
  }
165
167
  },
@@ -222,7 +224,7 @@ export default {
222
224
  ]
223
225
  return items
224
226
  },
225
- getComponentInfo({ row, value }) {
227
+ getComponentInfo({row, value}) {
226
228
  let item
227
229
  if (row.selectedValue && row.selectedValue[value]) {
228
230
  item = row.selectedValue[value]
@@ -0,0 +1,3 @@
1
+ <svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M11.4545 4.45454L8.90909 7H10.8182C10.8182 9.10636 9.10636 10.8182 7 10.8182C6.35727 10.8182 5.74636 10.6591 5.21818 10.3727L4.28909 11.3018C5.07182 11.7982 6.00091 12.0909 7 12.0909C9.81273 12.0909 12.0909 9.81272 12.0909 7H14L11.4545 4.45454ZM3.18182 7C3.18182 4.89363 4.89364 3.18182 7 3.18182C7.64273 3.18182 8.25364 3.34091 8.78182 3.62727L9.71091 2.69818C8.92818 2.20182 7.99909 1.90909 7 1.90909C4.18727 1.90909 1.90909 4.18727 1.90909 7H0L2.54545 9.54545L5.09091 7H3.18182Z" fill="#263238"/>
3
+ </svg>
@@ -0,0 +1,645 @@
1
+ <template>
2
+ <container-wrapper>
3
+ <upper-container v-if="filterViews && filterViews.length">
4
+ <view-container :maxWidth="activeView.length">
5
+ <select-component
6
+ @click.native.stop
7
+ selectWidth="100%"
8
+ selectHeight="36px"
9
+ fontSize="13px"
10
+ :label="$gettext('active_filter')"
11
+ alignItems="vertical"
12
+ >
13
+ <template #selector>
14
+ <option-title>
15
+ {{ activeView }}
16
+ </option-title>
17
+ </template>
18
+ <template #dropdown>
19
+ <Option
20
+ v-for="(item, idx) in filterViews"
21
+ :key="idx + '_view'"
22
+ @click.native="$emit('on-view-select', item)"
23
+ :value="item.name"
24
+ >{{ item.name }}
25
+ <delete-icon @click.native.stop="$emit('on-view-delete', item)"
26
+ /></Option>
27
+ </template>
28
+ </select-component>
29
+ </view-container>
30
+ <reset-button @click="$emit('on-reset-filters')">
31
+ <icon :name="'update'" size="14px" :color="theme.colors.blue" />
32
+ <div>{{ $gettext('reset_filters') }}</div>
33
+ </reset-button>
34
+ </upper-container>
35
+ <column-wrapper
36
+ :numCols="filterData.length"
37
+ :hasActiveView="!!filterViews && !!filterViews.length"
38
+ >
39
+ <column-container
40
+ v-for="(item, idx) in filterData"
41
+ :key="idx + '_filterdata'"
42
+ >
43
+ <column-title :showBorder="idx + 1 !== filterData.length">
44
+ {{ item.columnName }}
45
+ </column-title>
46
+ <row-container v-if="item.type === 'columns'">
47
+ <checkbox-container>
48
+ <draggable
49
+ @change="onDragChange({ data: item.dataOptions })"
50
+ handle=".drag-container"
51
+ style="display: contents"
52
+ ghost-class="ghost"
53
+ :setData="modifyDragItem"
54
+ v-model="item.dataOptions"
55
+ >
56
+ <checkbox-wrapper
57
+ v-for="(column, index) in item.dataOptions"
58
+ :key="index + 'dataOption'"
59
+ >
60
+ <drag-container class="drag-container">
61
+ <icon :name="'duplicate-1'" size="12px" />
62
+ </drag-container>
63
+ <checkbox
64
+ :label="column.text"
65
+ :isChecked="column.selected"
66
+ @on-event-handler="
67
+ onChange({
68
+ dataType: item.type,
69
+ value: $event,
70
+ choice: column.choice
71
+ })
72
+ "
73
+ size="small"
74
+ :isDisabled="column.selected && isCheckboxDisabled"
75
+ />
76
+ </checkbox-wrapper>
77
+ </draggable>
78
+ </checkbox-container>
79
+ </row-container>
80
+ <row-container v-if="item.type === 'filter'" showBorder>
81
+ <row-wrapper
82
+ v-for="(filter, index) in item.dataOptions"
83
+ :key="index + '_field'"
84
+ >
85
+ <select-component
86
+ v-if="isMultipleSelector(filter.filter_type)"
87
+ selectWidth="100%"
88
+ selectHeight="36px"
89
+ fontSize="13px"
90
+ :label="filter.label"
91
+ alignItems="vertical"
92
+ :disabled="!filter.choices.length"
93
+ >
94
+ <template #selector>
95
+ <option-title>
96
+ {{ filter.selectedText }}
97
+ </option-title>
98
+ </template>
99
+ <template #dropdown>
100
+ <dropdown-checkbox-container @click.stop>
101
+ <checkbox
102
+ v-for="(filterOption, optionIdx) in filter.choices"
103
+ :key="optionIdx + 'optionIdx'"
104
+ :label="filterOption.text"
105
+ :isChecked="filterOption.selected"
106
+ @on-event-handler="
107
+ onChange({
108
+ dataType: item.type,
109
+ value: $event,
110
+ choice: filterOption.choice,
111
+ field: filter.field
112
+ })
113
+ "
114
+ size="small"
115
+ />
116
+ </dropdown-checkbox-container>
117
+ </template>
118
+ </select-component>
119
+ <section-container v-else-if="isRangeSelector(filter.filter_type)">
120
+ <row-label>{{ filter.label }}</row-label>
121
+ <grid-container>
122
+ <input-number
123
+ :placeholder="
124
+ filter.unit
125
+ ? $gettext('min') + ' (' + filter.unit + ')'
126
+ : $gettext('min')
127
+ "
128
+ :numberPrecision="2"
129
+ :value="filter.range.start"
130
+ @input-change="
131
+ onChange({
132
+ dataType: item.type,
133
+ value: $event,
134
+ choice: 'start',
135
+ field: filter.field
136
+ })
137
+ "
138
+ fontSize="13px"
139
+ inputHeight="36px"
140
+ :unitName="filter.unit"
141
+ />
142
+ <input-number
143
+ :placeholder="
144
+ filter.unit
145
+ ? $gettext('max') + ' (' + filter.unit + ')'
146
+ : $gettext('max')
147
+ "
148
+ :numberPrecision="2"
149
+ :value="filter.range.end"
150
+ @input-change="
151
+ onChange({
152
+ dataType: item.type,
153
+ value: $event,
154
+ choice: 'end',
155
+ field: filter.field
156
+ })
157
+ "
158
+ fontSize="13px"
159
+ inputHeight="36px"
160
+ :unitName="filter.unit"
161
+ />
162
+ </grid-container>
163
+ </section-container>
164
+ <section-container
165
+ v-else-if="isDateSelector(filter.filter_type)"
166
+ @click.stop
167
+ >
168
+ <row-label>{{ filter.label }}</row-label>
169
+ <grid-container>
170
+ <date-picker-input
171
+ :placeholder="$gettext('Date from')"
172
+ :lang="getDatePickerLanguage()"
173
+ type="date"
174
+ :value="filter.range.start"
175
+ @change="
176
+ onChange({
177
+ dataType: item.type,
178
+ value: $event,
179
+ choice: 'start',
180
+ field: filter.field
181
+ })
182
+ "
183
+ @focus="onDatepickerFocus(filter.range)"
184
+ @close="onDatepickerBlur()"
185
+ format="YYYY-MM-DD"
186
+ valueType="format"
187
+ :disabled-date="disableFutureDates"
188
+ />
189
+ <date-picker-input
190
+ :placeholder="$gettext('Date to')"
191
+ :lang="getDatePickerLanguage()"
192
+ type="date"
193
+ :value="filter.range.end"
194
+ @change="
195
+ onChange({
196
+ dataType: item.type,
197
+ value: $event,
198
+ choice: 'end',
199
+ field: filter.field
200
+ })
201
+ "
202
+ @focus="onDatepickerFocus(filter.range)"
203
+ @close="onDatepickerBlur()"
204
+ format="YYYY-MM-DD"
205
+ valueType="format"
206
+ :disabled-date="disablePastDates"
207
+ />
208
+ </grid-container>
209
+ </section-container>
210
+ <select-component
211
+ v-else
212
+ selectWidth="100%"
213
+ selectHeight="36px"
214
+ fontSize="13px"
215
+ :label="filter.label"
216
+ alignItems="vertical"
217
+ :disabled="!filter.choices.length"
218
+ >
219
+ <template #selector="{ selectedValue }">
220
+ <option-title>
221
+ {{
222
+ getSelectedValue({
223
+ value: selectedValue,
224
+ options: filter.choices,
225
+ filter
226
+ })
227
+ }}
228
+ </option-title>
229
+ </template>
230
+ <template #dropdown>
231
+ <Option
232
+ v-for="(filterOption, filterIdx) in filter.choices"
233
+ :key="filterIdx + '_filterIdx'"
234
+ :value="filterOption.choice"
235
+ >{{ filterOption.text }}</Option
236
+ >
237
+ </template>
238
+ </select-component>
239
+ </row-wrapper>
240
+ </row-container>
241
+ </column-container>
242
+ </column-wrapper>
243
+ <button-container>
244
+ <main-button
245
+ v-if="buttonText.apply_view"
246
+ type="primary"
247
+ :text="buttonText.apply_view"
248
+ @click.native="$emit('on-apply-current-view')"
249
+ />
250
+ <main-button
251
+ type="secondary"
252
+ v-if="buttonText.save_view"
253
+ :text="buttonText.save_view"
254
+ @click.native="$emit('on-save-new-view')"
255
+ />
256
+ <main-button
257
+ type="cancel"
258
+ v-if="buttonText.cancel"
259
+ :text="buttonText.cancel"
260
+ @click.native="$emit('on-cancel-view')"
261
+ />
262
+ </button-container>
263
+ </container-wrapper>
264
+ </template>
265
+
266
+ <script>
267
+ import styled from 'vue-styled-components'
268
+ import DatePicker from 'vue2-datepicker'
269
+ import SelectComponent from '../inputs/select'
270
+ import Option from '../inputs/select/option'
271
+ import InputNumber from '../inputs/inputNumber'
272
+ import MainButton from '../buttons/mainButton'
273
+ import Checkbox from '../inputs/checkbox'
274
+ import draggable from 'vuedraggable'
275
+ import Icon from '../icon'
276
+ import DeleteIcon from '../deleteIcon'
277
+ import { datePickerLang } from '../../helpers/translateLang'
278
+ import theme from '@/assets/theme.js'
279
+ import 'vue2-datepicker/index.css'
280
+ import 'vue2-datepicker/locale/de'
281
+ import 'vue2-datepicker/locale/en'
282
+ import 'vue2-datepicker/locale/es'
283
+ import 'vue2-datepicker/locale/fr'
284
+ import 'vue2-datepicker/locale/it'
285
+
286
+ const ContainerWrapper = styled.div`
287
+ position: absolute;
288
+ margin-top: 4px;
289
+ background-color: ${(props) => props.theme.colors.white};
290
+ min-width: 100%;
291
+ width: max-content;
292
+ border: 1px solid ${(props) => props.theme.colors.grey4};
293
+ border-radius: 4px;
294
+ z-index: 9999;
295
+ font-size: 13px;
296
+ `
297
+
298
+ const ColAttrs = { numCols: Number, hasActiveView: Boolean }
299
+ const ColumnWrapper = styled('div', ColAttrs)`
300
+ display: grid;
301
+ grid-template-columns: repeat(${(props) => props.numCols}, auto);
302
+
303
+ ${({ hasActiveView, theme }) =>
304
+ hasActiveView &&
305
+ `
306
+ border-top: 1px solid ${theme.colors.grey4};
307
+ `}
308
+ `
309
+
310
+ const TitleAttrs = { showBorder: Boolean }
311
+ const ColumnTitle = styled('div', TitleAttrs)`
312
+ font-size: 14px;
313
+ font-weight: 700;
314
+ color: ${(props) => props.theme.colors.eturnityGrey};
315
+ padding: 10px 14px;
316
+ ${({ showBorder, theme }) =>
317
+ showBorder &&
318
+ `
319
+ border-right: 1px solid ${theme.colors.grey4};
320
+ `}
321
+ `
322
+
323
+ const ButtonContainer = styled.div`
324
+ display: flex;
325
+ gap: 10px;
326
+ padding: 15px;
327
+ `
328
+
329
+ const ColumnContainer = styled.div``
330
+
331
+ const DragContainer = styled.div`
332
+ cursor: grab;
333
+
334
+ &:active {
335
+ cursor: grabbing;
336
+ }
337
+ `
338
+
339
+ const RowContainer = styled('div', TitleAttrs)`
340
+ padding: 10px 14px;
341
+ width: 300px;
342
+
343
+ ${({ showBorder, theme }) =>
344
+ showBorder &&
345
+ `
346
+ border-right: 1px solid ${theme.colors.grey4};
347
+ `}
348
+
349
+ .ghost {
350
+ opacity: 0.5;
351
+ background-color: #e5fcb4;
352
+ }
353
+ `
354
+
355
+ const OptionTitle = styled.div`
356
+ cursor: pointer !important;
357
+ `
358
+
359
+ const CheckboxContainer = styled.div`
360
+ display: grid;
361
+ gap: 6px;
362
+ `
363
+
364
+ const CheckboxWrapper = styled.div`
365
+ display: grid;
366
+ grid-template-columns: auto 1fr;
367
+ gap: 16px;
368
+ padding: 2px;
369
+ align-items: center;
370
+ `
371
+
372
+ const DropdownCheckboxContainer = styled.div`
373
+ display: grid;
374
+ gap: 6px;
375
+ width: 100%;
376
+ padding: 12px 10px;
377
+ `
378
+
379
+ const RowWrapper = styled.div`
380
+ margin-bottom: 12px;
381
+ `
382
+
383
+ const DatePickerInput = styled(DatePicker)`
384
+ border: 1px solid ${(props) => props.theme.colors.grey4};
385
+ border-radius: 4px;
386
+ padding: 7px 12px 7px 7px;
387
+ width: 100%;
388
+ position: relative;
389
+
390
+ &.mx-datepicker {
391
+ width: 100% !important;
392
+ max-width: 100%;
393
+ height: 36px;
394
+ align-self: flex-end;
395
+ }
396
+
397
+ .mx-input-wrapper {
398
+ position: unset;
399
+
400
+ input {
401
+ border: none;
402
+ height: auto;
403
+ padding: 0;
404
+ font-size: 13px;
405
+ box-shadow: none;
406
+ color: #393939;
407
+ vertical-align: bottom;
408
+ }
409
+
410
+ .mx-input-append {
411
+ top: 1px;
412
+ }
413
+ }
414
+
415
+ .mx-input-append {
416
+ left: 0;
417
+ top: 5px;
418
+ height: auto;
419
+ cursor: pointer;
420
+ }
421
+ `
422
+
423
+ const LabelAttrs = {
424
+ marginTop: Boolean
425
+ }
426
+ const RowLabel = styled('div', LabelAttrs)`
427
+ font-weight: 700;
428
+ font-size: 13px;
429
+ margin-bottom: 8px;
430
+ margin-top: ${(props) => (props.marginTop ? '12px' : '0')};
431
+ `
432
+
433
+ const SectionContainer = styled.div``
434
+
435
+ const GridContainer = styled.div`
436
+ display: grid;
437
+ grid-template-columns: 1fr 1fr;
438
+ grid-gap: 12px;
439
+ `
440
+
441
+ const ViewContainerAttrs = { maxWidth: Number }
442
+ const ViewContainer = styled('div', ViewContainerAttrs)`
443
+ max-width: ${(props) =>
444
+ props.maxWidth && props.maxWidth > 300 ? props.maxWidth + 'ch' : '300px'};
445
+ `
446
+
447
+ const UpperContainer = styled.div`
448
+ display: grid;
449
+ grid-gap: 20px
450
+ grid-template-columns: 1fr 1fr;
451
+ padding: 10px 14px;
452
+ `
453
+
454
+ const ResetButton = styled.div`
455
+ display: inline-flex;
456
+ gap: 16px;
457
+ width: max-content;
458
+ margin-top: 20px;
459
+ align-self: center;
460
+ font-size: 13px;
461
+ color: ${(props) => props.theme.colors.blue};
462
+ cursor: pointer;
463
+ `
464
+
465
+ export default {
466
+ name: 'filter-settings',
467
+ components: {
468
+ ContainerWrapper,
469
+ ColumnWrapper,
470
+ ColumnTitle,
471
+ ColumnContainer,
472
+ SelectComponent,
473
+ RowContainer,
474
+ OptionTitle,
475
+ Option,
476
+ ButtonContainer,
477
+ MainButton,
478
+ CheckboxContainer,
479
+ CheckboxWrapper,
480
+ Checkbox,
481
+ RowWrapper,
482
+ DropdownCheckboxContainer,
483
+ draggable,
484
+ Icon,
485
+ DragContainer,
486
+ InputNumber,
487
+ DatePickerInput,
488
+ RowLabel,
489
+ SectionContainer,
490
+ GridContainer,
491
+ ViewContainer,
492
+ DeleteIcon,
493
+ UpperContainer,
494
+ ResetButton
495
+ },
496
+ props: {
497
+ filterData: {
498
+ required: true
499
+ },
500
+ hasActiveView: {
501
+ required: false
502
+ },
503
+ buttonText: {
504
+ required: true
505
+ // example:
506
+ // {
507
+ // 'save_new_view': '$gettext("save_new_view")',
508
+ // 'cancel': '$gettext("cancel")',
509
+ // 'save_view': '$gettext("save_view")'
510
+ // }
511
+ },
512
+ filterViews: {
513
+ required: true
514
+ },
515
+ activeLanguage: {
516
+ required: false
517
+ },
518
+ settingsTranslations: {
519
+ required: false
520
+ },
521
+ activeView: {
522
+ required: false
523
+ }
524
+ },
525
+ data() {
526
+ return {
527
+ selectedDates: null,
528
+ value1: null,
529
+ dateStart: null,
530
+ dateEnd: null
531
+ }
532
+ },
533
+ methods: {
534
+ onChange({ dataType, value, choice, field }) {
535
+ if (
536
+ dataType === 'columns' &&
537
+ this.isCheckboxDisabled &&
538
+ value === false
539
+ ) {
540
+ return
541
+ }
542
+ const data = { dataType, value, choice, field }
543
+ this.$emit('on-filter-change', data)
544
+ },
545
+ onDatepickerFocus(range) {
546
+ this.dateStart = range.start
547
+ this.dateEnd = range.end
548
+ this.$emit('on-prevent-close', true)
549
+ },
550
+ onDatepickerBlur() {
551
+ this.$emit('on-prevent-close', false)
552
+ },
553
+ disablePastDates(date) {
554
+ const dateString = this.dateStart
555
+ if (!dateString) {
556
+ return
557
+ }
558
+ const dateParts = dateString.split('-')
559
+
560
+ const year = parseInt(dateParts[0])
561
+ const month = parseInt(dateParts[1]) - 1 // Subtract 1 since January is month 0
562
+ const day = parseInt(dateParts[2])
563
+
564
+ const currentDate = new Date(year, month, day)
565
+ const selectedDate = new Date(date)
566
+
567
+ // Disable dates that are greater than or equal to the current date
568
+ return selectedDate <= currentDate
569
+ },
570
+ disableFutureDates(date) {
571
+ const dateString = this.dateEnd
572
+ if (!dateString) {
573
+ return
574
+ }
575
+ const dateParts = dateString.split('-')
576
+
577
+ const year = parseInt(dateParts[0])
578
+ const month = parseInt(dateParts[1]) - 1 // Subtract 1 since January is month 0
579
+ const day = parseInt(dateParts[2])
580
+
581
+ const currentDate = new Date(year, month, day)
582
+ const selectedDate = new Date(date)
583
+
584
+ // Disable dates that are greater than or equal to the current date
585
+ return selectedDate >= currentDate
586
+ },
587
+ getDatePickerLanguage() {
588
+ return datePickerLang(this.activeLanguage)
589
+ },
590
+ onDragChange({ data }) {
591
+ this.$emit('on-drag-change', data)
592
+ },
593
+ modifyDragItem(dataTransfer) {
594
+ const isSafari = /^((?!chrome|android).)*safari/i.test(
595
+ navigator.userAgent
596
+ )
597
+ // prevents the dragged element from dragging the whole row as a "ghost"
598
+ // Safari fix because this does not work on Safari
599
+ let img = new Image()
600
+ if (!isSafari) {
601
+ dataTransfer.setDragImage(img, 0, 0)
602
+ } else {
603
+ img.src =
604
+ 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
605
+ dataTransfer.setDragImage(img, 0, 0)
606
+ }
607
+ },
608
+ getSelectedValue({ value, options, filter }) {
609
+ const foundItem = options.find((item) => item.choice === value)
610
+ return foundItem ? foundItem.text : value ? value : filter.selectedText
611
+ },
612
+ isMultipleSelector(type) {
613
+ return type === 'multi_select_integer' || type === 'multi_select_string'
614
+ },
615
+ isRangeSelector(type) {
616
+ return type === 'integer_range'
617
+ },
618
+ isDateSelector(type) {
619
+ return type === 'datetime'
620
+ }
621
+ },
622
+ computed: {
623
+ isCheckboxDisabled() {
624
+ // if only 1 item left, disable checkbox
625
+ let isDisabled = false
626
+ let columnsData = this.filterData.filter(
627
+ (item) => item.type === 'columns'
628
+ )
629
+ if (columnsData.length) {
630
+ columnsData = columnsData[0]
631
+ const filteredColumns = columnsData.dataOptions.filter(
632
+ (item) => item.selected
633
+ )
634
+ if (filteredColumns.length === 1) {
635
+ isDisabled = true
636
+ }
637
+ }
638
+ return isDisabled
639
+ },
640
+ theme() {
641
+ return theme
642
+ }
643
+ }
644
+ }
645
+ </script>
@@ -0,0 +1,132 @@
1
+ <template>
2
+ <page-wrapper ref="dropdown">
3
+ <parent-dropdown
4
+ @on-toggle="onToggleDropdown()"
5
+ :isOpen="isDropdownOpen"
6
+ :dropdownText="dropdownText ? dropdownText : 'Default view'"
7
+ />
8
+ <filter-settings
9
+ v-if="isDropdownOpen"
10
+ :filterData="filterData"
11
+ :filterViews="filterViews"
12
+ :buttonText="buttonText"
13
+ @on-view-select="onViewSelect($event)"
14
+ @on-view-delete="onViewDelete($event)"
15
+ @on-save-new-view="$emit('on-save-new-view')"
16
+ @on-filter-change="onFilterChange($event)"
17
+ @on-cancel-view="onCancelSettings()"
18
+ @on-drag-change="$emit('on-drag-change', $event)"
19
+ @on-apply-current-view="onApplyCurrentView()"
20
+ @on-prevent-close="onPreventClose($event)"
21
+ @on-reset-filters="onResetFilters()"
22
+ :hasActiveView="hasActiveView"
23
+ :activeView="activeView"
24
+ :activeLanguage="activeLanguage"
25
+ :settingsTranslations="settingsTranslations"
26
+ />
27
+ </page-wrapper>
28
+ </template>
29
+
30
+ <script>
31
+ import styled from 'vue-styled-components'
32
+ import parentDropdown from './parentDropdown'
33
+ import filterSettings from './filterSettings'
34
+
35
+ const PageWrapper = styled.div`
36
+ position: relative;
37
+ `
38
+
39
+ export default {
40
+ name: 'filter-component',
41
+ components: {
42
+ parentDropdown,
43
+ PageWrapper,
44
+ filterSettings
45
+ },
46
+ props: {
47
+ filterData: {
48
+ required: true
49
+ },
50
+ dropdownText: {
51
+ required: false
52
+ },
53
+ filterViews: {
54
+ required: true
55
+ },
56
+ activeView: {
57
+ required: false,
58
+ default: null
59
+ },
60
+ buttonText: {
61
+ required: false
62
+ },
63
+ hasActiveView: {
64
+ required: false
65
+ },
66
+ activeLanguage: {
67
+ required: false,
68
+ default: 'en-us'
69
+ },
70
+ settingsTranslations: {
71
+ required: false
72
+ }
73
+ },
74
+ data() {
75
+ return {
76
+ isDropdownOpen: false,
77
+ activeFilter: null,
78
+ preventOutsideClick: false
79
+ }
80
+ },
81
+ methods: {
82
+ onToggleDropdown() {
83
+ this.isDropdownOpen = !this.isDropdownOpen
84
+ },
85
+ clickOutside(event) {
86
+ if (
87
+ !this.$refs.dropdown.$el.contains(event.target) &&
88
+ !this.preventOutsideClick
89
+ ) {
90
+ this.isDropdownOpen = false
91
+ }
92
+ },
93
+ onPreventClose(value) {
94
+ setTimeout(() => {
95
+ this.preventOutsideClick = value
96
+ }, 100)
97
+ },
98
+ onFilterChange(data) {
99
+ // this.preventOutsideClick = true is needed for when the user clicks on the calendar icon on the date range
100
+ // because clicking the calendar does not trigger the @focus
101
+ this.preventOutsideClick = true
102
+ this.$emit('on-filter-settings-change', data)
103
+ this.onPreventClose(false)
104
+ },
105
+ onCancelSettings() {
106
+ this.onToggleDropdown()
107
+ this.$emit('on-cancel-view')
108
+ },
109
+ onViewSelect(item) {
110
+ this.onToggleDropdown()
111
+ this.$emit('on-filter-view-select', item)
112
+ },
113
+ onViewDelete(item) {
114
+ this.$emit('on-filter-view-delete', item)
115
+ },
116
+ onApplyCurrentView() {
117
+ this.onToggleDropdown()
118
+ this.$emit('on-apply-current-view')
119
+ },
120
+ onResetFilters() {
121
+ this.onToggleDropdown()
122
+ this.$emit('on-reset-filters')
123
+ }
124
+ },
125
+ mounted() {
126
+ document.addEventListener('click', this.clickOutside)
127
+ },
128
+ beforeDestroy() {
129
+ document.removeEventListener('click', this.clickOutside)
130
+ }
131
+ }
132
+ </script>
@@ -0,0 +1,91 @@
1
+ <template>
2
+ <page-wrapper @click="$emit('on-toggle')">
3
+ <icon-wrapper>
4
+ <icon name="settings" size="18px" />
5
+ </icon-wrapper>
6
+ <title-wrapper :isOpen="isOpen">
7
+ <title-text>
8
+ {{ dropdownText }}
9
+ </title-text>
10
+ <arrow-wrapper>
11
+ <icon
12
+ @click.native.stop="$emit('on-toggle')"
13
+ :name="isOpen ? 'arrow_up' : 'arrow_down'"
14
+ size="12px"
15
+ />
16
+ </arrow-wrapper>
17
+ </title-wrapper>
18
+ </page-wrapper>
19
+ </template>
20
+
21
+ <script>
22
+ import styled from 'vue-styled-components'
23
+ import Icon from '../icon'
24
+
25
+ const PageWrapper = styled.div`
26
+ display: grid;
27
+ grid-template-columns: auto auto;
28
+ cursor: pointer;
29
+ `
30
+
31
+ const IconWrapper = styled.div`
32
+ display: grid;
33
+ align-items: center;
34
+ justify-items: center;
35
+ border: 1px solid ${(props) => props.theme.colors.grey4};
36
+ border-radius: 4px 0px 0px 4px;
37
+ padding: 6px;
38
+ `
39
+
40
+ const TitleAttrs = { isOpen: Boolean }
41
+ const TitleWrapper = styled('div', TitleAttrs)`
42
+ display: grid;
43
+ grid-template-columns: auto auto;
44
+ align-items: center;
45
+ justify-items: center;
46
+ grid-gap: 10px;
47
+ border: 1px solid ${(props) => props.theme.colors.grey4};
48
+ background-color: ${(props) =>
49
+ props.isOpen ? props.theme.colors.grey5 : props.theme.colors.white};
50
+ border-left: none;
51
+ border-radius: 0px 4px 4px 0px;
52
+ padding: 6px 14px;
53
+ user-select: none;
54
+ `
55
+
56
+ const TitleText = styled.div`
57
+ font-size: 13px;
58
+ `
59
+
60
+ const ArrowWrapper = styled.div`
61
+ display: grid;
62
+ align-items: center;
63
+
64
+ div {
65
+ height: auto !important;
66
+ min-height: unset;
67
+ }
68
+ `
69
+
70
+ export default {
71
+ name: 'parent-dropdown',
72
+ components: {
73
+ PageWrapper,
74
+ Icon,
75
+ IconWrapper,
76
+ TitleWrapper,
77
+ TitleText,
78
+ ArrowWrapper
79
+ },
80
+ props: {
81
+ isOpen: {
82
+ required: true,
83
+ default: false
84
+ },
85
+ dropdownText: {
86
+ required: true,
87
+ default: 'View'
88
+ }
89
+ }
90
+ }
91
+ </script>
@@ -112,10 +112,6 @@ export default {
112
112
  backgroundColor: {
113
113
  required: false
114
114
  },
115
- hasBorder: {
116
- required: false,
117
- default: false
118
- },
119
115
  hoveredBackgroundColor: {
120
116
  required: false,
121
117
  default: 'transparentWhite1'
@@ -134,15 +130,11 @@ export default {
134
130
  },
135
131
  borderRadius: {
136
132
  required: false,
137
- default: '4px'
133
+ default: '6px'
138
134
  },
139
135
  isHovered: {
140
136
  required: false,
141
137
  default: false
142
- },
143
- isStriked: {
144
- required: false,
145
- default: false
146
138
  }
147
139
  },
148
140
  data() {
@@ -433,6 +433,10 @@ export default {
433
433
  labelFontColor: {
434
434
  required: false,
435
435
  default: 'eturnityGrey'
436
+ },
437
+ focus: {
438
+ required: false,
439
+ default: false
436
440
  }
437
441
  },
438
442
  computed: {
@@ -660,7 +664,17 @@ export default {
660
664
  })
661
665
  }
662
666
  },
667
+ mounted() {
668
+ if (this.focus) {
669
+ this.focusInput()
670
+ }
671
+ },
663
672
  watch: {
673
+ focus(value) {
674
+ if (value) {
675
+ this.focusInput()
676
+ }
677
+ },
664
678
  clearInput: function (value) {
665
679
  if (value) {
666
680
  // If the value is typed, then we should clear the textInput on Continue
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <container>
2
+ <container :inputWidth="inputWidth">
3
3
  <input-wrapper>
4
4
  <input-container
5
5
  ref="inputElement"
@@ -9,6 +9,7 @@
9
9
  :disabled="disabled"
10
10
  :isDisabled="disabled"
11
11
  :inputWidth="inputWidth"
12
+ :isFilter="isFilter"
12
13
  :hasFocus="hasFocus"
13
14
  />
14
15
  <img
@@ -28,18 +29,24 @@
28
29
  // :disabled="true"
29
30
  // inputWidth="250px"
30
31
  // @on-change="function($event)"
32
+ // :isFilter="true" // to set the height at 30px
31
33
  // />
32
34
  import styled from 'vue-styled-components'
33
35
 
34
- const Container = styled.div`
35
- width: 100%;
36
+ const inputAttrs = {
37
+ isDisabled: Boolean,
38
+ inputWidth: String,
39
+ isFilter: Boolean
40
+ }
41
+ const Container = styled('div', inputAttrs)`
42
+ width: ${(props) => (props.inputWidth ? props.inputWidth : '100%')};
36
43
  position: relative;
37
44
  `
38
45
 
39
- const inputAttrs = { isDisabled: Boolean, inputWidth: String }
40
46
  const InputContainer = styled('input', inputAttrs)`
41
- border: 1px solid ${(props) => props.theme.colors.mediumGray};
42
- padding: 11px 30px 11px 10px;
47
+ border: 1px solid ${(props) => props.theme.colors.grey4};
48
+ padding: ${(props) =>
49
+ props.isFilter ? '7px 30px 7px 10px' : '11px 30px 11px 10px'};
43
50
  border-radius: 4px;
44
51
  font-size: 13px;
45
52
  color: ${(props) => props.theme.colors.black};
@@ -90,6 +97,10 @@ export default {
90
97
  required: false,
91
98
  default: null
92
99
  },
100
+ isFilter: {
101
+ required: false,
102
+ default: false
103
+ },
93
104
  hasFocus: {
94
105
  required: false,
95
106
  default: false
@@ -99,10 +110,10 @@ export default {
99
110
  onChangeHandler(event) {
100
111
  this.$emit('on-change', event)
101
112
  },
102
- focusInputElement(){
113
+ focusInputElement() {
103
114
  this.$nextTick(() => {
104
- this.$refs.inputElement.$el.focus();
105
- });
115
+ this.$refs.inputElement.$el.focus()
116
+ })
106
117
  }
107
118
  },
108
119
  watch: {
@@ -112,6 +123,5 @@ export default {
112
123
  }
113
124
  }
114
125
  }
115
-
116
126
  }
117
127
  </script>
@@ -32,6 +32,7 @@
32
32
  ref="select"
33
33
  @click="toggleDropdown"
34
34
  :selectHeight="selectHeight"
35
+ :height="height"
35
36
  :selectMinHeight="selectMinHeight"
36
37
  :bgColor="
37
38
  buttonBgColor || colorMode == 'dark' ? 'transparentBlack1' : 'white'
@@ -145,7 +146,6 @@ const Caret = styled.div`
145
146
  min-width: 30px;
146
147
  height: 100%;
147
148
  align-items: stretch
148
- padding-top: 5px;
149
149
  cursor: pointer;
150
150
  margin-left: auto;
151
151
  `
@@ -193,6 +193,7 @@ const selectButtonAttrs = {
193
193
  hasError: Boolean,
194
194
  disabled: Boolean,
195
195
  selectHeight: String,
196
+ height: String,
196
197
  selectMinHeight: String,
197
198
  isSearchBarVisible: Boolean,
198
199
  showBorder: Boolean
@@ -204,7 +205,14 @@ const selectButton = styled('div', selectButtonAttrs)`
204
205
  padding: ${(props) => (props.isSearchBarVisible ? '0' : '0px 0px 0 15px')};
205
206
  text-align: left;
206
207
  border-radius: 4px;
207
- min-height: ${(props) => props.selectMinHeight};
208
+ min-height: ${(props) =>
209
+ props.selectHeight
210
+ ? props.selectHeight
211
+ : props.selectMinHeight
212
+ ? props.selectMinHeight
213
+ : props.height
214
+ ? props.height
215
+ : '36px'};
208
216
  display: flex;
209
217
  align-items: center;
210
218
  max-height: ${(props) => props.selectHeight};
@@ -254,8 +262,9 @@ const selectDropdown = styled('div', selectDropdownAttrs)`
254
262
  props.theme.colors[props.fontColor]
255
263
  ? props.theme.colors[props.fontColor]
256
264
  : props.fontColor};
257
- max-height:300px;
258
- overflow-y:auto;
265
+ max-height: 300px;
266
+ min-height: 39px;
267
+ overflow-y: auto;
259
268
  & [data-value="${(props) => props.selectedValue}"]{
260
269
  backdrop-filter: brightness(1.4);
261
270
  }
@@ -309,6 +318,10 @@ export default {
309
318
  required: false,
310
319
  default: null
311
320
  },
321
+ height: {
322
+ required: false,
323
+ default: null
324
+ },
312
325
  selectMinHeight: {
313
326
  required: false,
314
327
  default: '36px'
@@ -70,6 +70,8 @@ export const datePickerLang = (lang) => {
70
70
  return 'fr'
71
71
  } else if (lang === 'it-it' || lang === 'it-ch') {
72
72
  return 'it'
73
+ } else if (lang === 'en-us' || lang === 'en-gb') {
74
+ return 'en'
73
75
  } else {
74
76
  return lang
75
77
  }