@imj_media/tareas 1.6.0 → 1.6.2

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.
@@ -1,8 +1,10 @@
1
- declare const ActionsTaskList: ({ id, priority, difficulty, endDate, atraso }: {
1
+ declare const ActionsTaskList: ({ id, priority, difficulty, endDate, atraso, role, status, }: {
2
2
  id: number;
3
3
  priority: number;
4
4
  difficulty: any;
5
5
  endDate: any;
6
6
  atraso: any;
7
+ role?: string | null;
8
+ status: number;
7
9
  }) => import("react/jsx-runtime").JSX.Element;
8
10
  export default ActionsTaskList;
@@ -0,0 +1,10 @@
1
+ export interface DifficultyButtonProps {
2
+ difficulty: number | null | undefined;
3
+ id: number;
4
+ /** Show level title next to the icon (e.g. details drawer, same as `PriorityButton`). */
5
+ withLabel?: boolean;
6
+ /** When false, show read-only tooltip (same pattern as `PriorityButton`). */
7
+ canEdit?: boolean;
8
+ }
9
+ declare const DifficultyButton: ({ difficulty, id, withLabel, canEdit }: DifficultyButtonProps) => import("react/jsx-runtime").JSX.Element;
10
+ export default DifficultyButton;
@@ -2,6 +2,8 @@ interface IPriorityButtonProps {
2
2
  priority: number;
3
3
  id: number;
4
4
  withLabel?: boolean;
5
+ /** When false, show read-only tooltip (aligned with `ButtonAssignUsers` / `canEditTaskFields`). */
6
+ canEdit?: boolean;
5
7
  }
6
- declare const PriorityButton: ({ priority, id, withLabel }: IPriorityButtonProps) => import("react/jsx-runtime").JSX.Element;
8
+ declare const PriorityButton: ({ priority, id, withLabel, canEdit }: IPriorityButtonProps) => import("react/jsx-runtime").JSX.Element;
7
9
  export default PriorityButton;
@@ -50,8 +50,8 @@ export declare const ESTADO_TAREA_PROGRESO_DEFS: readonly [{
50
50
  export type GraficoSerieNombreApi = (typeof ESTADO_TAREA_PROGRESO_DEFS)[number]['serieApiName'];
51
51
  /** Orden fijo de segmentos en la barra apilada (claves que envía / espera el API en `grafico`). */
52
52
  export declare const SERIE_API_NAMES_ORDER: GraficoSerieNombreApi[];
53
- /** Estado de fila que interpreta “Solo atrasadas en filtros del modal. */
54
- export declare const ESTADO_SINGULAR_BLOQUEADA: EstadoTareaProgreso;
53
+ /** Singulares que el toggle de demora del modal incluye (misma regla en cliente). */
54
+ export declare const ESTADOS_TOGGLE_DEMORA_SET: ReadonlySet<string>;
55
55
  export declare function getEstadoDefBySingular(estadoTrimmedLower: string): {
56
56
  readonly singular: "completada";
57
57
  readonly serieApiName: "completadas";
@@ -1,5 +1,5 @@
1
1
  /** Misma rejilla que `TeamsGrid` — un solo origen para layout de carga y datos. */
2
- export declare const TEAMS_GRID_LAYOUT_CLASS = "tm-grid tm-w-full tm-grid-cols-1 tm-items-baseline tm-gap-x-8 tm-gap-y-8 md:tm-grid-cols-2 lg:tm-grid-cols-3 lg:tm-gap-x-8 xl:tm-grid-cols-4";
2
+ export declare const TEAMS_GRID_LAYOUT_CLASS = "tm-grid tm-w-full tm-grid-cols-1 tm-items-baseline tm-gap-x-12 tm-gap-y-12 md:tm-grid-cols-2 lg:tm-grid-cols-3 lg:tm-gap-x-8 xl:tm-grid-cols-4";
3
3
  export declare function ImagesThumbnailSkeleton(): import("react/jsx-runtime").JSX.Element;
4
4
  type TeamsGridSkeletonProps = {
5
5
  length?: number;
@@ -1,5 +1,28 @@
1
1
  import { generatePopulateStructure } from './populate.utils';
2
- import { TeamFilters } from '../infrastructure/interfaces/team';
2
+ import { MemberList, Team, TeamFilters } from '../infrastructure/interfaces/team';
3
+ /**
4
+ * Aplana hijos directos del primer raíz para la API (alta y edición).
5
+ *
6
+ * - El primer raíz se mantiene con su árbol anidado (no se mueve a otros hijos).
7
+ * - Cada hijo directo del principal se envía también como fila raíz hermana
8
+ * (`miembros: []`, `miembro_padre: null`, `esEncargado: false`), para quienes
9
+ * **aún no** tienen esa fila plana en `otherRoots` (mismo `idUser.id`).
10
+ * - Así, un colaborador nuevo bajo el principal (p. ej. `id: null`) aparece en raíz
11
+ * sin duplicar a Maria/Andre/Zeferino que ya vienen como hermanos desde el backend.
12
+ *
13
+ * No se fuerza encargado: se respeta `esEncargado` del primer raíz.
14
+ *
15
+ * @see POST /api/registrar-equipo-miembros
16
+ * @see PATCH /api/actualizar-equipo-miembros/:id
17
+ */
18
+ export declare function expandFirstRootDirectChildrenForTeamPayload(team: Team): Team;
19
+ /**
20
+ * Miembros raíz a mostrar en el modal de equipo: solo encargados (`esEncargado`) y,
21
+ * bajo ellos, el árbol que ya viene en `miembros`. Oculta hermanos planos del API
22
+ * que no son encargado. Si no hay ningún encargado en raíz (p. ej. alta nueva),
23
+ * se muestran todos los raíz para poder seguir editando.
24
+ */
25
+ export declare function getMembersForModalView(miembros: MemberList): MemberList;
3
26
  export declare const randomColor: () => string;
4
27
  /**
5
28
  * Construye el objeto filters para la API de equipos (Strapi).
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @fileoverview Indicador visual del equipo asignado en la card de tarea del flujo (plantillas).
3
+ * Pila de avatares (DS `Avatar`/`AvatarStack`), contador `+N` si hay más miembros, etiqueta fija «Equipo» y tooltip con el nombre del equipo.
4
+ * @module modules/templates/components/atoms/tasks/AssignedTeam
5
+ */
6
+ /**
7
+ * Datos de equipo persistidos en el nodo de la tarea (id obligatorio para fetch; nombre opcional como respaldo de UI).
8
+ */
9
+ export type EquipoCardData = {
10
+ id?: number | string | null;
11
+ nombre?: string | null;
12
+ } | null;
13
+ /**
14
+ * Columna "Equipo" en la card del flujo: avatares de miembros (foto vía índice OBP por email),
15
+ * estado de carga, fallback sin miembros y `Tooltip` de `@imj_media/ui` con el nombre del equipo.
16
+ *
17
+ * @param props - Props del componente.
18
+ * @param props.equipo - Referencia al equipo (`id` y opcionalmente `nombre` desde el formulario / nodo).
19
+ * @returns `null` si no hay `equipo.id` válido; en caso contrario el bloque UI alineado al resto de métricas de la card.
20
+ */
21
+ export declare const AssignedTeam: ({ equipo }: {
22
+ equipo: EquipoCardData;
23
+ }) => import("react/jsx-runtime").JSX.Element;
@@ -1,6 +1,7 @@
1
- export declare const Responsible: ({ responsible }: {
2
- responsible: {
3
- id: string;
4
- email: string;
5
- };
1
+ export type ResponsibleUser = {
2
+ id?: string | number | null;
3
+ email?: string | null;
4
+ };
5
+ export declare const Responsible: ({ responsible, }: {
6
+ responsible: ResponsibleUser | null | undefined;
6
7
  }) => import("react/jsx-runtime").JSX.Element;
@@ -1,3 +1,4 @@
1
+ export * from './AssignedTeam';
1
2
  export * from './Difficulty';
2
3
  export * from './Duration';
3
4
  export * from './Priority';
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @fileoverview Datos de vista previa de un equipo para cards de flujo de plantillas.
3
+ * Obtiene nombre, jerarquía de miembros y lista plana de usuarios (deduplicada) vía API Strapi.
4
+ * @module modules/templates/hooks/useTeamFlowPreview
5
+ */
6
+ /**
7
+ * Usuario deduplicado extraído de la jerarquía `miembros` del equipo (para avatares en UI).
8
+ */
9
+ export type TeamFlowMemberPreview = {
10
+ id: number;
11
+ nombre: string;
12
+ email: string;
13
+ image?: unknown;
14
+ };
15
+ /**
16
+ * Forma mínima del equipo tras normalizar la respuesta de la API (nombre + árbol de miembros).
17
+ */
18
+ export type TeamFlowPreview = {
19
+ nombre: string;
20
+ miembros: unknown[];
21
+ };
22
+ /**
23
+ * React Query: carga datos de un equipo para mostrar avatares y tooltip en cards del flujo.
24
+ * La petición solo se ejecuta si `teamId` es un entero positivo válido. Varias cards con el
25
+ * mismo `teamId` comparten caché (`queryKey` incluye el id).
26
+ *
27
+ * @param teamId - Id del equipo en la tarea (`equipo.id`), o `null`/`undefined` para no consultar.
28
+ * @returns Resultado estándar de `useQuery` (`data`, `isLoading`, `isError`, etc.). `data` contiene
29
+ * `{ team: { nombre, miembros }, members: TeamFlowMemberPreview[] }` cuando hay éxito.
30
+ */
31
+ export declare const useTeamFlowPreview: (teamId: number | null | undefined) => import('@tanstack/react-query').UseQueryResult<{
32
+ team: TeamFlowPreview;
33
+ members: TeamFlowMemberPreview[];
34
+ }, Error>;
@@ -100,6 +100,11 @@ export interface UseZoomAndCenterParams {
100
100
  * Se usa para detectar nodo principal y calcular viewport inicial.
101
101
  */
102
102
  nodes: any[];
103
+ /**
104
+ * Al cambiar (p. ej. otra plantilla activa), se limpia el historial de zoom
105
+ * para no mezclar deshacer entre flujos distintos.
106
+ */
107
+ resetZoomHistoryKey?: number | null;
103
108
  }
104
109
  /**
105
110
  * @interface UseZoomAndCenterReturn
@@ -156,4 +161,4 @@ export interface UseZoomAndCenterReturn {
156
161
  * └── handleDoubleClick() // Undo zoom
157
162
  * ```
158
163
  */
159
- export declare function useZoomAndCenter({ reactFlowWrapper, nodes }: UseZoomAndCenterParams): UseZoomAndCenterReturn;
164
+ export declare function useZoomAndCenter({ reactFlowWrapper, nodes, resetZoomHistoryKey, }: UseZoomAndCenterParams): UseZoomAndCenterReturn;
@@ -27,6 +27,17 @@ interface TemplateGridStore {
27
27
  setViewMode: (templateId: number, viewMode: 'readonly' | 'edit') => void;
28
28
  getViewMode: (templateId: number) => 'readonly' | 'edit';
29
29
  clearViewMode: (templateId: number) => void;
30
+ /** Pan/zoom del lienzo por plantilla (sesión actual); independiente entre flujos */
31
+ flowViewportByTemplateId: Record<number, {
32
+ x: number;
33
+ y: number;
34
+ zoom: number;
35
+ }>;
36
+ setFlowViewportForTemplate: (templateId: number, viewport: {
37
+ x: number;
38
+ y: number;
39
+ zoom: number;
40
+ }) => void;
30
41
  expandedGroups: Set<string>;
31
42
  groupTemplateData: Record<string, any>;
32
43
  toggleGroupExpansion: (groupId: string) => void;
@@ -66,6 +66,8 @@ type DetailsTaskData = {
66
66
  fterminada: Date | null;
67
67
  responsable: Responsible | null;
68
68
  prioridad: string | null;
69
+ /** API `nivel_dificultad` (1–5); optional if older payloads omit it. */
70
+ nivel_dificultad?: number | string | null;
69
71
  lista: string | null;
70
72
  texto_corto: string | null;
71
73
  texto_largo: string | null;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Same rules as assignment (`ButtonAssignUsers`): Project Managers can edit regardless of status;
3
+ * other roles only when the task is still in backlog (`estatus === 0`).
4
+ */
5
+ export declare const TASKS_PROJECT_MANAGER_ROLE = "Project Manager";
6
+ export declare function canEditTaskFields(role: string | undefined | null, status: number): boolean;
@@ -1,12 +1,10 @@
1
1
  /**
2
- * Elegibilidad para multiselección masiva del Kanban (listado y campaña) y para mostrar el menú «mover»
3
- * en la card (`Task` `ButtonMoveTask`): una sola fuente de verdad.
2
+ * Elegibilidad para multiselección masiva del Kanban (listado y campaña): misma regla que
3
+ * `hasMoveMenuForBulk` en `Task.tsx` (menú «mover» + checkbox bulk).
4
4
  *
5
- * Incluye:
6
- * - **Unidades / repeticiones (rutas):** si la tarea tiene cuota (`repeatsToDo > 0`), no se puede mover ni
7
- * seleccionar en bloque hasta que el contador esté completo (`repeats === repeatsToDo`). Antes, el caso
8
- * `repeatsToDo === 1` se trataba como «sin repeticiones» y permitía `0/1` con menú mover y bulk.
9
- * - **Dependencia:** misma regla que el render de `ButtonMoveTask` (tarea previa obligatoria incompleta bloquea).
5
+ * - **`isVisibleMoveMenu`:** `(repeatsAreCompleted || dontHaveRepeats || statusIsZero) && status !== 2`
6
+ * - **Tarea requerida (como `ButtonMoveTask`):** `haveRequiredTask || !nameRequiredTask`, con
7
+ * `haveRequiredTask = (nameRequiredTask ?? '') !== '' && statusRequiredTask === 2`
10
8
  */
11
9
  export type TaskKanbanBulkEligibilityInput = {
12
10
  status: number;
@@ -15,4 +13,7 @@ export type TaskKanbanBulkEligibilityInput = {
15
13
  repeatsToDo?: number | null | undefined;
16
14
  repeats?: number | null | undefined;
17
15
  };
16
+ /**
17
+ * `true` si la tarea puede mostrar fila «mover» + bulk en la card (`Task` / `KanbanCampania` «Seleccionar todas»).
18
+ */
18
19
  export declare function isTaskEligibleForKanbanBulkSelection(t: TaskKanbanBulkEligibilityInput): boolean;