@imj_media/tareas 0.0.7

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 (114) hide show
  1. package/.env.template +8 -0
  2. package/.storybook/main.ts +26 -0
  3. package/.storybook/preview.ts +15 -0
  4. package/LICENSE.md +21 -0
  5. package/README.md +50 -0
  6. package/core/actions/get_all_users.action.ts +16 -0
  7. package/core/actions/get_salesman_response.action.ts +16 -0
  8. package/core/actions/get_tasks_project.action.ts +62 -0
  9. package/core/actions/get_tasks_response.action.ts +56 -0
  10. package/eslint.config.js +28 -0
  11. package/global.d.ts +3 -0
  12. package/infraestructure/interfaces/salesmans-obp-response.ts +43 -0
  13. package/infraestructure/interfaces/salesmans-obp.ts +4 -0
  14. package/infraestructure/interfaces/tasks-campania-response.ts +118 -0
  15. package/infraestructure/interfaces/tasks-campania.ts +26 -0
  16. package/infraestructure/interfaces/tasks-kanban-general.ts +25 -0
  17. package/infraestructure/interfaces/tasks-reponse.ts +111 -0
  18. package/infraestructure/interfaces/teams-response.ts +7 -0
  19. package/infraestructure/interfaces/teams.ts +5 -0
  20. package/infraestructure/interfaces/users-obp-response.ts +52 -0
  21. package/infraestructure/interfaces/users.ts +5 -0
  22. package/infraestructure/mappers/all-users-obp.ts +12 -0
  23. package/infraestructure/mappers/campaign-tasks.ts +35 -0
  24. package/infraestructure/mappers/kanban-tasks.ts +35 -0
  25. package/infraestructure/mappers/salesmans-obp.ts +11 -0
  26. package/infraestructure/mappers/teams.ts +12 -0
  27. package/package.json +61 -0
  28. package/postcss.config.js +6 -0
  29. package/src/components/atoms/Avatar.tsx +14 -0
  30. package/src/components/atoms/Comment.tsx +33 -0
  31. package/src/components/atoms/InputSearch.tsx +40 -0
  32. package/src/components/atoms/SkeletonCard.tsx +17 -0
  33. package/src/components/atoms/TabButton.tsx +16 -0
  34. package/src/components/atoms/TooltipUser.tsx +26 -0
  35. package/src/components/atoms/index.ts +2 -0
  36. package/src/components/index.ts +3 -0
  37. package/src/components/kanban-campania/DoneBoard.tsx +12 -0
  38. package/src/components/kanban-campania/KanbanCampania.tsx +39 -0
  39. package/src/components/kanban-campania/ToDoBoard.tsx +12 -0
  40. package/src/components/kanban-campania/WorkingBoard.tsx +13 -0
  41. package/src/components/kanban-campania/filters.ts +46 -0
  42. package/src/components/kanban-campania/index.ts +3 -0
  43. package/src/components/kanban-general/DoneBoard.tsx +12 -0
  44. package/src/components/kanban-general/KanbanGeneral.tsx +40 -0
  45. package/src/components/kanban-general/ToDoBoard.tsx +12 -0
  46. package/src/components/kanban-general/WorkingBoard.tsx +13 -0
  47. package/src/components/kanban-general/filters.ts +58 -0
  48. package/src/components/kanban-general/index.ts +3 -0
  49. package/src/components/layout/FilterButton.tsx +50 -0
  50. package/src/components/layout/FilterContent.tsx +70 -0
  51. package/src/components/layout/IndexComponents.tsx +32 -0
  52. package/src/components/lista-campania/ChildTask.tsx +22 -0
  53. package/src/components/lista-campania/Date.tsx +30 -0
  54. package/src/components/lista-campania/ListaCampania.tsx +21 -0
  55. package/src/components/lista-campania/ParentTask.tsx +57 -0
  56. package/src/components/molecules/AllComments.tsx +78 -0
  57. package/src/components/molecules/ButtonAssignUsers.tsx +175 -0
  58. package/src/components/molecules/DependentTasks.tsx +64 -0
  59. package/src/components/molecules/Tabs.tsx +39 -0
  60. package/src/components/molecules/index.ts +1 -0
  61. package/src/components/organisms/Board.tsx +87 -0
  62. package/src/components/organisms/Checkbox.tsx +45 -0
  63. package/src/components/organisms/DetailsTask.tsx +286 -0
  64. package/src/components/organisms/TabDetailsTask.tsx +39 -0
  65. package/src/components/organisms/Task.tsx +176 -0
  66. package/src/components/organisms/index.ts +2 -0
  67. package/src/components/tasks/PriorityButton.tsx +79 -0
  68. package/src/components/templates/Layout.tsx +84 -0
  69. package/src/components/templates/TableList/components/TableList.scss +270 -0
  70. package/src/components/templates/TableList/components/TableList.tsx +239 -0
  71. package/src/components/templates/TableList/components/index.tsx +1 -0
  72. package/src/constants/colors.ts +64 -0
  73. package/src/constants/gaps.ts +8 -0
  74. package/src/constants/paddings.ts +8 -0
  75. package/src/constants/shadows.ts +5 -0
  76. package/src/context/filtersLayout.context.tsx +118 -0
  77. package/src/context/kanbanCampania.context.tsx +50 -0
  78. package/src/context/useApis.context.tsx +47 -0
  79. package/src/context/userLog.context.tsx +50 -0
  80. package/src/env.d.ts +10 -0
  81. package/src/functions/taskCalculations.tsx +818 -0
  82. package/src/hooks/useAllUsers.ts +18 -0
  83. package/src/hooks/useCheckTask.tsx +15 -0
  84. package/src/hooks/useComerciales.ts +58 -0
  85. package/src/hooks/useDoneTasks.ts +90 -0
  86. package/src/hooks/useElementPosition.ts +34 -0
  87. package/src/hooks/useFunctionsTasks.ts +57 -0
  88. package/src/hooks/useNormalizedData.ts +36 -0
  89. package/src/hooks/useTeams.ts +19 -0
  90. package/src/hooks/useToDoTasks.ts +89 -0
  91. package/src/hooks/useWorkingTasks.ts +85 -0
  92. package/src/index.css +55 -0
  93. package/src/index.ts +2 -0
  94. package/src/index.tsx +1 -0
  95. package/src/pages/App.tsx +42 -0
  96. package/src/pages/NoAccessToken.tsx +20 -0
  97. package/src/pages/NoUser.tsx +20 -0
  98. package/src/stories/AppTasks.stories.tsx +36 -0
  99. package/src/stories/Table.stories.tsx +160 -0
  100. package/src/types/index.ts +107 -0
  101. package/src/types/interfaces.ts +67 -0
  102. package/src/types/layout.types.ts +30 -0
  103. package/src/utils/filters.functions.ts +17 -0
  104. package/src/utils/formats.ts +33 -0
  105. package/src/utils/functionsStorybook.tsx +0 -0
  106. package/src/utils/inputs.functions.ts +25 -0
  107. package/src/utils/tanstack.functions.ts +19 -0
  108. package/src/utils/utils.ts +12 -0
  109. package/src/vite-env.d.ts +1 -0
  110. package/tailwind.config.js +31 -0
  111. package/tsconfig.app.json +26 -0
  112. package/tsconfig.json +7 -0
  113. package/tsconfig.node.json +24 -0
  114. package/vite.config.ts +16 -0
@@ -0,0 +1,818 @@
1
+ import { normalizeData } from '../api/NormalizeData';
2
+ import { axiosQuery, createItem, deleteItem, updateItem } from '../api/axiosQuery';
3
+ import { equiposToDropdownQuery, plantillaQuery, usersQuery } from '../api/querys';
4
+
5
+ export const prioridadValues = [
6
+ ['none', 0],
7
+ ['baja', 1],
8
+ ['media', 2],
9
+ ['alta', 3],
10
+ ];
11
+
12
+ export const ROLENEEDSTOSHOWALLPROYECTS = ['PM', 'Operation Manager', 'Administrador'];
13
+
14
+ export const ESTATUSTASKSTOSTRINGS = {
15
+ 0: 'Por hacer',
16
+ 1: 'Trabajando',
17
+ 2: 'Completadas',
18
+ };
19
+
20
+ export const ESTATUSTASKSTONUMBERS = {
21
+ 'Por hacer': 0,
22
+ Trabajando: 1,
23
+ Completadas: 2,
24
+ };
25
+
26
+ export const dificultyValues = [
27
+ { id: 1, title: 'Muy fácil' },
28
+ { id: 2, title: 'Fácil' },
29
+ { id: 3, title: 'Normal' },
30
+ { id: 4, title: 'Dificil' },
31
+ { id: 5, title: 'Muy dificil' },
32
+ ];
33
+
34
+ export const statusValues = [
35
+ ['Por hacer', 0],
36
+ ['Trabajando', 1],
37
+ ['Completadas', 2],
38
+ ];
39
+
40
+ export const plantillaCampaniaValues = [
41
+ { id: 0, title: 'Sitios' },
42
+ { id: 1, title: 'Rutas' },
43
+ { id: 2, title: 'Indoors' },
44
+ { id: 3, title: 'Vallas Móviles' },
45
+ { id: 4, title: 'Sitios Digitales' },
46
+ { id: 5, title: 'Indoors Digitales' },
47
+ ];
48
+
49
+ export const plantillaTiposValues = [
50
+ { id: 1, title: 'Preventa' },
51
+ { id: 2, title: 'Venta' },
52
+ { id: 3, title: 'Postventa' },
53
+ ];
54
+
55
+ export const idsFromCampaniaTask = ['idmedio', 'idruta', 'idindoor', 'idvalla'];
56
+
57
+ export const rolesAdmin = [22 /** Operation manager */, 5 /** Admin */, 23 /** Super admin */];
58
+
59
+ export const getPrioridadText = (value: number) => {
60
+ if (!value) return prioridadValues[0][0];
61
+ return prioridadValues.find((e) => e[1] === value)[0];
62
+ };
63
+
64
+ export const getPrioridadNumber = (value: string) => {
65
+ return prioridadValues.find((e) => e[0] === value)[1];
66
+ };
67
+
68
+ export const getStatusText = (value: number) => {
69
+ return statusValues.find((e) => e[1] === value)[0];
70
+ };
71
+
72
+ export const getStatusNumber = (value: string) => {
73
+ return statusValues.find((e) => e[0] === value)[1];
74
+ };
75
+
76
+ export const getStatusOfTask = (tasks) => {
77
+ let status = 1;
78
+ let today = new Date();
79
+ tasks?.forEach((task) => {
80
+ if (task.estatus !== 2) {
81
+ let ffin_plus10 = new Date(task.ffin);
82
+ ffin_plus10.setDate(ffin_plus10.getDate() + 10);
83
+ if (new Date(task.ffin) < today && status < 2) status = 2;
84
+ if (ffin_plus10 < today && status < 3) status = 3;
85
+ }
86
+ });
87
+ return status;
88
+ };
89
+
90
+ export const getStatusTask = (task) => {
91
+ let status = 1,
92
+ today = new Date(),
93
+ ffin_plus = new Date(task?.ffin);
94
+ ffin_plus.setDate(ffin_plus.getDate() + 10);
95
+ if (task?.estatus === 2) status = 1;
96
+ else {
97
+ if (new Date(task?.ffin) < today && status < 2) status = 2;
98
+ if (ffin_plus < today && status < 3) status = 3;
99
+ }
100
+ return status;
101
+ };
102
+
103
+ export const getPersentageOfTask = (tareas) => {
104
+ let completed = 0;
105
+ let total = tareas?.length ?? 0;
106
+
107
+ tareas?.forEach((tarea) => {
108
+ if (tarea?.estatus === 2) completed++;
109
+ });
110
+ return Math.round((completed / total) * 100);
111
+ };
112
+
113
+ export const getRandId = () => {
114
+ return Math.floor(Math.random() * (99999 - 10000 + 1)) + 10000;
115
+ };
116
+
117
+ export const getRandIdTemplates = () => {
118
+ return Math.floor(Math.random() * (999999 - 100000 + 1)) + 100000;
119
+ };
120
+
121
+ export const getDataToSubmenu = (
122
+ menuOptions,
123
+ titleValue = 'nombre',
124
+ onClick = (e: any) => {},
125
+ classNameValue = null
126
+ ) => {
127
+ return [
128
+ ...(menuOptions?.map((option) => {
129
+ return {
130
+ id: option.id,
131
+ title: option[titleValue],
132
+ onClick: onClick,
133
+ className: classNameValue,
134
+ };
135
+ }) || []),
136
+ {
137
+ id: null,
138
+ title: 'Ninguno',
139
+ onClick: onClick,
140
+ className: classNameValue,
141
+ },
142
+ ];
143
+ };
144
+
145
+ export const sortByOrden = (array) => {
146
+ return array.sort((a, b) => a.orden - b.orden);
147
+ };
148
+
149
+ export const addTaskFromTemplate = (setData, template, fromTask, newElement) => {
150
+ let today = new Date();
151
+ let dict = {};
152
+
153
+ template?.tarea_plantillas?.forEach((e) => {
154
+ dict[e.id] = getRandIdTemplates();
155
+ });
156
+
157
+ let newTasksWithId = template?.tarea_plantillas?.map((e) => {
158
+ return {
159
+ ...e,
160
+ id: dict[e.id],
161
+ tarea_padre: dict[e?.tarea_padre?.id] || null,
162
+ };
163
+ });
164
+
165
+ const getDateWithDuration = (date, duration) => {
166
+ let newDate = new Date(date);
167
+ newDate.setDate(newDate.getDate() + duration);
168
+ return newDate.toISOString().slice(0, 16);
169
+ };
170
+
171
+ setData((prevState) => {
172
+ const numHermanas = prevState?.tasks?.filter((e) => e.fromTask === fromTask).length || 0;
173
+
174
+ let newElements =
175
+ newTasksWithId?.map((e) => {
176
+ let extraData = {
177
+ idTask: e.id,
178
+ startDate: today.toISOString().slice(0, 16),
179
+ endDate: getDateWithDuration(today, e.duracion),
180
+ responsable: e.responsable,
181
+ supervisor: e.supervisor,
182
+ recordatorio: e?.recordatorio,
183
+ texto_corto: e?.texto_corto,
184
+ texto_largo: e?.texto_largo,
185
+ dependence: e?.id_t_requerida
186
+ ? {
187
+ id: dict[e?.id_t_requerida?.id] || null,
188
+ title: e?.id_t_requerida?.texto_corto,
189
+ onClick: () => {},
190
+ }
191
+ : null,
192
+ nivel_dificultad: e?.nivel_dificultad,
193
+ };
194
+ let actualOrder = e.orden;
195
+ if (!e?.tarea_padre) {
196
+ actualOrder += numHermanas;
197
+ }
198
+ return newElement(e?.tarea_padre || fromTask, extraData, actualOrder);
199
+ }) || [];
200
+
201
+ return {
202
+ ...prevState,
203
+ tasks: prevState?.tasks ? [...prevState.tasks, ...newElements] : [...newElements],
204
+ };
205
+ });
206
+ };
207
+
208
+ export const addTemplateFromTemplate = (setData, template, fromTask, newElement) => {
209
+ let dict = {};
210
+
211
+ template?.tarea_plantillas?.forEach((e) => {
212
+ dict[e.id] = getRandIdTemplates();
213
+ });
214
+
215
+ let newTasksWithId = template?.tarea_plantillas?.map((e) => {
216
+ return {
217
+ ...e,
218
+ id: dict[e.id],
219
+ tarea_padre: dict[e?.tarea_padre?.id] || null,
220
+ };
221
+ });
222
+
223
+ setData((prevState) => {
224
+ const numHermanas =
225
+ prevState?.tasks?.filter((e) => {
226
+ let tareaPadre = e?.fromTask ? e?.fromTask : e?.tarea_padre;
227
+
228
+ return tareaPadre === fromTask;
229
+ }).length || 0;
230
+
231
+ let newElements =
232
+ newTasksWithId?.map((e) => {
233
+ let newTask = newElement(e?.tarea_padre);
234
+
235
+ let actualOrder = e?.orden;
236
+ if (!e?.tarea_padre) {
237
+ actualOrder += numHermanas;
238
+ }
239
+ newTask.idTask = e?.id;
240
+ newTask.durationValue = e?.duracion;
241
+ newTask.responsable = e?.responsable;
242
+ newTask.valueResponsable = e?.responsable?.nombre;
243
+ newTask.revisionInfo = e?.supervisor;
244
+ newTask.valueRevision = e?.supervisor?.nombre;
245
+ newTask.recordatorio = e?.recordatorio;
246
+ newTask.valueTask = e?.texto_corto;
247
+ newTask.valueDescription = e?.texto_largo;
248
+ newTask.dependence = e?.id_t_requerida
249
+ ? {
250
+ id: dict[e?.id_t_requerida?.id] || null,
251
+ title: e?.id_t_requerida?.texto_corto,
252
+ onClick: () => {},
253
+ }
254
+ : null;
255
+ newTask.nivel_dificultad = e.nivel_dificultad;
256
+ newTask.orden = actualOrder;
257
+
258
+ return { ...e, ...newTask };
259
+ }) || [];
260
+
261
+ let tasks = prevState?.tasks ? prevState.tasks : [];
262
+ tasks.push(...newElements);
263
+
264
+ return {
265
+ ...prevState,
266
+ tasks,
267
+ };
268
+ });
269
+ };
270
+
271
+ export const getSubtask = (item) => {
272
+ let subTask = [];
273
+ const extractSubTask = (tasks) => {
274
+ if (!tasks?.tareas || tasks?.tareas?.length === 0) return;
275
+ tasks?.tareas?.forEach((sub) => {
276
+ subTask.push({
277
+ ...sub,
278
+ tareas: null,
279
+ });
280
+ extractSubTask(sub);
281
+ });
282
+ };
283
+ extractSubTask(item);
284
+ return subTask;
285
+ };
286
+
287
+ export const getUsers = async (setUsers) => {
288
+ const users = await axiosQuery(
289
+ 'GET',
290
+ 'api/users',
291
+ {
292
+ ...usersQuery,
293
+ },
294
+ null
295
+ );
296
+
297
+ users?.data && setUsers(users.data?.filter((user) => !user.blocked));
298
+ };
299
+
300
+ export const getPlantillas = async (user, setPlantillas) => {
301
+ const plantillas = await axiosQuery(
302
+ 'GET',
303
+ 'api/plantillas',
304
+ {
305
+ ...plantillaQuery(user), // Poner el id del usuario
306
+ },
307
+ null
308
+ );
309
+
310
+ plantillas?.data && setPlantillas(plantillas.data);
311
+ };
312
+
313
+ export const getEquipos = async (setEquipos) => {
314
+ const equipos = await axiosQuery(
315
+ 'GET',
316
+ 'api/equipos',
317
+ {
318
+ ...equiposToDropdownQuery,
319
+ },
320
+ null
321
+ );
322
+
323
+ equipos?.data && setEquipos(equipos.data);
324
+ };
325
+
326
+ export const getEncargadoDeEquipo = async (id) => {
327
+ return await axiosQuery(
328
+ 'GET',
329
+ 'api/encargadoequipo',
330
+ {
331
+ id,
332
+ },
333
+ null
334
+ ).then((res) => {
335
+ if (res['data']) {
336
+ return res['data'];
337
+ } else {
338
+ console.log(res['error']);
339
+ }
340
+ });
341
+ };
342
+
343
+ export const validatePlantillaProyecto = (data) => {
344
+ let response = { reason: 'Guardando', isValid: true };
345
+ if (
346
+ (!data?.projectName && !data?.nombre_plantilla) ||
347
+ data?.projectName === '' ||
348
+ data?.nombre_plantilla === ''
349
+ )
350
+ return { reason: 'No se ha asignado nombre.', isValid: false };
351
+
352
+ response = validateTasks(data?.tasks);
353
+ return response;
354
+ };
355
+
356
+ export const validateTasks = (tasks, isPM = false) => {
357
+ if (!tasks || tasks?.length === 0)
358
+ return { reason: 'No hay tareas por guardar', isValid: false };
359
+
360
+ let tareasWithoutName = tasks?.filter((e) => !e.valueTask || e.valueTask === '');
361
+
362
+ if (tareasWithoutName?.length > 0)
363
+ return {
364
+ reason: 'Existen tareas sin nombre',
365
+ isValid: false,
366
+ };
367
+
368
+ let tareasWithoutResponsable = tasks?.filter(
369
+ (e) => !e.fromTask && (!e.responsable || !e?.responsable?.id)
370
+ );
371
+
372
+ if (tareasWithoutResponsable?.length > 0 && isPM)
373
+ return {
374
+ reason: 'Existen tareas principales sin responsable',
375
+ isValid: false,
376
+ };
377
+
378
+ return { reason: 'Guardando', isValid: true };
379
+ };
380
+
381
+ export const validateTeam = (team) => {
382
+ if (!team?.teamName || team?.teamName === '')
383
+ return { reason: 'Se necesita agregar nombre al equipo.', isValid: false };
384
+
385
+ if (!team?.color || team?.color === '')
386
+ return {
387
+ reason: 'Se necesita agregar un color al equipo.',
388
+ isValid: false,
389
+ };
390
+
391
+ if (!team?.members || team?.members?.length < 2)
392
+ return {
393
+ reason: 'Se necesita agregar al menos un encargado y un integrante al equipo.',
394
+ isValid: false,
395
+ };
396
+
397
+ return { reason: 'Guardando', isValid: true };
398
+ };
399
+
400
+ export const validateTasksWithoutResponsable = (tasks) => {
401
+ if (!tasks || tasks?.length === 0)
402
+ return { reason: 'No hay tareas por guardar', isValid: false };
403
+
404
+ let tareasWithoutName = tasks?.filter((e) => !e.valueTask || e.valueTask === '');
405
+
406
+ if (tareasWithoutName?.length > 0)
407
+ return {
408
+ reason: 'Existen tareas sin nombre',
409
+ isValid: false,
410
+ };
411
+
412
+ return { reason: 'Guardando', isValid: true };
413
+ };
414
+
415
+ export const getTareasPadre = (idTask, tasks) => {
416
+ let tareasPadre = [];
417
+ let tareaActual = idTask;
418
+
419
+ while (tareaActual) {
420
+ let tarea = tasks?.find((t) => t.idTask === tareaActual);
421
+ if (tarea) {
422
+ tareasPadre.push(tarea.idTask);
423
+ tareaActual = tarea?.fromTask;
424
+ } else {
425
+ tareaActual = null;
426
+ }
427
+ }
428
+
429
+ return tareasPadre.filter((e) => e !== idTask);
430
+ };
431
+
432
+ export const getTareasHijas = (idTask, tasks) => {
433
+ let tareasHijas = [];
434
+ let aux = tasks?.filter((t) => t.fromTask === idTask).map((t) => t.idTask);
435
+ tareasHijas = [...aux];
436
+ aux.forEach((id) => {
437
+ tareasHijas = [...getTareasHijas(id, tasks), ...tareasHijas];
438
+ });
439
+ return tareasHijas;
440
+ };
441
+
442
+ export const getTareasHermanas = (idTask, tasks) => {
443
+ let tareaActual = tasks?.find((t) => t.idTask === idTask);
444
+ let tareasHermanas = tasks?.filter((t) => t.fromTask === tareaActual.fromTask);
445
+ return tareasHermanas;
446
+ };
447
+
448
+ export const getTareasWithEstatus = (idTask, estatus, tasks) => {
449
+ let newTasks = tasks?.length > 0 ?
450
+ [
451
+ ...tasks?.map((t) => {
452
+ if (t.idTask === idTask) {
453
+ t.estatus = estatus;
454
+ t.check = estatus === 2;
455
+ }
456
+ return t;
457
+ }),
458
+ ] : [];
459
+ let tareasHijas = getTareasHijas(idTask, tasks);
460
+ let tareasPadres = getTareasPadre(idTask, tasks);
461
+
462
+ if (estatus === 2) {
463
+ if (tareasHijas.length > 0) {
464
+ newTasks = newTasks.map((t) => {
465
+ if (tareasHijas.includes(t.idTask)) {
466
+ t.estatus = 2;
467
+ t.check = true;
468
+ }
469
+ return t;
470
+ });
471
+ }
472
+ if (tareasPadres.length > 0) {
473
+ tareasPadres.forEach((id) => {
474
+ let tareasDePadre = newTasks.filter((t) => t.fromTask === id);
475
+ if (tareasDePadre.every((t) => t.estatus === 2)) {
476
+ newTasks = newTasks.map((t) => {
477
+ if (t.idTask === id) {
478
+ t.estatus = 2;
479
+ t.check = true;
480
+ }
481
+ return t;
482
+ });
483
+ }
484
+ });
485
+ }
486
+ } else if (estatus === 0) {
487
+ if (tareasHijas.length > 0) {
488
+ newTasks = newTasks.map((t) => {
489
+ if (tareasHijas.includes(t.idTask)) {
490
+ t.estatus = 0;
491
+ t.check = false;
492
+ }
493
+ return t;
494
+ });
495
+ }
496
+ if (tareasPadres.length > 0) {
497
+ newTasks = newTasks.map((t) => {
498
+ if (tareasPadres.includes(t.idTask) && t.estatus === 2) {
499
+ t.estatus = 0;
500
+ t.check = false;
501
+ }
502
+ return t;
503
+ });
504
+ }
505
+ }
506
+ return newTasks;
507
+ };
508
+
509
+ export const saveTasks = (tasks, onFinishSaved, user, firstFather = null) => {
510
+ let saved = [];
511
+ let isEditingChilds = firstFather ? true : false;
512
+
513
+ const saveTaskFrom = (fatherID) => {
514
+ let tasksToSave = tasks.filter((e) =>
515
+ isEditingChilds
516
+ ? (e.fromTask || e?.tarea_padre) === fatherID
517
+ : ((e.fromTask || e?.tarea_padre) === fatherID && !e?.id_t_requerida) ||
518
+ (e?.id_t_requerida === fatherID && fatherID)
519
+ );
520
+ if (tasksToSave?.length === 0) {
521
+ return;
522
+ }
523
+ tasksToSave.forEach((task) => {
524
+ let tareaPadre = task?.fromTask ? task?.fromTask : task?.tarea_padre;
525
+ let dataToSave = {
526
+ ...task,
527
+ tarea_padre: isEditingChilds
528
+ ? firstFather
529
+ : saved.find((e) => e?.idTask === tareaPadre)?.idDB ?? null,
530
+ id_t_requerida: task?.id_t_requerida ?? null,
531
+ responsable: task?.responsable ? task.responsable : task?.equipo ? null : user?.id,
532
+ equipo: task?.equipo ?? null,
533
+ updated_by: user?.id,
534
+ es_pausable: task?.es_pausable ?? false,
535
+ supervisor: task?.supervisor ?? null,
536
+ };
537
+
538
+ if (!task?.idDB) {
539
+ dataToSave.created_by = user?.id;
540
+ }
541
+
542
+ isEditingChilds = false;
543
+
544
+ if (task?.idDB) {
545
+ updateItem(
546
+ 'api/tareas',
547
+ task?.idDB,
548
+ {
549
+ ...dataToSave,
550
+ idTask: null, //! Puede eliminarse
551
+ },
552
+ async (e) => {
553
+ saved.push(task);
554
+ if (saved.length === tasks.length) {
555
+ onFinishSaved(saved);
556
+ return;
557
+ }
558
+ saveTaskFrom(task.idTask);
559
+ },
560
+ (error) => {
561
+ console.log('Error al actualizar la tarea: ', error, task?.idTask);
562
+ }
563
+ );
564
+ } else {
565
+ createItem(
566
+ 'api/tareas',
567
+ {
568
+ ...dataToSave,
569
+ idTask: null, //! Puede eliminarse
570
+ },
571
+ async (e) => {
572
+ task.idDB = e.id;
573
+ saved.push(task);
574
+ if (saved.length === tasks.length) {
575
+ onFinishSaved(saved);
576
+ return;
577
+ }
578
+ saveTaskFrom(task.idTask);
579
+ },
580
+ (error) => {
581
+ console.log('Error al crear la tarea: ', error);
582
+ }
583
+ );
584
+ }
585
+ });
586
+ };
587
+
588
+ saveTaskFrom(firstFather);
589
+ };
590
+
591
+ export const deleteTasks = async (tasks, setLoadingOverlay = null, setRefresh = null) => {
592
+ if (setLoadingOverlay) setLoadingOverlay(true);
593
+ for (const task of tasks) {
594
+ if (task.idindoor || task.idmedio || task.idruta || task.tipo_tarea) {
595
+ await updateItem(
596
+ 'api/tareas',
597
+ task.id,
598
+ {
599
+ cancelada: true,
600
+ },
601
+ async () => {
602
+ console.log('Tarea eliminada');
603
+ },
604
+ (error) => {
605
+ console.log('Error al eliminar tarea', error);
606
+ }
607
+ );
608
+ } else {
609
+ await deleteItem(
610
+ 'api/tareas',
611
+ task.id,
612
+ async () => {
613
+ console.log('Tarea eliminada');
614
+ },
615
+ (error) => {
616
+ console.log('Error al eliminar tarea', error);
617
+ }
618
+ );
619
+ }
620
+ }
621
+ if (setLoadingOverlay) setLoadingOverlay(false);
622
+ if (setRefresh) setRefresh(true);
623
+ };
624
+
625
+ export const deleteProject = async (project, setLoadingOverlay = null, setRefresh = null) => {
626
+ if (setLoadingOverlay) setLoadingOverlay(true);
627
+
628
+ if (project.responsable || project.comercial || project.linkkey) {
629
+ await updateItem(
630
+ 'api/proyectos',
631
+ project.id,
632
+ {
633
+ cancelada: true,
634
+ },
635
+ async () => {
636
+ console.log('Proyecto eliminada');
637
+ },
638
+ (error) => {
639
+ console.log('Error al eliminar proyecto', error);
640
+ }
641
+ );
642
+ } else {
643
+ await deleteItem(
644
+ 'api/proyectos',
645
+ project.id,
646
+ async () => {
647
+ console.log('Proyecto eliminada');
648
+ },
649
+ (error) => {
650
+ console.log('Error al eliminar proyecto', error);
651
+ }
652
+ );
653
+ }
654
+
655
+ if (setLoadingOverlay) setLoadingOverlay(false);
656
+ if (setRefresh) setRefresh(true);
657
+ };
658
+
659
+ export const getTaskToShow = (tasks, onHandleChangeTask, isPlantilla = false) => {
660
+ if (isPlantilla) {
661
+ return (
662
+ tasks?.map((e) => {
663
+ return {
664
+ ...e,
665
+ dependenciesOptions: getTareasHermanas(e.idTask, tasks)
666
+ ?.filter((task) => task.idTask !== e.idTask)
667
+ ?.filter((task) => task?.dependence?.id !== e.idTask)
668
+ .map((task) => ({
669
+ id: task.idTask,
670
+ title: task.valueTask,
671
+ onClick: () =>
672
+ onHandleChangeTask(e.idTask, 'dependence', {
673
+ id: task.idTask,
674
+ title: task.valueTask,
675
+ onClick: () => {},
676
+ }),
677
+ }))
678
+ .concat({
679
+ id: null,
680
+ title: 'Sin dependencia',
681
+ onClick: () => onHandleChangeTask(e.idTask, 'dependence', null),
682
+ }),
683
+ };
684
+ }) || []
685
+ );
686
+ }
687
+ return (
688
+ tasks?.map((e) => {
689
+ let tareaPadre = tasks?.find((t) => t.idTask === e.fromTask) || null;
690
+ let dificultadVal =
691
+ dificultyValues?.find((dif) => dif.id === e.nivel_dificultad) || dificultyValues[0];
692
+ return {
693
+ ...e,
694
+ maxEndDate: tareaPadre?.endDateValue || null,
695
+ maxStartDate: tareaPadre?.endDateValue || null,
696
+ minEndDate: tareaPadre?.startDateValue || null,
697
+ minStartDate: tareaPadre?.startDateValue || null,
698
+ pausable: tareaPadre?.pausable || false,
699
+ dependenciesOptions: getTareasHermanas(e.idTask, tasks)
700
+ ?.filter((task) => task.idTask !== e.idTask)
701
+ ?.filter((task) => task?.dependence?.id !== e.idTask)
702
+ .map((task) => ({
703
+ id: task.idTask,
704
+ title: task.valueTask,
705
+ onClick: () =>
706
+ onHandleChangeTask(e.idTask, 'dependence', {
707
+ id: task.idTask,
708
+ title: task.valueTask,
709
+ onClick: () => {},
710
+ }),
711
+ }))
712
+ .concat({
713
+ id: null,
714
+ title: 'Sin dependencia',
715
+ onClick: () => onHandleChangeTask(e.idTask, 'dependence', null),
716
+ }),
717
+ valueDificultad: { ...dificultadVal, id: dificultadVal.id.toString() },
718
+ onCh_dificultad: (dif) => {
719
+ onHandleChangeTask(e.idTask, 'nivel_dificultad', Number(dif.target.id));
720
+ },
721
+ };
722
+ }) || []
723
+ );
724
+ };
725
+
726
+ export const getOrdenGrafica = (tasks) => {
727
+ let ordenGrafica = [];
728
+
729
+ const getOrden = (tareasAAcomodar) => {
730
+ tareasAAcomodar.forEach((task) => {
731
+ ordenGrafica.push(task);
732
+ let subTasks = tasks.filter((e) => e?.tarea_padre?.id === task.id);
733
+ if (subTasks.length > 0) {
734
+ getOrden(subTasks);
735
+ }
736
+ });
737
+ };
738
+
739
+ getOrden(tasks.filter((e) => !e.tarea_padre));
740
+ return ordenGrafica;
741
+ };
742
+
743
+ export function incrementarBrillo(color, incremento) {
744
+ // Parseamos el color a valores RGB
745
+ const r = parseInt(color.substr(1, 2), 16);
746
+ const g = parseInt(color.substr(3, 2), 16);
747
+ const b = parseInt(color.substr(5, 2), 16);
748
+
749
+ // Incrementamos el brillo
750
+ const incrementoR = Math.round(r + incremento * 255);
751
+ const incrementoG = Math.round(g + incremento * 255);
752
+ const incrementoB = Math.round(b + incremento * 255);
753
+
754
+ // Limitamos los valores a 0-255
755
+ const brilloR = Math.min(255, Math.max(0, incrementoR));
756
+ const brilloG = Math.min(255, Math.max(0, incrementoG));
757
+ const brilloB = Math.min(255, Math.max(0, incrementoB));
758
+
759
+ // Convertimos los valores a hexadecimal
760
+ const nuevoColor = `#${componenteHexadecimal(brilloR)}${componenteHexadecimal(
761
+ brilloG
762
+ )}${componenteHexadecimal(brilloB)}`;
763
+
764
+ return nuevoColor;
765
+ }
766
+
767
+ function componenteHexadecimal(componente) {
768
+ const hex = componente.toString(16);
769
+ return hex.length === 1 ? `0${hex}` : hex;
770
+ }
771
+
772
+ export function seguirTarea(idTarea, user, setLoading, onSucces, onError) {
773
+ setLoading(true);
774
+ axiosQuery(
775
+ 'GET',
776
+ 'api/notificaciones',
777
+ { filters: { tarea: idTarea, user: user.id } },
778
+ null
779
+ ).then(async (res) => {
780
+ if (res['data']) {
781
+ let response = normalizeData(res['data']);
782
+ if (response?.length > 0) {
783
+ await deleteSeguimientoTarea(response[0].id, onError, onError);
784
+ } else {
785
+ await createItem(
786
+ 'api/notificaciones',
787
+ { tarea: idTarea, user: user.id },
788
+ async () => {
789
+ console.log('Notificación creada');
790
+ onSucces('Notificación creada');
791
+ },
792
+ (error) => {
793
+ console.log('Error al crear la notificación: ', error);
794
+ onError('Error al crear la notificación');
795
+ }
796
+ );
797
+ }
798
+ } else {
799
+ console.log(res['error']);
800
+ }
801
+ setLoading(false);
802
+ });
803
+ }
804
+
805
+ export const deleteSeguimientoTarea = async (idNotificacion, onSucces, onError) => {
806
+ await deleteItem(
807
+ 'api/notificaciones',
808
+ idNotificacion,
809
+ async () => {
810
+ console.log('Notificación eliminada');
811
+ onSucces('Notificación eliminada');
812
+ },
813
+ () => {
814
+ console.log('Error al eliminar la notificación');
815
+ onError('Error al eliminar la notificación');
816
+ }
817
+ );
818
+ };