@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.
- package/package.json +1 -1
- package/src/assets/theme.js +54 -6
- package/src/components/banner/banner/Banner.stories.js +99 -43
- package/src/components/banner/infoBanner/InfoBanner.stories.js +72 -30
- package/src/components/buttons/buttonIcon/ButtonIcon.stories.js +167 -0
- package/src/components/buttons/buttonIcon/index.vue +4 -5
- package/src/components/buttons/mainButton/MainButton.stories.js +116 -32
- package/src/components/draggableCard/draggableCard.stories.js +110 -54
- package/src/components/filterComponent/viewSettings.vue +220 -0
- package/src/components/icon/Icon.stories.js +220 -0
- package/src/components/projectMarker/ProjectMarker.stories.js +130 -0
- package/src/components/selectedOptions/selectedOptions.stories.js +135 -37
- package/src/components/spinner/Spinner.stories.js +70 -18
- package/src/components/spinnerGif/SpinnerGif.stories.js +86 -0
- package/src/components/tableDropdown/TableDropdown.stories.js +192 -0
- package/src/components/tables/mainTable/MainTable.stories.js +151 -0
- package/src/components/tabsHeader/TabsHeader.stories.js +142 -0
- package/src/components/videoThumbnail/videoThumbnail.stories.js +90 -17
- package/src/components/icon/Icons.stories.js +0 -31
@@ -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
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
31
|
-
|
32
|
-
|
33
|
-
|
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
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
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
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
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
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
-
<
|
31
|
-
<TextContainer>{{ args.sampleBody2 }}</TextContainer>
|
52
|
+
<div style="color: white;">Card body content</div>
|
32
53
|
</template>
|
33
54
|
<template #footer>
|
34
|
-
<
|
55
|
+
<div style="color: white;">Card footer content</div>
|
35
56
|
</template>
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
57
|
+
</DraggableCard>
|
58
|
+
`,
|
59
|
+
provide: {
|
60
|
+
theme,
|
61
|
+
},
|
62
|
+
})
|
40
63
|
|
41
|
-
export const Default =
|
64
|
+
export const Default = Template.bind({})
|
42
65
|
Default.args = {
|
43
|
-
|
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
|
47
|
-
|
48
|
-
|
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
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
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
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
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
|
77
|
-
|
78
|
-
|
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>
|