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

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,137 @@
1
+ <template>
2
+ <farm-box>
3
+ <farm-row justify="center" class="mb-4">
4
+ <img
5
+ v-if="isEmpty"
6
+ :src="isEmptyImage"
7
+ :alt="isEmptyImageAlt"
8
+ class="filter-empty-state__image"
9
+ />
10
+ <img
11
+ v-else-if="isNotFound"
12
+ :src="isNotFoundImage"
13
+ :alt="isNotFoundImageAlt"
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
+ export type FilterEmptyStateProps = {
38
+ /**
39
+ * Indicates if the state is empty (no data)
40
+ */
41
+ isEmpty?: boolean;
42
+ /**
43
+ * Indicates if the state is not found (no results from filter)
44
+ */
45
+ isNotFound?: boolean;
46
+ /**
47
+ * Custom image URL for empty state
48
+ */
49
+ isEmptyImage?: string;
50
+ /**
51
+ * Alt text for empty state image
52
+ */
53
+ isEmptyImageAlt?: string;
54
+ /**
55
+ * Custom image URL for not found state
56
+ */
57
+ isNotFoundImage?: string;
58
+ /**
59
+ * Alt text for not found state image
60
+ */
61
+ isNotFoundImageAlt?: string;
62
+ /**
63
+ * Title to be displayed
64
+ */
65
+ title?: string;
66
+ /**
67
+ * Subtitle to be displayed
68
+ */
69
+ subtitle?: string;
70
+ };
71
+
72
+ export default defineComponent({
73
+ name: 'farm-filter-empty-state',
74
+ props: {
75
+ /**
76
+ * Indicates if the state is empty (no data)
77
+ */
78
+ isEmpty: {
79
+ type: Boolean as PropType<FilterEmptyStateProps['isEmpty']>,
80
+ default: false,
81
+ },
82
+ /**
83
+ * Indicates if the state is not found (no results from filter)
84
+ */
85
+ isNotFound: {
86
+ type: Boolean as PropType<FilterEmptyStateProps['isNotFound']>,
87
+ default: false,
88
+ },
89
+ /**
90
+ * Custom image URL for empty state
91
+ */
92
+ isEmptyImage: {
93
+ type: String as PropType<FilterEmptyStateProps['isEmptyImage']>,
94
+ default: require('../../assets/imgs/empty-data.svg'),
95
+ },
96
+ /**
97
+ * Alt text for empty state image
98
+ */
99
+ isEmptyImageAlt: {
100
+ type: String as PropType<FilterEmptyStateProps['isEmptyImageAlt']>,
101
+ default: 'Imagem referente a dados vazios',
102
+ },
103
+ /**
104
+ * Custom image URL for not found state
105
+ */
106
+ isNotFoundImage: {
107
+ type: String as PropType<FilterEmptyStateProps['isNotFoundImage']>,
108
+ default: require('../../assets/imgs/empty-not-found.svg'),
109
+ },
110
+ /**
111
+ * Alt text for not found state image
112
+ */
113
+ isNotFoundImageAlt: {
114
+ type: String as PropType<FilterEmptyStateProps['isNotFoundImageAlt']>,
115
+ default: 'Imagem referente a filtro vazio',
116
+ },
117
+ /**
118
+ * Title to be displayed
119
+ */
120
+ title: {
121
+ type: String as PropType<FilterEmptyStateProps['title']>,
122
+ default: '',
123
+ },
124
+ /**
125
+ * Subtitle to be displayed
126
+ */
127
+ subtitle: {
128
+ type: String as PropType<FilterEmptyStateProps['subtitle']>,
129
+ default: '',
130
+ },
131
+ },
132
+ });
133
+ </script>
134
+
135
+ <style scoped lang="scss">
136
+ @import './FilterEmptyState.scss';
137
+ </style>
@@ -0,0 +1,108 @@
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(false);
92
+ expect(wrapper.props('isNotFound')).toBe(false);
93
+ expect(wrapper.props('title')).toBe('');
94
+ expect(wrapper.props('subtitle')).toBe('');
95
+ });
96
+
97
+ it('does not show image when neither isEmpty nor isNotFound is true', () => {
98
+ const wrapper = mount(FilterEmptyState, {
99
+ propsData: {
100
+ isEmpty: false,
101
+ isNotFound: false,
102
+ },
103
+ stubs: globalStubs,
104
+ });
105
+
106
+ expect(wrapper.find('.filter-empty-state__image').exists()).toBe(false);
107
+ });
108
+ });
@@ -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
  }