@eturnity/eturnity_reusable_components 6.43.9-EPDM-6751.4 → 6.43.9-EPDM-6751.6
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 +2 -2
- package/src/assets/theme.js +3 -3
- package/src/components/inputs/select/index.vue +41 -30
- package/src/components/inputs/select/option/index.vue +5 -5
- package/src/components/sideMenu/index.vue +5 -3
- package/src/components/tableDropdown/index.vue +9 -18
- package/src/components/tables/mainTable/index.vue +69 -6
- package/src/components/threeDots/index.vue +103 -52
- package/src/helpers/numberConverter.js +17 -17
- package/src/helpers/translateLang.js +12 -0
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@eturnity/eturnity_reusable_components",
|
3
|
-
"version": "6.43.9-EPDM-6751.
|
3
|
+
"version": "6.43.9-EPDM-6751.6",
|
4
4
|
"private": false,
|
5
5
|
"scripts": {
|
6
6
|
"dev": "vue-cli-service serve",
|
@@ -63,4 +63,4 @@
|
|
63
63
|
"author": "Aaron Enser",
|
64
64
|
"license": "ISC",
|
65
65
|
"homepage": "https://bitbucket.org/eturnitydevs/eturnity_reusable_components#readme"
|
66
|
-
}
|
66
|
+
}
|
package/src/assets/theme.js
CHANGED
@@ -3,7 +3,7 @@ const theme = {
|
|
3
3
|
primary: '#48a2d0',
|
4
4
|
secondary: '#fdb813',
|
5
5
|
tertiary: '#d5d5d5',
|
6
|
-
black: '#
|
6
|
+
black: '#263238',
|
7
7
|
yellow: '#fdb813',
|
8
8
|
darkGray: '#818181',
|
9
9
|
gray1: '#666',
|
@@ -20,8 +20,8 @@ const theme = {
|
|
20
20
|
grey5: '#fafafa',
|
21
21
|
grey6: '#555d61',
|
22
22
|
green: '#99db0c',
|
23
|
-
transparentWhite1:'#ffffff32',
|
24
|
-
transparentBlack1:'#263238e6',
|
23
|
+
transparentWhite1: '#ffffff32',
|
24
|
+
transparentBlack1: '#263238e6',
|
25
25
|
disabled: '#dfe1e1',
|
26
26
|
eturnityGrey: '#263238'
|
27
27
|
},
|
@@ -93,17 +93,18 @@
|
|
93
93
|
ref="dropdown"
|
94
94
|
v-show="isDropdownOpen"
|
95
95
|
:hoveredIndex="hoveredIndex"
|
96
|
+
:hoveredValue="hoveredValue"
|
96
97
|
:isActive="isActive"
|
97
98
|
:optionWidth="optionWidth"
|
98
|
-
:
|
99
|
-
|
100
|
-
"
|
99
|
+
:hoveredBgColor="colorMode == 'dark' ? '#000000' : dropdownBgColor"
|
100
|
+
:bgColor="colorMode == 'dark' ? 'black' : dropdownBgColor"
|
101
101
|
:fontColor="
|
102
102
|
dropdownFontColor || colorMode == 'dark' ? 'white' : 'black'
|
103
103
|
"
|
104
104
|
:selectedValue="selectedValue"
|
105
105
|
@option-selected="optionSelected"
|
106
106
|
@option-hovered="optionHovered"
|
107
|
+
@mouseleave="optionLeave"
|
107
108
|
>
|
108
109
|
<slot name="dropdown"></slot>
|
109
110
|
</selectDropdown>
|
@@ -154,7 +155,7 @@ const Selector = styled.div`
|
|
154
155
|
width: 100%;
|
155
156
|
`
|
156
157
|
|
157
|
-
const labelAttrs = { fontSize: String }
|
158
|
+
const labelAttrs = { fontSize: String, fontColor: String }
|
158
159
|
const InputLabel = styled('div', labelAttrs)`
|
159
160
|
color: ${(props) =>
|
160
161
|
props.theme.colors[props.fontColor]
|
@@ -234,11 +235,13 @@ const selectButton = styled('div', selectButtonAttrs)`
|
|
234
235
|
${(props) => (props.disabled ? 'pointer-events: none' : '')};
|
235
236
|
`
|
236
237
|
const selectDropdownAttrs = {
|
238
|
+
hoveredBgColor: String,
|
237
239
|
bgColor: String,
|
238
240
|
fontColor: String,
|
239
241
|
selectWidth: String,
|
240
242
|
optionWidth: String,
|
241
243
|
hoveredIndex: Number,
|
244
|
+
hoveredValue: Number | String,
|
242
245
|
selectedValue: Number | String
|
243
246
|
}
|
244
247
|
const selectDropdown = styled('div', selectDropdownAttrs)`
|
@@ -262,14 +265,13 @@ const selectDropdown = styled('div', selectDropdownAttrs)`
|
|
262
265
|
props.theme.colors[props.fontColor]
|
263
266
|
? props.theme.colors[props.fontColor]
|
264
267
|
: props.fontColor};
|
265
|
-
max-height:
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
backdrop-filter: brightness(1.2);
|
268
|
+
max-height:300px;
|
269
|
+
overflow-y:auto;
|
270
|
+
&>div[data-value="${(props) => props.hoveredValue}"]{
|
271
|
+
background-color:${(props) =>
|
272
|
+
props.theme.colors[props.hoveredBgColor]
|
273
|
+
? props.theme.colors[props.hoveredBgColor]
|
274
|
+
: props.hoveredBgColor};
|
273
275
|
}
|
274
276
|
`
|
275
277
|
const DropdownWrapper = styled('div')`
|
@@ -334,6 +336,10 @@ export default {
|
|
334
336
|
required: false,
|
335
337
|
default: false
|
336
338
|
},
|
339
|
+
dropdownAutoClose: {
|
340
|
+
required: false,
|
341
|
+
default: true
|
342
|
+
},
|
337
343
|
alignItems: {
|
338
344
|
required: false,
|
339
345
|
default: 'horizontal'
|
@@ -345,7 +351,8 @@ export default {
|
|
345
351
|
required: false
|
346
352
|
},
|
347
353
|
dropdownBgColor: {
|
348
|
-
required: false
|
354
|
+
required: false,
|
355
|
+
default: 'grey5'
|
349
356
|
},
|
350
357
|
dropdownFontColor: {
|
351
358
|
required: false
|
@@ -406,6 +413,7 @@ export default {
|
|
406
413
|
isActive: false,
|
407
414
|
textSearch: '',
|
408
415
|
hoveredIndex: 0,
|
416
|
+
hoveredValue:null,
|
409
417
|
isClickOutsideActive: false
|
410
418
|
}
|
411
419
|
},
|
@@ -444,13 +452,7 @@ export default {
|
|
444
452
|
this.$emit('input-change', e)
|
445
453
|
},
|
446
454
|
optionHovered(e) {
|
447
|
-
|
448
|
-
if (this.$refs.dropdown) {
|
449
|
-
this.hoveredIndex =
|
450
|
-
this.$refs.dropdown.$children
|
451
|
-
.map((component) => component.$el)
|
452
|
-
.indexOf(optionElement) + 1
|
453
|
-
}
|
455
|
+
this.hoveredValue=e
|
454
456
|
},
|
455
457
|
mouseEnterHandler() {
|
456
458
|
if (this.hoverDropdown) {
|
@@ -463,6 +465,11 @@ export default {
|
|
463
465
|
this.blur()
|
464
466
|
}
|
465
467
|
},
|
468
|
+
optionLeave() {
|
469
|
+
if(this.dropdownAutoClose) {
|
470
|
+
this.isDropdownOpen = false
|
471
|
+
}
|
472
|
+
},
|
466
473
|
searchChange(value) {
|
467
474
|
this.textSearch = value
|
468
475
|
this.$emit('search-change', value)
|
@@ -504,16 +511,20 @@ export default {
|
|
504
511
|
}
|
505
512
|
},
|
506
513
|
onArrowPress(dir) {
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
514
|
+
let newHoveredElem
|
515
|
+
const currentHoveredElem=this.$refs.dropdown.$el.querySelector(`[data-value="${this.hoveredValue}"]`);
|
516
|
+
if(currentHoveredElem){
|
517
|
+
if(dir>0){
|
518
|
+
newHoveredElem=currentHoveredElem.nextElementSibling
|
519
|
+
}else{
|
520
|
+
newHoveredElem=currentHoveredElem.previousElementSibling
|
521
|
+
}
|
522
|
+
if(newHoveredElem){
|
523
|
+
this.hoveredValue = newHoveredElem.getAttribute('data-value')
|
524
|
+
const topPos = newHoveredElem.offsetTop
|
525
|
+
this.$refs.dropdown.$el.scrollTop = topPos
|
526
|
+
}
|
527
|
+
}
|
517
528
|
}
|
518
529
|
},
|
519
530
|
computed: {
|
@@ -1,9 +1,8 @@
|
|
1
1
|
<template>
|
2
2
|
<optionContainer
|
3
3
|
:data-value="value"
|
4
|
-
:hoveredBgColor="
|
5
|
-
|
6
|
-
"
|
4
|
+
:hoveredBgColor="colorMode == 'dark' ? '#000000' : 'hoveredBgColor'"
|
5
|
+
:backgroundColor="colorMode == 'dark' ? 'eturnityGrey' : '#fff'"
|
7
6
|
@click="clickHandler"
|
8
7
|
@mouseover="hoverHandler"
|
9
8
|
>
|
@@ -15,7 +14,7 @@
|
|
15
14
|
// import selectButton from './selectButton'
|
16
15
|
// import selectDropdown from './selectDropDown'
|
17
16
|
import styled from 'vue-styled-components'
|
18
|
-
const optionProps = { hoveredBgColor: String }
|
17
|
+
const optionProps = { hoveredBgColor: String, backgroundColor: String }
|
19
18
|
const optionContainer = styled('div', optionProps)`
|
20
19
|
display: flex;
|
21
20
|
cursor: pointer;
|
@@ -25,12 +24,13 @@ const optionContainer = styled('div', optionProps)`
|
|
25
24
|
padding: 12px 10px;
|
26
25
|
gap: 14px;
|
27
26
|
width: 100%;
|
27
|
+
background-color: ${(props) => props.theme.colors[props.backgroundColor]?props.theme.colors[props.backgroundColor]:props.backgroundColor};
|
28
28
|
box-sizing: inherit;
|
29
29
|
&:hover {
|
30
30
|
background-color: ${(props) =>
|
31
31
|
props.theme.colors[props.hoveredBgColor]
|
32
32
|
? props.theme.colors[props.hoveredBgColor]
|
33
|
-
: props.hoveredBgColor};
|
33
|
+
: props.hoveredBgColor} !important;
|
34
34
|
}
|
35
35
|
`
|
36
36
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<template>
|
2
|
-
<page-container>
|
2
|
+
<page-container :isLoading="!tabsData.length">
|
3
3
|
<spinner-container v-if="!tabsData.length">
|
4
4
|
<spinner />
|
5
5
|
</spinner-container>
|
@@ -76,8 +76,10 @@ import styled from 'vue-styled-components'
|
|
76
76
|
import Icon from '../icon'
|
77
77
|
import Spinner from '../spinner'
|
78
78
|
|
79
|
-
const
|
80
|
-
|
79
|
+
const PageAttrs = { isLoading: Boolean }
|
80
|
+
const PageContainer = styled('div', PageAttrs)`
|
81
|
+
background-color: ${(props) =>
|
82
|
+
props.isLoading ? props.theme.colors.white : props.theme.colors.grey6};
|
81
83
|
padding: 14px 12px;
|
82
84
|
min-width: 220px;
|
83
85
|
display: flex;
|
@@ -104,12 +104,7 @@
|
|
104
104
|
:src="require('../../assets/icons/collapse_arrow_icon.svg')"
|
105
105
|
/>
|
106
106
|
</arrow-wrapper>
|
107
|
-
<options-container
|
108
|
-
v-if="isOpen"
|
109
|
-
:top="getItemLocation('top')"
|
110
|
-
:left="getItemLocation('left')"
|
111
|
-
ref="optionsContainer"
|
112
|
-
>
|
107
|
+
<options-container v-if="isOpen" ref="optionsContainer">
|
113
108
|
<options-wrapper @click.prevent.stop>
|
114
109
|
<search-container @click.prevent.stop>
|
115
110
|
<search-input
|
@@ -288,8 +283,7 @@ const OptionsContainer = styled('div', optionsAttrs)`
|
|
288
283
|
position: absolute;
|
289
284
|
display: grid;
|
290
285
|
grid-template-rows: 1fr auto;
|
291
|
-
|
292
|
-
left: ${(props) => props.left + 'px'};
|
286
|
+
left: 20px;
|
293
287
|
width: auto;
|
294
288
|
max-height: 360px;
|
295
289
|
min-height: 200px;
|
@@ -510,8 +504,13 @@ export default {
|
|
510
504
|
}
|
511
505
|
},
|
512
506
|
methods: {
|
513
|
-
toggleOpen() {
|
514
|
-
if (
|
507
|
+
toggleOpen(event) {
|
508
|
+
if (
|
509
|
+
this.disabled ||
|
510
|
+
(event &&
|
511
|
+
!(event.target === this.$el) &&
|
512
|
+
!this.$el.contains(event.target))
|
513
|
+
) {
|
515
514
|
return
|
516
515
|
}
|
517
516
|
this.wasClicked = false
|
@@ -558,14 +557,6 @@ export default {
|
|
558
557
|
this.inputText = value
|
559
558
|
this.$emit('dropdown-search', value)
|
560
559
|
},
|
561
|
-
getItemLocation(value) {
|
562
|
-
let ref = this.$refs.dropdownItem[0]
|
563
|
-
let location = ref.$el.getBoundingClientRect()[value]
|
564
|
-
if (value === 'top') {
|
565
|
-
location = location + window.scrollY + 40
|
566
|
-
}
|
567
|
-
return location
|
568
|
-
},
|
569
560
|
clickOutside(event) {
|
570
561
|
if (event.target === this.$el || this.$el.contains(event.target)) {
|
571
562
|
return
|
@@ -1,9 +1,15 @@
|
|
1
1
|
<template>
|
2
|
-
<page-container
|
2
|
+
<page-container
|
3
|
+
:tableHeight="tableHeight"
|
4
|
+
:shouldSetCustomHeight="doesTableContainDraggables"
|
5
|
+
>
|
3
6
|
<table-title v-if="titleText">
|
4
7
|
{{ titleText }}
|
5
8
|
</table-title>
|
6
|
-
<table-scroll
|
9
|
+
<table-scroll
|
10
|
+
ref="tableRef"
|
11
|
+
:isPositionAbsolute="doesTableContainDraggables"
|
12
|
+
>
|
7
13
|
<table-wrapper :fullWidth="fullWidth">
|
8
14
|
<spinner-wrapper v-if="isLoading">
|
9
15
|
<spinner />
|
@@ -26,7 +32,15 @@
|
|
26
32
|
import styled from 'vue-styled-components'
|
27
33
|
import Spinner from '../../spinner'
|
28
34
|
|
29
|
-
const
|
35
|
+
const pageContainerProps = {
|
36
|
+
tableHeight: String,
|
37
|
+
shouldSetCustomHeight: Boolean
|
38
|
+
}
|
39
|
+
const PageContainer = styled('div', pageContainerProps)`
|
40
|
+
position: relative;
|
41
|
+
height: ${(props) =>
|
42
|
+
props.shouldSetCustomHeight ? props.tableHeight : 'auto'};
|
43
|
+
`
|
30
44
|
|
31
45
|
const TableTitle = styled.div`
|
32
46
|
margin-bottom: 16px;
|
@@ -35,15 +49,27 @@ const TableTitle = styled.div`
|
|
35
49
|
text-transform: uppercase;
|
36
50
|
`
|
37
51
|
|
38
|
-
const
|
52
|
+
const tableScrollProps = {
|
53
|
+
isPositionAbsolute: Boolean
|
54
|
+
}
|
55
|
+
|
56
|
+
const TableScroll = styled('div', tableScrollProps)`
|
39
57
|
max-width: 100%;
|
58
|
+
height: auto;
|
59
|
+
${(props) =>
|
60
|
+
props.isPositionAbsolute &&
|
61
|
+
`
|
62
|
+
position: absolute;
|
63
|
+
left: -20px;
|
64
|
+
`}
|
40
65
|
`
|
41
66
|
|
42
67
|
const wrapperAttrs = { fullWidth: Boolean }
|
43
68
|
const TableWrapper = styled('div', wrapperAttrs)`
|
44
69
|
width: ${(props) => (props.fullWidth ? '100%' : 'fit-content')};
|
45
70
|
max-width: 100%;
|
46
|
-
overflow: auto;
|
71
|
+
overflow-x: auto;
|
72
|
+
overflow-y: hidden;
|
47
73
|
|
48
74
|
::-webkit-scrollbar {
|
49
75
|
height: 5px; //height of the whole scrollbar area
|
@@ -67,7 +93,11 @@ const SpinnerWrapper = styled.div`
|
|
67
93
|
justify-items: center;
|
68
94
|
`
|
69
95
|
|
70
|
-
const containerAttrs = {
|
96
|
+
const containerAttrs = {
|
97
|
+
cellPaddings: String,
|
98
|
+
tableCursor: String
|
99
|
+
}
|
100
|
+
|
71
101
|
const TableContainer = styled('table', containerAttrs)`
|
72
102
|
width: 100%;
|
73
103
|
border-collapse: collapse;
|
@@ -378,6 +408,39 @@ export default {
|
|
378
408
|
tableCursor: {
|
379
409
|
required: false
|
380
410
|
}
|
411
|
+
},
|
412
|
+
data() {
|
413
|
+
return {
|
414
|
+
tableHeight: 'auto',
|
415
|
+
doesTableContainDraggables: false
|
416
|
+
}
|
417
|
+
},
|
418
|
+
mounted() {
|
419
|
+
this.observeTableHeight()
|
420
|
+
},
|
421
|
+
beforeDestroy() {
|
422
|
+
if (this.resizeObserver) {
|
423
|
+
this.resizeObserver.disconnect()
|
424
|
+
}
|
425
|
+
},
|
426
|
+
methods: {
|
427
|
+
observeTableHeight() {
|
428
|
+
if (!this.$refs.tableRef) return
|
429
|
+
|
430
|
+
const tableElement = this.$refs.tableRef.$el
|
431
|
+
|
432
|
+
this.resizeObserver = new ResizeObserver(() => {
|
433
|
+
const newTableHeight = this.titleText
|
434
|
+
? tableElement.offsetHeight + 33
|
435
|
+
: tableElement.offsetHeight
|
436
|
+
this.tableHeight = `${newTableHeight}px`
|
437
|
+
this.doesTableContainDraggables = Boolean(
|
438
|
+
tableElement.querySelector('.drag-container')
|
439
|
+
)
|
440
|
+
})
|
441
|
+
|
442
|
+
this.resizeObserver.observe(tableElement)
|
443
|
+
}
|
381
444
|
}
|
382
445
|
}
|
383
446
|
</script>
|
@@ -1,66 +1,65 @@
|
|
1
1
|
<template>
|
2
|
-
<page-container @click="toggleButton()">
|
2
|
+
<page-container @click="toggleButton()" ref="pageContainer" :activated="isOpen">
|
3
3
|
<button-container ref="dropdownItem">
|
4
4
|
<dot-item />
|
5
5
|
<dot-item />
|
6
6
|
<dot-item />
|
7
7
|
</button-container>
|
8
8
|
<dropdown-container
|
9
|
-
v-if="isOpen"
|
10
9
|
@click.stop
|
11
|
-
:top="getItemLocation('top')"
|
12
|
-
:right="getItemLocation('right')"
|
13
10
|
:containerWidth="childOpen ? 440 : 240"
|
14
11
|
ref="dropdownContainer"
|
15
12
|
>
|
16
|
-
<
|
17
|
-
<
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
13
|
+
<template v-if="isOpen">
|
14
|
+
<loading-container v-if="isLoading">
|
15
|
+
<spinner />
|
16
|
+
</loading-container>
|
17
|
+
<children-container
|
18
|
+
class="child"
|
19
|
+
:isOpen="hoverItem !== null"
|
20
|
+
v-if="hoverItem !== null && !isLoading"
|
21
|
+
>
|
22
|
+
<option-child
|
23
|
+
v-for="child in childOpen"
|
24
|
+
:key="child.value"
|
25
|
+
@click.stop="
|
28
26
|
onSelect({
|
29
27
|
item: child,
|
30
28
|
hasChildren: hasChildren(child)
|
31
29
|
})
|
32
30
|
"
|
33
|
-
|
31
|
+
@keyup.enter.stop="
|
34
32
|
onSelect({
|
35
33
|
item: child,
|
36
34
|
hasChildren: hasChildren(child)
|
37
35
|
})
|
38
36
|
"
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
37
|
+
>
|
38
|
+
{{ child.name }}
|
39
|
+
</option-child>
|
40
|
+
</children-container>
|
41
|
+
<options-container v-if="!isLoading">
|
42
|
+
<option-item
|
43
|
+
v-for="(item, index) in options"
|
44
|
+
:key="item.value"
|
45
|
+
tabindex="0"
|
46
|
+
@click.stop="onSelect({ item: item, hasChildren: hasChildren(item) })"
|
47
|
+
@keyup.enter="
|
50
48
|
onSelect({ item: item, hasChildren: hasChildren(item) })
|
51
49
|
"
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
50
|
+
@mouseover="onItemHover({ index, item })"
|
51
|
+
:isDisabled="item.disabled"
|
52
|
+
>
|
53
|
+
<arrow-left
|
54
|
+
:hasChildren="hasChildren(item)"
|
55
|
+
v-if="hasChildren(item)"
|
56
|
+
/>
|
57
|
+
<span>
|
60
58
|
{{ item.name }}
|
61
59
|
</span>
|
62
|
-
|
63
|
-
|
60
|
+
</option-item>
|
61
|
+
</options-container>
|
62
|
+
</template>
|
64
63
|
</dropdown-container>
|
65
64
|
</page-container>
|
66
65
|
</template>
|
@@ -124,16 +123,20 @@
|
|
124
123
|
import styled from 'vue-styled-components'
|
125
124
|
import Spinner from '../spinner'
|
126
125
|
|
127
|
-
const
|
126
|
+
const PageContainerAttrs = {
|
127
|
+
activated: Boolean
|
128
|
+
}
|
129
|
+
const PageContainer = styled('div', PageContainerAttrs)`
|
128
130
|
display: grid;
|
129
131
|
align-items: center;
|
130
132
|
justify-items: center;
|
131
133
|
width: 30px;
|
132
134
|
height: 30px;
|
135
|
+
border-radius: 4px;
|
136
|
+
background-color: ${(props) => props.activated ? props.theme.colors.grey5 : ''};
|
133
137
|
|
134
138
|
&:hover {
|
135
139
|
background-color: ${(props) => props.theme.colors.grey5};
|
136
|
-
border-radius: 4px;
|
137
140
|
}
|
138
141
|
`
|
139
142
|
|
@@ -158,12 +161,11 @@ const DotItem = styled.div`
|
|
158
161
|
border-radius: 50%;
|
159
162
|
`
|
160
163
|
|
161
|
-
const dropdownAttrs = {
|
164
|
+
const dropdownAttrs = {
|
165
|
+
containerWidth: Number
|
166
|
+
}
|
162
167
|
const DropdownContainer = styled('div', dropdownAttrs)`
|
163
168
|
z-index: 99;
|
164
|
-
height: 200px;
|
165
|
-
top: ${(props) => props.top + 'px'};
|
166
|
-
left: ${(props) => props.right - props.containerWidth + 'px'};
|
167
169
|
position: absolute;
|
168
170
|
display: grid;
|
169
171
|
grid-template-columns: auto auto;
|
@@ -173,8 +175,8 @@ const LoadingContainer = styled.div`
|
|
173
175
|
border: 1px solid ${(props) => props.theme.colors.grey3};
|
174
176
|
display: grid;
|
175
177
|
grid-template-columns: 1fr;
|
176
|
-
min-width:
|
177
|
-
height:
|
178
|
+
min-width: 100px;
|
179
|
+
height: 100px;
|
178
180
|
align-items: center;
|
179
181
|
justify-items: center;
|
180
182
|
background: #fff;
|
@@ -255,6 +257,9 @@ const ChildrenContainer = styled('div', childAttrs)`
|
|
255
257
|
height: max-content;
|
256
258
|
max-height: 200px;
|
257
259
|
overflow: auto;
|
260
|
+
position: absolute;
|
261
|
+
top: 0;
|
262
|
+
right: 100%;
|
258
263
|
`
|
259
264
|
|
260
265
|
export default {
|
@@ -294,18 +299,64 @@ export default {
|
|
294
299
|
this.isOpen = !this.isOpen
|
295
300
|
|
296
301
|
if (this.isOpen) {
|
302
|
+
this.setContextMenuPosition()
|
303
|
+
window.addEventListener('resize', this.toggleButton)
|
297
304
|
document.addEventListener('click', this.clickOutside)
|
298
305
|
} else {
|
306
|
+
window.removeEventListener('resize', this.toggleButton)
|
299
307
|
document.removeEventListener('click', this.clickOutside)
|
300
308
|
}
|
301
309
|
},
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
310
|
+
setContextMenuPosition() {
|
311
|
+
const contextMenu = this.$refs.dropdownContainer.$el
|
312
|
+
const button = this.$refs.pageContainer.$el
|
313
|
+
const rectButton = button.getBoundingClientRect()
|
314
|
+
const relativeParent = this.findRelativeParent(contextMenu)
|
315
|
+
const rectRelativeParent = relativeParent.getBoundingClientRect()
|
316
|
+
|
317
|
+
const positionArray = this.determineElementQuarter(button, rectButton)
|
318
|
+
contextMenu.style.transform = ''
|
319
|
+
if (positionArray.includes('left')) {
|
320
|
+
contextMenu.style.left = (rectButton.right - rectRelativeParent.left + 5) + 'px'
|
321
|
+
} else {
|
322
|
+
contextMenu.style.left = (rectButton.left - rectRelativeParent.left - 5) + 'px'
|
323
|
+
contextMenu.style.transform = 'translateX(-100%)'
|
324
|
+
}
|
325
|
+
if (positionArray.includes('top')) {
|
326
|
+
contextMenu.style.top = (rectButton.top - rectRelativeParent.top) + 'px'
|
327
|
+
} else {
|
328
|
+
contextMenu.style.top = (rectButton.bottom - rectRelativeParent.top) + 'px'
|
329
|
+
contextMenu.style.transform += ' translateY(-100%)'
|
330
|
+
}
|
331
|
+
},
|
332
|
+
findRelativeParent(element) {
|
333
|
+
while (element.parentElement) {
|
334
|
+
if (window.getComputedStyle(element.parentElement).position === 'relative') {
|
335
|
+
return element.parentElement
|
336
|
+
}
|
337
|
+
element = element.parentElement
|
338
|
+
}
|
339
|
+
return null
|
340
|
+
},
|
341
|
+
determineElementQuarter(element, rect) {
|
342
|
+
const viewportWidth = window.innerWidth
|
343
|
+
const viewportHeight = window.innerHeight
|
344
|
+
|
345
|
+
const horizontalMidpoint = viewportWidth / 2
|
346
|
+
const verticalMidpoint = viewportHeight / 2
|
347
|
+
|
348
|
+
const isLeft = rect.left + rect.width / 2 < horizontalMidpoint
|
349
|
+
const isTop = rect.top + rect.height / 2 < verticalMidpoint
|
350
|
+
|
351
|
+
if (isLeft && isTop) {
|
352
|
+
return ['left', 'top']
|
353
|
+
} else if (isLeft && !isTop) {
|
354
|
+
return ['left', 'bottom']
|
355
|
+
} else if (!isLeft && isTop) {
|
356
|
+
return ['right', 'top']
|
357
|
+
} else {
|
358
|
+
return ['right', 'bottom']
|
307
359
|
}
|
308
|
-
return location
|
309
360
|
},
|
310
361
|
hasChildren(item) {
|
311
362
|
return !!item.children && !!item.children.length
|
@@ -1,12 +1,11 @@
|
|
1
|
+
import { langForLocaleString } from './translateLang'
|
2
|
+
|
1
3
|
export const stringToNumber = ({
|
2
|
-
value,
|
4
|
+
value = '',
|
3
5
|
numberPrecision = false,
|
4
|
-
allowNegative
|
6
|
+
allowNegative = false
|
5
7
|
}) => {
|
6
8
|
// This is for saving. It converts our input string to a readable number
|
7
|
-
if (value === undefined) {
|
8
|
-
value = ''
|
9
|
-
}
|
10
9
|
let newVal = value.toString()
|
11
10
|
const selectedLang = localStorage.getItem('lang')
|
12
11
|
// The first replace will replace not allowed characters with a blank
|
@@ -92,18 +91,19 @@ export const stringToNumber = ({
|
|
92
91
|
return parseFloat(newVal)
|
93
92
|
}
|
94
93
|
|
95
|
-
export const numberToString = ({ value, numberPrecision }) => {
|
96
|
-
let selectedLang = localStorage.getItem('lang')
|
97
|
-
? localStorage.getItem('lang') === 'fr-lu'
|
98
|
-
? 'fr-fr'
|
99
|
-
: localStorage.getItem('lang')
|
100
|
-
: 'en-US'
|
101
|
-
if (selectedLang == 'null') {
|
102
|
-
selectedLang = 'en-US'
|
103
|
-
}
|
94
|
+
export const numberToString = ({ value, numberPrecision = 0 }) => {
|
104
95
|
value = parseFloat(value)
|
105
|
-
|
106
|
-
|
107
|
-
|
96
|
+
let minNumberPrecision
|
97
|
+
let maxNumberPrecision
|
98
|
+
if (typeof numberPrecision === 'number') {
|
99
|
+
minNumberPrecision = numberPrecision
|
100
|
+
maxNumberPrecision = numberPrecision
|
101
|
+
} else {
|
102
|
+
minNumberPrecision = numberPrecision[0]
|
103
|
+
maxNumberPrecision = numberPrecision[1]
|
104
|
+
}
|
105
|
+
return value.toLocaleString(langForLocaleString(), {
|
106
|
+
minimumFractionDigits: minNumberPrecision,
|
107
|
+
maximumFractionDigits: maxNumberPrecision
|
108
108
|
})
|
109
109
|
}
|
@@ -78,6 +78,7 @@ export const datePickerLang = (lang) => {
|
|
78
78
|
}
|
79
79
|
|
80
80
|
export const tinyLanguage = (lang) => {
|
81
|
+
// the function is used to pass correct language to Tiny MCE text editor https://www.tiny.cloud/docs/tinymce/6/ui-localization/#language
|
81
82
|
if (
|
82
83
|
lang === 'de' ||
|
83
84
|
lang === 'de-de' ||
|
@@ -106,3 +107,14 @@ export const tinyLanguage = (lang) => {
|
|
106
107
|
return langCode
|
107
108
|
}
|
108
109
|
}
|
110
|
+
|
111
|
+
export const langForLocaleString = () => {
|
112
|
+
const selectedLang = localStorage.getItem('lang')
|
113
|
+
? localStorage.getItem('lang') === 'fr-lu'
|
114
|
+
? 'fr-fr'
|
115
|
+
: localStorage.getItem('lang') === 'fr-ch'
|
116
|
+
? 'de-ch'
|
117
|
+
: localStorage.getItem('lang')
|
118
|
+
: 'en-US'
|
119
|
+
return selectedLang !== 'null' ? selectedLang : 'en-US'
|
120
|
+
}
|