@eturnity/eturnity_reusable_components 7.24.3-EPDM-10576.1 → 7.24.3-EPDM-11320.0

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 (66) hide show
  1. package/.eslintrc.js +125 -0
  2. package/package.json +6 -20
  3. package/src/App.vue +75 -70
  4. package/src/components/addNewButton/index.vue +24 -27
  5. package/src/components/banner/actionBanner/index.vue +32 -30
  6. package/src/components/banner/banner/index.vue +88 -80
  7. package/src/components/banner/infoBanner/index.vue +36 -44
  8. package/src/components/buttons/buttonIcon/index.vue +83 -78
  9. package/src/components/buttons/closeButton/index.vue +26 -26
  10. package/src/components/buttons/mainButton/index.vue +80 -76
  11. package/src/components/card/index.vue +56 -52
  12. package/src/components/collapsableInfoText/index.vue +81 -76
  13. package/src/components/deleteIcon/index.vue +31 -28
  14. package/src/components/draggableInputHandle/index.vue +20 -17
  15. package/src/components/dropdown/Dropdown.stories.js +8 -8
  16. package/src/components/dropdown/index.vue +75 -72
  17. package/src/components/errorMessage/index.vue +23 -23
  18. package/src/components/filter/filterSettings.vue +349 -333
  19. package/src/components/filter/index.vue +130 -130
  20. package/src/components/filter/parentDropdown.vue +43 -40
  21. package/src/components/icon/Icons.stories.js +4 -4
  22. package/src/components/icon/iconCache.js +1 -1
  23. package/src/components/icon/iconCollection.vue +40 -37
  24. package/src/components/icon/index.vue +72 -65
  25. package/src/components/iconWrapper/index.vue +122 -118
  26. package/src/components/infoCard/index.vue +20 -17
  27. package/src/components/infoText/index.vue +88 -82
  28. package/src/components/inputs/checkbox/index.vue +91 -94
  29. package/src/components/inputs/inputNumber/index.vue +508 -488
  30. package/src/components/inputs/inputNumberQuestion/index.vue +127 -124
  31. package/src/components/inputs/inputText/index.vue +265 -252
  32. package/src/components/inputs/radioButton/index.vue +135 -120
  33. package/src/components/inputs/searchInput/index.vue +84 -81
  34. package/src/components/inputs/select/index.vue +644 -631
  35. package/src/components/inputs/select/option/index.vue +91 -91
  36. package/src/components/inputs/select/select.stories.js +7 -7
  37. package/src/components/inputs/slider/index.vue +46 -46
  38. package/src/components/inputs/switchField/index.vue +159 -152
  39. package/src/components/inputs/textAreaInput/index.vue +120 -113
  40. package/src/components/inputs/toggle/index.vue +137 -127
  41. package/src/components/label/index.vue +64 -61
  42. package/src/components/markerItem/index.vue +40 -40
  43. package/src/components/modals/actionModal/index.vue +32 -29
  44. package/src/components/modals/infoModal/index.vue +34 -27
  45. package/src/components/modals/modal/index.vue +88 -80
  46. package/src/components/navigationTabs/index.vue +50 -47
  47. package/src/components/pageSubtitle/index.vue +33 -29
  48. package/src/components/pageTitle/index.vue +47 -39
  49. package/src/components/pagination/index.vue +64 -62
  50. package/src/components/progressBar/index.vue +70 -67
  51. package/src/components/projectMarker/index.vue +172 -163
  52. package/src/components/rangeSlider/Slider.vue +449 -449
  53. package/src/components/rangeSlider/index.vue +282 -270
  54. package/src/components/rangeSlider/utils/dom.js +3 -3
  55. package/src/components/selectedOptions/index.vue +51 -51
  56. package/src/components/sideMenu/index.vue +117 -109
  57. package/src/components/spinner/index.vue +37 -34
  58. package/src/components/tableDropdown/index.vue +343 -326
  59. package/src/components/tables/mainTable/index.vue +109 -106
  60. package/src/components/tables/viewTable/index.vue +105 -92
  61. package/src/components/threeDots/index.vue +174 -171
  62. package/src/components/videoThumbnail/index.vue +67 -59
  63. package/src/components/videoThumbnail/videoThumbnail.stories.js +6 -6
  64. package/.prettierrc +0 -7
  65. package/public/favicon.ico +0 -0
  66. package/public/index.html +0 -17
@@ -1,159 +1,176 @@
1
1
  <template>
2
- <dropdown-row
2
+ <DropdownRow
3
3
  :colspan="colSpan"
4
- :isOpen="isOpen"
5
- @click="toggleOpen"
6
4
  :disabled="disabled"
5
+ :is-open="isOpen"
6
+ @click="toggleOpen"
7
7
  >
8
- <component-container :colSpan="colSpan - 1" class="table-dropdown">
9
- <component-item
8
+ <ComponentContainer
9
+ class="table-dropdown"
10
+ :col-span="colSpan - 1"
11
+ >
12
+ <ComponentItem
10
13
  v-for="(item, index) in tableItems"
11
14
  :key="index"
12
15
  ref="dropdownItem"
13
- :isNested="isNested"
14
16
  :class="{
15
17
  'table-dropdown-item': item.type !== 'input'
16
18
  }"
19
+ :is-nested="isNested"
17
20
  >
18
- <nested-container :isNested="isNested">
19
- <nested-icon
21
+ <NestedContainer :is-nested="isNested">
22
+ <NestedIcon
20
23
  v-if="
21
24
  isNested &&
22
- (item.type === 'input' ||
23
- item.type === 'no-template' ||
24
- item.type === 'template')
25
+ (item.type === 'input' ||
26
+ item.type === 'no-template' ||
27
+ item.type === 'template')
25
28
  "
26
29
  />
27
- <template-button
28
- @click.stop="onTemplateClick(item.row)"
30
+ <TemplateButton
29
31
  v-if="
30
32
  item.type &&
31
- item.type === 'template' &&
32
- (item.value === '' || item.value === '-')
33
+ item.type === 'template' &&
34
+ (item.value === '' || item.value === '-')
33
35
  "
34
36
  :key="index + '_button'"
35
- >{{ $gettext('Use template...') }}</template-button
37
+ @click.stop="onTemplateClick(item.row)"
36
38
  >
37
- <template-link
39
+ {{ $gettext('Use template...') }}
40
+ </TemplateButton>
41
+ <TemplateLink
38
42
  v-else-if="
39
43
  item.type && item.type === 'template' && item.value !== ''
40
44
  "
41
45
  @click.stop="onSelectedTemplateClick(item.row)"
42
46
  >
43
47
  <!-- <img :src="fileIcon" alt="icon" width="12" height="16" /> -->
44
- <icon
45
- name="template_icon_not_clickable"
48
+ <Icon
46
49
  :color="theme.colors.brightBlue"
50
+ name="template_icon_not_clickable"
47
51
  size="14px"
48
52
  />
49
53
  <div>{{ item.value }}</div>
50
- </template-link>
51
- <no-template v-if="item.type && item.type === 'no-template'">
54
+ </TemplateLink>
55
+ <NoTemplate v-if="item.type && item.type === 'no-template'">
52
56
  {{ $gettext('No main component template') }}
53
- </no-template>
54
- <input-container
57
+ </NoTemplate>
58
+ <InputContainer
55
59
  v-if="item.type === 'input'"
56
60
  @click.stop="onInputClick()"
57
61
  >
58
- <text-container
62
+ <TextContainer
59
63
  v-if="customInputDisabled"
60
64
  class="input-placeholder"
61
65
  >
62
66
  <span> {{ item.value }}</span>
63
- </text-container>
64
- <input-text
67
+ </TextContainer>
68
+ <InputText
65
69
  v-else
66
70
  class="inputField"
67
- :value="item.value"
68
- :noBorder="true"
69
- :minWidth="item.value.length + 'ch'"
70
71
  :disabled="customInputDisabled"
72
+ :min-width="item.value.length + 'ch'"
73
+ :no-border="true"
74
+ :value="item.value"
71
75
  @input-change="onCustomInputChange($event)"
72
76
  />
73
- </input-container>
74
- <text-container
77
+ </InputContainer>
78
+ <TextContainer
75
79
  v-else-if="
76
80
  item.type !== 'input' &&
77
- item.type !== 'no-template' &&
78
- item.type !== 'template'
81
+ item.type !== 'no-template' &&
82
+ item.type !== 'template'
79
83
  "
80
84
  >
81
85
  <span> {{ item.value }}</span>
82
- </text-container>
83
- </nested-container>
84
- </component-item>
85
- <arrow-container class="arrow-container" :isDisabled="disabled">
86
- <arrow-wrapper :showArchived="showArchived">
87
- <et-popover
86
+ </TextContainer>
87
+ </NestedContainer>
88
+ </ComponentItem>
89
+ <ArrowContainer
90
+ class="arrow-container"
91
+ :is-disabled="disabled"
92
+ >
93
+ <ArrowWrapper :show-archived="showArchived">
94
+ <EtPopover
88
95
  v-if="showArchived"
89
96
  button-class="error"
90
97
  :text="
91
98
  $gettext(`Component has been archived and shouldn't be used`)
92
99
  "
93
- triggerType="hover"
94
- ></et-popover>
95
- <arrow-down
96
- @click.stop="toggleOpen"
100
+ trigger-type="hover"
101
+ />
102
+ <ArrowDown
97
103
  v-if="!isOpen"
98
104
  class="arrow-dropdown"
105
+ @click.stop="toggleOpen"
99
106
  />
100
- <arrow-up @click.stop="toggleOpen" v-else />
101
- </arrow-wrapper>
102
- <options-container v-if="isOpen" ref="optionsContainer">
103
- <options-wrapper @click.prevent.stop>
104
- <search-container @click.prevent.stop>
105
- <search-input
106
- :value="inputText"
107
+ <ArrowUp
108
+ v-else
109
+ @click.stop="toggleOpen"
110
+ />
111
+ </ArrowWrapper>
112
+ <OptionsContainer
113
+ v-if="isOpen"
114
+ ref="optionsContainer"
115
+ >
116
+ <OptionsWrapper @click.prevent.stop>
117
+ <SearchContainer @click.prevent.stop>
118
+ <SearchInput
119
+ ref="searchInput"
107
120
  :placeholder="$gettext('Keyword') + '...'"
121
+ :value="inputText"
108
122
  @click.prevent.stop
109
123
  @on-change="onSearch($event)"
110
- ref="searchInput"
111
124
  />
112
- </search-container>
113
- <spinner v-if="optionsLoading" />
114
- <empty-text v-else-if="!optionsLoading && !optionItems.length">
125
+ </SearchContainer>
126
+ <Spinner v-if="optionsLoading" />
127
+ <EmptyText v-else-if="!optionsLoading && !optionItems.length">
115
128
  {{ emptyText ? emptyText : $gettext('No components found.') }}
116
- </empty-text>
117
- <options-item
118
- v-else
119
- :colSpan="colSpan - 1"
120
- :width="dynamicGridWidth"
129
+ </EmptyText>
130
+ <OptionsItem
121
131
  v-for="(item, index) in optionItems"
132
+ v-else
122
133
  :key="index"
123
- @click="onItemClick(item)"
134
+ :col-span="colSpan - 1"
124
135
  :tabindex="0"
136
+ :width="dynamicGridWidth"
137
+ @click="onItemClick(item)"
125
138
  @keyup.enter="onItemClick(item)"
126
139
  >
127
- <template v-for="(option, idx) in optionsDisplay" :key="idx">
140
+ <template
141
+ v-for="(option, idx) in optionsDisplay"
142
+ :key="idx"
143
+ >
128
144
  <span v-if="option !== 'template'">
129
145
  {{ !!item[option] ? item[option] : '-' }}
130
146
  </span>
131
- <template-button
132
- @click.stop="onTemplateClick(item)"
147
+ <TemplateButton
133
148
  v-else-if="option === 'template' && item.has_template"
134
- >{{ $gettext('Use template...') }}</template-button
149
+ @click.stop="onTemplateClick(item)"
135
150
  >
136
- <no-template
151
+ {{ $gettext('Use template...') }}
152
+ </TemplateButton>
153
+ <NoTemplate
137
154
  v-else-if="option === 'template' && !item.has_template"
138
155
  >
139
156
  {{ $gettext('No main component template') }}
140
- </no-template>
157
+ </NoTemplate>
141
158
  </template>
142
- </options-item>
143
- </options-wrapper>
144
- <custom-container
159
+ </OptionsItem>
160
+ </OptionsWrapper>
161
+ <CustomContainer
145
162
  v-if="inputText.length && allowFreeInputs"
146
163
  @click="onCustomNameClick()"
147
164
  >
148
- <custom-name>{{ getCustomName }}</custom-name>
149
- <custom-subtext
150
- >({{ $gettext('custom_component') }})</custom-subtext
151
- >
152
- </custom-container>
153
- </options-container>
154
- </arrow-container>
155
- </component-container>
156
- </dropdown-row>
165
+ <CustomName>{{ getCustomName }}</CustomName>
166
+ <CustomSubtext>
167
+ ({{ $gettext('custom_component') }})
168
+ </CustomSubtext>
169
+ </CustomContainer>
170
+ </OptionsContainer>
171
+ </ArrowContainer>
172
+ </ComponentContainer>
173
+ </DropdownRow>
157
174
  </template>
158
175
 
159
176
  <script>
@@ -176,18 +193,18 @@
176
193
  // :optionsDisplay="['display_name', 'company_item_number']" // Array. what should be displayed
177
194
  // :disabled="true"
178
195
  // />
179
- import styled from 'vue3-styled-components'
180
- import Spinner from '../spinner'
181
- import SearchInput from '../inputs/searchInput'
182
- import InputText from '../inputs/inputText'
183
- import CollapseArrowIcon from '../../assets/icons/collapse_arrow_icon.svg'
184
- import SubpositionMarkerIcon from '../../assets/icons/subposition_marker.svg'
185
- import fileIconPng from '../../assets/icons/file_icon.png'
186
- import Icon from '../icon'
187
- import theme from '@/assets/theme.js'
188
-
189
- const rowAttrs = { disabled: Boolean, isOpen: Boolean }
190
- const DropdownRow = styled('div', rowAttrs)`
196
+ import styled from 'vue3-styled-components'
197
+ import Spinner from '../spinner'
198
+ import SearchInput from '../inputs/searchInput'
199
+ import InputText from '../inputs/inputText'
200
+ import CollapseArrowIcon from '../../assets/icons/collapse_arrow_icon.svg'
201
+ import SubpositionMarkerIcon from '../../assets/icons/subposition_marker.svg'
202
+ import fileIconPng from '../../assets/icons/file_icon.png'
203
+ import Icon from '../icon'
204
+ import theme from '@/assets/theme.js'
205
+
206
+ const rowAttrs = { disabled: Boolean, isOpen: Boolean }
207
+ const DropdownRow = styled('div', rowAttrs)`
191
208
  cursor: ${(props) => (props.disabled ? 'not-allowed' : 'pointer')};
192
209
  display: contents;
193
210
 
@@ -201,8 +218,8 @@ const DropdownRow = styled('div', rowAttrs)`
201
218
  }
202
219
  `
203
220
 
204
- const ItemAttrs = { isNested: Boolean }
205
- const ComponentItem = styled('td', ItemAttrs)`
221
+ const ItemAttrs = { isNested: Boolean }
222
+ const ComponentItem = styled('td', ItemAttrs)`
206
223
  padding-left: ${(props) => (props.isNested ? '14px !important' : '0')};
207
224
  overflow: hidden;
208
225
  text-overflow: ellipsis;
@@ -226,8 +243,8 @@ const ComponentItem = styled('td', ItemAttrs)`
226
243
  }
227
244
  `
228
245
 
229
- const containerAttrs = { colSpan: Number, width: String }
230
- const ComponentContainer = styled('div', containerAttrs)`
246
+ const containerAttrs = { colSpan: Number, width: String }
247
+ const ComponentContainer = styled('div', containerAttrs)`
231
248
  display: contents;
232
249
  align-items: center;
233
250
  background-color: ${(props) => props.theme.colors.white};
@@ -235,19 +252,19 @@ const ComponentContainer = styled('div', containerAttrs)`
235
252
  padding: 5px 4px;
236
253
  `
237
254
 
238
- const ArrowDown = styled(CollapseArrowIcon)`
255
+ const ArrowDown = styled(CollapseArrowIcon)`
239
256
  width: 8px;
240
257
  transition: transform 150ms ease;
241
258
  `
242
259
 
243
- const ArrowUp = styled.img`
260
+ const ArrowUp = styled.img`
244
261
  width: 8px;
245
262
  transform: rotate(180deg);
246
263
  transition: transform 150ms ease;
247
264
  `
248
265
 
249
- const ArrowAttrs = { isDisabled: Boolean }
250
- const ArrowContainer = styled('td', ArrowAttrs)`
266
+ const ArrowAttrs = { isDisabled: Boolean }
267
+ const ArrowContainer = styled('td', ArrowAttrs)`
251
268
  border-bottom: 1px solid ${(props) => props.theme.colors.grey4};
252
269
  background-clip: content-box;
253
270
  padding: 8px 0 7px 0 !important;
@@ -267,18 +284,18 @@ const ArrowContainer = styled('td', ArrowAttrs)`
267
284
  }
268
285
  `
269
286
 
270
- const arrowAttrs = { showArchived: Boolean }
271
- const ArrowWrapper = styled('div', arrowAttrs)`
287
+ const arrowAttrs = { showArchived: Boolean }
288
+ const ArrowWrapper = styled('div', arrowAttrs)`
272
289
  display: grid;
273
290
  grid-template-columns: ${(props) =>
274
- props.showArchived ? 'auto auto' : 'auto'};
291
+ props.showArchived ? 'auto auto' : 'auto'};
275
292
  align-items: center;
276
293
  justify-items: center;
277
294
  height: 100%;
278
295
  `
279
296
 
280
- const optionsAttrs = { top: Number, left: Number }
281
- const OptionsContainer = styled('div', optionsAttrs)`
297
+ const optionsAttrs = { top: Number, left: Number }
298
+ const OptionsContainer = styled('div', optionsAttrs)`
282
299
  position: absolute;
283
300
  margin-top: 10px;
284
301
  display: grid;
@@ -294,7 +311,7 @@ const OptionsContainer = styled('div', optionsAttrs)`
294
311
  border-radius: 4px;
295
312
  `
296
313
 
297
- const EmptyText = styled.div`
314
+ const EmptyText = styled.div`
298
315
  align-self: center;
299
316
  justify-self: center;
300
317
  height: 100px;
@@ -302,7 +319,7 @@ const EmptyText = styled.div`
302
319
  align-content: center;
303
320
  `
304
321
 
305
- const OptionsWrapper = styled.div`
322
+ const OptionsWrapper = styled.div`
306
323
  display: grid;
307
324
  position: relative;
308
325
  padding: 12px;
@@ -313,7 +330,7 @@ const OptionsWrapper = styled.div`
313
330
  min-width: 400px; // kind of an arbitrary number until we know all use cases
314
331
  `
315
332
 
316
- const OptionsItem = styled('div', containerAttrs)`
333
+ const OptionsItem = styled('div', containerAttrs)`
317
334
  display: grid;
318
335
  grid-template-columns: ${(props) => props.width};
319
336
  grid-gap: 30px;
@@ -331,7 +348,7 @@ const OptionsItem = styled('div', containerAttrs)`
331
348
  }
332
349
  `
333
350
 
334
- const SearchContainer = styled.div`
351
+ const SearchContainer = styled.div`
335
352
  position: sticky;
336
353
  top: 0;
337
354
  padding-top: 6px;
@@ -339,7 +356,7 @@ const SearchContainer = styled.div`
339
356
  height: 40px;
340
357
  `
341
358
 
342
- const TemplateButton = styled.div`
359
+ const TemplateButton = styled.div`
343
360
  cursor: pointer;
344
361
  background-color: #263238;
345
362
  color: ${(props) => props.theme.colors.white};
@@ -350,7 +367,7 @@ const TemplateButton = styled.div`
350
367
  margin-left: 15px;
351
368
  `
352
369
 
353
- const NoTemplate = styled.div`
370
+ const NoTemplate = styled.div`
354
371
  color: ${(props) => props.theme.colors.gray1};
355
372
  font-style: italic;
356
373
  overflow: hidden;
@@ -358,7 +375,7 @@ const NoTemplate = styled.div`
358
375
  padding-left: 15px;
359
376
  `
360
377
 
361
- const TemplateLink = styled.div`
378
+ const TemplateLink = styled.div`
362
379
  color: ${(props) => props.theme.colors.brightBlue};
363
380
  cursor: pointer;
364
381
  display: grid;
@@ -367,13 +384,13 @@ const TemplateLink = styled.div`
367
384
  padding-left: 15px;
368
385
  `
369
386
 
370
- const InputContainer = styled.div`
387
+ const InputContainer = styled.div`
371
388
  .inputField input {
372
389
  border-radius: 4px 0 0 4px;
373
390
  }
374
391
  `
375
392
 
376
- const CustomContainer = styled.div`
393
+ const CustomContainer = styled.div`
377
394
  display: grid;
378
395
  grid-template-columns: auto 1fr;
379
396
  padding: 10px 22px;
@@ -385,254 +402,254 @@ const CustomContainer = styled.div`
385
402
  }
386
403
  `
387
404
 
388
- const CustomName = styled.div`
405
+ const CustomName = styled.div`
389
406
  justify-self: flex-start;
390
407
  `
391
408
 
392
- const CustomSubtext = styled.div`
409
+ const CustomSubtext = styled.div`
393
410
  justify-self: flex-end;
394
411
  color: ${(props) => props.theme.colors.grey3};
395
412
  `
396
413
 
397
- const TextContainer = styled.div`
414
+ const TextContainer = styled.div`
398
415
  height: 100%;
399
416
  display: grid;
400
417
  align-items: center;
401
418
  `
402
419
 
403
- const NestedIcon = styled(SubpositionMarkerIcon)`
420
+ const NestedIcon = styled(SubpositionMarkerIcon)`
404
421
  height: 10px;
405
422
  width: 6px;
406
423
  `
407
424
 
408
- const NestedAttrs = { isNested: Boolean }
409
- const NestedContainer = styled('div', NestedAttrs)`
425
+ const NestedAttrs = { isNested: Boolean }
426
+ const NestedContainer = styled('div', NestedAttrs)`
410
427
  display: grid;
411
428
  grid-gap: 5px;
412
429
  grid-template-columns: ${(props) => (props.isNested ? 'auto 1fr' : '1fr')};
413
430
  align-items: center;
414
431
  `
415
432
 
416
- export default {
417
- name: 'table-dropdown',
418
- components: {
419
- DropdownRow,
420
- ComponentItem,
421
- ComponentContainer,
422
- ArrowDown,
423
- ArrowUp,
424
- OptionsContainer,
425
- Spinner,
426
- EmptyText,
427
- SearchInput,
428
- ArrowWrapper,
429
- OptionsWrapper,
430
- OptionsItem,
431
- SearchContainer,
432
- TemplateButton,
433
- NoTemplate,
434
- TemplateLink,
435
- InputText,
436
- InputContainer,
437
- CustomContainer,
438
- CustomName,
439
- CustomSubtext,
440
- ArrowContainer,
441
- TextContainer,
442
- NestedIcon,
443
- NestedContainer,
444
- Icon
445
- },
446
- props: {
447
- colSpan: {
448
- required: false,
449
- default: 1
450
- },
451
- customInputDisabled: {
452
- // whether the input field should be disabled
453
- required: false,
454
- default: true
455
- },
456
- allowFreeInputs: {
457
- // whether we allow the user to select a custom input
458
- required: false,
459
- default: false
460
- },
461
- tableItems: {
462
- required: true
463
- },
464
- showArchived: {
465
- required: false,
466
- default: false
467
- },
468
- isOpen: {
469
- required: true,
470
- default: false
471
- },
472
- optionsLoading: {
473
- required: false,
474
- default: false
475
- },
476
- emptyText: {
477
- required: false,
478
- default: null
479
- },
480
- optionItems: {
481
- required: true
482
- },
483
- optionsDisplay: {
484
- required: true,
485
- default: [] // should be like ['display_name', 'company_item_number', 'description']
486
- },
487
- disabled: {
488
- required: false,
489
- default: false
490
- },
491
- isNested: {
492
- required: false,
493
- default: false
494
- }
495
- },
496
- data() {
497
- return {
498
- inputText: '',
499
- wasClicked: false, // prevents custom-name from being triggered on the <input-text />
500
- dynamicWidth: [], // for numbers
501
- dynamicGridWidth: [], // for grid values
502
- fileIcon: fileIconPng
503
- }
504
- },
505
- methods: {
506
- toggleOpen(event) {
507
- if (
508
- this.disabled ||
509
- (event &&
510
- !(event.target === this.$el) &&
511
- !this.$el.contains(event.target))
512
- ) {
513
- return
514
- }
515
- this.wasClicked = false
516
- if (!this.isOpen) {
517
- document.addEventListener('click', this.clickOutside)
518
- this.$emit('dropdown-search', '')
519
- this.$nextTick(() => {
520
- this.scrollToItem()
521
- })
522
- this.$emit('toggle-dropdown-open', { close: false })
523
- this.$nextTick(() => {
524
- this.$refs.searchInput.$el.children[0].children[1].focus()
525
- })
526
- } else {
527
- document.removeEventListener('click', this.clickOutside)
528
- this.$emit('toggle-dropdown-open', { close: true })
529
- this.inputText = ''
530
- }
433
+ export default {
434
+ name: 'TableDropdown',
435
+ components: {
436
+ DropdownRow,
437
+ ComponentItem,
438
+ ComponentContainer,
439
+ ArrowDown,
440
+ ArrowUp,
441
+ OptionsContainer,
442
+ Spinner,
443
+ EmptyText,
444
+ SearchInput,
445
+ ArrowWrapper,
446
+ OptionsWrapper,
447
+ OptionsItem,
448
+ SearchContainer,
449
+ TemplateButton,
450
+ NoTemplate,
451
+ TemplateLink,
452
+ InputText,
453
+ InputContainer,
454
+ CustomContainer,
455
+ CustomName,
456
+ CustomSubtext,
457
+ ArrowContainer,
458
+ TextContainer,
459
+ NestedIcon,
460
+ NestedContainer,
461
+ Icon
531
462
  },
532
- onInputClick() {
533
- if (!this.isOpen) {
534
- this.toggleOpen()
463
+ props: {
464
+ colSpan: {
465
+ required: false,
466
+ default: 1
467
+ },
468
+ customInputDisabled: {
469
+ // whether the input field should be disabled
470
+ required: false,
471
+ default: true
472
+ },
473
+ allowFreeInputs: {
474
+ // whether we allow the user to select a custom input
475
+ required: false,
476
+ default: false
477
+ },
478
+ tableItems: {
479
+ required: true
480
+ },
481
+ showArchived: {
482
+ required: false,
483
+ default: false
484
+ },
485
+ isOpen: {
486
+ required: true,
487
+ default: false
488
+ },
489
+ optionsLoading: {
490
+ required: false,
491
+ default: false
492
+ },
493
+ emptyText: {
494
+ required: false,
495
+ default: null
496
+ },
497
+ optionItems: {
498
+ required: true
499
+ },
500
+ optionsDisplay: {
501
+ required: true,
502
+ default: [] // should be like ['display_name', 'company_item_number', 'description']
503
+ },
504
+ disabled: {
505
+ required: false,
506
+ default: false
507
+ },
508
+ isNested: {
509
+ required: false,
510
+ default: false
535
511
  }
536
512
  },
537
- scrollToItem() {
538
- if (this.$refs.optionsContainer) {
539
- this.$refs.optionsContainer.$el.scrollIntoView({
540
- behavior: 'smooth',
541
- block: 'center'
542
- })
513
+ data() {
514
+ return {
515
+ inputText: '',
516
+ wasClicked: false, // prevents custom-name from being triggered on the <input-text />
517
+ dynamicWidth: [], // for numbers
518
+ dynamicGridWidth: [], // for grid values
519
+ fileIcon: fileIconPng
543
520
  }
544
521
  },
545
- onTemplateClick(item) {
546
- this.$emit('on-template-click', item)
547
- },
548
- onSelectedTemplateClick(item) {
549
- this.$emit('on-selected-template-click', item)
550
- },
551
- onItemClick(item) {
552
- this.wasClicked = true
553
- this.$emit('item-selected', item)
554
- },
555
- onSearch(value) {
556
- this.inputText = value
557
- this.$emit('dropdown-search', value)
558
- },
559
- clickOutside(event) {
560
- if (event.target === this.$el || this.$el.contains(event.target)) {
561
- return
522
+ computed: {
523
+ getCustomName() {
524
+ return this.inputText
525
+ },
526
+ theme() {
527
+ return theme
562
528
  }
563
- this.inputText = ''
564
- // 'close: true' is needed in case a box is open and another box is clicked on
565
- // so this one will close properly
566
- document.removeEventListener('click', this.clickOutside)
567
- this.$emit('toggle-dropdown-open', { close: true })
568
- },
569
- onCustomNameClick() {
570
- this.wasClicked = true
571
- this.$emit('on-custom-input-name', this.inputText)
572
- this.$emit('toggle-dropdown-open', { close: true })
573
- this.inputText = ''
574
529
  },
575
- onCustomInputChange(event) {
576
- if (this.wasClicked) {
577
- return
578
- }
579
- this.$emit('custom-input-change', event)
580
- },
581
- setDropdownWidth(options) {
582
- this.dynamicWidth = []
583
-
584
- options.forEach((item) => {
585
- this.optionsDisplay.forEach((header, index) => {
586
- let value =
587
- header === 'template'
588
- ? this.$gettext('No main component template')
589
- : item[header]
590
- value = value ? value : ''
591
-
592
- // Update dynamicWidth with the maximum value
593
- if (
594
- !this.dynamicWidth[index] ||
595
- value.length > this.dynamicWidth[index]
596
- ) {
597
- this.dynamicWidth[index] = value.length
530
+ watch: {
531
+ isOpen(newVal) {
532
+ if (newVal) {
533
+ document.addEventListener('click', this.clickOutside)
534
+ this.$emit('dropdown-search', '')
535
+ this.$nextTick(() => {
536
+ this.$refs.searchInput.$el.children[0].children[0].focus()
537
+ })
538
+ this.$nextTick(() => {
539
+ this.scrollToItem()
540
+ })
541
+ }
542
+ },
543
+ optionItems: {
544
+ immediate: true,
545
+ handler(val) {
546
+ if (val && val.length) {
547
+ this.setDropdownWidth(val)
598
548
  }
599
- })
600
- })
601
-
602
- this.dynamicGridWidth = this.dynamicWidth
603
- .map((width) => width + 'ch')
604
- .join(' ')
605
- }
606
- },
607
- computed: {
608
- getCustomName() {
609
- return this.inputText
610
- },
611
- theme() {
612
- return theme
613
- }
614
- },
615
- watch: {
616
- isOpen(newVal) {
617
- if (newVal) {
618
- document.addEventListener('click', this.clickOutside)
619
- this.$emit('dropdown-search', '')
620
- this.$nextTick(() => {
621
- this.$refs.searchInput.$el.children[0].children[0].focus()
622
- })
623
- this.$nextTick(() => {
624
- this.scrollToItem()
625
- })
549
+ }
626
550
  }
627
551
  },
628
- optionItems: {
629
- immediate: true,
630
- handler(val) {
631
- if (val && val.length) {
632
- this.setDropdownWidth(val)
552
+ methods: {
553
+ toggleOpen(event) {
554
+ if (
555
+ this.disabled ||
556
+ (event &&
557
+ !(event.target === this.$el) &&
558
+ !this.$el.contains(event.target))
559
+ ) {
560
+ return
561
+ }
562
+ this.wasClicked = false
563
+ if (!this.isOpen) {
564
+ document.addEventListener('click', this.clickOutside)
565
+ this.$emit('dropdown-search', '')
566
+ this.$nextTick(() => {
567
+ this.scrollToItem()
568
+ })
569
+ this.$emit('toggle-dropdown-open', { close: false })
570
+ this.$nextTick(() => {
571
+ this.$refs.searchInput.$el.children[0].children[1].focus()
572
+ })
573
+ } else {
574
+ document.removeEventListener('click', this.clickOutside)
575
+ this.$emit('toggle-dropdown-open', { close: true })
576
+ this.inputText = ''
577
+ }
578
+ },
579
+ onInputClick() {
580
+ if (!this.isOpen) {
581
+ this.toggleOpen()
582
+ }
583
+ },
584
+ scrollToItem() {
585
+ if (this.$refs.optionsContainer) {
586
+ this.$refs.optionsContainer.$el.scrollIntoView({
587
+ behavior: 'smooth',
588
+ block: 'center'
589
+ })
633
590
  }
591
+ },
592
+ onTemplateClick(item) {
593
+ this.$emit('on-template-click', item)
594
+ },
595
+ onSelectedTemplateClick(item) {
596
+ this.$emit('on-selected-template-click', item)
597
+ },
598
+ onItemClick(item) {
599
+ this.wasClicked = true
600
+ this.$emit('item-selected', item)
601
+ },
602
+ onSearch(value) {
603
+ this.inputText = value
604
+ this.$emit('dropdown-search', value)
605
+ },
606
+ clickOutside(event) {
607
+ if (event.target === this.$el || this.$el.contains(event.target)) {
608
+ return
609
+ }
610
+ this.inputText = ''
611
+ // 'close: true' is needed in case a box is open and another box is clicked on
612
+ // so this one will close properly
613
+ document.removeEventListener('click', this.clickOutside)
614
+ this.$emit('toggle-dropdown-open', { close: true })
615
+ },
616
+ onCustomNameClick() {
617
+ this.wasClicked = true
618
+ this.$emit('on-custom-input-name', this.inputText)
619
+ this.$emit('toggle-dropdown-open', { close: true })
620
+ this.inputText = ''
621
+ },
622
+ onCustomInputChange(event) {
623
+ if (this.wasClicked) {
624
+ return
625
+ }
626
+ this.$emit('custom-input-change', event)
627
+ },
628
+ setDropdownWidth(options) {
629
+ this.dynamicWidth = []
630
+
631
+ options.forEach((item) => {
632
+ this.optionsDisplay.forEach((header, index) => {
633
+ let value =
634
+ header === 'template'
635
+ ? this.$gettext('No main component template')
636
+ : item[header]
637
+ value = value ? value : ''
638
+
639
+ // Update dynamicWidth with the maximum value
640
+ if (
641
+ !this.dynamicWidth[index] ||
642
+ value.length > this.dynamicWidth[index]
643
+ ) {
644
+ this.dynamicWidth[index] = value.length
645
+ }
646
+ })
647
+ })
648
+
649
+ this.dynamicGridWidth = this.dynamicWidth
650
+ .map((width) => width + 'ch')
651
+ .join(' ')
634
652
  }
635
653
  }
636
654
  }
637
- }
638
655
  </script>