@eturnity/eturnity_reusable_components 8.16.2--EPDM-14330.2 → 8.16.2--EPDM-14330.3

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.
@@ -1,51 +1,135 @@
1
1
  import MainButton from './index.vue'
2
+ import theme from '../../../assets/theme'
2
3
 
3
4
  export default {
4
- title: 'MainButton',
5
+ title: 'Buttons/MainButton',
5
6
  component: MainButton,
6
7
  tags: ['autodocs'],
8
+ argTypes: {
9
+ type: {
10
+ control: 'select',
11
+ options: ['primary', 'secondary', 'tertiary', 'ghost'],
12
+ description: 'Button type',
13
+ },
14
+ variant: {
15
+ control: 'select',
16
+ options: ['main', 'cancel'],
17
+ description: 'Button variant',
18
+ },
19
+ buttonSize: {
20
+ control: 'select',
21
+ options: ['small', 'medium', 'large'],
22
+ description: 'Button size',
23
+ },
24
+ appTheme: {
25
+ control: 'select',
26
+ options: ['light', 'dark'],
27
+ description: 'Application theme',
28
+ },
29
+ },
7
30
  }
8
31
 
9
- export const DefaultButton = {
10
- args: {
11
- type: 'primary',
12
- text: 'Click me',
32
+ const Template = (args) => ({
33
+ components: { MainButton },
34
+ setup() {
35
+ return { args }
36
+ },
37
+ template: '<MainButton v-bind="args" />',
38
+ provide: {
39
+ theme,
13
40
  },
41
+ })
42
+
43
+ export const Default = Template.bind({})
44
+ Default.args = {
45
+ type: 'primary',
46
+ variant: 'main',
47
+ text: 'Default Button',
48
+ buttonSize: 'medium',
49
+ appTheme: 'light',
14
50
  }
15
51
 
16
- export const SecondaryButton = {
17
- args: {
18
- type: 'secondary',
19
- text: 'Click me',
20
- },
52
+ export const Primary = Template.bind({})
53
+ Primary.args = {
54
+ type: 'primary',
55
+ variant: 'main',
56
+ text: 'Primary Button',
57
+ buttonSize: 'medium',
58
+ appTheme: 'light',
21
59
  }
22
60
 
23
- export const CancelButton = {
24
- args: {
25
- type: 'cancel',
26
- text: 'Click me',
27
- },
61
+ export const Secondary = Template.bind({})
62
+ Secondary.args = {
63
+ type: 'secondary',
64
+ variant: 'main',
65
+ text: 'Secondary Button',
66
+ buttonSize: 'medium',
67
+ appTheme: 'light',
28
68
  }
29
69
 
30
- export const DisabledButton = {
31
- args: {
32
- text: 'Click me',
33
- isDisabled: true,
34
- },
70
+ export const Tertiary = Template.bind({})
71
+ Tertiary.args = {
72
+ type: 'tertiary',
73
+ variant: 'main',
74
+ text: 'Tertiary Button',
75
+ buttonSize: 'medium',
76
+ appTheme: 'light',
35
77
  }
36
78
 
37
- export const CustomColorButton = {
38
- args: {
39
- text: 'Click me',
40
- customColor: '#0068DE',
41
- fontColor: '#fdb813',
42
- },
79
+ export const Ghost = Template.bind({})
80
+ Ghost.args = {
81
+ type: 'ghost',
82
+ variant: 'main',
83
+ text: 'Ghost Button',
84
+ buttonSize: 'medium',
85
+ appTheme: 'light',
43
86
  }
44
87
 
45
- export const IconButton = {
46
- args: {
47
- text: 'Click me',
48
- icon: 'bell',
49
- customColor: '#fdb813',
50
- },
88
+ export const Cancel = Template.bind({})
89
+ Cancel.args = {
90
+ type: 'primary',
91
+ variant: 'cancel',
92
+ text: 'Cancel Button',
93
+ buttonSize: 'medium',
94
+ appTheme: 'light',
95
+ }
96
+
97
+ export const WithIcon = Template.bind({})
98
+ WithIcon.args = {
99
+ type: 'primary',
100
+ variant: 'main',
101
+ text: 'Button with Icon',
102
+ icon: 'bell',
103
+ buttonSize: 'medium',
104
+ appTheme: 'light',
105
+ }
106
+
107
+ export const Disabled = Template.bind({})
108
+ Disabled.args = {
109
+ type: 'primary',
110
+ variant: 'main',
111
+ text: 'Disabled Button',
112
+ isDisabled: true,
113
+ buttonSize: 'medium',
114
+ appTheme: 'light',
115
+ }
116
+
117
+ export const CustomSize = Template.bind({})
118
+ CustomSize.args = {
119
+ type: 'primary',
120
+ variant: 'main',
121
+ text: 'Custom Size',
122
+ minWidth: '200px',
123
+ height: '50px',
124
+ buttonSize: 'medium',
125
+ appTheme: 'light',
126
+ }
127
+
128
+ export const DarkTheme = Template.bind({})
129
+ DarkTheme.args = {
130
+ type: 'primary',
131
+ variant: 'main',
132
+ text: 'Dark Theme',
133
+ buttonSize: 'medium',
134
+ appTheme: 'dark',
51
135
  }
@@ -1,79 +1,135 @@
1
- import defaultProps from './defaultProps'
2
1
  import DraggableCard from './index.vue'
3
- import styled from 'vue3-styled-components'
4
2
  import theme from '@/assets/theme'
5
3
 
6
4
  export default {
7
5
  title: 'DraggableCard',
8
6
  component: DraggableCard,
9
7
  tags: ['autodocs'],
8
+ argTypes: {
9
+ width: {
10
+ control: 'text',
11
+ description: 'Width of the card',
12
+ },
13
+ initialPosition: {
14
+ control: 'object',
15
+ description: 'Initial position of the card (top, right, bottom, left)',
16
+ },
17
+ title: {
18
+ control: 'text',
19
+ description: 'Title of the card',
20
+ },
21
+ titleDataId: {
22
+ control: 'text',
23
+ description: 'Data ID for the title',
24
+ },
25
+ isCollapsible: {
26
+ control: 'boolean',
27
+ description: 'Whether the card can be collapsed',
28
+ },
29
+ infoText: {
30
+ control: 'text',
31
+ description: 'Additional info text to display next to the title',
32
+ },
33
+ dragTargets: {
34
+ control: 'array',
35
+ description: 'Targets where the card can be dragged',
36
+ },
37
+ dragBounds: {
38
+ control: 'object',
39
+ description: 'Boundaries for dragging the card',
40
+ },
41
+ },
10
42
  }
11
43
 
12
- const TextContainer = styled.div`
13
- font-family: ${theme.fonts.mainFont};
14
- color: ${theme.colors.white};
15
- font-weight: 400;
16
- font-size: 14px;
17
- line-height: 21px;
18
- letter-spacing: 0%;
19
- `
20
-
21
- const CompleteTemplate = (args) => {
22
- return {
23
- components: { DraggableCard, TextContainer },
24
- setup() {
25
- return { args }
26
- },
27
- template: `
28
- <DraggableCard v-bind="args">
44
+ const Template = (args) => ({
45
+ components: { DraggableCard },
46
+ setup() {
47
+ return { args }
48
+ },
49
+ template: `
50
+ <DraggableCard v-bind="args">
29
51
  <template #body>
30
- <TextContainer>{{ args.sampleBody1 }}</TextContainer>
31
- <TextContainer>{{ args.sampleBody2 }}</TextContainer>
52
+ <div style="color: white;">Card body content</div>
32
53
  </template>
33
54
  <template #footer>
34
- <TextContainer>{{ args.sampleFooter }}</TextContainer>
55
+ <div style="color: white;">Card footer content</div>
35
56
  </template>
36
- </DraggableCard>
37
- `,
38
- }
39
- }
57
+ </DraggableCard>
58
+ `,
59
+ provide: {
60
+ theme,
61
+ },
62
+ })
40
63
 
41
- export const Default = CompleteTemplate.bind({})
64
+ export const Default = Template.bind({})
42
65
  Default.args = {
43
- ...defaultProps,
66
+ width: '300px',
67
+ initialPosition: {
68
+ top: '20px',
69
+ left: '20px',
70
+ },
71
+ title: 'Default Card',
72
+ isCollapsible: true,
73
+ }
74
+
75
+ export const WithInfoText = Template.bind({})
76
+ WithInfoText.args = {
77
+ width: '300px',
78
+ initialPosition: {
79
+ top: '20px',
80
+ left: '20px',
81
+ },
82
+ title: 'Card with Info',
83
+ infoText: 'This is some additional information',
84
+ isCollapsible: true,
44
85
  }
45
86
 
46
- export const NotCollapsible = CompleteTemplate.bind({})
47
- NotCollapsible.args = {
48
- ...defaultProps,
87
+ export const NonCollapsible = Template.bind({})
88
+ NonCollapsible.args = {
89
+ width: '300px',
90
+ initialPosition: {
91
+ top: '20px',
92
+ left: '20px',
93
+ },
94
+ title: 'Non-Collapsible Card',
49
95
  isCollapsible: false,
50
96
  }
51
97
 
52
- export const AdjustWidth = CompleteTemplate.bind({})
53
- AdjustWidth.args = {
54
- ...defaultProps,
55
- minWidth: '100px',
56
- maxWidth: '500px',
98
+ export const WithDragBounds = Template.bind({})
99
+ WithDragBounds.args = {
100
+ width: '300px',
101
+ initialPosition: {
102
+ top: '20px',
103
+ left: '20px',
104
+ },
105
+ title: 'Card with Drag Bounds',
106
+ dragBounds: {
107
+ min: { top: 0, left: 0 },
108
+ max: { top: 500, left: 500 },
109
+ },
110
+ isCollapsible: true,
57
111
  }
58
112
 
59
- const NoFooterTemplate = (args) => {
60
- return {
61
- components: { DraggableCard, TextContainer },
62
- setup() {
63
- return { args }
64
- },
65
- template: `
66
- <DraggableCard v-bind="args">
67
- <template #body>
68
- <TextContainer>{{ args.sampleBody1 }}</TextContainer>
69
- <TextContainer>{{ args.sampleBody2 }}</TextContainer>
70
- </template>
71
- </DraggableCard>
72
- `,
73
- }
113
+ export const WithCustomDragTargets = Template.bind({})
114
+ WithCustomDragTargets.args = {
115
+ width: '300px',
116
+ initialPosition: {
117
+ top: '20px',
118
+ left: '20px',
119
+ },
120
+ title: 'Card with Custom Drag Targets',
121
+ dragTargets: ['document', 'parent'],
122
+ isCollapsible: true,
74
123
  }
75
124
 
76
- export const NoFooter = NoFooterTemplate.bind({})
77
- NoFooter.args = {
78
- ...defaultProps,
125
+ export const WithTitleDataId = Template.bind({})
126
+ WithTitleDataId.args = {
127
+ width: '300px',
128
+ initialPosition: {
129
+ top: '20px',
130
+ left: '20px',
131
+ },
132
+ title: 'Card with Data ID',
133
+ titleDataId: 'custom-data-id',
134
+ isCollapsible: true,
79
135
  }
@@ -0,0 +1,220 @@
1
+ <template>
2
+ <PageContainer>
3
+ <ButtonIcon
4
+ class="button-icon"
5
+ icon-name="settings"
6
+ :text="$gettext('view_settings')"
7
+ type="filter"
8
+ @click="toggleOptions"
9
+ />
10
+ <ButtonWrapper v-if="isOptionsVisible">
11
+ <BoxContainer class="box-container">
12
+ <BoxTitle>{{ $gettext('view_settings') }}</BoxTitle>
13
+ <SectionTitleContainer>
14
+ <SectionTitle>{{ $gettext('select_columns') }}</SectionTitle>
15
+ <MainButton
16
+ :text="$gettext('select_all')"
17
+ type="ghost"
18
+ @click="handleSelectAll"
19
+ />
20
+ </SectionTitleContainer>
21
+ <SelectOptionsContainer>
22
+ <SelectOption
23
+ v-for="column in columnsData"
24
+ :key="column.id"
25
+ :is-last-selected="column.selected && getSelectedCount() <= 1"
26
+ :is-selected="column.selected"
27
+ @click="handleSelectColumn(column)"
28
+ >
29
+ {{ $gettext(column.text) }}
30
+ </SelectOption>
31
+ </SelectOptionsContainer>
32
+ <LineSeparator v-if="detailedToggleOptions.length > 0" />
33
+ <SectionTitleContainer>
34
+ <SectionTitle>{{ $gettext('show_details') }}</SectionTitle>
35
+ </SectionTitleContainer>
36
+ <ToggleContainer>
37
+ <RCToggle
38
+ v-for="option in detailedToggleOptions"
39
+ :key="option.label"
40
+ :is-checked="option.value"
41
+ :label="$gettext(option.label)"
42
+ @on-toggle-change="$emit(option.onToggle, $event)"
43
+ />
44
+ </ToggleContainer>
45
+ </BoxContainer>
46
+ </ButtonWrapper>
47
+ </PageContainer>
48
+ </template>
49
+
50
+ <script>
51
+ import styled from 'vue3-styled-components'
52
+ import ButtonIcon from '../buttons/buttonIcon/index.vue'
53
+ import MainButton from '../buttons/mainButton/index.vue'
54
+ import RCToggle from '../inputs/toggle/index.vue'
55
+
56
+ const PageContainer = styled.div``
57
+
58
+ const ButtonWrapper = styled.div`
59
+ position: relative;
60
+ `
61
+
62
+ const BoxContainer = styled.div`
63
+ position: absolute;
64
+ z-index: 99;
65
+ top: 8px;
66
+ right: 0;
67
+ width: max-content;
68
+ max-width: 500px;
69
+ background-color: ${(props) => props.theme.colors.white};
70
+ border: 1px solid ${(props) => props.theme.semanticColors.grey[300]};
71
+ border-radius: 4px;
72
+ padding: 24px;
73
+ `
74
+
75
+ const BoxTitle = styled.div`
76
+ font-size: 14px;
77
+ font-weight: 500;
78
+ color: ${(props) => props.theme.semanticColors.teal[800]};
79
+ margin-bottom: 16px;
80
+ `
81
+
82
+ const SectionTitleContainer = styled.div`
83
+ display: flex;
84
+ align-items: center;
85
+ justify-content: space-between;
86
+ margin-bottom: 16px;
87
+ white-space: nowrap;
88
+ gap: 16px;
89
+ `
90
+
91
+ const SectionTitle = styled.div`
92
+ font-size: 12px;
93
+ font-weight: 500;
94
+ color: ${(props) => props.theme.semanticColors.teal[800]};
95
+ `
96
+
97
+ const SelectOptionsContainer = styled.div`
98
+ display: flex;
99
+ flex-direction: row;
100
+ flex-wrap: wrap;
101
+ gap: 8px;
102
+ `
103
+
104
+ const SelectAttrs = {
105
+ isSelected: Boolean,
106
+ isLastSelected: Boolean,
107
+ }
108
+ const SelectOption = styled('div', SelectAttrs)`
109
+ background-color: ${(props) =>
110
+ props.isSelected
111
+ ? props.theme.semanticColors.green[400]
112
+ : props.theme.colors.white};
113
+ color: ${(props) => props.theme.semanticColors.teal[800]};
114
+ border: 1px solid
115
+ ${(props) =>
116
+ props.isSelected
117
+ ? props.theme.semanticColors.green[400]
118
+ : props.theme.semanticColors.green[300]};
119
+ padding: 1px 10px;
120
+ font-size: 12px;
121
+ font-weight: 400;
122
+ border-radius: 4px;
123
+ cursor: ${(props) =>
124
+ props.isSelected && props.isLastSelected ? 'not-allowed' : 'pointer'};
125
+ user-select: none;
126
+ `
127
+
128
+ const LineSeparator = styled.div`
129
+ width: 100%;
130
+ height: 1px;
131
+ background-color: ${(props) => props.theme.semanticColors.grey[100]};
132
+ margin: 16px 0;
133
+ `
134
+
135
+ const ToggleContainer = styled.div`
136
+ display: flex;
137
+ flex-direction: column;
138
+ gap: 8px;
139
+ `
140
+
141
+ export default {
142
+ name: 'ViewSettings',
143
+ components: {
144
+ PageContainer,
145
+ ButtonIcon,
146
+ ButtonWrapper,
147
+ BoxContainer,
148
+ BoxTitle,
149
+ SectionTitleContainer,
150
+ SectionTitle,
151
+ MainButton,
152
+ SelectOptionsContainer,
153
+ SelectOption,
154
+ LineSeparator,
155
+ RCToggle,
156
+ ToggleContainer,
157
+ },
158
+ props: {
159
+ columnsData: {
160
+ type: Array,
161
+ required: true,
162
+ },
163
+ detailedToggleOptions: {
164
+ type: Array,
165
+ required: false,
166
+ },
167
+ },
168
+ emits: ['onSelectColumn', 'onSelectAllColumns'],
169
+ data() {
170
+ return {
171
+ isOptionsVisible: false,
172
+ }
173
+ },
174
+ mounted() {
175
+ // Remove the mounted event listener since we now handle it in toggleOptions
176
+ },
177
+ beforeUnmount() {
178
+ document.removeEventListener('click', this.handleClickOutside)
179
+ },
180
+ methods: {
181
+ getSelectedCount() {
182
+ return this.columnsData.filter((col) => col.selected).length
183
+ },
184
+ handleSelectAll() {
185
+ this.$emit('onSelectAllColumns')
186
+ },
187
+ handleSelectColumn(column) {
188
+ // Count currently selected columns
189
+ const selectedCount = this.getSelectedCount()
190
+
191
+ // Prevent deselecting if this is the last selected column
192
+ if (selectedCount <= 1 && column.selected) {
193
+ return
194
+ }
195
+
196
+ this.$emit('onSelectColumn', column)
197
+ },
198
+ toggleOptions() {
199
+ this.isOptionsVisible = !this.isOptionsVisible
200
+ if (this.isOptionsVisible) {
201
+ document.addEventListener('click', this.handleClickOutside)
202
+ } else {
203
+ document.removeEventListener('click', this.handleClickOutside)
204
+ }
205
+ },
206
+ handleClickOutside(event) {
207
+ const buttonIcon = this.$el.querySelector('.button-icon')
208
+ const boxContainer = this.$el.querySelector('.box-container')
209
+
210
+ if (
211
+ !buttonIcon.contains(event.target) &&
212
+ !boxContainer.contains(event.target)
213
+ ) {
214
+ this.isOptionsVisible = false
215
+ document.removeEventListener('click', this.handleClickOutside)
216
+ }
217
+ },
218
+ },
219
+ }
220
+ </script>