@pucp-gidis-hiisc/esm-fua-app 1.1.0 → 1.2.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.
Files changed (118) hide show
  1. package/dist/116.js +1 -0
  2. package/dist/116.js.map +1 -0
  3. package/dist/123.js +2 -0
  4. package/dist/123.js.map +1 -0
  5. package/dist/191.js +1 -0
  6. package/dist/191.js.map +1 -0
  7. package/dist/194.js +1 -0
  8. package/dist/194.js.map +1 -0
  9. package/dist/276.js +2 -0
  10. package/dist/{556.js.LICENSE.txt → 276.js.LICENSE.txt} +1 -11
  11. package/dist/276.js.map +1 -0
  12. package/dist/300.js +1 -1
  13. package/dist/31.js +1 -0
  14. package/dist/31.js.map +1 -0
  15. package/dist/322.js +1 -0
  16. package/dist/322.js.map +1 -0
  17. package/dist/336.js +1 -1
  18. package/dist/336.js.map +1 -1
  19. package/dist/372.js +1 -1
  20. package/dist/372.js.map +1 -1
  21. package/dist/397.js +1 -0
  22. package/dist/397.js.map +1 -0
  23. package/dist/41.js +1 -1
  24. package/dist/41.js.map +1 -1
  25. package/dist/457.js +1 -1
  26. package/dist/457.js.map +1 -1
  27. package/dist/464.js +1 -1
  28. package/dist/464.js.map +1 -1
  29. package/dist/470.js +1 -1
  30. package/dist/470.js.map +1 -1
  31. package/dist/495.js +2 -1
  32. package/dist/495.js.LICENSE.txt +9 -0
  33. package/dist/495.js.map +1 -1
  34. package/dist/51.js +2 -0
  35. package/dist/{main.js.LICENSE.txt → 51.js.LICENSE.txt} +18 -3
  36. package/dist/51.js.map +1 -0
  37. package/dist/661.js +1 -0
  38. package/dist/661.js.map +1 -0
  39. package/dist/69.js +1 -0
  40. package/dist/69.js.map +1 -0
  41. package/dist/745.js +1 -0
  42. package/dist/745.js.map +1 -0
  43. package/dist/794.js +1 -0
  44. package/dist/794.js.map +1 -0
  45. package/dist/810.js +1 -0
  46. package/dist/810.js.map +1 -0
  47. package/dist/876.js +1 -2
  48. package/dist/876.js.map +1 -1
  49. package/dist/89.js +1 -1
  50. package/dist/89.js.map +1 -1
  51. package/dist/913.js +1 -1
  52. package/dist/913.js.LICENSE.txt +3 -3
  53. package/dist/913.js.map +1 -1
  54. package/dist/932.js +1 -0
  55. package/dist/932.js.map +1 -0
  56. package/dist/964.js +1 -0
  57. package/dist/964.js.map +1 -0
  58. package/dist/99.js +1 -1
  59. package/dist/main.js +1 -2
  60. package/dist/main.js.map +1 -1
  61. package/dist/pucp-gidis-hiisc-esm-fua-app.js +1 -1
  62. package/dist/pucp-gidis-hiisc-esm-fua-app.js.buildmanifest.json +368 -101
  63. package/dist/pucp-gidis-hiisc-esm-fua-app.js.map +1 -1
  64. package/dist/routes.json +1 -1
  65. package/package.json +4 -2
  66. package/src/components/fua-html-viewer.component.tsx +81 -0
  67. package/src/components/fua-html-viewer.scss +44 -0
  68. package/src/components/summary-tiles/summary-tile.component.tsx +35 -0
  69. package/src/components/summary-tiles/summary-tiles.scss +64 -0
  70. package/src/config-schema.ts +15 -53
  71. package/src/declarations.d.ts +4 -6
  72. package/src/fua/fua-date-range-picker.component.tsx +38 -0
  73. package/src/fua/fua-date-range-picker.scss +15 -0
  74. package/src/fua/fua-header.scss +68 -0
  75. package/src/fua/{case-management-header.tsx → fua-header.tsx} +6 -6
  76. package/src/fua/{case-management-illustration.tsx → fua-illustration.tsx} +3 -3
  77. package/src/fua/fua-request-table.scss +80 -128
  78. package/src/fua/fuaRequestTable.tsx +148 -101
  79. package/src/fua-dashboard.component.tsx +25 -0
  80. package/src/fua-dashboard.scss +35 -0
  81. package/src/fua-tabs/data-table-extensions/all-fua-requests-table.extension.tsx +8 -0
  82. package/src/fua-tabs/data-table-extensions/completed-fua-requests-table.extension.tsx +8 -0
  83. package/src/fua-tabs/data-table-extensions/declined-fua-requests-table.extension.tsx +8 -0
  84. package/src/fua-tabs/data-table-extensions/in-progress-fua-requests-table.extension.tsx +8 -0
  85. package/src/fua-tabs/fua-tabs.component.tsx +74 -0
  86. package/src/fua-tabs/fua-tabs.scss +65 -0
  87. package/src/fua-tiles/all-fua-requests-tile.component.tsx +20 -0
  88. package/src/fua-tiles/completed-fua-requests-tile.component.tsx +19 -0
  89. package/src/fua-tiles/fua-summary-tiles.component.tsx +46 -0
  90. package/src/fua-tiles/fua-summary-tiles.scss +16 -0
  91. package/src/fua-tiles/in-progress-fua-requests-tile.component.tsx +20 -0
  92. package/src/fua-viewer-page/fua-viewer-page.component.tsx +90 -0
  93. package/src/fua-viewer-page/fua-viewer-page.scss +82 -0
  94. package/src/hooks/useFuaRequests.ts +93 -26
  95. package/src/index.ts +82 -7
  96. package/src/root.component.tsx +8 -0
  97. package/src/routes.json +94 -10
  98. package/src/types/index.ts +4 -0
  99. package/src/workspaces/fua-viewer.workspace.tsx +20 -0
  100. package/translations/en.json +15 -1
  101. package/translations/es.json +15 -1
  102. package/.turbo/turbo-build.log +0 -43
  103. package/.turbo/turbo-extract-translations.log +0 -11
  104. package/.turbo/turbo-lint.log +0 -14
  105. package/dist/144.js +0 -2
  106. package/dist/144.js.LICENSE.txt +0 -19
  107. package/dist/144.js.map +0 -1
  108. package/dist/466.js +0 -1
  109. package/dist/466.js.map +0 -1
  110. package/dist/556.js +0 -2
  111. package/dist/556.js.map +0 -1
  112. package/dist/596.js +0 -2
  113. package/dist/596.js.LICENSE.txt +0 -30
  114. package/dist/596.js.map +0 -1
  115. package/dist/790.js +0 -1
  116. package/dist/790.js.map +0 -1
  117. package/src/root.scss +0 -102
  118. /package/dist/{876.js.LICENSE.txt → 123.js.LICENSE.txt} +0 -0
@@ -1,173 +1,125 @@
1
- @use '@carbon/styles/scss/spacing';
2
- @use '@carbon/styles/scss/type';
3
1
  @use '@carbon/colors';
4
2
  @use '@carbon/layout';
3
+ @use '@carbon/type';
5
4
 
6
- @use '@openmrs/esm-styleguide/src/vars' as *;
7
- @use '../root.scss' as *;
8
-
9
- .jsonTable {
10
- width: 100%;
11
- border-collapse: collapse;
12
- margin-top: 0.5rem;
5
+ .tableContainer {
6
+ border: 1px solid colors.$gray-20;
7
+ background-color: colors.$gray-10;
8
+ padding: 0;
13
9
 
14
- td {
15
- border: 1px solid #e0e0e0;
16
- padding: 0.5rem;
17
- font-family: monospace;
10
+ :global(.cds--data-table-content) {
11
+ overflow-x: unset;
18
12
  }
19
- }
20
-
21
- .payloadCell {
22
- text-align: center;
23
- }
24
13
 
25
- .payloadButton {
26
- background-color: colors.$white-0;
27
- border: 1px solid colors.$gray-20;
28
- margin-bottom: 1rem;
29
- }
30
-
31
- .payloadExpandedContent {
32
- padding: 1rem;
33
- background-color: #f4f4f4;
34
- border: 1px solid #e0e0e0;
35
- overflow-x: auto;
36
- max-width: 100%;
37
- }
14
+ a {
15
+ text-decoration: none;
16
+ }
38
17
 
39
- .header {
40
- @include type.type-style('body-compact-02');
41
- color: $text-02;
42
- height: spacing.$spacing-12;
43
- background-color: $ui-02;
44
- border: 1px solid $ui-03;
45
- border-left: 0px;
46
- display: flex;
47
- justify-content: space-between;
48
- margin-bottom: 2rem;
49
- }
18
+ th {
19
+ color: colors.$gray-70;
20
+ }
50
21
 
51
- .left-justified-items {
52
- display: flex;
53
- flex-direction: row;
54
- align-items: center;
55
- margin-left: 0.75rem;
56
- }
22
+ :global(.cds--data-table) {
23
+ background-color: colors.$gray-20;
24
+ }
57
25
 
58
- .right-justified-items {
59
- @include type.type-style('body-compact-02');
60
- color: $text-02;
61
- padding-top: 1rem;
62
- }
26
+ :global(.cds--table-toolbar) {
27
+ position: static;
28
+ }
63
29
 
64
- .page-name {
65
- @include type.type-style('heading-04');
66
- }
30
+ :global(.cds--overflow-menu) {
31
+ background-color: transparent;
32
+ border: none;
33
+ }
67
34
 
68
- .page-labels {
69
- margin-left: 1rem;
35
+ :global(.cds--pagination) {
36
+ border-top: none;
37
+ }
70
38
 
71
- p:first-of-type {
72
- margin-bottom: 0.25rem;
39
+ .toolbarContent {
40
+ height: layout.$spacing-07;
41
+ margin-bottom: layout.$spacing-02;
73
42
  }
74
43
  }
75
44
 
76
- .date-and-location {
45
+ .toolbarContent {
77
46
  display: flex;
78
- justify-content: flex-end;
79
47
  align-items: center;
80
- margin-right: 1rem;
81
- }
82
-
83
- .value {
84
- margin-left: 0.25rem;
48
+ justify-content: flex-end;
85
49
  }
86
50
 
87
- .middot {
88
- margin: 0 0.5rem;
89
- }
51
+ .toolbarItem {
52
+ margin-left: layout.$spacing-05;
53
+ display: flex;
54
+ align-items: center;
90
55
 
91
- .view {
92
- @include type.type-style('label-01');
93
- }
56
+ & p {
57
+ padding-right: layout.$spacing-03;
58
+ @include type.type-style('body-01');
59
+ color: colors.$gray-70;
60
+ }
94
61
 
95
- svg.iconOverrides {
96
- width: 72 !important;
97
- height: 72 !important;
98
- fill: var(--brand-03);
99
- }
62
+ :global(.cds--date-picker__input) {
63
+ height: layout.$spacing-09;
64
+ }
100
65
 
101
- .svgContainer svg {
102
- width: 72px;
103
- height: 72px;
104
- fill: var(--brand-03);
105
- }
66
+ :global(.cds--dropdown) {
67
+ height: layout.$spacing-09;
68
+ }
106
69
 
107
- .header {
108
- @include type.type-style('body-compact-02');
109
- color: $text-02;
110
- height: spacing.$spacing-12;
111
- background-color: $ui-02;
112
- border: 1px solid $ui-03;
113
- border-left: 0px;
114
- display: flex;
115
- justify-content: space-between;
116
- margin-bottom: 2rem;
70
+ :global(.cds--list-box__menu:focus) {
71
+ outline: none;
72
+ }
117
73
  }
118
74
 
119
- .left-justified-items {
120
- display: flex;
121
- flex-direction: row;
122
- align-items: center;
123
- margin-left: 0.75rem;
75
+ .table {
76
+ width: 100%;
124
77
  }
125
78
 
126
- .right-justified-items {
127
- @include type.type-style('body-compact-02');
128
- color: $text-02;
129
- padding-top: 1rem;
79
+ .tableHeader {
80
+ @include type.type-style('heading-compact-01');
81
+ color: var(--cds-text-primary);
130
82
  }
131
83
 
132
- .page-name {
133
- @include type.type-style('heading-04');
84
+ .tableCell {
85
+ @include type.type-style('body-compact-01');
86
+ color: var(--cds-text-primary);
134
87
  }
135
88
 
136
- .page-labels {
137
- margin-left: 1rem;
138
-
139
- p:first-of-type {
140
- margin-bottom: 0.25rem;
89
+ .tableWrapper tr:last-of-type {
90
+ td {
91
+ border-bottom: none;
141
92
  }
142
93
  }
143
94
 
144
- .date-and-location {
145
- display: flex;
146
- justify-content: flex-end;
147
- align-items: center;
148
- margin-right: 1rem;
95
+ .tileContainer {
96
+ background-color: colors.$white;
97
+ border-top: 1px solid colors.$gray-20;
98
+ padding: 3rem 0;
149
99
  }
150
100
 
151
- .value {
152
- margin-left: 0.25rem;
101
+ .tile {
102
+ margin: auto;
103
+ width: fit-content;
153
104
  }
154
105
 
155
- .middot {
156
- margin: 0 0.5rem;
106
+ .tileContent {
107
+ display: flex;
108
+ flex-direction: column;
109
+ align-items: center;
157
110
  }
158
111
 
159
- .view {
160
- @include type.type-style('label-01');
112
+ .content {
113
+ @include type.type-style('heading-compact-02');
114
+ color: colors.$gray-70;
115
+ margin-bottom: layout.$spacing-03;
161
116
  }
162
117
 
163
- svg.iconOverrides {
164
- width: 72 !important;
165
- height: 72 !important;
166
- fill: var(--brand-03);
118
+ .emptyStateHelperText {
119
+ @include type.type-style('helper-text-02');
167
120
  }
168
121
 
169
- .svgContainer svg {
170
- width: 72px;
171
- height: 72px;
172
- fill: var(--brand-03);
122
+ .pagination {
123
+ border-top: 1px solid var(--cds-border-subtle-01);
124
+ background-color: var(--cds-layer-01);
173
125
  }
@@ -1,145 +1,192 @@
1
- import React, { useState } from 'react';
1
+ import React, { useState, useMemo } from 'react';
2
2
  import {
3
3
  DataTable,
4
+ DataTableSkeleton,
4
5
  Table,
5
6
  TableHead,
6
7
  TableRow,
7
8
  TableHeader,
8
9
  TableBody,
9
10
  TableCell,
10
- TableExpandHeader,
11
- TableExpandRow,
12
- TableExpandedRow,
13
11
  TableContainer,
12
+ TableToolbar,
13
+ TableToolbarContent,
14
+ TableToolbarSearch,
15
+ Pagination,
16
+ Layer,
17
+ Tile,
18
+ Button,
14
19
  } from '@carbon/react';
20
+ import { View } from '@carbon/react/icons';
15
21
  import { useTranslation } from 'react-i18next';
22
+ import { formatDate, usePagination, launchWorkspace } from '@openmrs/esm-framework';
16
23
  import useFuaRequests from '../hooks/useFuaRequests';
17
- import { ClaimManagementHeader } from './case-management-header';
24
+ import { FuaDateRangePicker } from './fua-date-range-picker.component';
18
25
  import styles from './fua-request-table.scss';
19
26
 
20
- const FuaRequestTable: React.FC = () => {
21
- const { data, isLoading, error } = useFuaRequests();
22
- const [expandedRowIndex, setExpandedRowIndex] = useState<number | null>(null);
27
+ interface FuaRequestTableProps {
28
+ statusFilter?: string;
29
+ }
30
+
31
+ const FuaRequestTable: React.FC<FuaRequestTableProps> = ({ statusFilter = 'all' }) => {
23
32
  const { t } = useTranslation();
24
33
 
25
- const toggleExpand = (index: number) => {
26
- setExpandedRowIndex(expandedRowIndex === index ? null : index);
27
- };
34
+ // Use the refactored hook with status filtering
35
+ const { fuaOrders, isLoading, isError } = useFuaRequests({
36
+ status: statusFilter !== 'all' ? statusFilter : null,
37
+ excludeCanceled: true,
38
+ });
39
+
40
+ const [searchString, setSearchString] = useState('');
41
+
42
+ // Apply search filter only (status filtering is now done by the hook)
43
+ const filteredData = useMemo(() => {
44
+ if (!fuaOrders) return [];
45
+
46
+ let filtered = fuaOrders;
28
47
 
29
- const renderJsonAsTable = (obj: any): JSX.Element => {
30
- if (typeof obj !== 'object' || obj === null) {
31
- return <span>{String(obj)}</span>;
48
+ // Apply search filter
49
+ if (searchString) {
50
+ const search = searchString.toLowerCase();
51
+ filtered = filtered.filter(req =>
52
+ req.name?.toLowerCase().includes(search) ||
53
+ req.uuid?.toLowerCase().includes(search) ||
54
+ req.fuaEstado?.nombre?.toLowerCase().includes(search)
55
+ );
32
56
  }
33
57
 
34
- return (
35
- <table className={styles.jsonTable}>
36
- <tbody>
37
- {Object.entries(obj).map(([key, value], idx) => (
38
- <tr key={idx} className={styles.jsonRow}>
39
- <td className={styles.jsonKey}>{key}</td>
40
- <td className={styles.jsonValue}>
41
- {typeof value === 'object' ? renderJsonAsTable(value) : String(value)}
42
- </td>
43
- </tr>
44
- ))}
45
- </tbody>
46
- </table>
47
- );
48
- };
58
+ return filtered;
59
+ }, [fuaOrders, searchString]);
60
+
61
+ const pageSizes = [10, 20, 30, 40, 50];
62
+ const [currentPageSize, setPageSize] = useState(10);
63
+ const { results, goTo, currentPage } = usePagination(filteredData ?? [], currentPageSize);
49
64
 
50
- if (isLoading) return <div>Cargando datos...</div>;
51
- if (error) return <div>Error: {error.message}</div>;
65
+ const handleViewFua = (fuaId: string) => {
66
+ launchWorkspace('fua-viewer-workspace', {
67
+ fuaId,
68
+ });
69
+ };
52
70
 
53
71
  const headers = [
54
- { key: 'name', header: 'Nombre del FUA' },
55
- { key: 'estado', header: 'Estado' },
56
- { key: 'uuid', header: 'UUID del FUA' },
57
- { key: 'visitUuid', header: 'UUID de la Visita' },
58
- { key: 'fechaCreacion', header: 'Fecha de Creación' },
59
- { key: 'fechaActualizacion', header: 'Fecha de Actualización' },
60
- { key: 'payload', header: 'Payload' },
72
+ { key: 'name', header: t('fuaName', 'Nombre del FUA') },
73
+ { key: 'estado', header: t('status', 'Estado') },
74
+ { key: 'uuid', header: t('fuaUuid', 'UUID del FUA') },
75
+ { key: 'visitUuid', header: t('visitUuid', 'UUID de la Visita') },
76
+ { key: 'fechaCreacion', header: t('creationDate', 'Fecha de Creación') },
77
+ { key: 'fechaActualizacion', header: t('updateDate', 'Fecha de Actualización') },
78
+ { key: 'actions', header: t('actions', 'Acciones') },
61
79
  ];
62
80
 
63
- const rows =
64
- data?.map((request: any, index: number) => ({
65
- id: String(index),
66
- name: request.name || 'N/A',
67
- estado: request.fuaEstado?.nombre || 'N/A',
68
- uuid: request.uuid,
69
- visitUuid: request.visitUuid || 'N/A',
70
- fechaCreacion: new Date(request.fechaCreacion).toLocaleString(),
71
- fechaActualizacion: new Date(request.fechaActualizacion).toLocaleString(),
72
- payload: request.payload,
73
- })) ?? [];
81
+ const rows = results?.map((request: any, index: number) => ({
82
+ id: String(index),
83
+ name: request.name || 'N/A',
84
+ estado: request.fuaEstado?.nombre || 'N/A',
85
+ uuid: request.uuid,
86
+ visitUuid: request.visitUuid || 'N/A',
87
+ fechaCreacion: formatDate(new Date(request.fechaCreacion), { mode: 'standard' }),
88
+ fechaActualizacion: formatDate(new Date(request.fechaActualizacion), { mode: 'standard' }),
89
+ actions: request.uuid,
90
+ })) ?? [];
91
+
92
+ if (isLoading) {
93
+ return <DataTableSkeleton role="progressbar" showHeader={false} showToolbar={false} />;
94
+ }
74
95
 
75
96
  return (
76
- <div className="omrs-main-content">
77
- <ClaimManagementHeader title={t('fuaRequests', 'Solicitudes FUA')} />
78
- <TableContainer>
79
- <DataTable rows={rows} headers={headers} isSortable={false} size="sm">
80
- {({ rows, headers, getHeaderProps, getRowProps }) => (
81
- <Table>
97
+ <div className={styles.tableContainer}>
98
+ <DataTable rows={rows} headers={headers} isSortable useZebraStyles size="sm">
99
+ {({ rows, headers, getHeaderProps, getTableProps, getRowProps }) => (
100
+ <TableContainer className={styles.tableContainer}>
101
+ <TableToolbar>
102
+ <TableToolbarContent className={styles.toolbarContent}>
103
+ <Layer className={styles.toolbarItem}>
104
+ <FuaDateRangePicker />
105
+ </Layer>
106
+ <Layer className={styles.toolbarItem}>
107
+ <TableToolbarSearch
108
+ expanded
109
+ onChange={(e) => {
110
+ if (typeof e === 'string') {
111
+ setSearchString(e);
112
+ } else {
113
+ setSearchString(e.target.value);
114
+ }
115
+ }}
116
+ placeholder={t('searchThisList', 'Buscar en esta lista')}
117
+ size="sm"
118
+ />
119
+ </Layer>
120
+ </TableToolbarContent>
121
+ </TableToolbar>
122
+ <Table {...getTableProps()} className={styles.table}>
82
123
  <TableHead>
83
124
  <TableRow>
84
- <TableExpandHeader />
85
125
  {headers.map((header) => (
86
126
  <TableHeader
87
127
  key={header.key}
88
128
  {...getHeaderProps({ header })}
89
- className={`${styles.productiveHeading01} ${styles.text02}`}>
129
+ className={styles.tableHeader}
130
+ >
90
131
  {header.header}
91
132
  </TableHeader>
92
133
  ))}
93
134
  </TableRow>
94
135
  </TableHead>
95
136
  <TableBody>
96
- {rows.map((row, index) => (
97
- <React.Fragment key={row.id}>
98
- <TableExpandRow
99
- {...getRowProps({ row })}
100
- onExpand={() => toggleExpand(index)}
101
- isExpanded={expandedRowIndex === index}>
102
- {row.cells.map((cell) => {
103
- if (cell.info.header === 'payload') {
104
- return (
105
- <TableCell key={cell.id} className={styles.payloadCell}>
106
- <button
107
- className={styles.payloadButton}
108
- onClick={(e) => {
109
- e.stopPropagation();
110
- toggleExpand(index);
111
- }}>
112
- {expandedRowIndex === index ? 'Ocultar payload' : 'Ver payload'}
113
- </button>
114
- </TableCell>
115
- );
116
- }
117
- return <TableCell key={cell.id}>{cell.value}</TableCell>;
118
- })}
119
- </TableExpandRow>
120
- {expandedRowIndex === index && (
121
- <TableExpandedRow colSpan={headers.length + 1}>
122
- <div className={styles.payloadExpandedContent}>
123
- {(() => {
124
- const payload = data?.[index]?.payload;
125
- if (!payload) return <div>No hay datos de payload</div>;
126
- try {
127
- const parsed = typeof payload === 'string' ? JSON.parse(payload) : payload;
128
- return renderJsonAsTable(parsed);
129
- } catch (err) {
130
- return <div>Payload inválido o no es JSON</div>;
131
- }
132
- })()}
133
- </div>
134
- </TableExpandedRow>
135
- )}
136
- </React.Fragment>
137
+ {rows.map((row) => (
138
+ <TableRow key={row.id} {...getRowProps({ row })}>
139
+ {row.cells.map((cell) => (
140
+ <TableCell key={cell.id} className={styles.tableCell}>
141
+ {cell.info.header === 'actions' ? (
142
+ <Button
143
+ kind="ghost"
144
+ size="sm"
145
+ renderIcon={View}
146
+ iconDescription={t('viewFua', 'Ver FUA')}
147
+ onClick={() => handleViewFua(cell.value)}
148
+ >
149
+ {t('view', 'Ver')}
150
+ </Button>
151
+ ) : (
152
+ cell.value
153
+ )}
154
+ </TableCell>
155
+ ))}
156
+ </TableRow>
137
157
  ))}
138
158
  </TableBody>
139
159
  </Table>
140
- )}
141
- </DataTable>
142
- </TableContainer>
160
+ {rows.length === 0 ? (
161
+ <div className={styles.tileContainer}>
162
+ <Tile className={styles.tile}>
163
+ <div className={styles.tileContent}>
164
+ <p className={styles.content}>{t('noFuaRequestsFound', 'No se encontraron solicitudes FUA')}</p>
165
+ <p className={styles.emptyStateHelperText}>
166
+ {t('checkFilters', 'Por favor revisa los filtros de arriba e intenta de nuevo')}
167
+ </p>
168
+ </div>
169
+ </Tile>
170
+ </div>
171
+ ) : null}
172
+ </TableContainer>
173
+ )}
174
+ </DataTable>
175
+ {filteredData.length > 0 && (
176
+ <Pagination
177
+ page={currentPage}
178
+ pageSize={currentPageSize}
179
+ pageSizes={pageSizes}
180
+ totalItems={filteredData.length}
181
+ onChange={({ page, pageSize }) => {
182
+ if (pageSize !== currentPageSize) {
183
+ setPageSize(pageSize);
184
+ }
185
+ goTo(page);
186
+ }}
187
+ className={styles.pagination}
188
+ />
189
+ )}
143
190
  </div>
144
191
  );
145
192
  };
@@ -0,0 +1,25 @@
1
+ import React, { useState } from 'react';
2
+ import dayjs from 'dayjs';
3
+ import { useTranslation } from 'react-i18next';
4
+ import { useDefineAppContext } from '@openmrs/esm-framework';
5
+ import { type DateFilterContext } from './types';
6
+ import FuaOrdersTabs from './fua-tabs/fua-tabs.component';
7
+ import FuaSummaryTiles from './fua-tiles/fua-summary-tiles.component';
8
+ import { FuaHeader } from './fua/fua-header';
9
+ import styles from './fua-dashboard.scss';
10
+
11
+ const FuaDashboard: React.FC = () => {
12
+ const { t } = useTranslation();
13
+ const [dateRange, setDateRange] = useState<Date[]>([dayjs().startOf('day').toDate(), new Date()]);
14
+ useDefineAppContext<DateFilterContext>('fua-date-filter', { dateRange, setDateRange });
15
+
16
+ return (
17
+ <div className={styles.dashboard}>
18
+ <FuaHeader title={t('fuaRequests', 'Solicitudes de Formato Único de Atención')} />
19
+ <FuaSummaryTiles />
20
+ <FuaOrdersTabs />
21
+ </div>
22
+ );
23
+ };
24
+
25
+ export default FuaDashboard;
@@ -0,0 +1,35 @@
1
+ @use '@carbon/styles/scss/spacing';
2
+ @use '@carbon/styles/scss/type';
3
+
4
+ .dashboard {
5
+ background-color: var(--cds-layer-01);
6
+ min-height: 100vh;
7
+ }
8
+
9
+ .headerContainer {
10
+ background-color: var(--cds-layer-01);
11
+ padding: spacing.$spacing-05;
12
+ border-bottom: 1px solid var(--cds-border-subtle-01);
13
+ }
14
+
15
+ .headerContent {
16
+ display: flex;
17
+ align-items: center;
18
+ gap: spacing.$spacing-04;
19
+ }
20
+
21
+ .headerIcon {
22
+ color: var(--cds-icon-primary);
23
+ }
24
+
25
+ .headerTitle {
26
+ @include type.type-style('heading-compact-01');
27
+ margin: 0;
28
+ color: var(--cds-text-secondary);
29
+ }
30
+
31
+ .headerSubtitle {
32
+ @include type.type-style('heading-03');
33
+ margin: 0;
34
+ color: var(--cds-text-primary);
35
+ }
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import FuaRequestTable from '../../fua/fuaRequestTable';
3
+
4
+ const AllFuaRequestsTable: React.FC = () => {
5
+ return <FuaRequestTable statusFilter="all" />;
6
+ };
7
+
8
+ export default AllFuaRequestsTable;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import FuaRequestTable from '../../fua/fuaRequestTable';
3
+
4
+ const CompletedFuaRequestsTable: React.FC = () => {
5
+ return <FuaRequestTable statusFilter="completed" />;
6
+ };
7
+
8
+ export default CompletedFuaRequestsTable;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import FuaRequestTable from '../../fua/fuaRequestTable';
3
+
4
+ const DeclinedFuaRequestsTable: React.FC = () => {
5
+ return <FuaRequestTable statusFilter="declined" />;
6
+ };
7
+
8
+ export default DeclinedFuaRequestsTable;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import FuaRequestTable from '../../fua/fuaRequestTable';
3
+
4
+ const InProgressFuaRequestsTable: React.FC = () => {
5
+ return <FuaRequestTable statusFilter="in-progress" />;
6
+ };
7
+
8
+ export default InProgressFuaRequestsTable;