Skip to content

Commit 3602ce5

Browse files
committed
feat: adiciona lógica de customizar colunas da tabela
1 parent 9d9f406 commit 3602ce5

File tree

4 files changed

+577
-1
lines changed

4 files changed

+577
-1
lines changed

src/components/DataTable.vue

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
<template>
2+
<div class="data-table">
3+
<div class="data-table__header">
4+
<div class="data-table__items-counter">
5+
{{ totalItems }} registros encontrados
6+
</div>
7+
8+
<!-- @slot Slot para renderização de conteúdo à direita do DataTable header. -->
9+
<div v-if="hasSlots">
10+
<slot name="right" />
11+
</div>
12+
13+
<div v-else>
14+
<cds-button
15+
size="sm"
16+
secondary
17+
@button-click="showSideSheet = true"
18+
>
19+
Personalizar tabela
20+
</cds-button>
21+
</div>
22+
</div>
23+
24+
<cds-table
25+
v-bind="$attrs"
26+
:selection-variant="selectionVariant"
27+
/>
28+
</div>
29+
30+
<cds-side-sheet
31+
v-model="showSideSheet"
32+
title="Personalizar tabela"
33+
ok-button-text="Salvar"
34+
cancel-button-text="Cancelar"
35+
:action-button-variant="selectionVariant"
36+
no-close-on-esc
37+
block-ok-button
38+
with-overlay
39+
no-close-on-backdrop
40+
@ok="handleOk"
41+
@cancel="handleCancel"
42+
>
43+
<cds-flexbox
44+
direction="column"
45+
gap="7"
46+
>
47+
<div class="side-sheet__description">
48+
Selecione as colunas que deseja exibir na tabela.
49+
</div>
50+
51+
<div>
52+
<div
53+
v-for="column in internalCustomColumnsList"
54+
:key="column"
55+
class="side-sheet__column-item"
56+
:class="[
57+
{ [`side-sheet__column-item--active--${selectionVariant}`] : column.visible },
58+
`side-sheet__column-item--${selectionVariant}`
59+
]"
60+
@click="column.visible = !column.visible"
61+
>
62+
<span
63+
class="side-sheet__item-label"
64+
:class="column.visible? `side-sheet__item-label--${selectionVariant}` : ''"
65+
>
66+
{{ column.label }}
67+
</span>
68+
69+
<cds-icon
70+
v-if="column.visible"
71+
:class="`side-sheet__icon--${selectionVariant}`"
72+
name="pin-outline"
73+
width="16"
74+
height="16"
75+
/>
76+
77+
<cds-icon
78+
v-else
79+
class="side-sheet__icon"
80+
name="pin-outline"
81+
width="16"
82+
height="16"
83+
/>
84+
</div>
85+
</div>
86+
</cds-flexbox>
87+
</cds-side-sheet>
88+
</template>
89+
90+
<script setup>
91+
import { ref } from 'vue';
92+
import CdsButton from './Button.vue';
93+
import CdsTable from './Table.vue';
94+
import CdsSideSheet from './SideSheet.vue';
95+
import CdsIcon from './Icon.vue';
96+
import { useHasSlots } from '../utils/composables/useHasSlots';
97+
import { cloneDeep } from 'lodash';
98+
99+
const hasSlots = useHasSlots();
100+
101+
const props = defineProps({
102+
/**
103+
* Variante de cor usada na estilização do componente.
104+
*/
105+
selectionVariant: {
106+
type: String,
107+
default: 'green',
108+
},
109+
/**
110+
* Quantidade total de registros encontrados.
111+
*/
112+
totalItems: {
113+
type: Number,
114+
required: true,
115+
},
116+
/**
117+
* Lista de colunas que serão exibidas na tabela personalizada.
118+
*/
119+
customColumnsList: {
120+
type: Array,
121+
default: () => [],
122+
}
123+
});
124+
125+
const emits = defineEmits(['update-columns-list']);
126+
127+
const showSideSheet = ref(false);
128+
const internalCustomColumnsList = ref(cloneDeep(props.customColumnsList));
129+
130+
function handleCancel() {
131+
internalCustomColumnsList.value = cloneDeep(props.customColumnsList);
132+
}
133+
134+
function handleOk() {
135+
emits('update-columns-list', internalCustomColumnsList.value);
136+
}
137+
138+
</script>
139+
140+
<style lang="scss" scoped>
141+
@import '../assets/sass/tokens.scss';
142+
143+
.data-table {
144+
display: flex;
145+
flex-direction: column;
146+
justify-content: center;
147+
gap: spacer(3);
148+
149+
&__header {
150+
display: flex;
151+
justify-content: space-between;
152+
align-items: flex-end;
153+
}
154+
155+
&__items-counter {
156+
@include caption;
157+
color: $n-600;
158+
}
159+
}
160+
161+
.side-sheet {
162+
163+
&__description {
164+
@include body-2;
165+
color: $n-600;
166+
margin: mb(3);
167+
}
168+
169+
&__item-label {
170+
@include body-2;
171+
color: $n-700;
172+
173+
@include variantResolver using ($color-name, $shade-50, $shade-100, $shade-200, $shade-300, $base-color, $shade-500, $shade-600) {
174+
color: $base-color;
175+
font-weight: 550;
176+
}
177+
}
178+
179+
&__column-item {
180+
display: flex;
181+
align-items: center;
182+
justify-content: space-between;
183+
width: 100%;
184+
padding: pa(5);
185+
border: 1px solid $n-30;
186+
border-radius: $border-radius-medium;
187+
margin: mb(2);
188+
cursor: pointer;
189+
190+
@include variantResolver using ($color-name, $shade-50, $shade-100, $shade-200, $shade-300, $base-color, $shade-500, $shade-600) {
191+
&:hover {
192+
border: 1px solid $shade-300;
193+
}
194+
}
195+
196+
&--active {
197+
@include variantResolver using ($color-name, $shade-50, $shade-100, $shade-200, $shade-300, $base-color, $shade-500, $shade-600) {
198+
border: 1px solid $shade-300;
199+
}
200+
}
201+
}
202+
203+
&__icon {
204+
color: $n-100;
205+
206+
@include variantResolver using ($color-name, $shade-50, $shade-100, $shade-200, $shade-300, $base-color, $shade-500, $shade-600) {
207+
color: $shade-300;
208+
}
209+
}
210+
}
211+
212+
</style>
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
<template>
2+
<div>
3+
<cds-side-sheet
4+
v-model="model"
5+
title="Personalizar tabela"
6+
ok-button-text="Salvar"
7+
cancel-button-text="Cancelar"
8+
:action-button-variant="selectionVariant"
9+
no-close-on-esc
10+
block-ok-button
11+
with-overlay
12+
no-close-on-backdrop
13+
@ok="handleOk"
14+
@cancel="handleCancel"
15+
>
16+
<cds-flexbox
17+
direction="column"
18+
gap="7"
19+
>
20+
<div class="side-sheet__description">
21+
Selecione as colunas que deseja exibir na tabela.
22+
</div>
23+
24+
<div>
25+
<div
26+
v-for="column in internalCustomColumnsList"
27+
:key="column"
28+
class="side-sheet__column-item"
29+
:class="[
30+
{ [`side-sheet__column-item--active--${selectionVariant}`] : column.visible },
31+
`side-sheet__column-item--${selectionVariant}`
32+
]"
33+
@click="column.visible = !column.visible"
34+
>
35+
<span
36+
class="side-sheet__item-label"
37+
:class="column.visible? `side-sheet__item-label--${selectionVariant}` : ''"
38+
>
39+
{{ column.label }}
40+
</span>
41+
42+
<cds-icon
43+
v-if="column.visible"
44+
:class="`side-sheet__icon--${selectionVariant}`"
45+
name="pin-outline"
46+
width="16"
47+
height="16"
48+
/>
49+
50+
<cds-icon
51+
v-else
52+
class="side-sheet__icon"
53+
name="pin-outline"
54+
width="16"
55+
height="16"
56+
/>
57+
</div>
58+
</div>
59+
</cds-flexbox>
60+
</cds-side-sheet>
61+
</div>
62+
</template>
63+
64+
<script setup>
65+
import CdsSideSheet from '../SideSheet.vue';
66+
import CdsIcon from '../Icon.vue';
67+
import { cloneDeep } from 'lodash';
68+
69+
const model = defineModel('modelValue', {
70+
type: String,
71+
});
72+
73+
const props = defineProps({
74+
selectionVariant: {
75+
type: String,
76+
default: 'green',
77+
},
78+
customColumnsList: {
79+
type: Array,
80+
default: () => [],
81+
}
82+
});
83+
84+
const emits = defineEmits(['update-columns-list']);
85+
86+
const internalCustomColumnsList = cloneDeep(props.customColumnsList);
87+
88+
function handleCancel() {
89+
internalCustomColumnsList.value = cloneDeep(props.customColumnsList);
90+
}
91+
92+
function handleOk() {
93+
emits('update-columns-list', internalCustomColumnsList.value);
94+
}
95+
96+
</script>
97+
98+
<style lang="scss" scoped>
99+
@import '../../assets/sass/tokens.scss';
100+
101+
.side-sheet {
102+
103+
&__description {
104+
@include body-2;
105+
color: $n-600;
106+
margin: mb(3);
107+
}
108+
109+
&__item-label {
110+
@include body-2;
111+
color: $n-700;
112+
113+
@include variantResolver using ($color-name, $shade-50, $shade-100, $shade-200, $shade-300, $base-color, $shade-500, $shade-600) {
114+
color: $base-color;
115+
font-weight: 550;
116+
}
117+
}
118+
119+
&__column-item {
120+
display: flex;
121+
align-items: center;
122+
justify-content: space-between;
123+
width: 100%;
124+
padding: pa(5);
125+
border: 1px solid $n-30;
126+
border-radius: $border-radius-medium;
127+
margin: mb(2);
128+
cursor: pointer;
129+
130+
@include variantResolver using ($color-name, $shade-50, $shade-100, $shade-200, $shade-300, $base-color, $shade-500, $shade-600) {
131+
&:hover {
132+
border: 1px solid $shade-300;
133+
}
134+
}
135+
136+
&--active {
137+
@include variantResolver using ($color-name, $shade-50, $shade-100, $shade-200, $shade-300, $base-color, $shade-500, $shade-600) {
138+
border: 1px solid $shade-300;
139+
}
140+
}
141+
}
142+
143+
&__icon {
144+
color: $n-100;
145+
146+
@include variantResolver using ($color-name, $shade-50, $shade-100, $shade-200, $shade-300, $base-color, $shade-500, $shade-600) {
147+
color: $shade-300;
148+
}
149+
}
150+
}
151+
</style>

src/components/Table.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ export default {
424424
position: v-bind('resolveFixedHeader');
425425
top: 0;
426426
box-shadow: v-bind('resolveHeaderShadow');
427-
z-index: $z-index-modal;
427+
z-index: $z-index-backdrop;
428428
429429
&-item {
430430
@include body-2;

0 commit comments

Comments
 (0)