@eturnity/eturnity_reusable_components 7.39.0 → 7.39.1-EPDM-11736.0
Sign up to get free protection for your applications and to get access to all the features.
package/package.json
CHANGED
@@ -157,7 +157,7 @@
|
|
157
157
|
isOpen: {
|
158
158
|
immediate: true,
|
159
159
|
handler(isOpen) {
|
160
|
-
document.body.style.overflow = isOpen ? 'hidden' :
|
160
|
+
document.body.style.overflow = isOpen ? 'hidden' : null
|
161
161
|
if (isOpen) {
|
162
162
|
window.addEventListener('keydown', this.handleKeyDown)
|
163
163
|
} else {
|
@@ -166,11 +166,13 @@
|
|
166
166
|
},
|
167
167
|
},
|
168
168
|
},
|
169
|
-
|
169
|
+
beforeUnmount() {
|
170
|
+
document.body.style.overflow = null
|
170
171
|
window.removeEventListener('keydown', this.handleKeyDown)
|
171
172
|
},
|
172
173
|
methods: {
|
173
174
|
onCloseModal() {
|
175
|
+
document.body.style.overflow = null
|
174
176
|
this.$emit('on-close')
|
175
177
|
},
|
176
178
|
handleKeyDown({ key }) {
|
@@ -1,50 +1,9 @@
|
|
1
1
|
<template>
|
2
2
|
<PageWrapper>
|
3
|
-
<
|
4
|
-
<BoxContainer>
|
5
|
-
<SelectedContainer>
|
6
|
-
{{ numberSelected }} {{ $gettext('selected') }}
|
7
|
-
</SelectedContainer>
|
8
|
-
<ListContainer v-if="optionsList.length">
|
9
|
-
<ListItem
|
10
|
-
v-for="item in limitedOptions"
|
11
|
-
:key="item.type"
|
12
|
-
:disabled="item.disabled || false"
|
13
|
-
:hover-color="item.hoverColor"
|
14
|
-
@click="$emit('on-' + item.type)"
|
15
|
-
>
|
16
|
-
{{ item.name }}
|
17
|
-
</ListItem>
|
18
|
-
<IconContainer @click="expandOptions">
|
19
|
-
<ButtonContainer
|
20
|
-
v-if="optionsList.length > optionLimit || hasComponent"
|
21
|
-
name="more_options,_tool_tips"
|
22
|
-
>
|
23
|
-
<DotItem />
|
24
|
-
<DotItem />
|
25
|
-
<DotItem />
|
26
|
-
</ButtonContainer>
|
27
|
-
</IconContainer>
|
28
|
-
</ListContainer>
|
29
|
-
<EmptyText v-if="!optionsList.length">
|
30
|
-
{{ $gettext('no_batch_actions_available') }}
|
31
|
-
</EmptyText>
|
32
|
-
<CloseContainer>
|
33
|
-
<IconContainer @click="$emit('on-close')">
|
34
|
-
<Icon
|
35
|
-
color="white"
|
36
|
-
cursor="pointer"
|
37
|
-
name="close_for_modals,_tool_tips"
|
38
|
-
size="14px"
|
39
|
-
/>
|
40
|
-
</IconContainer>
|
41
|
-
</CloseContainer>
|
42
|
-
</BoxContainer>
|
43
|
-
</PageContainer>
|
44
|
-
<CenterPageContainer v-else>
|
3
|
+
<CenterPageContainer v-if="expanded">
|
45
4
|
<CenterBox>
|
46
5
|
<TitleContainer>
|
47
|
-
<BoxTitle> {{ numberSelected }} {{
|
6
|
+
<BoxTitle> {{ numberSelected }} {{ selectedLabel }} </BoxTitle>
|
48
7
|
<IconContainer @click="$emit('on-close')">
|
49
8
|
<Icon
|
50
9
|
color="white"
|
@@ -62,7 +21,7 @@
|
|
62
21
|
v-for="item in expandedOptions"
|
63
22
|
:key="item.type"
|
64
23
|
:disabled="item.disabled || false"
|
65
|
-
:
|
24
|
+
:has-component="!!item?.component"
|
66
25
|
:hover-color="item.hoverColor"
|
67
26
|
@click="
|
68
27
|
!item?.component && !item.disabled && $emit('on-' + item.type)
|
@@ -70,7 +29,8 @@
|
|
70
29
|
>
|
71
30
|
<ListItemWrapper
|
72
31
|
v-if="item?.component"
|
73
|
-
:
|
32
|
+
:has-component="!!item?.component"
|
33
|
+
test-data-id="expanded_list_item"
|
74
34
|
@click="!item.disabled && toggleElement(item.type)"
|
75
35
|
>
|
76
36
|
<ListItemTitle>
|
@@ -99,6 +59,48 @@
|
|
99
59
|
</ExpandedList>
|
100
60
|
</CenterBox>
|
101
61
|
</CenterPageContainer>
|
62
|
+
<PageContainer v-else>
|
63
|
+
<BoxContainer>
|
64
|
+
<SelectedContainer>
|
65
|
+
{{ numberSelected }} {{ selectedText }}
|
66
|
+
</SelectedContainer>
|
67
|
+
<ListContainer v-if="optionsList.length">
|
68
|
+
<ListItem
|
69
|
+
v-for="item in limitedOptions"
|
70
|
+
:key="item.type"
|
71
|
+
:disabled="item.disabled || false"
|
72
|
+
:hover-color="item.hoverColor"
|
73
|
+
@click="$emit('on-' + item.type)"
|
74
|
+
>
|
75
|
+
{{ item.name }}
|
76
|
+
</ListItem>
|
77
|
+
<IconContainer
|
78
|
+
v-if="optionsList.length > optionLimit || hasComponent"
|
79
|
+
test-data-id="more_actions_button_wrapper"
|
80
|
+
@click="expandOptions"
|
81
|
+
>
|
82
|
+
<ButtonContainer name="more_options,_tool_tips">
|
83
|
+
<DotItem />
|
84
|
+
<DotItem />
|
85
|
+
<DotItem />
|
86
|
+
</ButtonContainer>
|
87
|
+
</IconContainer>
|
88
|
+
</ListContainer>
|
89
|
+
<EmptyText v-else test-data-id="no_bulk_actions">
|
90
|
+
{{ noBulkActionsText }}
|
91
|
+
</EmptyText>
|
92
|
+
<CloseContainer>
|
93
|
+
<IconContainer @click="$emit('on-close')">
|
94
|
+
<Icon
|
95
|
+
color="white"
|
96
|
+
cursor="pointer"
|
97
|
+
name="close_for_modals,_tool_tips"
|
98
|
+
size="14px"
|
99
|
+
/>
|
100
|
+
</IconContainer>
|
101
|
+
</CloseContainer>
|
102
|
+
</BoxContainer>
|
103
|
+
</PageContainer>
|
102
104
|
</PageWrapper>
|
103
105
|
</template>
|
104
106
|
|
@@ -173,8 +175,8 @@
|
|
173
175
|
`
|
174
176
|
|
175
177
|
const OptionsContainer = styled.div`
|
176
|
-
position:
|
177
|
-
|
178
|
+
position: absolute;
|
179
|
+
left: 101%;
|
178
180
|
background-color: ${(props) => props.theme.colors.black};
|
179
181
|
border-radius: 4px;
|
180
182
|
padding: 15px;
|
@@ -378,12 +380,21 @@
|
|
378
380
|
optionsList: {
|
379
381
|
type: Array,
|
380
382
|
required: true,
|
383
|
+
default: () => [],
|
381
384
|
},
|
382
385
|
numberSelected: {
|
383
386
|
type: Number,
|
384
387
|
required: true,
|
385
388
|
default: 0,
|
386
389
|
},
|
390
|
+
selectedLabel: {
|
391
|
+
type: String,
|
392
|
+
default: null,
|
393
|
+
},
|
394
|
+
noBulkActionsLabel: {
|
395
|
+
type: String,
|
396
|
+
default: null,
|
397
|
+
},
|
387
398
|
},
|
388
399
|
data() {
|
389
400
|
return {
|
@@ -401,6 +412,16 @@
|
|
401
412
|
limitedOptions() {
|
402
413
|
return this.expandedOptions.filter((option) => !option.component)
|
403
414
|
},
|
415
|
+
selectedText() {
|
416
|
+
//work around for storybook not finding the $gettext function
|
417
|
+
return this.selectedLabel || this.$gettext('selected')
|
418
|
+
},
|
419
|
+
noBulkActionsText() {
|
420
|
+
//work around for storybook not finding the $gettext function
|
421
|
+
return (
|
422
|
+
this.noBulkActionsLabel || this.$gettext('no_batch_actions_available')
|
423
|
+
)
|
424
|
+
},
|
404
425
|
},
|
405
426
|
watch: {
|
406
427
|
optionsList() {
|
@@ -415,7 +436,7 @@
|
|
415
436
|
this.expandedOptions = [...this.optionsList]
|
416
437
|
.map((option, index) => {
|
417
438
|
const currentOption = this.expandedOptions[index]
|
418
|
-
const isOpen =
|
439
|
+
const isOpen = currentOption ? currentOption.open : false
|
419
440
|
|
420
441
|
return { ...option, open: isOpen }
|
421
442
|
})
|
@@ -0,0 +1,176 @@
|
|
1
|
+
/* eslint-disable */
|
2
|
+
import { mount } from '@vue/test-utils'
|
3
|
+
import RCSelectedOptions from '@/components/selectedOptions'
|
4
|
+
import theme from '@/assets/theme'
|
5
|
+
|
6
|
+
jest.mock('@/components/icon/iconCache.mjs', () => ({
|
7
|
+
// need to mock this due to how jest handles import.meta
|
8
|
+
fetchIcon: jest.fn(() => Promise.resolve('close_for_modals,_tool_tips.svg')),
|
9
|
+
}))
|
10
|
+
|
11
|
+
describe('RCSelectedOptions.vue', () => {
|
12
|
+
const simpleOptionsProps = {
|
13
|
+
optionLimit: 4,
|
14
|
+
numberSelected: 2,
|
15
|
+
selectedLabel: 'selected',
|
16
|
+
noBulkActionsLabel: 'No bulk actions available',
|
17
|
+
optionsList: [
|
18
|
+
{
|
19
|
+
type: 'close',
|
20
|
+
name: 'Close',
|
21
|
+
},
|
22
|
+
{
|
23
|
+
type: 'delete',
|
24
|
+
name: 'Delete',
|
25
|
+
hoverColor: 'red',
|
26
|
+
},
|
27
|
+
],
|
28
|
+
}
|
29
|
+
|
30
|
+
it('selected options are rendered with correct options', () => {
|
31
|
+
const wrapper = mount(RCSelectedOptions, {
|
32
|
+
props: simpleOptionsProps,
|
33
|
+
global: {
|
34
|
+
provide: {
|
35
|
+
theme,
|
36
|
+
},
|
37
|
+
},
|
38
|
+
})
|
39
|
+
|
40
|
+
const selectedOptions = wrapper.findComponent(RCSelectedOptions)
|
41
|
+
expect(selectedOptions.exists()).toBe(true)
|
42
|
+
})
|
43
|
+
|
44
|
+
it('should display "No bulk actions available" if there are no options', () => {
|
45
|
+
const wrapper = mount(RCSelectedOptions, {
|
46
|
+
props: {
|
47
|
+
...simpleOptionsProps,
|
48
|
+
optionsList: [],
|
49
|
+
},
|
50
|
+
global: {
|
51
|
+
provide: {
|
52
|
+
theme,
|
53
|
+
},
|
54
|
+
},
|
55
|
+
})
|
56
|
+
|
57
|
+
const selectedOptions = wrapper.findComponent(RCSelectedOptions)
|
58
|
+
expect(selectedOptions.exists()).toBe(true)
|
59
|
+
|
60
|
+
const noBulkActions = selectedOptions.find(
|
61
|
+
'[test-data-id="no_bulk_actions"]'
|
62
|
+
)
|
63
|
+
expect(noBulkActions.exists()).toBe(true)
|
64
|
+
})
|
65
|
+
|
66
|
+
it('should not display "•••" option if it is less than the limit of 4', () => {
|
67
|
+
const wrapper = mount(RCSelectedOptions, {
|
68
|
+
props: simpleOptionsProps,
|
69
|
+
global: {
|
70
|
+
provide: {
|
71
|
+
theme,
|
72
|
+
},
|
73
|
+
},
|
74
|
+
})
|
75
|
+
|
76
|
+
const selectedOptions = wrapper.findComponent(RCSelectedOptions)
|
77
|
+
expect(selectedOptions.exists()).toBe(true)
|
78
|
+
|
79
|
+
//since we have 2 options, and the limit is 4, we should not see "•••" button
|
80
|
+
const moreActionsButton = selectedOptions.find(
|
81
|
+
'[test-data-id="more_actions_button_wrapper"]'
|
82
|
+
)
|
83
|
+
expect(moreActionsButton.exists()).toBe(false)
|
84
|
+
})
|
85
|
+
|
86
|
+
it('should display "•••" option if it is more than the limit of 4 or if there is a component parameter on the options', () => {
|
87
|
+
const wrapper = mount(RCSelectedOptions, {
|
88
|
+
props: {
|
89
|
+
...simpleOptionsProps,
|
90
|
+
optionsList: [
|
91
|
+
{
|
92
|
+
type: 'close',
|
93
|
+
name: 'Close',
|
94
|
+
},
|
95
|
+
{
|
96
|
+
type: 'delete',
|
97
|
+
name: 'Delete',
|
98
|
+
component: 'set_supplier',
|
99
|
+
},
|
100
|
+
],
|
101
|
+
},
|
102
|
+
global: {
|
103
|
+
provide: {
|
104
|
+
theme,
|
105
|
+
},
|
106
|
+
},
|
107
|
+
})
|
108
|
+
|
109
|
+
const selectedOptions = wrapper.findComponent(RCSelectedOptions)
|
110
|
+
expect(selectedOptions.exists()).toBe(true)
|
111
|
+
|
112
|
+
//since we a component parameter, we should see "•••" button
|
113
|
+
const moreActionsButton = selectedOptions.find(
|
114
|
+
'[test-data-id="more_actions_button_wrapper"]'
|
115
|
+
)
|
116
|
+
expect(moreActionsButton.exists()).toBe(true)
|
117
|
+
})
|
118
|
+
it("should display the named slot content when the 'component' parameter is passed", async () => {
|
119
|
+
const wrapper = mount(RCSelectedOptions, {
|
120
|
+
props: {
|
121
|
+
...simpleOptionsProps,
|
122
|
+
optionsList: [
|
123
|
+
{
|
124
|
+
type: 'close',
|
125
|
+
name: 'Close',
|
126
|
+
},
|
127
|
+
{
|
128
|
+
type: 'delete',
|
129
|
+
name: 'Delete',
|
130
|
+
component: 'set_supplier',
|
131
|
+
},
|
132
|
+
],
|
133
|
+
},
|
134
|
+
global: {
|
135
|
+
provide: {
|
136
|
+
theme,
|
137
|
+
},
|
138
|
+
},
|
139
|
+
slots: {
|
140
|
+
set_supplier: '<div data-id="set_supplier">set_supplier</div>',
|
141
|
+
},
|
142
|
+
})
|
143
|
+
|
144
|
+
const selectedOptions = wrapper.findComponent(RCSelectedOptions)
|
145
|
+
expect(selectedOptions.exists()).toBe(true)
|
146
|
+
|
147
|
+
//since we a component parameter, we should see "•••" button
|
148
|
+
const moreActionsButton = selectedOptions.find(
|
149
|
+
'[test-data-id="more_actions_button_wrapper"]'
|
150
|
+
)
|
151
|
+
expect(moreActionsButton.exists()).toBe(true)
|
152
|
+
|
153
|
+
//click the more actions button
|
154
|
+
moreActionsButton.trigger('click')
|
155
|
+
selectedOptions.vm.expanded = true
|
156
|
+
selectedOptions.vm.expandedOptions = selectedOptions.props().optionsList
|
157
|
+
expect(selectedOptions.vm.expanded).toBe(true)
|
158
|
+
|
159
|
+
await wrapper.vm.$nextTick()
|
160
|
+
|
161
|
+
//toggle the element with the component parameter
|
162
|
+
const expandedListItems = selectedOptions.findAll(
|
163
|
+
'[test-data-id="expanded_list_item"]'
|
164
|
+
)
|
165
|
+
|
166
|
+
//there should be only one since we have only one option with the component parameter
|
167
|
+
expect(expandedListItems.length).toBe(1)
|
168
|
+
expandedListItems[0].trigger('click')
|
169
|
+
|
170
|
+
await wrapper.vm.$nextTick()
|
171
|
+
|
172
|
+
//check if the named slot content is displayed
|
173
|
+
const setSupplierSlot = wrapper.find('[data-id="set_supplier"]')
|
174
|
+
expect(setSupplierSlot.exists()).toBe(true)
|
175
|
+
})
|
176
|
+
})
|
@@ -0,0 +1,155 @@
|
|
1
|
+
import SelectedOptions from './index.vue'
|
2
|
+
|
3
|
+
export default {
|
4
|
+
title: 'Components/SelectedOptions',
|
5
|
+
component: SelectedOptions,
|
6
|
+
tags: ['autodocs'],
|
7
|
+
// argTypes: {}
|
8
|
+
}
|
9
|
+
|
10
|
+
// How to use in your template
|
11
|
+
// import SelectedOptions from "@eturnity/eturnity_reusable_components/src/components/selectedOptions"
|
12
|
+
//
|
13
|
+
// optionsList = [
|
14
|
+
// {
|
15
|
+
// type: 'close',
|
16
|
+
// name: 'Close'
|
17
|
+
// },
|
18
|
+
// {
|
19
|
+
// type: 'export',
|
20
|
+
// name: 'Export'
|
21
|
+
// ...
|
22
|
+
// add component parameter if we were passing a component to the selected options (see below)
|
23
|
+
// component: 'set_supplier'
|
24
|
+
// },
|
25
|
+
// {
|
26
|
+
// type: 'delete',
|
27
|
+
// name: 'Delete',
|
28
|
+
// hoverColor: 'red' // default is green
|
29
|
+
// }
|
30
|
+
// ]
|
31
|
+
//
|
32
|
+
// @on-${type}="function" should $emit the callback for the 'type' in the optionsList
|
33
|
+
//
|
34
|
+
// <selected-options
|
35
|
+
// :numberSelected="numberSelected"
|
36
|
+
// :optionsList="optionsList"
|
37
|
+
// @on-close="onCloseFunction()"
|
38
|
+
// @on-export="function()" @on-delete="function()"
|
39
|
+
// >
|
40
|
+
// add any custom components here that you want to pass to the expanded options
|
41
|
+
// <template v-slot:set_supplier>
|
42
|
+
// <CustomSelectComponent
|
43
|
+
// :option-list="suppliers"
|
44
|
+
// @set-supplier="checkboxBulkActions('setSupplier', $event)"
|
45
|
+
// />
|
46
|
+
// </template>
|
47
|
+
// </SelectedOptions>
|
48
|
+
|
49
|
+
export const Default = {
|
50
|
+
render: (args) => ({
|
51
|
+
components: { SelectedOptions },
|
52
|
+
setup() {
|
53
|
+
return { args }
|
54
|
+
},
|
55
|
+
template: '<SelectedOptions v-bind="args" />',
|
56
|
+
}),
|
57
|
+
args: {
|
58
|
+
optionLimit: 4,
|
59
|
+
selectedLabel: 'selected',
|
60
|
+
noBulkActionsLabel: 'No bulk actions available',
|
61
|
+
|
62
|
+
//selected options count, in this case 5 options are selected
|
63
|
+
numberSelected: 5,
|
64
|
+
|
65
|
+
//show overlay
|
66
|
+
showOverlay: true,
|
67
|
+
|
68
|
+
//expanded options, this will display list of actions in the middle of the screen
|
69
|
+
expanded: false,
|
70
|
+
optionsList: [
|
71
|
+
{
|
72
|
+
type: 'export',
|
73
|
+
name: 'Export',
|
74
|
+
},
|
75
|
+
{
|
76
|
+
type: 'export_page',
|
77
|
+
name: 'Export Page',
|
78
|
+
},
|
79
|
+
],
|
80
|
+
expandedOptions: [],
|
81
|
+
},
|
82
|
+
}
|
83
|
+
|
84
|
+
export const Expanded = {
|
85
|
+
render: (args) => ({
|
86
|
+
components: { SelectedOptions },
|
87
|
+
setup() {
|
88
|
+
return { args }
|
89
|
+
},
|
90
|
+
template: `
|
91
|
+
<SelectedOptions v-bind="args">
|
92
|
+
<template v-slot:set_supplier>
|
93
|
+
<div>supplier</div>
|
94
|
+
</template>
|
95
|
+
</SelectedOptions>
|
96
|
+
`,
|
97
|
+
}),
|
98
|
+
args: {
|
99
|
+
...Default.args,
|
100
|
+
//expanded options, this will display list of actions in the middle of the screen
|
101
|
+
expanded: true,
|
102
|
+
|
103
|
+
//optionsList, to be displayed when expanded is false and this will be filtered based on the optionLimit
|
104
|
+
optionsList: [
|
105
|
+
{
|
106
|
+
type: 'export',
|
107
|
+
name: 'Export',
|
108
|
+
},
|
109
|
+
{
|
110
|
+
type: 'export_page',
|
111
|
+
name: 'Export Page',
|
112
|
+
},
|
113
|
+
{
|
114
|
+
type: 'export_all',
|
115
|
+
name: 'Export All',
|
116
|
+
},
|
117
|
+
{
|
118
|
+
type: 'export_row',
|
119
|
+
name: 'Export Row',
|
120
|
+
},
|
121
|
+
{
|
122
|
+
type: 'set_supplier',
|
123
|
+
name: 'Set Supplier',
|
124
|
+
// add component parameter if we were passing a component to the selected options
|
125
|
+
component: 'set_supplier',
|
126
|
+
},
|
127
|
+
],
|
128
|
+
|
129
|
+
//duplicate of optionsList, to be displayed when expanded is true
|
130
|
+
expandedOptions: [
|
131
|
+
{
|
132
|
+
type: 'export',
|
133
|
+
name: 'Export',
|
134
|
+
},
|
135
|
+
{
|
136
|
+
type: 'export_page',
|
137
|
+
name: 'Export Page',
|
138
|
+
},
|
139
|
+
{
|
140
|
+
type: 'export_all',
|
141
|
+
name: 'Export All',
|
142
|
+
},
|
143
|
+
{
|
144
|
+
type: 'export_row',
|
145
|
+
name: 'Export Row',
|
146
|
+
},
|
147
|
+
{
|
148
|
+
type: 'set_supplier',
|
149
|
+
name: 'Set Supplier',
|
150
|
+
// add component parameter if we were passing a component to the selected options
|
151
|
+
component: 'set_supplier',
|
152
|
+
},
|
153
|
+
],
|
154
|
+
},
|
155
|
+
}
|