@farm-investimentos/front-mfe-components 15.13.3 → 15.14.1

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,106 @@
1
+ import FilterEmptyState from './FilterEmptyState.vue';
2
+
3
+ export default {
4
+ title: 'Display/FilterEmptyState',
5
+ component: FilterEmptyState,
6
+ parameters: {
7
+ docs: {
8
+ description: {
9
+ component: `Componente para exibir estados vazios em filtros<br />
10
+ selector: <em>farm-filter-empty-state</em><br />
11
+ <span style="color: var(--farm-primary-base);">ready for use</span>
12
+ `,
13
+ },
14
+ },
15
+ viewMode: 'docs',
16
+ },
17
+ argTypes: {
18
+ isEmpty: {
19
+ control: { type: 'boolean' },
20
+ description: 'Indica se o estado é vazio (sem dados)',
21
+ },
22
+ isNotFound: {
23
+ control: { type: 'boolean' },
24
+ description: 'Indica se o estado é não encontrado (sem resultados do filtro)',
25
+ },
26
+ isEmptyImage: {
27
+ control: { type: 'text' },
28
+ description: 'URL da imagem personalizada para estado vazio',
29
+ },
30
+ isEmptyImageAlt: {
31
+ control: { type: 'text' },
32
+ description: 'Texto alternativo da imagem para estado vazio',
33
+ },
34
+ isNotFoundImage: {
35
+ control: { type: 'text' },
36
+ description: 'URL da imagem personalizada para estado não encontrado',
37
+ },
38
+ isNotFoundImageAlt: {
39
+ control: { type: 'text' },
40
+ description: 'Texto alternativo da imagem para estado não encontrado',
41
+ },
42
+ title: {
43
+ control: { type: 'text' },
44
+ description: 'Título personalizado',
45
+ },
46
+ subtitle: {
47
+ control: { type: 'text' },
48
+ description: 'Subtítulo personalizado',
49
+ },
50
+ },
51
+ args: {
52
+ isEmpty: true,
53
+ isNotFound: false,
54
+ },
55
+ };
56
+
57
+ // Empty state image
58
+ export const EmptyStateImage = args => ({
59
+ components: { FilterEmptyState },
60
+ setup() {
61
+ return { args };
62
+ },
63
+ template: '<farm-filter-empty-state v-bind="args" />',
64
+ });
65
+ EmptyStateImage.storyName = 'Empty state image';
66
+ EmptyStateImage.args = {
67
+ isEmpty: true,
68
+ isNotFound: false,
69
+ };
70
+
71
+ // Not found state image
72
+ export const NotFoundStateImage = args => ({
73
+ components: { FilterEmptyState },
74
+ setup() {
75
+ return { args };
76
+ },
77
+ template: '<farm-filter-empty-state v-bind="args" />',
78
+ });
79
+ NotFoundStateImage.storyName = 'Not found state image';
80
+ NotFoundStateImage.args = {
81
+ isEmpty: false,
82
+ isNotFound: true,
83
+ };
84
+
85
+ // Custom titles and subtitles (slot)
86
+ export const CustomTitlesAndSubtitles = args => ({
87
+ components: { FilterEmptyState },
88
+ setup() {
89
+ return { args };
90
+ },
91
+ template: `
92
+ <farm-filter-empty-state v-bind="args">
93
+ <template #title>
94
+ <span style="color: #4f8406;">Título customizado via slot</span>
95
+ </template>
96
+ <template #subtitle>
97
+ <span>Subtítulo <b>com HTML</b> via slot</span>
98
+ </template>
99
+ </farm-filter-empty-state>
100
+ `,
101
+ });
102
+ CustomTitlesAndSubtitles.storyName = 'Custom titles and subtitles (slot)';
103
+ CustomTitlesAndSubtitles.args = {
104
+ isEmpty: true,
105
+ isNotFound: false,
106
+ };
@@ -0,0 +1,140 @@
1
+ <template>
2
+ <farm-box>
3
+ <farm-row justify="center" class="mb-4">
4
+ <img
5
+ v-if="isNotFound"
6
+ :src="isNotFoundImage"
7
+ :alt="isNotFoundImageAlt"
8
+ class="filter-empty-state__image"
9
+ />
10
+ <img
11
+ v-else
12
+ :src="isEmptyImage"
13
+ :alt="isEmptyImageAlt"
14
+ class="filter-empty-state__image"
15
+ />
16
+ </farm-row>
17
+ <farm-row justify="center">
18
+ <farm-bodytext variation="bold" color="gray" :type="2">
19
+ <slot name="title">
20
+ {{ title || 'Nenhuma informação para exibir aqui' }}
21
+ </slot>
22
+ </farm-bodytext>
23
+ </farm-row>
24
+ <farm-row justify="center" class="mt-2">
25
+ <farm-caption variation="regular" color="gray">
26
+ <slot name="subtitle">
27
+ {{ subtitle || 'Tente filtrar novamente sua pesquisa.' }}
28
+ </slot>
29
+ </farm-caption>
30
+ </farm-row>
31
+ </farm-box>
32
+ </template>
33
+
34
+ <script lang="ts">
35
+ import { defineComponent, PropType } from 'vue';
36
+
37
+ const emptyDataImage: string = require('../../assets/imgs/empty-data.svg');
38
+ const emptyNotFoundImage: string = require('../../assets/imgs/empty-not-found.svg');
39
+
40
+ export type FilterEmptyStateProps = {
41
+ /**
42
+ * Indicates if the state is empty (no data)
43
+ */
44
+ isEmpty?: boolean;
45
+ /**
46
+ * Indicates if the state is not found (no results from filter)
47
+ */
48
+ isNotFound?: boolean;
49
+ /**
50
+ * Custom image URL for empty state
51
+ */
52
+ isEmptyImage?: string;
53
+ /**
54
+ * Alt text for empty state image
55
+ */
56
+ isEmptyImageAlt?: string;
57
+ /**
58
+ * Custom image URL for not found state
59
+ */
60
+ isNotFoundImage?: string;
61
+ /**
62
+ * Alt text for not found state image
63
+ */
64
+ isNotFoundImageAlt?: string;
65
+ /**
66
+ * Title to be displayed
67
+ */
68
+ title?: string;
69
+ /**
70
+ * Subtitle to be displayed
71
+ */
72
+ subtitle?: string;
73
+ };
74
+
75
+ export default defineComponent({
76
+ name: 'farm-filter-empty-state',
77
+ props: {
78
+ /**
79
+ * Indicates if the state is empty (no data)
80
+ */
81
+ isEmpty: {
82
+ type: Boolean as PropType<FilterEmptyStateProps['isEmpty']>,
83
+ default: true,
84
+ },
85
+ /**
86
+ * Indicates if the state is not found (no results from filter)
87
+ */
88
+ isNotFound: {
89
+ type: Boolean as PropType<FilterEmptyStateProps['isNotFound']>,
90
+ default: false,
91
+ },
92
+ /**
93
+ * Custom image URL for empty state
94
+ */
95
+ isEmptyImage: {
96
+ type: String as PropType<FilterEmptyStateProps['isEmptyImage']>,
97
+ default: emptyDataImage,
98
+ },
99
+ /**
100
+ * Alt text for empty state image
101
+ */
102
+ isEmptyImageAlt: {
103
+ type: String as PropType<FilterEmptyStateProps['isEmptyImageAlt']>,
104
+ default: 'Imagem referente a dados vazios',
105
+ },
106
+ /**
107
+ * Custom image URL for not found state
108
+ */
109
+ isNotFoundImage: {
110
+ type: String as PropType<FilterEmptyStateProps['isNotFoundImage']>,
111
+ default: emptyNotFoundImage,
112
+ },
113
+ /**
114
+ * Alt text for not found state image
115
+ */
116
+ isNotFoundImageAlt: {
117
+ type: String as PropType<FilterEmptyStateProps['isNotFoundImageAlt']>,
118
+ default: 'Imagem referente a filtro vazio',
119
+ },
120
+ /**
121
+ * Title to be displayed
122
+ */
123
+ title: {
124
+ type: String as PropType<FilterEmptyStateProps['title']>,
125
+ default: '',
126
+ },
127
+ /**
128
+ * Subtitle to be displayed
129
+ */
130
+ subtitle: {
131
+ type: String as PropType<FilterEmptyStateProps['subtitle']>,
132
+ default: '',
133
+ },
134
+ },
135
+ });
136
+ </script>
137
+
138
+ <style scoped lang="scss">
139
+ @import './FilterEmptyState.scss';
140
+ </style>
@@ -0,0 +1,130 @@
1
+ import { mount } from '@vue/test-utils';
2
+ import FilterEmptyState from '../FilterEmptyState.vue';
3
+
4
+ const globalStubs = {
5
+ 'farm-box': { template: '<div><slot /></div>' },
6
+ 'farm-row': { template: '<div><slot /></div>' },
7
+ 'farm-bodytext': { template: '<div><slot /></div>' },
8
+ 'farm-caption': { template: '<div><slot /></div>' },
9
+ };
10
+
11
+ describe('FilterEmptyState', () => {
12
+ it('renders empty state correctly', () => {
13
+ const wrapper = mount(FilterEmptyState, {
14
+ propsData: {
15
+ isEmpty: true,
16
+ isNotFound: false,
17
+ },
18
+ stubs: globalStubs,
19
+ });
20
+
21
+ expect(wrapper.find('.filter-empty-state__image').exists()).toBe(true);
22
+ expect(wrapper.text()).toContain('Nenhuma informação para exibir aqui');
23
+ expect(wrapper.text()).toContain('Tente filtrar novamente sua pesquisa.');
24
+ });
25
+
26
+ it('renders not found state correctly', () => {
27
+ const wrapper = mount(FilterEmptyState, {
28
+ propsData: {
29
+ isEmpty: false,
30
+ isNotFound: true,
31
+ },
32
+ stubs: globalStubs,
33
+ });
34
+
35
+ expect(wrapper.find('.filter-empty-state__image').exists()).toBe(true);
36
+ expect(wrapper.text()).toContain('Nenhuma informação para exibir aqui');
37
+ expect(wrapper.text()).toContain('Tente filtrar novamente sua pesquisa.');
38
+ });
39
+
40
+ it('renders custom title and subtitle', () => {
41
+ const wrapper = mount(FilterEmptyState, {
42
+ propsData: {
43
+ isEmpty: true,
44
+ title: 'Custom Title',
45
+ subtitle: 'Custom Subtitle',
46
+ },
47
+ stubs: globalStubs,
48
+ });
49
+
50
+ expect(wrapper.text()).toContain('Custom Title');
51
+ expect(wrapper.text()).toContain('Custom Subtitle');
52
+ });
53
+
54
+ it('uses custom images when provided', () => {
55
+ const wrapper = mount(FilterEmptyState, {
56
+ propsData: {
57
+ isEmpty: true,
58
+ isEmptyImage: 'custom-empty-image.svg',
59
+ isEmptyImageAlt: 'Custom empty image',
60
+ },
61
+ stubs: globalStubs,
62
+ });
63
+
64
+ const img = wrapper.find('.filter-empty-state__image');
65
+ expect(img.exists()).toBe(true);
66
+ expect(img.attributes('src')).toBe('custom-empty-image.svg');
67
+ expect(img.attributes('alt')).toBe('Custom empty image');
68
+ });
69
+
70
+ it('uses custom not found images when provided', () => {
71
+ const wrapper = mount(FilterEmptyState, {
72
+ propsData: {
73
+ isNotFound: true,
74
+ isNotFoundImage: 'custom-not-found-image.svg',
75
+ isNotFoundImageAlt: 'Custom not found image',
76
+ },
77
+ stubs: globalStubs,
78
+ });
79
+
80
+ const img = wrapper.find('.filter-empty-state__image');
81
+ expect(img.exists()).toBe(true);
82
+ expect(img.attributes('src')).toBe('custom-not-found-image.svg');
83
+ expect(img.attributes('alt')).toBe('Custom not found image');
84
+ });
85
+
86
+ it('has correct default props', () => {
87
+ const wrapper = mount(FilterEmptyState, {
88
+ stubs: globalStubs,
89
+ });
90
+
91
+ expect(wrapper.props('isEmpty')).toBe(true);
92
+ expect(wrapper.props('isNotFound')).toBe(false);
93
+ expect(wrapper.props('title')).toBe('');
94
+ expect(wrapper.props('subtitle')).toBe('');
95
+ });
96
+
97
+ it('shows empty image by default when no props are provided', () => {
98
+ const wrapper = mount(FilterEmptyState, {
99
+ stubs: globalStubs,
100
+ });
101
+
102
+ expect(wrapper.find('.filter-empty-state__image').exists()).toBe(true);
103
+ });
104
+
105
+ it('shows empty image when isEmpty is false and isNotFound is false', () => {
106
+ const wrapper = mount(FilterEmptyState, {
107
+ propsData: {
108
+ isEmpty: false,
109
+ isNotFound: false,
110
+ },
111
+ stubs: globalStubs,
112
+ });
113
+
114
+ expect(wrapper.find('.filter-empty-state__image').exists()).toBe(true);
115
+ });
116
+
117
+ it('prioritizes isNotFound over isEmpty', () => {
118
+ const wrapper = mount(FilterEmptyState, {
119
+ propsData: {
120
+ isEmpty: true,
121
+ isNotFound: true,
122
+ },
123
+ stubs: globalStubs,
124
+ });
125
+
126
+ const img = wrapper.find('.filter-empty-state__image');
127
+ expect(img.exists()).toBe(true);
128
+ expect(img.attributes('alt')).toBe('Imagem referente a filtro vazio');
129
+ });
130
+ });
@@ -0,0 +1,38 @@
1
+ import FilterEmptyState from './FilterEmptyState.vue';
2
+
3
+ export type FilterEmptyStateProps = {
4
+ /**
5
+ * Indicates if the state is empty (no data)
6
+ */
7
+ isEmpty?: boolean;
8
+ /**
9
+ * Indicates if the state is not found (no results from filter)
10
+ */
11
+ isNotFound?: boolean;
12
+ /**
13
+ * Custom image URL for empty state
14
+ */
15
+ isEmptyImage?: string;
16
+ /**
17
+ * Alt text for empty state image
18
+ */
19
+ isEmptyImageAlt?: string;
20
+ /**
21
+ * Custom image URL for not found state
22
+ */
23
+ isNotFoundImage?: string;
24
+ /**
25
+ * Alt text for not found state image
26
+ */
27
+ isNotFoundImageAlt?: string;
28
+ /**
29
+ * Title to be displayed
30
+ */
31
+ title?: string;
32
+ /**
33
+ * Subtitle to be displayed
34
+ */
35
+ subtitle?: string;
36
+ };
37
+
38
+ export default FilterEmptyState;
package/src/main.ts CHANGED
@@ -12,6 +12,7 @@ import DatePicker from './components/DatePicker';
12
12
  import ManagersList from './components/ManagersList';
13
13
  import PromptUserToConfirm from './components/PromptUserToConfirm';
14
14
  import ModalPromptUser from './components/ModalPromptUser';
15
+ import FilterEmptyState from './components/FilterEmptyState';
15
16
 
16
17
  import TableContextMenu from './components/TableContextMenu';
17
18
  import IconBox from './components/IconBox';
@@ -21,6 +22,7 @@ import Collapsible from './components/Collapsible';
21
22
  import IdCaption from './components/IdCaption';
22
23
  import ResourceMetaInfo from './components/ResourceMetaInfo';
23
24
  import GanttChart from './components/GanttChart';
25
+
24
26
  export {
25
27
  DataTableEmptyWrapper,
26
28
  DataTablePaginator,
@@ -41,6 +43,7 @@ export {
41
43
  Collapsible,
42
44
  IdCaption,
43
45
  ResourceMetaInfo,
46
+ FilterEmptyState,
44
47
  GanttChart,
45
48
  };
46
49
 
@@ -94,3 +97,4 @@ export * from './components/layout/ContainerFooter';
94
97
  export * from './components/layout/Row';
95
98
  export * from './components/layout/Line';
96
99
  export * from './components/GanttChart';
100
+ export * from './components/FilterEmptyState';
@@ -1,11 +1,16 @@
1
1
  import Vue, { VNode } from 'vue';
2
2
 
3
3
  declare global {
4
- namespace JSX {
5
- interface Element extends VNode {}
6
- interface ElementClass extends Vue {}
7
- interface IntrinsicElements {
8
- [elem: string]: any
9
- }
10
- }
4
+ namespace JSX {
5
+ interface Element extends VNode {}
6
+ interface ElementClass extends Vue {}
7
+ interface IntrinsicElements {
8
+ [elem: string]: any;
9
+ }
10
+ }
11
+ }
12
+
13
+ declare module '*.svg' {
14
+ const content: string;
15
+ export default content;
11
16
  }
@@ -1,4 +1,5 @@
1
1
  declare module '*.vue' {
2
- import Vue from 'vue';
3
- export default Vue;
2
+ import { DefineComponent } from 'vue';
3
+ const component: DefineComponent<{}, {}, any>;
4
+ export default component;
4
5
  }