@eturnity/eturnity_reusable_components 7.45.1-EPDM-12459.0 → 7.45.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.45.1-EPDM-12459.0",
3
+ "version": "7.45.2",
4
4
  "files": [
5
5
  "dist",
6
6
  "src"
@@ -0,0 +1,79 @@
1
+ import Card from './index.vue'
2
+
3
+ export default {
4
+ title: 'Card',
5
+ component: Card,
6
+ tags: ['autodocs'],
7
+ }
8
+
9
+ // To use:
10
+ // <RCCard
11
+ // :isLoading="true"
12
+ // minWidth="150px"
13
+ // popoverText="Sample popover text"
14
+ // :showPopover="true"
15
+ // title="Sample title"
16
+ // titleClass="sampleTitleClass"
17
+ // viewCardClass="sampleViewCardClass"
18
+ // width="200px"
19
+ // />
20
+
21
+ export const Default = {
22
+ args: {
23
+ title: 'Sample card title',
24
+ },
25
+ render: (args) => ({
26
+ components: { Card },
27
+ setup() {
28
+ return { args }
29
+ },
30
+ template: `
31
+ <Card v-bind="args">
32
+ Sample card content
33
+ </ActionBanner>
34
+ `,
35
+ }),
36
+ }
37
+
38
+ export const LoadingCard = {
39
+ args: {
40
+ isLoading: true,
41
+ },
42
+ }
43
+
44
+ export const CustomWidth = {
45
+ args: {
46
+ title: 'Sample card title',
47
+ width: '600px',
48
+ },
49
+ render: (args) => ({
50
+ components: { Card },
51
+ setup() {
52
+ return { args }
53
+ },
54
+ template: `
55
+ <Card v-bind="args">
56
+ Sample card content
57
+ </ActionBanner>
58
+ `,
59
+ }),
60
+ }
61
+
62
+ export const PopoverShown = {
63
+ args: {
64
+ title: 'Sample card title',
65
+ showPopover: true,
66
+ popoverText: 'Sample popover text',
67
+ },
68
+ render: (args) => ({
69
+ components: { Card },
70
+ setup() {
71
+ return { args }
72
+ },
73
+ template: `
74
+ <Card v-bind="args">
75
+ Sample card content
76
+ </ActionBanner>
77
+ `,
78
+ }),
79
+ }
@@ -0,0 +1,135 @@
1
+ /* eslint-disable */
2
+ import { mount, config } from '@vue/test-utils'
3
+ import Card from '@/components/card'
4
+ import theme from '@/assets/theme'
5
+
6
+ config.global.components = {
7
+ EtPopover: {
8
+ template: '<div>{{ text }}</div>',
9
+ props: ['text'],
10
+ },
11
+ }
12
+
13
+ config.global.mocks = {
14
+ $gettext: (msg) => msg,
15
+ }
16
+
17
+ describe('Card Component', () => {
18
+ it('card title is shown when a title props is passed', () => {
19
+ const title = 'Test Card Title'
20
+ const wrapper = mount(Card, {
21
+ props: {
22
+ title,
23
+ },
24
+ global: {
25
+ provide: {
26
+ theme,
27
+ },
28
+ },
29
+ })
30
+
31
+ expect(wrapper.text()).toContain(title)
32
+ })
33
+
34
+ it('card spinner is shown when user set isLoading props to true', async () => {
35
+ // Start with isLoading is false
36
+ const wrapper = mount(Card, {
37
+ props: {
38
+ title: 'Test Card Title',
39
+ isLoading: false,
40
+ },
41
+ global: {
42
+ provide: {
43
+ theme,
44
+ },
45
+ },
46
+ })
47
+
48
+ let cardSpinner = wrapper.find('[data-test-id="card_spinner"]')
49
+ expect(cardSpinner.exists()).toBe(false)
50
+ await wrapper.setProps({ isLoading: true })
51
+ await wrapper.vm.$nextTick()
52
+ cardSpinner = wrapper.find('[data-test-id="card_spinner"]')
53
+ expect(cardSpinner.exists()).toBe(true)
54
+ })
55
+
56
+ it('card wrapper has custom class when viewCardClass props is passed', async () => {
57
+ const viewCardClass = 'sampleClass'
58
+ const wrapper = mount(Card, {
59
+ props: {
60
+ title: 'Test Card Title',
61
+ viewCardClass,
62
+ },
63
+ global: {
64
+ provide: {
65
+ theme,
66
+ },
67
+ },
68
+ })
69
+
70
+ const cardMainWrapper = wrapper.find('[data-test-id="card_main_wrapper"]')
71
+ expect(cardMainWrapper.classes()).toContain(viewCardClass)
72
+ })
73
+
74
+ it('card title has custom class when titleClass props is passed', async () => {
75
+ const titleClass = 'sampleClass'
76
+ const wrapper = mount(Card, {
77
+ props: {
78
+ title: 'Test Card Title',
79
+ titleClass,
80
+ },
81
+ global: {
82
+ provide: {
83
+ theme,
84
+ },
85
+ },
86
+ })
87
+
88
+ const cardTitle = wrapper.find('[data-test-id="card_title"]')
89
+ expect(cardTitle.classes()).toContain(titleClass)
90
+ })
91
+
92
+ it('card popover is shown when user set showPopover props to true', async () => {
93
+ // Start with showPopover is false
94
+ const wrapper = mount(Card, {
95
+ props: {
96
+ title: 'Test Card Title',
97
+ showPopover: false,
98
+ popoverText: 'Sample popover text',
99
+ },
100
+ global: {
101
+ provide: {
102
+ theme,
103
+ },
104
+ },
105
+ })
106
+
107
+ let cardPopover = wrapper.find('[data-test-id="card_popover"]')
108
+ expect(cardPopover.exists()).toBe(false)
109
+ await wrapper.setProps({ showPopover: true })
110
+ await wrapper.vm.$nextTick()
111
+ cardPopover = wrapper.find('[data-test-id="card_popover"]')
112
+ expect(cardPopover.exists()).toBe(true)
113
+ expect(cardPopover.text()).toContain('Sample popover text')
114
+ })
115
+
116
+ it('card popover text is set when user passed a popoverText props value', async () => {
117
+ const popoverText = 'Sample popover text'
118
+ const wrapper = mount(Card, {
119
+ props: {
120
+ title: 'Test Card Title',
121
+ showPopover: true,
122
+ popoverText,
123
+ },
124
+ global: {
125
+ provide: {
126
+ theme,
127
+ },
128
+ },
129
+ })
130
+
131
+ let cardPopover = wrapper.find('[data-test-id="card_popover"]')
132
+ expect(cardPopover.exists()).toBe(true)
133
+ expect(cardPopover.text()).toContain('Sample popover text')
134
+ })
135
+ })
@@ -2,15 +2,22 @@
2
2
  <Wrapper
3
3
  v-show="!isLoading"
4
4
  :class="viewCardClass"
5
+ data-test-id="card_main_wrapper"
5
6
  :min-width="minWidth"
6
7
  :width="width"
7
8
  >
8
- <Spinner v-if="isLoading" :limited-to-modal="true" size="50px" />
9
+ <Spinner
10
+ v-if="isLoading"
11
+ data-test-id="card_spinner"
12
+ :limited-to-modal="true"
13
+ size="50px"
14
+ />
9
15
  <CardWrapper v-else>
10
- <CardTitle :class="titleClass">
16
+ <CardTitle :class="titleClass" data-test-id="card_title">
11
17
  {{ $gettext(title) }}
12
18
  <EtPopover
13
19
  v-if="showPopover && popoverText !== ''"
20
+ data-test-id="card_popover"
14
21
  :text="popoverText"
15
22
  />
16
23
  </CardTitle>
@@ -20,6 +27,19 @@
20
27
  </template>
21
28
 
22
29
  <script>
30
+ // To use:
31
+ // import RCCard from "@eturnity/eturnity_reusable_components/src/components/card"
32
+ // <RCCard
33
+ // :isLoading="true"
34
+ // minWidth="150px"
35
+ // popoverText="Sample popover text"
36
+ // :showPopover="true"
37
+ // title="Sample title"
38
+ // titleClass="sampleTitleClass"
39
+ // viewCardClass="sampleViewCardClass"
40
+ // width="200px"
41
+ // />
42
+
23
43
  import styled from 'vue3-styled-components'
24
44
  import Spinner from '../spinner'
25
45
 
@@ -606,10 +606,6 @@
606
606
  },
607
607
  dropdownWidth: null,
608
608
  hoveredValue: null,
609
- isDisplayedAtBottom: true,
610
- selectTopPosition: 0,
611
- selectAndDropdownDistance: 0,
612
- animationFrameId: null,
613
609
  }
614
610
  },
615
611
  computed: {
@@ -680,13 +676,8 @@
680
676
  }, 10)
681
677
  await this.$nextTick()
682
678
  this.handleSetDropdownOffet()
683
- this.calculateSelectTopPosition()
684
679
  } else {
685
680
  this.dropdownPosition.left = null
686
- if (this.animationFrameId) {
687
- cancelAnimationFrame(this.animationFrameId)
688
- this.animationFrameId = null
689
- }
690
681
  setTimeout(() => {
691
682
  this.isClickOutsideActive = false
692
683
  }, 10)
@@ -699,27 +690,11 @@
699
690
  })
700
691
  }
701
692
  },
702
- isSelectDropdownShown(isShown) {
703
- if (!isShown) return
704
-
705
- // Need to wait for 1ms to make sure the dropdown menu is shown in the DOM
706
- // before getting the distance between the select and the dropdown menu
707
- setTimeout(() => {
708
- this.getDistanceBetweenSelectAndDropdownMenu()
709
- }, 100)
710
- },
711
- selectTopPosition() {
712
- this.dropdownPosition.top =
713
- this.selectTopPosition +
714
- this.$refs.select.$el.clientHeight +
715
- this.selectAndDropdownDistance
716
- },
717
693
  },
718
694
  mounted() {
719
695
  this.observeDropdownHeight()
720
696
  this.observeSelectWidth()
721
697
  window.addEventListener('resize', this.handleSetDropdownOffet)
722
- document.body.addEventListener('scroll', this.calculateSelectTopPosition)
723
698
  },
724
699
  beforeMount() {
725
700
  this.selectedValue = this.value
@@ -728,34 +703,11 @@
728
703
  window.removeEventListener('resize', this.handleSetDropdownOffet)
729
704
  if (this.dropdownResizeObserver) this.dropdownResizeObserver.disconnect()
730
705
  if (this.selectResizeObserver) this.selectResizeObserver.disconnect()
731
- document.body.removeEventListener(
732
- 'scroll',
733
- this.calculateSelectTopPosition
734
- )
735
706
  },
736
707
  unmounted() {
737
708
  document.removeEventListener('click', this.clickOutside)
738
709
  },
739
710
  methods: {
740
- getDistanceBetweenSelectAndDropdownMenu() {
741
- const wholeSelectTopPosition =
742
- this.selectTopPosition + this.$refs.select.$el.clientHeight
743
- this.selectAndDropdownDistance =
744
- this.dropdownPosition.top - wholeSelectTopPosition
745
- },
746
- calculateSelectTopPosition() {
747
- const selectRef = this.$refs.select
748
- if (selectRef) {
749
- const currentTopPosition =
750
- selectRef.$el.getBoundingClientRect().top + window.scrollY
751
- if (this.selectTopPosition !== currentTopPosition) {
752
- this.selectTopPosition = currentTopPosition
753
- }
754
- }
755
- this.animationFrameId = requestAnimationFrame(
756
- this.calculateSelectTopPosition
757
- )
758
- },
759
711
  focus() {
760
712
  this.isActive = true
761
713
  },
@@ -856,11 +808,11 @@
856
808
  return
857
809
  }
858
810
  await this.$nextTick()
859
- this.isDisplayedAtBottom = await this.generateDropdownPosition()
811
+ const isDisplayedAtBottom = await this.generateDropdownPosition()
860
812
  // If the dropdown menu is going to be displayed at the bottom,
861
813
  // we need reverify its position after a dom update (nextTick)
862
814
  await this.$nextTick()
863
- if (this.isDisplayedAtBottom) this.generateDropdownPosition()
815
+ if (isDisplayedAtBottom) this.generateDropdownPosition()
864
816
  },
865
817
  async generateDropdownPosition() {
866
818
  const isDropdownNotCompletelyVisible =