@eturnity/eturnity_reusable_components 7.39.1-EPDM-11736.1 → 7.39.2

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eturnity/eturnity_reusable_components",
3
- "version": "7.39.1-EPDM-11736.1",
3
+ "version": "7.39.2",
4
4
  "files": [
5
5
  "dist",
6
6
  "src"
@@ -0,0 +1,45 @@
1
+ import ActionBanner from './index.vue'
2
+ import theme from '@/assets/theme'
3
+ export default {
4
+ title: 'ActionBanner',
5
+ component: ActionBanner,
6
+ tags: ['autodocs'],
7
+ }
8
+
9
+ // <RCActionBanner
10
+ // :isOpen="true"
11
+ // @on-close="handleClose"
12
+ // >
13
+ // <template #title>Sample title</template>
14
+ // <template #body>Sample body</template>
15
+ // <template #buttons>
16
+ // <button>Sample button </button>
17
+ // </template>
18
+ // </RCActionBanner>
19
+
20
+ export const Default = {
21
+ args: {
22
+ isOpen: false,
23
+ },
24
+ }
25
+
26
+ export const OpenedActionBanner = {
27
+ args: {
28
+ isOpen: true,
29
+ },
30
+ render: (args) => ({
31
+ components: { ActionBanner },
32
+ setup() {
33
+ return { args }
34
+ },
35
+ template: `
36
+ <ActionBanner v-bind="args">
37
+ <template #title>Sample title</template>
38
+ <template #body>Sample body</template>
39
+ <template #buttons>
40
+ <button>Sample button </button>
41
+ </template>
42
+ </ActionBanner>
43
+ `,
44
+ }),
45
+ }
@@ -0,0 +1,76 @@
1
+ /* eslint-disable */
2
+ import { h } from 'vue'
3
+ import { mount } from '@vue/test-utils'
4
+ import ActionBanner from '@/components/banner/actionBanner'
5
+ import theme from '@/assets/theme'
6
+
7
+ describe('Action Banner Component', () => {
8
+ it('action banner is shown when isOpen props is true', async () => {
9
+ const wrapper = mount(ActionBanner, {
10
+ props: {
11
+ isOpen: false,
12
+ },
13
+ global: {
14
+ provide: {
15
+ theme,
16
+ },
17
+ },
18
+ })
19
+
20
+ const bannerWrapper = wrapper.find('[data-test-id="action_banner_wrapper"]')
21
+ expect(bannerWrapper.exists()).toBe(true)
22
+ expect(bannerWrapper.classes()).not.toContain('visible')
23
+ expect(bannerWrapper.classes()).toContain('hidden')
24
+ await wrapper.setProps({ isOpen: true })
25
+ expect(bannerWrapper.classes()).toContain('visible')
26
+ expect(bannerWrapper.classes()).not.toContain('hidden')
27
+ })
28
+
29
+ it('action banner slots is display when user passed slots content', async () => {
30
+ const titleText = 'Sample title'
31
+ const bodyText = 'Sample body text'
32
+ const buttonText = 'Sample button'
33
+
34
+ const wrapper = mount(ActionBanner, {
35
+ props: {
36
+ isOpen: false,
37
+ },
38
+ slots: {
39
+ title: titleText,
40
+ body: bodyText,
41
+ buttons: h('button', {}, buttonText),
42
+ },
43
+ global: {
44
+ provide: {
45
+ theme,
46
+ },
47
+ },
48
+ })
49
+
50
+ const modalTitleEl = wrapper.find('[data-test-id="modal_title"]')
51
+ expect(modalTitleEl.text()).toBe(titleText)
52
+ const modalBodyEl = wrapper.find('[data-test-id="modal_body"]')
53
+ expect(modalBodyEl.text()).toBe(bodyText)
54
+ const modalButtonsEl = wrapper.find('[data-test-id="modal_buttons"]')
55
+ expect(modalButtonsEl.text()).toBe(buttonText)
56
+ })
57
+
58
+ it('action banner on-close event is emitted when modal close button is clicked', async () => {
59
+ const wrapper = mount(ActionBanner, {
60
+ props: {
61
+ isOpen: true,
62
+ },
63
+ global: {
64
+ provide: {
65
+ theme,
66
+ },
67
+ },
68
+ })
69
+
70
+ const modalCloseButton = wrapper.find('.close')
71
+ await modalCloseButton.trigger('click')
72
+ expect(wrapper.emitted('on-close')).toBeTruthy()
73
+ const emittedEvent = wrapper.emitted('on-close')
74
+ expect(emittedEvent).toHaveLength(1)
75
+ })
76
+ })
@@ -1,21 +1,37 @@
1
1
  <template>
2
- <Modal :is-open="isOpen" @on-close="closeModal">
2
+ <Modal
3
+ :is-open="isOpen"
4
+ data-test-id="action_banner_wrapper"
5
+ @on-close="closeModal"
6
+ >
3
7
  <ModalContainer>
4
- <ModalTitle v-if="$slots.title">
8
+ <ModalTitle v-if="$slots.title" data-test-id="modal_title">
5
9
  <slot name="title"></slot>
6
10
  </ModalTitle>
7
- <TextContainer v-if="$slots.body">
11
+ <TextContainer v-if="$slots.body" data-test-id="modal_body">
8
12
  <slot name="body"></slot>
9
13
  </TextContainer>
10
- <ButtonContainer v-if="$slots.buttons">
14
+ <ButtonContainer v-if="$slots.buttons" data-test-id="modal_buttons">
11
15
  <slot name="buttons"></slot>
12
16
  </ButtonContainer>
13
17
  </ModalContainer>
14
18
  </Modal>
15
19
  </template>
16
20
  <script>
21
+ // import RCBanner from "@eturnity/eturnity_reusable_components/src/components/banner/actionBanner"
22
+ // <RCActionBanner
23
+ // :isOpen="true"
24
+ // @on-close="handleClose"
25
+ // >
26
+ // <template #title>Sample title</template>
27
+ // <template #body>Sample body</template>
28
+ // <template #buttons>
29
+ // <button>Sample button </button>
30
+ // </template>
31
+ // </RCActionBanner>
32
+
17
33
  import styled from 'vue3-styled-components'
18
- import Modal from '../modal'
34
+ import Modal from '@/components/modals/modal'
19
35
  const ModalContainer = styled.div`
20
36
  width: 450px;
21
37
  min-height: 205px;
@@ -23,7 +39,7 @@
23
39
  `
24
40
  const ModalTitle = styled.div`
25
41
  color: ${(props) => props.theme.colors.black};
26
- font-family: ${(props) => props.theme.fonts.mainFont};
42
+ font-family: inherit;
27
43
  font-size: 18px;
28
44
  font-style: normal;
29
45
  font-weight: 700;
@@ -37,7 +53,7 @@
37
53
  `
38
54
  const TextContainer = styled.div`
39
55
  color: ${(props) => props.theme.colors.black};
40
- font-family: ${(props) => props.theme.fonts.mainFont};
56
+ font-family: inherit;
41
57
  font-size: 13px;
42
58
  font-style: normal;
43
59
  font-weight: 400;
@@ -45,6 +61,7 @@
45
61
  padding: 30px 0px;
46
62
  white-space: pre-wrap;
47
63
  `
64
+
48
65
  export default {
49
66
  name: 'ActionModal',
50
67
  components: {
@@ -54,7 +71,12 @@
54
71
  ButtonContainer,
55
72
  TextContainer,
56
73
  },
57
- props: ['isOpen'],
74
+ props: {
75
+ isOpen: {
76
+ type: Boolean,
77
+ default: false,
78
+ },
79
+ },
58
80
  methods: {
59
81
  closeModal() {
60
82
  this.$emit('on-close')
@@ -0,0 +1,64 @@
1
+ import Banner from './index.vue'
2
+ import theme from '@/assets/theme'
3
+
4
+ export default {
5
+ title: 'Banner',
6
+ component: Banner,
7
+ tags: ['autodocs'],
8
+ }
9
+
10
+ // To use:
11
+ // <RCBanner
12
+ // backdrop="white" // white, dark
13
+ // :hideClose="true"
14
+ // :isLoading="true"
15
+ // :isOpen="true"
16
+ // position="fixed"
17
+ // stopPropagation="false"
18
+ // @on-close="handleClose"
19
+ // />
20
+
21
+ export const Default = {
22
+ args: {
23
+ isOpen: false,
24
+ isLoading: false,
25
+ hideClose: false,
26
+ backdrop: 'white',
27
+ position: 'fixed',
28
+ stopPropagation: true,
29
+ },
30
+ }
31
+
32
+ export const OpenedBanner = {
33
+ args: {
34
+ isOpen: true,
35
+ },
36
+ }
37
+
38
+ export const LoadingBanner = {
39
+ args: {
40
+ isOpen: true,
41
+ isLoading: true,
42
+ },
43
+ }
44
+
45
+ export const HiddenCloseButton = {
46
+ args: {
47
+ isOpen: true,
48
+ hideClose: true,
49
+ },
50
+ }
51
+
52
+ export const DarkBackdrop = {
53
+ args: {
54
+ isOpen: true,
55
+ backdrop: 'dark',
56
+ },
57
+ }
58
+
59
+ export const AbsolutePositionBanner = {
60
+ args: {
61
+ isOpen: true,
62
+ position: 'absolute',
63
+ },
64
+ }
@@ -0,0 +1,149 @@
1
+ /* eslint-disable */
2
+ import { mount } from '@vue/test-utils'
3
+ import Banner from '@/components/banner/banner'
4
+ import theme from '@/assets/theme'
5
+
6
+ describe('Banner Component', () => {
7
+ it('banner is shown when isOpen props is true', async () => {
8
+ // Start with isOpen as false
9
+ const wrapper = mount(Banner, {
10
+ props: {
11
+ isOpen: false,
12
+ isLoading: false,
13
+ },
14
+ global: {
15
+ provide: {
16
+ theme,
17
+ },
18
+ },
19
+ })
20
+
21
+ const bannerWrapper = wrapper.find('[data-test-id="banner_wrapper"]')
22
+ // check that the element exists with correct props
23
+ expect(bannerWrapper.exists()).toBe(true)
24
+ // Check if wrapper doesnt have the 'visible' class, and have 'hidden' class
25
+ expect(bannerWrapper.classes()).not.toContain('visible')
26
+ expect(bannerWrapper.classes()).toContain('hidden')
27
+ // Now, set isOpen to true
28
+ await wrapper.setProps({ isOpen: true })
29
+ // Check if the 'visible' class is applied and 'hidden' class is not applied
30
+ expect(bannerWrapper.classes()).toContain('visible')
31
+ expect(bannerWrapper.classes()).not.toContain('hidden')
32
+ })
33
+
34
+ it('banner spinner is shown when user set isLoading props is true', async () => {
35
+ // Start with isLoading is false
36
+ const wrapper = mount(Banner, {
37
+ props: {
38
+ isOpen: true,
39
+ isLoading: false,
40
+ },
41
+ global: {
42
+ provide: {
43
+ theme,
44
+ },
45
+ },
46
+ })
47
+
48
+ const bannerWrapper = wrapper.find('[data-test-id="banner_wrapper"]')
49
+ // Initial check, spinner should not exist
50
+ let spinnerElement = bannerWrapper.find('[data-test-id="banner_spinner"]')
51
+ expect(spinnerElement.exists()).toBe(false)
52
+ // Set isLoading to true
53
+ await wrapper.setProps({ isLoading: true })
54
+ await wrapper.vm.$nextTick()
55
+ // Find the spinner element again after updating the prop and check if it exsit
56
+ spinnerElement = bannerWrapper.find('[data-test-id="banner_spinner"]')
57
+ expect(spinnerElement.exists()).toBe(true)
58
+ })
59
+
60
+ it('banner close button is not shown when hideClose props is true', async () => {
61
+ // Set hideClose to false
62
+ const wrapper = mount(Banner, {
63
+ props: {
64
+ isOpen: true,
65
+ hideClose: false,
66
+ },
67
+ global: {
68
+ provide: {
69
+ theme,
70
+ },
71
+ },
72
+ })
73
+
74
+ const bannerWrapper = wrapper.find('[data-test-id="banner_wrapper"]')
75
+
76
+ // Initial check, closeButton should exist
77
+ let closeButton = bannerWrapper.find('[data-test-id="banner_close_button"]')
78
+ expect(closeButton.exists()).toBe(true)
79
+ // Set isLoading to true
80
+ await wrapper.setProps({ hideClose: true })
81
+ await wrapper.vm.$nextTick()
82
+ // Find the closeButton element again after updating the prop
83
+ closeButton = bannerWrapper.find('[data-test-id="banner_close_button"]')
84
+ // Check if closeButton does not exist now
85
+ expect(closeButton.exists()).toBe(false)
86
+ })
87
+
88
+ it('banner on-close event is emitted when close button is clicked', async () => {
89
+ const wrapper = mount(Banner, {
90
+ props: {
91
+ isOpen: true,
92
+ },
93
+ global: {
94
+ provide: {
95
+ theme,
96
+ },
97
+ },
98
+ })
99
+
100
+ const bannerWrapper = wrapper.find('[data-test-id="banner_wrapper"]')
101
+ // Find the close button element
102
+ const closeButton = bannerWrapper.find(
103
+ '[data-test-id="banner_close_button"]'
104
+ )
105
+ // Simulate a click and check if the component emmitted a on-close event
106
+ await closeButton.trigger('click')
107
+ expect(wrapper.emitted('on-close')).toBeTruthy()
108
+ const emittedEvent = wrapper.emitted('on-close')
109
+ expect(emittedEvent).toHaveLength(1)
110
+ })
111
+
112
+ it('event.stopPropagation is called when stopPropagation prop is true and banner wrapper is clicked', async () => {
113
+ const wrapper = mount(Banner, {
114
+ props: {
115
+ isOpen: true,
116
+ stopPropagation: true,
117
+ },
118
+ global: {
119
+ provide: {
120
+ theme,
121
+ },
122
+ },
123
+ })
124
+
125
+ const bannerWrapper = wrapper.find('[data-test-id="banner_wrapper"]')
126
+ let modalWrapper = bannerWrapper.find('[data-test-id="modal-container"]')
127
+ // Mock for event.stopPropagation
128
+ const stopPropagationMock = jest.fn()
129
+ // Simulate a click event with the mocked stopPropagation function
130
+ await modalWrapper.trigger('click', {
131
+ stopPropagation: stopPropagationMock,
132
+ })
133
+ // Check if stopPropagation was called
134
+ expect(stopPropagationMock).toHaveBeenCalled()
135
+
136
+ // Set stopPropagation props to false and wait for the DOM to update
137
+ await wrapper.setProps({ stopPropagation: false })
138
+ await wrapper.vm.$nextTick()
139
+
140
+ // Create new mock for event.stopPropagation that should not be called
141
+ const stopPropagationNotCalledMock = jest.fn()
142
+ // Simulate againma click event
143
+ await modalWrapper.trigger('click', {
144
+ stopPropagation: stopPropagationNotCalledMock,
145
+ })
146
+ // Check if stopPropagation was NOT called
147
+ expect(stopPropagationNotCalledMock).not.toHaveBeenCalled()
148
+ })
149
+ })
@@ -2,29 +2,45 @@
2
2
  <PageWrapper
3
3
  :backdrop="backdrop"
4
4
  :class="{ visible: isOpen, hidden: !isOpen }"
5
+ data-test-id="banner_wrapper"
5
6
  :is-open="isOpen"
6
7
  :position="position"
7
8
  >
8
- <ModalContainer @click="onClickModalContainer">
9
- <Spinner v-if="isLoading" :limited-to-modal="true" size="50px" />
9
+ <ModalContainer
10
+ data-test-id="modal-container"
11
+ @click="onClickModalContainer"
12
+ >
13
+ <Spinner
14
+ v-if="isLoading"
15
+ data-test-id="banner_spinner"
16
+ :limited-to-modal="true"
17
+ size="50px"
18
+ />
10
19
  <ContentContainer :visible="!isLoading">
11
20
  <slot></slot>
12
21
  </ContentContainer>
13
- <CloseButton v-if="!hideClose" class="close" @click="onCloseModal()" />
22
+ <CloseButton
23
+ v-if="!hideClose"
24
+ class="close"
25
+ data-test-id="banner_close_button"
26
+ @click="onCloseModal()"
27
+ />
14
28
  </ModalContainer>
15
29
  </PageWrapper>
16
30
  </template>
17
31
 
18
32
  <script>
19
- // Rules: (as defined in https://e-turnity.atlassian.net/browse/EPDM-9694)
20
- // 1. On clicking the “escape” key, close the modal onCloseModal()
21
- // 2. Always prevent outside close
22
- // import Modal from "@eturnity/eturnity_reusable_components/src/components/modals/modal"
23
- // This is a more flexible modal box, where the parent can decide how the body of the modal looks
24
33
  // To use:
25
- // <modal :isOpen="isOpen" @on-close="$emit('on-close-summary')" :isLoading="true" :hideClose="true" :stopPropagation="false">
26
- // <div>Data....</div>
27
- // </modal>
34
+ // import RCBanner from "@eturnity/eturnity_reusable_components/src/components/banner/banner"
35
+ // <RCBanner
36
+ // backdrop="white" // white, dark
37
+ // :hideClose="true"
38
+ // :isLoading="true"
39
+ // :isOpen="true"
40
+ // position="fixed"
41
+ // stopPropagation="false"
42
+ // @on-close="handleClose"
43
+ // />
28
44
 
29
45
  import styled from 'vue3-styled-components'
30
46
  import CloseButton from '../../buttons/closeButton'
@@ -33,6 +49,7 @@
33
49
  const contentAttrs = { visible: Boolean }
34
50
  const ContentContainer = styled('div', contentAttrs)`
35
51
  visibility: ${(props) => (props.visible ? 'inherit' : 'hidden')};
52
+ color: red;
36
53
  `
37
54
 
38
55
  const pageAttrs = { isOpen: Boolean, backdrop: String, position: String }
@@ -129,23 +146,23 @@
129
146
  },
130
147
  props: {
131
148
  isOpen: {
132
- required: true,
149
+ type: Boolean,
133
150
  default: false,
134
151
  },
135
152
  isLoading: {
136
- required: false,
153
+ type: Boolean,
137
154
  default: false,
138
155
  },
139
156
  hideClose: {
140
- required: false,
157
+ type: Boolean,
141
158
  default: false,
142
159
  },
143
160
  backdrop: {
144
- required: false,
161
+ type: String,
145
162
  default: 'white',
146
163
  },
147
164
  position: {
148
- required: false,
165
+ type: String,
149
166
  default: 'fixed',
150
167
  },
151
168
  stopPropagation: {
@@ -1,9 +1,50 @@
1
1
  <template>
2
2
  <PageWrapper>
3
- <CenterPageContainer v-if="expanded">
3
+ <PageContainer v-if="!expanded">
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>
4
45
  <CenterBox>
5
46
  <TitleContainer>
6
- <BoxTitle> {{ numberSelected }} {{ selectedText }} </BoxTitle>
47
+ <BoxTitle> {{ numberSelected }} {{ $gettext('selected') }} </BoxTitle>
7
48
  <IconContainer @click="$emit('on-close')">
8
49
  <Icon
9
50
  color="white"
@@ -21,7 +62,7 @@
21
62
  v-for="item in expandedOptions"
22
63
  :key="item.type"
23
64
  :disabled="item.disabled || false"
24
- :has-component="!!item?.component"
65
+ :hasComponent="!!item?.component"
25
66
  :hover-color="item.hoverColor"
26
67
  @click="
27
68
  !item?.component && !item.disabled && $emit('on-' + item.type)
@@ -29,8 +70,7 @@
29
70
  >
30
71
  <ListItemWrapper
31
72
  v-if="item?.component"
32
- :has-component="!!item?.component"
33
- test-data-id="expanded_list_item"
73
+ :hasComponent="!!item?.component"
34
74
  @click="!item.disabled && toggleElement(item.type)"
35
75
  >
36
76
  <ListItemTitle>
@@ -59,48 +99,6 @@
59
99
  </ExpandedList>
60
100
  </CenterBox>
61
101
  </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>
104
102
  </PageWrapper>
105
103
  </template>
106
104
 
@@ -175,8 +173,8 @@
175
173
  `
176
174
 
177
175
  const OptionsContainer = styled.div`
178
- position: absolute;
179
- left: 101%;
176
+ position: fixed;
177
+ right: -252px;
180
178
  background-color: ${(props) => props.theme.colors.black};
181
179
  border-radius: 4px;
182
180
  padding: 15px;
@@ -380,21 +378,12 @@
380
378
  optionsList: {
381
379
  type: Array,
382
380
  required: true,
383
- default: () => [],
384
381
  },
385
382
  numberSelected: {
386
383
  type: Number,
387
384
  required: true,
388
385
  default: 0,
389
386
  },
390
- selectedLabel: {
391
- type: String,
392
- default: null,
393
- },
394
- noBulkActionsLabel: {
395
- type: String,
396
- default: null,
397
- },
398
387
  },
399
388
  data() {
400
389
  return {
@@ -412,16 +401,6 @@
412
401
  limitedOptions() {
413
402
  return this.expandedOptions.filter((option) => !option.component)
414
403
  },
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
- },
425
404
  },
426
405
  watch: {
427
406
  optionsList() {
@@ -436,7 +415,7 @@
436
415
  this.expandedOptions = [...this.optionsList]
437
416
  .map((option, index) => {
438
417
  const currentOption = this.expandedOptions[index]
439
- const isOpen = currentOption ? currentOption.open : false
418
+ const isOpen = !!currentOption ? currentOption.open : false
440
419
 
441
420
  return { ...option, open: isOpen }
442
421
  })
@@ -1,176 +0,0 @@
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
- })
@@ -1,155 +0,0 @@
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
- }