@eturnity/eturnity_reusable_components 7.30.3-EPDM-10647.0 → 7.30.3-EPDM-10576.2

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