@senior-gestao-relacionamento/angular-components 2.0.0 → 2.1.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.
- package/esm2022/lib/components/schedule/entities/participant-lookup.interface.mjs +2 -0
- package/esm2022/lib/components/schedule/entities/schedule-type.interface.mjs +2 -0
- package/esm2022/lib/components/schedule/entities/schedule.interface.mjs +2 -0
- package/esm2022/lib/components/schedule/enums/schedule.enums.mjs +65 -0
- package/esm2022/lib/components/schedule/helpers/schedule-date.helpers.mjs +109 -0
- package/esm2022/lib/components/schedule/helpers/schedule-display.helpers.mjs +108 -0
- package/esm2022/lib/components/schedule/schedule-detail/schedule-detail.component.mjs +79 -0
- package/esm2022/lib/components/schedule/schedule-form/schedule-form.component.mjs +737 -0
- package/esm2022/lib/components/schedule/services/schedule-type.service.mjs +33 -0
- package/esm2022/lib/components/schedule/services/schedule.service.mjs +66 -0
- package/esm2022/lib/config/provide-angular-components-translations.mjs +42 -0
- package/esm2022/lib/i18n/en-US.json +101 -0
- package/esm2022/lib/i18n/es-ES.json +101 -0
- package/esm2022/lib/i18n/pt-BR.json +101 -0
- package/esm2022/public-api.mjs +9 -1
- package/fesm2022/senior-gestao-relacionamento-angular-components.mjs +1511 -3
- package/fesm2022/senior-gestao-relacionamento-angular-components.mjs.map +1 -1
- package/lib/components/schedule/entities/participant-lookup.interface.d.ts +38 -0
- package/lib/components/schedule/entities/schedule-type.interface.d.ts +10 -0
- package/lib/components/schedule/entities/schedule.interface.d.ts +70 -0
- package/lib/components/schedule/enums/schedule.enums.d.ts +56 -0
- package/lib/components/schedule/helpers/schedule-date.helpers.d.ts +9 -0
- package/lib/components/schedule/helpers/schedule-display.helpers.d.ts +17 -0
- package/lib/components/schedule/schedule-detail/schedule-detail.component.d.ts +43 -0
- package/lib/components/schedule/schedule-form/schedule-form.component.d.ts +139 -0
- package/lib/components/schedule/services/schedule-type.service.d.ts +19 -0
- package/lib/components/schedule/services/schedule.service.d.ts +57 -0
- package/lib/config/provide-angular-components-translations.d.ts +20 -0
- package/package.json +3 -2
- package/public-api.d.ts +9 -0
|
@@ -1,8 +1,37 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { NgModule, Injectable } from '@angular/core';
|
|
2
|
+
import { NgModule, Injectable, EventEmitter, Component, Input, Output, ViewChild } from '@angular/core';
|
|
3
|
+
import * as i6 from '@angular/common';
|
|
3
4
|
import { CommonModule } from '@angular/common';
|
|
4
|
-
import { BehaviorSubject, of, tap } from 'rxjs';
|
|
5
|
+
import { BehaviorSubject, of, tap, Subject, debounceTime, switchMap } from 'rxjs';
|
|
5
6
|
import * as i1 from '@angular/common/http';
|
|
7
|
+
import { HttpParams } from '@angular/common/http';
|
|
8
|
+
import * as i1$1 from '@angular/forms';
|
|
9
|
+
import { Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
10
|
+
import * as i7 from 'primeng/button';
|
|
11
|
+
import { ButtonModule } from 'primeng/button';
|
|
12
|
+
import * as i4 from 'primeng/dialog';
|
|
13
|
+
import { DialogModule } from 'primeng/dialog';
|
|
14
|
+
import * as i9 from 'primeng/drawer';
|
|
15
|
+
import { DrawerModule } from 'primeng/drawer';
|
|
16
|
+
import * as i10 from 'primeng/dropdown';
|
|
17
|
+
import { DropdownModule } from 'primeng/dropdown';
|
|
18
|
+
import * as i11 from 'primeng/inputnumber';
|
|
19
|
+
import { InputNumberModule } from 'primeng/inputnumber';
|
|
20
|
+
import * as i12 from 'primeng/multiselect';
|
|
21
|
+
import { MultiSelectModule } from 'primeng/multiselect';
|
|
22
|
+
import * as i7$1 from 'primeng/tag';
|
|
23
|
+
import { TagModule } from 'primeng/tag';
|
|
24
|
+
import * as i13 from 'primeng/tooltip';
|
|
25
|
+
import { TooltipModule } from 'primeng/tooltip';
|
|
26
|
+
import * as i14 from 'primeng/divider';
|
|
27
|
+
import { DividerModule } from 'primeng/divider';
|
|
28
|
+
import * as i15 from 'primeng/table';
|
|
29
|
+
import { TableModule } from 'primeng/table';
|
|
30
|
+
import * as i16 from 'primeng/autocomplete';
|
|
31
|
+
import { AutoCompleteModule } from 'primeng/autocomplete';
|
|
32
|
+
import * as i5 from '@seniorsistemas/components-ai';
|
|
33
|
+
import { TranslatePipe, DynamicFormComponent, DateFormatPipe } from '@seniorsistemas/components-ai';
|
|
34
|
+
import * as i8 from 'primeng/api';
|
|
6
35
|
|
|
7
36
|
/**
|
|
8
37
|
* Módulo principal da biblioteca @senior-gestao-relacionamento/angular-components
|
|
@@ -216,6 +245,1485 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
216
245
|
}]
|
|
217
246
|
}], ctorParameters: () => [{ type: i1.HttpClient }, { type: StorageService }] });
|
|
218
247
|
|
|
248
|
+
var ptBR = {
|
|
249
|
+
"crmx.components.error": "Ops, algo deu errado",
|
|
250
|
+
"crmx.components.server_error": "Erro no Servidor",
|
|
251
|
+
"crmx.components.server_error_message": "Ocorreu um erro no servidor. Tente novamente mais tarde.",
|
|
252
|
+
"crmx.components.save": "Salvar",
|
|
253
|
+
"crmx.components.cancel": "Cancelar",
|
|
254
|
+
"crmx.components.close": "Fechar",
|
|
255
|
+
"crmx.components.yes": "Sim",
|
|
256
|
+
"crmx.components.no": "Não",
|
|
257
|
+
"crmx.components.success": "Sucesso",
|
|
258
|
+
"crmx.components.confirm_delete": "Confirmar Exclusão",
|
|
259
|
+
"crmx.components.confirm_delete_message": "Tem certeza que deseja excluir {{itemName}}?",
|
|
260
|
+
"crmx.components.entity_deleted_success": "{{entityName}} excluído com sucesso",
|
|
261
|
+
"crmx.components.entity_delete_error": "Erro ao excluir {{entityName}}",
|
|
262
|
+
"crmx.components.load_error": "Erro ao carregar {{entityType}}",
|
|
263
|
+
"crmx.components.required_field": "Campo obrigatório",
|
|
264
|
+
"crmx.components.min_length_error": "Mínimo de {{length}} caracteres",
|
|
265
|
+
"crmx.components.max_length_error": "Máximo de {{length}} caracteres",
|
|
266
|
+
"crmx.components.min_value_error": "Valor mínimo é {{value}}",
|
|
267
|
+
"crmx.components.max_value_error": "Valor máximo é {{value}}",
|
|
268
|
+
"crmx.components.select_option": "Selecione uma opção",
|
|
269
|
+
"crmx.components.not_informed": "Não informado",
|
|
270
|
+
"crmx.components.filter_search_placeholder": "Pesquisar por {{label}}",
|
|
271
|
+
"crmx.components.filter_select_placeholder": "Selecione {{label}}",
|
|
272
|
+
"crmx.components.boolean_true": "Sim",
|
|
273
|
+
"crmx.components.boolean_false": "Não",
|
|
274
|
+
"crmx.components.schedule_name": "Nome",
|
|
275
|
+
"crmx.components.schedule_priority": "Prioridade",
|
|
276
|
+
"crmx.components.schedule_priority_low": "Baixa",
|
|
277
|
+
"crmx.components.schedule_priority_medium": "Média",
|
|
278
|
+
"crmx.components.schedule_priority_high": "Alta",
|
|
279
|
+
"crmx.components.schedule_priority_critical": "Crítica",
|
|
280
|
+
"crmx.components.schedule_type": "Tipo",
|
|
281
|
+
"crmx.components.schedule_select_type": "Selecione o tipo",
|
|
282
|
+
"crmx.components.schedule_start_date": "Data Início",
|
|
283
|
+
"crmx.components.schedule_end_date": "Data Fim",
|
|
284
|
+
"crmx.components.schedule_start_time": "Hora Início",
|
|
285
|
+
"crmx.components.schedule_end_time": "Hora Fim",
|
|
286
|
+
"crmx.components.schedule_all_day": "Dia inteiro",
|
|
287
|
+
"crmx.components.schedule_with_recurrence": "Com recorrência",
|
|
288
|
+
"crmx.components.schedule_comments": "Observações",
|
|
289
|
+
"crmx.components.schedule_enter_name": "Digite o nome",
|
|
290
|
+
"crmx.components.schedule_enter_comments": "Digite as observações",
|
|
291
|
+
"crmx.components.schedule_schedule_new": "Novo Agendamento",
|
|
292
|
+
"crmx.components.schedule_schedule_edit": "Editar Agendamento",
|
|
293
|
+
"crmx.components.schedule_schedule_details": "Detalhes do Agendamento",
|
|
294
|
+
"crmx.components.schedule_recurrence_config": "Configuração de Recorrência",
|
|
295
|
+
"crmx.components.schedule_recurrence": "Recorrência",
|
|
296
|
+
"crmx.components.schedule_recurrence_interval": "Intervalo",
|
|
297
|
+
"crmx.components.schedule_recurrence_daily": "Diária",
|
|
298
|
+
"crmx.components.schedule_recurrence_weekly": "Semanal",
|
|
299
|
+
"crmx.components.schedule_recurrence_monthly": "Mensal",
|
|
300
|
+
"crmx.components.schedule_recurrence_yearly": "Anual",
|
|
301
|
+
"crmx.components.schedule_week_days": "Dias da Semana",
|
|
302
|
+
"crmx.components.schedule_select_week_day": "Selecione os dias",
|
|
303
|
+
"crmx.components.schedule_sunday": "Domingo",
|
|
304
|
+
"crmx.components.schedule_monday": "Segunda",
|
|
305
|
+
"crmx.components.schedule_tuesday": "Terça",
|
|
306
|
+
"crmx.components.schedule_wednesday": "Quarta",
|
|
307
|
+
"crmx.components.schedule_thursday": "Quinta",
|
|
308
|
+
"crmx.components.schedule_friday": "Sexta",
|
|
309
|
+
"crmx.components.schedule_saturday": "Sábado",
|
|
310
|
+
"crmx.components.schedule_repeat_when": "Repetir quando",
|
|
311
|
+
"crmx.components.schedule_repeat_in_day": "No dia",
|
|
312
|
+
"crmx.components.schedule_repeat_in_ordinal_week_day": "No dia da semana ordinal",
|
|
313
|
+
"crmx.components.schedule_repeat_when_day": "Dia",
|
|
314
|
+
"crmx.components.schedule_ordinal_week_day": "Dia ordinal",
|
|
315
|
+
"crmx.components.schedule_ordinal_first": "Primeiro",
|
|
316
|
+
"crmx.components.schedule_ordinal_second": "Segundo",
|
|
317
|
+
"crmx.components.schedule_ordinal_third": "Terceiro",
|
|
318
|
+
"crmx.components.schedule_ordinal_fourth": "Quarto",
|
|
319
|
+
"crmx.components.schedule_ordinal_last": "Último",
|
|
320
|
+
"crmx.components.schedule_week_month": "Dia da semana",
|
|
321
|
+
"crmx.components.schedule_repeat_month": "Mês",
|
|
322
|
+
"crmx.components.schedule_january": "Janeiro",
|
|
323
|
+
"crmx.components.schedule_february": "Fevereiro",
|
|
324
|
+
"crmx.components.schedule_march": "Março",
|
|
325
|
+
"crmx.components.schedule_april": "Abril",
|
|
326
|
+
"crmx.components.schedule_may": "Maio",
|
|
327
|
+
"crmx.components.schedule_june": "Junho",
|
|
328
|
+
"crmx.components.schedule_july": "Julho",
|
|
329
|
+
"crmx.components.schedule_august": "Agosto",
|
|
330
|
+
"crmx.components.schedule_september": "Setembro",
|
|
331
|
+
"crmx.components.schedule_october": "Outubro",
|
|
332
|
+
"crmx.components.schedule_november": "Novembro",
|
|
333
|
+
"crmx.components.schedule_december": "Dezembro",
|
|
334
|
+
"crmx.components.schedule_participants": "Participantes",
|
|
335
|
+
"crmx.components.schedule_search_participant": "Buscar participante",
|
|
336
|
+
"crmx.components.schedule_no_participants": "Nenhum participante adicionado",
|
|
337
|
+
"crmx.components.schedule_participant_type": "Tipo",
|
|
338
|
+
"crmx.components.schedule_participant_account": "Conta",
|
|
339
|
+
"crmx.components.schedule_participant_account_contact": "Contato",
|
|
340
|
+
"crmx.components.schedule_participant_collaborator": "Colaborador",
|
|
341
|
+
"crmx.components.schedule_participant_external": "Externo",
|
|
342
|
+
"crmx.components.schedule_participant_organizer_label": "Organizador",
|
|
343
|
+
"crmx.components.schedule_remove": "Remover",
|
|
344
|
+
"crmx.components.schedule_status": "Status",
|
|
345
|
+
"crmx.components.schedule_confirmation_yes": "Confirmado",
|
|
346
|
+
"crmx.components.schedule_confirmation_no": "Recusado",
|
|
347
|
+
"crmx.components.schedule_confirmation_pending": "Pendente"
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
var enUS = {
|
|
351
|
+
"crmx.components.error": "Oops, something went wrong",
|
|
352
|
+
"crmx.components.server_error": "Server Error",
|
|
353
|
+
"crmx.components.server_error_message": "A server error occurred. Please try again later.",
|
|
354
|
+
"crmx.components.save": "Save",
|
|
355
|
+
"crmx.components.cancel": "Cancel",
|
|
356
|
+
"crmx.components.close": "Close",
|
|
357
|
+
"crmx.components.yes": "Yes",
|
|
358
|
+
"crmx.components.no": "No",
|
|
359
|
+
"crmx.components.success": "Success",
|
|
360
|
+
"crmx.components.confirm_delete": "Confirm Deletion",
|
|
361
|
+
"crmx.components.confirm_delete_message": "Are you sure you want to delete {{itemName}}?",
|
|
362
|
+
"crmx.components.entity_deleted_success": "{{entityName}} deleted successfully",
|
|
363
|
+
"crmx.components.entity_delete_error": "Error deleting {{entityName}}",
|
|
364
|
+
"crmx.components.load_error": "Error loading {{entityType}}",
|
|
365
|
+
"crmx.components.required_field": "Required field",
|
|
366
|
+
"crmx.components.min_length_error": "Minimum of {{length}} characters",
|
|
367
|
+
"crmx.components.max_length_error": "Maximum of {{length}} characters",
|
|
368
|
+
"crmx.components.min_value_error": "Minimum value is {{value}}",
|
|
369
|
+
"crmx.components.max_value_error": "Maximum value is {{value}}",
|
|
370
|
+
"crmx.components.select_option": "Select an option",
|
|
371
|
+
"crmx.components.not_informed": "Not informed",
|
|
372
|
+
"crmx.components.filter_search_placeholder": "Search by {{label}}",
|
|
373
|
+
"crmx.components.filter_select_placeholder": "Select {{label}}",
|
|
374
|
+
"crmx.components.boolean_true": "Yes",
|
|
375
|
+
"crmx.components.boolean_false": "No",
|
|
376
|
+
"crmx.components.schedule_name": "Name",
|
|
377
|
+
"crmx.components.schedule_priority": "Priority",
|
|
378
|
+
"crmx.components.schedule_priority_low": "Low",
|
|
379
|
+
"crmx.components.schedule_priority_medium": "Medium",
|
|
380
|
+
"crmx.components.schedule_priority_high": "High",
|
|
381
|
+
"crmx.components.schedule_priority_critical": "Critical",
|
|
382
|
+
"crmx.components.schedule_type": "Type",
|
|
383
|
+
"crmx.components.schedule_select_type": "Select type",
|
|
384
|
+
"crmx.components.schedule_start_date": "Start Date",
|
|
385
|
+
"crmx.components.schedule_end_date": "End Date",
|
|
386
|
+
"crmx.components.schedule_start_time": "Start Time",
|
|
387
|
+
"crmx.components.schedule_end_time": "End Time",
|
|
388
|
+
"crmx.components.schedule_all_day": "All day",
|
|
389
|
+
"crmx.components.schedule_with_recurrence": "With recurrence",
|
|
390
|
+
"crmx.components.schedule_comments": "Comments",
|
|
391
|
+
"crmx.components.schedule_enter_name": "Enter name",
|
|
392
|
+
"crmx.components.schedule_enter_comments": "Enter comments",
|
|
393
|
+
"crmx.components.schedule_schedule_new": "New Schedule",
|
|
394
|
+
"crmx.components.schedule_schedule_edit": "Edit Schedule",
|
|
395
|
+
"crmx.components.schedule_schedule_details": "Schedule Details",
|
|
396
|
+
"crmx.components.schedule_recurrence_config": "Recurrence Configuration",
|
|
397
|
+
"crmx.components.schedule_recurrence": "Recurrence",
|
|
398
|
+
"crmx.components.schedule_recurrence_interval": "Interval",
|
|
399
|
+
"crmx.components.schedule_recurrence_daily": "Daily",
|
|
400
|
+
"crmx.components.schedule_recurrence_weekly": "Weekly",
|
|
401
|
+
"crmx.components.schedule_recurrence_monthly": "Monthly",
|
|
402
|
+
"crmx.components.schedule_recurrence_yearly": "Yearly",
|
|
403
|
+
"crmx.components.schedule_week_days": "Week Days",
|
|
404
|
+
"crmx.components.schedule_select_week_day": "Select days",
|
|
405
|
+
"crmx.components.schedule_sunday": "Sunday",
|
|
406
|
+
"crmx.components.schedule_monday": "Monday",
|
|
407
|
+
"crmx.components.schedule_tuesday": "Tuesday",
|
|
408
|
+
"crmx.components.schedule_wednesday": "Wednesday",
|
|
409
|
+
"crmx.components.schedule_thursday": "Thursday",
|
|
410
|
+
"crmx.components.schedule_friday": "Friday",
|
|
411
|
+
"crmx.components.schedule_saturday": "Saturday",
|
|
412
|
+
"crmx.components.schedule_repeat_when": "Repeat when",
|
|
413
|
+
"crmx.components.schedule_repeat_in_day": "On day",
|
|
414
|
+
"crmx.components.schedule_repeat_in_ordinal_week_day": "On ordinal week day",
|
|
415
|
+
"crmx.components.schedule_repeat_when_day": "Day",
|
|
416
|
+
"crmx.components.schedule_ordinal_week_day": "Ordinal day",
|
|
417
|
+
"crmx.components.schedule_ordinal_first": "First",
|
|
418
|
+
"crmx.components.schedule_ordinal_second": "Second",
|
|
419
|
+
"crmx.components.schedule_ordinal_third": "Third",
|
|
420
|
+
"crmx.components.schedule_ordinal_fourth": "Fourth",
|
|
421
|
+
"crmx.components.schedule_ordinal_last": "Last",
|
|
422
|
+
"crmx.components.schedule_week_month": "Week day",
|
|
423
|
+
"crmx.components.schedule_repeat_month": "Month",
|
|
424
|
+
"crmx.components.schedule_january": "January",
|
|
425
|
+
"crmx.components.schedule_february": "February",
|
|
426
|
+
"crmx.components.schedule_march": "March",
|
|
427
|
+
"crmx.components.schedule_april": "April",
|
|
428
|
+
"crmx.components.schedule_may": "May",
|
|
429
|
+
"crmx.components.schedule_june": "June",
|
|
430
|
+
"crmx.components.schedule_july": "July",
|
|
431
|
+
"crmx.components.schedule_august": "August",
|
|
432
|
+
"crmx.components.schedule_september": "September",
|
|
433
|
+
"crmx.components.schedule_october": "October",
|
|
434
|
+
"crmx.components.schedule_november": "November",
|
|
435
|
+
"crmx.components.schedule_december": "December",
|
|
436
|
+
"crmx.components.schedule_participants": "Participants",
|
|
437
|
+
"crmx.components.schedule_search_participant": "Search participant",
|
|
438
|
+
"crmx.components.schedule_no_participants": "No participants added",
|
|
439
|
+
"crmx.components.schedule_participant_type": "Type",
|
|
440
|
+
"crmx.components.schedule_participant_account": "Account",
|
|
441
|
+
"crmx.components.schedule_participant_account_contact": "Contact",
|
|
442
|
+
"crmx.components.schedule_participant_collaborator": "Collaborator",
|
|
443
|
+
"crmx.components.schedule_participant_external": "External",
|
|
444
|
+
"crmx.components.schedule_participant_organizer_label": "Organizer",
|
|
445
|
+
"crmx.components.schedule_remove": "Remove",
|
|
446
|
+
"crmx.components.schedule_status": "Status",
|
|
447
|
+
"crmx.components.schedule_confirmation_yes": "Confirmed",
|
|
448
|
+
"crmx.components.schedule_confirmation_no": "Declined",
|
|
449
|
+
"crmx.components.schedule_confirmation_pending": "Pending"
|
|
450
|
+
};
|
|
451
|
+
|
|
452
|
+
var esES = {
|
|
453
|
+
"crmx.components.error": "Ups, algo salió mal",
|
|
454
|
+
"crmx.components.server_error": "Error del Servidor",
|
|
455
|
+
"crmx.components.server_error_message": "Ocurrió un error en el servidor. Inténtelo de nuevo más tarde.",
|
|
456
|
+
"crmx.components.save": "Guardar",
|
|
457
|
+
"crmx.components.cancel": "Cancelar",
|
|
458
|
+
"crmx.components.close": "Cerrar",
|
|
459
|
+
"crmx.components.yes": "Sí",
|
|
460
|
+
"crmx.components.no": "No",
|
|
461
|
+
"crmx.components.success": "Éxito",
|
|
462
|
+
"crmx.components.confirm_delete": "Confirmar Eliminación",
|
|
463
|
+
"crmx.components.confirm_delete_message": "¿Está seguro de que desea eliminar {{itemName}}?",
|
|
464
|
+
"crmx.components.entity_deleted_success": "{{entityName}} eliminado con éxito",
|
|
465
|
+
"crmx.components.entity_delete_error": "Error al eliminar {{entityName}}",
|
|
466
|
+
"crmx.components.load_error": "Error al cargar {{entityType}}",
|
|
467
|
+
"crmx.components.required_field": "Campo obligatorio",
|
|
468
|
+
"crmx.components.min_length_error": "Mínimo de {{length}} caracteres",
|
|
469
|
+
"crmx.components.max_length_error": "Máximo de {{length}} caracteres",
|
|
470
|
+
"crmx.components.min_value_error": "El valor mínimo es {{value}}",
|
|
471
|
+
"crmx.components.max_value_error": "El valor máximo es {{value}}",
|
|
472
|
+
"crmx.components.select_option": "Seleccione una opción",
|
|
473
|
+
"crmx.components.not_informed": "No informado",
|
|
474
|
+
"crmx.components.filter_search_placeholder": "Buscar por {{label}}",
|
|
475
|
+
"crmx.components.filter_select_placeholder": "Seleccione {{label}}",
|
|
476
|
+
"crmx.components.boolean_true": "Sí",
|
|
477
|
+
"crmx.components.boolean_false": "No",
|
|
478
|
+
"crmx.components.schedule_name": "Nombre",
|
|
479
|
+
"crmx.components.schedule_priority": "Prioridad",
|
|
480
|
+
"crmx.components.schedule_priority_low": "Baja",
|
|
481
|
+
"crmx.components.schedule_priority_medium": "Media",
|
|
482
|
+
"crmx.components.schedule_priority_high": "Alta",
|
|
483
|
+
"crmx.components.schedule_priority_critical": "Crítica",
|
|
484
|
+
"crmx.components.schedule_type": "Tipo",
|
|
485
|
+
"crmx.components.schedule_select_type": "Seleccione el tipo",
|
|
486
|
+
"crmx.components.schedule_start_date": "Fecha Inicio",
|
|
487
|
+
"crmx.components.schedule_end_date": "Fecha Fin",
|
|
488
|
+
"crmx.components.schedule_start_time": "Hora Inicio",
|
|
489
|
+
"crmx.components.schedule_end_time": "Hora Fin",
|
|
490
|
+
"crmx.components.schedule_all_day": "Todo el día",
|
|
491
|
+
"crmx.components.schedule_with_recurrence": "Con recurrencia",
|
|
492
|
+
"crmx.components.schedule_comments": "Observaciones",
|
|
493
|
+
"crmx.components.schedule_enter_name": "Ingrese el nombre",
|
|
494
|
+
"crmx.components.schedule_enter_comments": "Ingrese las observaciones",
|
|
495
|
+
"crmx.components.schedule_schedule_new": "Nueva Programación",
|
|
496
|
+
"crmx.components.schedule_schedule_edit": "Editar Programación",
|
|
497
|
+
"crmx.components.schedule_schedule_details": "Detalles de la Programación",
|
|
498
|
+
"crmx.components.schedule_recurrence_config": "Configuración de Recurrencia",
|
|
499
|
+
"crmx.components.schedule_recurrence": "Recurrencia",
|
|
500
|
+
"crmx.components.schedule_recurrence_interval": "Intervalo",
|
|
501
|
+
"crmx.components.schedule_recurrence_daily": "Diaria",
|
|
502
|
+
"crmx.components.schedule_recurrence_weekly": "Semanal",
|
|
503
|
+
"crmx.components.schedule_recurrence_monthly": "Mensual",
|
|
504
|
+
"crmx.components.schedule_recurrence_yearly": "Anual",
|
|
505
|
+
"crmx.components.schedule_week_days": "Días de la Semana",
|
|
506
|
+
"crmx.components.schedule_select_week_day": "Seleccione los días",
|
|
507
|
+
"crmx.components.schedule_sunday": "Domingo",
|
|
508
|
+
"crmx.components.schedule_monday": "Lunes",
|
|
509
|
+
"crmx.components.schedule_tuesday": "Martes",
|
|
510
|
+
"crmx.components.schedule_wednesday": "Miércoles",
|
|
511
|
+
"crmx.components.schedule_thursday": "Jueves",
|
|
512
|
+
"crmx.components.schedule_friday": "Viernes",
|
|
513
|
+
"crmx.components.schedule_saturday": "Sábado",
|
|
514
|
+
"crmx.components.schedule_repeat_when": "Repetir cuando",
|
|
515
|
+
"crmx.components.schedule_repeat_in_day": "En el día",
|
|
516
|
+
"crmx.components.schedule_repeat_in_ordinal_week_day": "En el día ordinal de la semana",
|
|
517
|
+
"crmx.components.schedule_repeat_when_day": "Día",
|
|
518
|
+
"crmx.components.schedule_ordinal_week_day": "Día ordinal",
|
|
519
|
+
"crmx.components.schedule_ordinal_first": "Primero",
|
|
520
|
+
"crmx.components.schedule_ordinal_second": "Segundo",
|
|
521
|
+
"crmx.components.schedule_ordinal_third": "Tercero",
|
|
522
|
+
"crmx.components.schedule_ordinal_fourth": "Cuarto",
|
|
523
|
+
"crmx.components.schedule_ordinal_last": "Último",
|
|
524
|
+
"crmx.components.schedule_week_month": "Día de la semana",
|
|
525
|
+
"crmx.components.schedule_repeat_month": "Mes",
|
|
526
|
+
"crmx.components.schedule_january": "Enero",
|
|
527
|
+
"crmx.components.schedule_february": "Febrero",
|
|
528
|
+
"crmx.components.schedule_march": "Marzo",
|
|
529
|
+
"crmx.components.schedule_april": "Abril",
|
|
530
|
+
"crmx.components.schedule_may": "Mayo",
|
|
531
|
+
"crmx.components.schedule_june": "Junio",
|
|
532
|
+
"crmx.components.schedule_july": "Julio",
|
|
533
|
+
"crmx.components.schedule_august": "Agosto",
|
|
534
|
+
"crmx.components.schedule_september": "Septiembre",
|
|
535
|
+
"crmx.components.schedule_october": "Octubre",
|
|
536
|
+
"crmx.components.schedule_november": "Noviembre",
|
|
537
|
+
"crmx.components.schedule_december": "Diciembre",
|
|
538
|
+
"crmx.components.schedule_participants": "Participantes",
|
|
539
|
+
"crmx.components.schedule_search_participant": "Buscar participante",
|
|
540
|
+
"crmx.components.schedule_no_participants": "Ningún participante agregado",
|
|
541
|
+
"crmx.components.schedule_participant_type": "Tipo",
|
|
542
|
+
"crmx.components.schedule_participant_account": "Cuenta",
|
|
543
|
+
"crmx.components.schedule_participant_account_contact": "Contacto",
|
|
544
|
+
"crmx.components.schedule_participant_collaborator": "Colaborador",
|
|
545
|
+
"crmx.components.schedule_participant_external": "Externo",
|
|
546
|
+
"crmx.components.schedule_participant_organizer_label": "Organizador",
|
|
547
|
+
"crmx.components.schedule_remove": "Eliminar",
|
|
548
|
+
"crmx.components.schedule_status": "Estado",
|
|
549
|
+
"crmx.components.schedule_confirmation_yes": "Confirmado",
|
|
550
|
+
"crmx.components.schedule_confirmation_no": "Rechazado",
|
|
551
|
+
"crmx.components.schedule_confirmation_pending": "Pendiente"
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
const LIB_TRANSLATIONS = {
|
|
555
|
+
'pt-BR': ptBR,
|
|
556
|
+
'en-US': enUS,
|
|
557
|
+
'es-ES': esES
|
|
558
|
+
};
|
|
559
|
+
/**
|
|
560
|
+
* Cria um TranslationLoader que combina as traduções do angular-components
|
|
561
|
+
* com as traduções da aplicação consumidora.
|
|
562
|
+
*
|
|
563
|
+
* Uso no app.config.ts:
|
|
564
|
+
* ```ts
|
|
565
|
+
* import { provideAngularComponentsTranslations } from '@senior-gestao-relacionamento/angular-components';
|
|
566
|
+
*
|
|
567
|
+
* export const appConfig = {
|
|
568
|
+
* providers: [
|
|
569
|
+
* provideAngularComponentsTranslations(async (language) => {
|
|
570
|
+
* const translations = await import(`../locale/${language}.json`);
|
|
571
|
+
* return translations.default || translations;
|
|
572
|
+
* })
|
|
573
|
+
* ]
|
|
574
|
+
* };
|
|
575
|
+
* ```
|
|
576
|
+
*/
|
|
577
|
+
function provideAngularComponentsTranslations(appLoader) {
|
|
578
|
+
return {
|
|
579
|
+
provide: 'TranslationLoader',
|
|
580
|
+
useValue: {
|
|
581
|
+
loadTranslations: async (language) => {
|
|
582
|
+
const libTranslations = LIB_TRANSLATIONS[language] ?? {};
|
|
583
|
+
if (appLoader) {
|
|
584
|
+
const appTranslations = await appLoader(language);
|
|
585
|
+
return { ...libTranslations, ...appTranslations };
|
|
586
|
+
}
|
|
587
|
+
return libTranslations;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
var SchedulePriority;
|
|
594
|
+
(function (SchedulePriority) {
|
|
595
|
+
SchedulePriority["Low"] = "LOW";
|
|
596
|
+
SchedulePriority["Medium"] = "MEDIUM";
|
|
597
|
+
SchedulePriority["High"] = "HIGH";
|
|
598
|
+
SchedulePriority["Critical"] = "CRITICAL";
|
|
599
|
+
})(SchedulePriority || (SchedulePriority = {}));
|
|
600
|
+
var ScheduleRecurrence;
|
|
601
|
+
(function (ScheduleRecurrence) {
|
|
602
|
+
ScheduleRecurrence["Daily"] = "DAILY";
|
|
603
|
+
ScheduleRecurrence["Weekly"] = "WEEKLY";
|
|
604
|
+
ScheduleRecurrence["Monthly"] = "MONTHLY";
|
|
605
|
+
ScheduleRecurrence["Yearly"] = "YEARLY";
|
|
606
|
+
})(ScheduleRecurrence || (ScheduleRecurrence = {}));
|
|
607
|
+
var WeekDay;
|
|
608
|
+
(function (WeekDay) {
|
|
609
|
+
WeekDay["Sunday"] = "SUNDAY";
|
|
610
|
+
WeekDay["Monday"] = "MONDAY";
|
|
611
|
+
WeekDay["Tuesday"] = "TUESDAY";
|
|
612
|
+
WeekDay["Wednesday"] = "WEDNESDAY";
|
|
613
|
+
WeekDay["Thursday"] = "THURSDAY";
|
|
614
|
+
WeekDay["Friday"] = "FRIDAY";
|
|
615
|
+
WeekDay["Saturday"] = "SATURDAY";
|
|
616
|
+
})(WeekDay || (WeekDay = {}));
|
|
617
|
+
var Month;
|
|
618
|
+
(function (Month) {
|
|
619
|
+
Month["January"] = "JANUARY";
|
|
620
|
+
Month["February"] = "FEBRUARY";
|
|
621
|
+
Month["March"] = "MARCH";
|
|
622
|
+
Month["April"] = "APRIL";
|
|
623
|
+
Month["May"] = "MAY";
|
|
624
|
+
Month["June"] = "JUNE";
|
|
625
|
+
Month["July"] = "JULY";
|
|
626
|
+
Month["August"] = "AUGUST";
|
|
627
|
+
Month["September"] = "SEPTEMBER";
|
|
628
|
+
Month["October"] = "OCTOBER";
|
|
629
|
+
Month["November"] = "NOVEMBER";
|
|
630
|
+
Month["December"] = "DECEMBER";
|
|
631
|
+
})(Month || (Month = {}));
|
|
632
|
+
var RepeatWhen;
|
|
633
|
+
(function (RepeatWhen) {
|
|
634
|
+
RepeatWhen["InDay"] = "IN_DAY";
|
|
635
|
+
RepeatWhen["InOrdinalWeekDay"] = "IN_ORDINAL_WEEK_DAY";
|
|
636
|
+
})(RepeatWhen || (RepeatWhen = {}));
|
|
637
|
+
var OrdinalWeekDay;
|
|
638
|
+
(function (OrdinalWeekDay) {
|
|
639
|
+
OrdinalWeekDay["First"] = "FIRST";
|
|
640
|
+
OrdinalWeekDay["Second"] = "SECOND";
|
|
641
|
+
OrdinalWeekDay["Third"] = "THIRD";
|
|
642
|
+
OrdinalWeekDay["Fourth"] = "FOURTH";
|
|
643
|
+
OrdinalWeekDay["Last"] = "LAST";
|
|
644
|
+
})(OrdinalWeekDay || (OrdinalWeekDay = {}));
|
|
645
|
+
var ParticipantConfirmation;
|
|
646
|
+
(function (ParticipantConfirmation) {
|
|
647
|
+
ParticipantConfirmation["Yes"] = "YES";
|
|
648
|
+
ParticipantConfirmation["Pending"] = "PENDING";
|
|
649
|
+
ParticipantConfirmation["No"] = "NO";
|
|
650
|
+
})(ParticipantConfirmation || (ParticipantConfirmation = {}));
|
|
651
|
+
var Status;
|
|
652
|
+
(function (Status) {
|
|
653
|
+
Status["Active"] = "ACTIVE";
|
|
654
|
+
Status["Inactive"] = "INACTIVE";
|
|
655
|
+
Status["Deleted"] = "DELETED";
|
|
656
|
+
})(Status || (Status = {}));
|
|
657
|
+
|
|
658
|
+
const MINUTES_HALF_HOUR = 30;
|
|
659
|
+
const DAYS_IN_WEEK = 7;
|
|
660
|
+
const ORDINAL_THIRD_WEEK = 3;
|
|
661
|
+
const HOURS_IN_DAY = 24;
|
|
662
|
+
const MINUTES_IN_HOUR = 60;
|
|
663
|
+
const DATE_STRING_LENGTH = 10;
|
|
664
|
+
const TIME_SHORT_LENGTH = 5;
|
|
665
|
+
function formatDateToString(d) {
|
|
666
|
+
return d.toISOString().split('T')[0];
|
|
667
|
+
}
|
|
668
|
+
function toDateString(v) {
|
|
669
|
+
if (!v) {
|
|
670
|
+
return '';
|
|
671
|
+
}
|
|
672
|
+
if (v instanceof Date) {
|
|
673
|
+
return formatDateToString(v);
|
|
674
|
+
}
|
|
675
|
+
const s = String(v);
|
|
676
|
+
return s.length > DATE_STRING_LENGTH ? s.substring(0, DATE_STRING_LENGTH) : s;
|
|
677
|
+
}
|
|
678
|
+
function toTimeString(v) {
|
|
679
|
+
if (!v) {
|
|
680
|
+
return '';
|
|
681
|
+
}
|
|
682
|
+
if (v instanceof Date) {
|
|
683
|
+
return formatTime(v.getHours(), v.getMinutes());
|
|
684
|
+
}
|
|
685
|
+
const s = String(v);
|
|
686
|
+
if (s.includes('T')) {
|
|
687
|
+
const d = new Date(s);
|
|
688
|
+
return formatTime(d.getHours(), d.getMinutes());
|
|
689
|
+
}
|
|
690
|
+
return s.length === TIME_SHORT_LENGTH ? s + ':00' : s;
|
|
691
|
+
}
|
|
692
|
+
function getDefaultStartTime(d) {
|
|
693
|
+
let h = d.getHours();
|
|
694
|
+
let m = d.getMinutes();
|
|
695
|
+
if (m < MINUTES_HALF_HOUR) {
|
|
696
|
+
m = MINUTES_HALF_HOUR;
|
|
697
|
+
}
|
|
698
|
+
else {
|
|
699
|
+
h++;
|
|
700
|
+
m = 0;
|
|
701
|
+
}
|
|
702
|
+
if (h >= HOURS_IN_DAY) {
|
|
703
|
+
h = 0;
|
|
704
|
+
}
|
|
705
|
+
return formatTime(h, m);
|
|
706
|
+
}
|
|
707
|
+
function getDefaultEndTime(startTime) {
|
|
708
|
+
const [hS, mS] = startTime.split(':');
|
|
709
|
+
let h = +hS;
|
|
710
|
+
let m = +mS + MINUTES_HALF_HOUR;
|
|
711
|
+
if (m >= MINUTES_IN_HOUR) {
|
|
712
|
+
h++;
|
|
713
|
+
m -= MINUTES_IN_HOUR;
|
|
714
|
+
}
|
|
715
|
+
if (h >= HOURS_IN_DAY) {
|
|
716
|
+
h = 0;
|
|
717
|
+
}
|
|
718
|
+
return formatTime(h, m);
|
|
719
|
+
}
|
|
720
|
+
function getCurrentWeekDay(d) {
|
|
721
|
+
const days = [
|
|
722
|
+
WeekDay.Sunday, WeekDay.Monday, WeekDay.Tuesday,
|
|
723
|
+
WeekDay.Wednesday, WeekDay.Thursday, WeekDay.Friday,
|
|
724
|
+
WeekDay.Saturday
|
|
725
|
+
];
|
|
726
|
+
return days[d.getDay()];
|
|
727
|
+
}
|
|
728
|
+
function getCurrentMonth(d) {
|
|
729
|
+
const months = [
|
|
730
|
+
Month.January, Month.February, Month.March,
|
|
731
|
+
Month.April, Month.May, Month.June,
|
|
732
|
+
Month.July, Month.August, Month.September,
|
|
733
|
+
Month.October, Month.November, Month.December
|
|
734
|
+
];
|
|
735
|
+
return months[d.getMonth()];
|
|
736
|
+
}
|
|
737
|
+
function getOrdinalForDate(d) {
|
|
738
|
+
const dom = d.getDate();
|
|
739
|
+
const wn = Math.ceil(dom / DAYS_IN_WEEK);
|
|
740
|
+
const ld = new Date(d.getFullYear(), d.getMonth() + 1, 0).getDate();
|
|
741
|
+
if (dom + DAYS_IN_WEEK > ld && wn >= 4) {
|
|
742
|
+
return OrdinalWeekDay.Last;
|
|
743
|
+
}
|
|
744
|
+
switch (wn) {
|
|
745
|
+
case 1: {
|
|
746
|
+
return OrdinalWeekDay.First;
|
|
747
|
+
}
|
|
748
|
+
case 2: {
|
|
749
|
+
return OrdinalWeekDay.Second;
|
|
750
|
+
}
|
|
751
|
+
case ORDINAL_THIRD_WEEK: {
|
|
752
|
+
return OrdinalWeekDay.Third;
|
|
753
|
+
}
|
|
754
|
+
case 4: {
|
|
755
|
+
return OrdinalWeekDay.Fourth;
|
|
756
|
+
}
|
|
757
|
+
default: {
|
|
758
|
+
return OrdinalWeekDay.Last;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
function formatTime(h, m) {
|
|
763
|
+
return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}:00`;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
const ICON_PI_USER = 'pi pi-user';
|
|
767
|
+
const ORIGIN_LABELS = {
|
|
768
|
+
ACCOUNT: 'crmx.components.schedule_participant_account',
|
|
769
|
+
ACCOUNT_CONTACT: 'crmx.components.schedule_participant_account_contact',
|
|
770
|
+
COLLABORATOR: 'crmx.components.schedule_participant_collaborator',
|
|
771
|
+
EXTERNAL_PARTICIPANT: 'crmx.components.schedule_participant_external'
|
|
772
|
+
};
|
|
773
|
+
const ORIGIN_ICONS = {
|
|
774
|
+
ACCOUNT: 'pi pi-building',
|
|
775
|
+
ACCOUNT_CONTACT: 'pi pi-id-card',
|
|
776
|
+
COLLABORATOR: ICON_PI_USER,
|
|
777
|
+
EXTERNAL_PARTICIPANT: 'pi pi-user-plus'
|
|
778
|
+
};
|
|
779
|
+
function getOriginLabel(t, o) {
|
|
780
|
+
return t.translate(ORIGIN_LABELS[o] ?? o);
|
|
781
|
+
}
|
|
782
|
+
function getOriginIcon(o) {
|
|
783
|
+
return ORIGIN_ICONS[o] ?? ICON_PI_USER;
|
|
784
|
+
}
|
|
785
|
+
function getParticipantName(p) {
|
|
786
|
+
const candidates = [
|
|
787
|
+
p.collaborator?.name,
|
|
788
|
+
p.account?.name,
|
|
789
|
+
p.accountContact?.name,
|
|
790
|
+
p.externalParticipant?.name
|
|
791
|
+
];
|
|
792
|
+
return candidates.find(name => name != null) ?? '-';
|
|
793
|
+
}
|
|
794
|
+
function getParticipantType(t, p) {
|
|
795
|
+
if (p.collaborator) {
|
|
796
|
+
return t.translate('crmx.components.schedule_participant_collaborator');
|
|
797
|
+
}
|
|
798
|
+
if (p.account) {
|
|
799
|
+
return t.translate('crmx.components.schedule_participant_account');
|
|
800
|
+
}
|
|
801
|
+
if (p.accountContact) {
|
|
802
|
+
return t.translate('crmx.components.schedule_participant_account_contact');
|
|
803
|
+
}
|
|
804
|
+
if (p.externalParticipant) {
|
|
805
|
+
return t.translate('crmx.components.schedule_participant_external');
|
|
806
|
+
}
|
|
807
|
+
return '-';
|
|
808
|
+
}
|
|
809
|
+
function getParticipantTypeIcon(p) {
|
|
810
|
+
if (p.collaborator) {
|
|
811
|
+
return ICON_PI_USER;
|
|
812
|
+
}
|
|
813
|
+
if (p.account) {
|
|
814
|
+
return 'pi pi-building';
|
|
815
|
+
}
|
|
816
|
+
if (p.accountContact) {
|
|
817
|
+
return 'pi pi-id-card';
|
|
818
|
+
}
|
|
819
|
+
if (p.externalParticipant) {
|
|
820
|
+
return 'pi pi-user-plus';
|
|
821
|
+
}
|
|
822
|
+
return ICON_PI_USER;
|
|
823
|
+
}
|
|
824
|
+
function getPrioritySeverity(p) {
|
|
825
|
+
switch (p) {
|
|
826
|
+
case SchedulePriority.Low: {
|
|
827
|
+
return 'success';
|
|
828
|
+
}
|
|
829
|
+
case SchedulePriority.Medium: {
|
|
830
|
+
return 'info';
|
|
831
|
+
}
|
|
832
|
+
case SchedulePriority.High: {
|
|
833
|
+
return 'warn';
|
|
834
|
+
}
|
|
835
|
+
case SchedulePriority.Critical: {
|
|
836
|
+
return 'danger';
|
|
837
|
+
}
|
|
838
|
+
default: {
|
|
839
|
+
return 'info';
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
function getPriorityLabel(t, p) {
|
|
844
|
+
return t.translate(`crmx.components.schedule_priority_${p.toLowerCase()}`);
|
|
845
|
+
}
|
|
846
|
+
function getConfirmationSeverity(c) {
|
|
847
|
+
switch (c) {
|
|
848
|
+
case 'YES': {
|
|
849
|
+
return 'success';
|
|
850
|
+
}
|
|
851
|
+
case 'NO': {
|
|
852
|
+
return 'danger';
|
|
853
|
+
}
|
|
854
|
+
default: {
|
|
855
|
+
return 'warn';
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
function getConfirmationLabel(t, c) {
|
|
860
|
+
switch (c) {
|
|
861
|
+
case 'YES': {
|
|
862
|
+
return t.translate('crmx.components.schedule_confirmation_yes');
|
|
863
|
+
}
|
|
864
|
+
case 'NO': {
|
|
865
|
+
return t.translate('crmx.components.schedule_confirmation_no');
|
|
866
|
+
}
|
|
867
|
+
default: {
|
|
868
|
+
return t.translate('crmx.components.schedule_confirmation_pending');
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
class ScheduleService {
|
|
874
|
+
http;
|
|
875
|
+
entityUrl = 'crmx/schedule/entities/schedule';
|
|
876
|
+
actionsUrl = 'crmx/schedule/actions';
|
|
877
|
+
queriesUrl = 'crmx/schedule/queries';
|
|
878
|
+
constructor(http) {
|
|
879
|
+
this.http = http;
|
|
880
|
+
}
|
|
881
|
+
get(id) {
|
|
882
|
+
return this.http.get(`/${this.entityUrl}/${id}`);
|
|
883
|
+
}
|
|
884
|
+
insert(entity) {
|
|
885
|
+
return this.http.post(`/${this.entityUrl}`, entity);
|
|
886
|
+
}
|
|
887
|
+
update(id, entity) {
|
|
888
|
+
return this.http.put(`/${this.entityUrl}/${id}`, entity);
|
|
889
|
+
}
|
|
890
|
+
delete(id) {
|
|
891
|
+
return this.http.delete(`/${this.entityUrl}/${id}`);
|
|
892
|
+
}
|
|
893
|
+
getRecurrencesByDate(startDate, endDate) {
|
|
894
|
+
return this.http.post(`/${this.queriesUrl}/getRecurrencesByDate`, { startDate, endDate });
|
|
895
|
+
}
|
|
896
|
+
generateRecurrenceDescription(payload) {
|
|
897
|
+
return this.http.post(`/${this.queriesUrl}/generateRecurrenceDescription`, payload);
|
|
898
|
+
}
|
|
899
|
+
acceptSchedule(scheduleId, participantId, date) {
|
|
900
|
+
return this.http.post(`/${this.actionsUrl}/acceptSchedule`, { scheduleId, participantId, date });
|
|
901
|
+
}
|
|
902
|
+
rejectSchedule(scheduleId, participantId, date) {
|
|
903
|
+
return this.http.post(`/${this.actionsUrl}/rejectSchedule`, { scheduleId, participantId, date });
|
|
904
|
+
}
|
|
905
|
+
cancelSchedule(scheduleId, date) {
|
|
906
|
+
return this.http.post(`/${this.actionsUrl}/cancelSchedule`, { scheduleId, date });
|
|
907
|
+
}
|
|
908
|
+
manageParticipants(scheduleId, participants) {
|
|
909
|
+
return this.http.post(`/crmx/schedule/signals/manageScheduleParticipants`, { scheduleId, ...participants });
|
|
910
|
+
}
|
|
911
|
+
listParticipants(scheduleId) {
|
|
912
|
+
return this.http.get(`/${this.entityUrl}/${scheduleId}/participants`);
|
|
913
|
+
}
|
|
914
|
+
searchParticipantLookup(filter, size = 10, offset = 0) {
|
|
915
|
+
return this.http.post(`/${this.queriesUrl}/listParticipants`, { filter, size, offset, orderBy: 'name ASC' });
|
|
916
|
+
}
|
|
917
|
+
list(params = {}) {
|
|
918
|
+
let httpParams = new HttpParams();
|
|
919
|
+
if (params.size) {
|
|
920
|
+
httpParams = httpParams.set('size', String(params.size));
|
|
921
|
+
}
|
|
922
|
+
if (params.filterQuery) {
|
|
923
|
+
httpParams = httpParams.set('filter', params.filterQuery);
|
|
924
|
+
}
|
|
925
|
+
return this.http.get(`/${this.entityUrl}`, { params: httpParams });
|
|
926
|
+
}
|
|
927
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScheduleService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
928
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScheduleService, providedIn: 'root' });
|
|
929
|
+
}
|
|
930
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScheduleService, decorators: [{
|
|
931
|
+
type: Injectable,
|
|
932
|
+
args: [{ providedIn: 'root' }]
|
|
933
|
+
}], ctorParameters: () => [{ type: i1.HttpClient }] });
|
|
934
|
+
|
|
935
|
+
class ScheduleTypeService {
|
|
936
|
+
http;
|
|
937
|
+
entityUrl = 'crmx/schedule/entities/scheduleType';
|
|
938
|
+
constructor(http) {
|
|
939
|
+
this.http = http;
|
|
940
|
+
}
|
|
941
|
+
list(params = {}) {
|
|
942
|
+
let httpParams = new HttpParams();
|
|
943
|
+
if (params.size) {
|
|
944
|
+
httpParams = httpParams.set('size', String(params.size));
|
|
945
|
+
}
|
|
946
|
+
const statusFilter = "status != 'DELETED'";
|
|
947
|
+
const filter = params.filterQuery
|
|
948
|
+
? `(${params.filterQuery}) and ${statusFilter}`
|
|
949
|
+
: statusFilter;
|
|
950
|
+
httpParams = httpParams.set('filter', filter);
|
|
951
|
+
return this.http.get(`/${this.entityUrl}`, { params: httpParams });
|
|
952
|
+
}
|
|
953
|
+
get(id) {
|
|
954
|
+
return this.http.get(`/${this.entityUrl}/${id}`);
|
|
955
|
+
}
|
|
956
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScheduleTypeService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
957
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScheduleTypeService, providedIn: 'root' });
|
|
958
|
+
}
|
|
959
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScheduleTypeService, decorators: [{
|
|
960
|
+
type: Injectable,
|
|
961
|
+
args: [{ providedIn: 'root' }]
|
|
962
|
+
}], ctorParameters: () => [{ type: i1.HttpClient }] });
|
|
963
|
+
|
|
964
|
+
/** S109: Extract magic numbers to named constants */
|
|
965
|
+
const MAX_NAME_LENGTH = 255;
|
|
966
|
+
const DEBOUNCE_MS = 500;
|
|
967
|
+
const PARTICIPANT_SEARCH_LIMIT = 5;
|
|
968
|
+
class ScheduleFormComponent {
|
|
969
|
+
fb;
|
|
970
|
+
scheduleService;
|
|
971
|
+
scheduleTypeService;
|
|
972
|
+
currentCollaboratorService;
|
|
973
|
+
t;
|
|
974
|
+
visible = false;
|
|
975
|
+
selectedDate = new Date();
|
|
976
|
+
visibleChange = new EventEmitter();
|
|
977
|
+
saved = new EventEmitter();
|
|
978
|
+
detailFormComponent;
|
|
979
|
+
scheduleDetailFields = [];
|
|
980
|
+
entityDataForForm = null;
|
|
981
|
+
scheduleForm;
|
|
982
|
+
isEditing = false;
|
|
983
|
+
currentCollaboratorId = null;
|
|
984
|
+
scheduleTypes = [];
|
|
985
|
+
participants = [];
|
|
986
|
+
participantsLoading = false;
|
|
987
|
+
recurrenceDescription = '';
|
|
988
|
+
/** S2933: Mark as readonly */
|
|
989
|
+
recurrenceChange$ = new Subject();
|
|
990
|
+
participantSuggestions = [];
|
|
991
|
+
selectedParticipantLookup = null;
|
|
992
|
+
addedParticipants = [];
|
|
993
|
+
priorityOptions = [];
|
|
994
|
+
recurrenceOptions = [];
|
|
995
|
+
weekDayOptions = [];
|
|
996
|
+
repeatWhenOptions = [];
|
|
997
|
+
ordinalOptions = [];
|
|
998
|
+
monthOptions = [];
|
|
999
|
+
/** S2933: Mark constructor-injected services as readonly */
|
|
1000
|
+
constructor(fb, scheduleService, scheduleTypeService, currentCollaboratorService, t) {
|
|
1001
|
+
this.fb = fb;
|
|
1002
|
+
this.scheduleService = scheduleService;
|
|
1003
|
+
this.scheduleTypeService = scheduleTypeService;
|
|
1004
|
+
this.currentCollaboratorService = currentCollaboratorService;
|
|
1005
|
+
this.t = t;
|
|
1006
|
+
}
|
|
1007
|
+
ngOnInit() {
|
|
1008
|
+
this.initOptions();
|
|
1009
|
+
this.initDetailFields();
|
|
1010
|
+
this.initForm();
|
|
1011
|
+
this.loadScheduleTypes();
|
|
1012
|
+
this.loadCollaborator();
|
|
1013
|
+
this.setupRecurrenceDescriptionWatcher();
|
|
1014
|
+
}
|
|
1015
|
+
loadCollaborator() {
|
|
1016
|
+
this.currentCollaboratorService.load().subscribe({
|
|
1017
|
+
next: (collab) => {
|
|
1018
|
+
this.currentCollaboratorId = collab?.id ?? null;
|
|
1019
|
+
},
|
|
1020
|
+
error: () => {
|
|
1021
|
+
this.currentCollaboratorId = null;
|
|
1022
|
+
}
|
|
1023
|
+
});
|
|
1024
|
+
}
|
|
1025
|
+
initOptions() {
|
|
1026
|
+
this.priorityOptions = [
|
|
1027
|
+
{ label: this.t.translate('crmx.components.schedule_priority_low'), value: SchedulePriority.Low },
|
|
1028
|
+
{ label: this.t.translate('crmx.components.schedule_priority_medium'), value: SchedulePriority.Medium },
|
|
1029
|
+
{ label: this.t.translate('crmx.components.schedule_priority_high'), value: SchedulePriority.High },
|
|
1030
|
+
{ label: this.t.translate('crmx.components.schedule_priority_critical'), value: SchedulePriority.Critical }
|
|
1031
|
+
];
|
|
1032
|
+
this.recurrenceOptions = [
|
|
1033
|
+
{ label: this.t.translate('crmx.components.schedule_recurrence_daily'), value: ScheduleRecurrence.Daily },
|
|
1034
|
+
{ label: this.t.translate('crmx.components.schedule_recurrence_weekly'), value: ScheduleRecurrence.Weekly },
|
|
1035
|
+
{ label: this.t.translate('crmx.components.schedule_recurrence_monthly'), value: ScheduleRecurrence.Monthly },
|
|
1036
|
+
{ label: this.t.translate('crmx.components.schedule_recurrence_yearly'), value: ScheduleRecurrence.Yearly }
|
|
1037
|
+
];
|
|
1038
|
+
this.weekDayOptions = [
|
|
1039
|
+
{ label: this.t.translate('crmx.components.schedule_sunday'), value: WeekDay.Sunday },
|
|
1040
|
+
{ label: this.t.translate('crmx.components.schedule_monday'), value: WeekDay.Monday },
|
|
1041
|
+
{ label: this.t.translate('crmx.components.schedule_tuesday'), value: WeekDay.Tuesday },
|
|
1042
|
+
{ label: this.t.translate('crmx.components.schedule_wednesday'), value: WeekDay.Wednesday },
|
|
1043
|
+
{ label: this.t.translate('crmx.components.schedule_thursday'), value: WeekDay.Thursday },
|
|
1044
|
+
{ label: this.t.translate('crmx.components.schedule_friday'), value: WeekDay.Friday },
|
|
1045
|
+
{ label: this.t.translate('crmx.components.schedule_saturday'), value: WeekDay.Saturday }
|
|
1046
|
+
];
|
|
1047
|
+
this.repeatWhenOptions = [
|
|
1048
|
+
{ label: this.t.translate('crmx.components.schedule_repeat_in_day'), value: RepeatWhen.InDay },
|
|
1049
|
+
{ label: this.t.translate('crmx.components.schedule_repeat_in_ordinal_week_day'), value: RepeatWhen.InOrdinalWeekDay }
|
|
1050
|
+
];
|
|
1051
|
+
this.ordinalOptions = [
|
|
1052
|
+
{ label: this.t.translate('crmx.components.schedule_ordinal_first'), value: OrdinalWeekDay.First },
|
|
1053
|
+
{ label: this.t.translate('crmx.components.schedule_ordinal_second'), value: OrdinalWeekDay.Second },
|
|
1054
|
+
{ label: this.t.translate('crmx.components.schedule_ordinal_third'), value: OrdinalWeekDay.Third },
|
|
1055
|
+
{ label: this.t.translate('crmx.components.schedule_ordinal_fourth'), value: OrdinalWeekDay.Fourth },
|
|
1056
|
+
{ label: this.t.translate('crmx.components.schedule_ordinal_last'), value: OrdinalWeekDay.Last }
|
|
1057
|
+
];
|
|
1058
|
+
this.monthOptions = Object.values(Month).map(m => ({
|
|
1059
|
+
label: this.t.translate(`crmx.components.schedule_${m.toLowerCase()}`), value: m
|
|
1060
|
+
}));
|
|
1061
|
+
}
|
|
1062
|
+
initDetailFields() {
|
|
1063
|
+
const now = new Date();
|
|
1064
|
+
const defaultStart = this.getDefaultStartTime(now);
|
|
1065
|
+
const defaultEnd = this.getDefaultEndTime(defaultStart);
|
|
1066
|
+
const fullRow = { xl: 12, lg: 12, md: 12, sm: 12 };
|
|
1067
|
+
const halfRow = { xl: 6, lg: 6, md: 6, sm: 12 };
|
|
1068
|
+
this.scheduleDetailFields = [
|
|
1069
|
+
{ field: 'name', label: this.t.translate('crmx.components.schedule_name'), type: 'text', required: true, validators: [Validators.required, Validators.maxLength(MAX_NAME_LENGTH)], placeholder: this.t.translate('crmx.components.schedule_enter_name'), maxLength: MAX_NAME_LENGTH, size: fullRow },
|
|
1070
|
+
{ field: 'priority', label: this.t.translate('crmx.components.schedule_priority'), type: 'dropdown', required: true, validators: [Validators.required], options: this.priorityOptions, optionLabel: 'label', optionValue: 'value', defaultValue: SchedulePriority.Medium, size: fullRow },
|
|
1071
|
+
{ field: 'type', label: this.t.translate('crmx.components.schedule_type'), type: 'lookup', lookupService: this.scheduleTypeService, lookupDisplayField: 'name', lookupValueField: 'id', lookupSearchFields: ['name'], showClear: true, lookupAutocomplete: true, lookupColumns: [{ field: 'name', header: this.t.translate('crmx.components.schedule_name') }], lookupFilters: "status = 'ACTIVE'", placeholder: this.t.translate('crmx.components.schedule_select_type'), size: fullRow },
|
|
1072
|
+
{ field: 'startDate', label: this.t.translate('crmx.components.schedule_start_date'), type: 'date', required: true, validators: [Validators.required], defaultValue: formatDateToString(now), size: (v) => v['withRecurrence'] ? halfRow : fullRow },
|
|
1073
|
+
{ field: 'endDate', label: this.t.translate('crmx.components.schedule_end_date'), type: 'date', visibleWhen: (v) => v['withRecurrence'] === true, size: halfRow },
|
|
1074
|
+
{ field: 'startTime', label: this.t.translate('crmx.components.schedule_start_time'), type: 'time', defaultValue: defaultStart, visibleWhen: (v) => v['allDay'] !== true, size: halfRow },
|
|
1075
|
+
{ field: 'endTime', label: this.t.translate('crmx.components.schedule_end_time'), type: 'time', defaultValue: defaultEnd, visibleWhen: (v) => v['allDay'] !== true, size: halfRow },
|
|
1076
|
+
{ field: 'allDay', label: this.t.translate('crmx.components.schedule_all_day'), type: 'checkbox', defaultValue: false, size: halfRow },
|
|
1077
|
+
{ field: 'withRecurrence', label: this.t.translate('crmx.components.schedule_with_recurrence'), type: 'checkbox', defaultValue: false, size: halfRow },
|
|
1078
|
+
{ field: 'comments', label: this.t.translate('crmx.components.schedule_comments'), type: 'textarea', placeholder: this.t.translate('crmx.components.schedule_enter_comments'), rows: 3, size: fullRow }
|
|
1079
|
+
];
|
|
1080
|
+
}
|
|
1081
|
+
onDetailFormReady(form) {
|
|
1082
|
+
this.scheduleForm = form;
|
|
1083
|
+
this.addRecurrenceControls();
|
|
1084
|
+
this.scheduleForm.valueChanges.subscribe(() => this.recurrenceChange$.next());
|
|
1085
|
+
this.setupRecurrenceFormWatchers();
|
|
1086
|
+
}
|
|
1087
|
+
/** S121: Add braces to all if statements */
|
|
1088
|
+
addRecurrenceControls() {
|
|
1089
|
+
const now = new Date();
|
|
1090
|
+
if (!this.scheduleForm.contains('id')) {
|
|
1091
|
+
this.scheduleForm.addControl('id', this.fb.control(null));
|
|
1092
|
+
}
|
|
1093
|
+
if (!this.scheduleForm.contains('recurrence')) {
|
|
1094
|
+
this.scheduleForm.addControl('recurrence', this.fb.control(ScheduleRecurrence.Daily));
|
|
1095
|
+
}
|
|
1096
|
+
if (!this.scheduleForm.contains('recurrenceInterval')) {
|
|
1097
|
+
this.scheduleForm.addControl('recurrenceInterval', this.fb.control(1));
|
|
1098
|
+
}
|
|
1099
|
+
if (!this.scheduleForm.contains('weekDays')) {
|
|
1100
|
+
this.scheduleForm.addControl('weekDays', this.fb.control([getCurrentWeekDay(now)]));
|
|
1101
|
+
}
|
|
1102
|
+
if (!this.scheduleForm.contains('repeatWhen')) {
|
|
1103
|
+
this.scheduleForm.addControl('repeatWhen', this.fb.control(RepeatWhen.InDay));
|
|
1104
|
+
}
|
|
1105
|
+
if (!this.scheduleForm.contains('repeatWhenDay')) {
|
|
1106
|
+
this.scheduleForm.addControl('repeatWhenDay', this.fb.control(now.getDate()));
|
|
1107
|
+
}
|
|
1108
|
+
if (!this.scheduleForm.contains('repeatWhenOrdinalWeekDay')) {
|
|
1109
|
+
this.scheduleForm.addControl('repeatWhenOrdinalWeekDay', this.fb.control(getOrdinalForDate(now)));
|
|
1110
|
+
}
|
|
1111
|
+
if (!this.scheduleForm.contains('repeatWhenWeekMonth')) {
|
|
1112
|
+
this.scheduleForm.addControl('repeatWhenWeekMonth', this.fb.control(getCurrentWeekDay(now)));
|
|
1113
|
+
}
|
|
1114
|
+
if (!this.scheduleForm.contains('repeatWhenMonth')) {
|
|
1115
|
+
this.scheduleForm.addControl('repeatWhenMonth', this.fb.control(getCurrentMonth(now)));
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
/**
|
|
1119
|
+
* S1541: Break setupRecurrenceFormWatchers into smaller helpers
|
|
1120
|
+
* to reduce cyclomatic complexity
|
|
1121
|
+
*/
|
|
1122
|
+
setupRecurrenceFormWatchers() {
|
|
1123
|
+
const d = this.selectedDate || new Date();
|
|
1124
|
+
this.watchRecurrenceChanges(d);
|
|
1125
|
+
this.watchRepeatWhenChanges(d);
|
|
1126
|
+
this.watchWithRecurrenceChanges(d);
|
|
1127
|
+
}
|
|
1128
|
+
watchRecurrenceChanges(d) {
|
|
1129
|
+
this.scheduleForm.get('recurrence')?.valueChanges.subscribe((rec) => {
|
|
1130
|
+
this.handleRecurrenceWeekDays(rec, d);
|
|
1131
|
+
this.handleRecurrenceMonthlyYearly(rec, d);
|
|
1132
|
+
this.handleRecurrenceYearlyMonth(rec, d);
|
|
1133
|
+
this.recurrenceChange$.next();
|
|
1134
|
+
});
|
|
1135
|
+
}
|
|
1136
|
+
handleRecurrenceWeekDays(rec, d) {
|
|
1137
|
+
if (rec === ScheduleRecurrence.Weekly) {
|
|
1138
|
+
const current = this.scheduleForm.get('weekDays')?.value;
|
|
1139
|
+
if (!current || current.length === 0) {
|
|
1140
|
+
this.scheduleForm.patchValue({ weekDays: [getCurrentWeekDay(d)] }, { emitEvent: false });
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
else {
|
|
1144
|
+
this.scheduleForm.patchValue({ weekDays: [] }, { emitEvent: false });
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
handleRecurrenceMonthlyYearly(rec, d) {
|
|
1148
|
+
if (rec === ScheduleRecurrence.Monthly ||
|
|
1149
|
+
rec === ScheduleRecurrence.Yearly) {
|
|
1150
|
+
this.scheduleForm.patchValue({
|
|
1151
|
+
repeatWhen: this.scheduleForm.get('repeatWhen')?.value ?? RepeatWhen.InDay,
|
|
1152
|
+
repeatWhenDay: this.scheduleForm.get('repeatWhenDay')?.value ?? d.getDate(),
|
|
1153
|
+
repeatWhenOrdinalWeekDay: this.scheduleForm.get('repeatWhenOrdinalWeekDay')?.value
|
|
1154
|
+
?? getOrdinalForDate(d),
|
|
1155
|
+
repeatWhenWeekMonth: this.scheduleForm.get('repeatWhenWeekMonth')?.value
|
|
1156
|
+
?? getCurrentWeekDay(d)
|
|
1157
|
+
}, { emitEvent: false });
|
|
1158
|
+
}
|
|
1159
|
+
else {
|
|
1160
|
+
this.scheduleForm.patchValue({
|
|
1161
|
+
repeatWhen: null,
|
|
1162
|
+
repeatWhenDay: null,
|
|
1163
|
+
repeatWhenOrdinalWeekDay: null,
|
|
1164
|
+
repeatWhenWeekMonth: null,
|
|
1165
|
+
repeatWhenMonth: null
|
|
1166
|
+
}, { emitEvent: false });
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
handleRecurrenceYearlyMonth(rec, d) {
|
|
1170
|
+
if (rec === ScheduleRecurrence.Yearly) {
|
|
1171
|
+
this.scheduleForm.patchValue({
|
|
1172
|
+
repeatWhenMonth: this.scheduleForm.get('repeatWhenMonth')?.value
|
|
1173
|
+
?? getCurrentMonth(d)
|
|
1174
|
+
}, { emitEvent: false });
|
|
1175
|
+
}
|
|
1176
|
+
else {
|
|
1177
|
+
this.scheduleForm.patchValue({ repeatWhenMonth: null }, { emitEvent: false });
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
watchRepeatWhenChanges(d) {
|
|
1181
|
+
this.scheduleForm.get('repeatWhen')?.valueChanges.subscribe((rw) => {
|
|
1182
|
+
if (rw === RepeatWhen.InDay) {
|
|
1183
|
+
this.scheduleForm.patchValue({
|
|
1184
|
+
repeatWhenDay: this.scheduleForm.get('repeatWhenDay')?.value ?? d.getDate(),
|
|
1185
|
+
repeatWhenOrdinalWeekDay: null,
|
|
1186
|
+
repeatWhenWeekMonth: null
|
|
1187
|
+
}, { emitEvent: false });
|
|
1188
|
+
}
|
|
1189
|
+
else if (rw === RepeatWhen.InOrdinalWeekDay) {
|
|
1190
|
+
this.scheduleForm.patchValue({
|
|
1191
|
+
repeatWhenDay: null,
|
|
1192
|
+
repeatWhenOrdinalWeekDay: this.scheduleForm.get('repeatWhenOrdinalWeekDay')?.value
|
|
1193
|
+
?? getOrdinalForDate(d),
|
|
1194
|
+
repeatWhenWeekMonth: this.scheduleForm.get('repeatWhenWeekMonth')?.value
|
|
1195
|
+
?? getCurrentWeekDay(d)
|
|
1196
|
+
}, { emitEvent: false });
|
|
1197
|
+
}
|
|
1198
|
+
else {
|
|
1199
|
+
// No action needed for other repeatWhen values
|
|
1200
|
+
}
|
|
1201
|
+
this.recurrenceChange$.next();
|
|
1202
|
+
});
|
|
1203
|
+
}
|
|
1204
|
+
watchWithRecurrenceChanges(d) {
|
|
1205
|
+
this.scheduleForm.get('withRecurrence')?.valueChanges.subscribe(() => {
|
|
1206
|
+
const enabled = this.scheduleForm.get('withRecurrence')?.value === true;
|
|
1207
|
+
if (enabled) {
|
|
1208
|
+
this.onRecurrenceEnabled(d);
|
|
1209
|
+
}
|
|
1210
|
+
else {
|
|
1211
|
+
this.onRecurrenceDisabled();
|
|
1212
|
+
}
|
|
1213
|
+
});
|
|
1214
|
+
}
|
|
1215
|
+
onRecurrenceEnabled(d) {
|
|
1216
|
+
this.resetRecurrenceDefaults(d);
|
|
1217
|
+
this.recurrenceChange$.next();
|
|
1218
|
+
}
|
|
1219
|
+
onRecurrenceDisabled() {
|
|
1220
|
+
this.recurrenceDescription = '';
|
|
1221
|
+
}
|
|
1222
|
+
initForm() {
|
|
1223
|
+
const now = new Date();
|
|
1224
|
+
const defaultStart = this.getDefaultStartTime(now);
|
|
1225
|
+
const defaultEnd = this.getDefaultEndTime(defaultStart);
|
|
1226
|
+
this.scheduleForm = this.fb.group({
|
|
1227
|
+
id: [null],
|
|
1228
|
+
name: ['', [Validators.required, Validators.maxLength(MAX_NAME_LENGTH)]],
|
|
1229
|
+
type: [null],
|
|
1230
|
+
priority: [SchedulePriority.Medium, Validators.required],
|
|
1231
|
+
allDay: [false],
|
|
1232
|
+
withRecurrence: [false],
|
|
1233
|
+
startDate: [
|
|
1234
|
+
formatDateToString(this.selectedDate || now),
|
|
1235
|
+
Validators.required
|
|
1236
|
+
],
|
|
1237
|
+
endDate: [null],
|
|
1238
|
+
startTime: [defaultStart],
|
|
1239
|
+
endTime: [defaultEnd],
|
|
1240
|
+
recurrence: [ScheduleRecurrence.Daily],
|
|
1241
|
+
recurrenceInterval: [1],
|
|
1242
|
+
weekDays: [[getCurrentWeekDay(now)]],
|
|
1243
|
+
repeatWhen: [RepeatWhen.InDay],
|
|
1244
|
+
repeatWhenDay: [now.getDate()],
|
|
1245
|
+
repeatWhenOrdinalWeekDay: [getOrdinalForDate(now)],
|
|
1246
|
+
repeatWhenWeekMonth: [getCurrentWeekDay(now)],
|
|
1247
|
+
repeatWhenMonth: [getCurrentMonth(now)],
|
|
1248
|
+
comments: ['']
|
|
1249
|
+
});
|
|
1250
|
+
}
|
|
1251
|
+
setupRecurrenceDescriptionWatcher() {
|
|
1252
|
+
this.recurrenceChange$.pipe(debounceTime(DEBOUNCE_MS)).subscribe(() => this.fetchRecurrenceDescription());
|
|
1253
|
+
}
|
|
1254
|
+
fetchRecurrenceDescription() {
|
|
1255
|
+
if (!this.scheduleForm) {
|
|
1256
|
+
return;
|
|
1257
|
+
}
|
|
1258
|
+
const v = this.scheduleForm.value;
|
|
1259
|
+
if (!v.withRecurrence || !v.startDate) {
|
|
1260
|
+
this.recurrenceDescription = '';
|
|
1261
|
+
return;
|
|
1262
|
+
}
|
|
1263
|
+
this.scheduleService.generateRecurrenceDescription(this.buildRecurrencePayload(v)).subscribe({
|
|
1264
|
+
next: (r) => {
|
|
1265
|
+
this.recurrenceDescription = r.description ?? '';
|
|
1266
|
+
},
|
|
1267
|
+
error: () => {
|
|
1268
|
+
this.recurrenceDescription = '';
|
|
1269
|
+
}
|
|
1270
|
+
});
|
|
1271
|
+
}
|
|
1272
|
+
buildRecurrencePayload(v) {
|
|
1273
|
+
return {
|
|
1274
|
+
...this.buildDateTimePayload(v),
|
|
1275
|
+
allDay: v['allDay'] || false,
|
|
1276
|
+
withRecurrence: true,
|
|
1277
|
+
recurrenceInterval: v['recurrenceInterval'] || 1,
|
|
1278
|
+
recurrence: v['recurrence'],
|
|
1279
|
+
...this.buildNullableRecurrenceFields(v)
|
|
1280
|
+
};
|
|
1281
|
+
}
|
|
1282
|
+
buildDateTimePayload(v) {
|
|
1283
|
+
return {
|
|
1284
|
+
startDate: toDateString(v['startDate']),
|
|
1285
|
+
endDate: v['endDate'] ? toDateString(v['endDate']) : null,
|
|
1286
|
+
startTime: v['startTime'] ? toTimeString(v['startTime']) : null,
|
|
1287
|
+
endTime: v['endTime'] ? toTimeString(v['endTime']) : null
|
|
1288
|
+
};
|
|
1289
|
+
}
|
|
1290
|
+
buildNullableRecurrenceFields(v) {
|
|
1291
|
+
return {
|
|
1292
|
+
weekDays: v['weekDays'] ?? null,
|
|
1293
|
+
repeatWhen: v['repeatWhen'] ?? null,
|
|
1294
|
+
repeatWhenDay: v['repeatWhenDay'] ?? null,
|
|
1295
|
+
repeatWhenOrdinalWeekDay: v['repeatWhenOrdinalWeekDay'] ?? null,
|
|
1296
|
+
repeatWhenWeekMonth: v['repeatWhenWeekMonth'] ?? null,
|
|
1297
|
+
repeatWhenMonth: v['repeatWhenMonth'] ?? null
|
|
1298
|
+
};
|
|
1299
|
+
}
|
|
1300
|
+
loadScheduleTypes() {
|
|
1301
|
+
this.scheduleTypeService.list({
|
|
1302
|
+
size: 100,
|
|
1303
|
+
filterQuery: "status = 'ACTIVE'"
|
|
1304
|
+
}).subscribe({
|
|
1305
|
+
next: (r) => {
|
|
1306
|
+
this.scheduleTypes = r.contents;
|
|
1307
|
+
}
|
|
1308
|
+
});
|
|
1309
|
+
}
|
|
1310
|
+
openNew() {
|
|
1311
|
+
this.isEditing = false;
|
|
1312
|
+
const now = new Date();
|
|
1313
|
+
const defaultStart = this.getDefaultStartTime(now);
|
|
1314
|
+
const defaultEnd = this.getDefaultEndTime(defaultStart);
|
|
1315
|
+
this.entityDataForForm = null;
|
|
1316
|
+
if (this.detailFormComponent) {
|
|
1317
|
+
this.detailFormComponent.resetForm();
|
|
1318
|
+
}
|
|
1319
|
+
this.entityDataForForm = {
|
|
1320
|
+
startDate: formatDateToString(this.selectedDate || now),
|
|
1321
|
+
priority: SchedulePriority.Medium,
|
|
1322
|
+
allDay: false,
|
|
1323
|
+
withRecurrence: false,
|
|
1324
|
+
startTime: defaultStart,
|
|
1325
|
+
endTime: defaultEnd
|
|
1326
|
+
};
|
|
1327
|
+
this.resetRecurrenceDefaults(this.selectedDate || now);
|
|
1328
|
+
this.recurrenceDescription = '';
|
|
1329
|
+
this.participants = [];
|
|
1330
|
+
this.addedParticipants = [];
|
|
1331
|
+
this.selectedParticipantLookup = null;
|
|
1332
|
+
this.visible = true;
|
|
1333
|
+
this.visibleChange.emit(true);
|
|
1334
|
+
}
|
|
1335
|
+
openEdit(scheduleId) {
|
|
1336
|
+
this.isEditing = true;
|
|
1337
|
+
this.participants = [];
|
|
1338
|
+
this.addedParticipants = [];
|
|
1339
|
+
this.selectedParticipantLookup = null;
|
|
1340
|
+
this.scheduleService.get(scheduleId).subscribe({
|
|
1341
|
+
next: (data) => {
|
|
1342
|
+
this.entityDataForForm = { ...data, type: data.type ?? null };
|
|
1343
|
+
this.loadParticipants(scheduleId);
|
|
1344
|
+
this.visible = true;
|
|
1345
|
+
this.visibleChange.emit(true);
|
|
1346
|
+
setTimeout(() => {
|
|
1347
|
+
if (this.scheduleForm) {
|
|
1348
|
+
this.scheduleForm.patchValue({
|
|
1349
|
+
id: data.id,
|
|
1350
|
+
recurrence: data.recurrence,
|
|
1351
|
+
recurrenceInterval: data.recurrenceInterval,
|
|
1352
|
+
weekDays: data.weekDays,
|
|
1353
|
+
repeatWhen: data.repeatWhen,
|
|
1354
|
+
repeatWhenDay: data.repeatWhenDay,
|
|
1355
|
+
repeatWhenOrdinalWeekDay: data.repeatWhenOrdinalWeekDay,
|
|
1356
|
+
repeatWhenWeekMonth: data.repeatWhenWeekMonth,
|
|
1357
|
+
repeatWhenMonth: data.repeatWhenMonth
|
|
1358
|
+
});
|
|
1359
|
+
}
|
|
1360
|
+
});
|
|
1361
|
+
}
|
|
1362
|
+
});
|
|
1363
|
+
}
|
|
1364
|
+
loadParticipants(scheduleId) {
|
|
1365
|
+
this.participantsLoading = true;
|
|
1366
|
+
this.scheduleService.listParticipants(scheduleId).subscribe({
|
|
1367
|
+
next: (r) => {
|
|
1368
|
+
this.participants = r.contents ?? [];
|
|
1369
|
+
this.addedParticipants = this.participants
|
|
1370
|
+
.filter(p => !p.organizer)
|
|
1371
|
+
.map(p => this.participantToLookup(p))
|
|
1372
|
+
.filter((p) => p !== null);
|
|
1373
|
+
this.participantsLoading = false;
|
|
1374
|
+
},
|
|
1375
|
+
error: () => {
|
|
1376
|
+
this.participantsLoading = false;
|
|
1377
|
+
}
|
|
1378
|
+
});
|
|
1379
|
+
}
|
|
1380
|
+
participantToLookup(p) {
|
|
1381
|
+
if (p.collaborator) {
|
|
1382
|
+
return {
|
|
1383
|
+
id: p.collaborator.id,
|
|
1384
|
+
name: p.collaborator.name,
|
|
1385
|
+
origin: 'COLLABORATOR'
|
|
1386
|
+
};
|
|
1387
|
+
}
|
|
1388
|
+
if (p.account) {
|
|
1389
|
+
return {
|
|
1390
|
+
id: p.account.id,
|
|
1391
|
+
name: p.account.name,
|
|
1392
|
+
origin: 'ACCOUNT'
|
|
1393
|
+
};
|
|
1394
|
+
}
|
|
1395
|
+
if (p.accountContact) {
|
|
1396
|
+
return {
|
|
1397
|
+
id: p.accountContact.id,
|
|
1398
|
+
name: p.accountContact.name,
|
|
1399
|
+
referenceName: p.accountContact.account?.name,
|
|
1400
|
+
referenceId: p.accountContact.account?.id,
|
|
1401
|
+
origin: 'ACCOUNT_CONTACT'
|
|
1402
|
+
};
|
|
1403
|
+
}
|
|
1404
|
+
if (p.externalParticipant) {
|
|
1405
|
+
return {
|
|
1406
|
+
id: p.externalParticipant.id,
|
|
1407
|
+
name: p.externalParticipant.name,
|
|
1408
|
+
origin: 'EXTERNAL_PARTICIPANT'
|
|
1409
|
+
};
|
|
1410
|
+
}
|
|
1411
|
+
return null;
|
|
1412
|
+
}
|
|
1413
|
+
onSearchParticipants(event) {
|
|
1414
|
+
this.scheduleService.searchParticipantLookup(event.query ?? '', PARTICIPANT_SEARCH_LIMIT).subscribe({
|
|
1415
|
+
next: (r) => {
|
|
1416
|
+
const addedIds = new Set(this.addedParticipants.map(p => p.id + p.origin));
|
|
1417
|
+
this.participantSuggestions = (r.contents ?? [])
|
|
1418
|
+
.filter(p => !addedIds.has(p.id + p.origin));
|
|
1419
|
+
},
|
|
1420
|
+
error: () => {
|
|
1421
|
+
this.participantSuggestions = [];
|
|
1422
|
+
}
|
|
1423
|
+
});
|
|
1424
|
+
}
|
|
1425
|
+
onSelectParticipant(participant) {
|
|
1426
|
+
if (!this.addedParticipants.some(p => p.id === participant.id && p.origin === participant.origin)) {
|
|
1427
|
+
this.addedParticipants = [...this.addedParticipants, participant];
|
|
1428
|
+
}
|
|
1429
|
+
setTimeout(() => {
|
|
1430
|
+
this.selectedParticipantLookup = null;
|
|
1431
|
+
});
|
|
1432
|
+
}
|
|
1433
|
+
onRemoveParticipant(participant) {
|
|
1434
|
+
this.addedParticipants = this.addedParticipants.filter(p => !(p.id === participant.id && p.origin === participant.origin));
|
|
1435
|
+
}
|
|
1436
|
+
/**
|
|
1437
|
+
* S1541: Break onSave into smaller helpers to reduce complexity
|
|
1438
|
+
* S121/S2681: Add braces to all if statements
|
|
1439
|
+
*/
|
|
1440
|
+
onSave() {
|
|
1441
|
+
if (this.scheduleForm.invalid) {
|
|
1442
|
+
this.scheduleForm.markAllAsTouched();
|
|
1443
|
+
return;
|
|
1444
|
+
}
|
|
1445
|
+
const payload = this.buildSavePayload();
|
|
1446
|
+
const op = this.isEditing
|
|
1447
|
+
? this.scheduleService.update(payload['id'], payload)
|
|
1448
|
+
: this.scheduleService.insert(payload);
|
|
1449
|
+
let scheduleId;
|
|
1450
|
+
op.pipe(switchMap((result) => {
|
|
1451
|
+
scheduleId = this.isEditing
|
|
1452
|
+
? payload['id']
|
|
1453
|
+
: result?.['id'];
|
|
1454
|
+
return this.scheduleService.manageParticipants(scheduleId, this.buildManageParticipantsPayload());
|
|
1455
|
+
})).subscribe({
|
|
1456
|
+
next: () => {
|
|
1457
|
+
this.visible = false;
|
|
1458
|
+
this.visibleChange.emit(false);
|
|
1459
|
+
this.saved.emit(scheduleId);
|
|
1460
|
+
}
|
|
1461
|
+
});
|
|
1462
|
+
}
|
|
1463
|
+
buildSavePayload() {
|
|
1464
|
+
const payload = {
|
|
1465
|
+
...this.scheduleForm.value,
|
|
1466
|
+
type: this.scheduleForm.value.type || null,
|
|
1467
|
+
whenOccurs: this.recurrenceDescription ?? null
|
|
1468
|
+
};
|
|
1469
|
+
if (payload['startDate']) {
|
|
1470
|
+
payload['startDate'] = toDateString(payload['startDate']);
|
|
1471
|
+
}
|
|
1472
|
+
if (payload['endDate']) {
|
|
1473
|
+
payload['endDate'] = toDateString(payload['endDate']);
|
|
1474
|
+
}
|
|
1475
|
+
if (payload['startTime']) {
|
|
1476
|
+
payload['startTime'] = toTimeString(payload['startTime']);
|
|
1477
|
+
}
|
|
1478
|
+
if (payload['endTime']) {
|
|
1479
|
+
payload['endTime'] = toTimeString(payload['endTime']);
|
|
1480
|
+
}
|
|
1481
|
+
if (!payload['withRecurrence']) {
|
|
1482
|
+
this.clearRecurrencePayload(payload);
|
|
1483
|
+
}
|
|
1484
|
+
else {
|
|
1485
|
+
this.cleanRecurrenceFields(payload);
|
|
1486
|
+
}
|
|
1487
|
+
if (payload['allDay']) {
|
|
1488
|
+
payload['startTime'] = null;
|
|
1489
|
+
payload['endTime'] = null;
|
|
1490
|
+
}
|
|
1491
|
+
return payload;
|
|
1492
|
+
}
|
|
1493
|
+
clearRecurrencePayload(payload) {
|
|
1494
|
+
payload['endDate'] = null;
|
|
1495
|
+
payload['recurrenceInterval'] = null;
|
|
1496
|
+
payload['weekDays'] = null;
|
|
1497
|
+
payload['repeatWhen'] = null;
|
|
1498
|
+
payload['repeatWhenDay'] = null;
|
|
1499
|
+
payload['repeatWhenOrdinalWeekDay'] = null;
|
|
1500
|
+
payload['repeatWhenWeekMonth'] = null;
|
|
1501
|
+
payload['repeatWhenMonth'] = null;
|
|
1502
|
+
}
|
|
1503
|
+
onCancel() {
|
|
1504
|
+
this.visible = false;
|
|
1505
|
+
this.visibleChange.emit(false);
|
|
1506
|
+
}
|
|
1507
|
+
buildManageParticipantsPayload() {
|
|
1508
|
+
const a = [];
|
|
1509
|
+
const ac = [];
|
|
1510
|
+
const c = [];
|
|
1511
|
+
const e = [];
|
|
1512
|
+
for (const p of this.addedParticipants) {
|
|
1513
|
+
switch (p.origin) {
|
|
1514
|
+
case 'ACCOUNT': {
|
|
1515
|
+
a.push(p.id);
|
|
1516
|
+
break;
|
|
1517
|
+
}
|
|
1518
|
+
case 'ACCOUNT_CONTACT': {
|
|
1519
|
+
ac.push(p.id);
|
|
1520
|
+
break;
|
|
1521
|
+
}
|
|
1522
|
+
case 'COLLABORATOR': {
|
|
1523
|
+
c.push(p.id);
|
|
1524
|
+
break;
|
|
1525
|
+
}
|
|
1526
|
+
case 'EXTERNAL_PARTICIPANT': {
|
|
1527
|
+
e.push(p.id);
|
|
1528
|
+
break;
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
return {
|
|
1533
|
+
accountsId: a,
|
|
1534
|
+
accountContactsId: ac,
|
|
1535
|
+
collaboratorsId: c,
|
|
1536
|
+
externalParticipantsId: e
|
|
1537
|
+
};
|
|
1538
|
+
}
|
|
1539
|
+
/**
|
|
1540
|
+
* S1541: Break cleanRecurrenceFields into smaller helpers
|
|
1541
|
+
* S121/S2681: Add braces to all if statements
|
|
1542
|
+
*/
|
|
1543
|
+
cleanRecurrenceFields(p) {
|
|
1544
|
+
const r = p['recurrence'];
|
|
1545
|
+
if (r !== ScheduleRecurrence.Weekly) {
|
|
1546
|
+
p['weekDays'] = null;
|
|
1547
|
+
}
|
|
1548
|
+
this.cleanDailyWeeklyFields(p, r);
|
|
1549
|
+
this.cleanMonthlyFields(p, r);
|
|
1550
|
+
this.cleanYearlyFields(p, r);
|
|
1551
|
+
}
|
|
1552
|
+
cleanDailyWeeklyFields(p, r) {
|
|
1553
|
+
if (r === ScheduleRecurrence.Daily ||
|
|
1554
|
+
r === ScheduleRecurrence.Weekly) {
|
|
1555
|
+
p['repeatWhen'] = null;
|
|
1556
|
+
p['repeatWhenDay'] = null;
|
|
1557
|
+
p['repeatWhenOrdinalWeekDay'] = null;
|
|
1558
|
+
p['repeatWhenWeekMonth'] = null;
|
|
1559
|
+
p['repeatWhenMonth'] = null;
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
cleanMonthlyFields(p, r) {
|
|
1563
|
+
if (r === ScheduleRecurrence.Monthly) {
|
|
1564
|
+
p['repeatWhenMonth'] = null;
|
|
1565
|
+
this.cleanRepeatWhenFields(p);
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
cleanYearlyFields(p, r) {
|
|
1569
|
+
if (r === ScheduleRecurrence.Yearly) {
|
|
1570
|
+
this.cleanRepeatWhenFields(p);
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
cleanRepeatWhenFields(p) {
|
|
1574
|
+
if (p['repeatWhen'] === RepeatWhen.InDay) {
|
|
1575
|
+
p['repeatWhenOrdinalWeekDay'] = null;
|
|
1576
|
+
p['repeatWhenWeekMonth'] = null;
|
|
1577
|
+
}
|
|
1578
|
+
else {
|
|
1579
|
+
p['repeatWhenDay'] = null;
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
resetRecurrenceDefaults(date) {
|
|
1583
|
+
if (!this.scheduleForm) {
|
|
1584
|
+
return;
|
|
1585
|
+
}
|
|
1586
|
+
const d = date || new Date();
|
|
1587
|
+
this.scheduleForm.patchValue({
|
|
1588
|
+
id: null,
|
|
1589
|
+
recurrence: ScheduleRecurrence.Daily,
|
|
1590
|
+
recurrenceInterval: 1,
|
|
1591
|
+
weekDays: [getCurrentWeekDay(d)],
|
|
1592
|
+
repeatWhen: RepeatWhen.InDay,
|
|
1593
|
+
repeatWhenDay: d.getDate(),
|
|
1594
|
+
repeatWhenOrdinalWeekDay: getOrdinalForDate(d),
|
|
1595
|
+
repeatWhenWeekMonth: getCurrentWeekDay(d),
|
|
1596
|
+
repeatWhenMonth: getCurrentMonth(d)
|
|
1597
|
+
});
|
|
1598
|
+
}
|
|
1599
|
+
get showRecurrenceFields() {
|
|
1600
|
+
return this.scheduleForm?.get('withRecurrence')?.value === true;
|
|
1601
|
+
}
|
|
1602
|
+
get currentRecurrence() {
|
|
1603
|
+
return this.scheduleForm?.get('recurrence')?.value;
|
|
1604
|
+
}
|
|
1605
|
+
get currentRepeatWhen() {
|
|
1606
|
+
return this.scheduleForm?.get('repeatWhen')?.value;
|
|
1607
|
+
}
|
|
1608
|
+
get showWeekDays() {
|
|
1609
|
+
return this.currentRecurrence === ScheduleRecurrence.Weekly;
|
|
1610
|
+
}
|
|
1611
|
+
get showRepeatWhen() {
|
|
1612
|
+
return (this.currentRecurrence === ScheduleRecurrence.Monthly ||
|
|
1613
|
+
this.currentRecurrence === ScheduleRecurrence.Yearly);
|
|
1614
|
+
}
|
|
1615
|
+
get showRepeatWhenDay() {
|
|
1616
|
+
return this.showRepeatWhen && this.currentRepeatWhen === RepeatWhen.InDay;
|
|
1617
|
+
}
|
|
1618
|
+
get showOrdinalFields() {
|
|
1619
|
+
return (this.showRepeatWhen &&
|
|
1620
|
+
this.currentRepeatWhen === RepeatWhen.InOrdinalWeekDay);
|
|
1621
|
+
}
|
|
1622
|
+
get showMonthField() {
|
|
1623
|
+
return this.currentRecurrence === ScheduleRecurrence.Yearly;
|
|
1624
|
+
}
|
|
1625
|
+
getOriginLabel(o) { return getOriginLabel(this.t, o); }
|
|
1626
|
+
getOriginIcon(o) { return getOriginIcon(o); }
|
|
1627
|
+
getParticipantName(p) { return getParticipantName(p); }
|
|
1628
|
+
getParticipantType(p) { return getParticipantType(this.t, p); }
|
|
1629
|
+
getParticipantTypeIcon(p) { return getParticipantTypeIcon(p); }
|
|
1630
|
+
getPrioritySeverity(p) { return getPrioritySeverity(p); }
|
|
1631
|
+
getPriorityLabel(p) { return getPriorityLabel(this.t, p); }
|
|
1632
|
+
getConfirmationSeverity(c) { return getConfirmationSeverity(c); }
|
|
1633
|
+
getConfirmationLabel(c) { return getConfirmationLabel(this.t, c); }
|
|
1634
|
+
getDefaultStartTime(d) {
|
|
1635
|
+
return getDefaultStartTime(d);
|
|
1636
|
+
}
|
|
1637
|
+
getDefaultEndTime(st) {
|
|
1638
|
+
return getDefaultEndTime(st);
|
|
1639
|
+
}
|
|
1640
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScheduleFormComponent, deps: [{ token: i1$1.FormBuilder }, { token: ScheduleService }, { token: ScheduleTypeService }, { token: CurrentCollaboratorService }, { token: i5.TranslationService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1641
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ScheduleFormComponent, isStandalone: true, selector: "s-schedule-form", inputs: { visible: "visible", selectedDate: "selectedDate" }, outputs: { visibleChange: "visibleChange", saved: "saved" }, viewQueries: [{ propertyName: "detailFormComponent", first: true, predicate: ["detailForm"], descendants: true }], ngImport: i0, template: "<!-- Schedule Drawer -->\n<p-drawer\n [(visible)]=\"visible\"\n position=\"right\"\n [style]=\"{ width: '85vw', 'max-width': '1200px' }\"\n [modal]=\"true\"\n (onHide)=\"onCancel()\"\n>\n <ng-template pTemplate=\"header\">\n <span class=\"drawer-title\">\n <i class=\"pi pi-calendar\"></i>\n {{\n isEditing\n ? ('crmx.components.schedule_schedule_edit' | translate)\n : ('crmx.components.schedule_schedule_new' | translate)\n }}\n </span>\n </ng-template>\n\n <div class=\"drawer-layout\" *ngIf=\"scheduleForm\">\n <!-- Left: Form -->\n <div class=\"drawer-left\">\n <div class=\"drawer-section-header\">\n <i class=\"pi pi-info-circle\"></i>\n <span>\n {{ 'crmx.components.schedule_schedule_details' | translate }}\n </span>\n </div>\n <sia-dynamic-form\n #detailForm\n [sections]=\"[{ fields: scheduleDetailFields }]\"\n [entityData]=\"entityDataForForm\"\n [mode]=\"'form'\"\n [showSubmitButton]=\"false\"\n [showCancelButton]=\"false\"\n (formReady)=\"onDetailFormReady($event)\"\n ></sia-dynamic-form>\n </div>\n\n <!-- Right: Recurrence + Participants -->\n <div class=\"drawer-right\">\n <div\n class=\"drawer-section\"\n *ngIf=\"showRecurrenceFields\"\n >\n <div class=\"drawer-section-header\">\n <i class=\"pi pi-replay\"></i>\n <span>\n {{\n 'crmx.components.schedule_recurrence_config'\n | translate\n }}\n </span>\n </div>\n <form\n [formGroup]=\"scheduleForm\"\n class=\"drawer-form\"\n >\n <div class=\"form-row\">\n <div class=\"form-field flex-1\">\n <label for=\"recurrence\">\n {{ 'crmx.components.schedule_recurrence' | translate }}\n </label>\n <p-dropdown\n id=\"recurrence\"\n formControlName=\"recurrence\"\n [options]=\"recurrenceOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n class=\"w-full\"\n ></p-dropdown>\n </div>\n <div class=\"form-field flex-1\">\n <label for=\"recurrenceInterval\">\n {{\n 'crmx.components.schedule_recurrence_interval'\n | translate\n }}\n </label>\n <p-inputNumber\n id=\"recurrenceInterval\"\n formControlName=\"recurrenceInterval\"\n [min]=\"1\"\n [max]=\"99\"\n class=\"w-full\"\n ></p-inputNumber>\n </div>\n </div>\n <div\n class=\"form-row\"\n *ngIf=\"showWeekDays\"\n >\n <div class=\"form-field flex-1\">\n <label for=\"weekDays\">\n {{ 'crmx.components.schedule_week_days' | translate }}\n </label>\n <p-multiSelect\n id=\"weekDays\"\n formControlName=\"weekDays\"\n [options]=\"weekDayOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"\n 'crmx.components.schedule_select_week_day'\n | translate\n \"\n class=\"w-full\"\n ></p-multiSelect>\n </div>\n </div>\n <div\n class=\"form-row\"\n *ngIf=\"showRepeatWhen\"\n >\n <div class=\"form-field flex-1\">\n <label for=\"repeatWhen\">\n {{\n 'crmx.components.schedule_repeat_when' | translate\n }}\n </label>\n <p-dropdown\n id=\"repeatWhen\"\n formControlName=\"repeatWhen\"\n [options]=\"repeatWhenOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n class=\"w-full\"\n ></p-dropdown>\n </div>\n <div\n class=\"form-field flex-1\"\n *ngIf=\"showRepeatWhenDay\"\n >\n <label for=\"repeatWhenDay\">\n {{\n 'crmx.components.schedule_repeat_when_day'\n | translate\n }}\n </label>\n <p-inputNumber\n id=\"repeatWhenDay\"\n formControlName=\"repeatWhenDay\"\n [min]=\"1\"\n [max]=\"31\"\n class=\"w-full\"\n ></p-inputNumber>\n </div>\n <div\n class=\"form-field flex-1\"\n *ngIf=\"showOrdinalFields\"\n >\n <label for=\"repeatWhenOrdinalWeekDay\">\n {{\n 'crmx.components.schedule_ordinal_week_day'\n | translate\n }}\n </label>\n <p-dropdown\n id=\"repeatWhenOrdinalWeekDay\"\n formControlName=\"repeatWhenOrdinalWeekDay\"\n [options]=\"ordinalOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n class=\"w-full\"\n ></p-dropdown>\n </div>\n <div\n class=\"form-field flex-1\"\n *ngIf=\"showOrdinalFields\"\n >\n <label for=\"repeatWhenWeekMonth\">\n {{\n 'crmx.components.schedule_week_month' | translate\n }}\n </label>\n <p-dropdown\n id=\"repeatWhenWeekMonth\"\n formControlName=\"repeatWhenWeekMonth\"\n [options]=\"weekDayOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n class=\"w-full\"\n ></p-dropdown>\n </div>\n </div>\n <div\n class=\"form-row\"\n *ngIf=\"showMonthField\"\n >\n <div class=\"form-field flex-1\">\n <label for=\"repeatWhenMonth\">\n {{\n 'crmx.components.schedule_repeat_month' | translate\n }}\n </label>\n <p-dropdown\n id=\"repeatWhenMonth\"\n formControlName=\"repeatWhenMonth\"\n [options]=\"monthOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n class=\"w-full\"\n ></p-dropdown>\n </div>\n </div>\n </form>\n <div\n class=\"recurrence-description\"\n *ngIf=\"recurrenceDescription\"\n >\n <i class=\"pi pi-info-circle\"></i>\n <span>{{ recurrenceDescription }}</span>\n </div>\n </div>\n\n <p-divider></p-divider>\n\n <!-- Participants -->\n <div class=\"drawer-section\">\n <div class=\"drawer-section-header\">\n <i class=\"pi pi-users\"></i>\n <span>\n {{ 'crmx.components.schedule_participants' | translate }}\n </span>\n </div>\n <div class=\"participant-search\">\n <p-autoComplete\n [(ngModel)]=\"selectedParticipantLookup\"\n [ngModelOptions]=\"{standalone: true}\"\n [suggestions]=\"participantSuggestions\"\n (completeMethod)=\"\n onSearchParticipants($event)\n \"\n (onSelect)=\"\n onSelectParticipant($event.value)\n \"\n (onFocus)=\"\n onSearchParticipants({ query: '' })\n \"\n optionLabel=\"name\"\n [placeholder]=\"\n 'crmx.components.schedule_search_participant'\n | translate\n \"\n [minLength]=\"0\"\n [forceSelection]=\"true\"\n [showClear]=\"true\"\n [fluid]=\"true\"\n >\n <ng-template\n let-item\n pTemplate=\"item\"\n >\n <div class=\"participant-suggestion\">\n <i\n [class]=\"getOriginIcon(item.origin)\"\n ></i>\n <div\n class=\"participant-suggestion-info\"\n >\n <span\n class=\"participant-suggestion-name\"\n >\n {{ item.name }}\n </span>\n <span\n class=\"participant-suggestion-detail\"\n *ngIf=\"item.referenceName\"\n >\n {{ item.referenceName }}\n </span>\n </div>\n <span\n class=\"participant-suggestion-origin\"\n >\n {{ getOriginLabel(item.origin) }}\n </span>\n </div>\n </ng-template>\n </p-autoComplete>\n </div>\n <div\n *ngIf=\"\n !participantsLoading &&\n addedParticipants.length === 0\n \"\n class=\"participants-empty\"\n >\n <i class=\"pi pi-users\"></i>\n <p>\n {{\n 'crmx.components.schedule_no_participants'\n | translate\n }}\n </p>\n </div>\n <p-table\n *ngIf=\"\n !participantsLoading &&\n addedParticipants.length > 0\n \"\n [value]=\"addedParticipants\"\n styleClass=\"p-datatable-sm p-datatable-striped\"\n >\n <ng-template pTemplate=\"header\">\n <tr>\n <th scope=\"col\">\n {{ 'crmx.components.schedule_name' | translate }}\n </th>\n <th\n scope=\"col\"\n class=\"col-participant-type\"\n >\n {{\n 'crmx.components.schedule_participant_type'\n | translate\n }}\n </th>\n <th\n scope=\"col\"\n class=\"col-actions\"\n ></th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-p>\n <tr>\n <td>\n <div class=\"participant-name-cell\">\n <span>{{ p.name }}</span>\n <span\n *ngIf=\"p.referenceName\"\n class=\"participant-reference\"\n >\n {{ p.referenceName }}\n </span>\n </div>\n </td>\n <td>\n <div class=\"participant-type-cell\">\n <i\n [class]=\"getOriginIcon(p.origin)\"\n ></i>\n <span>\n {{ getOriginLabel(p.origin) }}\n </span>\n </div>\n </td>\n <td>\n <p-button\n icon=\"pi pi-trash\"\n [rounded]=\"true\"\n [text]=\"true\"\n severity=\"danger\"\n (onClick)=\"onRemoveParticipant(p)\"\n [pTooltip]=\"\n 'crmx.components.schedule_remove' | translate\n \"\n tooltipPosition=\"top\"\n ></p-button>\n </td>\n </tr>\n </ng-template>\n </p-table>\n </div>\n </div>\n </div>\n\n <ng-template pTemplate=\"footer\">\n <div class=\"drawer-footer\">\n <p-button\n [label]=\"'crmx.components.cancel' | translate\"\n icon=\"pi pi-times\"\n severity=\"secondary\"\n [outlined]=\"true\"\n (onClick)=\"onCancel()\"\n ></p-button>\n <p-button\n [label]=\"'crmx.components.save' | translate\"\n icon=\"pi pi-check\"\n (onClick)=\"onSave()\"\n ></p-button>\n </div>\n </ng-template>\n</p-drawer>\n", styles: [".col-participant-type{width:10rem}.col-actions{width:4rem}.drawer-title{display:flex;align-items:center;gap:.75rem;font-size:1.15rem;font-weight:600;color:var(--p-text-color)}.drawer-title i{color:var(--p-primary-color)}.drawer-layout{display:flex;gap:0;height:100%}.drawer-left{width:380px;min-width:380px;border-right:1px solid var(--p-surface-200);padding:0 1.5rem 1.5rem 0;overflow-y:auto}.drawer-right{flex:1;padding:0 0 0 1.5rem;overflow-y:auto}.drawer-section-header{display:flex;align-items:center;gap:.5rem;padding-bottom:1rem;margin-bottom:1rem;border-bottom:1px solid var(--p-surface-200);font-weight:600;font-size:.95rem;color:var(--p-text-color)}.drawer-section-header i{color:var(--p-primary-color);font-size:1rem}.drawer-form{display:flex;flex-direction:column;gap:1rem}.drawer-form .form-field{display:flex;flex-direction:column;gap:.375rem}.drawer-form .form-field label{font-weight:500;font-size:.8rem;color:var(--p-text-secondary-color);text-transform:uppercase;letter-spacing:.3px}.drawer-form .form-row{display:flex;gap:1rem}.drawer-form .form-row.checkboxes{gap:2rem;padding:.5rem 0}.drawer-form .form-check{display:flex;align-items:center;gap:.5rem}.drawer-form .form-check label{font-size:.875rem;font-weight:500;margin:0;text-transform:none;letter-spacing:0}.drawer-section{margin-bottom:1.5rem}.recurrence-description{display:flex;align-items:flex-start;gap:.5rem;margin-top:1rem;padding:.75rem 1rem;background:var(--p-primary-50);border-left:3px solid var(--p-primary-color);border-radius:4px;font-size:.85rem;color:var(--p-text-color);line-height:1.4}.recurrence-description i{color:var(--p-primary-color);margin-top:.1rem;flex-shrink:0}.participants-empty{display:flex;flex-direction:column;align-items:center;padding:2rem;text-align:center;color:var(--p-text-secondary-color);border:1px dashed var(--p-surface-300);border-radius:8px}.participants-empty i{font-size:2rem;margin-bottom:.5rem;opacity:.4}.participants-empty p{margin:0}.participant-name-cell{display:flex;align-items:center;gap:.5rem}.participant-type-cell{display:flex;align-items:center;gap:.5rem;font-size:.85rem;color:var(--p-text-secondary-color)}.participant-type-cell i{font-size:.9rem}.drawer-footer{display:flex;gap:.75rem;justify-content:flex-end}.participant-search{margin-bottom:1rem}.participant-search :host ::ng-deep .p-autocomplete{width:100%;display:flex}.participant-search :host ::ng-deep .p-autocomplete-input{width:100%}.participant-suggestion{display:flex;align-items:center;gap:.75rem;padding:.25rem 0}.participant-suggestion i{font-size:1.1rem;color:var(--p-text-secondary-color)}.participant-suggestion-info{display:flex;flex-direction:column;flex:1;min-width:0}.participant-suggestion-name{font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.participant-suggestion-detail{font-size:.8rem;color:var(--p-text-secondary-color)}.participant-suggestion-origin{font-size:.75rem;color:var(--p-text-secondary-color);white-space:nowrap}.participant-reference{font-size:.8rem;color:var(--p-text-secondary-color);margin-left:.25rem}.detail-dialog-body{display:flex;flex-direction:column;gap:.5rem}.detail-dialog-row{display:flex;align-items:center;gap:.75rem;padding:.4rem 0}.detail-label{font-weight:500;color:var(--p-text-secondary-color);min-width:8rem}@media (max-width: 768px){.drawer-layout{flex-direction:column}.drawer-left{width:100%;min-width:100%;border-right:none;border-bottom:1px solid var(--p-surface-200);padding:0 0 1.5rem}.drawer-right{padding:1.5rem 0 0}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i7.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i8.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: DialogModule }, { kind: "ngmodule", type: DrawerModule }, { kind: "component", type: i9.Drawer, selector: "p-drawer", inputs: ["appendTo", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "closeButtonProps", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen", "header", "maskStyle", "closable"], outputs: ["onShow", "onHide", "visibleChange"] }, { kind: "ngmodule", type: DropdownModule }, { kind: "component", type: i10.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: InputNumberModule }, { kind: "component", type: i11.InputNumber, selector: "p-inputNumber, p-inputnumber, p-input-number", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "style", "placeholder", "size", "maxlength", "tabindex", "title", "ariaLabelledBy", "ariaLabel", "ariaRequired", "name", "required", "autocomplete", "min", "max", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "step", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "variant", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus", "disabled", "fluid"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }, { kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i12.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "style", "styleClass", "panelStyle", "panelStyleClass", "inputId", "disabled", "fluid", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "variant", "appendTo", "dataKey", "name", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "size", "showClear", "autofocus", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "defaultLabel", "placeholder", "options", "filterValue", "itemSize", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "ngmodule", type: TagModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i13.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i14.Divider, selector: "p-divider", inputs: ["style", "styleClass", "layout", "type", "align"] }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i15.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "virtualRowHeight", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "ngmodule", type: AutoCompleteModule }, { kind: "component", type: i16.AutoComplete, selector: "p-autoComplete, p-autocomplete, p-auto-complete", inputs: ["minLength", "delay", "style", "panelStyle", "styleClass", "panelStyleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "readonly", "disabled", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "maxlength", "name", "required", "size", "appendTo", "autoHighlight", "forceSelection", "type", "autoZIndex", "baseZIndex", "ariaLabel", "dropdownAriaLabel", "ariaLabelledBy", "dropdownIcon", "unique", "group", "completeOnFocus", "showClear", "field", "dropdown", "showEmptyMessage", "dropdownMode", "multiple", "tabindex", "dataKey", "emptyMessage", "showTransitionOptions", "hideTransitionOptions", "autofocus", "autocomplete", "optionGroupChildren", "optionGroupLabel", "overlayOptions", "suggestions", "itemSize", "optionLabel", "optionValue", "id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "selectOnFocus", "searchLocale", "optionDisabled", "focusOnHover", "typeahead", "variant", "fluid"], outputs: ["completeMethod", "onSelect", "onUnselect", "onFocus", "onBlur", "onDropdownClick", "onClear", "onKeyUp", "onShow", "onHide", "onLazyLoad"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "component", type: DynamicFormComponent, selector: "sia-dynamic-form", inputs: ["sections", "entityData", "mode", "displayMode", "visible", "dialogConfig", "drawerConfig", "showSubmitButton", "showCancelButton", "submitButtonLabel", "cancelButtonLabel", "submitButtonIcon", "cancelButtonIcon"], outputs: ["formReady", "formSubmit", "visibleChange", "onCancel", "fieldSave"] }] });
|
|
1642
|
+
}
|
|
1643
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScheduleFormComponent, decorators: [{
|
|
1644
|
+
type: Component,
|
|
1645
|
+
args: [{ selector: 's-schedule-form', standalone: true, imports: [
|
|
1646
|
+
CommonModule, FormsModule, ReactiveFormsModule,
|
|
1647
|
+
ButtonModule, DialogModule, DrawerModule, DropdownModule,
|
|
1648
|
+
InputNumberModule, MultiSelectModule, TagModule, TooltipModule,
|
|
1649
|
+
DividerModule, TableModule, AutoCompleteModule,
|
|
1650
|
+
TranslatePipe, DynamicFormComponent
|
|
1651
|
+
], template: "<!-- Schedule Drawer -->\n<p-drawer\n [(visible)]=\"visible\"\n position=\"right\"\n [style]=\"{ width: '85vw', 'max-width': '1200px' }\"\n [modal]=\"true\"\n (onHide)=\"onCancel()\"\n>\n <ng-template pTemplate=\"header\">\n <span class=\"drawer-title\">\n <i class=\"pi pi-calendar\"></i>\n {{\n isEditing\n ? ('crmx.components.schedule_schedule_edit' | translate)\n : ('crmx.components.schedule_schedule_new' | translate)\n }}\n </span>\n </ng-template>\n\n <div class=\"drawer-layout\" *ngIf=\"scheduleForm\">\n <!-- Left: Form -->\n <div class=\"drawer-left\">\n <div class=\"drawer-section-header\">\n <i class=\"pi pi-info-circle\"></i>\n <span>\n {{ 'crmx.components.schedule_schedule_details' | translate }}\n </span>\n </div>\n <sia-dynamic-form\n #detailForm\n [sections]=\"[{ fields: scheduleDetailFields }]\"\n [entityData]=\"entityDataForForm\"\n [mode]=\"'form'\"\n [showSubmitButton]=\"false\"\n [showCancelButton]=\"false\"\n (formReady)=\"onDetailFormReady($event)\"\n ></sia-dynamic-form>\n </div>\n\n <!-- Right: Recurrence + Participants -->\n <div class=\"drawer-right\">\n <div\n class=\"drawer-section\"\n *ngIf=\"showRecurrenceFields\"\n >\n <div class=\"drawer-section-header\">\n <i class=\"pi pi-replay\"></i>\n <span>\n {{\n 'crmx.components.schedule_recurrence_config'\n | translate\n }}\n </span>\n </div>\n <form\n [formGroup]=\"scheduleForm\"\n class=\"drawer-form\"\n >\n <div class=\"form-row\">\n <div class=\"form-field flex-1\">\n <label for=\"recurrence\">\n {{ 'crmx.components.schedule_recurrence' | translate }}\n </label>\n <p-dropdown\n id=\"recurrence\"\n formControlName=\"recurrence\"\n [options]=\"recurrenceOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n class=\"w-full\"\n ></p-dropdown>\n </div>\n <div class=\"form-field flex-1\">\n <label for=\"recurrenceInterval\">\n {{\n 'crmx.components.schedule_recurrence_interval'\n | translate\n }}\n </label>\n <p-inputNumber\n id=\"recurrenceInterval\"\n formControlName=\"recurrenceInterval\"\n [min]=\"1\"\n [max]=\"99\"\n class=\"w-full\"\n ></p-inputNumber>\n </div>\n </div>\n <div\n class=\"form-row\"\n *ngIf=\"showWeekDays\"\n >\n <div class=\"form-field flex-1\">\n <label for=\"weekDays\">\n {{ 'crmx.components.schedule_week_days' | translate }}\n </label>\n <p-multiSelect\n id=\"weekDays\"\n formControlName=\"weekDays\"\n [options]=\"weekDayOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"\n 'crmx.components.schedule_select_week_day'\n | translate\n \"\n class=\"w-full\"\n ></p-multiSelect>\n </div>\n </div>\n <div\n class=\"form-row\"\n *ngIf=\"showRepeatWhen\"\n >\n <div class=\"form-field flex-1\">\n <label for=\"repeatWhen\">\n {{\n 'crmx.components.schedule_repeat_when' | translate\n }}\n </label>\n <p-dropdown\n id=\"repeatWhen\"\n formControlName=\"repeatWhen\"\n [options]=\"repeatWhenOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n class=\"w-full\"\n ></p-dropdown>\n </div>\n <div\n class=\"form-field flex-1\"\n *ngIf=\"showRepeatWhenDay\"\n >\n <label for=\"repeatWhenDay\">\n {{\n 'crmx.components.schedule_repeat_when_day'\n | translate\n }}\n </label>\n <p-inputNumber\n id=\"repeatWhenDay\"\n formControlName=\"repeatWhenDay\"\n [min]=\"1\"\n [max]=\"31\"\n class=\"w-full\"\n ></p-inputNumber>\n </div>\n <div\n class=\"form-field flex-1\"\n *ngIf=\"showOrdinalFields\"\n >\n <label for=\"repeatWhenOrdinalWeekDay\">\n {{\n 'crmx.components.schedule_ordinal_week_day'\n | translate\n }}\n </label>\n <p-dropdown\n id=\"repeatWhenOrdinalWeekDay\"\n formControlName=\"repeatWhenOrdinalWeekDay\"\n [options]=\"ordinalOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n class=\"w-full\"\n ></p-dropdown>\n </div>\n <div\n class=\"form-field flex-1\"\n *ngIf=\"showOrdinalFields\"\n >\n <label for=\"repeatWhenWeekMonth\">\n {{\n 'crmx.components.schedule_week_month' | translate\n }}\n </label>\n <p-dropdown\n id=\"repeatWhenWeekMonth\"\n formControlName=\"repeatWhenWeekMonth\"\n [options]=\"weekDayOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n class=\"w-full\"\n ></p-dropdown>\n </div>\n </div>\n <div\n class=\"form-row\"\n *ngIf=\"showMonthField\"\n >\n <div class=\"form-field flex-1\">\n <label for=\"repeatWhenMonth\">\n {{\n 'crmx.components.schedule_repeat_month' | translate\n }}\n </label>\n <p-dropdown\n id=\"repeatWhenMonth\"\n formControlName=\"repeatWhenMonth\"\n [options]=\"monthOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n class=\"w-full\"\n ></p-dropdown>\n </div>\n </div>\n </form>\n <div\n class=\"recurrence-description\"\n *ngIf=\"recurrenceDescription\"\n >\n <i class=\"pi pi-info-circle\"></i>\n <span>{{ recurrenceDescription }}</span>\n </div>\n </div>\n\n <p-divider></p-divider>\n\n <!-- Participants -->\n <div class=\"drawer-section\">\n <div class=\"drawer-section-header\">\n <i class=\"pi pi-users\"></i>\n <span>\n {{ 'crmx.components.schedule_participants' | translate }}\n </span>\n </div>\n <div class=\"participant-search\">\n <p-autoComplete\n [(ngModel)]=\"selectedParticipantLookup\"\n [ngModelOptions]=\"{standalone: true}\"\n [suggestions]=\"participantSuggestions\"\n (completeMethod)=\"\n onSearchParticipants($event)\n \"\n (onSelect)=\"\n onSelectParticipant($event.value)\n \"\n (onFocus)=\"\n onSearchParticipants({ query: '' })\n \"\n optionLabel=\"name\"\n [placeholder]=\"\n 'crmx.components.schedule_search_participant'\n | translate\n \"\n [minLength]=\"0\"\n [forceSelection]=\"true\"\n [showClear]=\"true\"\n [fluid]=\"true\"\n >\n <ng-template\n let-item\n pTemplate=\"item\"\n >\n <div class=\"participant-suggestion\">\n <i\n [class]=\"getOriginIcon(item.origin)\"\n ></i>\n <div\n class=\"participant-suggestion-info\"\n >\n <span\n class=\"participant-suggestion-name\"\n >\n {{ item.name }}\n </span>\n <span\n class=\"participant-suggestion-detail\"\n *ngIf=\"item.referenceName\"\n >\n {{ item.referenceName }}\n </span>\n </div>\n <span\n class=\"participant-suggestion-origin\"\n >\n {{ getOriginLabel(item.origin) }}\n </span>\n </div>\n </ng-template>\n </p-autoComplete>\n </div>\n <div\n *ngIf=\"\n !participantsLoading &&\n addedParticipants.length === 0\n \"\n class=\"participants-empty\"\n >\n <i class=\"pi pi-users\"></i>\n <p>\n {{\n 'crmx.components.schedule_no_participants'\n | translate\n }}\n </p>\n </div>\n <p-table\n *ngIf=\"\n !participantsLoading &&\n addedParticipants.length > 0\n \"\n [value]=\"addedParticipants\"\n styleClass=\"p-datatable-sm p-datatable-striped\"\n >\n <ng-template pTemplate=\"header\">\n <tr>\n <th scope=\"col\">\n {{ 'crmx.components.schedule_name' | translate }}\n </th>\n <th\n scope=\"col\"\n class=\"col-participant-type\"\n >\n {{\n 'crmx.components.schedule_participant_type'\n | translate\n }}\n </th>\n <th\n scope=\"col\"\n class=\"col-actions\"\n ></th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-p>\n <tr>\n <td>\n <div class=\"participant-name-cell\">\n <span>{{ p.name }}</span>\n <span\n *ngIf=\"p.referenceName\"\n class=\"participant-reference\"\n >\n {{ p.referenceName }}\n </span>\n </div>\n </td>\n <td>\n <div class=\"participant-type-cell\">\n <i\n [class]=\"getOriginIcon(p.origin)\"\n ></i>\n <span>\n {{ getOriginLabel(p.origin) }}\n </span>\n </div>\n </td>\n <td>\n <p-button\n icon=\"pi pi-trash\"\n [rounded]=\"true\"\n [text]=\"true\"\n severity=\"danger\"\n (onClick)=\"onRemoveParticipant(p)\"\n [pTooltip]=\"\n 'crmx.components.schedule_remove' | translate\n \"\n tooltipPosition=\"top\"\n ></p-button>\n </td>\n </tr>\n </ng-template>\n </p-table>\n </div>\n </div>\n </div>\n\n <ng-template pTemplate=\"footer\">\n <div class=\"drawer-footer\">\n <p-button\n [label]=\"'crmx.components.cancel' | translate\"\n icon=\"pi pi-times\"\n severity=\"secondary\"\n [outlined]=\"true\"\n (onClick)=\"onCancel()\"\n ></p-button>\n <p-button\n [label]=\"'crmx.components.save' | translate\"\n icon=\"pi pi-check\"\n (onClick)=\"onSave()\"\n ></p-button>\n </div>\n </ng-template>\n</p-drawer>\n", styles: [".col-participant-type{width:10rem}.col-actions{width:4rem}.drawer-title{display:flex;align-items:center;gap:.75rem;font-size:1.15rem;font-weight:600;color:var(--p-text-color)}.drawer-title i{color:var(--p-primary-color)}.drawer-layout{display:flex;gap:0;height:100%}.drawer-left{width:380px;min-width:380px;border-right:1px solid var(--p-surface-200);padding:0 1.5rem 1.5rem 0;overflow-y:auto}.drawer-right{flex:1;padding:0 0 0 1.5rem;overflow-y:auto}.drawer-section-header{display:flex;align-items:center;gap:.5rem;padding-bottom:1rem;margin-bottom:1rem;border-bottom:1px solid var(--p-surface-200);font-weight:600;font-size:.95rem;color:var(--p-text-color)}.drawer-section-header i{color:var(--p-primary-color);font-size:1rem}.drawer-form{display:flex;flex-direction:column;gap:1rem}.drawer-form .form-field{display:flex;flex-direction:column;gap:.375rem}.drawer-form .form-field label{font-weight:500;font-size:.8rem;color:var(--p-text-secondary-color);text-transform:uppercase;letter-spacing:.3px}.drawer-form .form-row{display:flex;gap:1rem}.drawer-form .form-row.checkboxes{gap:2rem;padding:.5rem 0}.drawer-form .form-check{display:flex;align-items:center;gap:.5rem}.drawer-form .form-check label{font-size:.875rem;font-weight:500;margin:0;text-transform:none;letter-spacing:0}.drawer-section{margin-bottom:1.5rem}.recurrence-description{display:flex;align-items:flex-start;gap:.5rem;margin-top:1rem;padding:.75rem 1rem;background:var(--p-primary-50);border-left:3px solid var(--p-primary-color);border-radius:4px;font-size:.85rem;color:var(--p-text-color);line-height:1.4}.recurrence-description i{color:var(--p-primary-color);margin-top:.1rem;flex-shrink:0}.participants-empty{display:flex;flex-direction:column;align-items:center;padding:2rem;text-align:center;color:var(--p-text-secondary-color);border:1px dashed var(--p-surface-300);border-radius:8px}.participants-empty i{font-size:2rem;margin-bottom:.5rem;opacity:.4}.participants-empty p{margin:0}.participant-name-cell{display:flex;align-items:center;gap:.5rem}.participant-type-cell{display:flex;align-items:center;gap:.5rem;font-size:.85rem;color:var(--p-text-secondary-color)}.participant-type-cell i{font-size:.9rem}.drawer-footer{display:flex;gap:.75rem;justify-content:flex-end}.participant-search{margin-bottom:1rem}.participant-search :host ::ng-deep .p-autocomplete{width:100%;display:flex}.participant-search :host ::ng-deep .p-autocomplete-input{width:100%}.participant-suggestion{display:flex;align-items:center;gap:.75rem;padding:.25rem 0}.participant-suggestion i{font-size:1.1rem;color:var(--p-text-secondary-color)}.participant-suggestion-info{display:flex;flex-direction:column;flex:1;min-width:0}.participant-suggestion-name{font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.participant-suggestion-detail{font-size:.8rem;color:var(--p-text-secondary-color)}.participant-suggestion-origin{font-size:.75rem;color:var(--p-text-secondary-color);white-space:nowrap}.participant-reference{font-size:.8rem;color:var(--p-text-secondary-color);margin-left:.25rem}.detail-dialog-body{display:flex;flex-direction:column;gap:.5rem}.detail-dialog-row{display:flex;align-items:center;gap:.75rem;padding:.4rem 0}.detail-label{font-weight:500;color:var(--p-text-secondary-color);min-width:8rem}@media (max-width: 768px){.drawer-layout{flex-direction:column}.drawer-left{width:100%;min-width:100%;border-right:none;border-bottom:1px solid var(--p-surface-200);padding:0 0 1.5rem}.drawer-right{padding:1.5rem 0 0}}\n"] }]
|
|
1652
|
+
}], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: ScheduleService }, { type: ScheduleTypeService }, { type: CurrentCollaboratorService }, { type: i5.TranslationService }], propDecorators: { visible: [{
|
|
1653
|
+
type: Input
|
|
1654
|
+
}], selectedDate: [{
|
|
1655
|
+
type: Input
|
|
1656
|
+
}], visibleChange: [{
|
|
1657
|
+
type: Output
|
|
1658
|
+
}], saved: [{
|
|
1659
|
+
type: Output
|
|
1660
|
+
}], detailFormComponent: [{
|
|
1661
|
+
type: ViewChild,
|
|
1662
|
+
args: ['detailForm']
|
|
1663
|
+
}] } });
|
|
1664
|
+
|
|
1665
|
+
class ScheduleDetailComponent {
|
|
1666
|
+
scheduleService;
|
|
1667
|
+
t;
|
|
1668
|
+
visible = false;
|
|
1669
|
+
visibleChange = new EventEmitter();
|
|
1670
|
+
schedule = null;
|
|
1671
|
+
scheduleData = null;
|
|
1672
|
+
participants = [];
|
|
1673
|
+
participantsLoading = false;
|
|
1674
|
+
loading = false;
|
|
1675
|
+
constructor(scheduleService, t) {
|
|
1676
|
+
this.scheduleService = scheduleService;
|
|
1677
|
+
this.t = t;
|
|
1678
|
+
}
|
|
1679
|
+
open(scheduleId) {
|
|
1680
|
+
this.schedule = null;
|
|
1681
|
+
this.scheduleData = null;
|
|
1682
|
+
this.participants = [];
|
|
1683
|
+
this.loading = true;
|
|
1684
|
+
this.participantsLoading = true;
|
|
1685
|
+
this.visible = true;
|
|
1686
|
+
this.visibleChange.emit(true);
|
|
1687
|
+
this.scheduleService.get(scheduleId).subscribe({
|
|
1688
|
+
next: (data) => {
|
|
1689
|
+
this.scheduleData = data;
|
|
1690
|
+
this.schedule = {
|
|
1691
|
+
id: data.id, name: data.name,
|
|
1692
|
+
scheduleType: data.type ?? null,
|
|
1693
|
+
withRecurrence: data.withRecurrence,
|
|
1694
|
+
whenOccurs: data.whenOccurs ?? '',
|
|
1695
|
+
allDay: data.allDay, startTime: data.startTime,
|
|
1696
|
+
endTime: data.endTime, priority: data.priority
|
|
1697
|
+
};
|
|
1698
|
+
this.loading = false;
|
|
1699
|
+
},
|
|
1700
|
+
error: () => { this.loading = false; }
|
|
1701
|
+
});
|
|
1702
|
+
this.scheduleService.listParticipants(scheduleId).subscribe({
|
|
1703
|
+
next: (r) => { this.participants = r.contents ?? []; this.participantsLoading = false; },
|
|
1704
|
+
error: () => { this.participantsLoading = false; }
|
|
1705
|
+
});
|
|
1706
|
+
}
|
|
1707
|
+
onClose() { this.visible = false; this.visibleChange.emit(false); }
|
|
1708
|
+
getParticipantName(p) { return getParticipantName(p); }
|
|
1709
|
+
getParticipantType(p) { return getParticipantType(this.t, p); }
|
|
1710
|
+
getParticipantTypeIcon(p) { return getParticipantTypeIcon(p); }
|
|
1711
|
+
getPrioritySeverity(p) { return getPrioritySeverity(p); }
|
|
1712
|
+
getPriorityLabel(p) { return getPriorityLabel(this.t, p); }
|
|
1713
|
+
getConfirmationSeverity(c) { return getConfirmationSeverity(c); }
|
|
1714
|
+
getConfirmationLabel(c) { return getConfirmationLabel(this.t, c); }
|
|
1715
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScheduleDetailComponent, deps: [{ token: ScheduleService }, { token: i5.TranslationService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1716
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ScheduleDetailComponent, isStandalone: true, selector: "s-schedule-detail", inputs: { visible: "visible" }, outputs: { visibleChange: "visibleChange" }, ngImport: i0, template: "<p-dialog\n [(visible)]=\"visible\"\n [header]=\"schedule?.name || ''\"\n [modal]=\"true\"\n styleClass=\"detail-dialog\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n (onHide)=\"onClose()\"\n>\n <div class=\"detail-dialog-body\" *ngIf=\"schedule\">\n <div\n class=\"detail-dialog-section\"\n *ngIf=\"scheduleData\"\n >\n <div class=\"detail-dialog-row\">\n <span class=\"detail-label\">\n {{ 'crmx.components.schedule_priority' | translate }}\n </span>\n <p-tag\n [value]=\"getPriorityLabel(schedule.priority)\"\n [severity]=\"getPrioritySeverity(schedule.priority)\"\n ></p-tag>\n </div>\n <div\n class=\"detail-dialog-row\"\n *ngIf=\"schedule.scheduleType\"\n >\n <span class=\"detail-label\">\n {{ 'crmx.components.schedule_type' | translate }}\n </span>\n <span>{{ schedule.scheduleType.name }}</span>\n </div>\n <div\n class=\"detail-dialog-row\"\n *ngIf=\"schedule.whenOccurs\"\n >\n <span class=\"detail-label\">\n {{ 'crmx.components.schedule_recurrence' | translate }}\n </span>\n <span>{{ schedule.whenOccurs }}</span>\n </div>\n <div\n class=\"detail-dialog-row\"\n *ngIf=\"scheduleData.comments\"\n >\n <span class=\"detail-label\">\n {{ 'crmx.components.schedule_comments' | translate }}\n </span>\n <span>{{ scheduleData.comments }}</span>\n </div>\n </div>\n <p-divider *ngIf=\"scheduleData\"></p-divider>\n <div\n class=\"detail-dialog-section\"\n *ngIf=\"scheduleData\"\n >\n <div class=\"detail-section-header\">\n <i class=\"pi pi-users\"></i>\n <span>\n {{ 'crmx.components.schedule_participants' | translate }}\n </span>\n </div>\n <p-table\n [value]=\"participants\"\n [loading]=\"participantsLoading\"\n styleClass=\"p-datatable-sm p-datatable-striped\"\n >\n <ng-template pTemplate=\"header\">\n <tr>\n <th scope=\"col\">\n {{ 'crmx.components.schedule_name' | translate }}\n </th>\n <th\n scope=\"col\"\n class=\"col-participant-type\"\n >\n {{ 'crmx.components.schedule_participant_type' | translate }}\n </th>\n <th\n scope=\"col\"\n class=\"col-status\"\n >\n {{ 'crmx.components.schedule_status' | translate }}\n </th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-p>\n <tr>\n <td>\n <span>{{ getParticipantName(p) }}</span>\n </td>\n <td>\n <div class=\"participant-type-cell\">\n <i\n [class]=\"getParticipantTypeIcon(p)\"\n ></i>\n <span>\n {{ getParticipantType(p) }}\n </span>\n </div>\n </td>\n <td>\n <p-tag\n *ngIf=\"p.organizer\"\n [value]=\"\n 'crmx.components.schedule_participant_organizer_label'\n | translate\n \"\n severity=\"info\"\n ></p-tag>\n <p-tag\n *ngIf=\"!p.organizer\"\n [value]=\"\n getConfirmationLabel(p.confirmation)\n \"\n [severity]=\"\n getConfirmationSeverity(p.confirmation)\n \"\n ></p-tag>\n </td>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"emptymessage\">\n <tr>\n <td colspan=\"3\">\n <div class=\"participants-empty\">\n <i class=\"pi pi-users\"></i>\n <p>\n {{\n 'crmx.components.schedule_no_participants'\n | translate\n }}\n </p>\n </div>\n </td>\n </tr>\n </ng-template>\n </p-table>\n </div>\n </div>\n</p-dialog>\n", styles: [":host ::ng-deep .detail-dialog{width:600px}.detail-dialog-body{display:flex;flex-direction:column;gap:.5rem}.detail-dialog-row{display:flex;align-items:center;gap:.75rem;padding:.4rem 0}.detail-label{font-weight:500;color:var(--p-text-secondary-color);min-width:8rem}.detail-section-header{display:flex;align-items:center;gap:.5rem;padding-bottom:1rem;margin-bottom:1rem;border-bottom:1px solid var(--p-surface-200);font-weight:600;font-size:.95rem;color:var(--p-text-color)}.detail-section-header i{color:var(--p-primary-color);font-size:1rem}.participant-type-cell{display:flex;align-items:center;gap:.5rem;font-size:.85rem;color:var(--p-text-secondary-color)}.participant-type-cell i{font-size:.9rem}.col-participant-type{width:10rem}.col-status{width:8rem}.participants-empty{display:flex;flex-direction:column;align-items:center;padding:2rem;text-align:center;color:var(--p-text-secondary-color);border:1px dashed var(--p-surface-300);border-radius:8px}.participants-empty i{font-size:2rem;margin-bottom:.5rem;opacity:.4}.participants-empty p{margin:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i4.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "directive", type: i8.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i14.Divider, selector: "p-divider", inputs: ["style", "styleClass", "layout", "type", "align"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i7$1.Tag, selector: "p-tag", inputs: ["style", "styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i15.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "virtualRowHeight", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
1717
|
+
}
|
|
1718
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScheduleDetailComponent, decorators: [{
|
|
1719
|
+
type: Component,
|
|
1720
|
+
args: [{ selector: 's-schedule-detail', standalone: true, imports: [CommonModule, DialogModule, DividerModule, TagModule, TableModule, TranslatePipe, DateFormatPipe], template: "<p-dialog\n [(visible)]=\"visible\"\n [header]=\"schedule?.name || ''\"\n [modal]=\"true\"\n styleClass=\"detail-dialog\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n (onHide)=\"onClose()\"\n>\n <div class=\"detail-dialog-body\" *ngIf=\"schedule\">\n <div\n class=\"detail-dialog-section\"\n *ngIf=\"scheduleData\"\n >\n <div class=\"detail-dialog-row\">\n <span class=\"detail-label\">\n {{ 'crmx.components.schedule_priority' | translate }}\n </span>\n <p-tag\n [value]=\"getPriorityLabel(schedule.priority)\"\n [severity]=\"getPrioritySeverity(schedule.priority)\"\n ></p-tag>\n </div>\n <div\n class=\"detail-dialog-row\"\n *ngIf=\"schedule.scheduleType\"\n >\n <span class=\"detail-label\">\n {{ 'crmx.components.schedule_type' | translate }}\n </span>\n <span>{{ schedule.scheduleType.name }}</span>\n </div>\n <div\n class=\"detail-dialog-row\"\n *ngIf=\"schedule.whenOccurs\"\n >\n <span class=\"detail-label\">\n {{ 'crmx.components.schedule_recurrence' | translate }}\n </span>\n <span>{{ schedule.whenOccurs }}</span>\n </div>\n <div\n class=\"detail-dialog-row\"\n *ngIf=\"scheduleData.comments\"\n >\n <span class=\"detail-label\">\n {{ 'crmx.components.schedule_comments' | translate }}\n </span>\n <span>{{ scheduleData.comments }}</span>\n </div>\n </div>\n <p-divider *ngIf=\"scheduleData\"></p-divider>\n <div\n class=\"detail-dialog-section\"\n *ngIf=\"scheduleData\"\n >\n <div class=\"detail-section-header\">\n <i class=\"pi pi-users\"></i>\n <span>\n {{ 'crmx.components.schedule_participants' | translate }}\n </span>\n </div>\n <p-table\n [value]=\"participants\"\n [loading]=\"participantsLoading\"\n styleClass=\"p-datatable-sm p-datatable-striped\"\n >\n <ng-template pTemplate=\"header\">\n <tr>\n <th scope=\"col\">\n {{ 'crmx.components.schedule_name' | translate }}\n </th>\n <th\n scope=\"col\"\n class=\"col-participant-type\"\n >\n {{ 'crmx.components.schedule_participant_type' | translate }}\n </th>\n <th\n scope=\"col\"\n class=\"col-status\"\n >\n {{ 'crmx.components.schedule_status' | translate }}\n </th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-p>\n <tr>\n <td>\n <span>{{ getParticipantName(p) }}</span>\n </td>\n <td>\n <div class=\"participant-type-cell\">\n <i\n [class]=\"getParticipantTypeIcon(p)\"\n ></i>\n <span>\n {{ getParticipantType(p) }}\n </span>\n </div>\n </td>\n <td>\n <p-tag\n *ngIf=\"p.organizer\"\n [value]=\"\n 'crmx.components.schedule_participant_organizer_label'\n | translate\n \"\n severity=\"info\"\n ></p-tag>\n <p-tag\n *ngIf=\"!p.organizer\"\n [value]=\"\n getConfirmationLabel(p.confirmation)\n \"\n [severity]=\"\n getConfirmationSeverity(p.confirmation)\n \"\n ></p-tag>\n </td>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"emptymessage\">\n <tr>\n <td colspan=\"3\">\n <div class=\"participants-empty\">\n <i class=\"pi pi-users\"></i>\n <p>\n {{\n 'crmx.components.schedule_no_participants'\n | translate\n }}\n </p>\n </div>\n </td>\n </tr>\n </ng-template>\n </p-table>\n </div>\n </div>\n</p-dialog>\n", styles: [":host ::ng-deep .detail-dialog{width:600px}.detail-dialog-body{display:flex;flex-direction:column;gap:.5rem}.detail-dialog-row{display:flex;align-items:center;gap:.75rem;padding:.4rem 0}.detail-label{font-weight:500;color:var(--p-text-secondary-color);min-width:8rem}.detail-section-header{display:flex;align-items:center;gap:.5rem;padding-bottom:1rem;margin-bottom:1rem;border-bottom:1px solid var(--p-surface-200);font-weight:600;font-size:.95rem;color:var(--p-text-color)}.detail-section-header i{color:var(--p-primary-color);font-size:1rem}.participant-type-cell{display:flex;align-items:center;gap:.5rem;font-size:.85rem;color:var(--p-text-secondary-color)}.participant-type-cell i{font-size:.9rem}.col-participant-type{width:10rem}.col-status{width:8rem}.participants-empty{display:flex;flex-direction:column;align-items:center;padding:2rem;text-align:center;color:var(--p-text-secondary-color);border:1px dashed var(--p-surface-300);border-radius:8px}.participants-empty i{font-size:2rem;margin-bottom:.5rem;opacity:.4}.participants-empty p{margin:0}\n"] }]
|
|
1721
|
+
}], ctorParameters: () => [{ type: ScheduleService }, { type: i5.TranslationService }], propDecorators: { visible: [{
|
|
1722
|
+
type: Input
|
|
1723
|
+
}], visibleChange: [{
|
|
1724
|
+
type: Output
|
|
1725
|
+
}] } });
|
|
1726
|
+
|
|
219
1727
|
/*
|
|
220
1728
|
* Public API Surface of @senior-gestao-relacionamento/angular-components
|
|
221
1729
|
*/
|
|
@@ -224,5 +1732,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
224
1732
|
* Generated bundle index. Do not edit.
|
|
225
1733
|
*/
|
|
226
1734
|
|
|
227
|
-
export { AngularComponentsModule, CurrentCollaboratorService, StorageService };
|
|
1735
|
+
export { AngularComponentsModule, CurrentCollaboratorService, Month, OrdinalWeekDay, ParticipantConfirmation, RepeatWhen, ScheduleDetailComponent, ScheduleFormComponent, SchedulePriority, ScheduleRecurrence, ScheduleService, ScheduleTypeService, Status, StorageService, WeekDay, provideAngularComponentsTranslations };
|
|
228
1736
|
//# sourceMappingURL=senior-gestao-relacionamento-angular-components.mjs.map
|