@farm-investimentos/front-mfe-components-vue3 1.6.6 → 1.6.9

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.
@@ -0,0 +1,111 @@
1
+ <template>
2
+ <farm-box>
3
+ <farm-row justify="center" class="mb-4">
4
+ <!-- Custom image via prop -->
5
+ <img
6
+ v-if="hasCustomImage"
7
+ :src="currentImageSrc"
8
+ :alt="currentImageAlt"
9
+ class="filter-empty-state__image"
10
+ />
11
+ <!-- SVG component for not found state -->
12
+ <EmptyNotFoundSvg
13
+ v-else-if="isNotFound"
14
+ :alt="isNotFoundImageAlt"
15
+ class="filter-empty-state__image"
16
+ />
17
+ <!-- SVG component for empty state -->
18
+ <EmptyDataSvg v-else :alt="isEmptyImageAlt" class="filter-empty-state__image" />
19
+ </farm-row>
20
+ <farm-row justify="center">
21
+ <farm-bodytext variation="bold" color="gray" :type="2">
22
+ <slot name="title">
23
+ {{ title || 'Nenhuma informação para exibir aqui' }}
24
+ </slot>
25
+ </farm-bodytext>
26
+ </farm-row>
27
+ <farm-row justify="center" class="mt-2">
28
+ <farm-caption variation="regular" color="gray">
29
+ <slot name="subtitle">
30
+ {{ subtitle || 'Tente filtrar novamente sua pesquisa.' }}
31
+ </slot>
32
+ </farm-caption>
33
+ </farm-row>
34
+ </farm-box>
35
+ </template>
36
+
37
+ <script setup lang="ts">
38
+ import { computed } from 'vue';
39
+
40
+ import EmptyDataSvg from './EmptyDataSvg.vue';
41
+ import EmptyNotFoundSvg from './EmptyNotFoundSvg.vue';
42
+
43
+ defineOptions({
44
+ name: 'farm-filter-empty-state',
45
+ });
46
+
47
+ interface FilterEmptyStateProps {
48
+ /**
49
+ * Indicates if the state is empty (no data)
50
+ */
51
+ isEmpty?: boolean;
52
+ /**
53
+ * Indicates if the state is not found (no results from filter)
54
+ */
55
+ isNotFound?: boolean;
56
+ /**
57
+ * Custom image URL for empty state
58
+ */
59
+ isEmptyImage?: string;
60
+ /**
61
+ * Alt text for empty state image
62
+ */
63
+ isEmptyImageAlt?: string;
64
+ /**
65
+ * Custom image URL for not found state
66
+ */
67
+ isNotFoundImage?: string;
68
+ /**
69
+ * Alt text for not found state image
70
+ */
71
+ isNotFoundImageAlt?: string;
72
+ /**
73
+ * Title to be displayed
74
+ */
75
+ title?: string;
76
+ /**
77
+ * Subtitle to be displayed
78
+ */
79
+ subtitle?: string;
80
+ }
81
+
82
+ const props = withDefaults(defineProps<FilterEmptyStateProps>(), {
83
+ isEmpty: true,
84
+ isNotFound: false,
85
+ isEmptyImage: '',
86
+ isEmptyImageAlt: 'Imagem referente a dados vazios',
87
+ isNotFoundImage: '',
88
+ isNotFoundImageAlt: 'Imagem referente a filtro vazio',
89
+ title: '',
90
+ subtitle: '',
91
+ });
92
+
93
+ // Check if user provided custom images
94
+ const hasCustomImage = computed(() => {
95
+ return props.isNotFound ? !!props.isNotFoundImage : !!props.isEmptyImage;
96
+ });
97
+
98
+ // Get the current image source (for custom images)
99
+ const currentImageSrc = computed(() => {
100
+ return props.isNotFound ? props.isNotFoundImage : props.isEmptyImage;
101
+ });
102
+
103
+ // Get the current image alt text
104
+ const currentImageAlt = computed(() => {
105
+ return props.isNotFound ? props.isNotFoundImageAlt : props.isEmptyImageAlt;
106
+ });
107
+ </script>
108
+
109
+ <style scoped lang="scss">
110
+ @import './FilterEmptyState.scss';
111
+ </style>
@@ -0,0 +1,149 @@
1
+ import { mount } from '@vue/test-utils';
2
+
3
+ import FilterEmptyState from '../FilterEmptyState.vue';
4
+
5
+ const globalStubs = {
6
+ 'farm-box': { template: '<div><slot /></div>' },
7
+ 'farm-row': { template: '<div><slot /></div>' },
8
+ 'farm-bodytext': { template: '<div><slot /></div>' },
9
+ 'farm-caption': { template: '<div><slot /></div>' },
10
+ };
11
+
12
+ describe('FilterEmptyState', () => {
13
+ it('renders empty state correctly', () => {
14
+ const wrapper = mount(FilterEmptyState, {
15
+ props: {
16
+ isEmpty: true,
17
+ isNotFound: false,
18
+ },
19
+ global: {
20
+ stubs: globalStubs,
21
+ },
22
+ });
23
+
24
+ expect(wrapper.find('.filter-empty-state__image').exists()).toBe(true);
25
+ expect(wrapper.text()).toContain('Nenhuma informação para exibir aqui');
26
+ expect(wrapper.text()).toContain('Tente filtrar novamente sua pesquisa.');
27
+ });
28
+
29
+ it('renders not found state correctly', () => {
30
+ const wrapper = mount(FilterEmptyState, {
31
+ props: {
32
+ isEmpty: false,
33
+ isNotFound: true,
34
+ },
35
+ global: {
36
+ stubs: globalStubs,
37
+ },
38
+ });
39
+
40
+ expect(wrapper.find('.filter-empty-state__image').exists()).toBe(true);
41
+ expect(wrapper.text()).toContain('Nenhuma informação para exibir aqui');
42
+ expect(wrapper.text()).toContain('Tente filtrar novamente sua pesquisa.');
43
+ });
44
+
45
+ it('renders custom title and subtitle', () => {
46
+ const wrapper = mount(FilterEmptyState, {
47
+ props: {
48
+ isEmpty: true,
49
+ title: 'Custom Title',
50
+ subtitle: 'Custom Subtitle',
51
+ },
52
+ global: {
53
+ stubs: globalStubs,
54
+ },
55
+ });
56
+
57
+ expect(wrapper.text()).toContain('Custom Title');
58
+ expect(wrapper.text()).toContain('Custom Subtitle');
59
+ });
60
+
61
+ it('uses custom images when provided', () => {
62
+ const wrapper = mount(FilterEmptyState, {
63
+ props: {
64
+ isEmpty: true,
65
+ isEmptyImage: 'custom-empty-image.svg',
66
+ isEmptyImageAlt: 'Custom empty image',
67
+ },
68
+ global: {
69
+ stubs: globalStubs,
70
+ },
71
+ });
72
+
73
+ const img = wrapper.find('.filter-empty-state__image');
74
+ expect(img.exists()).toBe(true);
75
+ expect(img.attributes('src')).toBe('custom-empty-image.svg');
76
+ expect(img.attributes('alt')).toBe('Custom empty image');
77
+ });
78
+
79
+ it('uses custom not found images when provided', () => {
80
+ const wrapper = mount(FilterEmptyState, {
81
+ props: {
82
+ isNotFound: true,
83
+ isNotFoundImage: 'custom-not-found-image.svg',
84
+ isNotFoundImageAlt: 'Custom not found image',
85
+ },
86
+ global: {
87
+ stubs: globalStubs,
88
+ },
89
+ });
90
+
91
+ const img = wrapper.find('.filter-empty-state__image');
92
+ expect(img.exists()).toBe(true);
93
+ expect(img.attributes('src')).toBe('custom-not-found-image.svg');
94
+ expect(img.attributes('alt')).toBe('Custom not found image');
95
+ });
96
+
97
+ it('has correct default props', () => {
98
+ const wrapper: any = mount(FilterEmptyState, {
99
+ global: {
100
+ stubs: globalStubs,
101
+ },
102
+ });
103
+
104
+ expect(wrapper.vm.isEmpty).toBe(true);
105
+ expect(wrapper.vm.isNotFound).toBe(false);
106
+ expect(wrapper.vm.title).toBe('');
107
+ expect(wrapper.vm.subtitle).toBe('');
108
+ });
109
+
110
+ it('shows empty image by default when no props are provided', () => {
111
+ const wrapper = mount(FilterEmptyState, {
112
+ global: {
113
+ stubs: globalStubs,
114
+ },
115
+ });
116
+
117
+ expect(wrapper.find('.filter-empty-state__image').exists()).toBe(true);
118
+ });
119
+
120
+ it('shows empty image when isEmpty is false and isNotFound is false', () => {
121
+ const wrapper = mount(FilterEmptyState, {
122
+ props: {
123
+ isEmpty: false,
124
+ isNotFound: false,
125
+ },
126
+ global: {
127
+ stubs: globalStubs,
128
+ },
129
+ });
130
+
131
+ expect(wrapper.find('.filter-empty-state__image').exists()).toBe(true);
132
+ });
133
+
134
+ it('prioritizes isNotFound over isEmpty', () => {
135
+ const wrapper = mount(FilterEmptyState, {
136
+ props: {
137
+ isEmpty: true,
138
+ isNotFound: true,
139
+ },
140
+ global: {
141
+ stubs: globalStubs,
142
+ },
143
+ });
144
+
145
+ const img = wrapper.find('.filter-empty-state__image');
146
+ expect(img.exists()).toBe(true);
147
+ expect(img.attributes('aria-label')).toBe('Imagem referente a filtro vazio');
148
+ });
149
+ });
@@ -0,0 +1,4 @@
1
+ import FilterEmptyState from './FilterEmptyState.vue';
2
+
3
+ export { FilterEmptyState };
4
+ export default FilterEmptyState;
package/src/main.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './components/DataTableEmptyWrapper';
2
+ export * from './components/FilterEmptyState';
2
3
 
3
4
  import DefaultButton from './components/Buttons/DefaultButton';
4
5
  import Collapsible from './components/Collapsible';