@imj_media/tareas 1.5.50 → 1.5.52
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.
- package/dist/src/components/templates/CampaniaAlertasTableColumn.d.ts +24 -0
- package/dist/src/components/templates/progress-modal/ProgressModal.d.ts +21 -0
- package/dist/src/components/templates/progress-modal/api/fetchListadoProgreso.d.ts +18 -0
- package/dist/src/components/templates/progress-modal/api/listadoProgreso.types.d.ts +63 -0
- package/dist/src/components/templates/progress-modal/components/cells/ResponsablesStackWithPopups.d.ts +9 -0
- package/dist/src/components/templates/progress-modal/components/filters/ListadoProgresoFilterDropdown.d.ts +23 -0
- package/dist/src/components/templates/progress-modal/components/layout/ProgressPhaseLayout.d.ts +3 -0
- package/dist/src/components/templates/progress-modal/components/layout/index.d.ts +2 -0
- package/dist/src/components/templates/progress-modal/components/sections/FiltersBarSection.d.ts +23 -0
- package/dist/src/components/templates/progress-modal/components/sections/TasksChartAccordionSection.d.ts +12 -0
- package/dist/src/components/templates/progress-modal/components/sections/TasksTablePlaceholderSection.d.ts +13 -0
- package/dist/src/components/templates/progress-modal/components/sections/TopBarSection.d.ts +7 -0
- package/dist/src/components/templates/progress-modal/components/sections/index.d.ts +4 -0
- package/dist/src/components/templates/progress-modal/config/estadoTareaProgreso.config.d.ts +106 -0
- package/dist/src/components/templates/progress-modal/hooks/useListadoProgreso.d.ts +10 -0
- package/dist/src/components/templates/progress-modal/types/progressPhaseUi.types.d.ts +34 -0
- package/dist/src/components/templates/progress-modal/utils/listadoProgresoClientView.d.ts +19 -0
- package/dist/src/components/templates/progress-modal/utils/listadoProgresoFilters.d.ts +20 -0
- package/dist/src/components/templates/progress-modal/utils/listadoProgresoTable.mapper.d.ts +25 -0
- package/dist/src/components/templates/progress-modal/utils/listadoTextNormalize.d.ts +6 -0
- package/dist/src/modules/teams/ui/atoms/TeamModalHeader.d.ts +1 -1
- package/dist/src/modules/templates/hooks/filters/useGetInputFiltersByPath.d.ts +7 -7
- package/dist/src/modules/templates/hooks/useBuildTemplateFields.d.ts +1 -1
- package/dist/src/modules/templates/hooks/useCopyPaste.d.ts +1 -1
- package/dist/src/modules/templates/infraestructure/interfaces/filter.types.d.ts +1 -1
- package/dist/src/modules/templates/utils/typeGuards.d.ts +1 -1
- package/dist/tareas.cjs +20 -20
- package/dist/tareas.css +1 -1
- package/dist/tareas.es.js +6506 -5723
- package/package.json +4 -3
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Forma de `alertas` que viene en cada fila del listado (API / normalización). */
|
|
2
|
+
export type CampaniaAlertasBackend = {
|
|
3
|
+
pausas: number;
|
|
4
|
+
atrasos: number;
|
|
5
|
+
vencidos: number;
|
|
6
|
+
};
|
|
7
|
+
export type CampaniaAlertVariant = 'sin-alertas' | 'atrasos' | 'pausas' | 'vencidos';
|
|
8
|
+
export type CampaniaAlertTag = {
|
|
9
|
+
label: string;
|
|
10
|
+
color: 'info' | 'danger' | 'warning' | 'gray';
|
|
11
|
+
variant: CampaniaAlertVariant;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Transforma conteos del backend en hasta dos `Tag` con `variant` para que la celda decida icono/color sin inspeccionar el texto.
|
|
15
|
+
*/
|
|
16
|
+
export declare function buildCampaniaAlertTags(alertas?: CampaniaAlertasBackend): CampaniaAlertTag[];
|
|
17
|
+
export interface CampaniaAlertasTagsProps {
|
|
18
|
+
tags: CampaniaAlertTag[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Celda: un `Tag` por chip, icono solo en **atrasos** (danger).
|
|
22
|
+
*/
|
|
23
|
+
declare const CampaniaAlertasTags: ({ tags }: CampaniaAlertasTagsProps) => import("react/jsx-runtime").JSX.Element;
|
|
24
|
+
export default CampaniaAlertasTags;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
interface ProgressModalProps {
|
|
2
|
+
isOpen: boolean;
|
|
3
|
+
/** `proyecto_id` del endpoint (mismo id que usa el kanban al abrir la campaña). */
|
|
4
|
+
proyectoId: number;
|
|
5
|
+
campaignName: string;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Modal de progreso por campaña: tabs Preventa/Venta
|
|
10
|
+
* cuerpo con `ProgressPhaseLayout` (tabla + gráfica + filtros).
|
|
11
|
+
*
|
|
12
|
+
* Filtros (medios → `types_media`, plazas → `locations`, estados → `status`):
|
|
13
|
+
* - Usamos una respuesta base por fase (`listadoCatalogo`) y aplicamos filtros de fila en cliente.
|
|
14
|
+
* - Esto evita inconsistencias detectadas en backend al combinar filtros (p. ej. campos mutados por `status`)
|
|
15
|
+
* y garantiza que tabla + gráfica siempre usen exactamente el mismo universo filtrado.
|
|
16
|
+
*
|
|
17
|
+
* El cuerpo del modal recibe en `ProgressPhaseLayout` objetos `search`, `listado` y `filters` (tipados en
|
|
18
|
+
* `types/progressPhaseUi.types.ts`) para no arrastrar decenas de props sueltas.
|
|
19
|
+
*/
|
|
20
|
+
declare const ProgressModal: ({ isOpen, proyectoId, campaignName, onClose }: ProgressModalProps) => import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
export default ProgressModal;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { AxiosInstance } from 'axios';
|
|
2
|
+
import { ListadoProgresoQueryParams, ListadoProgresoResponse, ListadoProgresoWireResponse } from './listadoProgreso.types';
|
|
3
|
+
/** Ruta que en tasksdev responde 200 (alias del doc). */
|
|
4
|
+
export declare const LISTADO_PROGRESO_PATH_DEFAULT = "/api/listado-progreso";
|
|
5
|
+
/** Ruta documentada como principal; en algunos entornos puede devolver 500 o no existir. */
|
|
6
|
+
export declare const LISTADO_PROGRESO_PATH_FALLBACK = "/api/proyectos/listado-progreso";
|
|
7
|
+
/**
|
|
8
|
+
* Normaliza params para evitar 500 por tipos raros (doc: proyecto_id numérico, fase en minúsculas).
|
|
9
|
+
* Solo incluye opcionales si tienen valor (evita mandar undefined/null en query).
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildListadoProgresoRequestParams(raw: ListadoProgresoQueryParams): Record<string, string | number | string[]>;
|
|
12
|
+
/** Unifica `grafico` / `graficos` y `data` para el resto de la app. */
|
|
13
|
+
export declare function normalizeListadoProgresoResponse(wire: ListadoProgresoWireResponse): ListadoProgresoResponse;
|
|
14
|
+
/**
|
|
15
|
+
* GET listado-progreso. Usa `tasks_api` (Bearer + qs.encodeValuesOnly en el cliente).
|
|
16
|
+
* Intenta primero `/api/listado-progreso`; si 404, `/api/proyectos/listado-progreso`.
|
|
17
|
+
*/
|
|
18
|
+
export declare function fetchListadoProgreso(tasks_api: AxiosInstance, rawParams: ListadoProgresoQueryParams): Promise<ListadoProgresoResponse>;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { EstadoTareaProgreso } from '../config/estadoTareaProgreso.config';
|
|
2
|
+
export type FaseProgreso = 'preventa' | 'venta';
|
|
3
|
+
export type { EstadoTareaProgreso };
|
|
4
|
+
export interface ImagenOBPFormat {
|
|
5
|
+
url?: string;
|
|
6
|
+
ext?: string;
|
|
7
|
+
mime?: string;
|
|
8
|
+
width?: number;
|
|
9
|
+
height?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface ImagenOBP {
|
|
12
|
+
id?: number;
|
|
13
|
+
name?: string;
|
|
14
|
+
url?: string;
|
|
15
|
+
formats?: {
|
|
16
|
+
thumbnail?: ImagenOBPFormat;
|
|
17
|
+
small?: ImagenOBPFormat;
|
|
18
|
+
medium?: ImagenOBPFormat;
|
|
19
|
+
large?: ImagenOBPFormat;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export interface ResponsableProgreso {
|
|
23
|
+
id: number | null;
|
|
24
|
+
nombre: string;
|
|
25
|
+
email: string | null;
|
|
26
|
+
role: string | null;
|
|
27
|
+
imagen: ImagenOBP | null;
|
|
28
|
+
}
|
|
29
|
+
export interface ListadoProgresoRow {
|
|
30
|
+
id: number;
|
|
31
|
+
responsables: ResponsableProgreso[];
|
|
32
|
+
tarea: string;
|
|
33
|
+
categoria: string;
|
|
34
|
+
estado: EstadoTareaProgreso;
|
|
35
|
+
nota: string;
|
|
36
|
+
clave: string;
|
|
37
|
+
tipo_medio: string;
|
|
38
|
+
ubicacion: string;
|
|
39
|
+
}
|
|
40
|
+
export interface GraficoSerieProgreso {
|
|
41
|
+
name: string;
|
|
42
|
+
data: number[];
|
|
43
|
+
}
|
|
44
|
+
export interface ListadoProgresoResponse {
|
|
45
|
+
data: ListadoProgresoRow[];
|
|
46
|
+
/** Series para barra apilada; el API en algunos entornos envía `graficos` en lugar de `grafico`. */
|
|
47
|
+
grafico: GraficoSerieProgreso[];
|
|
48
|
+
}
|
|
49
|
+
/** Payload HTTP antes de normalizar (doc vs respuesta real). */
|
|
50
|
+
export interface ListadoProgresoWireResponse {
|
|
51
|
+
data?: ListadoProgresoRow[] | null;
|
|
52
|
+
grafico?: GraficoSerieProgreso[];
|
|
53
|
+
graficos?: GraficoSerieProgreso[];
|
|
54
|
+
}
|
|
55
|
+
export interface ListadoProgresoQueryParams {
|
|
56
|
+
proyecto_id: number;
|
|
57
|
+
fase: FaseProgreso;
|
|
58
|
+
status?: string[];
|
|
59
|
+
types_media?: string[];
|
|
60
|
+
locations?: string[];
|
|
61
|
+
search?: string;
|
|
62
|
+
blocked_only?: boolean | 'true' | 'false';
|
|
63
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ResponsableProgreso } from '../../api/listadoProgreso.types';
|
|
2
|
+
export interface ResponsablesStackWithPopupsProps {
|
|
3
|
+
responsables: ResponsableProgreso[] | undefined | null;
|
|
4
|
+
getImageOBP: (path: string) => string;
|
|
5
|
+
/** Id de fila para `popupId` únicos (evita colisiones entre filas en `closeOtherPopups`). */
|
|
6
|
+
rowId: string | number;
|
|
7
|
+
}
|
|
8
|
+
declare const ResponsablesStackWithPopups: ({ responsables, getImageOBP, rowId, }: ResponsablesStackWithPopupsProps) => import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export default ResponsablesStackWithPopups;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { DropdownOption } from '@imj_media/ui';
|
|
2
|
+
/**
|
|
3
|
+
* Creamos dicho archivo para evitar repetir el bloque 3 veces y asi centralizamos el patrón del dropdown en un solo punto y evita repetir codigo.
|
|
4
|
+
*/
|
|
5
|
+
export interface ListadoProgresoFilterDropdownProps {
|
|
6
|
+
options: DropdownOption[];
|
|
7
|
+
selected: string[];
|
|
8
|
+
onChange: (next: string[]) => void;
|
|
9
|
+
/** Placeholder del campo cerrado cuando `selected` está vacío (equivale a «sin filtro» en `ProgressModal`). */
|
|
10
|
+
emptyPlaceholder: string;
|
|
11
|
+
/** Texto e id de la fila de cabecera del panel (selección global). */
|
|
12
|
+
header: {
|
|
13
|
+
id: string;
|
|
14
|
+
label: string;
|
|
15
|
+
};
|
|
16
|
+
/** Título del popover del chip +n si los tags no caben en una línea. */
|
|
17
|
+
tagsOverflowPopoverTitle: string;
|
|
18
|
+
/** `true` solo en plazas: buscador arriba en el panel. */
|
|
19
|
+
panelSearch: boolean;
|
|
20
|
+
/** Placeholder del buscador del panel (solo si `panelSearch`). */
|
|
21
|
+
panelSearchPlaceholder?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function ListadoProgresoFilterDropdown({ options, selected, onChange, emptyPlaceholder, header, tagsOverflowPopoverTitle, panelSearch, panelSearchPlaceholder, }: ListadoProgresoFilterDropdownProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/src/components/templates/progress-modal/components/sections/FiltersBarSection.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { DropdownOption } from '@imj_media/ui';
|
|
2
|
+
interface FiltersBarSectionProps {
|
|
3
|
+
mediosOptions: DropdownOption[];
|
|
4
|
+
plazasOptions: DropdownOption[];
|
|
5
|
+
estadosOptions: DropdownOption[];
|
|
6
|
+
selectedMedios: string[];
|
|
7
|
+
selectedPlazas: string[];
|
|
8
|
+
selectedEstados: string[];
|
|
9
|
+
onlyDelayed: boolean;
|
|
10
|
+
onChangeMedios: (next: string[]) => void;
|
|
11
|
+
onChangePlazas: (next: string[]) => void;
|
|
12
|
+
onChangeEstados: (next: string[]) => void;
|
|
13
|
+
onChangeOnlyDelayed: (next: boolean) => void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Filtros del modal de progreso (medios, plazas, estados).
|
|
17
|
+
*
|
|
18
|
+
* Sustituye el antiguo `listVariant="checkbox-item"` con fila sintética `__all__` y `onToggleChange` por el
|
|
19
|
+
* `Dropdown` multiselección con panel `search-multi-checkbox` del DS (misma API que las stories de plazas en UI).
|
|
20
|
+
* El estado sigue siendo arrays de strings en el padre: vacío ⇒ sin filtro en `ProgressModal` / `rowMatchesFilters`.
|
|
21
|
+
*/
|
|
22
|
+
declare const FiltersBarSection: ({ mediosOptions, plazasOptions, estadosOptions, selectedMedios, selectedPlazas, selectedEstados, onlyDelayed, onChangeMedios, onChangePlazas, onChangeEstados, onChangeOnlyDelayed, }: FiltersBarSectionProps) => import("react/jsx-runtime").JSX.Element;
|
|
23
|
+
export default FiltersBarSection;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { UseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import { ListadoProgresoResponse } from '../../api/listadoProgreso.types';
|
|
3
|
+
interface TasksChartAccordionSectionProps {
|
|
4
|
+
id: string;
|
|
5
|
+
listadoProgreso: UseQueryResult<ListadoProgresoResponse, Error>;
|
|
6
|
+
/** Etiqueta activa para el eje Y (depende del tab Preventa/Venta). */
|
|
7
|
+
phaseLabel: string;
|
|
8
|
+
/** Misma fuente que la tabla: `grafico` recalculado en cliente cuando hay filtros de fila activos. */
|
|
9
|
+
listadoForUi: ListadoProgresoResponse | null;
|
|
10
|
+
}
|
|
11
|
+
declare const TasksChartAccordionSection: ({ id, listadoProgreso, phaseLabel, listadoForUi, }: TasksChartAccordionSectionProps) => import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export default TasksChartAccordionSection;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { UseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import { ListadoProgresoResponse } from '../../api/listadoProgreso.types';
|
|
3
|
+
export interface TasksTablePlaceholderSectionProps {
|
|
4
|
+
listadoProgreso: UseQueryResult<ListadoProgresoResponse, Error>;
|
|
5
|
+
/**
|
|
6
|
+
* Respuesta ya alineada con filtros (API + refuerzo en cliente). Si es null, se usan filas del query crudo.
|
|
7
|
+
*/
|
|
8
|
+
listadoForUi: ListadoProgresoResponse | null;
|
|
9
|
+
/** En fase Preventa se oculta la columna "Código / Ruta". */
|
|
10
|
+
hideClaveColumn?: boolean;
|
|
11
|
+
}
|
|
12
|
+
declare const TasksTablePlaceholderSection: ({ listadoProgreso, listadoForUi, hideClaveColumn, }: TasksTablePlaceholderSectionProps) => import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export default TasksTablePlaceholderSection;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
interface TopBarSectionProps {
|
|
2
|
+
campaignName: string;
|
|
3
|
+
searchValue: string;
|
|
4
|
+
onSearchChange: (next: string) => void;
|
|
5
|
+
}
|
|
6
|
+
declare const TopBarSection: ({ campaignName, searchValue, onSearchChange }: TopBarSectionProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default TopBarSection;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { default as TopBarSection } from './TopBarSection';
|
|
2
|
+
export { default as FiltersBarSection } from './FiltersBarSection';
|
|
3
|
+
export { default as TasksChartAccordionSection } from './TasksChartAccordionSection';
|
|
4
|
+
export { default as TasksTablePlaceholderSection } from './TasksTablePlaceholderSection';
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Define los estados que entiende el flujo (completada, progresada, pausada, etc.) y, para cada uno, todo lo que la UI necesita en un solo sitio:
|
|
3
|
+
* etiquetas en UI (tags, filtros) y leyenda/colores del gráfico ECharts.
|
|
4
|
+
*/
|
|
5
|
+
export type EstadoTareaProgreso = 'completada' | 'progresada' | 'pausada' | 'atrasada' | 'pendiente' | 'vencida';
|
|
6
|
+
export type ProgresoTagColor = 'accent' | 'gray' | 'success' | 'warning' | 'danger' | 'info' | 'disabled';
|
|
7
|
+
export declare const ESTADO_TAREA_PROGRESO_DEFS: readonly [{
|
|
8
|
+
readonly singular: "completada";
|
|
9
|
+
readonly serieApiName: "completadas";
|
|
10
|
+
readonly uiLabel: "Completada";
|
|
11
|
+
readonly chartLegendLabel: "Completadas";
|
|
12
|
+
readonly tagColor: "success";
|
|
13
|
+
readonly chartColorHex: "#22C55E";
|
|
14
|
+
}, {
|
|
15
|
+
readonly singular: "progresada";
|
|
16
|
+
readonly serieApiName: "progresadas";
|
|
17
|
+
readonly uiLabel: "En progreso";
|
|
18
|
+
readonly chartLegendLabel: "En progreso";
|
|
19
|
+
readonly tagColor: "accent";
|
|
20
|
+
readonly chartColorHex: "#3658C1";
|
|
21
|
+
}, {
|
|
22
|
+
readonly singular: "pausada";
|
|
23
|
+
readonly serieApiName: "pausadas";
|
|
24
|
+
readonly uiLabel: "Pausada";
|
|
25
|
+
readonly chartLegendLabel: "Pausadas";
|
|
26
|
+
readonly tagColor: "warning";
|
|
27
|
+
readonly chartColorHex: "#EAB308";
|
|
28
|
+
}, {
|
|
29
|
+
readonly singular: "atrasada";
|
|
30
|
+
readonly serieApiName: "atrasadas";
|
|
31
|
+
readonly uiLabel: "Atrasada";
|
|
32
|
+
readonly chartLegendLabel: "Atrasadas";
|
|
33
|
+
readonly tagColor: "danger";
|
|
34
|
+
readonly chartColorHex: "#EF4444";
|
|
35
|
+
}, {
|
|
36
|
+
readonly singular: "pendiente";
|
|
37
|
+
readonly serieApiName: "pendientes";
|
|
38
|
+
readonly uiLabel: "Pendiente";
|
|
39
|
+
readonly chartLegendLabel: "Pendientes";
|
|
40
|
+
readonly tagColor: "gray";
|
|
41
|
+
readonly chartColorHex: "#BABCBF";
|
|
42
|
+
}, {
|
|
43
|
+
readonly singular: "vencida";
|
|
44
|
+
readonly serieApiName: "vencidas";
|
|
45
|
+
readonly uiLabel: "Vencida";
|
|
46
|
+
readonly chartLegendLabel: "Vencidas";
|
|
47
|
+
readonly tagColor: "info";
|
|
48
|
+
readonly chartColorHex: "#0592AA";
|
|
49
|
+
}];
|
|
50
|
+
export type GraficoSerieNombreApi = (typeof ESTADO_TAREA_PROGRESO_DEFS)[number]['serieApiName'];
|
|
51
|
+
/** Orden fijo de segmentos en la barra apilada (claves que envía / espera el API en `grafico`). */
|
|
52
|
+
export declare const SERIE_API_NAMES_ORDER: GraficoSerieNombreApi[];
|
|
53
|
+
/** Estado de fila que interpreta “Solo bloqueadas” en filtros del modal. */
|
|
54
|
+
export declare const ESTADO_SINGULAR_BLOQUEADA: EstadoTareaProgreso;
|
|
55
|
+
export declare function getEstadoDefBySingular(estadoTrimmedLower: string): {
|
|
56
|
+
readonly singular: "completada";
|
|
57
|
+
readonly serieApiName: "completadas";
|
|
58
|
+
readonly uiLabel: "Completada";
|
|
59
|
+
readonly chartLegendLabel: "Completadas";
|
|
60
|
+
readonly tagColor: "success";
|
|
61
|
+
readonly chartColorHex: "#22C55E";
|
|
62
|
+
} | {
|
|
63
|
+
readonly singular: "progresada";
|
|
64
|
+
readonly serieApiName: "progresadas";
|
|
65
|
+
readonly uiLabel: "En progreso";
|
|
66
|
+
readonly chartLegendLabel: "En progreso";
|
|
67
|
+
readonly tagColor: "accent";
|
|
68
|
+
readonly chartColorHex: "#3658C1";
|
|
69
|
+
} | {
|
|
70
|
+
readonly singular: "pausada";
|
|
71
|
+
readonly serieApiName: "pausadas";
|
|
72
|
+
readonly uiLabel: "Pausada";
|
|
73
|
+
readonly chartLegendLabel: "Pausadas";
|
|
74
|
+
readonly tagColor: "warning";
|
|
75
|
+
readonly chartColorHex: "#EAB308";
|
|
76
|
+
} | {
|
|
77
|
+
readonly singular: "atrasada";
|
|
78
|
+
readonly serieApiName: "atrasadas";
|
|
79
|
+
readonly uiLabel: "Atrasada";
|
|
80
|
+
readonly chartLegendLabel: "Atrasadas";
|
|
81
|
+
readonly tagColor: "danger";
|
|
82
|
+
readonly chartColorHex: "#EF4444";
|
|
83
|
+
} | {
|
|
84
|
+
readonly singular: "pendiente";
|
|
85
|
+
readonly serieApiName: "pendientes";
|
|
86
|
+
readonly uiLabel: "Pendiente";
|
|
87
|
+
readonly chartLegendLabel: "Pendientes";
|
|
88
|
+
readonly tagColor: "gray";
|
|
89
|
+
readonly chartColorHex: "#BABCBF";
|
|
90
|
+
} | {
|
|
91
|
+
readonly singular: "vencida";
|
|
92
|
+
readonly serieApiName: "vencidas";
|
|
93
|
+
readonly uiLabel: "Vencida";
|
|
94
|
+
readonly chartLegendLabel: "Vencidas";
|
|
95
|
+
readonly tagColor: "info";
|
|
96
|
+
readonly chartColorHex: "#0592AA";
|
|
97
|
+
};
|
|
98
|
+
export declare function rowEstadoToSerieApiName(estado: string): GraficoSerieNombreApi | undefined;
|
|
99
|
+
/** Etiqueta para dropdown de filtro cuando el valor no está en el catálogo canónico. */
|
|
100
|
+
export declare function uiLabelForEstadoFilterValue(valueLower: string): string;
|
|
101
|
+
export type EstadoTagPayload = {
|
|
102
|
+
label: string;
|
|
103
|
+
color: ProgresoTagColor;
|
|
104
|
+
};
|
|
105
|
+
/** Un solo tag: contrato de `type: 'tags'` en la tabla del modal. */
|
|
106
|
+
export declare function mapEstadoToTagPayload(estado: string | null | undefined, emptyDisplay: string): EstadoTagPayload[];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { UseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import { FaseProgreso, ListadoProgresoQueryParams, ListadoProgresoResponse } from '../api/listadoProgreso.types';
|
|
3
|
+
export interface UseListadoProgresoOptions {
|
|
4
|
+
proyectoId: number;
|
|
5
|
+
fase: FaseProgreso;
|
|
6
|
+
/** Solo consultar con el modal abierto (evita requests innecesarios). */
|
|
7
|
+
enabled: boolean;
|
|
8
|
+
filters?: Omit<ListadoProgresoQueryParams, 'proyecto_id' | 'fase'>;
|
|
9
|
+
}
|
|
10
|
+
export declare function useListadoProgreso({ proyectoId, fase, enabled, filters, }: UseListadoProgresoOptions): UseQueryResult<ListadoProgresoResponse, Error>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { DropdownOption } from '@imj_media/ui';
|
|
2
|
+
import { UseQueryResult } from '@tanstack/react-query';
|
|
3
|
+
import { FaseProgreso, ListadoProgresoResponse } from '../api/listadoProgreso.types';
|
|
4
|
+
/** Estado y handler del input de búsqueda en la top bar (valor en vivo; el debounce vive en el Modal). */
|
|
5
|
+
export interface ProgressPhaseSearchBlock {
|
|
6
|
+
value: string;
|
|
7
|
+
onChange: (next: string) => void;
|
|
8
|
+
}
|
|
9
|
+
/** Catálogo por fase (React Query) y vista ya filtrada en cliente para tabla + acordeón del gráfico. */
|
|
10
|
+
export interface ProgressPhaseListadoBlock {
|
|
11
|
+
query: UseQueryResult<ListadoProgresoResponse, Error>;
|
|
12
|
+
dataForUi: ListadoProgresoResponse | null;
|
|
13
|
+
}
|
|
14
|
+
/** Opciones de dropdowns derivadas del catálogo + selección actual + callbacks hacia el estado del Modal. */
|
|
15
|
+
export interface ProgressPhaseFiltersBlock {
|
|
16
|
+
mediosOptions: DropdownOption[];
|
|
17
|
+
plazasOptions: DropdownOption[];
|
|
18
|
+
estadosOptions: DropdownOption[];
|
|
19
|
+
selectedMedios: string[];
|
|
20
|
+
selectedPlazas: string[];
|
|
21
|
+
selectedEstados: string[];
|
|
22
|
+
onlyDelayed: boolean;
|
|
23
|
+
onChangeMedios: (next: string[]) => void;
|
|
24
|
+
onChangePlazas: (next: string[]) => void;
|
|
25
|
+
onChangeEstados: (next: string[]) => void;
|
|
26
|
+
onChangeOnlyDelayed: (next: boolean) => void;
|
|
27
|
+
}
|
|
28
|
+
export interface ProgressPhaseLayoutProps {
|
|
29
|
+
campaignName: string;
|
|
30
|
+
phase: FaseProgreso;
|
|
31
|
+
search: ProgressPhaseSearchBlock;
|
|
32
|
+
listado: ProgressPhaseListadoBlock;
|
|
33
|
+
filters: ProgressPhaseFiltersBlock;
|
|
34
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { GraficoSerieProgreso, ListadoProgresoResponse, ListadoProgresoRow } from '../api/listadoProgreso.types';
|
|
2
|
+
/** Mismo criterio que enviamos al API (`locations` ya puede incluir `""` para “Sin ubicación”). */
|
|
3
|
+
export interface ListadoRowFilterPayload {
|
|
4
|
+
types_media?: string[];
|
|
5
|
+
locations?: string[];
|
|
6
|
+
status?: string[];
|
|
7
|
+
search?: string;
|
|
8
|
+
onlyDelayed?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Recalcula las series del gráfico a partir de las filas visibles (mismas claves que el API en `grafico`).
|
|
12
|
+
*/
|
|
13
|
+
export declare function buildGraficoSeriesFromRows(rows: ListadoProgresoRow[]): GraficoSerieProgreso[];
|
|
14
|
+
/**
|
|
15
|
+
* Aplica en cliente los mismos criterios que el modal manda al API. Evita filas “huérfanas”
|
|
16
|
+
* (p. ej. estado no pedido) y alinea la gráfica con la tabla. Si no hay filtros de fila, devuelve
|
|
17
|
+
* la respuesta original sin copiar.
|
|
18
|
+
*/
|
|
19
|
+
export declare function applyListadoClienteFilters(response: ListadoProgresoResponse, payload: ListadoRowFilterPayload): ListadoProgresoResponse;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { DropdownOption } from '@imj_media/ui';
|
|
2
|
+
import { ListadoProgresoRow } from '../api/listadoProgreso.types';
|
|
3
|
+
/**
|
|
4
|
+
* Deriva opciones de dropdown (medios/plazas/estados). Convierte selección de plazas a parámetro API.
|
|
5
|
+
*/
|
|
6
|
+
export declare const EMPTY_UBICACION_DROPDOWN_VALUE = "__sin_ubicacion__";
|
|
7
|
+
/**
|
|
8
|
+
* Traduce la selección del dropdown de plazas a lo que espera el query `locations` del endpoint.
|
|
9
|
+
* Las filas sin `ubicacion` en backend vienen como `""`; eso se representa en UI con `EMPTY_UBICACION_DROPDOWN_VALUE`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function plazasSelectionToLocationsParam(selectedPlazas: string[]): string[];
|
|
12
|
+
/**
|
|
13
|
+
* Opciones únicas para los tres filtros del modal (medios, plazas, estados), derivadas del listado base
|
|
14
|
+
* sin aplicar esos filtros. El panel `search-multi-checkbox` añade la fila «seleccionar todo» por su cuenta.
|
|
15
|
+
*/
|
|
16
|
+
export declare function deriveDropdownFilterOptions(rows: ListadoProgresoRow[]): {
|
|
17
|
+
medios: DropdownOption[];
|
|
18
|
+
plazas: DropdownOption[];
|
|
19
|
+
estados: DropdownOption[];
|
|
20
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ListadoProgresoRow, ResponsableProgreso } from '../api/listadoProgreso.types';
|
|
2
|
+
import { EstadoTagPayload } from '../config/estadoTareaProgreso.config';
|
|
3
|
+
export { LISTADO_PROGRESO_EMPTY_TEXT } from './listadoTextNormalize';
|
|
4
|
+
/** Misma heurística que `AvatarsCell`: solo tratar como imagen URLs absolutas válidas o data/blob. */
|
|
5
|
+
export declare function isImageSourceForAvatar(value?: string): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Nombre + `src` opcional + letras para `Avatar` tipo letter (hasta 3 caracteres, alineado con AvatarsCell).
|
|
8
|
+
* Usado por la columna de responsables con Popup (no usamos `type: 'avatars'` del DS).
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolveResponsableAvatarProps(r: ResponsableProgreso, getImageOBP: (path: string) => string): {
|
|
11
|
+
name: string;
|
|
12
|
+
src?: string;
|
|
13
|
+
letter: string;
|
|
14
|
+
};
|
|
15
|
+
/** Campos de texto de la fila ya normalizados para columnas `accessor` por clave. */
|
|
16
|
+
export declare function mapListadoRowTextFields(row: ListadoProgresoRow): {
|
|
17
|
+
tarea: string;
|
|
18
|
+
categoria: string;
|
|
19
|
+
nota: string;
|
|
20
|
+
clave: string;
|
|
21
|
+
tipo_medio: string;
|
|
22
|
+
ubicacion: string;
|
|
23
|
+
};
|
|
24
|
+
/** Un solo elemento: patrón para `type: 'tags'`. */
|
|
25
|
+
export declare function mapEstadoToTagsValue(estado: string | undefined | null): EstadoTagPayload[];
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Texto mostrado en celdas cuando el backend manda vacío o solo espacios. */
|
|
2
|
+
export declare const LISTADO_PROGRESO_EMPTY_TEXT = "-";
|
|
3
|
+
/** Para catálogos / filtros: sin texto útil → null (no opción en dropdown). */
|
|
4
|
+
export declare function trimListadoFieldToNull(value: string | null | undefined): string | null;
|
|
5
|
+
/** Para columnas de tabla: sin texto útil → guion de producto. */
|
|
6
|
+
export declare function trimListadoFieldToEmptyDisplay(value: string | null | undefined): string;
|
|
@@ -30,26 +30,26 @@
|
|
|
30
30
|
*/
|
|
31
31
|
export declare const useGetInputFiltersByPath: (currentPath: string) => {
|
|
32
32
|
inputFilters: ({
|
|
33
|
-
icon?: import('ui
|
|
33
|
+
icon?: import('@imj_media/ui').VisualSlotType;
|
|
34
34
|
label: string;
|
|
35
35
|
keyName?: string;
|
|
36
36
|
value?: string;
|
|
37
|
-
onValueChange?: (value: import('ui
|
|
38
|
-
options?: import('ui
|
|
37
|
+
onValueChange?: (value: import('@imj_media/ui').FilterChangeValue) => void;
|
|
38
|
+
options?: import('@imj_media/ui').DropdownOption[];
|
|
39
39
|
placeholder?: string;
|
|
40
40
|
clearText?: string;
|
|
41
|
-
type?: "date" | "
|
|
41
|
+
type?: "date" | "multiple" | "group" | "dropdown" | "input" | "textarea" | "dateRange";
|
|
42
42
|
title?: string;
|
|
43
43
|
} | {
|
|
44
44
|
options: any;
|
|
45
|
-
icon?: import('ui
|
|
45
|
+
icon?: import('@imj_media/ui').VisualSlotType;
|
|
46
46
|
label: string;
|
|
47
47
|
keyName?: string;
|
|
48
48
|
value?: string;
|
|
49
|
-
onValueChange?: (value: import('ui
|
|
49
|
+
onValueChange?: (value: import('@imj_media/ui').FilterChangeValue) => void;
|
|
50
50
|
placeholder?: string;
|
|
51
51
|
clearText?: string;
|
|
52
|
-
type?: "date" | "
|
|
52
|
+
type?: "date" | "multiple" | "group" | "dropdown" | "input" | "textarea" | "dateRange";
|
|
53
53
|
title?: string;
|
|
54
54
|
})[];
|
|
55
55
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FieldValues, UseFormSetValue } from 'react-hook-form';
|
|
2
|
-
import { DropdownOption } from 'ui
|
|
2
|
+
import { DropdownOption } from '@imj_media/ui';
|
|
3
3
|
import { ITemplateField } from '../infraestructure/interfaces/templates';
|
|
4
4
|
/**
|
|
5
5
|
* Hook personalizado para manejar el formulario de templates
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* @dependencies
|
|
22
22
|
* - React: useCallback para optimización de rendimiento
|
|
23
23
|
* - @xyflow/react: Gestión del canvas y nodos
|
|
24
|
-
* - ui
|
|
24
|
+
* - @imj_media/ui: Sistema de notificaciones toast
|
|
25
25
|
*
|
|
26
26
|
* @stores
|
|
27
27
|
* - useTemplateGridStore: Estado del clipboard y viewMode
|