remove unnecessary code

This commit is contained in:
Peter Maquiran
2024-10-18 12:12:55 +01:00
parent 8484b1b600
commit 3f41e9e9c0
102 changed files with 102 additions and 196 deletions
@@ -0,0 +1,58 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AgendaPage } from './agenda.page';
const routes: Routes = [
{
path: '',
component: AgendaPage
},
{
path: 'approve-event-modal',
loadChildren: () => import('../../pages/gabinete-digital/event-list/approve-event-modal/approve-event-modal.module').then( m => m.ApproveEventModalPageModule)
},
{
path: 'event-actions-popover',
loadChildren: () => import('./modal/event-actions-popover/event-actions-popover.module').then( m => m.EventActionsPopoverPageModule)
},
{
path: 'emend-message-modal',
loadChildren: () => import('./modal/emend-message-modal/emend-message-modal.module').then( m => m.EmendMessageModalPageModule)
},
{
path: 'new-event',
loadChildren: () => import('./modal/new-event/new-event.module').then( m => m.NewEventPageModule)
},
{
path: 'edit-event',
loadChildren: () => import('./modal/edit-event/edit-event.module').then( m => m.EditEventPageModule)
},
{
path: 'view-event',
loadChildren: () => import('./modal/view-event/view-event.module').then( m => m.ViewEventPageModule)
},
{
path: 'new-event',
loadChildren: () => import('./component/new-event/new-event.module').then( m => m.NewEventPageModule)
},
{
path: 'event-list',
loadChildren: () => import('./component/event-list/event-list.module').then( m => m.EventListPageModule)
},
{
path: 'approve-event',
loadChildren: () => import('./component/approve-event/approve-event.module').then( m => m.ApproveEventPageModule)
},
{
path: 'edit-event-to-approve',
loadChildren: () => import('./component/edit-event-to-approve/edit-event-to-approve.module').then( m => m.EditEventToApprovePageModule)
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class AgendaPageRoutingModule {}
+91
View File
@@ -0,0 +1,91 @@
import { NgModule, LOCALE_ID, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { AgendaPageRoutingModule } from './agenda-routing.module';
import { AgendaPage } from './agenda.page';
import { NgCalendarModule } from 'ionic2-calendar';
import { registerLocaleData } from '@angular/common';
import localeDe from '@angular/common/locales/pt';
registerLocaleData(localeDe);
import { CalendarModule, DateAdapter } from 'angular-calendar';
import { adapterFactory } from 'angular-calendar/date-adapters/date-fns';
import { AttendeeModalPageModule } from 'src/app/shared/event/attendee-modal/attendee-modal.module';
import { ViewEventPageModule } from 'src/app/ui/agenda/component/view-event/view-event.module';
import { ApproveEventPageModule } from 'src/app/ui/agenda/component/approve-event/approve-event.module';
import { NewEventPageModule } from 'src/app/ui/agenda/component/new-event/new-event.module';
import { EventsToApprovePageModule } from 'src/app/shared/gabinete-digital/events-to-approve/events-to-approve.module';
import { EventListPageModule } from 'src/app/ui/agenda/component/event-list/event-list.module';
import { EditEventPageModule } from 'src/app/ui/agenda/component/edit-event/edit-event.module';
import { EditEventToApprovePageModule } from 'src/app/ui/agenda/component/edit-event-to-approve/edit-event-to-approve.module';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatInputModule } from '@angular/material/input';
import { MatNativeDateModule } from '@angular/material/core';
import {
NgxMatDatetimePickerModule,
NgxMatNativeDateModule,
NgxMatTimepickerModule
} from '@angular-material-components/datetime-picker';
import { ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatSelectModule } from '@angular/material/select';
import { NgxMatMomentModule } from '@angular-material-components/moment-adapter';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
/* */
CalendarModule.forRoot({
provide: DateAdapter,
useFactory: adapterFactory
}),
AgendaPageRoutingModule,
NgCalendarModule,
// entryComponents
ViewEventPageModule,
AttendeeModalPageModule,
EventsToApprovePageModule,
ApproveEventPageModule,
NewEventPageModule,
EventListPageModule,
EditEventPageModule,
EditEventToApprovePageModule,
//
MatDatepickerModule,
MatInputModule,
MatNativeDateModule,
NgxMatDatetimePickerModule,
NgxMatTimepickerModule,
NgxMatNativeDateModule,
NgxMatMomentModule,
MatSelectModule,
MatButtonModule,
ReactiveFormsModule
],
declarations: [
AgendaPage
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [
{ provide: LOCALE_ID, useValue: 'pt-PT'}
]
})
export class AgendaPageModule {}
+447
View File
@@ -0,0 +1,447 @@
<!-- Progress bar -->
<ion-content id="timeline-conteiner agenda-container pt-20" class="timeline ">
<ion-refresher name="refresher" slot="fixed" (ionRefresh)="doRefresh($event)">
<ion-refresher-content>
</ion-refresher-content>
</ion-refresher>
<div class="d-flex container-wrapper">
<div class="calendar-timeline d-flex flex-column height-100 bg-blue">
<div class="calendar-wrapper">
<div class="main-content">
<!-- Toolbar -->
<ion-progress-bar type="indeterminate" *ngIf="showLoader"></ion-progress-bar>
<div class="weeksToShow">
<!-- Calendar is here -->
<div class="calendar-segment-{{profile}}" [class.calendar-segment-pr-force]="SessionStore.user.Profile =='PR'">
<div class="calendar-container" class="calendarHeight" >
<ion-row class="ion-justify-content-between calendar-tool-tip">
<ion-row class="ion-align-items-center first-row">
<!-- Move back one screen of the slides -->
<div class="arrow cursor-pointer resize">
<button (click)="back()" class="btn-no-color resize" >
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " slot="icon-only" src="assets/images/icons-calendar-arrow-left.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " slot="icon-only" src="assets/images/theme/gov/icons-calendar-arrow-left.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " slot="icon-only" src="assets/images/theme/{{ThemeService.currentTheme}}/icons-calendar-arrow-left.svg"></ion-icon>
</button>
</div>
<h2 class="capitaliseText d-flex align-center">
{{ viewTitle }}
</h2>
<div (click)="next()" class="arrow cursor-pointer resize">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " slot="icon-only" src="assets/images/icons-calendar-arrow-right.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " slot="icon-only" src="assets/images/theme/gov/icons-calendar-arrow-right.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " slot="icon-only" src="assets/images/theme/{{ThemeService.currentTheme}}/icons-calendar-arrow-right.svg"></ion-icon>
</div>
<div *ngIf="SessionStore.user.RoleID !== 100000014 && (sharedCalendar | async) as calendarData" style="
padding-bottom: 10px;
padding-left: 10px;
padding-right: 10px;
background: #f7f7f7;
border-radius: 5px;
margin-right: 10px;"
class="select-calendar">
<!-- Debug line to print data -->
<mat-form-field class="select-calendar" appearance="none" color="ion-color-secondary" placeholder="Selecione agenda" *ngIf="calendarData?.length && showCalendarField">
<div *ngIf="hasPrCalendar(calendarData) && !hasChangeCalendar " style="margin-bottom: -20px;">PR </div>
<div *ngIf="selectedUserCalendar == SessionStore.user.UserId && !hasChangeCalendar " style="margin-bottom: -20px;">
Minha agenda
</div>
<mat-select [(value)]="selectedUserCalendar" (selectionChange)="reloadCalendar();changeSegmentCalendar();" >
<mat-option *ngFor="let calendars of calendarData" value="{{calendars.wxUserId}}" >
<div *ngIf="environment.presidential">
<div *ngIf="calendars.roleId == RoleIdService.PRES">PR </div>
<div *ngIf="calendars.roleId == RoleIdService.MD && calendars.roleId != SessionStore.user.RoleID">MDGPR</div>
<div *ngIf="calendars.roleId != RoleIdService.MD && calendars.roleId != RoleIdService.PRES && calendars.wxFullName && calendars.wxUserId != SessionStore.user.UserId "> Agenda {{calendars.wxFullName}} </div>
<div *ngIf="calendars.wxUserId == SessionStore.user.UserId ">
Minha agenda
</div>
</div>
<div *ngIf="!environment.presidential">
<div *ngIf="calendars.roleId == RoleIdService.PRES">{{ environment.agendaPR}} </div>
<div *ngIf="calendars.roleId == RoleIdService.MD && calendars.roleId != SessionStore.user.RoleID">{{ environment.agendaVP}}</div>
<div *ngIf="calendars.roleId != RoleIdService.MD && calendars.roleId != RoleIdService.PRES && calendars.wxFullName && calendars.wxUserId != SessionStore.user.UserId "> Agenda {{calendars.wxFullName}} </div>
<div *ngIf="calendars.wxUserId == SessionStore.user.UserId ">
Minha agenda
</div>
</div>
</mat-option>
<mat-option value="PR+MDGPR" *ngIf="p.userPermission([p.permissionList.Gabinete.md_tasks]) && environment.presidential">
PR+MDGPR
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="float-button" *ngIf="(sharedCalendar | async) as calendarData">
<button title="Visualizar a lista de Eventos para aprovação" class="cursor-pointer resize pr-20-rem" (click)="viewEventsToApprove()" *ngIf="p.userPermission([p.permissionList.Gabinete.aprove_event])">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="right-icons" src="assets/images/icons-received-event.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' && !mobileComponent.showEventList" class="right-icons" src="assets/images/theme/gov/icons-received-event.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' && mobileComponent.showEventList" class="right-icons" src="assets/images/theme/gov/icons-received-event-selected.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " class="right-icons" src="assets/images/theme/{{ThemeService.currentTheme}}/icons-received-event.svg"></ion-icon>
</button>
<button *ngIf="calendarData.length >=1" title="Novo Evento" class="cy-add-event cursor-pointer resize" (click)="clearContact();openAddEvent();">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="right-icons" src="assets/images/icons-add.svg" ></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' && !mobileComponent.showAddNewEvent" class="right-icons" src="assets/images/theme/gov/icons-add.svg" ></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' && mobileComponent.showAddNewEvent" class="right-icons" src="assets/images/theme/gov/icons-add-selected.svg" ></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " class="right-icons" slot="icon-only" src="assets/images/theme/{{ThemeService.currentTheme}}/icons-add.svg"></ion-icon>
</button>
</div>
</ion-row>
<ion-row class="ion-align-items-center calendar-options" *ngIf="(sharedCalendar | async) as calendarData">
<button title="Visualizar a lista de Eventos para aprovação" class="cursor-pointer resize pr-10" (click)="viewEventsToApprove()" *ngIf="p.userPermission([p.permissionList.Gabinete.aprove_event])">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="right-icons" src="assets/images/icons-received-event.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' && !mobileComponent.showEventList" class="right-icons" src="assets/images/theme/gov/icons-received-event.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' && mobileComponent.showEventList" class="right-icons" src="assets/images/theme/gov/icons-received-event-selected.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " class="right-icons" src="assets/images/theme/{{ThemeService.currentTheme}}/icons-received-event.svg"></ion-icon>
</button>
<button *ngIf="calendarData.length >=1 && p.userPermission([p.permissionList.Agenda.creatEvent])" title="Novo Evento" class="cy-add-event cursor-pointer resize" (click)="clearContact();openAddEvent();">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="right-icons" src="assets/images/icons-add.svg" ></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' && !mobileComponent.showAddNewEvent" class="right-icons" src="assets/images/theme/gov/icons-add.svg" ></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' && mobileComponent.showAddNewEvent" class="right-icons" src="assets/images/theme/gov/icons-add-selected.svg" ></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " class="right-icons" slot="icon-only" src="assets/images/theme/{{ThemeService.currentTheme}}/icons-add.svg"></ion-icon>
</button>
</ion-row>
</ion-row>
<table class="custom-calendar-header">
<thead>
<th>S</th>
<th>T</th>
<th>Q</th>
<th>Q</th>
<th>S</th>
<th>S</th>
<th>D</th>
</thead>
</table>
<div class="calendar-conteiner-height overflow-hidden" [style.height]="listBoxService.height">
<calendar
class="calendar-component"
[eventSource]="listToPresent"
[calendarMode]="calendar.mode"
[currentDate]="calendar.currentDate"
(onTitleChanged)="onViewTitleChanged($event)"
(onRangeChanged)="onRangeChanged($event)"
(onCurrentDateChanged)="onCurrentChanged($event)"
queryMode="remote"
startHour="6"
endHour="20"
step="30"
startingDayMonth="1"
noEventsLabel="Sem Eventos"
allDayLabel="Todo o dia"
[monthviewDisplayEventTemplate]="template"
>
</calendar>
</div>
<!-- Adding a customized ng-template -->
<ng-template #template let-view="view" let-row="row" let-col="col">
<div class="day-container">
<div [className]="currentDayEventDisplayBorder(view.dates, row*7+col)" class="d-flex justify-center align-center" [class.with-event]="view.dates[row*7+col].events.length">
<div class="day">
<div class="number"> {{ view.dates[row*7+col].label }}</div>
</div>
</div>
</div>
</ng-template>
</div>
</div>
<div class="calendar-border"></div>
<!-- {{ eventSource$ | async | json }} -->
<div class="calendar-title-container px-20 d-flex">
<ion-row class="timeline-date align-center pr-10">
<button class="no-color" *ngIf="showCalendar" (click)="listBoxService.height='0px';showCalendar=false">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="collaps font-25" src="assets/images/icons-collaps-up.svg" ></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="collaps font-25" src="assets/images/theme/gov/icons-collaps-up.svg" ></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " class="collaps font-25" src="assets/images/theme/{{ThemeService.currentTheme}}/icons-collaps-up.svg"></ion-icon>
</button>
<button class="no-color" *ngIf="!showCalendar" (click)="weekToShow();showCalendar=true">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="collaps font-25" src="assets/images/icons-collaps-down.svg" ></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="collaps font-25" src="assets/images/theme/gov/icons-collaps-down.svg" ></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " class="collaps font-25" src="assets/images/theme/{{ThemeService.currentTheme}}/icons-collaps-down.svg" ></ion-icon>
</button >
</ion-row>
<div style="padding-right: 50px" class="font-16-em text-black align-center cursor-pointer" (click)="changeSegment('Combinado')" [class.active]="segment == 'Combinado' ">
Todos...
</div>
<div style="padding-right: 50px" class="font-16-em text-black align-center cursor-pointer" (click)="changeSegment('Pessoal')" [class.active]="segment == 'Pessoal' ">
Pessoais
</div>
<div class="font-16-em text-black align-center cursor-pointer" (click)="changeSegment('Oficial')" [class.active]="segment == 'Oficial' ">
Oficiais
</div>
</div>
</div>
</div>
</div>
<div class="timeline-wrapper flex-grow-1 height-100" >
<div class="height-100">
<div class="timeline-container height-100 d-flex pt-10 pl-20 filter-{{segment}} flex-column" >
<div class="ss-timeline timeline-mobile flex-grow-1 pr-10 text-black height-100 width-100 overflow-y-auto" >
<div *ngFor="let year of TimelineMDList " >
<!-- {{year.yearInfo.yearName}} -->
<div *ngFor="let month of year.months " class="header-day" >
<div *ngFor="let day of month.days; let i = index " class="EventListBox-container" >
<div class="day" >
<span *ngIf="i == 0 && isSelectedDayIsToday" > Hoje, </span>
{{ day.daysInfo.dayName }} <div style="text-transform: capitalize; display: inline;">{{month.monthInfo.monthName}}</div>
</div>
<div *ngFor="let event of day.events " class="EventListBox mb-10" >
<div class="d-flex content-{{event.profile}}-{{event.event.CalendarName}} mt-10 cursor-pointer width-100 " (click)="eventClicked(event)">
<div class="schedule-time" *ngIf="event.event.IsAllDayEvent != true">
<div *ngIf="event.startMany" class="time-start labelb">Início</div>
<div *ngIf="event.endMany " class="time-end labelb">Fim</div>
<div *ngIf="event.endMany == false && event.middle == false || event.sameDay" class="time-start">{{event.event.StartDate | date: 'HH:mm'}}</div>
<div *ngIf="event.endMany == false && event.middle == false && event.eventTotalDuration>=1" class="time-start" >{{ event.duration }}</div>
<div *ngIf="event.startMany == false && event.middle == false && event.eventTotalDuration==0 || event.sameDay || event.endMany" class="time-end">
<span *ngIf="event.hasMany == true" >
{{event.event.EndDate | date: 'HH:mm'}}
</span>
<span *ngIf="event.manyDays == false">
{{event.event.EndDate | date: 'HH:mm'}}
</span>
</div>
<div *ngIf="event.startMany == false && event.middle == false && event.eventTotalDuration>=1 && event.endMany == false" class="time-end" > {{ event.duration }} </div>
<div *ngIf="event.middle" class="time-start"> Todo </div>
<div *ngIf="event.middle" class="time-end text-center"> o dia </div>
<div *ngIf="event.middle" class="time-start">
<span *ngIf="event.daysLeft >= 1">
{{ event.duration }}
</span>
</div>
</div>
<div class="schedule-time" *ngIf="event.event.IsAllDayEvent == true">
<div *ngIf="event.middle" class="time-start">Todo </div>
<div *ngIf="event.middle" class="time-end text-center">o dia</div>
<div *ngIf="!event.middle && !(event.endMany)" class="time-start">Todo </div>
<div *ngIf="!event.middle && !(event.endMany)" class="time-end text-center">o dia </div>
<div *ngIf="event.endMany" class="time-start">{{event.event.StartDate | date: 'HH:mm'}}</div>
<div *ngIf="event.endMany" class="time-end"> {{event.event.EndDate | date: 'HH:mm'}} </div>
</div>
<div class="schedule-details">
<div class="description">
<p class="m-0">{{event.event.Subject}}</p>
</div>
<div class="location">
{{event.event.Location}}
<!-- <span style="color:red;" *ngIf="event.daysLeft >= 1">
{{ event.duration }}
</span>
<span style="color:red;" *ngIf="event.event.IsAllDayEvent != true && event.endMany">
{{ event.duration }} h
</span> -->
</div>
<!-- <div class="font-13 calendar-owner"*ngIf="eventService.getCalendarOwnNameByCalendarId(event.event.CalendarId) == 'Meu calendario'">{{SessionStore.user.FullName}} </div>
<ng-template #other_content>{{eventService.getCalendarOwnNameByCalendarId(event.event.CalendarId)}}</ng-template> -->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="event-details bg-blue ">
<div *ngIf="(
mobileComponent.showAddNewEvent == false &&
mobileComponent.showEditEvent == false &&
mobileComponent.showEventDetails == false &&
mobileComponent.showEventList == false &&
mobileComponent.showEventToApprove == false &&
mobileComponent.showAttendees == false &&
mobileComponent.showAttendeeModal == false &&
mobileComponent.showEditEventToApprove == false
)
"
class="text-black nothing-to-show">
Nenhum evento selecionado
</div>
<!-- New -->
<app-new-event *ngIf="mobileComponent.showAddNewEvent"
[profile]="profile"
[selectedSegment]=segment
[taskParticipants]="taskParticipants"
[taskParticipantsCc]="taskParticipantsCc"
[selectedDate]="eventSelectedDate"
(onAddEvent)="openAddEventDismiss($event)"
(openAttendeesComponent)="openAttendeesComponent($event)"
(cloneAllmobileComponent)="cloneAllmobileComponent()"
[eventAttendees]="contacts"
(clearContact)="clearContact()"
(setContact)="setContact($event)"
[CalendarDate]="viewDate"
(setIntervenient)="setIntervenient($event)"
(setIntervenientCC)="setIntervenientCC($event)"
></app-new-event>
<!-- Edit -->
<app-edit-event *ngIf="mobileComponent.showEditEvent"
[taskParticipants]="taskParticipants"
[taskParticipantsCc]="taskParticipantsCc"
[profile]="profile"
[selectedSegment]="segment"
[postEvent]="postEvent"
(clearPostEvent)="clearPostEvent"
(clearContact)="clearContact()"
(openAttendeesComponent)="openAttendeesComponent($event)"
(setContact)="setContact($event)"
(closeComponent)="closeComponentEditEventOrAdd()"
(setIntervenient)="setIntervenient($event)"
(setIntervenientCC)="setIntervenientCC($event)"
></app-edit-event>
<!-- Edit event to approve -->
<app-edit-event-to-approve
class="d-flex flex-column height-100"
*ngIf="mobileComponent.showEditEventToApprove"
[taskParticipants]="taskParticipants"
[taskParticipantsCc]="taskParticipantsCc"
[saveData] = "eventToaprove.saveData"
[serialNumber] = "eventToaprove.serialNumber"
(setContact)="setContact($event)"
(clearContact)="clearContact()"
(openAttendeesComponent)="openAttendeesComponent($event)"
(closeComponent)="approveEventDismissGoBack()"
(approveEventDismiss) = "approveEventDismiss($event)"
(setIntervenient)="setIntervenient($event)"
(setIntervenientCC)="setIntervenientCC($event)"
(closeEventToApprove)="closeEventToApproveGoBack()"
></app-edit-event-to-approve>
<!-- View -->
<app-view-event *ngIf="mobileComponent.showEventDetails"
[profile]="profile"
[eventId]="selectedEventId"
[CalendarId]="selectedEventCalendarId"
(viewEventDetailDismiss)="viewEventDetailDismiss($event)"
[eventAttendees]="contacts"
></app-view-event>
<app-event-list
[style.display]="mobileComponent.showEventList ? 'flex' : 'none'"
[profile]="profile"
[showComponent] = "mobileComponent.showEventList"
(approveEventDismiss) = "approveEventDismiss($event)"
(cloneAllmobileComponent)="viewEventDetailDismiss($event)"
>
</app-event-list>
<!-- Event to approve details -->
<app-approve-event class="d-flex flex-column"
*ngIf="mobileComponent.showEventToApprove"
[style.display]="mobileComponent.transparentEventToApprove ? 'flex' : 'none'"
[showComponent] = "mobileComponent.showEventToApprove"
[componentTransparent] = "mobileComponent.transparentEventToApprove"
[serialNumber] = "eventToaprove.serialNumber"
[InstanceId] = "eventToaprove.InstanceId"
[saveData] = "eventToaprove.saveData"
(cloneAllmobileComponent)="viewEventDetailDismiss($event)"
(closeEventToApprove)="closeEventToApproveGoBack()"
(AproveEventEditEvent)="AproveEventEditEvent($event)"
(EditApproveEventDismiss)="EditApproveEventDismiss()"
[eventAttendees]="contacts"
>
</app-approve-event>
<app-attendee-modal
[footer]="true"
class="d-flex flex-column height-100"
*ngIf="mobileComponent.showAttendees"
(closeComponent)="GoBackEditOrAdd()"
(setContact)="setContact($event)"
[adding]="adding"
[taskParticipants]="taskParticipants"
[taskParticipantsCc]="taskParticipantsCc"
[hideExternalDomain]="false"
(setIntervenient)="setIntervenient($event)"
(setIntervenientCC)="setIntervenientCC($event)"
>
</app-attendee-modal>
</div>
</div>
</ion-content>
File diff suppressed because it is too large Load Diff
+24
View File
@@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { AgendaPage } from './agenda.page';
describe('AgendaPage', () => {
let component: AgendaPage;
let fixture: ComponentFixture<AgendaPage>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AgendaPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(AgendaPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { ApproveEventPage } from './approve-event.page';
const routes: Routes = [
{
path: '',
component: ApproveEventPage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class ApproveEventPageRoutingModule {}
@@ -0,0 +1,21 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { ApproveEventPageRoutingModule } from './approve-event-routing.module';
import { ApproveEventPage } from './approve-event.page';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
ApproveEventPageRoutingModule
],
declarations: [ApproveEventPage],
exports: [ApproveEventPage]
})
export class ApproveEventPageModule {}
@@ -0,0 +1,141 @@
<ion-content id="main-content">
<div class="main-content d-flex flex-column height-100" *ngIf="loadedEvent">
<div class="pl-20 pr-20 text-center d-flex justify-center align-center" style="width:100%; height: 30px; background-color: var(--Event-approve-header-color); border-top-right-radius: 25px;">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="right-icons font-28" src="assets/images/icons-received-event.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov'" class="right-icons font-28" src="assets/images/theme/gov/icons-received-event.svg"></ion-icon>
<!-- <ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="right-icons" src="assets/images/theme/gov/icons-received-event-selected.svg"></ion-icon> -->
<div style="color: black;">
Evento Pendente de Aprovação
</div>
<!-- List events to approve desktop -->
</div>
<div class="main-content d-flex height-100 width-100">
<div class="content d-flex flex-column">
<div class="header-content width-100 d-flex justify-space-between">
<div (click)="close()" class="header-icon-left cursor-pointer">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/images/icons-arrow-arrow-left.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " src="assets/images/theme/doneIt/icons-calendar-arrow-left.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/images/theme/gov/icons-calendar-arrow-left.svg"></ion-icon>
</div>
<div class="header-title flex-grow-1 cursor-pointer">
<label>{{loadedEvent.workflowInstanceDataFields.Subject}}</label>
</div>
<div (click)="editar(loadedEvent.serialNumber)" class="header-icon-right display-none-{{showAside}}" *ngIf="p.userPermission([p.permissionList.Agenda.creatEvent])">
<button class="btn-no-color">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/images/icons-edit.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/images/theme/gov/icons-edit.svg"></ion-icon>
</button>
</div>
<div (click)="rejectTask(loadedEvent.serialNumber)" class="header-icon-right display-none-{{showAside}}">
<button class="btn-no-color" >
<ion-icon class="delete" name="trash-sharp"></ion-icon>
</button>
</div>
</div>
<div class="upper-content d-flex flex-column">
<div class="content-location">
<p>
<span class="location">{{loadedEvent.workflowInstanceDataFields.Location}}</span>
<span class="event-type-{{loadedEvent.workflowInstanceDataFields.Agenda}}" *ngIf="loadedEvent.workflowDisplayName == 'Agenda Oficial MDGPR' " style="background-color: #ffb703;">
{{loadedEvent.workflowInstanceDataFields.Agenda}}
</span>
<span class="event-type-{{loadedEvent.workflowInstanceDataFields.Agenda}}" *ngIf="loadedEvent.workflowDisplayName == 'Agenda Pessoal MDGPR' " style="background-color: #f05d5e;">
{{loadedEvent.workflowInstanceDataFields.Agenda}}
</span>
<span class="event-type-{{loadedEvent.workflowInstanceDataFields.Agenda}}" *ngIf="loadedEvent.workflowDisplayName == 'Agenda Oficial PR' " style="background-color: #99e47b;">
{{loadedEvent.workflowInstanceDataFields.Agenda}}
</span>
<span class="event-type-{{loadedEvent.workflowInstanceDataFields.Agenda}}" *ngIf="loadedEvent.workflowDisplayName == 'Agenda Pessoal PR' " style="background-color: #958bfc;">
{{loadedEvent.workflowInstanceDataFields.Agenda}}
</span>
</p>
</div>
<div class="content-details">
<ion-label>
<p>{{customDate}}</p>
<p *ngIf="toDateString(loadedEvent.workflowInstanceDataFields.StartDate) == toDateString(loadedEvent.workflowInstanceDataFields.EndDate)">das {{loadedEvent.workflowInstanceDataFields.StartDate | date: 'HH:mm'}} às {{loadedEvent.workflowInstanceDataFields.EndDate | date: 'HH:mm'}}</p>
<p *ngIf="toDateString(loadedEvent.workflowInstanceDataFields.StartDate) != toDateString(loadedEvent.workflowInstanceDataFields.EndDate)">{{loadedEvent.workflowInstanceDataFields.StartDate | date: 'd/M/yy' }} - {{ loadedEvent.workflowInstanceDataFields.EndDate | date: 'dd/M/yy'}} </p>
<p>
<span *ngIf="loadedEvent.workflowInstanceDataFields.OccurrenceType == 0">Diário</span>
<span *ngIf="loadedEvent.workflowInstanceDataFields.OccurrenceType == 1">Semanal</span>
<span *ngIf="loadedEvent.workflowInstanceDataFields.OccurrenceType == 2">Mensal</span>
<span *ngIf="loadedEvent.workflowInstanceDataFields.OccurrenceType == 3">Anual</span>
<span *ngIf="loadedEvent.workflowInstanceDataFields.OccurrenceType == -1">(Não se repete)</span>
</p>
</ion-label>
</div>
</div>
<div class="line"></div>
<div class="overflow-y-auto">
<div class="middle-content">
<div *ngIf="loadedEvent.workflowInstanceDataFields.ParticipantsList">
<h5 class="font-17-rem">Intervenientes({{loadedEvent.workflowInstanceDataFields.ParticipantsList.length}})</h5>
<div *ngFor="let att of loadedEvent.workflowInstanceDataFields.ParticipantsList">
<ion-label>{{att.Name}}</ion-label>
</div>
<div class="line"></div>
</div>
<div *ngIf="loadedEvent.workflowInstanceDataFields.Body">
<h5 class="font-17-rem">Detalhes</h5>
<ion-item lines="none" class="ion-no-margin ion-no-padding">
<pre class="width-100 text">{{ loadedEvent.workflowInstanceDataFields.Body }} </pre>
</ion-item>
<div class="line"></div>
</div>
</div>
<div *ngIf="loadedAttachments" class="bottom-content width-100">
<ion-list>
<h5 class="font-17-rem">Documentos Anexados({{loadedAttachments.length}}) </h5>
<ion-item class="ion-no-margin ion-no-padding cursor-pointer"
*ngFor="let attachment of loadedAttachments"
(click)="viewDocument(attachment.DocId, attachment)">
<ion-label>
<p class="attach-title-item d-block">{{attachment.Description || 'Sem título'}}</p>
<p><span class="span-left">{{attachment.Stakeholders}}</span><span class="span-right">{{ attachment.CreateDate | date: 'dd-MM-yyyy HH:mm' }}</span></p>
</ion-label>
</ion-item>
</ion-list>
</div>
</div>
</div>
<div *ngIf="showAside" class="aside-right flex-column height-100 cursor-pointer">
<div class="aside-buttons">
<button (click)="approveTask(loadedEvent.serialNumber)" full class="btn-ok" shape="round" >Aprovar</button>
<button full class="btn-ok" shape="round" >Editar evento</button>
<button (click)="emendTask(loadedEvent.serialNumber)" class="btn-cancel" shape="round" >Enviar para Revisão</button>
<div class="solid"></div>
<button full class="btn-cancel" shape="round" (click)="editar(loadedEvent.serialNumber)" >Editar</button>
<button (click)="rejectTask(loadedEvent.serialNumber)" full class="btn-delete" shape="round" >Eliminar</button>
</div>
</div>
</div>
</div>
</ion-content>
<ion-footer *ngIf="loadedEvent" class="display-none-{{showAside}} ion-no-border">
<div class="buttons">
<button class="btn-cancel" shape="round" (click)="emendTask(loadedEvent.serialNumber)">Enviar para Revisão</button>
<button class="btn-cancel" shape="round" (click)="approveTask(loadedEvent.serialNumber)">Aprovar</button>
<!-- <button *ngIf="loadedEvent.activityInstanceName == 'Editar Evento'" full class="btn-cancel" shape="round" (click)="editar(loadedEvent.serialNumber)" >Editar</button>
<button *ngIf="loadedEvent.activityInstanceName == 'Editar Evento'" full class="btn-delete" shape="round" (click)="rejectTask(loadedEvent.serialNumber)" >Rejeitar</button> -->
</div>
</ion-footer>
@@ -0,0 +1,229 @@
@import '~src/function.scss';
.display-none-true{
display: none;
border: 1px solid red;
}
.header-content{
//margin: 25px auto;
.header-icon-left{
width: 36px;
font-size: rem(33);
color: #42b9fe;
float: left;
}
.header-icon-right{
width: rem(45);
font-size: rem(45);
float: left;
margin-left: 5px;
}
}
.header-title{
font-family: Roboto;
font-size: rem(25);
margin: 0 5px 0 5px;
padding: 0;
color:#000;
float: left;
}
.content{
padding: 30px 20px 0 20px !important;
overflow: auto;
width: 100%;
.upper-content{
margin-left: 40px;
font-size: rem(18);
.content-location{
margin-top: 0px !important;
width: 100%;
padding: 0;
}
.location{
float: left;
}
.event-type-Oficial{
font-family: Roboto;
border-radius: 20px;
background: var(--label-bg-color);
float: right !important;
padding: 5px 13.5px 5px 13.5px;
color: #fff;
}
.event-type-Pessoal{
font-family: Roboto;
border-radius: 20px;
background: #f05d5e;
float: right !important;
padding: 5px 13.5px 5px 13.5px;
color: #fff;
}
.button-edit-event {
width: 140px;
height: 44px;
border-radius: 22.5px;
--background: #e0e9ee;
--color:#061b52;
}
.content-details p{
font-size: rem(16);
}
}
.middle-conten{
.middle-content h3, .middle-content p{
font-size: rem(16);
}
}
.bottom-content{
margin: 0 auto;
.bottom-content h3{
font-size: rem(16);
margin: 0 0 0 10px;
}
.attach-document{
font-size: rem(15);
color: var(--title-text-color);
margin: 5px 5px 5px 10px;
padding: 5px;
float: left;
}
.attach-icon{
width: 37px;
font-size: rem(35);
float: left;
}
.attach-title-item{
width: 100%;
font-size: rem(15);
color:#0d89d1;
}
/* SPAN */
.span-left{
float: left;
font-size: rem(15);
}
.span-right{
text-align: right;
float: right;
font-size: rem(13);
}
}
}
.aside-right{
overflow: auto;
padding: 30px 20px 0 20px !important;
.arrow-right{
display: flex;
justify-content: flex-end;
margin-bottom: 20px;
/* .arrow-right-icon{
width: 37px;
float: right;
font-size: rem(35);
overflow: hidden;
} */
}
.aside-buttons{
width: 100% !important;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.btn-ok, .btn-cancel, .btn-delete{
height: auto !important;
font-size: rem(16) !important;
width: 100% !important;
margin-bottom: 10px !important;
padding: 15px !important;
}
}
.solid {
display: block;
width: 90%;
border-top: 1px solid #ebebeb;
margin: 0 auto !important;
margin-bottom: 10px !important;
}
}
.buttons{
display: flex;
justify-content: space-between;
overflow: auto;
padding: 5px;
.button-options {
height: 44px;
--color: #42b9fe;
/* opacity: 0; */
}
.button-approve {
width: 140px;
height: 44px;
border-radius: 22.5px;
--background: #42b9fe;
}
.button-reject {
width: 140px;
height: 44px;
--color: #d30a0a;
border-radius: 22.5px;
--background: #ffe0e0;
}
}
/* @media only screen and (max-width: 1140px) {
.content{
width: 100%;
}
.aside-right{
display: none;
}
} */
/* @media only screen and (min-width: 1140px) {
.div-icon{
display: none;
}
.content{
//width: 75%;
border-right: 1px solid #d8d8d8;
}
.aside-right{
width: 25%;
}
} */
.delete{
padding: 7px;
font-size: rem(21);
color:#fff;
background: #d30606;
border-radius: 20px;
}
.text {
text-transform: initial !important
}
@@ -0,0 +1,24 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { ApproveEventPage } from './approve-event.page';
describe('ApproveEventPage', () => {
let component: ApproveEventPage;
let fixture: ComponentFixture<ApproveEventPage>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ ApproveEventPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(ApproveEventPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,280 @@
import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core';
import { NavigationExtras, Router } from '@angular/router';
import { ModalController, PopoverController } from '@ionic/angular';
import { Event } from 'src/app/models/event.model';
import { AttachmentsService } from 'src/app/services/attachments.service';
import { ProcessesService } from 'src/app/services/processes.service';
import { ToastService } from 'src/app/services/toast.service';
import { ViewDocumentPage } from 'src/app/modals/view-document/view-document.page';
import { ThemeService } from 'src/app/services/theme.service';
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service';
import { TaskService } from 'src/app/services/task.service'
import { AgendaDataRepositoryService } from 'src/app/module/agenda/data/repository/agenda-data-repository.service';
import { EventToApproveDetails } from 'src/app/models/entiry/agenda/eventToApproveDetails';
import { EventsService } from 'src/app/services/events.service';
import { isHttpError } from 'src/app/services/http.service';
import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
import { PermissionService } from 'src/app/services/permission.service';
import { EventActionsPopoverPage } from 'src/app/ui/agenda/modal/event-actions-popover/event-actions-popover.page';
import { EmendMessageModalPage } from 'src/app/ui/agenda/modal/emend-message-modal/emend-message-modal.page';
@Component({
selector: 'app-approve-event',
templateUrl: './approve-event.page.html',
styleUrls: ['./approve-event.page.scss'],
})
export class ApproveEventPage implements OnInit {
event: Event;
@Input() loadedEvent: EventToApproveDetails;
loadedAttachments: any;
customDate: any;
today: any;
show: boolean = false;
months = ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"];
days = ["Domingo", "Segunda-feira", "Terça-feira", "Quarta-feira", "Quinta-feira", "Sexta-feira", "Sábado"];
@Input() serialNumber: string;
@Input() showComponent: string;
@Input() componentTransparent: any
@Input() InstanceId: string;
@Input() showAside: boolean;
@Output() approveEventDismiss = new EventEmitter<any>();
@Output() closeEventToApprove = new EventEmitter<any>();
@Output() AproveEventEditEvent = new EventEmitter<any>();
@Output() EditApproveEventDismiss = new EventEmitter<any>();
constructor(
private router: Router,
private modalController: ModalController,
private popoverController: PopoverController,
private toastService: ToastService,
public ThemeService: ThemeService,
private httpErroHandle: HttpErrorHandle,
public TaskService: TaskService,
private agendaDataRepository: AgendaDataRepositoryService,
public EventsService: EventsService,
private httpErrorHandle: HttpErrorHandle,
public p: PermissionService,
) {
// Event to approve list
window['edit-approve-event-desktop'] = () => {
this.getTask()
}
}
toDateString(e) {
return new Date(e).toDateString()
}
ngOnInit() {
this.getTask();
}
close() {
this.closeEventToApprove.emit();
this.modalController.dismiss();
}
@XTracerAsync({name:'ApproveEventPage/getTask', bugPrint: true})
async getTask(tracing?: TracingType) {
const res = await this.agendaDataRepository.getEventToApproveById(this.serialNumber, tracing)
if (res.isOk()) {
this.loadedEvent = res.value;
this.loadedAttachments = this.loadedEvent.Attachments
this.today = new Date(res.value.workflowInstanceDataFields.StartDate);
//
this.customDate = this.days[this.today.getDay()] + ", " + this.today.getDate() + " de " + (this.months[this.today.getMonth()]);
tracing.setAttribute('outcome', 'success')
} else {
tracing.setAttribute('eventId', this.serialNumber)
if(!isHttpError(res.error)) {
this.toastService._badRequest('Pedimos desculpa mas não foi possível executar a acção. Por favor, contacte o apoio técnico. #133')
console.log(res.error)
} else if (isHttpError(res.error)) {
if(res.error.status == 404) {
this.toastService._badRequest('Este evento já não existe')
} else {
this.httpErrorHandle.httpStatusHandle(res.error)
}
}
}
}
async approveTask(serialNumber: string) {
let body = { "serialNumber": serialNumber, "action": "Aprovar" }
const loader = this.toastService.loading()
const result = await this.agendaDataRepository.approveEvent(serialNumber)// .subscribe((value) => {
if(result.isOk()) {
console.log(result.value)
this.modalController.dismiss(serialNumber);
this.httpErroHandle.httpsSucessMessagge('Aprovar')
this.TaskService.loadEventosParaAprovacao();
} else {
console.log('aprove event error: ', result.error)
this.httpErroHandle.httpStatusHandle(result.error)
}
this.close()
loader.remove()
}
async rejectTask(serialNumber: string) {
let body = { "serialNumber": serialNumber, "action": "Rejeitar" }
const loader = this.toastService.loading()
const result = await this.agendaDataRepository.deleteEvent(serialNumber, true)//.subscribe((value) => {
if(result.isOk()) {
this.httpErroHandle.httpsSucessMessagge('delete event');
this.TaskService.loadEventosParaAprovacao();
this.close()
} else {
console.log('reject event error: ', result.error)
this.httpErroHandle.httpStatusHandle(result.error)
}
loader.remove()
}
async viewDocument(DocId: string, Document) {
const modal = await this.modalController.create({
component: ViewDocumentPage,
componentProps: {
trustedUrl: '',
file: {
title: Document.Description,
url: '',
title_link: '',
},
Document,
applicationId: Document.ApplicationId,
docId: Document.DocId || Document.SourceId,
// folderId: this.loadedEvent.FolderId,
task: this.loadedEvent
},
cssClass: 'modal modal-desktop'
});
await modal.present();
}
async openOptions(ev: any) {
const popover = await this.popoverController.create({
component: EventActionsPopoverPage,
componentProps: {
activityInstanceName: this.loadedEvent.activityInstanceName
},
cssClass: 'event-actions-popover',
event: ev,
translucent: true
});
return await popover.present().then(() => {
this.TaskService.loadEventosParaAprovacao()
this.getTask()
}, (error) => {
console.log(error)
})
}
async emendTask(serialNumber: string) {
const modal = await this.modalController.create({
component: EmendMessageModalPage,
componentProps: {
},
cssClass: 'emend-message-modal',
backdropDismiss: false
});
modal.onDidDismiss()
.then(async (res) => {
if (res.data.option == 'save') {
let body = {
"serialNumber": serialNumber,
"action": "Emendar",
"dataFields": {
"ReviewUserComment": res.data,
}
}
const loader = this.toastService.loading();
/* await this.processes.PostTaskAction(body).toPromise(); */
const result = await this.agendaDataRepository.eventToaprovalStatus(serialNumber, 'Revision', res.data.note)// .subscribe((value) => {
if(result.isOk()) {
this.httpErroHandle.httpsSucessMessagge('Rever')
this.TaskService.loadEventosParaAprovacao();
this.close();
} else {
console.log('send event to revision error: ', result.error)
this.httpErroHandle.httpStatusHandle(result.error)
}
loader.remove()
} else {
}
}, (error) => {
console.log(error)
});
await modal.present();
}
goToEventsToApprove() {
if (window.location.pathname.startsWith('/home/agenda')) {
this.close()
} else {
let navigationExtras: NavigationExtras = {
queryParams: {
"eventos": true,
}
};
this.router.navigate(['/home/gabinete-digital'], navigationExtras);
}
}
/** @description edit event to aprove */
async editar(serialNumber: string) {
this.EditApproveEventDismiss.emit();
}
}
@@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { EditEventToApprovePage } from './edit-event-to-approve.page';
const routes: Routes = [
{
path: '',
component: EditEventToApprovePage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class EditEventToApprovePageRoutingModule {}
@@ -0,0 +1,50 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { EditEventToApprovePageRoutingModule } from './edit-event-to-approve-routing.module';
import { EditEventToApprovePage } from './edit-event-to-approve.page';
import { MatNativeDateModule } from '@angular/material/core';
import {
NgxMatDatetimePickerModule,
NgxMatNativeDateModule,
NgxMatTimepickerModule
} from '@angular-material-components/datetime-picker';
import { ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatSelectModule } from '@angular/material/select';
import { NgxMatMomentModule } from '@angular-material-components/moment-adapter';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatInputModule } from '@angular/material/input';
import { MatDialogModule } from '@angular/material/dialog';
import { AttendeeModalPageModule } from 'src/app/shared/event/attendee-modal/attendee-modal.module';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
EditEventToApprovePageRoutingModule,
// Angular material
MatDatepickerModule,
MatInputModule,
MatNativeDateModule,
NgxMatDatetimePickerModule,
NgxMatTimepickerModule,
NgxMatNativeDateModule,
NgxMatMomentModule,
MatSelectModule,
MatButtonModule,
ReactiveFormsModule,
MatDialogModule,
AttendeeModalPageModule,
],
declarations: [EditEventToApprovePage],
exports: [EditEventToApprovePage]
})
export class EditEventToApprovePageModule {}
@@ -0,0 +1,332 @@
<ion-content>
<!-- Edit event for Inicio -->
<div class="main-content height-100 d-flex">
<div class="content d-flex flex-column width-md-100 height-100">
<div class="main-header pt-30 px-20 background-white pb-15">
<ion-header>
<div class="title-content">
<div class="middle">
<ion-label class="title">Editar evento por aprovar</ion-label> <br>
<i style="margin-top: -3px; font-size: 15px;" > Campos marcados com * são obrigatórios</i>
</div>
</div>
</ion-header>
</div>
<ion-item-sliding class="overflow-y-auto" >
<div class="px-20">
<div class="ion-item-container width-100" [class.input-error]="Form?.get('Subject')?.invalid && validateFrom ">
<ion-input autocomplete="on" autocorrect="on" spellcheck="true" placeholder="Assunto*" [(ngModel)]="eventProcess.workflowInstanceDataFields.Subject"></ion-input>
</div>
<div *ngIf="Form && validateFrom" >
<div *ngIf="Form.get('Subject').invalid " class="input-errror-message">
<div *ngIf="Form.get('Subject').errors?.required">
</div>
<div *ngIf="Form.get('Subject').errors?.minlength">
O campo deve ter pelo menos 4 caracteres.
</div>
</div>
</div>
<div class="container-div width-100">
<div class="ion-item-class-2">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-location.svg"></ion-icon>
</div>
<div class="ion-input-class" [class.input-error]="Form?.get('Location')?.invalid && validateFrom ">
<ion-input autocomplete="on" autocorrect="on" spellcheck="true" placeholder="Localização*" [(ngModel)]="eventProcess.workflowInstanceDataFields.Location"></ion-input>
</div>
</div>
</div>
<div *ngIf="Form && validateFrom" >
<div *ngIf="Form.get('Location').invalid " class="input-errror-message">
<div *ngIf="Form.get('Location').errors?.required">
</div>
</div>
</div>
<div class="container-div width-100">
<div class="ion-item-class-2">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class">
<ion-select placeholder="Selecione agenda*"
class="d-block d-md-none"
selectedText="{{eventProcess.workflowInstanceDataFields.Agenda}}"
[(ngModel)]="eventProcess.workflowInstanceDataFields.Agenda"
interface="action-sheet" Cancel-text="Cancelar"
required
[disabled]=true
>
<ion-select-option value="Oficial">Agenda Oficial</ion-select-option>
<ion-select-option value="Pessoal">Agenda Pessoal</ion-select-option>
</ion-select>
<mat-form-field appearance="none"
class="d-none d-md-block width-100" >
<mat-select placeholder="Selecione agenda"
[(ngModel)]="eventProcess.workflowInstanceDataFields.Agenda" >
<mat-option value="Oficial">
Oficial
</mat-option>
<mat-option value="Pessoal">
Pessoal
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
<div class="container-div width-100">
<div class="ion-item-class-2">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class" [class.input-error]="Form?.get('Categories')?.invalid && validateFrom ">
<ion-select placeholder="Selecione tipo de evento*"
class="d-block d-md-none"
[(ngModel)]="eventProcess.workflowInstanceDataFields.Category"
interface="action-sheet"
Cancel-text="Cancelar" required>
<ion-select-option value="Reunião">Reunião</ion-select-option>
<ion-select-option value="Viagem">Viagem</ion-select-option>
<ion-select-option value="Conferência">Conferência</ion-select-option>
<ion-select-option value="Encontro">Encontro</ion-select-option>
</ion-select>
<mat-form-field class="d-none d-md-block" appearance="none" class="width-100" placeholder="Sample Type" required>
<!-- <input matInput type="text" > -->
<mat-select [(ngModel)]="eventProcess.workflowInstanceDataFields.Category" >
<mat-option value="Meeting">
Reunião
</mat-option>
<mat-option value="Travel">
Viagem
</mat-option>
<mat-option value="Conference">
Conferência
</mat-option>
<mat-option value="Encontro">
Encontro
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
<div class="container-div width-100">
<div>
<ion-item>
<ion-label>Todo dia</ion-label>
<ion-checkbox [(ngModel)]="eventProcess.workflowInstanceDataFields.IsAllDayEvent" (ionChange)="onCheckboxChange($event)"></ion-checkbox>
</ion-item>
</div>
</div>
<div *ngIf="Form && validateFrom" >
<div *ngIf="Form.get('participantes').invalid " class="input-errror-message">
<div *ngIf="Form.get('participantes').errors?.required">
Adicionar participante
</div>
</div>
</div>
<div class="container-div width-100">
<div class="ion-item-class-2 width-100">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class width-100">
<ion-datetime
class="d-block d-md-none"
placeholder="Início"
[(ngModel)]="eventProcess.workflowInstanceDataFields.StartDate"
displayFormat="D MMM YYYY H:mm"
minuteValues="0,5,10,15,20,25,30,35,40,45,50,55"
monthShortNames="Jan, Fev, Mar, Abr, Mai, Jun, Jul, Aug, Sep, Out, Nov, Dez"
(ngModelChange)="onDateChange($event)"
>
</ion-datetime>
<mat-form-field appearance="none" class="width-100 date-hour-picker d-none d-md-block">
<input matInput [ngxMatDatetimePicker]="picker1"
placeholder="Choose a date"
[(ngModel)]="eventProcess.workflowInstanceDataFields.StartDate"
[disabled]="disabled"
(ngModelChange)="onDateChange($event)"
>
<mat-datepicker-toggle id="new-inicio" matSuffix [for]="picker1"></mat-datepicker-toggle>
<ngx-mat-datetime-picker #picker1
[showSpinners]="showSpinners"
[showSeconds]="showSeconds"
[stepHour]="stepHour" [stepMinute]="stepMinute"
[stepSecond]="stepSecond"
[touchUi]="touchUi">
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
</div>
</div>
<div class="container-div width-100">
<div class="ion-item-class-2">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class">
<ion-datetime
class="d-none d-md-none"
placeholder="Fim"
[(ngModel)]="eventProcess.workflowInstanceDataFields.EndDate"
displayFormat="D MMM YYYY H:mm"
minuteValues="0,5,10,15,20,25,30,35,40,45,50,55"
monthShortNames="Jan, Fev, Mar, Abr, Mai, Jun, Jul, Aug, Sep, Out, Nov, Dez"
>
</ion-datetime>
<mat-form-field appearance="none" class="width-100 date-hour-picker d-none d-md-block">
<input matInput [ngxMatDatetimePicker]="fim"
placeholder="Choose a date"
[(ngModel)]="eventProcess.workflowInstanceDataFields.EndDate"
[min]="endMinDate" [max]="maxDate"
[disabled]="disabled"
>
<mat-datepicker-toggle id="new-fim" matSuffix [for]="fim"></mat-datepicker-toggle>
<ngx-mat-datetime-picker #fim
[showSpinners]="showSpinners"
[showSeconds]="showSeconds"
[stepHour]="stepHour" [stepMinute]="stepMinute"
[stepSecond]="stepSecond"
[touchUi]="touchUi">
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
</div>
</div>
<div class="container-div width-100">
<div class="ion-item-class-2">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-person.svg"></ion-icon>
</div>
<div class="ion-input-class-no-height d-flex cursor-pointer" (click)="addParticipants()">
<div class="list-people flex-grow-1">
<ion-item lines="none">
<ion-list>
<ion-label *ngIf="taskParticipants?.length < 1" class="list-people-title">Adicionar Intervenientes*</ion-label>
<ion-label *ngFor="let participant of taskParticipants">{{participant.Name}}</ion-label>
</ion-list>
</ion-item>
</div>
<div class="add-people cursor-pointer" >
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " slot="start" src="assets/images/icons-arrow-forward.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " slot="start" src="assets/images/theme/gov/icons-arrow-forward.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " slot="start" src="assets/images/theme/{{ThemeService.currentTheme}}/icons-arrow-forward.svg"></ion-icon>
</div>
</div>
</div>
</div>
<div class="container-div width-100">
<div class="ion-item-class-2">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-people-cc.svg"></ion-icon>
</div>
<div class="ion-input-class-no-height d-flex cursor-pointer" (click)="addParticipantsCC()">
<div class="list-people flex-grow-1">
<ion-item lines="none">
<ion-list
style="
display: grid;
">
<ion-label *ngIf="taskParticipantsCc?.length < 1" class="list-people-title">Com Conhecimento</ion-label>
<ion-label *ngFor="let participant of taskParticipantsCc">{{participant.Name}}</ion-label>
</ion-list>
</ion-item>
</div>
<div class="add-people cursor-pointer" >
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " slot="start" src="assets/images/icons-arrow-forward.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " slot="start" src="assets/images/theme/gov/icons-arrow-forward.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " slot="start" src="assets/images/theme/{{ThemeService.currentTheme}}/icons-arrow-forward.svg"></ion-icon>
</div>
</div>
</div>
</div>
<div class="container-div d-flex width-100">
<div class="ion-item-class-2 d-flex width-100">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-description.svg"></ion-icon>
</div>
<div class="ion-input-class-no-height width-100 flex-grow-1">
<ion-textarea autoGrow="true" autocomplete="on" autocorrect="on" spellcheck="true" [(ngModel)]="eventProcess.workflowInstanceDataFields.Body" placeholder="Detalhes" rows="6" cols="20"></ion-textarea>
</div>
</div>
</div>
<div (click)="getDoc()" class="cursor-pointer d-flex container-div width-100 ion-item-container-no-border" >
<ion-label>
<div class="attach-icon">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/images/icons-attach-doc.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/images/theme/gov/icons-attach-doc.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " src="assets/images/theme/{{ThemeService.currentTheme}}/icons-attach-doc.svg"></ion-icon>
</div>
<div class="attach-document">
<ion-label>Adicionar documentos</ion-label>
</div>
</ion-label>
</div>
<div class="d-flex container-div width-100" >
<ion-list class="width-100 ">
<ion-item class="width-100" *ngFor="let document of loadedAttachments; let i = index">
<ion-label class="width-100 d-block list" >
<p class="d-flex ion-justify-content-between">
<span class="attach-title-item">{{document.subject || document.Description || document.SourceName || document.sourceName || 'Sem título'}}</span>
<span class="app-name" *ngIf="document.applicationId == 8 || document.ApplicationId == 8"> Correspondencia </span>
<span class="app-name" *ngIf="document.applicationId == 386 || document.ApplicationId == 386"> AccoesPresidenciais </span>
<span class="app-name" *ngIf="document.applicationId == 361 || document.ApplicationId == 361 "> ArquivoDespachoElect </span>
<span class="close-button text-black cursor-pointer" (click)="deleteAttachment(document, i)" >
<ion-icon class="font-20" src="assets/images/icons-delete-25.svg"></ion-icon>
</span>
</p>
<p><span class="span-left" *ngIf="document.Stakeholders != false">{{document.Stakeholders}}</span><span class="span-right" *ngIf="document.dateEntry != false"> {{document.dateEntry }} </span></p>
</ion-label>
</ion-item>
</ion-list>
</div>
</div>
</ion-item-sliding>
</div>
</div>
</ion-content>
<ion-footer class="background-whit">
<div class="buttons">
<button class="btn-ok cursor-pointer" shape="round" (click)="gravasAction()">Gravar</button>
<button class="btn-cancel cursor-pointer" shape="round" (click)="close()">Cancelar</button>
</div>
</ion-footer>
@@ -0,0 +1,204 @@
@import '~src/function.scss';
.title-content::after, .header-md::after{
display: none;
}
.content {
margin: 0;
float: left;
border-right: 1px solid #d8d8d8 !important;
}
.main-header{
font-family: Roboto;
background-color: #fff;
min-height: 86px;
overflow:hidden;
transform: translate3d(0, 1px, 0);
.title-content{
margin: 0px auto;
padding: 0 !important;
background: #fff;
.middle{
padding: 0!important;
float: left;
}
}
.title{
font-size: rem(25);
}
}
.ion-item-container{
margin: rem(15) auto;
border: 1px solid #ebebeb;
border-radius: 5px;
padding-left: 10px;
}
.ion-item-container-no-border{
width: 100%;
margin: 0px auto;
padding: 0 !important;
}
.container-div{
margin-bottom: 15px;
float: left;
}
.ion-item-class-2{
margin: 0px auto;
}
.ion-icon-class{
width: rem(45);
height: rem(45);
float: left;
padding: 10px;
font-size: rem(25);
}
ion-select{
padding-left: 5px;
margin-left: 0;
}
.ion-input-class{
width: calc(100% - 45px);
height: rem(45);
border: 1px solid #ebebeb;
border-radius: 5px;
padding-left: 5px;
padding-right: 10px;
float: left;
}
.ion-input-class-no-height{
width: calc(100% - 45px);
border: 1px solid #ebebeb;
border-radius: 5px;
}
.list-people{
float: left;
}
.add-people{
width: rem(45);
float: right;
overflow: auto;
font-size: rem(25);
height: rem(45);
display: flex;
}
.list-people-title{
/* font-size: rem(13); */
color: #797979;
}
.attach-document{
font-size: rem(15);
color: var(--title-text-color);
margin: 5px 5px 5px 10px;
padding: 5px;
float: left;
}
.attach-icon{
width: 37px;
font-size: rem(35);
float: left;
}
.attach-title-item{
width: 100%;
font-size: rem(15);
color:var(--title-text-color);
}
/* SPAN */
.span-left{
float: left;
font-size: rem(15);
}
.span-right{
text-align: right;
float: right;
font-size: rem(13);
}
.container-footer{
margin:0 auto;
overflow: auto;
}
.button-cancel {
width: rem(170);
height: rem(44);
border-radius: 22.5px;
--background: #e0e9ee;
--color: #061b52;
margin:10px;
}
.button-save {
width: rem(170);
height: rem(44);
border-radius: 22.5px;
--background: #42b9fe;
--color:#ffffff;
margin:10px;
}
.text-input{
width: 100%;
border: 1px solid #ebebeb;
margin: 0px 15px 15px 0px;
padding: 0 !important;
border-radius: 5px;
}
/* Error Messages */
.error{
color:red;
font-size: rem(12);
font-weight: bold;
padding-bottom: 20px;
}
.span-color{
color:red;
}
.buttons{
display: flex;
justify-content: space-between;
padding: 20px;
overflow: auto;
}
.app-name{
background: var(--title-text-color);
border-radius: 18px;
text-align: center;
display: flex;
align-items: center;
padding: 0px 5px;
color: white;
font-size: rem(12);
font-weight: 500;
height: 19px;
-webkit-border-radius: 18px;
-moz-border-radius: 18px;
-ms-border-radius: 18px;
-o-border-radius: 18px;
}
.close-button {
display: none;
height: 20px;
}
.list:hover {
.app-name {
display: none;
}
.close-button {
display: block !important;
}
}
@@ -0,0 +1,24 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { EditEventToApprovePage } from './edit-event-to-approve.page';
describe('EditEventToApprovePage', () => {
let component: EditEventToApprovePage;
let fixture: ComponentFixture<EditEventToApprovePage>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ EditEventToApprovePage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(EditEventToApprovePage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,790 @@
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { AlertController, ModalController } from '@ionic/angular';
import * as moment from 'moment';
import { Attachment } from 'src/app/models/attachment.model';
import { EventPerson } from 'src/app/models/eventperson.model';
import { SearchList } from 'src/app/models/search-document';
import { SearchPage } from 'src/app/pages/search/search.page';
import { AttachmentsService } from 'src/app/services/attachments.service';
import { EventsService } from 'src/app/services/events.service';
import { ProcessesService } from 'src/app/services/processes.service';
import { ToastService } from 'src/app/services/toast.service';
import { NgxMatDateFormats } from '@angular-material-components/datetime-picker';
import { removeDuplicate } from 'src/plugin/removeDuplicate.js'
import { EventToApproveEdit } from 'src/app/models/event.model';
import { ThemeService } from 'src/app/services/theme.service'
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service';
import { AgendaDataRepositoryService } from 'src/app/module/agenda/data/repository/agenda-data-repository.service';
import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
import { AttendeesLIstChangeDetector } from 'src/app/module/agenda/data/async/change/attendeesLIstChangeDetector';
const CUSTOM_DATE_FORMATS: NgxMatDateFormats = {
parse: {
dateInput: "YYYY-MMMM-DD HH:mm"
},
display: {
dateInput: "DD MMM YYYY H:mm",
monthYearLabel: "MMM YYYY",
dateA11yLabel: "LL",
monthYearA11yLabel: "MMMM YYYY"
}
}
@Component({
selector: 'app-edit-event-to-approve',
templateUrl: './edit-event-to-approve.page.html',
styleUrls: ['./edit-event-to-approve.page.scss'],
})
export class EditEventToApprovePage implements OnInit {
public date: any;
public disabled = false;
public showSpinners = true;
public showSeconds = false;
public touchUi = false;
public enableMeridian = false;
public minDate = new Date()
public endMinDate = new Date(new Date().getTime() + 15 * 60000);
public maxDate: any;
public stepHour = 1;
public stepMinute = 15;
public stepSecond = 5;
public dateControlStart = new FormControl(moment("DD MM YYYY hh"));
public dateControlEnd = new FormControl(moment("DD MM YYYY hh"));
recurringTypes: any;
selectedRecurringType: any;
showLoader = false;
get dateStart() {
return this.dateControlStart.value
}
get dateEnd() {
return this.dateControlEnd.value
}
@ViewChild('picker') picker: any;
@ViewChild('fim') fim: any;
@ViewChild('inicio') inicio: any;
@ViewChild('picker1') picker1: any;
loadedAttachments: any[] = []
eventProcess = {
Attachments: [],
serialNumber: "",
taskStartDate: "",
activityInstanceName: "",
workflowInstanceDataFields: {
Body: "",
OccurrenceType: '',
Category: '',
LastOccurrence: new Date(),
IsRecurring: false,
ParticipantsList: [],
Agenda: '',
EndDate: '',
Location: '',
Subject: '',
InstanceId: '',
EventType: '',
StartDate: '',
MDEmail: '',
MDName: '',
IsAllDayEvent: false,
Message: '',
Status: ''
}
}
show = false
isRecurring: string;
isEventEdited: boolean;
profile: string;
eventAttendees: EventPerson[];
loadedEventAttachments: Attachment[];
adding: "intervenient" | "CC" = "intervenient";
showAttendees = false;
InstanceId: string;
Form: FormGroup;
validateFrom = false
addedAttachmentsList = [];
deletedAttachmentsList = [];
@Output() openAttendeesComponent = new EventEmitter<any>();
@Output() clearContact = new EventEmitter<any>();
@Output() setIntervenient = new EventEmitter<any>();
@Output() setIntervenientCC = new EventEmitter<any>();
@Output() closeComponent = new EventEmitter<any>();
@Output() closeEventToApprove = new EventEmitter<any>();
@Output() approveEventDismiss = new EventEmitter<any>();
@Input() saveData: any;
@Input() serialNumber: string
@Input() taskParticipants: EventPerson[];
@Input() taskParticipantsCc: EventPerson[];
constructor(
private modalController: ModalController,
private eventsService: EventsService,
public alertController: AlertController,
private attachmentsService: AttachmentsService,
private processes: ProcessesService,
private toastService: ToastService,
public ThemeService: ThemeService,
public httpErrorHandler: HttpErrorHandle,
private agendaDataRepository: AgendaDataRepositoryService,
private httpErroHalde: HttpErrorHandle,
) {
this.isEventEdited = false;
}
ngOnInit() {
console.log('here!!!')
if (this.restoreTemporaryData()) {
this.setOtherData()
} else {
this.getTask();
}
this.getRecurrenceTypes();
}
@XTracerAsync({name:'edit-event-approve/getTask', bugPrint: true})
async getTask(tracing?: TracingType) {
const res = await this.agendaDataRepository.getEventToApproveById(this.serialNumber)
if(res.isOk()) {
console.log('evento to apro to edit', res.value)
this.eventProcess = res.value as any;
this.eventProcess.workflowInstanceDataFields.LastOccurrence = new Date(this.eventProcess.workflowInstanceDataFields.LastOccurrence)
this.restoreDatepickerData()
// description
try {
let body: any = this.eventProcess.workflowInstanceDataFields?.Body?.replace(/<[^>]+>/g, '')
this.eventProcess.workflowInstanceDataFields.Body = body
} catch (error) {}
this.eventProcess.workflowInstanceDataFields.Category = this.setEventType(this.eventProcess.workflowInstanceDataFields.EventType)
this.InstanceId = this.eventProcess.workflowInstanceDataFields.InstanceId
this.loadedAttachments = res.value.Attachments;
console.log(this.loadedAttachments)
this.setOtherData()
this.saveTemporaryData()
tracing.setAttribute('outcome', 'success')
} else {
tracing.setAttribute('outcome', 'failed')
this.httpErroHalde.httpStatusHandle(res.error)
}
}
getRecurrenceTypes() {
this.eventsService.getRecurrenceTypes().subscribe(res => {
this.recurringTypes = res;
});
}
calculetedLastOccurrence(type: number) {
var valor;
var opcao: boolean;
if (type == 0) {
valor = 7;
opcao = true;
} else if (type == 1) {
valor = 30;
opcao = true;
} else if (type == 2) {
valor = 1;
opcao = false;
} else if (type == 3) {
valor = 5;
opcao = false;
}
this.defineLastOccurrence(valor, opcao);
}
onDateChange(e) {
const cloneDateStartDate = new Date(this.eventProcess.workflowInstanceDataFields.StartDate);
const cloneDateEndDate = new Date(this.eventProcess.workflowInstanceDataFields.EndDate);
if(cloneDateStartDate.getTime() >= cloneDateEndDate.getTime()) {
cloneDateStartDate.setHours(cloneDateStartDate.getHours() + 1);
this.eventProcess.workflowInstanceDataFields.EndDate = cloneDateStartDate as any
}
}
defineLastOccurrence(valor: number, opcao: boolean) {
var time = new Date(this.eventProcess.workflowInstanceDataFields.EndDate);
if (opcao == true) {
time.setDate(time.getDate() + valor);
this.eventProcess.workflowInstanceDataFields.LastOccurrence = time;
} else {
time = new Date(
time.getFullYear() + valor,
time.getMonth(),
time.getDate(),
time.getHours(),
time.getMinutes()
);
this.eventProcess.workflowInstanceDataFields.LastOccurrence = time;
}
}
setOtherData() {
if (this.eventProcess.workflowInstanceDataFields.ParticipantsList) {
this.eventProcess.workflowInstanceDataFields.ParticipantsList.forEach(e => {
console.log('intervenientes ', e)
if (e.IsRequired) {
this.taskParticipants.push(e);
} else {
this.taskParticipantsCc.push(e);
}
})
}
this.taskParticipants = removeDuplicate(this.taskParticipants)
this.taskParticipantsCc = removeDuplicate(this.taskParticipantsCc)
if (this.eventProcess.workflowInstanceDataFields.IsRecurring == false) {
this.isRecurring = "Não se repete";
}
else {
this.isRecurring = "Repete";
}
this.InstanceId = this.eventProcess.workflowInstanceDataFields.InstanceId
/* this.getAttachments() */
}
close() {
window['temp.path:/shared/agenda/edit-event-to-approve.ts'] = {};
this.closeEventToApprove.emit();
this.setIntervenient.emit([]);
this.setIntervenientCC.emit([]);
this.clearContact.emit();
this.approveEventDismiss.emit({
serialNumber: this.eventProcess.serialNumber,
action: "Aprovar",
saveData: this.eventProcess
});
}
runValidation() {
this.validateFrom = true
}
injectValidation() {
this.Form = new FormGroup({
Subject: new FormControl(this.eventProcess.workflowInstanceDataFields.Subject, [
Validators.required,
// Validators.minLength(4)
]),
Location: new FormControl(this.eventProcess.workflowInstanceDataFields.Location, [
Validators.required,
]),
//CalendarName: new FormControl(this.postEvent.CalendarName),
// Categories: new FormControl(this.postEvent.Categories, [
// Validators.required
// ]),
dateStart: new FormControl(this.dateStart, [
Validators.required
]),
dateEnd: new FormControl(this.dateEnd, [
Validators.required
]),
// IsRecurring: new FormControl(this.postEvent.IsRecurring, [
// Validators.required
// ]),
participantes: new FormControl(this.taskParticipants, [
// Validators.required
]),
})
}
@XTracerAsync({name:'desktop/edit-event', bugPrint: true, daley: 4000})
async save(tracing?: TracingType) {
this.injectValidation()
this.runValidation()
if (this.Form.invalid) return false
const serverCurrentList = this.eventProcess.workflowInstanceDataFields.ParticipantsList
this.dateControlStart = new FormControl(moment(new Date(this.eventProcess.workflowInstanceDataFields.StartDate)).add(1, 'hours'));
this.dateControlEnd = new FormControl(moment(new Date(this.eventProcess.workflowInstanceDataFields.EndDate)).add(1, 'hours'));
this.taskParticipantsCc.forEach(e => {
e.IsRequired = false
})
this.eventProcess.workflowInstanceDataFields.Subject = /* this.domSanitizeService.sanitizeInput( */this.eventProcess.workflowInstanceDataFields.Subject/* ) */;
this.eventProcess.workflowInstanceDataFields.Location = /* this.domSanitizeService.sanitizeInput( */this.eventProcess.workflowInstanceDataFields.Location/* ) */;
this.eventProcess.workflowInstanceDataFields.Body = /* this.domSanitizeService.sanitizeInput( */this.eventProcess.workflowInstanceDataFields.Body/* ) */;
this.eventProcess.workflowInstanceDataFields.ParticipantsList = this.taskParticipants.concat(this.taskParticipantsCc)
this.eventProcess.workflowInstanceDataFields.ParticipantsList.forEach(e => {
if (e.hasOwnProperty('$type')) {
delete e.$type
}
})
const event: EventToApproveEdit = {
SerialNumber: this.eventProcess.serialNumber,
Body: this.eventProcess.workflowInstanceDataFields.Body,
Location: this.eventProcess.workflowInstanceDataFields.Location,
Subject: this.eventProcess.workflowInstanceDataFields.Subject,
StartDate: this.dateControlStart.value,
EndDate: this.dateControlEnd.value,
ReviewUserComment: '',
Agenda: this.eventProcess.workflowInstanceDataFields.Agenda,
MDName: this.eventProcess.workflowInstanceDataFields.MDName,
MDEmail: this.eventProcess.workflowInstanceDataFields.MDEmail,
IsAllDayEvent: this.eventProcess.workflowInstanceDataFields.IsAllDayEvent,
Status: this.eventProcess.workflowInstanceDataFields.Status,
EventType: this.eventProcess.workflowInstanceDataFields.EventType,
IsRecurring: this.eventProcess.workflowInstanceDataFields.IsRecurring,
Message: this.eventProcess.workflowInstanceDataFields.Message,
EventRecurrence: {
Type: this.eventProcess.workflowInstanceDataFields.OccurrenceType || '-1',
LastOccurrence: this.eventProcess.workflowInstanceDataFields.LastOccurrence,
},
ParticipantsList: this.eventProcess.workflowInstanceDataFields.ParticipantsList,
Category: this.eventProcess.workflowInstanceDataFields.Category
}
try {
const calendar = await this.agendaDataRepository.getCalendarByUserId((this.eventProcess as any).owner.wxUserId)
if(calendar.isOk()) {
const value = await this.agendaDataRepository.updateEvent(this.eventProcess.serialNumber, event, true, calendar.value, tracing)
if(value.isOk()) {
console.log(value)
tracing.setAttribute('outcome', 'success')
} else {
console.log('edit event error: ', value.error)
tracing.setAttribute('outcome', 'failed')
}
console.log({serverCurrentList, list: this.eventProcess.workflowInstanceDataFields.ParticipantsList, e: this.eventProcess})
const { insert, remove } = AttendeesLIstChangeDetector(serverCurrentList as any, this.eventProcess.workflowInstanceDataFields.ParticipantsList as any)
console.log({insert, remove})
if(insert.length >= 1) {
try {
await this.agendaDataRepository.addEventAttendee(this.eventProcess.serialNumber, insert, tracing).toPromise()
} catch (error) {
console.log('add Attendee error: ', error)
tracing.setAttribute('failed.attendees', 'true')
}
// this.agendaDataRepository.addEventAttendee(this.eventProcess.serialNumber, insert, tracing).subscribe((value) => {
// console.log(value)
// }, ((error) => {
// console.log('add Attendee error: ', error)
// tracing.setAttribute('failed.attendees', 'true')
// }));
}
if(remove.length >= 1) {
try {
await this.agendaDataRepository.removeEventAttendee(this.eventProcess.serialNumber, remove).toPromise()
} catch (error) {
console.log('add Attendee error: ', error)
tracing.setAttribute('failed.attendees', 'true')
}
// this.agendaDataRepository.removeEventAttendee(this.eventProcess.serialNumber, remove).subscribe((value) => {
// }, ((error) => {
// console.log('add Attendee error: ', error)
// tracing.setAttribute('failed.attendees', 'true')
// }));
}
if (this.addedAttachmentsList.length > 0) {
try {
await this.agendaDataRepository.addEventAttachment(this.eventProcess.serialNumber, this.loadedAttachments, tracing).toPromise();
} catch (error) {
this.showLoader = false
console.log('add attachment error: ', error)
tracing.setAttribute('failed.add.attachment', 'true')
}
// this.agendaDataRepository.addEventAttachment(this.eventProcess.serialNumber, this.loadedAttachments, tracing).subscribe((value) => {
// console.log(value)
// }, ((error) => {
// this.showLoader = false
// console.log('add attachment error: ', error)
// tracing.setAttribute('failed.add.attachment', 'true')
// }));
}
if (this.deletedAttachmentsList.length > 0) {
try {
await this.agendaDataRepository.removeEventAttachment(this.eventProcess.serialNumber, { attachments: this.deletedAttachmentsList }).toPromise()
} catch (error) {
this.showLoader = false
console.log('remove attachment error: ', error)
tracing.setAttribute('failed.remove.attachment', 'true')
}
// this.agendaDataRepository.removeEventAttachment(this.eventProcess.serialNumber, { attachments: this.deletedAttachmentsList }).subscribe((value) => {
// console.log(value)
// }, ((error) => {
// this.showLoader = false
// console.log('remove attachment error: ', error)
// tracing.setAttribute('failed.remove.attachment', 'true')
// }));
}
this.close()
this.httpErrorHandler.httpsSucessMessagge('Editar evento');
}
} catch (e) {
this.httpErrorHandler.httpStatusHandle(e);
this.toastService._badRequest('Evento não editado');
}
// this.loadedAttachments.forEach((document: any) => {
// if (document['action'] == 'add') {
// delete document.action
// this.attachmentsService.setEventAttachmentById(document).subscribe(() => {
// window['edit-approve-event-desktop']()
// }, error => {
// this.toastService.badRequest();
// });
// } else if (document['action'] == 'delete') {
// delete document.action
// this.attachmentsService.deleteEventAttachmentById(document.Id).subscribe(res => {
// window['edit-approve-event-desktop']()
// }, error => {
// this.toastService.badRequest()
// })
// }
// })
}
documentAdded(documents: any[]) {
console.log('document added', documents)
return documents.map((element) => {
return {
docId: parseInt(element.SourceId),
sourceName: element.SourceName,
description: "",
applicationId: parseInt(element.ApplicationId)
};
});
}
atendeesSeletedType(type) {
var selectedType = {
'true': 1,
'false': 2,
'other': 3,
}
return selectedType[type];
}
attendeesAdded(taskParticipants: any[]) {
return taskParticipants.map((e) => {
return {
name: e.Name,
emailAddress: e.EmailAddress,
attendeeType: this.atendeesSeletedType(JSON.stringify(e.IsRequired)),
wxUserId: e.wxUserId,
}
});
}
async gravasAction() {
await this.save();
this.reenviar();
}
async reenviar() {
let body = {
serialNumber: this.eventProcess.serialNumber,
action: "Reenviar",
dataFields: {
ReviewUserComment: "",
}
}
const loader = this.toastService.loading();
try {
await this.processes.PostTaskAction(body).toPromise();
this.toastService._successMessage();
this.goToApproveEventList();
} catch (error) {
if (error.status == 0) {
this.toastService._badRequest('Sem acesso à internet. Por favor verifique sua conexão')
} else {
this.toastService._badRequest();
}
} finally {
loader.remove()
}
}
goToApproveEventList() {
this.closeEventToApprove.emit();
this.modalController.dismiss();
}
dynamicSetIntervenient({ taskParticipants, taskParticipantsCc }) {
this.taskParticipants = removeDuplicate(taskParticipants);
this.taskParticipantsCc = removeDuplicate(taskParticipantsCc);
}
onCheckboxChange(event: any) {
if (this.eventProcess.workflowInstanceDataFields.IsAllDayEvent) {
this.eventProcess.workflowInstanceDataFields.StartDate = this.setAlldayTime(this.eventProcess.workflowInstanceDataFields.StartDate)
this.eventProcess.workflowInstanceDataFields.EndDate = this.setAlldayTimeEndDate(this.eventProcess.workflowInstanceDataFields.EndDate)
console.log('Recurso ativado!!');
} else {
this.eventProcess.workflowInstanceDataFields.IsAllDayEvent = this.eventProcess.workflowInstanceDataFields.IsAllDayEvent;
this.eventProcess.workflowInstanceDataFields.EndDate = this.setAlldayTimeEndDateNotAlday(this.eventProcess.workflowInstanceDataFields.EndDate)
console.log('Recurso desativado');
}
}
setAlldayTime(timeToReturn) {
let date: any = new Date(timeToReturn) || new Date();
let newdate = new Date();
date.setHours(0)
date.setMinutes(0)
date.setSeconds(0);
return date
}
setAlldayTimeEndDate(timeToReturn) {
let date: any = new Date(timeToReturn) || new Date();
let newdate = new Date();
date.setHours(23)
date.setMinutes(59)
date.setSeconds(0);
return date
}
setAlldayTimeEndDateNotAlday(timeToReturn) {
let date: any = new Date(timeToReturn) || new Date();
let newdate = new Date();
date.setHours(23)
date.setMinutes(0)
date.setSeconds(0);
return date
}
async addParticipants() {
//this.saveTemporaryData();
this.openAttendeesComponent.emit({
type: "intervenient"
});
this.clearContact.emit();
}
async addParticipantsCC() {
this.openAttendeesComponent.emit({
type: "CC"
});
this.clearContact.emit();
}
saveTemporaryData() {
this.getDatepickerData()
window['temp.path:/shared/agenda/edit-event-to-approve.ts'] = {
eventProcess: this.eventProcess,
attachment: this.loadedAttachments
}
}
restoreTemporaryData(): boolean {
const restoredData = window['temp.path:/shared/agenda/edit-event-to-approve.ts']
if (JSON.stringify(restoredData) != "{}" && undefined != restoredData) {
this.eventProcess = restoredData.eventProcess,
this.loadedAttachments = restoredData.attachment
// restore dater for date and hours picker
this.restoreDatepickerData()
return true;
} else {
return false;
}
}
async getAttachments() {
let result: any;
try {
result = await this.attachmentsService.getAttachmentsById(this.InstanceId).toPromise();
} catch (error) {
console.error('getAttachment', error)
}
result.forEach((e) => {
e.action = false
})
this.loadedAttachments = result
//
}
deleteAttachment(attachment: Attachment, index) {
const id: any = this.loadedAttachments[index].id
console.log(this.loadedAttachments)
let update = this.removeItemById(this.loadedAttachments, id)
this.loadedAttachments = update;
this.deletedAttachmentsList.push(id)
}
removeItemById(array, id) {
return array.filter(item => item.id !== id);
}
async getDoc() {
const modal = await this.modalController.create({
component: SearchPage,
cssClass: 'modal-width-100-width-background modal',
componentProps: {
type: 'AccoesPresidenciais & ArquivoDespachoElect',
showSearchInput: true,
eventAgenda: true,
select: true,
}
});
await modal.present();
modal.onDidDismiss().then(async (res) => {
if (res) {
const data: SearchList = res.data.selected;
console.log(data)
/* const DocumentToSave: any = {
SourceTitle: data.Assunto,
ParentId: this.InstanceId,
Source: '1',
SourceId: data.Id,
ApplicationId: data.ApplicationType.toString(),
Id: '',
Link: '',
SerialNumber: '',
action: 'add',
CreateDate: data.Data,
Data: data.Data,
Description: data.DocTypeDesc,
SourceName: data.Assunto,
Stakeholders: data.EntidadeOrganicaNome,
}; */
this.loadedAttachments.push(data)
this.addedAttachmentsList.push(data)
// await this.attachmentsService.setEventAttachmentById(DocumentToSave).subscribe(()=>{
// this.getAttachments();
// });
}
});
}
restoreDatepickerData() {
this.dateControlStart = new FormControl(moment(new Date(this.eventProcess.workflowInstanceDataFields.StartDate)));
this.dateControlEnd = new FormControl(moment(new Date(this.eventProcess.workflowInstanceDataFields.EndDate)));
}
getDatepickerData() {
this.eventProcess.workflowInstanceDataFields.StartDate = this.dateStart
this.eventProcess.workflowInstanceDataFields.EndDate = this.dateEnd
}
setEventType(eventType) {
var selectedEventType = {
1: 'Meeting',
2: 'Travel',
3: 'Conference',
4: 'Encontro'
}
return selectedEventType[eventType];
}
}
@@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { EditEventPage } from './edit-event.page';
const routes: Routes = [
{
path: '',
component: EditEventPage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class EditEventPageRoutingModule {}
@@ -0,0 +1,49 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { EditEventPageRoutingModule } from './edit-event-routing.module';
import { EditEventPage } from './edit-event.page';
import { MatNativeDateModule } from '@angular/material/core';
import {
NgxMatDatetimePickerModule,
NgxMatNativeDateModule,
NgxMatTimepickerModule
} from '@angular-material-components/datetime-picker';
import { ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatSelectModule } from '@angular/material/select';
import { NgxMatMomentModule } from '@angular-material-components/moment-adapter';
import { MAT_DATE_LOCALE } from '@angular/material/core';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatInputModule } from '@angular/material/input';
import { MatDialogModule } from '@angular/material/dialog';
import { MatMenuModule } from '@angular/material/menu';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
EditEventPageRoutingModule,
// Angular material
MatDatepickerModule,
MatInputModule,
MatNativeDateModule,
NgxMatDatetimePickerModule,
NgxMatTimepickerModule,
NgxMatNativeDateModule,
NgxMatMomentModule,
MatSelectModule,
MatButtonModule,
ReactiveFormsModule,
MatDialogModule,
],
providers: [
{ provide: MAT_DATE_LOCALE, useValue: 'pt' },
],
declarations: [EditEventPage],
exports: [EditEventPage]
})
export class EditEventPageModule {}
@@ -0,0 +1,448 @@
<ion-header class="ion-no-border">
<ion-toolbar class="header-toolbar">
<div class="main-header">
<div class="title-content">
<div class="middle">
<ion-label id="edit-event-desktop" class="title">Editar Evento</ion-label> <br>
<i style="margin-top: -3px; font-size: 15px;"> Campos marcados com * são obrigatórios</i>
</div>
</div>
<ion-progress-bar class="calendar-progress-bar" type="indeterminate" *ngIf="showLoader"></ion-progress-bar>
</div>
</ion-toolbar>
</ion-header>
<ion-content>
<div class="main-content">
<div class="ion-item-container" [class.input-error]="Form?.get('Subject')?.invalid && validateFrom ">
<ion-input autocomplete="on" autocorrect="on" spellcheck="true" placeholder="Assunto*"
[(ngModel)]="_postEvent.Subject"></ion-input>
</div>
<div *ngIf="Form && validateFrom">
<div *ngIf="Form.get('Subject').invalid " class="input-errror-message">
<div *ngIf="Form.get('Subject').errors?.required">
</div>
<div *ngIf="Form.get('Subject').errors?.minlength">
O campo deve ter pelo menos 4 caracteres.
</div>
</div>
</div>
<div class="container-div">
<div class="ion-item-class-2 width-100 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-location.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1" [class.input-error]="Form?.get('Location')?.invalid && validateFrom ">
<ion-input autocomplete="on" autocorrect="on" spellcheck="true" placeholder="Localização*"
[(ngModel)]="_postEvent.Location"></ion-input>
</div>
</div>
<!-- Error messages -->
<!-- <span class="error ion-padding" >
Campo obrigatório
</span> -->
</div>
<div *ngIf="(sharedCalendar | async) as calendarData" class="container-div" >
<div class="ion-item-class-2 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1 justify-center align-center material-inputs " [class.input-error]="Form?.get('CalendarName')?.invalid && validateFrom ">
<mat-form-field appearance="none" class="width-100" color="ion-color-secondary" placeholder="Selecione agenda">
<div *ngIf="selectedUserCalendar == SessionStore.user.UserId && !hasChangeCalendar && SessionStore.user.Profile != 'PR' " style="margin-bottom: -20px;">
Minha agenda
</div>
<div *ngIf="!(selectedUserCalendar == SessionStore.user.UserId && SessionStore.user.Profile != 'PR' ) && !hasChangeCalendar" style="margin-bottom: -20px;">
PR
</div>
<mat-select [(value)]="selectedUserCalendar" (selectionChange)="changeAgenda();changeSegmentCalendar()">
<mat-option *ngFor="let calendars of calendarData" value="{{calendars.wxUserId}}">
<div *ngIf="calendars.roleId == RoleIdService.PRES">PR </div>
<div *ngIf="calendars.roleId == RoleIdService.MD && calendars.roleId != SessionStore.user.RoleID">AGENDA DO MDGPR</div>
<div *ngIf="calendars.roleId != RoleIdService.MD && calendars.roleId != RoleIdService.PRES && calendars.wxFullName && calendars.wxUserId != SessionStore.user.UserId"> Agenda do {{calendars.wxFullName}} </div>
<div *ngIf="calendars.wxUserId == SessionStore.user.UserId && SessionStore.user.Profile != 'PR'">
Minha agenda
</div>
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="Form && validateFrom">
<div *ngIf="Form.get('Location').invalid " class="input-errror-message">
<div *ngIf="Form.get('Location').errors?.required">
</div>
<div *ngIf="Form.get('Location').errors?.minlength">
O campo deve ter pelo menos 4 caracteres.
</div>
</div>
</div>
<div class="container-div">
<div class="ion-item-class-2 width-100 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1">
<mat-form-field appearance="none" floatLabel="never" class="width-100 ">
<mat-select placeholder="Selecione agenda*" [(ngModel)]="_postEvent.CalendarName" [disabled]=false>
<mat-option *ngFor="let calendars of CalendarNamesOptions" value="{{calendars}}">
Agenda {{ calendars }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
<div class="container-div">
<div class="ion-item-class-2 width-100 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1"
[class.input-error]="Form?.get('Categories')?.invalid && validateFrom ">
<mat-form-field appearance="none" floatLabel="never" class="width-100" required>
<!-- <input matInput type="text" > -->
<mat-select placeholder="Selecione o tipo de evento*" matInput [(ngModel)]="_postEvent.Category">
<mat-option value="Meeting">
Reunião
</mat-option>
<mat-option value="Travel">
Viagem
</mat-option>
<mat-option value="Conference">
Conferência
</mat-option>
<mat-option value="Encontro">
Encontro
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
<div class="container-div">
<div>
<ion-item>
<ion-label>Todo dia</ion-label>
<ion-checkbox [(ngModel)]="allDayCheck" (ionChange)="onCheckboxChange($event)"></ion-checkbox>
</ion-item>
</div>
</div>
<div class="container-div">
<div class="ion-item-class-2 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-reapet.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1 justify-center align-center material-inputs">
<mat-form-field appearance="none" class="width-100" placeholder="Sample Type" required>
<!-- <input matInput type="text" > -->
<mat-select [(value)]="_postEvent.EventRecurrence.frequency" >
<mat-option value="never">
Nunca
</mat-option>
<mat-option value="daily">
Diário
</mat-option>
<mat-option value="weekly">
Semanalmente
</mat-option>
<mat-option value="monthly">
Mensal
</mat-option>
<mat-option value="yearly">
Anual
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
<!-- <div *ngIf="_postEvent.EventRecurrence.frequency == 'weekly'" class="container-div ion-item-class-2 d-flex pl-45 pb-20 justify-content-between">
<div class="days-to-select">Seg</div>
<div class="days-to-select">Ter</div>
<div class="days-to-select">Qua</div>
<div class="days-to-select">Qui</div>
<div class="days-to-select">Sex</div>
<div class="days-to-select">Sab</div>
<div class="days-to-select">Dom</div>
</div> -->
<div *ngIf="_postEvent.EventRecurrence.frequency != 'never'" class="container-div">
<div class="ion-item-class-2 d-flex" >
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-reapet.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1 justify-center align-center material-inputs materia-top" >
<mat-form-field appearance="none" class="date-hour-picker">
<input matInput [ngxMatDatetimePicker]="picker1"
placeholder="Data Fim de Recorrência*"
[(ngModel)]="postEvent.EventRecurrence.until"
[disabled]="disabled"
>
<mat-datepicker-toggle id="new-inicio" matSuffix [for]="picker1" ></mat-datepicker-toggle>
<ngx-mat-datetime-picker #picker1
[showSpinners]="showSpinners"
[showSeconds]="showSeconds"
[stepHour]="stepHour" [stepMinute]="stepMinute"
[stepSecond]="stepSecond"
[touchUi]="touchUi"
[hideTime]="true"
>
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="allDayCheck" class="container-div">
<div class="ion-item-class-2 width-100 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1" [class.input-error]="Form?.get('Date')?.invalid && validateFrom ">
<mat-form-field appearance="none" floatLabel="never" class="date-hour-picker">
<input matInput [ngxMatDatetimePicker]="picker1" placeholder="Choose a date"
[(ngModel)]="_postEvent.StartDate" [max]="maxDate" [disabled]="disabled"
(ngModelChange)="onDateChange($event)"
>
<mat-datepicker-toggle id="new-inicio" matSuffix [for]="picker1"></mat-datepicker-toggle>
<ngx-mat-datetime-picker #picker1 [showSpinners]="showSpinners" [showSeconds]="showSeconds"
[stepHour]="stepHour" [stepMinute]="stepMinute" [stepSecond]="stepSecond" [touchUi]="touchUi" [hideTime]="true">
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="!allDayCheck" class="container-div">
<div class="ion-item-class-2 width-100 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1" [class.input-error]="Form?.get('Date')?.invalid && validateFrom ">
<mat-form-field appearance="none" floatLabel="never" class="date-hour-picker">
<input matInput [ngxMatDatetimePicker]="picker1" placeholder="Choose a date"
[(ngModel)]="_postEvent.StartDate" [max]="maxDate" [disabled]="disabled" (ngModelChange)="onDateChange($event)">
<mat-datepicker-toggle id="new-inicio" matSuffix [for]="picker1"></mat-datepicker-toggle>
<ngx-mat-datetime-picker #picker1 [showSpinners]="showSpinners" [showSeconds]="showSeconds"
[stepHour]="stepHour" [stepMinute]="stepMinute" [stepSecond]="stepSecond" [touchUi]="touchUi" [hideTime]="false">
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="allDayCheck" class="container-div">
<div class="ion-item-class-2 width-100 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1" [class.input-error]="Form?.get('Date')?.invalid && validateFrom ">
<mat-form-field appearance="none" floatLabel="never" floatLabel="never" class="date-hour-picker">
<input matInput [ngxMatDatetimePicker]="fim" placeholder="Choose a date" [(ngModel)]="_postEvent.EndDate"
[max]="maxDate" [disabled]="disabled" [min]="_postEvent.StartDate" >
<mat-datepicker-toggle id="new-fim" matSuffix [for]="fim"></mat-datepicker-toggle>
<ngx-mat-datetime-picker #fim [showSpinners]="showSpinners" [showSeconds]="showSeconds"
[stepHour]="stepHour" [stepMinute]="stepMinute" [stepSecond]="stepSecond" [hideTime]="true">
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="!allDayCheck" class="container-div">
<div class="ion-item-class-2 width-100 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1" [class.input-error]="Form?.get('Date')?.invalid && validateFrom ">
<mat-form-field appearance="none" floatLabel="never" floatLabel="never" class="date-hour-picker">
<input matInput [ngxMatDatetimePicker]="fim" placeholder="Choose a date" [(ngModel)]="_postEvent.EndDate"
[max]="maxDate" [disabled]="disabled" [min]="_postEvent.StartDate">
<mat-datepicker-toggle id="new-fim" matSuffix [for]="fim"></mat-datepicker-toggle>
<ngx-mat-datetime-picker #fim [showSpinners]="showSpinners" [showSeconds]="showSeconds"
[stepHour]="stepHour" [stepMinute]="stepMinute" [stepSecond]="stepSecond" [hideTime]="false">
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="_postEvent.EventRecurrence.Type != '-1'" class="container-div width-100">
<div class="ion-item-class-2 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div (click)="openLastOccurrence()" class="ion-input-class flex-grow-1">
<mat-form-field class="date-hour-picker">
<input matInput [ngxMatDatetimePicker]="occurrrence" placeholder="Choose a date"
[(ngModel)]="_postEvent.EventRecurrence.LastOccurrence" [disabled]="disabled" [min]="_postEvent.EndDate">
<mat-datepicker-toggle id="last-occurrence" matSuffix [for]="occurrrence"></mat-datepicker-toggle>
<ngx-mat-datetime-picker #occurrrence [showSpinners]="showSpinners" [showSeconds]="showSeconds"
[stepHour]="stepHour" [stepMinute]="stepMinute" [stepSecond]="stepSecond" [touchUi]="touchUi">
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
</div>
</div>
<div class=" d-flex width-100">
<div class="ion-item-class-2 width-100">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-person.svg"></ion-icon>
</div>
<div class="ion-input-class-no-height"
[class.input-error]="Form?.get('participantes')?.invalid && validateFrom">
<div class="list-people">
<ion-item lines="none">
<ion-list>
<div *ngIf="taskParticipants?.length < 1" class="list-people-title">Adicionar Intervenientes*</div>
<div *ngFor="let participant of taskParticipants">{{participant.Name}}</div>
</ion-list>
</ion-item>
</div>
<div class="add-people">
<button class="btn-no-color cursor-pointer" (click)="addParticipants()">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="font-35-rem" slot="start"
src="assets/images/icons-arrow-forward.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="font-35-rem" slot="start"
src="assets/images/theme/gov/icons-arrow-forward.svg"></ion-icon>
</button>
</div>
</div>
</div>
</div>
<div class=" d-flex width-100">
<div class="ion-item-class-2 width-100">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-people-cc.svg"></ion-icon>
</div>
<div class="ion-input-class-no-height"
[class.input-error]="Form?.get('participantes')?.invalid && validateFrom">
<div class="list-people">
<ion-item lines="none">
<ion-list>
<ion-label *ngIf="taskParticipantsCc?.length < 1" class="list-people-title">Com conhecimento</ion-label>
<ion-label *ngFor="let participant of taskParticipantsCc">{{participant.Name}}</ion-label>
</ion-list>
</ion-item>
</div>
<div class="add-people">
<button class="btn-no-color cursor-pointer" (click)="addParticipantsCc()">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="font-35-rem" slot="start"
src="assets/images/icons-arrow-forward.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="font-35-rem" slot="start"
src="assets/images/theme/gov/icons-arrow-forward.svg"></ion-icon>
</button>
</div>
</div>
</div>
</div>
<div class="container-div">
<div class="ion-item-class-2 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-description.svg"></ion-icon>
</div>
<div class="ion-input-class-no-height width-100">
<ion-textarea autocomplete="on" autocorrect="on" spellcheck="true" [(ngModel)]="_postEvent.Body.Text"
placeholder="Detalhes" rows="6" cols="20"></ion-textarea>
</div>
</div>
</div>
<div (click)="getDoc()" class="d-flex container-div width-100 ion-item-container-no-border cursor-pointer">
<ion-label>
<div class="attach-icon">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/images/icons-attach-doc.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' "
src="assets/images/theme/gov/icons-attach-doc.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' "
src="assets/images/theme/{{ThemeService.currentTheme}}/icons-attach-doc.svg"></ion-icon>
</div>
<div class="attach-document">
<ion-label>Adicionar documentos</ion-label>
</div>
</ion-label>
</div>
<div class="d-flex container-div width-100" *ngFor="let document of loadedEventAttachments; let i = index">
<ion-list class="width-100 list" *ngIf="!document.remove">
<ion-item class="width-100">
<ion-label class="width-100">
<p class="d-flex ion-justify-content-between">
<span class="attach-title-item">{{document.subject || document.sourceName || document.SourceName || 'Sem título'}}</span>
<span class="app-name" *ngIf="document.applicationId == 8 || document.ApplicationId == 8"> Correspondencia </span>
<span class="app-name" *ngIf="document.applicationId == 386 || document.ApplicationId == 386"> AccoesPresidenciais </span>
<span class="app-name" *ngIf="document.applicationId == 361 || document.ApplicationId == 361 "> ArquivoDespachoElect </span>
<span class="close-button text-black cursor-pointer" (click)="deleteAttachment(document.Id, i)">
<ion-icon class="font-20" src="assets/images/icons-delete-25.svg"></ion-icon>
</span>
</p>
<p><span class="span-left">{{document.Stakeholders}}</span><span class="span-right"> {{ document.dateEntry }} </span></p>
</ion-label>
</ion-item>
</ion-list>
</div>
</div>
</ion-content>
<ion-footer class="ion-no-border">
<ion-toolbar class="width-100 d-flex justify-space-between px-20">
<ion-buttons slot="start">
<button class="btn-ok" fill="clear" color="#fff" (click)="save_v2()">
<ion-label>Gravar</ion-label>
</button>
</ion-buttons>
<ion-title></ion-title>
<ion-buttons slot="end">
<button class="btn-cancel" fill="clear" color="#061b52" (click)="close()">
<ion-label>Cancelar</ion-label>
</button>
</ion-buttons>
</ion-toolbar>
</ion-footer>
@@ -0,0 +1,233 @@
@import '~src/function.scss';
ion-content{
--background:transparent;
}
.header-toolbar{
--background:transparent;
--opacity: 1;
}
.main-header{
width: 100%; /* 400px */
height: 100%;
font-family: Roboto;
border-top-left-radius: 25px;
border-top-right-radius: 25px;
background-color: #fff;
overflow:hidden;
padding: 30px 20px 0px 20px;
color:#000;
transform: translate3d(0, 1px, 0);
.title-content{
margin: 0px auto;
padding: 0 !important;
background: #fff;
.middle{
padding: 0!important;
float: left;
margin: 2.5px 0 0 5px;
}
}
.title{
font-size: rem(25);
}
}
.main-content{
width: 100%; /* 400px */
height: 100%;
font-family: Roboto;
margin: 0 auto;
background-color: #fff;
padding: 15px 20px 0 20px;
.ion-item-container{
margin: rem(15) auto;
border: 1px solid #ebebeb;
border-radius: 5px;
padding-left: 10px;
}
.ion-item-container-no-border{
width: 100%;
margin: 0px auto;
padding: 0 !important;
}
.container-div{
margin-bottom: 15px;
}
.ion-item-class-2{
margin: 0px auto;
}
.ion-icon-class{
width: rem(45);
height: rem(45);
float: left;
padding: 10px;
font-size: rem(25);
}
ion-select{
padding-left: 5px;
margin-left: 0;
}
.ion-input-class{
height: rem(45);
border: 1px solid #ebebeb;
border-radius: 5px;
padding-left: 5px;
padding-right: 10px;
float: left;
}
.ion-input-class-no-height{
height: auto !important;
border: 1px solid #ebebeb;
border-radius: 5px;
margin-bottom: 15px;
overflow: auto;
}
.list-people{
float: left;
}
.add-people{
width: rem(45);
float: right;
font-size: rem(25);
height: rem(45);
display: flex;
}
.list-people-title{
/* font-size: rem(13); */
color: #a3a3a3;
}
.attach-document{
font-size: rem(15);
color: var(--title-text-color);
margin: 5px 5px 5px 10px;
padding: 5px;
float: left;
}
.attach-icon{
width: 37px;
font-size: rem(35);
float: left;
}
.attach-title-item{
width: 100%;
font-size: rem(15);
color: var(--title-text-color);
}
/* SPAN */
.span-left{
float: left;
font-size: rem(15);
}
.span-right{
text-align: right;
float: right;
font-size: rem(13);
}
.container-footer{
margin:0 auto;
}
.button-cancel {
width: 170px;
height: rem(44);
border-radius: 22.5px;
--background: #e0e9ee;
--color: #061b52;
margin:10px;
}
.button-save {
width: 170px;
height: rem(44);
border-radius: 22.5px;
--background: #42b9fe;
--color:#ffffff;
margin:10px;
}
.text-input{
width: 100%;
border: 1px solid #ebebeb;
margin: 0px 15px 15px 0px;
padding: 0 !important;
border-radius: 5px;
}
/* Error Messages */
.error{
color:red;
font-size: rem(12);
font-weight: bold;
padding-bottom: 20px;
}
.span-color{
color:red;
}
}
.app-name{
background: var(--title-text-color);
border-radius: 18px;
text-align: center;
display: flex;
align-items: center;
padding: 0px 5px;
color: white;
font-size: rem(12);
font-weight: 500;
height: 19px;
-webkit-border-radius: 18px;
-moz-border-radius: 18px;
-ms-border-radius: 18px;
-o-border-radius: 18px;
}
.close-button {
display: none;
height: 20px;
}
.list:hover {
.app-name {
display: none;
}
.close-button {
display: block !important;
height: 20px;
}
}
.materia-top {
padding-top: 7px;
}
.days-to-select{
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
background: #ebebeb;
border-radius: 50px;
box-shadow: 0px 0px 10px #f9f9f9;
border: 1px solid #d1d1d1;
cursor: pointer;
user-select: none;
-webkit-border-radius: 50px;
-moz-border-radius: 50px;
-ms-border-radius: 50px;
-o-border-radius: 50px;
}
@@ -0,0 +1,24 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { EditEventPage } from './edit-event.page';
describe('EditEventPage', () => {
let component: EditEventPage;
let fixture: ComponentFixture<EditEventPage>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ EditEventPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(EditEventPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,715 @@
import { Component, OnInit, Input, Output, EventEmitter, ViewChild } from '@angular/core';
import { ModalController } from '@ionic/angular';
import { EventBody } from 'src/app/models/eventbody.model';
import { EventPerson } from 'src/app/models/eventperson.model';
import { Event } from 'src/app/models/event.model';
import { AlertController } from '@ionic/angular';
import { removeDuplicate } from 'src/plugin/removeDuplicate.js'
import { SearchPage } from 'src/app/pages/search/search.page';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { ParticipantsPipe } from 'src/app/pipes/participants.pipe';
import { ThemeService } from 'src/app/services/theme.service'
import { SessionStore } from 'src/app/store/session.service';
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service';
import { AgendaDataRepositoryService } from 'src/app/module/agenda/data/repository/agenda-data-repository.service';
import { SearchList_v2 } from 'src/app/models/search-document';
import { Utils } from 'src/app/module/agenda/utils';
import { Observable } from 'rxjs';
import { TableSharedCalendar } from 'src/app/module/agenda/data/data-source/agenda-local-data-source.service';
import { RoleIdService } from 'src/app/services/role-id.service'
import { XTracerAsync, TracingType } from 'src/app/services/monitoring/opentelemetry/tracer';
import { AttendeesLIstChangeDetector } from 'src/app/module/agenda/data/async/change/attendeesLIstChangeDetector';
import { EventRecurrenceComponentReturn, EventRecurrencePage } from 'src/app/modals/event-recurrence/event-recurrence.page';
@Component({
selector: 'app-edit-event',
templateUrl: './edit-event.page.html',
styleUrls: ['./edit-event.page.scss'],
})
export class EditEventPage implements OnInit {
stEvent: Event;
isRecurring: string;
isEventEdited: boolean;
loadedEvent: Event;
initCalendarName: string;
eventBody: EventBody;
segment: string = "true";
eventAttendees: EventPerson[];
// minDate: string;
loadedEventAttachments: any[] = [];
selectedRecurringType: any;
deletedAttachmentsList = [];
public date: any;
public disabled = false;
public showSpinners = true;
public showSeconds = false;
public touchUi = false;
public enableMeridian = false;
public minDate = new Date().toISOString().slice(0, 10)
public endMinDate = new Date(new Date().getTime() + 15 * 60000).toISOString().slice(0, 10)
public maxDate: any;
public stepHour = 1;
public stepMinute = 15;
public stepSecond = 15;
Form: FormGroup;
validateFrom = false
@Input() taskParticipants: EventPerson[];
@Input() taskParticipantsCc: EventPerson[];
@Input() profile: string;
@Input() selectedSegment: string;
@Input() postEvent: Event;
@Output() clearContact = new EventEmitter<any>();
@Output() openAttendeesComponent = new EventEmitter<any>();
@Output() closeComponent = new EventEmitter<any>();
@Output() setIntervenient = new EventEmitter<any>();
@Output() setIntervenientCC = new EventEmitter<any>();
@Output() clearPostEvent = new EventEmitter<any>();
showLoader = false
@ViewChild('picker') picker: any;
@ViewChild('fim') fim: any;
@ViewChild('inicio') inicio: any;
@ViewChild('picker1') picker1: any;
@Input() _postEvent: Event;
public options = [
{ value: true, label: 'True' },
{ value: false, label: 'False' }
];
public listColors = ['primary', 'accent', 'warn'];
public stepHours = [1, 2, 3, 4, 5];
public stepMinutes = [1, 5, 10, 15, 20, 25];
public stepSeconds = [1, 5, 10, 15, 20, 25];
private participantsPipe = new ParticipantsPipe()
SessionStore= SessionStore
allDayCheck: boolean = false;
addedAttachmentsList = [];
sharedCalendar: Observable<TableSharedCalendar[]>
hasChangeCalendar = false
selectedUserCalendar:any;
CalendarNamesOptions = ['Oficial', 'Pessoal']
dateDifference = 0
editAllEvent = false
constructor(
private modalController: ModalController,
public alertController: AlertController,
public ThemeService: ThemeService,
private httpErrorHandle: HttpErrorHandle,
private agendaDataRepository: AgendaDataRepositoryService,
private utils: Utils,
public RoleIdService: RoleIdService,
) {
this.sharedCalendar = this.agendaDataRepository.getShareCalendarItemsLiveWithOrder()
}
hasPrCalendar(data: TableSharedCalendar[]) {
for(const e of data) {
if(e.roleId == this.RoleIdService.PRES) {
return true
}
}
return false
}
changeSegmentCalendar() {
this.hasChangeCalendar = true
}
ngOnInit() {
this.selectedUserCalendar = this.postEvent.owner.wxUserId
this.loadedEventAttachments = this.postEvent.Attachments
this._postEvent = this.postEvent
this._postEvent.Category = this.setEventType(this._postEvent.Category)
if (!this._postEvent.IsRecurring) {
this._postEvent.EventRecurrence.frequency = 'never';
} else {
this._postEvent.EventRecurrence.frequency = this.utils.recurenceTypeSeleted(this.postEvent.EventRecurrence.frequency)
}
this.allDayCheck = this.postEvent.IsAllDayEvent;
if (!this.restoreTemporaryData()) {
this.validationEditAllEvent()
// clear
if (this._postEvent) {
if (this._postEvent.Body) {
if (typeof (this._postEvent.Body.Text) == 'string') {
this._postEvent.Body.Text = this._postEvent.Body.Text.replace(/<[^>]+>/g, '');
}
}
}
if (this._postEvent.Attendees != null) {
const result = this.participantsPipe.transform(this._postEvent.Attendees)
this.taskParticipants = result.taskParticipants
this.taskParticipantsCc = result.taskParticipantsCc
this.taskParticipants = removeDuplicate(this.taskParticipants);
this.taskParticipantsCc = removeDuplicate(this.taskParticipantsCc);
this.setIntervenient.emit(this.taskParticipants);
this.setIntervenientCC.emit(this.taskParticipantsCc);
}
}
this.initCalendarName = this._postEvent.CalendarName;
setTimeout(() => {
this._postEvent.EventRecurrence.Type = this._postEvent.EventRecurrence.Type.toString();
}, 500);
this.changeAgenda()
}
ngOnDestroy() {
clearInterval(this.myInterval)
}
myInterval = setInterval(() => {
document.querySelectorAll('.ngx-mat-timepicker input').forEach((e: any) => {
if (e) {
e.disabled = true;
}
})
}, 1000);
ngOnChanges(changes: any): void {
this.loadedEventAttachments = this._postEvent?.Attachments
}
close() {
this.closeComponent.emit();
this.setIntervenient.emit([]);
this.setIntervenientCC.emit([]);
this.clearContact.emit();
this.deleteTemporaryData();
}
runValidation() {
this.validateFrom = true
}
injectValidation() {
if (typeof (this._postEvent.EventRecurrence.Type) == 'number') {
const str: any = this._postEvent.EventRecurrence.Type.toString()
this._postEvent.EventRecurrence.Type = str
}
this.Form = new FormGroup({
Subject: new FormControl(this._postEvent.Subject, [
Validators.required,
// Validators.minLength(4)
]),
Location: new FormControl(this._postEvent.Location, [
Validators.required,
]),
CalendarName: new FormControl(this._postEvent.CalendarName),
Categories: new FormControl(this._postEvent.Category, [
Validators.required
]),
dateOccurrence: new FormControl(this._postEvent.EventRecurrence.Type.toString() == '-1' ? ['ok'] : this._postEvent.EventRecurrence.LastOccurrence && new Date(this._postEvent.EventRecurrence.LastOccurrence).getTime() > new Date(this._postEvent.EndDate).getTime() ? 'ok' : null, [
Validators.required
]),
participantes: new FormControl(this.taskParticipants, [
// Validators.required
]),
Date: new FormControl(true, [
Validators.required
]),
})
}
openInicio() {
let input: any = document.querySelector('#new-inicio')
if (input) {
input.click()
}
}
openFim() {
let input: any = document.querySelector('#new-fim')
if (input) {
input.click()
}
}
openLastOccurrence() {
let input: any = document.querySelector('#last-occurrence')
if (input) {
input.click()
}
}
roundTimeQuarterHour() {
let date = new Date();
const minutes = date.getMinutes();
date.setSeconds(0);
if (minutes % 15 != 0) {
if (minutes > 45) {
date.setMinutes(60)
} else if (minutes > 30) {
date.setMinutes(45)
} else if (minutes > 15) {
date.setMinutes(30)
} else if (minutes > 0) {
date.setMinutes(15)
}
}
return date
}
roundTimeQuarterHourPlus15(date: Date) {
const _date = new Date(date);
const minutes = _date.getMinutes();
_date.setMinutes(minutes + 15)
return _date
}
calculetedLastOccurrence(type: number) {
var valor;
var opcao: boolean;
if (type == 0) {
valor = 7;
opcao = true;
} else if (type == 1) {
valor = 30;
opcao = true;
} else if (type == 2) {
valor = 1;
opcao = false;
} else if (type == 3) {
valor = 5;
opcao = false;
}
this.defineLastOccurrence(valor, opcao);
}
defineLastOccurrence(valor: number, opcao: boolean) {
var time = new Date(this._postEvent.EndDate);
if (opcao == true) {
time.setDate(time.getDate() + valor);
this._postEvent.EventRecurrence.LastOccurrence = time;
} else {
time = new Date(
time.getFullYear() + valor,
time.getMonth(),
time.getDate(),
time.getHours(),
time.getMinutes()
);
this._postEvent.EventRecurrence.LastOccurrence = time;
}
}
async validationEditAllEvent() {
if (this.postEvent.IsRecurring ) {
const modal = await this.modalController.create({
component: EventRecurrencePage,
componentProps: {},
cssClass: 'event-recurrence-modal',
});
modal.onDidDismiss().then((res) => {
const data: EventRecurrenceComponentReturn = res.data
if(data =='EditAll') {
this.editAllEvent = true
} else if (data == 'EditOne') {
this.editAllEvent = false
} else if(data == 'Cancel') {
this.close()
} else {
this.close()
}
});
await modal.present();
}
}
@XTracerAsync({name:'desktop/edit-event', bugPrint: true, daley: 4000})
async save_v2(tracing?: TracingType) {
this.injectValidation()
this.runValidation()
if (this.Form.invalid) {
return false
}
const serverCurrentList = this._postEvent.Attendees
this._postEvent.Attendees = this.taskParticipants.concat(this.taskParticipantsCc);
try {
const calendar = await this.agendaDataRepository.getCalendarByUserId(this.selectedUserCalendar)
if(calendar.isOk()) {
this.showLoader = true;
const value = await this.agendaDataRepository.updateEvent(this._postEvent.EventId, this._postEvent, this.editAllEvent, calendar.value, tracing)
if(value.isOk()) {
console.log(value.value)
this.httpErrorHandle.httpsSucessMessagge('Editar evento')
this.clearPostEvent.emit();
this.deleteTemporaryData();
this.showLoader = false;
tracing
} else {
console.log('edit event error: ', value.error)
tracing.setAttribute('outcome', 'failed')
}
const { insert, remove } = AttendeesLIstChangeDetector(serverCurrentList as any, this._postEvent.Attendees as any)
console.log({ insert, remove });
if(insert.length >= 1) {
try {
await this.agendaDataRepository.addEventAttendee(this._postEvent.EventId, insert, tracing).toPromise()
} catch (error) {
tracing.setAttribute('failed.attendees', 'true')
console.log('add Attendee error: ', error)
}
// let a = this.agendaDataRepository.addEventAttendee(this._postEvent.EventId, insert, tracing).subscribe((value) => {
// console.log(value)
// }, ((error) => {
// tracing.setAttribute('failed.attendees', 'true')
// console.log('add Attendee error: ', error)
// }));
}
if(remove.length >= 1) {
try {
await this.agendaDataRepository.removeEventAttendee(this._postEvent.EventId, remove).toPromise()
} catch (error) {
tracing.setAttribute('failed.attendees', 'true')
console.log('add Attendee error: ', error)
}
// this.agendaDataRepository.removeEventAttendee(this._postEvent.EventId, remove).subscribe((value) => {
// console.log(value)
// }, ((error) => {
// tracing.setAttribute('failed.attendees', 'true')
// console.log('add Attendee error: ', error)
// }));
}
if (this.addedAttachmentsList.length >= 1) {
try {
await this.agendaDataRepository.addEventAttachment(this._postEvent.EventId, this.loadedEventAttachments, tracing).toPromise()
} catch (error) {
this.showLoader = false
tracing.setAttribute('failed.add.attachment', 'true')
console.log('add attachment error: ', error)
}
// this.agendaDataRepository.addEventAttachment(this._postEvent.EventId, this.loadedEventAttachments, tracing).subscribe((value) => {
// console.log(value)
// }, ((error) => {
// this.showLoader = false
// tracing.setAttribute('failed.add.attachment', 'true')
// console.log('add attachment error: ', error)
// }));
}
if (this.deletedAttachmentsList.length >= 1) {
try {
await this.agendaDataRepository.removeEventAttachment(this._postEvent.EventId, { attachments: this.deletedAttachmentsList }).toPromise()
} catch (error) {
this.showLoader = false
console.log('remove attachment error: ', error)
}
// this.agendaDataRepository.removeEventAttachment(this._postEvent.EventId, { attachments: this.deletedAttachmentsList }).subscribe((value) => {
// console.log(value)
// }, ((error) => {
// this.showLoader = false
// console.log('remove attachment error: ', error)
// }));
}
this.close();
} else {
console.log('this.selectedUserCalendar', this.selectedUserCalendar)
console.log(calendar.error)
}
} catch (error) {
this.httpErrorHandle.httpStatusHandle(error)
console.log('edit: ', error)
}
}
async addParticipants() {
this.saveTemporaryData();
this.openAttendeesComponent.emit({
type: "intervenient"
});
this.clearContact.emit();
}
async addParticipantsCc() {
this.saveTemporaryData();
this.openAttendeesComponent.emit({
type: "CC"
});
this.clearContact.emit();
}
onDateChange(e) {
const cloneDateStartDate = new Date(this._postEvent.StartDate);
const cloneDateEndDate = new Date(this._postEvent.EndDate);
if(cloneDateStartDate.getTime() >= cloneDateEndDate.getTime()) {
cloneDateStartDate.setHours(cloneDateStartDate.getHours() + 1);
this._postEvent.EndDate = cloneDateStartDate
}
}
saveTemporaryData() {
window['temp.path:/home/agenda/edit-event.component.ts'] = {
postEvent: this._postEvent,
eventBody: this.eventBody,
segment: this.segment,
loadedEventAttachments: this.loadedEventAttachments,
}
}
restoreTemporaryData(): boolean {
const restoredData = window['temp.path:/home/agenda/edit-event.component.ts']
if (JSON.stringify(restoredData) != "{}" && undefined != restoredData) {
this._postEvent = restoredData.postEvent
this.eventBody = restoredData.eventBody
this.segment = restoredData.segment
this.loadedEventAttachments = restoredData.loadedEventAttachments
return true;
} else {
return false;
}
}
deleteTemporaryData() {
window['temp.path:/home/agenda/edit-event.component.ts'] = {}
}
deleteAttachment(attachmentID: string, index) {
const indexToRemove = index; // Assuming you already know the index you want to remove
const DocumentId: any = this.loadedEventAttachments[index].Id
if (indexToRemove > -1 && indexToRemove < this.loadedEventAttachments.length) {
this.loadedEventAttachments.splice(indexToRemove, 1);
}
this.deletedAttachmentsList.push(DocumentId)
}
async getDoc() {
const modal = await this.modalController.create({
component: SearchPage,
cssClass: 'modal-width-100-width-background modal',
componentProps: {
type: 'AccoesPresidenciais & ArquivoDespachoElect',
eventAgenda: true,
showSearchInput: true,
select: true,
}
});
modal.onDidDismiss().then(async (res) => {
if (res) {
const data = res.data;
console.log('Get Doc', data.selected)
/* const ApplicationIdDocumentToSave: any = {
SourceName: data.selected.Assunto,
ParentId: this._postEvent.EventId,
SourceId: data.selected.Id,
Stakeholders: data.selected.EntidadeOrganicaNome | data.selected.Stakeholders,
ApplicationId: data.selected.ApplicationType.toString(),
CreateDate: data.selected.Data,
Id: 'add',
SourceTitle: data.selected.Assunto,
Source: '1',
Link: '',
SerialNumber: '',
}*/
console.log({data})
let newDocObject: SearchList_v2 & {ApplicationId: any} = {
docId: data.selected.docId,
sourceName: data.selected.sourceName,
description: data.selected.description,
applicationId: data.selected.applicationId,
classificator: data.selected.classificator,
dateEntry: data.selected.dateEntry,
docNumber: data.selected.docNumber,
subject: data.selected.subject,
userId: data.selected.userId,
ApplicationId: data.selected.applicationId
}
this.loadedEventAttachments.push(data.selected)
this.addedAttachmentsList.push(data.selected)
}
});
await modal.present();
}
async changeAgenda() {
const result = await this.agendaDataRepository.geCalendars()
const selectedCalendar = result.find(e => e.wxUserId == this.selectedUserCalendar)
if(selectedCalendar) {
if(selectedCalendar.shareType == 1) {
this.CalendarNamesOptions = ['Oficial']
} else if(selectedCalendar.shareType == 2) {
this.CalendarNamesOptions = ['Pessoal']
} else if (selectedCalendar.shareType == 3) {
this.CalendarNamesOptions = ['Oficial', 'Pessoal']
}
}
}
onCheckboxChange(event: any) {
console.log(this.postEvent.CalendarId)
if (this.allDayCheck) {
this.postEvent.IsAllDayEvent = this.allDayCheck;
this.postEvent.StartDate = this.setAlldayTime(this.postEvent.StartDate)
this.postEvent.EndDate = this.setAlldayTimeEndDate(this.postEvent.EndDate)
console.log('Recurso ativado!!');
} else {
this.postEvent.IsAllDayEvent = this.allDayCheck;
this.postEvent.EndDate = this.setAlldayTimeEndDateNotAlday(this.postEvent.EndDate)
console.log('Recurso desativado');
}
}
setAlldayTime(timeToReturn) {
let date: any = new Date(timeToReturn) || new Date();
let newdate = new Date();
date.setHours(0)
date.setMinutes(0)
date.setSeconds(0);
return date
}
setAlldayTimeEndDate(timeToReturn) {
let date: any = new Date(timeToReturn) || new Date();
let newdate = new Date();
date.setHours(23)
date.setMinutes(59)
date.setSeconds(0);
return date
}
setAlldayTimeEndDateNotAlday(timeToReturn) {
let date: any = new Date(timeToReturn) || new Date();
let newdate = new Date();
date.setHours(23)
date.setMinutes(0)
date.setSeconds(0);
return date
}
setEventType(eventType) {
if(typeof eventType == 'number') {
var selectedEventType = {
1: 'Meeting',
2: 'Travel',
3: 'Conference',
4: 'Encontro'
}
return selectedEventType[eventType];
} else {
return this._postEvent.Category
}
}
}
@@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { EventListPage } from './event-list.page';
const routes: Routes = [
{
path: '',
component: EventListPage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class EventListPageRoutingModule {}
@@ -0,0 +1,47 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { EventListPageRoutingModule } from './event-list-routing.module';
import { EventListPage } from './event-list.page';
import { MatInputModule } from '@angular/material/input';
import { MatNativeDateModule } from '@angular/material/core';
import {
NgxMatDatetimePickerModule,
NgxMatNativeDateModule,
NgxMatTimepickerModule
} from '@angular-material-components/datetime-picker';
import { ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatSelectModule } from '@angular/material/select';
import { NgxMatMomentModule } from '@angular-material-components/moment-adapter';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
EventListPageRoutingModule,
//
MatInputModule,
MatNativeDateModule,
NgxMatDatetimePickerModule,
NgxMatTimepickerModule,
NgxMatNativeDateModule,
NgxMatMomentModule,
MatSelectModule,
MatButtonModule,
],
declarations: [EventListPage],
exports: [EventListPage]
})
export class EventListPageModule {}
@@ -0,0 +1,80 @@
<ion-header class="ion-no-border">
<div class="header-content">
<div class="header-title d-flex align-center justify-between width-100">
<div class="flex-grow-1">Eventos para aprovação</div>
<div (click)="refreshing()">
<button title="Atualizar" class="btn-no-color" >
<ion-icon class=" font-45-em" src="assets/images/theme/gov/icon-reload.svg"></ion-icon>
</button>
</div>
</div>
<ion-toolbar *ngIf="(sharedCalendar | async) as calendarData">
<ion-segment [(ngModel)]="selectedUserCalendar" (ionChange)="segmentChanged($event)" *ngIf="SessionStore.user.RoleID !== 100000014">
<ion-segment-button *ngFor="let calendars of calendarData" value="{{calendars.wxUserId}}" >
<div *ngIf="environment.presidential">
<div *ngIf="calendars.roleId == RoleIdService.PRES">AGENDA DO PR </div>
<div *ngIf="calendars.roleId == RoleIdService.MD && calendars.roleId != SessionStore.user.RoleID">AGENDA DO MDGPR</div>
<div *ngIf="calendars.roleId != RoleIdService.MD && calendars.roleId != RoleIdService.PRES && calendars.wxFullName && calendars.wxUserId != SessionStore.user.UserId "> Agenda {{calendars.wxFullName}} </div>
<div *ngIf="calendars.wxUserId == SessionStore.user.UserId ">
Minha agenda
</div>
</div>
<div *ngIf="!environment.presidential">
<div *ngIf="calendars.roleId == RoleIdService.PRES">{{ environment.agendaPR}} </div>
<div *ngIf="calendars.roleId == RoleIdService.MD && calendars.roleId != SessionStore.user.RoleID">{{ environment.agendaVP}}</div>
<div *ngIf="calendars.roleId != RoleIdService.MD && calendars.roleId != RoleIdService.PRES && calendars.wxFullName && calendars.wxUserId != SessionStore.user.UserId "> Agenda {{calendars.wxFullName}} </div>
<div *ngIf="calendars.wxUserId == SessionStore.user.UserId ">
Minha agenda
</div>
</div>
</ion-segment-button>
</ion-segment>
</ion-toolbar>
</div>
</ion-header>
<ion-content>
<ion-refresher name="refresher" slot="fixed" (ionRefresh)="doRefresh($event)">
<ion-progress-bar type="indeterminate" *ngIf="showLoader"></ion-progress-bar>
<ion-refresher-content>
</ion-refresher-content>
</ion-refresher>
<div class="main-content overflow-y-auto height-100" >
<!-- <div class="header-content width-100"> -->
<!-- </div> -->
<ion-list class="width-100">
<div class="width-100" >
<div
class="item ion-no-padding width-100 cursor-pointer"
*ngFor="let event of eventoaprovacaostore.get(selectedUserCalendar)"
(click)="openApproveModal(event.serialNumber, event)"
>
<div class="event-{{color}}-{{event.workflowInstanceDataFields.Agenda}} width-100">
<div *ngIf="!event.workflowInstanceDataFields.IsAllDayEvent" class="approve-event-time">
<p>{{event.workflowInstanceDataFields.StartDate | date: 'HH:mm'}}</p>
<p>{{event.workflowInstanceDataFields.EndDate | date: 'HH:mm'}}</p>
</div>
<div *ngIf="event.workflowInstanceDataFields.IsAllDayEvent" class="approve-event-time">
<p>Todo</p>
<p>o dia</p>
</div>
<div class="approve-event-detail">
<h3>{{event.workflowInstanceDataFields.Subject}}</h3>
<p *ngIf="toDateString(event.workflowInstanceDataFields.StartDate) != toDateString(event.workflowInstanceDataFields.EndDate)">{{event.workflowInstanceDataFields.StartDate | date: 'd/M/yy' }} - {{ event.workflowInstanceDataFields.EndDate | date: 'dd/M/yy'}} | {{event.workflowInstanceDataFields.Location}}</p>
<p *ngIf="toDateString(event.workflowInstanceDataFields.StartDate) == toDateString(event.workflowInstanceDataFields.EndDate)">{{event.workflowInstanceDataFields.StartDate | date: 'd/M/yy' }} | {{event.workflowInstanceDataFields.Location}}</p>
<div *ngIf="event.activityInstanceName">
<div class="label-event-type font-13-rem"> {{ event.activityInstanceName }} </div>
</div>
</div>
</div>
</div>
</div>
</ion-list>
</div>
</ion-content>
@@ -0,0 +1,121 @@
@import '~src/function.scss';
:host{
margin: 0;
}
.header-content{
overflow: auto;
margin: 0 auto;
padding: 30px 20px 0 20px !important;
}
.header-icon-left{
font-size: rem(33);
color: #42b9fe;
float: left;
}
.header-title{
font-family: Roboto;
font-size: rem(25);
padding: 0;
color:#000;
float: left;
}
.main-content{
padding: 0px 20px 0 20px !important;
margin-top: 20px;
.item{
--inner-padding-end: 0 !important;
--inner-padding-top: 10px;
--inner-padding-bottom:10px;
border-radius: 15px;
box-shadow: 0 0 10px 0 rgb(0 0 0 / 7%);
border: 1px solid #e9e9e9 !important;
background-color: var(--white);
margin-bottom: 10px !important;
padding: 15px;
}
.event-pr-Oficial{
background-color: var(--white);
border-radius: 5px;
border-right: 5px solid #99e47b;
overflow: auto;
}
.event-pr-Pessoal{
background-color: var(--white);
border-radius: 5px;
border-right: 5px solid #958bfc;
overflow: auto;
}
.event-mdgpr-Oficial{
border-radius: 5px;
border-right: 5px solid var(--label-bg-color);
overflow: auto;
}
.event-mdgpr-Pessoal{
border-radius: 5px;
border-right: 5px solid #f05d5e;
overflow: auto;
}
.approve-event-time{
float: left;
}
.approve-event-time p{
width: 33px;
font-family: Roboto;
font-size: rem(13);
font-weight: normal;
font-stretch: normal;
font-style: normal;
line-height: normal;
letter-spacing: normal;
color: var(--Antartic-grey);
margin: 0;
padding-bottom: 10px;
}
.approve-event-detail{
float: left;
margin-left: 10px;
}
.approve-event-detail p{
//width: 250px;
font-family: Roboto;
font-size: rem(13);
font-weight: normal;
font-stretch: normal;
font-style: normal;
line-height: normal;
letter-spacing: normal;
color: var(--black);
margin: 0;
padding-bottom: 10px;
}
.approve-event-detail h3{
width: 250px;
font-family: Roboto;
font-size: rem(15);
font-weight: bold;
font-stretch: normal;
font-style: normal;
line-height: normal;
letter-spacing: normal;
text-transform: none ;
color: var(--title-text-color);
margin: 0;
padding: 0;
max-width: 200px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.label-event-type {
padding: 1px 7px;
display: inline-block;
background: #f05d5e;
border-radius: 17px;
color: white;
font-size: rem(13);
}
@@ -0,0 +1,24 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { EventListPage } from './event-list.page';
describe('EventListPage', () => {
let component: EventListPage;
let fixture: ComponentFixture<EventListPage>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ EventListPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(EventListPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,216 @@
import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core';
import { EventBody } from 'src/app/models/eventbody.model';
import { EventPerson } from 'src/app/models/eventperson.model';
import { ProcessesService } from 'src/app/services/processes.service';
import { NavigationEnd, Router } from '@angular/router';
import { LoginUserRespose } from 'src/app/models/user.model';
import { SortService } from 'src/app/services/functions/sort.service';
import { SessionStore } from 'src/app/store/session.service';
import { EventsService } from 'src/app/services/events.service';
import { EventoAprovacaoStore } from 'src/app/store/eventoaprovacao-store.service';
import { environment } from 'src/environments/environment';
import { AgendaDataRepositoryService } from 'src/app/module/agenda/data/repository/agenda-data-repository.service';
import { EventToApproveList } from 'src/app/models/entiry/agenda/eventToApproveList';
import { RoleIdService } from 'src/app/services/role-id.service'
import { map } from 'rxjs/operators';
import { Observable } from 'rxjs';
import { TableSharedCalendar } from 'src/app/module/agenda/data/data-source/agenda-local-data-source.service';
import { EEventFilterStatus } from 'src/app/module/agenda/data/dto/enums';
import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
import { isHttpError } from 'src/app/services/http.service';
import { ToastService } from 'src/app/services/toast.service';
@Component({
selector: 'app-event-list',
templateUrl: './event-list.page.html',
styleUrls: ['./event-list.page.scss'],
})
export class EventListPage implements OnInit {
// [desktop] event list to approve
showLoader: boolean;
eventsList: EventToApproveList = []
eventPerson: EventPerson;
eventBody: EventBody;
categories: string[];
serialnumber:string;
loggeduser: LoginUserRespose;
segment:string;
eventoaprovacaostore = EventoAprovacaoStore;
environment = environment
color: 'pr' | 'mdgpr'
SessionStore = SessionStore;
@Input() profile:string;
@Input() showComponent:string;
@Output() cloneAllmobileComponent = new EventEmitter<any>();
@Output() approveEventDismiss = new EventEmitter<any>();
sharedCalendar: Observable<TableSharedCalendar[]>
selectedUserCalendar:any;
constructor(
private processes:ProcessesService,
private router: Router,
private sortService: SortService,
public eventService: EventsService,
public AgendaDataRepositoryService: AgendaDataRepositoryService,
public RoleIdService: RoleIdService,
private toastService: ToastService,
) {
this.loggeduser = SessionStore.user;
// Define the role priorities
const rolePriorities: { [key: number]: number } = {
100000014: 1, // Presidente da República
100000011: 2, // Vice Presidente (example role ID)
// Add other roles with their priorities here
};
this.sharedCalendar = this.AgendaDataRepositoryService.getShareCalendarItemsLive().pipe(
map(data => data.sort((a, b) => {
const priorityA = rolePriorities[a.roleId] || Infinity;
const priorityB = rolePriorities[b.roleId] || Infinity;
return priorityA - priorityB;
}))
)
this.setCalendarByDefault()
}
async setCalendarByDefault() {
const data = await this.AgendaDataRepositoryService.geCalendars()
const prObject = data.find(e => e?.roleId == 100000014)
if(prObject) {
this.selectedUserCalendar = prObject.wxUserId
} else {
this.selectedUserCalendar = SessionStore.user.UserId
}
}
ngAfterViewInit(): void {}
ngOnInit() {
const pathname = window.location.pathname
this.router.events.forEach((event) => {
if(event instanceof NavigationEnd && event.url == pathname) {
this.LoadToApproveEvents();
}
});
}
ngOnChanges() {
this.LoadToApproveEvents();
setTimeout(() => {
this.LoadToApproveEventsNoLoader();
}, 3000)
}
segmentChanged(ev: any) {
this.LoadToApproveEvents();
}
toDateString(e) {
return new Date(e).toDateString()
}
@XTracerAsync({name:'EventListPageShared/LoadToApproveEvents', bugPrint: true})
async LoadToApproveEvents(tracing?: TracingType) {
this.showLoader = true;
const segment = this.selectedUserCalendar
let userId;
if(this.selectedUserCalendar == SessionStore.user.UserId) {
// color
if(SessionStore.user.Profile == 'PR') {
this.color = 'pr'
} else {
this.color = 'mdgpr'
}
userId = SessionStore.user.UserId
} else if(segment) {
this.color = 'pr'
userId = this.selectedUserCalendar
}
if(userId) {
let allEvents = await this.AgendaDataRepositoryService.eventToApproveList({
userId,
status: EEventFilterStatus.Pending
}, tracing)
if(allEvents.isOk()) {
tracing.setAttribute('outcome', 'success')
if(allEvents.value.length >= 1) {
this.eventsList = this.sortService.sortArrayByDate(allEvents.value).reverse();
this.eventoaprovacaostore.save(this.selectedUserCalendar, this.eventsList)
} else {
this.eventoaprovacaostore.save(this.selectedUserCalendar, [])
}
} else {
tracing.setAttribute('outcome', 'failed')
if(!isHttpError(allEvents.error)) {
this.toastService._badRequest('Pedimos desculpa mas não foi possível executar a acção. Por favor, contacte o apoio técnico. #3')
console.log(allEvents.error)
}
this.eventsList = [];
}
this.showLoader = false;
} else {
tracing.setAttribute('run', 'to early')
console.warn('calling to early eventlistpageshared/loadtoapproveevents')
}
}
async LoadToApproveEventsNoLoader() {
this.LoadToApproveEvents()
}
async openApproveModal(eventSerialNumber, data) {
this.approveEventDismiss.emit({
"serialNumber": eventSerialNumber,
"action": "Aprovar",
"saveData": data
});
}
refreshing() {
this.LoadToApproveEvents();
}
doRefresh(event) {
this.LoadToApproveEvents();
setTimeout(() => {
try {
event?.target?.complete();
} catch(error) {}
}, 2000);
}
close() {
this.cloneAllmobileComponent.emit();
}
}
@@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { NewEventPage } from './new-event.page';
const routes: Routes = [
{
path: '',
component: NewEventPage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class NewEventPageRoutingModule {}
@@ -0,0 +1,69 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, NgControl } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { NewEventPageRoutingModule } from './new-event-routing.module';
import { NewEventPage } from './new-event.page';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatInputModule } from '@angular/material/input';
import { MatNativeDateModule } from '@angular/material/core';
import {
NgxMatDatetimePickerModule,
NgxMatNativeDateModule,
NgxMatTimepickerModule
} from '@angular-material-components/datetime-picker';
import { ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatSelectModule } from '@angular/material/select';
import { NgxMatMomentModule } from '@angular-material-components/moment-adapter';
import {
MAT_MOMENT_DATE_FORMATS,
MomentDateAdapter,
MAT_MOMENT_DATE_ADAPTER_OPTIONS
} from '@angular/material-moment-adapter';
import {DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE} from '@angular/material/core';
import { AttendeeModalPageModule } from 'src/app/shared/event/attendee-modal/attendee-modal.module';
import { InputFilterDirective } from 'src/app/services/directives/input-filter.directive';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
NewEventPageRoutingModule,
NgbModule,
MatDatepickerModule,
MatInputModule,
MatNativeDateModule,
//
NgxMatDatetimePickerModule,
NgxMatTimepickerModule,
NgxMatNativeDateModule,
//
NgxMatMomentModule,
// BrowserAnimationsModule,
// MatRadioModule,
MatSelectModule,
//MatRadioModule,
//MatCheckboxModule,
MatButtonModule,
ReactiveFormsModule,
AttendeeModalPageModule
],
declarations: [NewEventPage],
providers: [
{ provide: MAT_DATE_LOCALE, useValue: 'pt' },
],
exports: [NewEventPage]
})
export class NewEventPageModule {}
@@ -0,0 +1,457 @@
<ion-header class="ion-no-border">
<ion-toolbar class="header-toolbar">
<div class="main-header">
<div class="title-content">
<div class="middle">
<ion-label class="title">Novo Evento</ion-label> <br>
<i style="margin-top: -3px; font-size: 15px;" > Campos marcados com * são obrigatórios</i>
</div>
</div>
<ion-progress-bar class="calendar-progress-bar" type="indeterminate" *ngIf="showLoader"></ion-progress-bar>
</div>
</ion-toolbar>
</ion-header>
<ion-content>
<div class="main-content">
<div class="ion-item-container" [class.input-error]="Form?.get('Subject')?.invalid && validateFrom ">
<ion-input autocomplete="on" autocorrect="on" spellcheck="true" placeholder="Assunto*" [(ngModel)]="postEvent.Subject"></ion-input>
</div>
<div *ngIf="Form && validateFrom" >
<div *ngIf="Form.get('Subject').invalid " class="input-errror-message">
<div *ngIf="Form.get('Subject').errors?.required">
</div>
<div *ngIf="Form.get('Subject').errors?.minlength">
O campo deve ter pelo menos 4 caracteres.
</div>
</div>
</div>
<div *ngIf="(sharedCalendar | async) as calendarData" class="container-div" >
<div class="ion-item-class-2 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1 justify-center align-center material-inputs " [class.input-error]="Form?.get('CalendarName')?.invalid && validateFrom ">
<mat-form-field appearance="none" class="width-100" color="ion-color-secondary" placeholder="Selecione agenda">
<div *ngIf="hasPrCalendar(calendarData) && !hasChangeCalendar " style="margin-bottom: -20px;">PR</div>
<div *ngIf="selectedUserCalendar == SessionStore.user.UserId && !hasChangeCalendar && SessionStore.user.Profile != 'PR' " style="margin-bottom: -20px;">
Minha agenda
</div>
<mat-select [(value)]="selectedUserCalendar" (selectionChange)="changeAgenda();changeSegmentCalendar()">
<mat-option *ngFor="let calendars of calendarData" value="{{calendars.wxUserId}}">
<div *ngIf="calendars.roleId == RoleIdService.PRES">PR </div>
<div *ngIf="calendars.roleId == RoleIdService.MD && calendars.roleId != SessionStore.user.RoleID">AGENDA DO MDGPR</div>
<div *ngIf="calendars.roleId != RoleIdService.MD && calendars.roleId != RoleIdService.PRES && calendars.wxFullName && calendars.wxUserId != SessionStore.user.UserId"> Agenda do {{calendars.wxFullName}} </div>
<div *ngIf="calendars.wxUserId == SessionStore.user.UserId && SessionStore.user.Profile != 'PR'">
Minha agenda
</div>
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
<div class="container-div">
<div class="ion-item-class-2 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-location.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1 width-100" [class.input-error]="Form?.get('Location')?.invalid && validateFrom " >
<ion-input autocomplete="on" autocorrect="on" spellcheck="true" type="text" placeholder="Localização*" [(ngModel)]="postEvent.Location"></ion-input>
</div>
</div>
</div>
<div class="container-div" >
<div class="ion-item-class-2 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1 justify-center align-center material-inputs " [class.input-error]="Form?.get('CalendarName')?.invalid && validateFrom ">
<mat-form-field appearance="none" class="width-100" color="ion-color-secondary" placeholder="Selecione agenda">
<mat-select [(value)]="postEvent.CalendarName" >
<mat-option *ngFor="let calendars of CalendarNamesOptions" value="{{calendars}}">
Calendário {{ calendars }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
<div class="container-div">
<div class="ion-item-class-2 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-description.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1 justify-center align-center material-inputs">
<mat-form-field appearance="none" class="width-100" placeholder="Sample Type" required>
<!-- <input matInput type="text" > -->
<mat-select [(value)]="postEvent.Category" >
<mat-option value="Meeting">
Reunião
</mat-option>
<mat-option value="Travel">
Viagem
</mat-option>
<mat-option value="Conference">
Conferência
</mat-option>
<mat-option value="Encontro">
Encontro
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
<div class="container-div">
<div>
<ion-item>
<ion-label>Todo dia</ion-label>
<ion-checkbox [(ngModel)]="allDayCheck" (ionChange)="onCheckboxChange($event)"></ion-checkbox>
</ion-item>
</div>
</div>
<div class="container-div">
<div class="ion-item-class-2 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-reapet.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1 justify-center align-center material-inputs">
<mat-form-field appearance="none" class="width-100" placeholder="Sample Type" required>
<!-- <input matInput type="text" > -->
<mat-select [(value)]="postEvent.EventRecurrence.frequency" >
<mat-option value="never">
Nunca
</mat-option>
<mat-option value="daily">
Diário
</mat-option>
<mat-option value="weekly">
Semanalmente
</mat-option>
<mat-option value="monthly">
Mensal
</mat-option>
<mat-option value="yearly">
Anual
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="postEvent.EventRecurrence.frequency != 'never'" class="container-div">
<div class="ion-item-class-2 d-flex" >
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-reapet.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1 justify-center align-center material-inputs materia-top" >
<mat-form-field appearance="none" class="date-hour-picker">
<input matInput [ngxMatDatetimePicker]="picker1"
placeholder="Data Fim de Recorrência*"
[(ngModel)]="postEvent.EventRecurrence.until"
[disabled]="disabled"
>
<mat-datepicker-toggle id="new-inicio" matSuffix [for]="picker1" ></mat-datepicker-toggle>
<ngx-mat-datetime-picker #picker1
[showSpinners]="showSpinners"
[showSeconds]="showSeconds"
[stepHour]="stepHour" [stepMinute]="stepMinute"
[stepSecond]="stepSecond"
[touchUi]="touchUi"
[hideTime]="true"
>
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="allDayCheck" class="container-div">
<div class="ion-item-class-2 d-flex" >
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1 justify-center align-center material-inputs materia-top" >
<mat-form-field appearance="none" class="date-hour-picker">
<input matInput [ngxMatDatetimePicker]="picker1"
placeholder="Data Inicio*"
[(ngModel)]="postEvent.StartDate"
[disabled]="disabled"
(ngModelChange)="onDateChange($event)"
>
<mat-datepicker-toggle id="new-inicio" matSuffix [for]="picker1" ></mat-datepicker-toggle>
<ngx-mat-datetime-picker #picker1
[showSpinners]="showSpinners"
[showSeconds]="showSeconds"
[stepHour]="stepHour" [stepMinute]="stepMinute"
[stepSecond]="stepSecond"
[touchUi]="touchUi"
[hideTime]="true"
>
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="!allDayCheck" class="container-div">
<div class="ion-item-class-2 d-flex" >
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1 justify-center align-center material-inputs materia-top" >
<mat-form-field appearance="none" class="date-hour-picker">
<input matInput [ngxMatDatetimePicker]="picker1"
placeholder="Data Inicio*"
[(ngModel)]="postEvent.StartDate"
[disabled]="disabled"
(ngModelChange)="onDateChange($event)"
>
<mat-datepicker-toggle id="new-inicio" matSuffix [for]="picker1" ></mat-datepicker-toggle>
<ngx-mat-datetime-picker #picker1
[showSpinners]="showSpinners"
[showSeconds]="showSeconds"
[stepHour]="stepHour" [stepMinute]="stepMinute"
[stepSecond]="stepSecond"
[touchUi]="touchUi"
[hideTime]="false"
>
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="allDayCheck" class="container-div">
<div class="ion-item-class-2 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<!--
[className]="Form?.get('Subject')?.invalid ? 'input-error ion-input-class flex-grow-1' : 'ion-input-class ion-input-class flex-grow-1' "
-->
<div (click)="openFim()" class="ion-input-class flex-grow-1 justify-center align-center materia-top" [class.input-error]="Form?.get('Date')?.invalid && validateFrom ">
<mat-form-field appearance="none" class="date-hour-picker">
<input matInput [ngxMatDatetimePicker]="fim"
placeholder="Data de fim*"
[(ngModel)]="postEvent.EndDate"
[disabled]="disabled"
[min]="postEvent.StartDate"
>
<mat-datepicker-toggle id="new-fim" matSuffix [for]="fim" ></mat-datepicker-toggle>
<ngx-mat-datetime-picker #fim
[showSpinners]="showSpinners"
[showSeconds]="showSeconds"
[stepHour]="stepHour" [stepMinute]="stepMinute"
[stepSecond]="stepSecond"
[hideTime]="true"
>
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="!allDayCheck" class="container-div">
<div class="ion-item-class-2 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<!--
[className]="Form?.get('Subject')?.invalid ? 'input-error ion-input-class flex-grow-1' : 'ion-input-class ion-input-class flex-grow-1' "
-->
<div (click)="openFim()" class="ion-input-class flex-grow-1 justify-center align-center materia-top" [class.input-error]="Form?.get('Date')?.invalid && validateFrom ">
<mat-form-field appearance="none" class="date-hour-picker">
<input matInput [ngxMatDatetimePicker]="fim"
placeholder="Data de fim*"
[(ngModel)]="postEvent.EndDate"
[disabled]="disabled"
[min]="postEvent.StartDate"
>
<mat-datepicker-toggle id="new-fim" matSuffix [for]="fim" ></mat-datepicker-toggle>
<ngx-mat-datetime-picker #fim
[showSpinners]="showSpinners"
[showSeconds]="showSeconds"
[stepHour]="stepHour" [stepMinute]="stepMinute"
[stepSecond]="stepSecond"
[hideTime]="false"
>
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
</div>
</div>
<div class="container-div width-100">
<div class="ion-item-class-2 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-person.svg"></ion-icon>
</div>
<div class="ion-input-class-no-height flex-grow-1 cursor-pointer" (click)="addParticipants()" [class.input-error]="Form?.get('participantes')?.invalid && validateFrom">
<div class="list-people">
<ion-item lines="none">
<ion-list>
<ion-label *ngIf="taskParticipants.length ==0" class="list-people-title">Adicionar Intervenientes*</ion-label>
<ion-label *ngFor="let participant of taskParticipants">{{participant.Name}}</ion-label>
</ion-list>
</ion-item>
</div>
<div class="add-people cursor-pointer" >
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " slot="start" src="assets/images/icons-arrow-forward.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " slot="start" src="assets/images/theme/gov/icons-arrow-forward.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " slot="start" src="assets/images/theme/{{ThemeService.currentTheme}}/icons-arrow-forward.svg"></ion-icon>
</div>
</div>
</div>
</div>
<div class="container-div">
<div class="ion-item-class-2 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-people-cc.svg"></ion-icon>
</div>
<div class="ion-input-class-no-height flex-grow-1 cursor-pointer" [class.input-error]="Form?.get('participantes')?.invalid && validateFrom" (click)="addParticipantsCc()">
<div class="list-people">
<ion-item lines="none">
<ion-list>
<ion-label *ngIf="taskParticipantsCc.length ==0" class="list-people-title">Com conhecimento</ion-label>
<ion-label *ngFor="let participant of taskParticipantsCc">{{participant.Name}}</ion-label>
</ion-list>
</ion-item>
</div>
<div class="add-people cursor-pointer" >
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " slot="start" src="assets/images/icons-arrow-forward.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " slot="start" src="assets/images/theme/gov/icons-arrow-forward.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " slot="start" src="assets/images/theme/{{ThemeService.currentTheme}}/icons-arrow-forward.svg"></ion-icon>
</div>
</div>
</div>
</div>
<div class="container-div">
<div class="ion-item-class-2 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-description.svg"></ion-icon>
</div>
<div class="ion-input-class-no-height flex-grow-1">
<ion-textarea class="heigh-200" autocomplete="on" autocorrect="on" spellcheck="true" [(ngModel)]="postEvent.Body.Text" placeholder="Detalhes" autoGrow="true" ></ion-textarea>
</div>
</div>
</div>
<div class="ion-item-container-no-border cursor-pointer" (click)="getDoc()">
<ion-label>
<div class="attach-icon">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/images/icons-attach-doc.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/images/theme/gov/icons-attach-doc.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " src="assets/images/theme/{{ThemeService.currentTheme}}/icons-attach-doc.svg"></ion-icon>
</div>
<div class="attach-document">
<ion-label>Adicionar documentos</ion-label>
</div>
</ion-label>
</div>
<div class="list " *ngFor="let document of documents; let i = index" >
<ion-list>
<ion-item>
<ion-label>
<p class="d-flex ion-justify-content-between">
<span class="attach-title-item">{{document.subject}}</span>
<span class="app-name" *ngIf="document.applicationId == 8 || document.ApplicationId == 8"> Correspondência </span>
<span class="app-name" *ngIf="document.applicationId == 386 || document.ApplicationId == 386"> Acções Presidenciais </span>
<span class="app-name" *ngIf="document.applicationId == 361 || document.ApplicationId == 361 "> Arquivo Despacho Electrónico </span>
<span class="close-button text-black cursor-pointer" (click)="removeAttachment(i)" >
<ion-icon class="font-20" src="assets/images/icons-delete-25.svg"></ion-icon>
</span>
</p>
<p><span class="span-left">{{(document.EntidadeOrganicaNome || document.Sender)}}</span><span class="span-right"> {{(document.dateEntry) | date: 'dd-MM-yyyy HH:mm'}} </span></p>
</ion-label>
</ion-item>
</ion-list>
</div>
</div>
<!-- <div *ngIf="mostrarModal">
<app-attendee-modal [loggedAttendSon]="loggedAttendDad"></app-attendee-modal>
</div> -->
</ion-content>
<ion-footer class="ion-no-border">
<ion-toolbar class="footer-toolbar">
<ion-buttons slot="start">
<button class="btn-ok" fill="clear" color="#fff" (click)="save_v2()">
<ion-label>Gravar</ion-label>
</button>
</ion-buttons>
<ion-title></ion-title>
<ion-buttons slot="end">
<button class="btn-cancel" fill="clear" color="#061b52" (click)="close()">
<ion-label>Cancelar</ion-label>
</button>
</ion-buttons>
<!-- <app-new-event
[loggedAttend]="loggedAttend"
></app-new-event> -->
</ion-toolbar>
</ion-footer>
@@ -0,0 +1,222 @@
@import '~src/function.scss';
ion-content{
--background:transparent;
}
.header-toolbar{
--background:transparent;
--opacity: 1;
}
.main-header{
width: 100%; /* 400px */
height: 100%;
font-family: Roboto;
border-top-left-radius: 25px;
border-top-right-radius: 25px;
background-color: #fff;
overflow:hidden;
padding: 30px 20px 0px 20px;
color:#000;
transform: translate3d(0, 1px, 0);
.title-content{
margin: 0px auto;
overflow: auto;
padding: 0 !important;
background: #fff;
.middle{
padding: 0!important;
float: left;
width: 300px;
margin: 2.5px 0 0 5px;
}
}
.title{
font-size: rem(25);
}
}
.main-content{
width: 100%; /* 400px */
height: 100%;
font-family: Roboto;
margin: 0 auto;
background-color: #fff;
overflow:auto;
padding: 15px 20px 0 20px;
.ion-item-container{
margin: rem(15) auto;
border: 1px solid #ebebeb;
border-radius: 5px;
padding-left: 10px;
}
.ion-item-container-no-border{
width: 100%;
margin: 0px auto;
padding: 0 !important;
overflow: auto;
}
.container-div{
margin-bottom: 15px;
}
.ion-item-class-2{
margin: 0px auto;
}
.ion-icon-class{
width: rem(45);
height: rem(45);
float: left;
padding: 10px;
font-size: rem(25);
}
ion-select{
padding-left: 5px;
margin-left: 0;
}
.ion-input-class{
height: rem(45);
border: 1px solid #ebebeb;
border-radius: 5px;
padding-left: 5px;
padding-right: 10px;
float: left;
}
.ion-input-class-no-height{
border: 1px solid #ebebeb;
border-radius: 5px;
overflow: auto;
}
.list-people{
width: 256px;
float: left;
}
.add-people{
width: rem(45);
float: right;
overflow: auto;
font-size: rem(25);
height: rem(45);
display: flex;
}
.list-people-title{
/* font-size: rem(13); */
color: #a3a3a3;
}
.attach-document{
font-size: rem(15);
color: var(--title-text-color);
margin: 5px 5px 5px 10px;
padding: 5px;
float: left;
}
.attach-icon{
width: 37px;
font-size: rem(35);
float: left;
}
.attach-title-item{
width: 100%;
font-size: rem(15);
color:#0d89d1;
}
/* SPAN */
.span-left{
float: left;
font-size: rem(15);
}
.span-right{
text-align: right;
float: right;
font-size: rem(13);
}
.container-footer{
margin:0 auto;
overflow: auto;
}
.button-cancel {
width: rem(170);
height: rem(44);
border-radius: 22.5px;
--background: #e0e9ee;
--color: #061b52;
margin:10px;
}
.button-save {
width: rem(170);
height: rem(44);
border-radius: 22.5px;
--background: #42b9fe;
--color:#ffffff;
margin:10px;
}
.text-input{
width: 100%;
border: 1px solid #ebebeb;
margin: 0px 15px 15px 0px;
padding: 0 !important;
border-radius: 5px;
}
/* Error Messages */
.error{
color:red;
font-size: rem(12);
font-weight: bold;
padding-bottom: 20px;
}
.span-color{
color:red;
}
}
.container-div {
ion-textarea {
// height: 81px;
}
}
.app-name{
background: var(--title-text-color);
border-radius: 18px;
text-align: center;
display: flex;
align-items: center;
padding: 0px 5px;
color: white;
font-size: rem(12);
font-weight: 500;
height: 19px;
-webkit-border-radius: 18px;
-moz-border-radius: 18px;
-ms-border-radius: 18px;
-o-border-radius: 18px;
}
.close-button {
display: none;
height: 20px;
}
.list:hover {
.app-name {
display: none;
}
.close-button {
display: block !important;
}
}
.materia-top {
padding-top: 7px;
}
@@ -0,0 +1,24 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { NewEventPage } from './new-event.page';
describe('NewEventPage', () => {
let component: NewEventPage;
let fixture: ComponentFixture<NewEventPage>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ NewEventPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(NewEventPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,703 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { EventBody } from 'src/app/models/eventbody.model';
import { EventPerson } from 'src/app/models/eventperson.model';
import { EventsService } from 'src/app/services/events.service';
import { Event } from 'src/app/models/event.model';
import { ModalController } from '@ionic/angular';
import { removeDuplicate } from 'src/plugin/removeDuplicate.js'
import { SearchPage } from 'src/app/pages/search/search.page';
import { SearchList_v2 } from "src/app/models/search-document";
import { ToastService } from 'src/app/services/toast.service';
import { LoginUserRespose } from 'src/app/models/user.model';
import { DateAdapter } from '@angular/material/core';
import * as _moment from 'moment';
import * as _rollupMoment from 'moment';
import { FormControl } from '@angular/forms';
import { NgxMatDateFormats } from '@angular-material-components/datetime-picker';
import { ThemePalette } from '@angular/material/core';
import { ViewChild } from '@angular/core';
import { FormGroup, Validators } from '@angular/forms';
import { NGX_MAT_DATE_FORMATS } from '@angular-material-components/datetime-picker';
import { ThemeService } from 'src/app/services/theme.service'
import { SessionStore } from 'src/app/store/session.service';
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service';
import { environment } from 'src/environments/environment';
import { EventToAprove } from 'src/app/models/eventToAprove.model';
import { Observable } from 'rxjs';
import { TaskService } from 'src/app/services/task.service'
import { ChangeProfileService } from 'src/app/services/change-profile.service';
import { AgendaDataRepositoryService } from 'src/app/module/agenda/data/repository/agenda-data-repository.service';
import { RoleIdService } from 'src/app/services/role-id.service'
import { TableSharedCalendar } from 'src/app/module/agenda/data/data-source/agenda-local-data-source.service';
import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
import { ContactRepositoryService } from 'src/app/services/Repositorys/contacts/repository/contacts-repository.service';
import { UserList } from 'src/app/models/entiry/agenda/contact';
import { AgendaService } from 'src/app/module/agenda/domain/agenda.service'
import { RoleId } from 'src/app/core/agenda/use-case/event-set-default-participants.service';
const CUSTOM_DATE_FORMATS: NgxMatDateFormats = {
parse: {
dateInput: "YYYY-MMMM-DD HH:mm"
},
display: {
dateInput: "DD MMM YYYY H:mm",
monthYearLabel: "MMM YYYY",
dateA11yLabel: "LL",
monthYearA11yLabel: "MMMM YYYY"
}
}
@Component({
selector: 'app-new-event',
templateUrl: './new-event.page.html',
styleUrls: ['./new-event.page.scss'],
providers: [
{ provide: NGX_MAT_DATE_FORMATS, useValue: CUSTOM_DATE_FORMATS },
]
})
export class NewEventPage implements OnInit {
eventBody: EventBody;
segment: string = "true";
public date: any;
public disabled = false;
public showSpinners = true;
public showSeconds = false;
public touchUi = false;
public enableMeridian = false;
public stepHour = 1;
public stepMinute = 15;
public stepSecond = 15;
currentDate = this.roundTimeQuarterHour();
public color: ThemePalette = 'primary';
recurringTypes = []
selectedRecurringType: any;
loggedAttendDad: boolean = true;
mostrarModal = false;
eventRecurence = 'never'
@Input() attendees: []
@Input() profile: string;
@Input() roomId: string;
@Input() selectedSegment: string;
@Input() selectedDate: Date;
@Input() CalendarDate: Date;
@Input() taskParticipants: UserList = [];
@Input() taskParticipantsCc: any = [];
@Output() setIntervenient = new EventEmitter<any>();
@Output() setIntervenientCC = new EventEmitter<any>();
postEvent: Event;
postEventToAprove: EventToAprove;
@Output() onAddEvent = new EventEmitter<any>();
@Output() openAttendeesComponent = new EventEmitter<any>();
@Output() clearContact = new EventEmitter<any>();
@Output() GoBackEditOrAdd = new EventEmitter<any>();
@Output() cloneAllmobileComponent = new EventEmitter<any>();
@Output() backToChat = new EventEmitter<any>();
documents: SearchList_v2[] = [];
loggeduser: LoginUserRespose;
@ViewChild('picker') picker: any;
@ViewChild('fim') fim: any;
@ViewChild('inicio') inicio: any;
@ViewChild('occurrence') occurrence: any;
@ViewChild('picker1') picker1: any;
Form: FormGroup;
validateFrom = false;
autoStartTime;
autoEndTime;
public options = [
{ value: true, label: 'True' },
{ value: false, label: 'False' }
];
public listColors = ['primary', 'accent', 'warn'];
public stepHours = [1, 2, 3, 4, 5];
public stepMinutes = [1, 5, 10, 15, 20, 25];
public stepSeconds = [1, 5, 10, 15, 20, 25];
showLoader = false
CalendarName;
CalendarNameShow = true
CalendarNamesOptions = ['Oficial', 'Pessoal']
environment = environment
eventPersons: UserList;
contacts: UserList = [];
allDayCheck: boolean = false;
sharedCalendar: Observable<TableSharedCalendar[]>
selectedUserCalendar:any;
SessionStore = SessionStore
hasChangeCalendar = false
constructor(
private modalController: ModalController,
public eventService: EventsService,
private toastService: ToastService,
private dateAdapter: DateAdapter<any>,
public ThemeService: ThemeService,
private hhtpErrorHandle: HttpErrorHandle,
public TaskService: TaskService,
private changeProfileService: ChangeProfileService,
private agendaDataRepository: AgendaDataRepositoryService,
public RoleIdService: RoleIdService,
private ContactRepositoryService: ContactRepositoryService,
private AgendaService: AgendaService
) {
this.dateAdapter.setLocale('pt');
this.loggeduser = SessionStore.user;
this.postEvent = new Event();
this.sharedCalendar = this.agendaDataRepository.getShareCalendarItemsLiveWithOrder()
}
hasPrCalendar(data: TableSharedCalendar[]) {
for(const e of data) {
if(e.roleId == this.RoleIdService.PRES) {
return true
}
}
return false
}
async setCalendarByDefault(force) {
if (!this.selectedUserCalendar || force) {
const data = await this.agendaDataRepository.geCalendars()
const prObject = data.find(e => e?.roleId == RoleId.PRES)
if(prObject) {
this.selectedUserCalendar = prObject.wxUserId
} else {
this.selectedUserCalendar = SessionStore.user.UserId
}
this.changeAgenda()
}
}
ngOnInit() {
this.changeProfileService.registerCallback(() => {
this.initializeData()
})
this.getRecurrenceTypes();
if (!this.restoreTemporaryData()) {
// clear
this.setCalendarByDefault(true)
this.eventBody = { BodyType: "1", Text: "" };
this.postEvent.Body = this.eventBody;
this.initializeData()
if (this.postEvent.Attendees != null) {
this.postEvent.Attendees.forEach(e => {
if (e.IsRequired) {
this.taskParticipants.push(e as any);
} else {
this.taskParticipantsCc.push(e);
}
})
}
console.log('Attendes', this.taskParticipants)
this.taskParticipants = removeDuplicate(this.taskParticipants);
this.taskParticipantsCc = removeDuplicate(this.taskParticipantsCc);
this.setIntervenient.emit(this.taskParticipants);
this.setIntervenientCC.emit(this.taskParticipantsCc);
this.setDefaultTime();
this.fetchContacts("")
}
this.injectValidation();
this.changeAgenda()
}
initializeData() {
this.postEvent = {
EventId: '',
Subject: '',
Body: this.eventBody,
Location: '',
CalendarId: '',
CalendarName: 'Oficial',
StartDate: this.autoStartTime,
EndDate: this.autoEndTime,
EventType: 'Reunião',
Attendees: this.attendees || null,
IsMeeting: false,
IsRecurring: false,
AppointmentState: 0,
TimeZone: '',
Organizer: '',
Category: 'Meeting',
HasAttachments: false,
EventRecurrence: {
frequency: this.eventRecurence, until: "",
Type: ''
},
}
}
setDefaultTime() {
this.postEvent.StartDate = this.roundTimeQuarterHour(this.CalendarDate);
this.postEvent.EndDate = this.roundTimeQuarterHourPlus15(this.postEvent.StartDate);
}
roundTimeQuarterHour(timeToReturn = new Date()): Date {
let date = new Date(timeToReturn) || new Date();
let newdate = new Date();
const minutes = newdate.getMinutes();
date.setHours(newdate.getHours())
date.setSeconds(0);
if (minutes % 15 != 0) {
if (minutes > 45) {
date.setMinutes(60)
} else if (minutes > 30) {
date.setMinutes(45)
} else if (minutes > 15) {
date.setMinutes(30)
} else if (minutes > 0) {
date.setMinutes(15)
}
}
return date
}
roundTimeQuarterHourPlus15(date: Date) {
const _date = new Date(date);
const minutes = _date.getMinutes();
_date.setMinutes(minutes + 15)
return _date
}
roundTimeQuarterHour1(timeToReturn) {
let date: any = new Date(timeToReturn) || new Date();
const minutes = date.getMinutes();
date.setSeconds(0);
if ((minutes % 15) != 0) {
let a = (Math.floor(minutes / 15) + 1) * 15
date.setMinutes(a)
}
return date
}
setStartDate() {
// this.postEvent.StartDate = this.roundTimeQuarterHour();
}
setEndDate() {
// this.postEvent.EndDate = this.postEvent.StartDate;
}
runValidation() {
this.validateFrom = true;
if (new Date(this.postEvent.StartDate).getTime() > new Date(this.postEvent.EndDate).getTime()) {
this.toastService._badRequest("A data de fim não pode ser inferior a data de início do evento")
}
}
injectValidation() {
/* if (typeof (this.postEvent.EventRecurrence.Type) == 'number') {
const str: any = this.postEvent.EventRecurrence.Type.toString()
this.postEvent.EventRecurrence.Type = str
} */
this.Form = new FormGroup({
Subject: new FormControl(this.postEvent.Subject, [
Validators.required,
// Validators.minLength(4)
]),
Location: new FormControl(this.postEvent.Location, [
Validators.required,
]),
CalendarName: new FormControl(this.postEvent.CalendarName),
Categories: new FormControl(this.postEvent.Category, [
Validators.required
]),
dateStart: new FormControl(this.postEvent.StartDate, [
Validators.required
]),
dateEnd: new FormControl(this.postEvent.EndDate, [
Validators.required
]),
/* dateOccurrence: new FormControl(this.postEvent.EventRecurrence.Type.toString() == '-1' ? ['ok'] : this.postEvent.EventRecurrence.LastOccurrence && new Date(this.postEvent.EventRecurrence.LastOccurrence).getTime() > new Date(this.postEvent.EndDate).getTime() ? 'ok' : null, [
Validators.required
]), */
participantes: new FormControl(this.taskParticipants, [
Validators.required
]),
Date: new FormControl(new Date(this.postEvent.StartDate).getTime() < new Date(this.postEvent.EndDate).getTime() ? 'ok' : null, [
Validators.required
]),
})
}
openFim() {
let input: any = document.querySelector('#new-fim')
if (input) {
input.click()
}
}
changeSegmentCalendar() {
this.hasChangeCalendar = true
}
async changeAgenda() {
this.CalendarNameShow = false
const result = await this.agendaDataRepository.geCalendars()
const selectedCalendar = result.find(e => e.wxUserId == this.selectedUserCalendar)
if(selectedCalendar) {
if(selectedCalendar.shareType == 1) {
this.CalendarNamesOptions = ['Oficial']
} else if(selectedCalendar.shareType == 2) {
this.CalendarNamesOptions = ['Pessoal']
} else if (selectedCalendar.shareType == 3) {
this.CalendarNamesOptions = ['Oficial', 'Pessoal']
}
}
}
// openLastOccurrence() {
// let input: any = document.querySelector('#last-occurrence')
// if (input) {
// input.click()
// }
// }
async getDoc() {
const modal = await this.modalController.create({
component: SearchPage,
cssClass: 'modal-width-100-width-background modal',
componentProps: {
type: 'AccoesPresidenciais & ArquivoDespachoElect',
eventAgenda: true,
showSearchInput: true,
select: true
}
});
modal.onDidDismiss().then((res) => {
if (res) {
const data = res.data;
/* let newDocObject: SearchList_v2 = {
docId: parseInt(data.selected.Id),
sourceName: data.selected.Assunto,
description: "",
applicationId: data.selected.ApplicationType
} */
console.log('get doc', data)
this.documents.push(data.selected);
console.log('pushed')
}
});
await modal.present();
}
close() {
this.deleteTemporaryData();
this.clearContact.emit();
this.setIntervenient.emit([]);
this.setIntervenientCC.emit([]);
// chat exit
this.backToChat.emit({ roomId: this.roomId })
// agenda exit
this.cloneAllmobileComponent.emit({})
}
getRecurrenceTypes() {
this.eventService.getRecurrenceTypes().subscribe(res => {
this.recurringTypes = res;
});
}
calculetedLastOccurrence(type: number) {
var valor;
var opcao: boolean;
if (type == 0) {
valor = 7;
opcao = true;
} else if (type == 1) {
valor = 30;
opcao = true;
} else if (type == 2) {
valor = 1;
opcao = false;
} else if (type == 3) {
valor = 5;
opcao = false;
}
this.defineLastOccurrence(valor, opcao);
}
defineLastOccurrence(valor: number, opcao: boolean) {
var time = new Date(this.postEvent.EndDate);
if (opcao == true) {
time.setDate(time.getDate() + valor);
this.postEvent.EventRecurrence.LastOccurrence = time;
} else {
time = new Date(
time.getFullYear() + valor,
time.getMonth(),
time.getDate(),
time.getHours(),
time.getMinutes()
);
this.postEvent.EventRecurrence.LastOccurrence = time;
}
}
@XTracerAsync({name:'desktop/create-event', bugPrint: true})
async save_v2(tracing?: TracingType) {
this.injectValidation()
this.runValidation()
if (this.Form.invalid) {
if (new Date(this.postEvent.StartDate).getTime() < new Date(this.postEvent.EndDate).getTime()) {
this.toastService._badRequest("Data de inicio menor que a data de fim")
}
return false
}
let loader = this.toastService.loading();
this.postEvent.Attendees = this.taskParticipants.concat(this.taskParticipantsCc) as any
this.postEvent.IsAllDayEvent = this.allDayCheck;
const calendar = await this.agendaDataRepository.getCalendarByUserId(this.selectedUserCalendar)
if(calendar.isOk()) {
const value = await this.agendaDataRepository.createEvent(this.postEvent, this.documents, calendar.value, tracing)
if(value.isOk()) {
console.log(value)
this.afterSave();
this.hhtpErrorHandle.httpsSucessMessagge('new event')
loader.remove();
tracing.setAttribute('outcome', 'success')
} else {
console.log('create event error: ', value.error)
tracing.setAttribute('outcome', 'failed')
loader.remove();
this.hhtpErrorHandle.httpStatusHandle(value.error.status)
}
} else {}
}
afterSave() {
this.deleteTemporaryData();
this.onAddEvent.emit(Object.assign(this.postEvent, {
roomId: this.roomId
}));
this.GoBackEditOrAdd.emit();
this.setIntervenient.emit([]);
this.setIntervenientCC.emit([]);
}
removeAttachment(index: number) {
this.documents = this.documents.filter((e, i) => index != i);
}
async addParticipants() {
this.saveTemporaryData();
this.openAttendeesComponent.emit({
type: "intervenient"
});
this.clearContact.emit();
this.mostrarModal = true;
}
async addParticipantsCc() {
this.saveTemporaryData();
this.openAttendeesComponent.emit({
type: "CC"
});
this.clearContact.emit();
}
saveTemporaryData() {
window['temp.path:/home/agenda/new-event.component.ts'] = {
postEvent: this.postEvent,
eventBody: this.eventBody,
allDayCheck: this.allDayCheck,
segment: this.segment,
CalendarName: this.CalendarName,
documents: this.documents,
selectedUserCalendar: this.selectedUserCalendar,
hasChangeCalendar: this.hasChangeCalendar
}
}
/**
*
* @description o pipeline já esta a funcionar tuda vez que nos fazer push na branch master e test o pipeline executa os teste, mas agora os teste temos que melhora para testar a app em tudos os pontos
* o pipeline já está a funcionar toda vez que nos fazer um push na branch master ou teste o pipeline executa os testes, mas agora os testes temos que melhorar para testar a app em todos os pontos
*/
restoreTemporaryData(): boolean {
const restoredData = window['temp.path:/home/agenda/new-event.component.ts']
if (JSON.stringify(restoredData) != "{}" && undefined != restoredData) {
this.postEvent = restoredData.postEvent
this.allDayCheck = restoredData.allDayCheck
this.eventBody = restoredData.eventBody
this.segment = restoredData.segment
this.CalendarName = restoredData.CalendarName
this.documents = restoredData.documents
this.selectedUserCalendar = restoredData.selectedUserCalendar
this.hasChangeCalendar = restoredData.hasChangeCalendar
// restore dater for date and hours picker
return true;
} else {
return false
}
}
deleteTemporaryData() {
window['temp.path:/home/agenda/new-event.component.ts'] = {}
}
async fetchContacts(filter: string) {
console.log(this.loggeduser.Profile)
//if(this.taskParticipants.length ==0) {
const result = await this.AgendaService.setDefaultParticipants()
if(result.isOk()) {
if(result.value) {
this.taskParticipants.push(result.value[0]);
this.setIntervenient.emit(result.value);
console.log('Attendes Email', result.value)
}
}
//}
}
onCheckboxChange(event: any) {
if (this.allDayCheck) {
this.postEvent.IsAllDayEvent = this.allDayCheck;
this.postEvent.StartDate = this.setAlldayTime(this.postEvent.StartDate)
this.postEvent.EndDate = this.setAlldayTimeEndDate(this.postEvent.EndDate)
console.log('Recurso ativado!!');
} else {
this.postEvent.IsAllDayEvent = this.allDayCheck;
this.postEvent.EndDate = this.setAlldayTimeEndDateNotAlday(this.postEvent.EndDate)
console.log('Recurso desativado');
}
}
setAlldayTime(timeToReturn) {
let date: any = new Date(timeToReturn) || new Date();
let newdate = new Date();
date.setHours(0)
date.setMinutes(0)
date.setSeconds(0);
return date
}
setAlldayTimeEndDate(timeToReturn) {
let date: any = new Date(timeToReturn) || new Date();
let newdate = new Date();
date.setHours(23)
date.setMinutes(59)
date.setSeconds(0);
return date
}
setAlldayTimeEndDateNotAlday(timeToReturn) {
let date: any = new Date(timeToReturn) || new Date();
let newdate = new Date();
date.setHours(23)
date.setMinutes(0)
date.setSeconds(0);
return date
}
onDateChange(e) {
const cloneDateStartDate = new Date(this.postEvent.StartDate);
const cloneDateEndDate = new Date(this.postEvent.EndDate);
if(cloneDateStartDate.getTime() >= cloneDateEndDate.getTime()) {
cloneDateStartDate.setHours(cloneDateStartDate.getHours() + 1);
this.postEvent.EndDate = cloneDateStartDate
}
}
}
@@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { ViewEventPage } from './view-event.page';
const routes: Routes = [
{
path: '',
component: ViewEventPage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class ViewEventPageRoutingModule {}
@@ -0,0 +1,21 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { ViewEventPageRoutingModule } from './view-event-routing.module';
import { ViewEventPage } from './view-event.page';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
ViewEventPageRoutingModule
],
declarations: [ViewEventPage],
exports: [ViewEventPage]
})
export class ViewEventPageModule {}
@@ -0,0 +1,147 @@
<ion-header class="ion-no-border">
<ion-toolbar class="header-toolbar" >
<div class="main-header px-20" style="overflow: unset !important;">
<div class="title-content d-flex">
<div class="left">
<button class="btn-no-color" (click)="close()">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " slot="end"
src='assets/images/icons-calendar-arrow-left.svg'></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " slot="end"
src='assets/images/theme/gov/icons-calendar-arrow-left.svg'></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " slot="end"
src='assets/images/theme/{{ThemeService.currentTheme}}/icons-calendar-arrow-left.svg'></ion-icon>
</button>
</div>
<div class="middle" (click)="openOptions()">
<p class="title">{{loadedEvent.Subject}}</p>
</div>
<div class="div-icon d-flex align-base">
<button class="btn-no-color" (click)="editEvent()" *ngIf="p.userPermission([p.permissionList.Agenda.creatEvent])">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="edit" slot="end"
src="assets/images/icons-edit.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="edit" slot="end"
src="assets/images/theme/gov/icons-edit.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " class="edit" slot="end"
src="assets/images/theme/{{ThemeService.currentTheme}}/icons-edit.svg"></ion-icon>
</button>
<button class="btn-no-color" (click)="deleteYesOrNo()">
<ion-icon class="delete" name="trash-sharp"></ion-icon>
</button>
<!-- <div class="div-icon" (click)="openOptions()">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/images/theme/blue/icons-menu.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/images/theme/gov/icons-menu.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " src="assets/images/theme/{{ThemeService.currentTheme}}/icons-menu.svg"></ion-icon>
</div>
<div *ngIf="loadedEvent.Subject">
<div (click)="editEvent()">Editar</div>
<div (click)="deleteYesOrNo()">Apagar</div>
<div id="desktop-create-chat-from-event" (click)="openNewGroupPage()">Criar Conversa</div>
</div> -->
</div>
</div>
</div>
</ion-toolbar>
</ion-header>
<ion-content>
<div class="main-content">
<div class="upper-content">
<div class="content-location">
<span class="date">{{loadedEvent.Location}}</span>
<div *ngIf="loadedEvent.Organizer">
<div *ngIf="loadedEvent.owner.wxUserId != sesseionStora.user.UserId || sesseionStora.user.Profile =='PR'">
<span class="label" *ngIf="loadedEvent.CalendarName == 'Oficial' "
style="background-color: #99e47b;">{{loadedEvent.CalendarName}}</span>
<span class="label" *ngIf="loadedEvent.CalendarName == 'Pessoal' "
style="background-color: #958bfc;">{{loadedEvent.CalendarName}}</span>
</div>
<div *ngIf="loadedEvent.owner.wxUserId == sesseionStora.user.UserId && sesseionStora.user.Profile !='PR'">
<span class="label" *ngIf="loadedEvent.CalendarName == 'Oficial' "
style="background-color: #ffb703;">{{loadedEvent.CalendarName}}</span>
<span class="label" *ngIf="loadedEvent.CalendarName == 'Pessoal' "
style="background-color: #f05d5e;">{{loadedEvent.CalendarName}}</span>
</div>
</div>
</div>
<div class="content-details">
<ion-label>
<p>{{customDate}}</p>
<p>{{TimeZoneString}}</p>
<p *ngIf="toDateString(loadedEvent.StartDate) == toDateString(loadedEvent.EndDate)">das
{{loadedEvent.StartDate | date: 'HH:mm'}} às {{loadedEvent.EndDate | date: 'HH:mm'}}</p>
<p *ngIf="toDateString(loadedEvent.StartDate) != toDateString(loadedEvent.EndDate)">{{loadedEvent.StartDate |
date: 'd/M/yy' }} - {{ loadedEvent.EndDate | date: 'dd/M/yy'}} </p>
<p *ngIf="loadedEvent.EventRecurrence">
<span *ngIf="stringToNumber(loadedEvent.EventRecurrence.frequency) == 1">Diário</span>
<span *ngIf="stringToNumber(loadedEvent.EventRecurrence.frequency) == 2">Semanal</span>
<span *ngIf="stringToNumber(loadedEvent.EventRecurrence.frequency) == 3">Mensal</span>
<span *ngIf="stringToNumber(loadedEvent.EventRecurrence.frequency) == 4">Anual</span>
<span *ngIf="!loadedEvent.IsRecurring">(Não se repete)</span>
</p>
<!-- <p >
{{ daysToEnd }} dias para terminar o evento
</p> -->
</ion-label>
</div>
</div>
<div class="line"></div>
<div class="middle-content">
<div *ngIf="loadedEvent.Attendees">
<h5 class="font-17-rem">Intervenientes({{ loadedEvent.Attendees.length }})</h5>
<ion-item class="ion-no-margin ion-no-padding">
<ion-label>
<div *ngFor="let attendee of loadedEvent.Attendees">
<p>{{attendee.Name}}</p>
</div>
</ion-label>
</ion-item>
</div>
<div *ngIf="loadedEvent.Body.Text">
<h5 class="font-17-rem">Detalhes</h5>
<ion-item lines="none" class="ion-no-margin ion-no-padding">
<pre class="text">{{ loadedEvent.Body.Text }} </pre>
</ion-item>
<div class="line"></div>
</div>
</div>
<div *ngIf="loadedEvent.Attachments" class="bottom-content width-100">
<h5 class="font-17-rem">Documentos Anexados({{ loadedEvent.Attachments.length }})</h5>
<ion-list class="width-100">
<li *ngFor="let attach of loadedEvent.Attachments; let i = index" class="width-100" lines="none"
class="ion-no-margin ion-no-padding pa-0">
<ion-label class="width-100 d-flex align-center">
<p class="flex-grow-1 cursor-pointer" (click)="docIndex(i);LoadDocumentDetails()">
<span class="attach-title-item d-block">{{attach.subject || attach.sourceName || attach.SourceName || 'Sem título'}}</span>
<span class="span-left d-block">{{attach.Stakeholders}}</span>
</p>
<div class="d-flex pr-10 cursor-pointer" (click)="docIndex(i);LoadDocumentDetails()">
<span class="span-right">{{ attach.dateEntry | date: 'dd-MM-yyyy HH:mm' }}</span>
</div>
<!-- <div (click)="docIndex(i);LoadDocumentDetails()" class="doc-options">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/images/theme/blue/icons-menu.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' "
src="assets/images/theme/gov/icons-menu.svg"></ion-icon>
</div> -->
</ion-label>
</li>
</ion-list>
</div>
</div>
</ion-content>
@@ -0,0 +1,218 @@
@import '~src/function.scss';
ion-content{
--background:transparent;
--padding-top:0px;
--padding-start: 20px;
--padding-end: 20px;
font-size: rem(18);
overflow: auto;
}
.header-toolbar{
--background:transparent;
--opacity: 1;
}
.main-header{
width: 100%; /* 400px */
height: 100%;
font-family: Roboto;
border-top-left-radius: 25px;
border-top-right-radius: 25px;
background-color: #fff;
padding: 30px 0px 0px 0px;
color:#000;
transform: translate3d(0, 1px, 0);
overflow: auto;
.title-content{
width: 100% !important;
margin: 0px auto;
padding: 0 !important;
background: #fff;
overflow: auto;
.left{
width: 37px;
float: left;
font-size: rem(35);
}
.middle{
width: calc(100% - 138.5px) !important;
padding: 0 !important;
float: left;
margin: 0 !important;
overflow: auto;
p{
margin: 0 !important;
}
}
.header-icon-right{
width: rem(45);
font-size: rem(45);
float: right;
}
.div-icon{
width: fit-content;
height: fit-content;
display: flex;
align-items: flex-start;
justify-content:flex-start;
float: right;
padding: 1px !important;
top: 0 !important;
margin: 0 0 0 15px !important;
}
.div-icon .edit{
font-size: rem(35);
float: left;
}
.div-icon .delete{
padding: 7px;
font-size: rem(21);
color:#fff;
background: #d30606;
border-radius: 20px;
margin-left: 10px;
}
}
.title{
font-size: rem(25);
}
}
.main-content{
width: 100%; /* 400px */
font-family: Roboto;
margin: 0 auto;
background-color: #fff;
padding: 15px 0px 0 0px;
overflow: auto !important;
.upper-content{
width: calc(100%-50px);
margin-left: 50px;
font-size: rem(18);
.content-location{
width: 100%;
margin: 0 auto !important;
padding: 0 !important;
overflow: auto;
.date{
width: calc(100% - 105px);
float: left;
}
.label{
width: fit-content;
border-radius: 20px;
background: var(--label-bg-color);
float: right !important;
padding: 5px 13.5px 5px 13.5px;
color: black;
font-size: rem(14);
}
}
.location-detail{
font-weight: 700;
font-size: rem(18);
float: left;
margin: 5px 5px 5px 0px;
}
.button-calendar-type ion-button{
height: rem(25);
}
.button-edit-event {
width: 140px;
height: 44px;
border-radius: 22.5px;
--background: #e0e9ee;
--color:#061b52;
}
.content-details p{
font-size: rem(16);
}
}
.line{
width: 100% !important;
margin-top: 15px;
border-top: 1px solid #d8d8d8;
}
.middle-content{
width: 100% !important;
overflow: auto;
.middle-content h3, .middle-content p{
font-size: rem(16);
}
}
.bottom-content{
margin: 0 auto;
.bottom-content h3{
font-size: rem(16);
margin: 0 0 0 10px;
}
.attach-document{
font-size: rem(15);
color: var(--title-text-color);
margin: 5px 5px 5px 10px;
padding: 5px;
float: left;
}
.attach-icon{
width: 37px;
font-size: rem(35);
float: left;
}
.attach-title-item{
width: 100%;
font-size: rem(15);
color:#0d89d1;
/* color:var(--title-text-color); */
}
/* SPAN */
.span-left{
float: left;
font-size: rem(15);
}
.span-right{
text-align: right;
float: right;
font-size: rem(13);
}
}
}
.chat-popover .popover-content {
width: 100% !important;
left: 0 !important;
bottom: 0 !important;
right: 0 !important;
bottom: 0px !important;
}
.doc-options {
cursor: pointer;
display: flex;
justify-content: center;
width: rem(35);
height: 41px;
align-items: center;
}
.text {
text-transform: initial !important
}
@@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { ViewEventPage } from './view-event.page';
describe('ViewEventPage', () => {
let component: ViewEventPage;
let fixture: ComponentFixture<ViewEventPage>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ViewEventPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(ViewEventPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,461 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { AlertController, ModalController, PopoverController } from '@ionic/angular';
import { Attachment } from 'src/app/models/attachment.model';
import { EventBody } from 'src/app/models/eventbody.model';
import { EventsService } from 'src/app/services/events.service';
import { Event } from 'src/app/models/event.model';
import { InAppBrowser } from '@ionic-native/in-app-browser/ngx';
import { ProcessesService } from 'src/app/services/processes.service';
import { ToastService } from 'src/app/services/toast.service';
import { EliminateEventPage } from 'src/app/modals/eliminate-event/eliminate-event.page';
import { ExpedientTaskModalPageNavParamsTask } from 'src/app/models/ExpedientTaskModalPage';
import { DocumentSetUpMeetingPage } from 'src/app/modals/document-set-up-meeting/document-set-up-meeting.page';
import { ExpedientTaskModalPage } from 'src/app/pages/gabinete-digital/expediente/expedient-task-modal/expedient-task-modal.page';
import { ViewDocumentPage } from 'src/app/modals/view-document/view-document.page';
import { ThemeService } from 'src/app/services/theme.service';
import { SessionStore } from 'src/app/store/session.service';
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service'
import { NavigationExtras, Router } from '@angular/router';
import { DateService } from 'src/app/services/date.service';
import { AgendaDataRepositoryService } from 'src/app/module/agenda/data/repository/agenda-data-repository.service';
import { SearchList_v2 } from 'src/app/models/search-document';
import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
import { isHttpError } from 'src/app/services/http.service';
import { PermissionService } from 'src/app/services/permission.service';
import { DeleteEventRecurrencePage, EventDeleteRecurrenceComponentReturn } from 'src/app/modals/delete-event-recurrence/delete-event-recurrence.page';
@Component({
selector: 'app-view-event',
templateUrl: './view-event.page.html',
styleUrls: ['./view-event.page.scss'],
})
export class ViewEventPage implements OnInit {
loadedEvent: Event;
isEventEdited: boolean;
eventBody: EventBody;
loadedAttachments:any;
pageId: string;
showLoader: boolean;
task: ExpedientTaskModalPageNavParamsTask;
minDate: Date;
LoadedDocument:any = null;
customDate:any;
today:any;
months = ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"];
days = ["Domingo", "Segunda-feira", "Terça-feira", "Quarta-feira", "Quinta-feira", "Sexta-feira", "Sábado"];
documents: Attachment[] = [];
dicIndex = 0;
@Input() profile:string;
@Input() eventId: string;
@Input() CalendarId: string;
@Output() viewEventDetailDismiss = new EventEmitter<any>();
sesseionStora = SessionStore
TimeZoneString = ''
daysToEnd = 0
constructor(
public eventsService: EventsService,
public alertController: AlertController,
private iab: InAppBrowser,
private processes: ProcessesService,
private modalController: ModalController,
public popoverController: PopoverController,
private toastService: ToastService,
public ThemeService: ThemeService,
private httpErrorHandle: HttpErrorHandle,
private router: Router,
private dateService: DateService,
private agendaDataRepository: AgendaDataRepositoryService,
public p: PermissionService,
) {
this.isEventEdited = false;
this.loadedEvent = new Event();
this.eventBody = { BodyType : "1", Text : ""};
this.loadedEvent.Body = this.eventBody;
}
daysToEndWithJS(startDateStr: any, endDateStr: any) {
// Define the start and end dates
const startDate: any = new Date(startDateStr);
const endDate: any = new Date(endDateStr);
// Calculate the difference in milliseconds between the two dates
const differenceMs = Math.abs(endDate - startDate);
// Convert milliseconds to days
const millisecondsPerDay = 1000 * 60 * 60 * 24;
const differenceDays = Math.ceil(differenceMs / millisecondsPerDay);
console.log(`Number of days between the dates: ${differenceDays}`);
return differenceDays
}
deferenceBetweenDays(start: any, end: any) {
start.setHours(0, 0, 0, 0);
end.setHours(0, 0, 0, 0);
const diffTime = Math.abs(end - start);
return Math.ceil(diffTime / (1000 * 60 * 60 * 24));
}
ngOnInit() {
this.loadEvent();
}
doRefresh(ev) {
this.loadEvent();
ev.target.complete();
}
ngOnChanges(changes: any): void {
this.loadedEvent.Attachments = null;
this.loadEvent();
}
toDateString(e) {
return new Date(e).toString()
}
openOptions() {
}
docIndex(index: number) {
this.dicIndex = index;
}
close() {
this.viewEventDetailDismiss.emit({
type: 'close'
})
}
setTimeZone() {
this.TimeZoneString = this.loadedEvent.TimeZone
}
@XTracerAsync({name:'desktop/event-details', bugPrint: true})
async loadEvent(tracing?: TracingType) {
let res = await this.agendaDataRepository.getEventById(this.eventId, tracing)
if(res.isOk()) {
tracing.setAttribute('outcome', 'success')
/* let changeDate = this.dateService.fixDate(res.value as any) as any */
this.loadedEvent = res.value as any;
console.log('this.loadedEvent', this.loadedEvent)
if(new Date().getTime() <= new Date(this.loadedEvent.EndDate).getTime()) {
if(this.deferenceBetweenDays(new Date(), new Date(this.loadedEvent.EndDate))) {
this.daysToEnd = this.daysToEndWithJS(new Date(this.loadedEvent.StartDate), new Date(this.loadedEvent.EndDate))
} else {
this.daysToEnd = 0
}
} else {
this.daysToEnd = 0
}
this.setTimeZone()
} else {
tracing.setAttribute('eventId', this.eventId)
if(!isHttpError(res.error)) {
this.toastService._badRequest('Pedimos desculpa mas não foi possível executar a acção. Por favor, contacte o apoio técnico. #133')
console.log(res.error)
} else if (isHttpError(res.error)) {
if(res.error.status == 404) {
this.toastService._badRequest('Este evento já não existe')
} else {
this.httpErrorHandle.httpStatusHandle(res.error)
}
}
tracing.setAttribute('outcome', 'failed')
this.viewEventDetailDismiss.emit({
type: 'close'
})
}
}
async deleteYesOrNo() {
if (this.loadedEvent.IsRecurring) {
const modal = await this.modalController.create({
component: DeleteEventRecurrencePage,
componentProps: {},
cssClass: 'event-recurrence-modal',
});
modal.onDidDismiss().then((res) => {
const data: EventDeleteRecurrenceComponentReturn = res.data
if(data =='DeleteAll') {
this.deleteEvent_v2(true);
} else if (data == 'DeleteOne') {
this.deleteEvent_v2(false);
} else if(data == 'Cancel') {
this.close()
} else {
this.close()
}
});
await modal.present();
} else {
this.alertController.create({
header: 'Eliminar evento?',
message: '',
buttons: [
{
text: 'Sim',
handler: () => {
this.deleteEvent_v2(false);
}
},
{
text: 'Não',
handler: () => {
}
}
]
}).then(res => {
res.present();
})
}
}
async deleteEvent_v2(deleteAll) {
console.log(this.loadedEvent.EventId)
const loader = this.toastService.loading()
const value = await this.agendaDataRepository.deleteEvent(this.loadedEvent.EventId,deleteAll)//.subscribe(() => {
if(value.isOk()) {
console.log(value.value)
this.httpErrorHandle.httpsSucessMessagge('delete event')
this.close();
} else {
console.log('delete event error: ', value.error)
this.httpErrorHandle.httpStatusHandle(value.error)
}
loader.remove();
}
// async deleteEvent() {
// if (this.loadedEvent.IsRecurring) {
// const loader = this.toastService.loading()
// if(this.sesseionStora.user.Profile == 'MDGPR' || this.sesseionStora.user.Profile == 'PR') {
// this.eventsService.deleteEvent(this.loadedEvent.EventId, 0, this.loadedEvent.CalendarName).subscribe(async () => {
// this.httpErrorHandle.httpsSucessMessagge('delete event')
// this.close();
// },(error)=>{
// this.httpErrorHandle.httpStatusHandle(error)
// },
// ()=>{
// loader.remove();
// });
// } else {
// if(this.CalendarId) {
// this.eventsService.genericDeleteEvent(this.loadedEvent.EventId, 0, this.loadedEvent.CalendarName, this.CalendarId).subscribe(async () => {
// this.httpErrorHandle.httpsSucessMessagge('delete event');
// this.close();
// },(error)=>{
// this.httpErrorHandle.httpStatusHandle(error)
// },
// ()=>{
// loader.remove();
// });
// }
// }
// } else {
// const loader = this.toastService.loading()
// if(this.sesseionStora.user.Profile == 'MDGPR' || this.sesseionStora.user.Profile == 'PR') {
// this.eventsService.deleteEvent(this.loadedEvent.EventId, 0, this.loadedEvent.CalendarName).subscribe(async () => {
// this.httpErrorHandle.httpsSucessMessagge('delete event');
// this.close();
// },(error)=>{
// this.httpErrorHandle.httpStatusHandle(error)
// },
// ()=>{
// loader.remove();
// });
// } else {
// this.eventsService.genericDeleteEvent(this.loadedEvent.EventId, 0, this.loadedEvent.CalendarName, this.CalendarId).subscribe(async () => {
// this.httpErrorHandle.httpsSucessMessagge('delete event');
// this.close();
// },(error)=>{
// this.httpErrorHandle.httpStatusHandle(error)
// },
// ()=>{
// loader.remove();
// });
// }
// }
// }
async deleteRecurringEvent() {
const modal = await this.modalController.create({
component: EliminateEventPage,
componentProps: {},
cssClass: 'discart-expedient-modal',
});
modal.onDidDismiss().then((res) => {
});
await modal.present();
}
async editEvent() {
this.viewEventDetailDismiss.emit({
type: 'edit',
event: this.loadedEvent
})
}
viewDocument(sourceId) {
this.processes.GetDocumentUrl(sourceId, '8').subscribe(res=>{
const url: string = res.replace("webTRIX.Viewer","webTRIX.Viewer.Branch1");
const browser = this.iab.create(url,"_blank");
browser.show();
});
}
async LoadDocumentDetails() {
const docId = this.loadedEvent.Attachments[ this.dicIndex].SourceId
const applicationId: any = this.loadedEvent.Attachments[ this.dicIndex].ApplicationId
const selectedDoc = this.loadedEvent.Attachments[ this.dicIndex]
this.task = {
serialNumber: '',
taskStartDate: '',
isEvent: true,
workflowInstanceDataFields: {
FolderID: '',
Subject: selectedDoc.SourceName,
SourceSecFsID: selectedDoc.ApplicationId || selectedDoc['ApplicationID'],
SourceType: 'DOC',
SourceID: selectedDoc.SourceId,
DispatchNumber: ''
}
}
const modal = await this.modalController.create({
component: ViewDocumentPage,
componentProps: {
trustedUrl: '',
file: {
title: this.task.workflowInstanceDataFields.Subject,
url: '',
title_link: '',
},
Document: this.loadedEvent.Attachments[ this.dicIndex],
applicationId: this.task.workflowInstanceDataFields.SourceSecFsID,
docId: selectedDoc.SourceId,
folderId: '',
task: this.task
},
cssClass: 'modal modal-desktop'
});
await modal.present();
}
async openBookMeetingModal() {
let classs;
if( window.innerWidth < 701) {
classs = 'book-meeting-modal modal modal-desktop'
} else {
classs = 'modal modal-desktop showAsideOptions'
}
const modal = await this.modalController.create({
component: DocumentSetUpMeetingPage,
componentProps: {
subject: this.task.workflowInstanceDataFields.Subject,
document: this.loadedEvent.Attachments[ this.dicIndex],
},
cssClass: classs,
backdropDismiss: false
});
modal.onDidDismiss().then(res=>{
//this.RouteService.goBack();
});
await modal.present();
}
// efetuar despacho
async openExpedientActionsModal( taskAction: any) {
let classs;
if( window.innerWidth < 701) {
classs = 'modal modal-desktop'
} else {
classs = 'modal modal-desktop showAsideOptions'
}
const modal = await this.modalController.create({
component: ExpedientTaskModalPage,
componentProps: {
taskAction: taskAction,
task: this.task,
seachDocuments: this.loadedEvent.Attachments[ this.dicIndex],
aplicationId: this.loadedEvent.Attachments[ this.dicIndex].ApplicationId || this.loadedEvent.Attachments[ this.dicIndex]['ApplicationID']
},
cssClass: classs,
});
modal.onDidDismiss().then( async(res)=>{});
await modal.present();
}
stringToNumber(number: string) {
return parseInt(number)
}
}
@@ -0,0 +1,16 @@
import { CalendarDateFormatter, DateFormatterParams } from 'angular-calendar';
import { formatDate } from '@angular/common';
import { Injectable } from '@angular/core';
@Injectable()
export class CustomDateFormatter extends CalendarDateFormatter {
// you can override any of the methods defined in the parent class
public dayViewHour({ date, locale }: DateFormatterParams): string {
return formatDate(date, 'HH', locale);
}
public weekViewHour({ date, locale }: DateFormatterParams): string {
return this.dayViewHour({ date, locale });
}
}
@@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { EditEventPage } from './edit-event.page';
const routes: Routes = [
{
path: '',
component: EditEventPage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class EditEventPageRoutingModule {}
@@ -0,0 +1,50 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { EditEventPageRoutingModule } from './edit-event-routing.module';
import { EditEventPage } from './edit-event.page';
import { AttendeeModalPageModule } from 'src/app/shared/event/attendee-modal/attendee-modal.module';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatInputModule } from '@angular/material/input';
import { MatNativeDateModule } from '@angular/material/core';
import {
NgxMatDatetimePickerModule,
NgxMatNativeDateModule,
NgxMatTimepickerModule
} from '@angular-material-components/datetime-picker';
import { ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatSelectModule } from '@angular/material/select';
import { NgxMatMomentModule } from '@angular-material-components/moment-adapter';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
EditEventPageRoutingModule,
MatDatepickerModule,
MatInputModule,
MatNativeDateModule,
NgxMatDatetimePickerModule,
NgxMatTimepickerModule,
NgxMatNativeDateModule,
NgxMatMomentModule,
MatSelectModule,
MatButtonModule,
ReactiveFormsModule,
//
AttendeeModalPageModule
],
declarations: [
EditEventPage
]
})
export class EditEventPageModule {}
@@ -0,0 +1,515 @@
<ion-content>
<!-- Edit event for Inicio -->
<div class="main-content height-100">
<div class="content d-flex flex-column width-md-100 height-100">
<div class="main-header pt-30 px-20 background-white pb-15">
<ion-header>
<div class="title-content">
<div class="middle">
<ion-label id="vsdfajnl" class="title" style="font-size: 21.1px">Editar Evento</ion-label>
</div>
</div>
</ion-header>
</div>
<ion-item-sliding class="overflow-y-auto">
<div class="px-20">
<div class="ion-item-container width-100" [class.input-error]="Form?.get('Subject')?.invalid && validateFrom ">
<ion-input autocomplete="on" autocorrect="on" spellcheck="true" placeholder="Assunto*" [(ngModel)]="postEvent.Subject"></ion-input>
</div>
<div *ngIf="Form && validateFrom" >
<div *ngIf="Form.get('Subject').invalid " class="input-errror-message">
<!-- <div *ngIf="Form.get('Subject').errors?.required">
</div> -->
<div *ngIf="Form.get('Subject').errors?.minlength">
O campo deve ter pelo menos 4 caracteres.
</div>
</div>
</div>
<div *ngIf="(sharedCalendar | async) as calendarData" class="container-div width-100" >
<div class="ion-item-class-2 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1 justify-center align-center material-inputs " [class.input-error]="Form?.get('CalendarName')?.invalid && validateFrom ">
<mat-form-field appearance="none" class="width-100" color="ion-color-secondary" placeholder="Selecione agenda">
<div *ngIf="selectedUserCalendar == SessionStore.user.UserId && !hasChangeCalendar && SessionStore.user.Profile != 'PR' " style="margin-bottom: -20px;">
Minha agenda
</div>
<div *ngIf="!(selectedUserCalendar == SessionStore.user.UserId && SessionStore.user.Profile != 'PR' ) && !hasChangeCalendar" style="margin-bottom: -20px;">
PR
</div>
<mat-select [(value)]="selectedUserCalendar" (selectionChange)="changeAgenda();changeSegmentCalendar()">
<mat-option *ngFor="let calendars of calendarData" value="{{calendars.wxUserId}}">
<div *ngIf="calendars.roleId == RoleIdService.PRES">PR </div>
<div *ngIf="calendars.roleId == RoleIdService.MD && calendars.roleId != SessionStore.user.RoleID">AGENDA DO MDGPR</div>
<div *ngIf="calendars.roleId != RoleIdService.MD && calendars.roleId != RoleIdService.PRES && calendars.wxFullName && calendars.wxUserId != SessionStore.user.UserId"> Agenda do {{calendars.wxFullName}} </div>
<div *ngIf="calendars.wxUserId == SessionStore.user.UserId && SessionStore.user.Profile != 'PR'">
Minha agenda
</div>
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
<div class="container-div width-100">
<div class="ion-item-class-2">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-location.svg"></ion-icon>
</div>
<div class="ion-input-class" [class.input-error]="Form?.get('Location')?.invalid && validateFrom ">
<ion-input autocomplete="on" autocorrect="on" spellcheck="true" placeholder="Localização*" [(ngModel)]="postEvent.Location"></ion-input>
</div>
</div>
</div>
<div *ngIf="Form && validateFrom" >
<div *ngIf="Form.get('Location').invalid " class="input-errror-message">
<div *ngIf="Form.get('Location').errors?.required">
</div>
<div *ngIf="Form.get('Location').errors?.minlength">
O campo deve ter pelo menos 4 caracteres.
</div>
</div>
</div>
<div class="container-div width-100">
<div class="ion-item-class-2 width-100 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1 width-100">
<mat-form-field appearance="none" floatLabel="never" class="width-100 " >
<mat-select [(value)]="postEvent.CalendarName" class="width-100" [disabled]=false>
<mat-option *ngFor="let calendars of CalendarNamesOptions" value="{{calendars}}">
Agenda {{ calendars }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="Form && validateFrom" >
<div *ngIf="Form.get('CalendarName').invalid " class="input-errror-message">
{{ postEvent.Category }}
<div *ngIf="Form.get('CalendarName').errors?.required">
</div>
</div>
</div>
<div class="container-div width-100">
<div class="ion-item-class-2 width-100 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1" [class.input-error]="Form?.get('Categories')?.invalid && validateFrom ">
<mat-form-field appearance="none" floatLabel="never" class="width-100" required>
<!-- <input matInput type="text" > -->
<mat-select placeholder="Selecione o tipo de evento*" matInput [(ngModel)]="postEvent.Category" >
<mat-option value="Meeting">
Reunião
</mat-option>
<mat-option value="Travel">
Viagem
</mat-option>
<mat-option value="Conference">
Conferência
</mat-option>
<mat-option value="Encontro">
Encontro
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="Form && validateFrom" >
<div *ngIf="Form.get('Categories').invalid " class="input-errror-message">
{{ postEvent.Category}}
<div *ngIf="Form.get('Categories').errors?.required">
</div>
</div>
</div>
<div class="container-div width-100">
<div>
<ion-item>
<ion-label>Todo dia</ion-label>
<ion-checkbox [(ngModel)]="allDayCheck" (ionChange)="onCheckboxChange($event)"></ion-checkbox>
</ion-item>
</div>
</div>
<div class="container-div" *ngIf="postEvent?.EventRecurrence?.frequency">
<div class="ion-item-class-2 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-reapet.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1 justify-center align-center material-inputs">
<mat-form-field appearance="none" class="width-100" placeholder="Sample Type" required>
<!-- <input matInput type="text" > -->
<mat-select [(value)]="postEvent.EventRecurrence.frequency" >
<mat-option value="never">
Nunca
</mat-option>
<mat-option value="daily">
Diário
</mat-option>
<mat-option value="weekly">
Semanalmente
</mat-option>
<mat-option value="monthly">
Mensal
</mat-option>
<mat-option value="yearly">
Anual
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="postEvent?.EventRecurrence?.frequency != 'never'" class="container-div">
<div class="ion-item-class-2 d-flex" >
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-reapet.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1 justify-center align-center material-inputs materia-top" >
<mat-form-field appearance="none" class="date-hour-picker">
<input matInput [ngxMatDatetimePicker]="picker1"
placeholder="Data Fim de Recorrência*"
[(ngModel)]="postEvent.EventRecurrence.until"
[disabled]="disabled"
>
<mat-datepicker-toggle id="new-inicio" matSuffix [for]="picker1" ></mat-datepicker-toggle>
<ngx-mat-datetime-picker #picker1
[showSpinners]="showSpinners"
[showSeconds]="showSeconds"
[stepHour]="stepHour" [stepMinute]="stepMinute"
[stepSecond]="stepSecond"
[touchUi]="touchUi"
[hideTime]="true"
>
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="allDayCheck" class="container-div width-100">
<div class="ion-item-class-2 width-100">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class" [class.input-error]="Form?.get('Date')?.invalid && validateFrom ">
<mat-form-field appearance="none" floatLabel="never" class="date-hour-picker">
<input matInput [ngxMatDatetimePicker]="picker1"
placeholder="Choose a date"
[(ngModel)]="postEvent.StartDate"
[max]="maxDate"
[disabled]="disabled"
(ngModelChange)="onDateChange($event)"
>
<mat-datepicker-toggle id="new-inicio" matSuffix [for]="picker1"></mat-datepicker-toggle>
<ngx-mat-datetime-picker #picker1
[showSpinners]="showSpinners"
[showSeconds]="showSeconds"
[stepHour]="stepHour" [stepMinute]="stepMinute"
[stepSecond]="stepSecond"
[touchUi]="touchUi"
[hideTime]="true">
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="!allDayCheck" class="container-div width-100">
<div class="ion-item-class-2 width-100">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class" [class.input-error]="Form?.get('Date')?.invalid && validateFrom ">
<mat-form-field appearance="none" floatLabel="never" class="date-hour-picker">
<input matInput [ngxMatDatetimePicker]="picker1"
placeholder="Choose a date"
[(ngModel)]="postEvent.StartDate"
[max]="maxDate"
[disabled]="disabled"
(ngModelChange)="onDateChange($event)"
>
<mat-datepicker-toggle id="new-inicio" matSuffix [for]="picker1"></mat-datepicker-toggle>
<ngx-mat-datetime-picker #picker1
[showSpinners]="showSpinners"
[showSeconds]="showSeconds"
[stepHour]="stepHour" [stepMinute]="stepMinute"
[stepSecond]="stepSecond"
[touchUi]="touchUi"
[hideTime]="false">
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="allDayCheck" class="container-div width-100">
<div class="ion-item-class-2 width-100 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1" [class.input-error]="Form?.get('Date')?.invalid && validateFrom ">
<mat-form-field appearance="none" floatLabel="never" floatLabel="never" class="date-hour-picker">
<input matInput [ngxMatDatetimePicker]="fim"
placeholder="Choose a date"
[(ngModel)]="postEvent.EndDate"
[min]="postEvent.StartDate"
[max]="maxDate"
[disabled]="disabled"
>
<mat-datepicker-toggle id="new-fim" matSuffix [for]="fim"></mat-datepicker-toggle>
<ngx-mat-datetime-picker #fim
[showSpinners]="showSpinners"
[showSeconds]="showSeconds"
[stepHour]="stepHour" [stepMinute]="stepMinute"
[stepSecond]="stepSecond"
[hideTime]="true">
>
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="!allDayCheck" class="container-div width-100">
<div class="ion-item-class-2 width-100 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1" [class.input-error]="Form?.get('Date')?.invalid && validateFrom ">
<mat-form-field appearance="none" floatLabel="never" floatLabel="never" class="date-hour-picker">
<input matInput [ngxMatDatetimePicker]="fim"
placeholder="Choose a date"
[(ngModel)]="postEvent.EndDate"
[min]="postEvent.StartDate"
[max]="maxDate"
[disabled]="disabled"
>
<mat-datepicker-toggle id="new-fim" matSuffix [for]="fim"></mat-datepicker-toggle>
<ngx-mat-datetime-picker #fim
[showSpinners]="showSpinners"
[showSeconds]="showSeconds"
[stepHour]="stepHour" [stepMinute]="stepMinute"
[stepSecond]="stepSecond"
[hideTime]="false">
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="selectedRecurringType != '-1'" class="container-div width-100">
<div class="ion-item-class-2 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div (click)="openLastOccurrence()" class="ion-input-class flex-grow-1">
<mat-form-field class="date-hour-picker">
<input matInput [ngxMatDatetimePicker]="occurrrence"
placeholder="Choose a date"
[(ngModel)]="postEvent.EventRecurrence.LastOccurrence"
[disabled]="disabled"
[min]="postEvent.EndDate"
>
<mat-datepicker-toggle id="last-occurrence" matSuffix [for]="occurrrence"></mat-datepicker-toggle>
<ngx-mat-datetime-picker #occurrrence
[showSpinners]="showSpinners"
[showSeconds]="showSeconds"
[stepHour]="stepHour" [stepMinute]="stepMinute"
[stepSecond]="stepSecond"
[touchUi]="touchUi"
>
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
</div>
</div>
<div class="container-div width-100">
<div (click)="addParticipants()" class="ion-item-class-2 cursor-pointer">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-person.svg"></ion-icon>
</div>
<div class="ion-input-class-no-height d-flex" [class.input-error]="Form?.get('participantes')?.invalid && validateFrom">
<div class="list-people flex-grow-1">
<ion-item lines="none">
<ion-list>
<ion-label *ngIf="taskParticipants?.length < 1" class="list-people-title">Adicionar Intervenientes*</ion-label>
<ion-label *ngFor="let participant of taskParticipants">{{participant.Name}}</ion-label>
</ion-list>
</ion-item>
</div>
<div class="add-people">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " slot="start" src="assets/images/icons-arrow-forward.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " slot="start" src="assets/images/theme/gov/icons-arrow-forward.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " slot="start" src="assets/images/theme/{{ThemeService.currentTheme}}/icons-arrow-forward.svg"></ion-icon>
</div>
</div>
</div>
</div>
<div class="container-div width-100">
<div (click)="addParticipantsCC()" class="ion-item-class-2 cursor-pointer">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-people-cc.svg"></ion-icon>
</div>
<div class="ion-input-class-no-height d-flex">
<div class="list-people flex-grow-1">
<ion-item lines="none">
<ion-list>
<ion-label *ngIf="taskParticipantsCc?.length < 1" class="list-people-title">Com Conhecimento</ion-label>
<ion-label *ngFor="let participant of taskParticipantsCc">{{participant.Name}}</ion-label>
</ion-list>
</ion-item>
</div>
<div class="add-people">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " slot="start" src="assets/images/icons-arrow-forward.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " slot="start" src="assets/images/theme/gov/icons-arrow-forward.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " slot="start" src="assets/images/theme/{{ThemeService.currentTheme}}/icons-arrow-forward.svg"></ion-icon>
</div>
</div>
</div>
</div>
<div class="container-div width-100">
<div class="ion-item-class-2 d-flex width-100">
<div class="ion-icon-class d-flex">
<ion-icon slot="start" src="assets/images/icons-description.svg"></ion-icon>
</div>
<div class="ion-input-class-no-height width-100 flex-grow-1">
<!-- rows="6" cols="20" -->
<ion-textarea class="heigh-200" autocomplete="on" autocorrect="on" spellcheck="true" [(ngModel)]="postEvent.Body.Text" placeholder="Detalhes" ></ion-textarea>
</div>
</div>
</div>
<div class="d-flex container-div width-100 ion-item-container-no-border" >
<ion-label (click)="getDoc()" class="cursor-pointer">
<div class="attach-icon">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' "src="assets/images/icons-attach-doc.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/images/theme/gov/icons-attach-doc.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " src="assets/images/theme/{{ThemeService.currentTheme}}/icons-attach-doc.svg"></ion-icon>
</div>
<div class="attach-document">
<ion-label>Adicionar documentos</ion-label>
</div>
</ion-label>
</div>
<div class="d-flex container-div width-100" *ngFor="let document of loadedEventAttachments; let i = index" >
<ion-list class="width-100 list">
<ion-item class="width-100 ion-no-border ion-no-padding">
<ion-label class="width-100">
<p class="p-item-title d-flex ion-justify-content-between">
<span class="attach-title-item">{{document.subject || document.SourceName || document.sourceName}}</span>
<span class="close-button text-black" (click)="deleteAttachment(document.Id, i)" >
<ion-icon class="font-20" src="assets/images/icons-delete-25.svg"></ion-icon>
</span>
</p>
<!-- <p *ngIf="document.Stakeholders" ><span class="span-left" >{{document.Stakeholders}}</span></p> -->
<p>
<span class="app-name span-left" *ngIf="document.applicationId == 8 || document.ApplicationId == 8"> Correspondência </span>
<span class="app-name span-left" *ngIf="document.applicationId == 386 || document.ApplicationId == 386"> Acções Presidenciais </span>
<span class="app-name span-left" *ngIf="document.applicationId == 361 || document.ApplicationId == 361 "> Arquivo Despacho Electrónico </span>
</p>
</ion-label>
</ion-item>
</ion-list>
</div>
</div>
</ion-item-sliding>
</div>
<app-attendee-modal class="aside-right flex-column height-100 d-none d-md-flex pt-10"
*ngIf="showAttendees"
[footer]="false"
[taskParticipants]="taskParticipants"
[taskParticipantsCc]="taskParticipantsCc"
[adding]="adding"
[footer]="false"
(dynamicSetIntervenient)="dynamicSetIntervenient($event)"
></app-attendee-modal>
</div>
</ion-content>
<ion-footer class="ion-no-border">
<ion-toolbar class="footer-toolbar px-20">
<ion-buttons slot="start">
<button class="btn-ok" fill="clear" color="#fff" (click)="save_v2()">
<ion-label>Gravar</ion-label>
</button>
</ion-buttons>
<ion-buttons slot="end">
<button class="btn-cancel" fill="clear" color="#061b52" (click)="cancel()">
<ion-label>Cancelar</ion-label>
</button>
</ion-buttons>
</ion-toolbar>
</ion-footer>
@@ -0,0 +1,206 @@
@import '~src/function.scss';
.title-content::after, .header-md::after{
display: none;
}
.content{
margin: 0;
float: left;
border-left: 1px solid #d8d8d8 !important;
}
.main-header{
font-family: Roboto;
background-color: #fff;
overflow:hidden;
transform: translate3d(0, 1px, 0);
.title-content{
margin: 0px auto;
padding: 0 !important;
background: #fff;
.middle{
padding: 0!important;
float: left;
}
}
.title{
font-size: rem(25);
}
}
.ion-item-container{
margin: rem(15) auto;
border: 1px solid #ebebeb;
border-radius: 5px;
padding-left: 10px;
}
.ion-item-container-no-border{
width: 100%;
margin: 0px auto;
padding: 0 !important;
}
.container-div{
margin-bottom: 15px;
float: left;
}
.ion-item-class-2{
margin: 0px auto;
}
.ion-icon-class{
width: rem(45);
height: rem(45);
float: left;
padding: 10px;
font-size: rem(25);
}
ion-select{
padding-left: 5px;
margin-left: 0;
}
.ion-input-class{
width: calc(100% - 45px);
height: rem(45);
border: 1px solid #ebebeb;
border-radius: 5px;
padding-left: 5px;
padding-right: 10px;
float: left;
}
.ion-input-class-no-height{
width: calc(100% - 45px);
border: 1px solid #ebebeb;
border-radius: 5px;
}
.list-people{
float: left;
}
.add-people{
width: rem(45);
float: right;
overflow: auto;
font-size: rem(25);
height: rem(45);
display: flex;
}
.list-people-title{
/* font-size: rem(13); */
color: #a3a3a3;
}
.attach-document{
font-size: rem(15);
color: var(--title-text-color);;
margin: 5px 5px 5px 10px;
padding: 5px;
float: left;
}
.attach-icon{
width: 37px;
font-size: rem(35);
float: left;
}
.attach-title-item{
width: 100%;
font-size: rem(15);
color:var(--title-text-color);
}
/* SPAN */
.span-left{
float: left;
font-size: rem(15);
}
.span-right{
text-align: right;
float: right;
font-size: rem(13);
}
.container-footer{
margin:0 auto;
overflow: auto;
}
.button-cancel {
width: rem(170);
height: rem(44);
border-radius: 22.5px;
--background: #e0e9ee;
--color: #061b52;
margin:10px;
}
.button-save {
width: rem(170);
height: rem(44);
border-radius: 22.5px;
--background: #42b9fe;
--color:#ffffff;
margin:10px;
}
.text-input{
width: 100%;
border: 1px solid #ebebeb;
margin: 0px 15px 15px 0px;
padding: 0 !important;
border-radius: 5px;
}
/* Error Messages */
.error{
color:red;
font-size: rem(12);
font-weight: bold;
padding-bottom: 20px;
}
.span-color{
color:red;
}
.buttons{
display: flex;
justify-content: space-between;
padding: 20px;
overflow: auto;
}
.app-name{
background: var(--title-text-color);
border-radius: 18px;
text-align: center;
display: flex;
align-items: center;
padding: 0px 5px;
color: white;
font-size: rem(12);
font-weight: 500;
height: 19px;
-webkit-border-radius: 18px;
-moz-border-radius: 18px;
-ms-border-radius: 18px;
-o-border-radius: 18px;
}
.close-button {
display: none;
height: 20px;
}
.list:hover {
.app-name {
display: none;
}
.close-button {
display: block !important;
height: 20px;
}
}
@@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { EditEventPage } from './edit-event.page';
describe('EditEventPage', () => {
let component: EditEventPage;
let fixture: ComponentFixture<EditEventPage>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ EditEventPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(EditEventPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,761 @@
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { AlertController, ModalController, NavParams } from '@ionic/angular';
import { Attachment } from 'src/app/models/attachment.model';
import { EventBody } from 'src/app/models/eventbody.model';
import { EventPerson } from 'src/app/models/eventperson.model';
import { AttachmentsService } from 'src/app/services/attachments.service';
import { EventsService } from 'src/app/services/events.service';
import { Event } from '../../../../models/event.model';
import { AttendeesPageModal } from '../../../../pages/events/attendees/attendees.page';
import { SearchPage } from '../../../../pages/search/search.page';
import { ThemeService } from 'src/app/services/theme.service';
import { NgxMatDateFormats } from '@angular-material-components/datetime-picker';
import { NGX_MAT_DATE_FORMATS } from '@angular-material-components/datetime-picker';
import { SessionStore } from 'src/app/store/session.service';
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service'
import { environment } from 'src/environments/environment';
import { AgendaDataRepositoryService } from 'src/app/module/agenda/data/repository/agenda-data-repository.service';
import { TableSharedCalendar } from 'src/app/module/agenda/data/data-source/agenda-local-data-source.service';
import { Observable } from 'rxjs';
import { RoleIdService } from 'src/app/services/role-id.service'
import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
import { EventRecurrencePage, EventRecurrenceComponentReturn } from 'src/app/modals/event-recurrence/event-recurrence.page';
import { Utils } from 'src/app/module/agenda/utils';
import { AttendeesLIstChangeDetector } from 'src/app/module/agenda/data/async/change/attendeesLIstChangeDetector';
const CUSTOM_DATE_FORMATS: NgxMatDateFormats = {
parse: {
dateInput: "YYYY-MMMM-DD HH:mm"
},
display: {
dateInput: "DD MMM YYYY H:mm",
monthYearLabel: "MMM YYYY",
dateA11yLabel: "LL",
monthYearA11yLabel: "MMMM YYYY"
}
}
export interface EditEventPageParams {
eventId: string
caller?: string
closeModal: Boolean
}
@Component({
selector: 'app-edit-event',
templateUrl: './edit-event.page.html',
styleUrls: ['./edit-event.page.scss'],
providers: [
{ provide: NGX_MAT_DATE_FORMATS, useValue: CUSTOM_DATE_FORMATS },
]
})
export class EditEventPage implements OnInit {
static params: EditEventPageParams
Form: FormGroup;
validateFrom = false
postEvent: Event;
isRecurring: string;
isEventEdited: boolean;
loadedEvent: Event;
eventBody: EventBody;
segment: string = "true";
profile: string;
eventAttendees: EventPerson[];
selectedSegment: string;
selectedDate: Date;
initCalendarName: string;
caller: string;
selectedRecurringType: any;
public date: any;
public disabled = false;
public showSpinners = true;
public showSeconds = false;
public touchUi = false;
public enableMeridian = false;
public endMinDate = new Date(new Date().getTime() + 15 * 60000).toISOString().slice(0, 10)
public maxDate: any;
public stepHour = 1;
public stepMinute = 15;
public stepSecond = 15;
loadedEventAttachments: Attachment[] = [];
taskParticipants: any = [];
taskParticipantsCc: any = [];
adding: "intervenient" | "CC" = "intervenient";
showAttendees = false;
public listColors = ['primary', 'accent', 'warn'];
public stepHours = [1, 2, 3, 4, 5];
public stepMinutes = [1, 5, 10, 15, 20, 25];
public stepSeconds = [1, 5, 10, 15, 20, 25];
sesseionStora = SessionStore
environment = environment
allDayCheck: boolean = false;
deletedAttachmentsList = [];
addedAttachmentsList = [];
sharedCalendar: Observable<TableSharedCalendar[]>
hasChangeCalendar = false
selectedUserCalendar:any;
SessionStore = SessionStore
serverCurrentList = []
CalendarNamesOptions = ['Oficial', 'Pessoal']
editAllEvent = false
closeModal = false
constructor(
private modalController: ModalController,
private navParams: NavParams,
public eventsService: EventsService,
public alertController: AlertController,
private attachmentsService: AttachmentsService,
public ThemeService: ThemeService,
private httpErrorHandle: HttpErrorHandle,
private agendaDataRepository: AgendaDataRepositoryService,
private utils: Utils,
public RoleIdService: RoleIdService,
) {
/* this.postEvent = new Event(); */
this.isEventEdited = false;
/* this.postEvent.EventRecurrence = { Type:'-1', LastOccurrence:''}; */
this.postEvent = this.navParams.get('event');
this.serverCurrentList = this.postEvent.Attendees
console.log('this.postEvent', this.postEvent)
this.caller = this.navParams.get('caller');
this.closeModal = this.navParams.get('closeModal');
this.initCalendarName = this.postEvent.CalendarName;
this.allDayCheck = this.postEvent.IsAllDayEvent;
this.validationEditAllEvent()
if (this.postEvent) {
if (this.postEvent.Body) {
if (typeof (this.postEvent?.Body?.Text) == 'string') {
this.postEvent.Body.Text = this.postEvent.Body.Text.replace(/<[^>]+>/g, '');
}
}
}
if (this.postEvent.Attendees == null) {
this.taskParticipants = []
} else {
this.postEvent.Attendees.forEach(e => {
if (e.IsRequired) {
this.taskParticipants.push(e);
} else {
this.taskParticipantsCc.push(e);
}
})
}
if (this.postEvent.EventRecurrence.frequency == 'never') {
this.isRecurring = "Não se repete";
}
else {
this.isRecurring = "Repete";
}
this.loadedEventAttachments = this.postEvent?.Attachments
this.agendaDataRepository.getSharedCalendar()
this.changeAgenda()
this.sharedCalendar = this.agendaDataRepository.getShareCalendarItemsLiveWithOrder()
}
hasPrCalendar(data: TableSharedCalendar[]) {
for(const e of data) {
if(e.roleId == this.RoleIdService.PRES) {
return true
}
}
return false
}
changeSegmentCalendar() {
this.hasChangeCalendar = true
}
ngOnInit() {
this.selectedUserCalendar = this.postEvent.owner.wxUserId
if (!this.postEvent.IsRecurring) {
this.postEvent.EventRecurrence.frequency = 'never'
} else {
this.postEvent.EventRecurrence.frequency = this.utils.recurenceTypeSeleted(this.postEvent.EventRecurrence.frequency)
}
this.postEvent.Category = this.setEventType(this.postEvent.Category)
window.onresize = (event) => {
// if not mobile remove all component
if (window.innerWidth >= 1024) {
this.modalController.dismiss();
}
}
if (window.innerWidth > 800) {
this.showAttendees = true;
}
setTimeout(() => {
this.selectedRecurringType = this.postEvent.EventRecurrence.Type.toString();
}, 500);
}
ngOnDestroy() {
clearInterval(this.myInterval)
}
myInterval = setInterval(() => {
document.querySelectorAll('.ngx-mat-timepicker input').forEach((e: any) => {
if (e) {
e.disabled = true;
}
})
}, 1000);
ngOnChanges(changes: any): void {
this.loadedEventAttachments = this.postEvent?.Attachments
}
close() {
this.modalController.dismiss();
}
cancel() {
this.modalController.dismiss({ action: 'cancel' });
}
roundTimeQuarterHour(timeToReturn = new Date()) {
let date = timeToReturn || new Date();
const minutes = date.getMinutes();
date.setSeconds(0);
if (minutes % 15 != 0) {
if (minutes > 45) {
date.setMinutes(60)
} else if (minutes > 30) {
date.setMinutes(45)
} else if (minutes > 15) {
date.setMinutes(30)
} else if (minutes > 0) {
date.setMinutes(15)
}
}
return date
}
roundTimeQuarterHourPlus15(date: Date) {
const _date = new Date(date);
const minutes = _date.getMinutes();
_date.setMinutes(minutes + 15)
return _date
}
calculetedLastOccurrence(type: number) {
// console.log(type);
var valor;
var opcao: boolean;
if (type == 0) {
valor = 7;
opcao = true;
} else if (type == 1) {
valor = 30;
opcao = true;
} else if (type == 2) {
valor = 1;
opcao = false;
} else if (type == 3) {
valor = 5;
opcao = false;
}
this.defineLastOccurrence(valor, opcao);
}
defineLastOccurrence(valor: number, opcao: boolean) {
var time = new Date(this.postEvent.EndDate);
if (opcao == true) {
time.setDate(time.getDate() + valor);
this.postEvent.EventRecurrence.LastOccurrence = time;
} else {
time = new Date(
time.getFullYear() + valor,
time.getMonth(),
time.getDate(),
time.getHours(),
time.getMinutes()
);
this.postEvent.EventRecurrence.LastOccurrence = time;
}
}
runValidation() {
this.validateFrom = true
}
injectValidation() {
this.Form = new FormGroup({
Subject: new FormControl(this.postEvent.Subject, [
Validators.required,
// Validators.minLength(4)
]),
Location: new FormControl(this.postEvent.Location, [
Validators.required,
]),
CalendarName: new FormControl(this.postEvent.CalendarName, [
Validators.required
]),
Categories: new FormControl(this.postEvent.Category, [
Validators.required
]),
IsRecurring: new FormControl(this.postEvent.IsRecurring, [
Validators.required
]),
dateOccurrence: new FormControl(this.postEvent.EventRecurrence.Type.toString() == '-1' ? ['ok'] : this.postEvent.EventRecurrence.LastOccurrence && new Date(this.postEvent.EventRecurrence.LastOccurrence).getTime() > new Date(this.postEvent.EndDate).getTime() ? 'ok' : null, [
Validators.required
]),
Date: new FormControl(new Date(this.postEvent.StartDate).getTime() <= new Date(this.postEvent.EndDate).getTime() ? 'ok' : null, [
Validators.required
]),
participantes: new FormControl(this.taskParticipants, [
Validators.required
]),
})
}
openInicio() {
let input: any = document.querySelector('#new-inicio')
if (input) {
input.click()
}
}
openFim() {
let input: any = document.querySelector('#new-fim')
if (input) {
input.click()
}
}
openLastOccurrence() {
let input: any = document.querySelector('#last-occurrence')
if (input) {
input.click()
}
}
async validationEditAllEvent() {
if (this.postEvent.IsRecurring) {
const modal = await this.modalController.create({
component: EventRecurrencePage,
componentProps: {},
cssClass: 'event-recurrence-modal',
});
modal.onDidDismiss().then((res) => {
const data: EventRecurrenceComponentReturn = res.data
if(data =='EditAll') {
this.editAllEvent = true
} else if (data == 'EditOne') {
this.editAllEvent = false
} else if(data == 'Cancel') {
this.cancel()
} else {
this.cancel()
}
});
await modal.present();
}
}
onDateChange(e) {
const cloneDateStartDate = new Date(this.postEvent.StartDate);
const cloneDateEndDate = new Date(this.postEvent.EndDate);
if(cloneDateStartDate.getTime() >= cloneDateEndDate.getTime()) {
cloneDateStartDate.setHours(cloneDateStartDate.getHours() + 1);
this.postEvent.EndDate = cloneDateStartDate
}
}
@XTracerAsync({name:'mobile/create-event', bugPrint: true, daley: 4000})
async save_v2(tracing?: TracingType) {
this.injectValidation()
this.runValidation()
if (this.Form.invalid) {
return false
}
this.postEvent.Attendees = this.taskParticipants.concat(this.taskParticipantsCc);
try {
const calendar = await this.agendaDataRepository.getCalendarByUserId(this.selectedUserCalendar)
if(calendar.isOk()) {
const _value = await this.agendaDataRepository.updateEvent(this.postEvent.EventId, this.postEvent, this.editAllEvent, calendar.value, tracing)//.subscribe((value) => {
// _value.then((value) => {
// if(value.isOk()) {
// console.log(value.value)
// this.close();
// this.httpErrorHandle.httpsSucessMessagge('Editar evento')
// tracing.setAttribute('outcome', 'success')
// } else {
// tracing.setAttribute('outcome', 'failed')
// console.log('edit event error: ', value.error)
// }
// })
console.log({serverCurrentList: this.serverCurrentList, Attendees: this.postEvent.Attendees})
const { insert, remove } = AttendeesLIstChangeDetector(this.serverCurrentList as any, this.postEvent.Attendees as any)
console.log({insert, remove })
if(insert.length >= 1) {
try {
await this.agendaDataRepository.addEventAttendee(this.postEvent.EventId, insert, tracing).toPromise()
} catch (error) {
tracing.setAttribute('failed.attendees', 'true')
console.log('add Attendee error: ', error)
}
// this.agendaDataRepository.addEventAttendee(this.postEvent.EventId, insert, tracing).subscribe((value) => {
// console.log(value)
// }, ((error) => {
// tracing.setAttribute('failed.attendees', 'true')
// console.log('add Attendee error: ', error)
// }));
}
if(remove.length >= 1) {
try {
await this.agendaDataRepository.removeEventAttendee(this.postEvent.EventId, remove).toPromise();
} catch (error) {
tracing.setAttribute('failed.attendees', 'true')
console.log('add Attendee error: ', error)
}
// this.agendaDataRepository.removeEventAttendee(this.postEvent.EventId, remove).subscribe((value) => {
// console.log(value)
// }, ((error) => {
// tracing.setAttribute('failed.attendees', 'true')
// console.log('add Attendee error: ', error)
// }));
}
if (this.addedAttachmentsList.length > 0) {
try {
await this.agendaDataRepository.addEventAttachment(this.postEvent.EventId, this.loadedEventAttachments, tracing).toPromise();
} catch (error) {
console.log('add attachment error: ', error)
}
// this.agendaDataRepository.addEventAttachment(this.postEvent.EventId, this.loadedEventAttachments, tracing).subscribe((value) => {
// console.log(value)
// }, ((error) => {
// console.log('add attachment error: ', error)
// }));
}
if (this.deletedAttachmentsList.length > 0) {
try {
await this.agendaDataRepository.removeEventAttachment(this.postEvent.EventId, { attachments: this.deletedAttachmentsList }).toPromise()
} catch (error) {
console.log('remove attachment error: ', error)
tracing.setAttribute('failed.remove.attachment', 'true')
}
// this.agendaDataRepository.removeEventAttachment(this.postEvent.EventId, { attachments: this.deletedAttachmentsList }).subscribe((value) => {
// console.log(value)
// }, ((error) => {
// console.log('remove attachment error: ', error)
// tracing.setAttribute('failed.remove.attachment', 'true')
// }));
}
if(_value.isOk()) {
console.log(_value.value)
this.close();
this.httpErrorHandle.httpsSucessMessagge('Editar evento')
tracing.setAttribute('outcome', 'success')
} else {
tracing.setAttribute('outcome', 'failed')
console.log('edit event error: ', _value.error)
}
this.isEventEdited = true;
} else {
console.log(calendar.error)
}
} catch (error) {
this.httpErrorHandle.httpStatusHandle(error)
console.log('edit: ', error)
}
}
async openAttendees() {
if (window.innerWidth > 801) {
this.showAttendees = true;
}
else {
const modal = await this.modalController.create({
component: AttendeesPageModal,
componentProps: {
adding: this.adding,
taskParticipants: this.taskParticipants,
taskParticipantsCc: this.taskParticipantsCc
},
cssClass: 'modal attendee modal-desktop',
backdropDismiss: false
});
await modal.present();
modal.onDidDismiss().then((data) => {
if (data) {
data = data['data'];
const newAttendees: EventPerson[] = data['taskParticipants'];
const newAttendeesCC: EventPerson[] = data['taskParticipantsCc'];
if (newAttendees.length) {
this.setIntervenient(newAttendees);
} else {
this.setIntervenient([]);
}
if (newAttendeesCC) {
this.setIntervenientCC(newAttendeesCC);
} else {
this.setIntervenientCC([]);
}
}
});
}
}
setIntervenient(data) {
this.taskParticipants = data;
this.postEvent.Attendees = data;
}
setIntervenientCC(data) {
this.taskParticipantsCc = data;
}
addParticipants() {
this.adding = 'intervenient'
this.openAttendees();
}
addParticipantsCC() {
this.adding = 'CC';
this.openAttendees();
}
dynamicSetIntervenient({ taskParticipants, taskParticipantsCc }) {
this.taskParticipants = taskParticipants;
this.taskParticipantsCc = taskParticipantsCc;
}
getAttachments(eventId: string) {
if (this.postEvent.HasAttachments) {
this.attachmentsService.getAttachmentsById(eventId).subscribe(res => {
// this.loadedEventAttachments = res;
}, ((erro) => {
console.error('editgetAttchament', erro)
}));
}
}
deleteAttachment(attachmentID: string, index) {
const indexToRemove = index; // Assuming you already know the index you want to remove
const DocumentId: any = this.loadedEventAttachments[index].Id
if (indexToRemove > -1 && indexToRemove < this.loadedEventAttachments.length) {
this.loadedEventAttachments.splice(indexToRemove, 1);
}
this.deletedAttachmentsList.push(DocumentId)
}
removeItemById(array, id) {
return array.filter(item => item.docId !== id);
}
async getDoc() {
const modal = await this.modalController.create({
component: SearchPage,
cssClass: 'modal-width-100-width-background modal',
componentProps: {
type: 'AccoesPresidenciais & ArquivoDespachoElect',
showSearchInput: true,
eventAgenda: true,
select: true,
}
});
modal.onDidDismiss().then(async (res) => {
if (res) {
const data = res.data;
/* const ApplicationIdDocumentToSave: any = {
SourceName: data.selected.Assunto,
ParentId: this.postEvent.EventId,
SourceId: data.selected.Id,
Stakeholders: false,
ApplicationId: data.selected.ApplicationType.toString(),
CreateDate: false,
// needed to attach this document
Id: 'add',
SourceTitle: data.selected.Assunto,
Source: '1',
Link: '',
SerialNumber: '',
} */
this.loadedEventAttachments.push(data.selected)
this.addedAttachmentsList.push(data.selected)
}
})
await modal.present();
}
async changeAgenda() {
const result = await this.agendaDataRepository.geCalendars()
const selectedCalendar = result.find(e => e.wxUserId == this.selectedUserCalendar)
if(selectedCalendar) {
if(selectedCalendar.shareType == 1) {
this.CalendarNamesOptions = ['Oficial']
} else if(selectedCalendar.shareType == 2) {
this.CalendarNamesOptions = ['Pessoal']
} else if (selectedCalendar.shareType == 3) {
this.CalendarNamesOptions = ['Oficial', 'Pessoal']
}
}
}
onCheckboxChange(event: any) {
if (this.allDayCheck) {
this.postEvent.IsAllDayEvent = this.allDayCheck;
this.postEvent.StartDate = this.setAlldayTime(this.postEvent.StartDate)
this.postEvent.EndDate = this.setAlldayTimeEndDate(this.postEvent.EndDate)
console.log('Recurso ativado!!');
} else {
this.postEvent.IsAllDayEvent = this.allDayCheck;
this.postEvent.EndDate = this.setAlldayTimeEndDateNotAlday(this.postEvent.EndDate)
console.log('Recurso desativado');
}
}
setAlldayTime(timeToReturn) {
let date: any = new Date(timeToReturn) || new Date();
let newdate = new Date();
date.setHours(0)
date.setMinutes(0)
date.setSeconds(0);
return date
}
setAlldayTimeEndDate(timeToReturn) {
let date: any = new Date(timeToReturn) || new Date();
let newdate = new Date();
date.setHours(23)
date.setMinutes(59)
date.setSeconds(0);
return date
}
setAlldayTimeEndDateNotAlday(timeToReturn) {
let date: any = new Date(timeToReturn) || new Date();
let newdate = new Date();
date.setHours(23)
date.setMinutes(0)
date.setSeconds(0);
return date
}
setEventType(eventType) {
var selectedEventType = {
1: 'Meeting',
2: 'Travel',
3: 'Conference',
4: 'Encontro'
}
return selectedEventType[eventType];
}
}
@@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { EmendMessageModalPage } from './emend-message-modal.page';
const routes: Routes = [
{
path: '',
component: EmendMessageModalPage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class EmendMessageModalPageRoutingModule {}
@@ -0,0 +1,20 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { EmendMessageModalPageRoutingModule } from './emend-message-modal-routing.module';
import { EmendMessageModalPage } from './emend-message-modal.page';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
EmendMessageModalPageRoutingModule
],
declarations: [EmendMessageModalPage]
})
export class EmendMessageModalPageModule {}
@@ -0,0 +1,29 @@
<ion-header class="ion-no-border">
<div class="header-content">
<div hidden class="header-icon-left">
<button class="btn-no-color cursor-pointer" (click)="close()">
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " src="assets/images/theme/doneIt/icons-calendar-arrow-left.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/images/icons-arrow-arrow-left.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/images/icons-arrow-arrow-left.svg"></ion-icon>
</button>
</div>
<div class="header-title">
<label>Detalhes da Revisão</label>
</div>
</div>
</ion-header>
<ion-content>
<div class="ion-input-class-no-height">
<ion-textarea autocomplete="on" autocorrect="on" spellcheck="true" [(ngModel)]="emendMessage" rows="6" cols="20" placeholder="Indique o que necessita ser revisto!"></ion-textarea>
</div>
</ion-content>
<ion-footer class="ion-no-border">
<div class="buttons width-100">
<button class="btn-ok cursor-pointer" shape="round" (click)="save()">Enviar</button>
<button class="btn-cancel cursor-pointer" shape="round" (click)="close()">Cancelar</button>
</div>
</ion-footer>
@@ -0,0 +1,59 @@
@import '~src/function.scss';
.header-content{
//width: 360px;
overflow: auto;
margin-top: 25px;
}
.header-icon-left{
width: 36px;
font-size: rem(33);
color: #42b9fe;
float: left;
}
.header-title{
width: 264px;
font-family: Roboto;
font-size: rem(25);
margin: 0 5px 10px 20px;
padding: 0;
color:#000;
float: left;
}
.buttons{
width: 320px;
margin: 0 auto;
padding: 5px 0 5px 0;
}
.button-reject {
width: 130px;
height: 44px;
--color: #d30a0a;
border-radius: 22.5px;
--background: #ffe0e0;
margin: 0 12px 0 0px;
}
.button-approve {
width: 130px;
height: 44px;
border-radius: 22.5px;
--background: #42b9fe;
margin: 0 0px 0 12px;
}
.buttons{
display: flex;
width: 100% !important;
justify-content: space-between;
padding: 15px 0 15px 0;
overflow: auto;
}
.ion-input-class-no-height{
border: 1px solid #ebebeb;
border-radius: 5px;
overflow: auto;
margin: 0 20px 0 20px !important;
}
@@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { EmendMessageModalPage } from './emend-message-modal.page';
describe('EmendMessageModalPage', () => {
let component: EmendMessageModalPage;
let fixture: ComponentFixture<EmendMessageModalPage>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ EmendMessageModalPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(EmendMessageModalPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,33 @@
import { Component, OnInit } from '@angular/core';
import { ModalController } from '@ionic/angular';
import { ThemeService } from 'src/app/services/theme.service'
import { ToastService } from 'src/app/services/toast.service';
@Component({
selector: 'app-emend-message-modal',
templateUrl: './emend-message-modal.page.html',
styleUrls: ['./emend-message-modal.page.scss'],
})
export class EmendMessageModalPage implements OnInit {
emendMessage: string = '';
constructor(
private modalController: ModalController,
public ThemeService: ThemeService,
private toastService: ToastService,
) {
this.emendMessage = '';
}
ngOnInit() {}
close() {
this.modalController.dismiss({option:'close', note: this.emendMessage});
}
save() {
this.modalController.dismiss({option:'save', note: this.emendMessage});
}
}
@@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { EventActionsPopoverPage } from './event-actions-popover.page';
const routes: Routes = [
{
path: '',
component: EventActionsPopoverPage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class EventActionsPopoverPageRoutingModule {}
@@ -0,0 +1,20 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { EventActionsPopoverPageRoutingModule } from './event-actions-popover-routing.module';
import { EventActionsPopoverPage } from './event-actions-popover.page';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
EventActionsPopoverPageRoutingModule
],
declarations: [EventActionsPopoverPage]
})
export class EventActionsPopoverPageModule {}
@@ -0,0 +1,16 @@
<ion-content class="wrapper">
<div class="arrow-right" (click)="closePopover()">
<button class="btn-no-color">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' "slot="end" class="arrow-right-icon" src='assets/images/icons-arrow-arrow-right.svg'></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " slot="end" class="arrow-right-icon" src='assets/images/theme/gov/icons-calendar-arrow-right.svg'></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " slot="end" class="arrow-right-icon" src='assets/images/theme/{{ThemeService.currentTheme}}/icons-calendar-arrow-right.svg'></ion-icon>
</button>
</div>
<div class="buttons">
<button class="btn-cancel" shape="round" (click)="approveTask()">Aprovar</button>
<button class="btn-cancel" shape="round" (click)="editTask()">Editar</button>
<button class="btn-cancel" shape="round" (click)="emendarTask()">Enviar para Revisão</button>
<button class="btn-delete" shape="round" (click)="rejeitar()">Eliminar</button>
</div>
</ion-content>
@@ -0,0 +1,60 @@
@import '~src/function.scss';
.wrapper{
--padding-top:20px !important;
--padding-bottom:20px !important;
--padding-start:20px !important;
--padding-end:20px !important;
}
.arrow-right{
display: none;
margin-bottom: 20px;
.arrow-right-icon{
width: 37px;
float: right;
font-size: rem(35);
overflow: hidden;
}
}
.buttons{
display: flex;
flex-wrap: wrap;
justify-content: space-around;
align-items: center;
}
.solid {
display: none;
width: 90%;
border-top: 5px solid #bbb;
margin: 0 auto !important;
}
.btn-ok, .btn-cancel{
//width: 50% !important;
justify-content: center;
margin-bottom: 10px !important;
margin-top: 10px !important;
}
@media only screen and (max-width: 800px) {
.btn-ok, .btn-cancel, .btn-delete{
width: 47% !important;
}
}
@media only screen and (min-width: 1024px) {
.arrow-right{
display: flex;
justify-content: flex-end;
}
.btn-cancel{
display: none;
width: 100% !important;
margin-bottom: 10px !important;
}
.btn-delete, .btn-ok{
width: 100% !important;
margin-bottom: 10px !important;
margin-top: 10px !important;
}
/* .solid{
display: block;
} */
}
@@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { EventActionsPopoverPage } from './event-actions-popover.page';
describe('EventActionsPopoverPage', () => {
let component: EventActionsPopoverPage;
let fixture: ComponentFixture<EventActionsPopoverPage>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ EventActionsPopoverPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(EventActionsPopoverPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,186 @@
import { Component, OnInit } from '@angular/core';
import { ModalController, NavParams, PopoverController } from '@ionic/angular';
import { ProcessesService } from 'src/app/services/processes.service';
import { ToastService } from 'src/app/services/toast.service';
import { EditEventToApproveComponent } from 'src/app/shared/gabinete-digital/edit-event-to-approve/edit-event.page';
import { EmendMessageModalPage } from '../emend-message-modal/emend-message-modal.page';
import { ThemeService } from 'src/app/services/theme.service'
import { RouteService } from 'src/app/services/route.service';
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service';
import { TaskService } from 'src/app/services/task.service'
import { AgendaDataRepositoryService } from 'src/app/module/agenda/data/repository/agenda-data-repository.service';
@Component({
selector: 'app-event-actions-popover',
templateUrl: './event-actions-popover.page.html',
styleUrls: ['./event-actions-popover.page.scss'],
})
export class EventActionsPopoverPage implements OnInit {
serialNumber: string;
instanceId: string;
activityInstanceName: string
constructor(
private navParams: NavParams,
private processes: ProcessesService,
private modalController: ModalController,
private popoverController: PopoverController,
private toastService: ToastService,
private RouteService: RouteService,
private httpErrorHandle: HttpErrorHandle,
public ThemeService: ThemeService,
public TaskService: TaskService,
private agendaDataRepository: AgendaDataRepositoryService) {
this.serialNumber = this.navParams.get('serialNumber');
this.instanceId = this.navParams.get('InstanceId');
this.activityInstanceName = this.navParams.get('InstanceId');
}
ngOnInit() {
console.log('Teste tes',this.activityInstanceName)
window.onresize = (event) => {
if (window.innerWidth >= 800) {
this.popoverController.dismiss();
}
};
}
goBack() {
this.closePopover();
this.RouteService.goBack()
}
closePopover(message?) {
this.popoverController.dismiss(message);
}
async approveTask() {
let body = { "serialNumber": this.serialNumber, "action": "Aprovar" }
const loader = this.toastService.loading()
const value = await this.agendaDataRepository.approveEvent(this.serialNumber)// .subscribe((value) => {
if(value.isOk()) {
console.log(value.value)
this.TaskService.loadEventosParaAprovacao()
this.httpErrorHandle.httpsSucessMessagge('Evento aprovação')
this.goBack();
} else {
console.log('aprove event error: ', value.error)
this.httpErrorHandle.httpStatusHandle(value.error)
}
loader.remove()
}
async ReenviarTask() {
let body = { "serialNumber": this.serialNumber, "action": "Reenviar" }
const loader = this.toastService.loading()
try {
await this.processes.PostTaskAction(body).toPromise()
this.TaskService.loadEventosParaAprovacao()
this.httpErrorHandle.httpsSucessMessagge('Rever')
this.goBack();
} catch (error) {
this.httpErrorHandle.httpStatusHandle(error)
}
finally {
loader.remove()
}
}
async emendarTask() {
this.closePopover();
const modal = await this.modalController.create({
component: EmendMessageModalPage,
componentProps: {
},
cssClass: 'emend-message-modal',
backdropDismiss: false
});
modal.onDidDismiss()
.then(async (res) => {
if (res.data.option == 'save') {
let body = {
"serialNumber": this.serialNumber,
"action": "Emendar",
"dataFields": {
"ReviewUserComment": res.data,
}
}
const loader = this.toastService.loading()
const result = await this.agendaDataRepository.eventToaprovalStatus(this.serialNumber, 'Revision', res.data.note)// .subscribe((value) => {
if(result.isOk()) {
this.httpErrorHandle.httpsSucessMessagge('Rever')
this.TaskService.loadEventosParaAprovacao()
this.goBack();
} else {
console.log('send event to revision error: ', result.error)
this.httpErrorHandle.httpStatusHandle(result.error)
}
loader.remove()
} else {
}
});
await modal.present();
}
async rejeitar() {
let body = { "serialNumber": this.serialNumber, "action": "Descartar" }
const loader = this.toastService.loading();
const result = await this.agendaDataRepository.deleteEvent(this.serialNumber, true)//.subscribe((value) => {
if(result.isOk()) {
this.TaskService.loadEventosParaAprovacao()
this.httpErrorHandle.httpsSucessMessagge('delete event')
this.goBack();
} else {
console.log('reject event error: ', result.error)
this.httpErrorHandle.httpStatusHandle(result.error)
}
loader.remove();
}
async editTask() {
this.closePopover();
const modal = await this.modalController.create({
component: EditEventToApproveComponent,
componentProps: {
serialNumber: this.serialNumber,
InstanceId: this.instanceId
},
cssClass: 'modal modal-desktop',
// backdropDismiss: false
});
modal.onDidDismiss().then(res => { });
await modal.present();
}
}
@@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { NewEventPage } from './new-event.page';
const routes: Routes = [
{
path: '',
component: NewEventPage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class NewEventPageRoutingModule {}
@@ -0,0 +1,49 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { NewEventPageRoutingModule } from './new-event-routing.module';
import { NewEventPage } from './new-event.page';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatInputModule } from '@angular/material/input';
import { MatNativeDateModule } from '@angular/material/core';
import {
NgxMatDatetimePickerModule,
NgxMatNativeDateModule,
NgxMatTimepickerModule
} from '@angular-material-components/datetime-picker';
import { ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatSelectModule } from '@angular/material/select';
import { NgxMatMomentModule } from '@angular-material-components/moment-adapter';
import { MatDialogModule } from '@angular/material/dialog';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
NewEventPageRoutingModule,
//
MatDatepickerModule,
MatInputModule,
MatNativeDateModule,
NgxMatDatetimePickerModule,
NgxMatTimepickerModule,
NgxMatNativeDateModule,
NgxMatMomentModule,
MatSelectModule,
MatButtonModule,
ReactiveFormsModule,
MatDialogModule,
],
declarations: [NewEventPage]
})
export class NewEventPageModule {}
@@ -0,0 +1,432 @@
<ion-header class="ion-no-border">
<ion-toolbar class="header-toolbar">
<div class="main-header">
<div class="title-content width-100">
<div class="middle">
<ion-label class="title" style="font-size: 21.1px">Novo Evento</ion-label> <br>
<i style="margin-top: -3px; font-size: 15px;" > Campos marcados com * são obrigatórios</i>
</div>
</div>
</div>
</ion-toolbar>
</ion-header>
<ion-content>
<div class="main-content">
<!-- <input type="text" ngbDatepicker #d="ngbDatepicker"/> -->
<div class="ion-item-container" [class.input-error]="Form?.get('Subject')?.invalid && validateFrom ">
<ion-input autocomplete="on" autocorrect="on" spellcheck="true" placeholder="Assunto*" [(ngModel)]="postEvent.Subject"></ion-input>
</div>
<div *ngIf="(sharedCalendar | async) as calendarData" class="container-div" >
<div class="ion-item-class-2 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1 justify-center align-center material-inputs " [class.input-error]="Form?.get('CalendarName')?.invalid && validateFrom ">
<mat-form-field appearance="none" class="width-100" color="ion-color-secondary" placeholder="Selecione agenda">
<div *ngIf="hasPrCalendar(calendarData) && !hasChangeCalendar " style="margin-bottom: -20px;">PR </div>
<div *ngIf="selectedUserCalendar == SessionStore.user.UserId && !hasChangeCalendar && SessionStore.user.Profile != 'PR'" style="margin-bottom: -20px;">
Minha agenda
</div>
<mat-select [(value)]="selectedUserCalendar" (selectionChange)="changeAgenda();changeSegmentCalendar()">
<mat-option *ngFor="let calendars of calendarData" value="{{calendars.wxUserId}}">
<div *ngIf="calendars.roleId == RoleIdService.PRES">PR </div>
<div *ngIf="calendars.roleId == RoleIdService.MD && calendars.roleId != SessionStore.user.RoleID">AGENDA DO MDGPR</div>
<div *ngIf="calendars.roleId != RoleIdService.MD && calendars.roleId != RoleIdService.PRES && calendars.wxFullName && calendars.wxUserId != SessionStore.user.UserId"> Agenda {{calendars.wxFullName}} </div>
<div *ngIf="calendars.wxUserId == SessionStore.user.UserId && SessionStore.user.Profile != 'PR'">
Minha agenda
</div>
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
<div class="container-div">
<div class="ion-item-class-2">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-location.svg"></ion-icon>
</div>
<div class="ion-input-class" [class.input-error]="Form?.get('Location')?.invalid && validateFrom ">
<ion-input autocomplete="on" autocorrect="on" spellcheck="true" placeholder="Localização*" [(ngModel)]="postEvent.Location"></ion-input>
</div>
</div>
</div>
<div class="container-div">
<div class="ion-item-class-2 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1 justify-center align-center material-inputs " [class.input-error]="Form?.get('CalendarName')?.invalid && validateFrom ">
<mat-form-field appearance="none" class="width-100" color="ion-color-secondary" placeholder="Selecione agenda">
<mat-select [(value)]="postEvent.CalendarName" >
<mat-option *ngFor="let calendars of CalendarNamesOptions" value="{{calendars}}">
Agenda {{ calendars }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
<div class="container-div">
<div class="ion-item-class-2 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-description.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1 justify-center align-center material-inputs">
<mat-form-field appearance="none" class="width-100" placeholder="Sample Type" required>
<!-- <input matInput type="text" > -->
<mat-select [(value)]="postEvent.Category" >
<mat-option value="Meeting">
Reunião
</mat-option>
<mat-option value="Travel">
Viagem
</mat-option>
<mat-option value="Conference">
Conferência
</mat-option>
<mat-option value="Encontro">
Encontro
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
<div class="container-div">
<div>
<ion-item>
<ion-label>Todo dia</ion-label>
<ion-checkbox [(ngModel)]="allDayCheck" (ionChange)="onCheckboxChange($event)"></ion-checkbox>
</ion-item>
</div>
</div>
<div class="container-div">
<div class="ion-item-class-2 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-reapet.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1 justify-center align-center material-inputs">
<mat-form-field appearance="none" class="width-100" placeholder="Sample Type" required>
<!-- <input matInput type="text" > -->
<mat-select [(value)]="postEvent.EventRecurrence.frequency" >
<mat-option value="never">
Nunca
</mat-option>
<mat-option value="daily">
Diário
</mat-option>
<mat-option value="weekly">
Semanalmente
</mat-option>
<mat-option value="monthly">
Mensal
</mat-option>
<mat-option value="yearly">
Anual
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="postEvent.EventRecurrence.frequency != 'never'" class="container-div">
<div class="ion-item-class-2 d-flex" >
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-reapet.svg"></ion-icon>
</div>
<div class="ion-input-class flex-grow-1 justify-center align-center material-inputs materia-top" >
<mat-form-field appearance="none" class="date-hour-picker">
<input matInput [ngxMatDatetimePicker]="picker1"
placeholder="Data Fim de Recorrência*"
[(ngModel)]="postEvent.EventRecurrence.until"
[disabled]="disabled"
>
<mat-datepicker-toggle id="new-inicio" matSuffix [for]="picker1" ></mat-datepicker-toggle>
<ngx-mat-datetime-picker #picker1
[showSpinners]="showSpinners"
[showSeconds]="showSeconds"
[stepHour]="stepHour" [stepMinute]="stepMinute"
[stepSecond]="stepSecond"
[touchUi]="touchUi"
[hideTime]="true"
>
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
</div>
</div>
<div class="container-div">
<div class="ion-item-class-2 d-flex" >
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<div *ngIf="allDayCheck" class="ion-input-class flex-grow-1 justify-center align-center material-inputs materia-top" [class.input-error]="Form?.get('Date')?.invalid && validateFrom ">
<mat-form-field appearance="none" class="date-hour-picker">
<input matInput [ngxMatDatetimePicker]="picker1"
placeholder="Data Inicio*"
[(ngModel)]="postEvent.StartDate"
[disabled]="disabled"
(ngModelChange)="onDateChange($event)"
>
<mat-datepicker-toggle id="new-inicio" matSuffix [for]="picker1" ></mat-datepicker-toggle>
<ngx-mat-datetime-picker #picker1
[stepHour]="1"
[stepMinute]="15"
[hideTime]="true"
>
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
<div *ngIf="!allDayCheck" class="ion-input-class flex-grow-1 justify-center align-center material-inputs materia-top" [class.input-error]="Form?.get('Date')?.invalid && validateFrom ">
<mat-form-field appearance="none" class="date-hour-picker">
<input matInput [ngxMatDatetimePicker]="picker1"
placeholder="Data Inicio*"
[(ngModel)]="postEvent.StartDate"
[disabled]="disabled"
(ngModelChange)="onDateChange($event)"
>
<mat-datepicker-toggle id="new-inicio" matSuffix [for]="picker1" ></mat-datepicker-toggle>
<ngx-mat-datetime-picker #picker1
[stepHour]="1"
[stepMinute]="15"
[hideTime]="false"
>
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="!allDayCheck" class="container-div">
<div class="ion-item-class-2 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<!--
[className]="Form?.get('Subject')?.invalid ? 'input-error ion-input-class flex-grow-1' : 'ion-input-class ion-input-class flex-grow-1' "
-->
<div class="ion-input-class flex-grow-1 justify-center align-center materia-top" [class.input-error]="Form?.get('Date')?.invalid && validateFrom ">
<mat-form-field appearance="none" class="date-hour-picker" >
<input matInput [ngxMatDatetimePicker]="fim"
placeholder="Data de fim*"
[(ngModel)]="postEvent.EndDate"
[disabled]="disabled"
[min]="postEvent.StartDate"
>
<mat-datepicker-toggle id="new-fim" matSuffix [for]="fim" ></mat-datepicker-toggle>
<ngx-mat-datetime-picker #fim
[stepHour]="1" [stepMinute]="15"
>
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="allDayCheck" class="container-div">
<div class="ion-item-class-2 d-flex">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-calendar.svg"></ion-icon>
</div>
<!--
[className]="Form?.get('Subject')?.invalid ? 'input-error ion-input-class flex-grow-1' : 'ion-input-class ion-input-class flex-grow-1' "
-->
<div class="ion-input-class flex-grow-1 justify-center align-center materia-top" [class.input-error]="Form?.get('Date')?.invalid && validateFrom ">
<mat-form-field appearance="none" class="date-hour-picker" >
<input matInput [ngxMatDatetimePicker]="fim"
placeholder="Data de fim*"
[(ngModel)]="postEvent.EndDate"
[disabled]="disabled"
[min]="postEvent.StartDate"
>
<mat-datepicker-toggle id="new-fim" matSuffix [for]="fim" ></mat-datepicker-toggle>
<ngx-mat-datetime-picker #fim
[stepHour]="1" [stepMinute]="15"
[hideTime]="true"
>
</ngx-mat-datetime-picker>
</mat-form-field>
</div>
</div>
</div>
<div class="container-div">
<div class="ion-item-class-2">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-person.svg"></ion-icon>
</div>
<div class="ion-input-class-no-height cursor-pointer" (click)="addParticipants()" [class.input-error]="Form?.get('participantes')?.invalid && validateFrom ">
<div class="list-people">
<ion-item lines="none">
<ion-list>
<ion-label *ngIf="taskParticipants?.length < 1" class="list-people-title">Adicionar Intervenientes*</ion-label>
<ion-label *ngFor="let participant of taskParticipants">{{participant.Name}}</ion-label>
</ion-list>
</ion-item>
</div>
<div class="add-people cursor-pointer">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " slot="start" src="assets/images/icons-arrow-forward.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " slot="start" src="assets/images/theme/gov/icons-arrow-forward.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " slot="start" src="assets/images/theme/{{ThemeService.currentTheme}}/icons-arrow-forward.svg"></ion-icon>
</div>
</div>
</div>
</div>
<div class="container-div">
<div class="ion-item-class-2">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-people-cc.svg"></ion-icon>
</div>
<div class="ion-input-class-no-height cursor-pointer" (click)="addParticipantsCC()">
<div class="list-people">
<ion-item lines="none">
<ion-list>
<ion-label *ngIf="taskParticipantsCc?.length < 1" class="list-people-title">Com conhecimento</ion-label>
<ion-label *ngFor="let participant of taskParticipantsCc">{{participant.Name}}</ion-label>
</ion-list>
</ion-item>
</div>
<div class="add-people cursor-pointer">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " slot="start" src="assets/images/icons-arrow-forward.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " slot="start" src="assets/images/theme/gov/icons-arrow-forward.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " slot="start" src="assets/images/theme/{{ThemeService.currentTheme}}/icons-arrow-forward.svg"></ion-icon>
</div>
</div>
</div>
</div>
<!-- <div style="align-items: flex-start; display: flex; height: fit-content; margin-bottom: 15px">
<ion-icon style="height: 30px; width: 30px; margin-right: 10px; padding-left: 5px;" slot="start" src="assets/images/icons-description.svg"></ion-icon>
<ion-textarea class="textarea" autocomplete="on" autocorrect="on" spellcheck="true" [(ngModel)]="postEvent.Body.Text" placeholder="Detalhes" autoGrow="true" ></ion-textarea>
</div> -->
<div class="container-div">
<div class="ion-item-class-2">
<div class="ion-icon-class">
<ion-icon slot="start" src="assets/images/icons-description.svg"></ion-icon>
</div>
<div class="ion-input-class-no-height flex-grow-1">
<ion-textarea class="textarea heigh-200" autocomplete="on" autocorrect="on" spellcheck="true" [(ngModel)]="postEvent.Body.Text" placeholder="Detalhes" autoGrow="true" ></ion-textarea>
</div>
</div>
</div>
<div class="ion-item-container-no-border cursor-pointer" (click)="getDoc()">
<ion-label>
<div class="attach-icon">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/images/icons-attach-doc.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/images/theme/gov/icons-attach-doc.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " src="assets/images/theme/{{ThemeService.currentTheme}}/icons-attach-doc.svg"></ion-icon>
</div>
<div class="attach-document">
<ion-label>Adicionar documentos</ion-label>
</div>
</ion-label>
</div>
<div *ngFor="let document of documents; let i = index" >
<ion-list class="list">
<ion-item>
<ion-label>
<p class="d-flex ion-justify-content-between">
<span class="attach-title-item">{{document.subject}}</span>
<span class="app-name">
<span class="app-name" *ngIf="document.applicationId == 8 || document.ApplicationId == 8"> Correspondência </span>
<span class="app-name" *ngIf="document.applicationId == 386 || document.ApplicationId == 386"> Acções Presidenciais </span>
<span class="app-name" *ngIf="document.applicationId == 361 || document.ApplicationId == 361 "> Arquivo Despacho Electrónico </span>
</span>
<span class="close-button text-black cursor-pointer" (click)="removeAttachment(i)" >
<ion-icon class="font-20" src="assets/images/icons-delete-25.svg"></ion-icon>
</span>
</p>
<p><span class="span-left">{{(document.EntidadeOrganicaNome || document.Sender)}}</span><span class="span-right"> {{(document.dateEntry || document.DocDate) | date: 'dd-MM-yyyy HH:mm'}} </span></p>
</ion-label>
</ion-item>
</ion-list>
</div>
<!--
<div >
<ion-list class="list">
<ion-item>
<ion-label>
<p class="d-flex ion-justify-content-between">
<span class="attach-title-item">Assunto</span>
<span class="app-name">appName</span>
<span class="close-button text-black cursor-pointer" (click)="removeAttachment(i)" >
<ion-icon class="font-20" src="assets/images/icons-delete-25.svg"></ion-icon>
</span>
</p>
<p><span class="span-left">EntidadeOrganicaNome</span><span class="span-right"> document </span></p>
</ion-label>
</ion-item>
</ion-list>
</div> -->
</div>
</ion-content>
<ion-footer class="ion-no-border">
<ion-toolbar class="footer-toolbar px-20">
<ion-buttons slot="start">
<button class="btn-ok" fill="clear" color="#fff" (click)="save_v2()">
<ion-label>Gravar</ion-label>
</button>
</ion-buttons>
<ion-buttons slot="end">
<button class="btn-cancel" fill="clear" color="#061b52" (click)="close()">
<ion-label>Cancelar</ion-label>
</button>
</ion-buttons>
</ion-toolbar>
</ion-footer>
@@ -0,0 +1,229 @@
@import '~src/function.scss';
ion-content{
--background:transparent;
}
.header-toolbar{
--background:transparent;
--opacity: 1;
}
.main-header{
width: 100%; /* 400px */
height: 100%;
font-family: Roboto;
border-top-left-radius: 25px;
border-top-right-radius: 25px;
background-color: #fff;
overflow:hidden;
padding: 30px 20px 0px 20px;
color:#000;
transform: translate3d(0, 1px, 0);
.title-content{
margin: 0px auto;
overflow: auto;
background: #fff;
.middle{
padding: 0!important;
float: left;
width: max-content;
margin: 2.5px 0 0 5px;
}
}
.title{
font-size: rem(25);
}
}
.main-content{
width: 100%; /* 400px */
height: 100%;
font-family: Roboto;
margin: 0 auto;
background-color: #fff;
overflow:auto;
padding: 15px 20px 0 20px;
.ion-item-container{
flex: 1;
width: 100%;
margin: 15px auto;
border: 1px solid #ebebeb;
border-radius: 5px;
padding-left: 10px;
}
.ion-item-container-no-border{
width: 100%;
margin: 0px auto;
padding: 0 !important;
overflow: auto;
}
.container-div{
margin-bottom: 15px;
//overflow: auto;
}
.ion-item-class-2{
display: flex;
margin: 0px auto;
}
.ion-icon-class{
width: rem(45);
height: rem(45);
float: left;
padding: 10px;
font-size: rem(25);
}
ion-select{
padding-left: 5px;
margin-left: 0;
}
.ion-input-class{
height: rem(45);
border: 1px solid #ebebeb;
border-radius: 5px;
padding-left: 5px;
padding-right: 10px;
float: left;
flex: 1;
}
.ion-input-class-no-height{
border: 1px solid #ebebeb;
border-radius: 5px;
flex: 1;
}
.textarea{
font-size: small;
}
.list-people{
width: 250px;
float: left;
}
.add-people{
width: rem(45);
float: right;
overflow: auto;
font-size: rem(25);
height: rem(45);
display: flex;
}
.list-people-title{
/* font-size: rem(13); */
color: #a3a3a3;
}
.attach-document{
font-size: rem(15);
color: var(--title-text-color);
margin: 5px 5px 5px 10px;
padding: 5px;
float: left;
}
.attach-icon{
width: 37px;
font-size: rem(35);
float: left;
}
.attach-title-item{
width: 100%;
font-size: rem(15);
color:var(--title-text-color);
}
/* SPAN */
.span-left{
float: left;
font-size: rem(15);
}
.span-right{
text-align: right;
float: right;
font-size: rem(13);
}
.container-footer{
margin:0 auto;
overflow: auto;
}
.button-cancel {
width: rem(170);
height: rem(44);
border-radius: 22.5px;
--background: #e0e9ee;
--color: #061b52;
margin:10px;
}
.button-save {
width: rem(170);
height: rem(44);
border-radius: 22.5px;
--background: #42b9fe;
--color:#ffffff;
margin:10px;
}
.text-input{
width: 100%;
border: 1px solid #ebebeb;
margin: 0px 15px 15px 0px;
padding: 0 !important;
border-radius: 5px;
}
/* Error Messages */
.error{
color:red;
font-size: rem(12);
font-weight: bold;
padding-bottom: 20px;
}
.span-color{
color:red;
}
}
.app-name{
background: var(--title-text-color);
border-radius: 18px;
text-align: center;
display: flex;
align-items: center;
padding: 0px 5px;
color: white;
font-size: rem(12);
font-weight: 500;
height: 19px;
-webkit-border-radius: 18px;
-moz-border-radius: 18px;
-ms-border-radius: 18px;
-o-border-radius: 18px;
}
.close-button {
display: none;
height: 20px;
}
.list:hover {
.app-name {
display: none;
}
.close-button {
display: block !important;
}
}
.icon-time{
color: #797979b0;
}
.checkbox{
width: auto;
height: 30px;
}
@@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { NewEventPage } from './new-event.page';
describe('NewEventPage', () => {
let component: NewEventPage;
let fixture: ComponentFixture<NewEventPage>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ NewEventPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(NewEventPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,687 @@
import { Component, OnInit } from '@angular/core';
import { ModalController, NavParams, Platform } from '@ionic/angular';
import { EventBody } from 'src/app/models/eventbody.model';
import { EventPerson } from 'src/app/models/eventperson.model';
import { SearchList } from 'src/app/models/search-document';
import { LoginUserRespose } from 'src/app/models/user.model';
import { EventsService } from 'src/app/services/events.service';
import { ToastService } from 'src/app/services/toast.service';
import { Event } from '../../../../models/event.model';
import { AttendeesPageModal } from '../../../../pages/events/attendees/attendees.page';
import { SearchPage } from '../../../../pages/search/search.page';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { ThemeService } from 'src/app/services/theme.service';
import { NgxMatDateFormats } from '@angular-material-components/datetime-picker';
import { NGX_MAT_DATE_FORMATS } from '@angular-material-components/datetime-picker';
import { SessionStore } from 'src/app/store/session.service';
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service';
import { environment } from 'src/environments/environment';
import { ProcessesService } from 'src/app/services/processes.service';
import { TaskService } from 'src/app/services/task.service'
import { ContactsService } from 'src/app/services/contacts.service';
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE, ThemePalette } from '@angular/material/core';
import { MomentDateAdapter } from '@angular/material-moment-adapter';
import { AgendaDataRepositoryService } from 'src/app/module/agenda/data/repository/agenda-data-repository.service';
import { Observable } from 'rxjs';
import { TableSharedCalendar } from 'src/app/module/agenda/data/data-source/agenda-local-data-source.service';
import { map } from 'rxjs/operators';
import { RoleIdService } from 'src/app/services/role-id.service'
import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
import { AgendaService } from 'src/app/module/agenda/domain/agenda.service'
import { RoleId } from 'src/app/core/agenda/entity/event';
const CUSTOM_DATE_FORMATS: NgxMatDateFormats = {
parse: {
dateInput: "YYYY-MMMM-DD HH:mm"
},
display: {
dateInput: "DD MMM YYYY H:mm",
monthYearLabel: "MMM YYYY",
dateA11yLabel: "LL",
monthYearA11yLabel: "MMMM YYYY"
}
}
const MY_DATE_FORMAT = {
parse: {
dateInput: 'DD-MM-YYYY',
},
display: {
dateInput: 'DD/MM/YYYY',
monthYearLabel: 'MMMM YYYY',
dateA11yLabel: 'LL',
monthYearA11yLabel: 'MMMM YYYY'
}
};
@Component({
selector: 'app-new-event',
templateUrl: './new-event.page.html',
styleUrls: ['./new-event.page.scss'],
providers: [
{ provide: NGX_MAT_DATE_FORMATS, useValue: CUSTOM_DATE_FORMATS },
{ provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE] },
{ provide: MAT_DATE_FORMATS, useValue: MY_DATE_FORMAT }
]
})
export class NewEventPage implements OnInit {
// date picker
public date: any;
public disabled = false;
public showSpinners = false;
public showSeconds = true;
public touchUi = false;
public enableMeridian = false;
public stepHour = 1;
public stepMinute = 15;
public stepSecond = 15;
public color: ThemePalette = 'primary';
Form: FormGroup;
validateFrom = false
postEvent: Event;
eventBody: EventBody;
segment: string = "true";
profile: string;
eventAttendees: EventPerson[];
selectedSegment: string;
selectedDate: Date;
CalendarDate: Date;
selectedRecurringType: any;
adding: "intervenient" | "CC";
taskParticipants: any = [];
taskParticipantsCc: any = [];
documents: SearchList[] = [];
loggeduser: LoginUserRespose;
members: any;
CalendarName;
SessionStore = SessionStore;
public listColors = ['primary', 'accent', 'warn'];
public stepHours = [1, 2, 3, 4, 5];
public stepMinutes = [1, 5, 10, 15, 20, 25];
public stepSeconds = [1, 5, 10, 15, 20, 25];
autoStartTime;
autoEndTime;
CalendarNamesOptions = ['Oficial', 'Pessoal']
roomId: string;
globalEnd = new Date('1999')
environment = environment
eventPersons: EventPerson[];
contacts: EventPerson[];
allDayCheck: boolean = false;
eventRecurence = 'never';
sharedCalendar: Observable<TableSharedCalendar[]>
selectedUserCalendar:any;
hasChangeCalendar = false
constructor(
private modalController: ModalController,
private navParams: NavParams,
public eventService: EventsService,
private toastService: ToastService,
public ThemeService: ThemeService,
private platform: Platform,
private hhtpErrorHandle: HttpErrorHandle,
private processeService: ProcessesService,
public TaskService: TaskService,
private contactsService: ContactsService,
private agendaDataRepository: AgendaDataRepositoryService,
public RoleIdService: RoleIdService,
private AgendaService: AgendaService
) {
this.loggeduser = SessionStore.user;
this.postEvent = new Event();
this.postEvent.EventRecurrence = { Type: '-1' };
this.eventBody = { BodyType: "1", Text: "" };
this.postEvent.Body = this.eventBody;
this.roomId = this.navParams.get('roomId');
this.selectedSegment = this.navParams.get('segment');
this.selectedDate = this.navParams.get('eventSelectedDate');
this.taskParticipants = this.navParams.get('attendees');
this.CalendarDate = this.navParams.get('CalendarDate')
// Define the role priorities
const rolePriorities: { [key: number]: number } = {
100000014: 1, // Presidente da República
100000011: 2, // Vice Presidente (example role ID)
// Add other roles with their priorities here
};
this.agendaDataRepository.getSharedCalendar()
this.sharedCalendar = this.agendaDataRepository.getShareCalendarItemsLive().pipe(
map(data => data.sort((a, b) => {
const priorityA = rolePriorities[a.roleId] || Infinity;
const priorityB = rolePriorities[b.roleId] || Infinity;
return priorityA - priorityB;
}))
)
this.setCalendarByDefault(true)
}
hasPrCalendar(data: TableSharedCalendar[]) {
for(const e of data) {
if(e.roleId == this.RoleIdService.PRES) {
return true
}
}
return false
}
changeSegmentCalendar() {
this.hasChangeCalendar = true
}
async setCalendarByDefault(force) {
if (!this.selectedUserCalendar || force) {
const data = await this.agendaDataRepository.geCalendars()
const prObject = data.find(e => e?.roleId == RoleId.PRES)
if(prObject) {
this.selectedUserCalendar = prObject.wxUserId
} else {
this.selectedUserCalendar = SessionStore.user.UserId
}
}
}
ngOnInit() {
if (this.platform.is('desktop')) {
// this.taskParticipants = [];
}
this.selectedRecurringType = "-1";
this.postEvent = {
EventId: '',
Subject: '',
Body: this.eventBody,
Location: '',
CalendarId: '',
CalendarName: 'Oficial',
StartDate: this.autoStartTime,
EndDate: this.autoEndTime,
EventType: 'Reunião',
Attendees: null,
IsMeeting: false,
IsRecurring: false,
AppointmentState: 0,
TimeZone: '',
Organizer: '',
Category: 'Meeting',
HasAttachments: false,
EventRecurrence: { frequency: this.eventRecurence, until: "",
Type: '' },
};
window.onresize = (event) => {
if (window.innerWidth >= 1024) {
this.modalController.dismiss();
}
};
this.setDefaultTime()
this.changeAgenda()
this.fetchContacts("")
}
ngOnDestroy() {
clearInterval(this.myInterval)
}
myInterval = setInterval(() => {
document.querySelectorAll('.ngx-mat-timepicker input').forEach((e: any) => {
if (e) {
e.disabled = true;
}
})
}, 1000);
setDefaultTime() {
console.log('defalt call')
this.postEvent.StartDate = this.roundTimeQuarterHour(this.CalendarDate);
this.postEvent.EndDate = this.roundTimeQuarterHourPlus15(this.postEvent.StartDate);
console.log('defalt call', this.postEvent.StartDate)
}
close() {
this.modalController.dismiss();
}
roundTimeQuarterHour(timeToReturn = new Date()) {
let date: any = new Date(timeToReturn) || new Date();
let newdate = new Date();
const minutes = newdate.getMinutes();
date.setHours(newdate.getHours())
date.setSeconds(0);
if (minutes % 15 != 0) {
if (minutes > 45) {
date.setMinutes(60)
} else if (minutes > 30) {
date.setMinutes(45)
} else if (minutes > 15) {
date.setMinutes(30)
} else if (minutes > 0) {
date.setMinutes(15)
}
}
return date
}
roundTimeQuarterHourPlus15(date: Date) {
const _date = new Date(date);
const minutes = _date.getMinutes();
_date.setMinutes(minutes + 15)
return _date
}
setStartDate() {
if (!this.postEvent.StartDate) {
this.postEvent.StartDate = this.roundTimeQuarterHour();
}
}
setEndDate() {
if (!this.postEvent.EndDate) {
this.postEvent.EndDate = this.postEvent.StartDate;
}
}
onDateChange(e) {
const cloneDateStartDate = new Date(this.postEvent.StartDate);
const cloneDateEndDate = new Date(this.postEvent.EndDate);
if(cloneDateStartDate.getTime() >= cloneDateEndDate.getTime()) {
cloneDateStartDate.setHours(cloneDateStartDate.getHours() + 1);
this.postEvent.EndDate = cloneDateStartDate
}
}
calculetedLastOccurrence(type: number) {
// console.log(type);
var valor;
var opcao: boolean;
if (type == 0) {
valor = 7;
opcao = true;
} else if (type == 1) {
valor = 30;
opcao = true;
} else if (type == 2) {
valor = 1;
opcao = false;
} else if (type == 3) {
valor = 5;
opcao = false;
}
this.defineLastOccurrence(valor, opcao);
}
defineLastOccurrence(valor: number, opcao: boolean) {
var time = new Date(this.postEvent.EndDate);
if (opcao == true) {
time.setDate(time.getDate() + valor);
this.postEvent.EventRecurrence.LastOccurrence = time;
} else {
time = new Date(
time.getFullYear() + valor,
time.getMonth(),
time.getDate(),
time.getHours(),
time.getMinutes()
);
this.postEvent.EventRecurrence.LastOccurrence = time;
}
}
runValidation() {
this.validateFrom = true;
if (new Date(this.postEvent.StartDate).getTime() > new Date(this.postEvent.EndDate).getTime()) {
this.toastService._badRequest("A data de fim não pode ser inferior a data de início do evento")
}
}
get dateValid() {
if (window.innerWidth <= 800) {
return this.postEvent.StartDate < this.postEvent.EndDate ? ['ok'] : []
} else {
return ['ok']
}
}
injectValidation() {
this.Form = new FormGroup({
Subject: new FormControl(this.postEvent.Subject, [
Validators.required,
// Validators.minLength(4)
]),
Location: new FormControl(this.postEvent.Location, [
Validators.required,
]),
CalendarName: new FormControl(this.postEvent.CalendarName, [
Validators.required
]),
Date: new FormControl(new Date(this.postEvent.StartDate).getTime() < new Date(this.postEvent.EndDate).getTime() ? 'ok' : null, [
Validators.required
]),
Categories: new FormControl(this.postEvent.Category, [
Validators.required
]),
participantes: new FormControl(this.taskParticipants, [
Validators.required
]),
/* dateOccurrence: new FormControl(this.postEvent.EventRecurrence.Type.toString() == '-1' ? ['ok'] : this.postEvent.EventRecurrence.LastOccurrence && new Date(this.postEvent.EventRecurrence.LastOccurrence).getTime() > new Date(this.postEvent.EndDate).getTime() ? 'ok' : null, [
Validators.required
]), */
})
}
openInicio() {
let input: any = document.querySelector('#new-inicio')
if (input) {
input.click()
}
}
openFim() {
let input: any = document.querySelector('#new-fim')
if (input) {
input.click()
}
}
openLastOccurrence() {
let input: any = document.querySelector('#last-occurrence')
if (input) {
input.click()
}
}
@XTracerAsync({name:'Mobile/create-event', bugPrint: true})
async save_v2(tracing?: TracingType) {
this.injectValidation()
this.runValidation()
console.log(new Date(this.postEvent.StartDate).getTime())
console.log(new Date(this.postEvent.EndDate).getTime())
console.log(new Date(this.postEvent.StartDate).getTime() < new Date(this.postEvent.EndDate).getTime() ? 'ok' : null)
if (this.Form.invalid) {
/* if (new Date(this.postEvent.StartDate).getTime() < new Date(this.postEvent.EndDate).getTime()) {
this.toastService._badRequest("Data de inicio menor que a data de fim")
} */
return false
}
const calendar = await this.agendaDataRepository.getCalendarByUserId(this.selectedUserCalendar)
if(calendar.isOk()) {
const loader = this.toastService.loading()
this.postEvent.Attendees = this.taskParticipants.concat(this.taskParticipantsCc);
this.postEvent.IsAllDayEvent = this.allDayCheck;
const value = await this.agendaDataRepository.createEvent(this.postEvent, this.documents, calendar.value, tracing)
if(value.isOk()) {
console.log(value.value)
loader.remove()
this.hhtpErrorHandle.httpsSucessMessagge('new event')
let data = Object.assign(this.postEvent)
this.modalController.dismiss(data);
tracing.setAttribute('outcome', 'success');
} else {
tracing.setAttribute('outcome', 'failed');
console.log('create event error: ', value.error)
loader.remove()
}
} else {
}
}
//This method return calendar onwner user id
selectedCalendarUserId() {
if (this.eventService.calendarNamesType[this.CalendarName]?.['Oficial'] && this.postEvent.CalendarName == 'Oficial') {
return this.eventService.calendarNamesType[this.CalendarName]['OwnerId']
} else if (this.eventService.calendarNamesType[this.CalendarName]?.['Pessoal'] && this.postEvent.CalendarName == 'Pessoal') {
return this.eventService.calendarNamesType[this.CalendarName]['OwnerId']
} else {
return '11:11'
}
}
async changeAgenda() {
const result = await this.agendaDataRepository.geCalendars()
const selectedCalendar = result.find(e => e.wxUserId == this.selectedUserCalendar)
if(selectedCalendar) {
if(selectedCalendar.shareType == 1) {
this.CalendarNamesOptions = ['Oficial']
} else if(selectedCalendar.shareType == 2) {
this.CalendarNamesOptions = ['Pessoal']
} else if (selectedCalendar.shareType == 3) {
this.CalendarNamesOptions = ['Oficial', 'Pessoal']
}
}
}
async openAttendees() {
const modal = await this.modalController.create({
component: AttendeesPageModal,
componentProps: {
hideExternalDomain: false,
adding: this.adding,
taskParticipants: this.taskParticipants,
taskParticipantsCc: this.taskParticipantsCc
},
cssClass: 'attendee modal modal-desktop',
backdropDismiss: false
});
modal.onDidDismiss().then((data) => {
if (data) {
data = data['data'];
if (data) {
const newAttendees: EventPerson[] = data['taskParticipants'];
const newAttendeesCC: EventPerson[] = data['taskParticipantsCc'];
this.setIntervenient(newAttendees);
this.setIntervenientCC(newAttendeesCC);
}
}
});
await modal.present();
}
setIntervenient(data) {
this.taskParticipants = [];
this.taskParticipants = data;
this.postEvent.Attendees = data;
}
setIntervenientCC(data) {
this.taskParticipantsCc = [];
this.taskParticipantsCc = data;
}
addParticipants() {
this.adding = 'intervenient'
this.openAttendees();
}
addParticipantsCC() {
this.adding = 'CC'
this.openAttendees();
}
async getDoc() {
const modal = await this.modalController.create({
component: SearchPage,
cssClass: 'modal-width-100-width-background modal',
componentProps: {
type: 'AccoesPresidenciais & ArquivoDespachoElect',
showSearchInput: true,
eventAgenda: true,
select: true
}
});
modal.onDidDismiss().then((res) => {
if (res) {
const data = res.data;
this.documents.push(data.selected);
}
});
await modal.present();
}
removeAttachment(index: number) {
this.documents = this.documents.filter((e, i) => index != i);
}
// Deve ser removido posteriormente
eventToaproveBody(event, calendarId, role, userId, attachments) {
let toAproveObject = {
"EventProcess": {
"Body": event.Body,
"Location": event.Location,
"Subject": event.Subject,
"StartDate": event.StartDate,
"EndDate": event.EndDate,
"Status": "Active",
"IsAllDayEvent": event.IsRecurring,
"EventType": event.EventType,
"ParticipantsList": event.Attendees,
"EventRecurrence": event.EventRecurrence,
"HasAttachments": event.HasAttachments,
"CalendarId": calendarId,
"Role": role,
"wxUserID": userId,
"TimeZone": "W. Central Africa Standard Time"
},
"Attachments": attachments,
"InstanceID": "AGD_" + this.loggeduser.UserName + "_" + this.processeService.generateInstaceFormatDate()
}
return toAproveObject;
}
async fetchContacts(filter: string) {
const result = await this.AgendaService.setDefaultParticipants()
if(result.isOk()) {
if(result.value) {
this.taskParticipants.push(result.value[0]);
this.setIntervenient(result.value);
console.log('Attendes Email', result.value)
}
}
}
onCheckboxChange(event: any) {
if (this.allDayCheck) {
this.postEvent.IsAllDayEvent = this.allDayCheck;
this.postEvent.StartDate = this.setAlldayTime(this.postEvent.StartDate)
this.postEvent.EndDate = this.setAlldayTimeEndDate(this.postEvent.EndDate)
console.log('Recurso ativado!!');
} else {
this.postEvent.IsAllDayEvent = this.allDayCheck;
this.postEvent.EndDate = this.setAlldayTimeEndDateNotAlday(this.postEvent.EndDate)
console.log('Recurso desativado');
}
}
setAlldayTime(timeToReturn) {
let date: any = new Date(timeToReturn) || new Date();
let newdate = new Date();
date.setHours(0)
date.setMinutes(0)
date.setSeconds(0);
return date
}
setAlldayTimeEndDate(timeToReturn) {
let date: any = new Date(timeToReturn) || new Date();
let newdate = new Date();
date.setHours(23)
date.setMinutes(59)
date.setSeconds(0);
return date
}
setAlldayTimeEndDateNotAlday(timeToReturn) {
let date: any = new Date(timeToReturn) || new Date();
let newdate = new Date();
date.setHours(23)
date.setMinutes(0)
date.setSeconds(0);
return date
}
}
@@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { ViewEventPage } from './view-event.page';
const routes: Routes = [
{
path: '',
component: ViewEventPage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class ViewEventPageRoutingModule {}
@@ -0,0 +1,25 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { ViewEventPageRoutingModule } from './view-event-routing.module';
import { ViewEventPage } from './view-event.page';
import { SharedModule } from 'src/app/shared/shared.module';
import { BtnModalDismissPageModule } from 'src/app/shared/btn-modal-dismiss/btn-modal-dismiss.module';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
ViewEventPageRoutingModule,
BtnModalDismissPageModule,
],
declarations: [ViewEventPage]
})
export class ViewEventPageModule {}
@@ -0,0 +1,128 @@
<ion-content class="container-wrapper main-content-l height-100 white ">
<ion-refresher name="refresher" slot="fixed" (ionRefresh)="doRefresh($event)">
<ion-progress-bar type="indeterminate" *ngIf="showLoader"></ion-progress-bar>
<ion-refresher-content>
</ion-refresher-content>
</ion-refresher>
<div class="main-content d-flex height-100" [className]="isModal ? '_main-content d-flex height-100 ma-0 px-20 pt-30 pb-20 background-white' : 'main-content d-flex height-100'">
<div class="content d-flex flex-column width-100">
<div class="main-header d-flex">
<div class="title-content d-flex justify-between width-100 mb-10">
<div class="left d-flex">
<button class="btn-no-color d-flex align-center" (click)="goBack()">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/images/theme/blue/icons-calendar-arrow-left.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " slot="end" src='assets/images/theme/gov/icons-calendar-arrow-left.svg'></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " slot="end" src='assets/images/theme/{{ThemeService.currentTheme}}/icons-calendar-arrow-left.svg'></ion-icon>
</button>
</div>
<div class="middle d-flex align-center">
<p class="title" style="font-size: 21.1px"><span>{{loadedEvent.Subject}}</span></p>
<!-- Event details page -->
</div>
<div class="menu-options d-flex">
<button class="btn-no-color" (click)="editEvent()" *ngIf="p.userPermission([p.permissionList.Agenda.creatEvent])">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="edit" slot="end" src="assets/images/icons-edit.svg" ></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="edit" slot="end" src="assets/images/theme/gov/icons-edit.svg" ></ion-icon>
</button>
<button class="btn-no-color d-flex" (click)="deleteYesOrNo()">
<ion-icon class="delete" name="trash-sharp"></ion-icon>
</button>
</div>
</div>
</div>
<div class="overflow-y-auto">
<div class="upper-content ml-45">
<div class="content-location">
<span class="date">{{loadedEvent.Location}}</span>
<div *ngIf="loadedEvent.Organizer" class="font-15-rem">
<div *ngIf="loadedEvent.owner.wxUserId != sesseionStora.user.UserId || sesseionStora.user.Profile =='PR'">
<span class="label" *ngIf="loadedEvent.CalendarName == 'Oficial' " style="background-color: #99e47b;">{{loadedEvent.CalendarName}}</span>
<span class="label" *ngIf="loadedEvent.CalendarName == 'Pessoal' " style="background-color: #958bfc;">{{loadedEvent.CalendarName}}</span>
</div>
<div *ngIf="loadedEvent.owner.wxUserId == sesseionStora.user.UserId && sesseionStora.user.Profile !='PR'">
<span class="label" *ngIf="loadedEvent.CalendarName == 'Oficial' " style="background-color: #ffb703;">{{loadedEvent.CalendarName}}</span>
<span class="label" *ngIf="loadedEvent.CalendarName == 'Pessoal' " style="background-color: #f05d5e;">{{loadedEvent.CalendarName}}</span>
</div>
</div>
</div>
<div class="content-details">
<ion-label>
<p>{{customDate}}</p>
<p>{{TimeZoneString}}</p>
<p *ngIf="toDateString(loadedEvent.StartDate) == toDateString(loadedEvent.EndDate)">das {{loadedEvent.StartDate | date: 'HH:mm'}} às {{loadedEvent.EndDate | date: 'HH:mm'}}</p>
<p *ngIf="toDateString(loadedEvent.StartDate) != toDateString(loadedEvent.EndDate)">{{loadedEvent.StartDate | date: 'd/M/yy' }} - {{ loadedEvent.EndDate | date: 'dd/M/yy'}} </p>
<p *ngIf="loadedEvent.EventRecurrence">
<span *ngIf="stringToNumber(loadedEvent.EventRecurrence.frequency) == 1">Diário</span>
<span *ngIf="stringToNumber(loadedEvent.EventRecurrence.frequency) == 2">Semanal</span>
<span *ngIf="stringToNumber(loadedEvent.EventRecurrence.frequency) == 3">Mensal</span>
<span *ngIf="stringToNumber(loadedEvent.EventRecurrence.frequency) == 4">Anual</span>
<span *ngIf="!loadedEvent.IsRecurring">(Não se repete)</span>
</p>
</ion-label>
</div>
</div>
<div class="line"></div>
<div class="middle-content">
<div *ngIf="loadedEvent.Attendees">
<h5 class="font-17-rem">Intervenientes({{ loadedEvent.Attendees.length }})</h5>
<ion-item class="ion-no-margin ion-no-padding">
<ion-label>
<div *ngFor="let attendee of loadedEvent.Attendees">
<p>{{attendee.Name}}</p>
</div>
</ion-label>
</ion-item>
</div>
<div *ngIf="loadedEvent.Body.Text">
<h5 class="font-17-rem">Detalhes</h5>
<ion-item lines="none" class="ion-no-margin ion-no-padding">
<pre class="width-100 text">{{ loadedEvent.Body.Text }} </pre>
</ion-item>
<div class="line"></div>
</div>
</div>
<div *ngIf="loadedEvent.Attachments" class="bottom-content width-100">
<h5 class="font-17-rem">Documentos Anexados({{ loadedEvent.Attachments.length }})</h5>
<ion-list class="width-100">
<ion-item *ngFor="let attach of loadedEvent.Attachments; let i = index" class="width-100" class="ion-no-margin ion-no-padding">
<ion-label class="width-100 d-flex " (click)="docIndex(i);LoadDocumentDetails()">
<p class="flex-grow-1" >
<span class="attach-title-item d-block">{{attach.SourceName || attach.subject || attach.sourceName || 'Sem título'}}</span>
<span class="span-left d-block">{{attach.Stakeholders}}</span>
</p>
<div class="d-flex pr-10">
<span class="span-right">{{ attach.CreateDate | date: 'dd-MM-yyyy HH:mm' }}</span>
</div>
<!-- <div (click)="docIndex(i);LoadDocumentDetails()" class="cursor-pointer" style="width: 35px; height: 41px;" autoHide="false">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/images/icons-menu.svg" ></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/images/theme/gov/icons-menu.svg" ></ion-icon>
</div> -->
</ion-label>
</ion-item>
</ion-list>
</div>
</div>
</div>
<div class="aside-right flex-column height-100">
<div class="buttons">
<button (click)="editEvent()" full class="btn-ok" shape="round" >Editar</button>
<div class="solid"></div>
<button (click)="deleteYesOrNo()" full class="btn-delete" shape="round" >Eliminar</button>
</div>
</div>
</div>
</ion-content>
@@ -0,0 +1,306 @@
@import '~src/function.scss';
ion-content{
--background:transparent;
/* --padding-top:0px;
--padding-start: 20px;
--padding-end: 20px;
font-size: rem(18); */
overflow: auto;
}
ion-menu{
--height: 225px;
}
.header-toolbar{
--background:transparent;
--opacity: 1;
}
.main-header{
width: 100%; /* 400px */
font-family: Roboto;
background-color: #fff;
color:#000;
transform: translate3d(0, 1px, 0);
.title-content{
width: 100% !important;
margin: 0px auto;
padding: 0 !important;
background: #fff;
overflow: auto;
.left{
width: 37px;
float: left;
font-size: rem(35);
}
.middle{
width: calc(100% - 138.5px) !important;
padding: 0 !important;
float: left;
margin: 0 !important;
overflow: auto;
p{
margin: 0 !important;
}
}
.header-icon-right{
width: rem(45);
font-size: rem(45);
float: right;
}
.menu-options{
width: fit-content;
height: fit-content;
align-items: flex-start;
justify-content: flex-start;
float: right;
padding: 1px;
margin-left: 15px;
}
.menu-options .edit{
font-size: rem(35);
float: left;
}
.menu-options .delete{
padding: 7px;
font-size: rem(21);
color:#fff;
background: #d30606;
border-radius: 20px;
margin-left: 10px;
}
}
.title{
font-size: rem(25);
}
}
.main-content{
width: 100%;
font-family: Roboto;
background-color: #fff !important;
border-top-left-radius: 25px;
border-top-right-radius: 25px;
overflow:auto;
.content{
padding: 30px 20px 0 20px !important;
margin: 0;
float: left;
}
.upper-content{
width: calc(100%-50px);
margin-left: 50px;
font-size: rem(18);
.content-location{
width: 100%;
margin: 0 auto;
padding: 0;
overflow: auto;
.date{
width: calc(100% - 105px);
float: left;
}
}
.location-detail{
width: 210px;
font-weight: 700;
font-size: rem(18);
float: left;
margin: 5px 5px 5px 0px;
}
.button-mdgpr-Oficial{
width: 91px;
--border-radius: 20px;
--background: var(--label-bg-color);
margin-left: 5px;
float: left;
}
.button-mdgpr-Pessoal{
width: 91px;
--border-radius: 20px;
--background: #f05d5e;
margin-left: 5px;
float: left;
}
.button-pr-Oficial{
width: 91px;
--border-radius: 20px;
--background: #cbeecb;
margin-left: 5px;
float: left;
}
.button-pr-Pessoal{
width: 91px;
--border-radius: 20px;
--background: #cab0dc;
margin-left: 5px;
float: left;
}
.button-calendar-type ion-button{
height: rem(25);
}
.button-edit-event {
width: 140px;
height: 44px;
border-radius: 22.5px;
--background: #e0e9ee;
--color:#061b52;
}
.content-details p{
font-size: rem(16);
}
}
.line{
width: 100% !important;
margin-top: 15px;
border-top: 1px solid #d8d8d8;
}
.middle-conten{
width: 100% !important;
overflow: auto;
.middle-content h3, .middle-content p{
font-size: rem(16);
}
}
.bottom-content{
margin: 0 auto;
.bottom-content h3{
font-size: rem(16);
margin: 0 0 0 10px;
}
.attach-document{
font-size: rem(15);
color: var(--title-text-color);
margin: 5px 5px 5px 10px;
padding: 5px;
float: left;
}
.attach-icon{
width: 37px;
font-size: rem(35);
float: left;
}
.attach-title-item{
width: 100%;
font-size: rem(15);
color:#0d89d1;
/* color: var(--title-text-color); */
}
/* SPAN */
.span-left{
float: left;
font-size: rem(15);
}
.span-right{
text-align: right;
float: right;
font-size: rem(13);
}
}
}
.aside-right{
padding: 30px 20px 0 20px !important;
.arrow-right{
display: flex;
justify-content: flex-end;
margin-bottom: 20px;
.arrow-right-icon{
width: 37px;
float: right;
font-size: rem(35);
}
}
.buttons{
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.btn-ok, .btn-cancel, .btn-delete{
height: auto !important;
font-size: rem(16) !important;
width: 100% !important;
margin-bottom: 10px !important;
padding: 15px !important;
}
}
.solid {
display: block;
width: 90%;
border-top: 1px solid #ebebeb;
margin: 0 auto !important;
margin-bottom: 10px !important;
}
}
textarea{
border:none;
--background:#fff !important;
}
@media only screen and (max-width: 800px) {
.content{
width: 100% !important;
}
.aside-right{
display: none;
}
}
@media only screen and (min-width: 801px) {
.menu-options{
display: none !important;
}
.content{
width: 65%;
border-right: 1px solid #d8d8d8;
}
.aside-right{
width: 35%;
}
}
@media only screen and (min-width: 1024px){
.content{
width: 70%;
}
.aside-right{
width: 30%;
}
}
@media only screen and (min-width: 1140px){
.content{
width: 75%;
}
.aside-right{
width: 25%;
}
}
.label{
border-radius: 20px;
background: var(--label-bg-color);
float: right;
padding: 5px 13.5px 5px 13.5px;
color: black;
}
.text {
text-transform: initial !important
}
@@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { ViewEventPage } from './view-event.page';
describe('ViewEventPage', () => {
let component: ViewEventPage;
let fixture: ComponentFixture<ViewEventPage>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ViewEventPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(ViewEventPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,484 @@
import { Component, OnInit } from '@angular/core';
import { AlertController, ModalController, PopoverController, Platform } from '@ionic/angular';
import { EventBody } from 'src/app/models/eventbody.model';
import { EventsService } from 'src/app/services/events.service';
import { Event } from '../../../../models/event.model';
import { EditEventPage } from '../edit-event/edit-event.page';
import { ActivatedRoute } from '@angular/router';
import { ToastService } from 'src/app/services/toast.service';
import { EliminateEventPage } from 'src/app/modals/eliminate-event/eliminate-event.page';
import { ExpedientTaskModalPageNavParamsTask } from 'src/app/models/ExpedientTaskModalPage';
import { DocumentSetUpMeetingPage } from 'src/app/modals/document-set-up-meeting/document-set-up-meeting.page';
import { ExpedientTaskModalPage } from '../../../../pages/gabinete-digital/expediente/expedient-task-modal/expedient-task-modal.page';
import { ViewDocumentPage } from 'src/app/modals/view-document/view-document.page';
import { ThemeService } from 'src/app/services/theme.service'
import { RouteService } from 'src/app/services/route.service';
import { SessionStore } from 'src/app/store/session.service';
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service'
import { AgendaDataRepositoryService } from 'src/app/module/agenda/data/repository/agenda-data-repository.service';
import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
import { isHttpError } from 'src/app/services/http.service';
import { PermissionService } from 'src/app/services/permission.service';
import { DeleteEventRecurrencePage, EventDeleteRecurrenceComponentReturn } from 'src/app/modals/delete-event-recurrence/delete-event-recurrence.page';
@Component({
selector: 'app-view-event',
templateUrl: './view-event.page.html',
styleUrls: ['./view-event.page.scss'],
})
export class ViewEventPage implements OnInit {
loadedEvent: Event;
isEventEdited: boolean;
eventBody: EventBody;
loadedAttachments: any;
pageId: string;
showLoader: boolean;
minDate: Date;
profile: string;
eventId: string;
CalendarId: string;
caller: string;
customDate: any;
today: any;
months = ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"];
days = ["Domingo", "Segunda-feira", "Terça-feira", "Quarta-feira", "Quinta-feira", "Sexta-feira", "Sábado"];
dicIndex = 0;
isModal = false
header = true
task: ExpedientTaskModalPageNavParamsTask;
LoadedDocument: any = null;
sesseionStora = SessionStore
TimeZoneString = ''
constructor(
private modalController: ModalController,
public eventsService: EventsService,
public alertController: AlertController,
public popoverController: PopoverController,
private activatedRoute: ActivatedRoute,
private toastService: ToastService,
public platform: Platform,
public ThemeService: ThemeService,
private RouteService: RouteService,
private httpErrorHandle: HttpErrorHandle,
private agendaDataRepository: AgendaDataRepositoryService,
public p: PermissionService,
) {
this.isEventEdited = false;
this.loadedEvent = new Event();
this.eventBody = { BodyType: "1", Text: "" };
this.loadedEvent.Body = this.eventBody;
this.activatedRoute.paramMap.subscribe(params => {
this.eventId = params['params'].eventId;
const urlParams = new URLSearchParams(window.location.search);
this.CalendarId = urlParams.get('CalendarId');
this.eventId = this.eventId.replace(' ', '')
if (params["params"].caller) {
this.caller = (params["params"].caller);
}
if (params["params"].isModal) {
this.isModal = params["params"].isModal
}
if (params["params"].header) {
this.header = params["params"].header
}
});
}
ngOnInit() {
this.loadEvent();
window.onresize = (event) => {
// if not mobile remove all component
if (window.innerWidth >= 1024) {
this.modalController.dismiss(this.isEventEdited);
}
};
}
close() {
this.modalController.dismiss(this.isEventEdited);
}
goBack() {
if (this.isModal) {
this.close()
} else {
this.activatedRoute.paramMap.subscribe(params => {
if (params["params"].caller == 'expediente') {
window.history.back();
}
else {
// this.router.navigate(['/home', params["params"].caller]);
this.RouteService.goBack();
}
});
}
}
doRefresh(ev) {
this.loadEvent();
ev.target.complete();
}
setTimeZone() {
this.TimeZoneString = this.loadedEvent.TimeZone
}
@XTracerAsync({name:'mobile/loadEventDetails', bugPrint: true})
async loadEvent(tracing?: TracingType) {
const loader = this.toastService.loading();
let res = await this.agendaDataRepository.getEventById(this.eventId, tracing)
if (res.isOk()) {
tracing.setAttribute('outcome', 'success')
console.log('Loaded Event', res.value)
loader.remove()
/* let changeDate = this.dateService.fixDate(res.value as any) as any */
this.loadedEvent = res.value as any;
this.setTimeZone()
} else {
tracing.setAttribute('eventId', this.eventId)
if(!isHttpError(res.error)) {
this.toastService._badRequest('Pedimos desculpa mas não foi possível executar a acção. Por favor, contacte o apoio técnico. #13')
console.log(res.error)
} else if (isHttpError(res.error)) {
if(res.error.status == 404) {
this.toastService._badRequest('Este evento já não existe')
} else {
this.httpErrorHandle.httpStatusHandle(res.error)
}
}
tracing.setAttribute('outcome', 'failed')
// this.toastService.badRequest('Este evento já não existe na sua agenda')
this.RouteService.goBack();
}
loader.remove()
}
async deleteYesOrNo() {
if (this.loadedEvent.IsRecurring) {
const modal = await this.modalController.create({
component: DeleteEventRecurrencePage,
componentProps: {},
cssClass: 'event-recurrence-modal',
});
modal.onDidDismiss().then((res) => {
const data: EventDeleteRecurrenceComponentReturn = res.data
if(data =='DeleteAll') {
this.deleteEvent(true);
} else if (data == 'DeleteOne') {
this.deleteEvent(false);
} else if(data == 'Cancel') {
this.close()
} else {
this.close()
}
});
await modal.present();
} else {
this.alertController.create({
header: 'Eliminar evento?',
message: '',
buttons: [
{
text: 'Sim',
handler: (data) => {
this.deleteEvent(false);
}
},
{
text: 'Não',
handler: () => {
// sconsole.log('Let me think');
}
}
]
}).then(res => {
res.present();
});
}
}
async deleteEvent(deleteAll) {
const loader = this.toastService.loading()
console.log(this.loadedEvent.EventId)
const result = await this.agendaDataRepository.deleteEvent(this.loadedEvent.EventId,deleteAll)//.subscribe(async () => {
if(result.isOk()) {
const alert = await this.alertController.create({
cssClass: 'my-custom-class',
header: 'Evento removido',
buttons: ['OK']
});
setTimeout(() => {
alert.dismiss();
}, 1500);
this.goBack();
this.httpErrorHandle.httpsSucessMessagge('delete event')
} else {
console.log('delete event error: ', result.error)
this.httpErrorHandle.httpStatusHandle(result.error)
}
loader.remove();
}
async OpenDeleteEventModal() {
const modal = await this.modalController.create({
component: EliminateEventPage,
componentProps: {
eventId: this.loadedEvent.EventId,
caller: this.caller,
},
cssClass: 'discart-expedient-modal',
});
modal.onDidDismiss().then((res) => {
if (res) {
setTimeout(() => {
/* this.loadEvent(); */
this.loadEvent()
}, 250);
this.isEventEdited = true;
}
});
await modal.present();
}
toDateString(e) {
return new Date(e).toDateString()
}
async editEventDetail() {
const modal = await this.modalController.create({
component: EditEventPage,
componentProps: {
eventId: this.loadedEvent.EventId,
caller: this.caller,
closeModal: true
},
cssClass: 'modal modal-desktop',
});
await modal.present();
modal.onDidDismiss().then((res) => {
if (res.data?.action == 'cancel') {
console.log('res', res)
} else {
this.loadEvent()
this.isEventEdited = true;
// if (res.data.Attendees?.length >= 1) {
// this.loadedEvent.HasAttachments = true
// // this.getAttachments()
// }
console.log('res', res)
}
});
}
async editEvent() {
let classs;
if (window.innerWidth <= 800) {
classs = 'modal modal-desktop'
} else {
classs = 'modal modal-desktop showAsideOptions'
}
const modal = await this.modalController.create({
component: EditEventPage,
componentProps: {
event: this.loadedEvent,
caller: this.caller,
},
cssClass: classs,
});
modal.onDidDismiss().then((res) => {
if (res.data?.action == 'cancel') {
console.log('res', res)
} else {
this.loadEvent()
this.isEventEdited = true;
// if (res.data.Attendees?.length >= 1) {
// this.loadedEvent.HasAttachments = true
// // this.getAttachments()
// }
// console.log('res', res)
}
});
await modal.present();
}
docIndex(index: number) {
this.dicIndex = index
}
async LoadDocumentDetails() {
const docId = this.loadedEvent.Attachments[this.dicIndex].SourceId
const applicationId: any = this.loadedEvent.Attachments[this.dicIndex].ApplicationId
const selectedDoc = this.loadedEvent.Attachments[this.dicIndex]
this.task = {
serialNumber: '',
taskStartDate: '',
isEvent: true,
workflowInstanceDataFields: {
FolderID: '',
Subject: selectedDoc.SourceName,
SourceSecFsID: selectedDoc.ApplicationId || selectedDoc['ApplicationID'],
SourceType: 'DOC',
SourceID: selectedDoc.SourceId,
DispatchNumber: ''
}
}
const modal = await this.modalController.create({
component: ViewDocumentPage,
componentProps: {
trustedUrl: '',
file: {
title: this.task.workflowInstanceDataFields.Subject,
url: '',
title_link: '',
},
Document: this.loadedEvent.Attachments[this.dicIndex],
applicationId: this.task.workflowInstanceDataFields.SourceSecFsID,
docId: selectedDoc.SourceId,
folderId: '',
task: this.task
},
cssClass: 'modal modal-desktop'
});
await modal.present();
}
async openBookMeetingModal() {
let classs;
if (window.innerWidth < 701) {
classs = 'book-meeting-modal modal modal-desktop'
} else {
classs = 'modal modal-desktop showAsideOptions'
}
const modal = await this.modalController.create({
component: DocumentSetUpMeetingPage,
componentProps: {
subject: this.task.workflowInstanceDataFields.Subject,
document: this.loadedEvent.Attachments[this.dicIndex],
},
cssClass: classs,
backdropDismiss: false
});
modal.onDidDismiss().then(res => {
//this.RouteService.goBack();
});
await modal.present();
}
// efetuar despacho
async openExpedientActionsModal(taskAction: any) {
let classs;
if (window.innerWidth < 701) {
classs = 'modal modal-desktop'
} else {
classs = 'modal modal-desktop showAsideOptions'
}
const modal = await this.modalController.create({
component: ExpedientTaskModalPage,
componentProps: {
taskAction: taskAction,
task: this.task,
seachDocuments: this.loadedEvent.Attachments[this.dicIndex],
aplicationId: this.loadedEvent.Attachments[this.dicIndex].ApplicationId || this.loadedEvent.Attachments[this.dicIndex]['ApplicationID']
},
cssClass: classs,
});
await modal.present();
modal.onDidDismiss().then(async (res) => { });
}
getFromDb() {
}
stringToNumber(number: string) {
return parseInt(number)
}
}
+1 -1
View File
@@ -9,7 +9,7 @@ import { ChatPageRoutingModule } from './chat-routing.module';
import { ChatPage } from './chat.page';
import { RouterModule } from '@angular/router';
import { PipesModule } from 'src/app/pipes/pipes.module';
import { NewEventPageModule } from 'src/app/shared/agenda/new-event/new-event.module';
import { NewEventPageModule } from 'src/app/ui/agenda/component/new-event/new-event.module';
import { AttendeeModalPageModule } from 'src/app/shared/event/attendee-modal/attendee-modal.module';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import { ImageCropperModule } from 'ngx-image-cropper';
@@ -2,7 +2,7 @@ import { Component, OnInit } from '@angular/core';
import { ModalController, NavParams, PopoverController } from '@ionic/angular';
import { EventPerson } from 'src/app/models/eventperson.model';
import { SearchList } from 'src/app/models/search-document';
import { NewEventPage } from 'src/app/pages/agenda/new-event/new-event.page';
import { NewEventPage } from 'src/app/ui/agenda/modal/new-event/new-event.page';
import { SearchPage } from 'src/app/pages/search/search.page';
import { environment } from 'src/environments/environment';
import { ThemeService } from 'src/app/services/theme.service'
@@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HeaderPrPage } from './header-pr.page';
const routes: Routes = [
{
path: '',
component: HeaderPrPage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class HeaderPrPageRoutingModule {}
@@ -0,0 +1,20 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { HeaderPrPageRoutingModule } from './header-pr-routing.module';
import { HeaderPrPage } from './header-pr.page';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
HeaderPrPageRoutingModule
],
declarations: [HeaderPrPage]
})
export class HeaderPrPageModule {}
@@ -0,0 +1,17 @@
<ion-toolbar>
<div class="div-top-header">
<div class="div-search">
<ion-icon src='assets/images/icons-search.svg'></ion-icon>
</div>
<div class="div-logo">
<img src='assets/images/logo-no-bg.png' alt='logo'>
</div>
<div class="div-profile">
<ion-icon src='assets/images/icons-profile-pr.svg'></ion-icon>
<ion-icon class="font-45-rem" *ngIf="loggeduser.Profile == 'MDGPR'" src='assets/images/icons-profile.svg'></ion-icon>
<ion-icon class="font-45-rem" *ngIf="loggeduser.Profile == 'PR' " src='assets/images/icons-profile-pr-header.svg'></ion-icon>
</div>
</div>
</ion-toolbar>
@@ -0,0 +1,49 @@
@import '~src/function.scss';
.div-top-header{
margin: 0 em(20);
background-color: #0782c9;
padding-top: em(15);
border: 0!important;
}
.div-logo{
background: transparent;
width: em(140);
justify-content: center;
display: flex;
}
.div-logo img{
width: 100%;
margin: 0px auto;
}
.div-profile{
font-size: rem(45);
justify-content: flex-end;
display: flex;
}
.desktop{
display: none;
}
@media only screen and (min-width: 1366px) {
.mobile{
display: none !important;
}
.desktop{
display: block;
}
}
.tab{
height: 65px;
cursor: pointer;
user-select: none;
}
.active{
border-top: 7px solid white;
}
@@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { HeaderPrPage } from './header-pr.page';
describe('HeaderPrPage', () => {
let component: HeaderPrPage;
let fixture: ComponentFixture<HeaderPrPage>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ HeaderPrPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(HeaderPrPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,27 @@
import { Component, OnInit } from '@angular/core';
import { LoginUserRespose } from 'src/app/models/user.model';
import { AuthService } from 'src/app/services/auth.service';
import { SessionStore } from 'src/app/store/session.service';
@Component({
selector: 'app-header-pr',
templateUrl: './header-pr.page.html',
styleUrls: ['./header-pr.page.scss'],
})
export class HeaderPrPage implements OnInit {
loggeduser: LoginUserRespose;
constructor(authService: AuthService) {
this.loggeduser = SessionStore.user;
}
ngOnInit() {
}
locationPathname(): string {
return window.location.pathname
}
}
@@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HeaderPage } from './header.page';
const routes: Routes = [
{
path: '',
component: HeaderPage
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class HeaderPageRoutingModule {}
@@ -0,0 +1,21 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { HeaderPageRoutingModule } from './header-routing.module';
import { HeaderPage } from './header.page';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
HeaderPageRoutingModule
],
declarations: [HeaderPage],
exports: [HeaderPage]
})
export class HeaderPageModule {}
@@ -0,0 +1,260 @@
<div class="header-container header-fix" [ngClass]="{'d-none-header':HeaderSettingsService.hideHeader && ActiveTabService.pages.gabineteDetails}" >
<div class="main-tab pb-10 ion-toolbar header-color">
<div class="mobile pt-20 d-flex div-top-header justify-space-between">
<div title="Pesquisa" *ngIf="!hideSearchBtn" class="div-search viewport-font-size">
<div (click)="openSearch()" class="{{Cy.header.b.search}}">
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " class="font-45-em"
src="assets/images/theme/doneIt/icons-search.svg"></ion-icon>
<ion-icon *ngIf=" ThemeService.currentTheme == 'default' " class="font-45-em"
src='assets/images/icons-search.svg'></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="font-45-em"
src='assets/images/theme/gov/icons-search.svg'></ion-icon>
</div>
</div>
<div class="div-logo align-center justify-center">
<div class="logo-icon pr-10-rem">
<img *ngIf="ThemeService.currentTheme == 'default' " src='assets/images/logo-no-bg.png' alt='logo'>
<img *ngIf="ThemeService.currentTheme == 'gov' " src='assets/images/theme/gov/governoangola_A.png' alt='logo'>
<img *ngIf="ThemeService.currentTheme == 'doneIt'" src="assets/images/theme/doneIt/governoangola_A1.png"
alt='logo' />
</div>
<div *ngIf="ThemeService.currentTheme == 'gov'"
class="logo-description d-flex align-center justify-content-center">
<div class="logo-description-content">
<p class="logo-description-text tp-5">{{ environment.logoLabel }}</p>
<div class="add-line"></div>
<p class="logo-description-text tp-5">GABINETE DIGITAL</p>
</div>
</div>
<div *ngIf="ThemeService.currentTheme == 'default' "
class="logo-description d-flex align-center justify-content-center">
<div class="logo-description-content">
<p class="logo-description-text tp-5 color-white">{{ environment.logoLabel }}</p>
<div class="add-line-white"></div>
<p class="logo-description-text tp-5 color-white">GABINETE DIGITAL</p>
</div>
</div>
</div>
<div title="Perfil" class="div-profile cursor-pointer viewport-font-size " >
<div *ngIf="PublicationHolderService.count != 0" style="color: black" style="display: flex;
color: black;
justify-content: center;
align-items: center;
" >
<span *ngIf="!PublicationHolderService.PublicationFormMV?.[0]?.retry">{{ PublicationHolderService.count }}%</span>
<span style="padding-right: 12px" *ngIf="PublicationHolderService.PublicationFormMV?.[0]?.retry" (click)="PublicationHolderService.PublicationFormMV?.[0]?.retryFunction()" ><ion-icon src="assets/images/retry-svgrepo-com.svg" > </ion-icon></span>
<span style="padding-right: 7px" *ngIf="PublicationHolderService.PublicationFormMV?.[0]?.retry" (click)="PublicationHolderService.remove(PublicationHolderService.PublicationFormMV?.[0]?.id)">X</span>
</div>
<!-- <div *ngIf="this.NotificationHolderService.notificationList.length > 0" class="icon-badge">{{NotificationHolderService.notificationList.length}}</div> -->
<!-- <ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " class="icon font-45-em" src='assets/images/theme/doneIt/icons-profile.svg'></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="icon font-45-em" src='assets/images/icons-profile.svg'></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="icon font-45-em" src='assets/images/theme/gov/icons-profile.svg'></ion-icon> -->
<div (click)="openProfile()" *ngIf="profilePictureSubject == undefined " class="profile-image" >
<!-- <img *ngIf="loggeduser.RoleDescription == 'Presidente da República' " class="profile-image"
src='assets/images/presidente.png'>
<img *ngIf="loggeduser.RoleDescription == 'Ministro e Director do Gabinete do PR' " class="profile-image"
src='assets/images/ministro.png'>
<img *ngIf="loggeduser.RoleDescription == 'Secretário Geral' " class="profile-image"
src='assets/images/secretaria_geral.png'> -->
<ion-icon
class="icon font-45-em" src='assets/images/theme/gov/icons-profile.svg'></ion-icon>
</div>
<div (click)="openProfile()" *ngIf="(profilePictureSubject | async) as calendarData" class="profile-image">
<img class="profile-image image-prety" src={{calendarData.base64}}>
</div>
<div class="profile-text" *ngIf="(notificationCount$ | async) as notificationCount ">
<div *ngIf="notificationCount > 0" class="icon-badge" style="right: -6px;top: 38px;top: -6px;">
{{notificationCount}} </div>
</div>
</div>
</div>
<div class="desktop mx-20">
<div class="d-flex justify-space-between align-center">
<div tab="events" class="div-logo height-fit-content">
<div class="logo-icon pr-10-rem">
<img *ngIf="ThemeService.currentTheme == 'default'" src='assets/images/logo-no-bg.png' alt='logo'>
<img *ngIf="ThemeService.currentTheme == 'gov' " src='assets/images/theme/gov/governoangola_A.png'
alt='logo'>
<img *ngIf="ThemeService.currentTheme == 'doneIt' "
src='assets/images/theme/{{ThemeService.currentTheme}}/governoangola_A1.png' alt='logo'>
</div>
<div class="logo-description d-flex align-center justify-content-center">
<div class="logo-description-content">
<div *ngIf="ThemeService.currentTheme == 'gov' " class="logo-description-content">
<p class="logo-description-text">{{ environment.logoLabel }}</p>
<div class="add-line"></div>
<p class="logo-description-text">GABINETE DIGITAL</p>
</div>
<div *ngIf="ThemeService.currentTheme == 'default' " class="logo-description-content">
<p class="logo-description-text" style="color: white;">GABINETE DIGITAL</p>
<div class="add-line" style="border-bottom: 1px solid white;"></div>
</div>
</div>
</div>
</div>
<div class="d-flex flex-1 pr-20 pl-50"
*ngIf="p.userPermissionCount([permissionList.Agenda.access, permissionList.Gabinete.access, permissionList.Actions.access, permissionList.Chat.access]) >= 2 || (p.userPermission([permissionList.Agenda.access]) && loggeduser.OwnerCalendars.length != 0) || p.userPermission([permissionList.Gabinete.access])">
<div
*ngIf="p.userPermission([permissionList.Agenda.access]) || p.userPermission([permissionList.Gabinete.access])"
class="tab mr-20 d-flex align-center cursor-pointer" (click)="changeRoute('/home/events')"
[class.active]="ActiveTabService.pages.home">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' || ThemeService.currentTheme == 'doneIt' "
class="font-40-rem" src='assets/images/icons-nav-home-active-black.svg'></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="font-40-rem"
src='assets/images/theme/gov/icons-nav-home-active-black.svg'></ion-icon>
<span>Início</span>
</div>
<div *ngIf="p.userPermission([permissionList.Agenda.access])"
class="tab mr-20 d-flex align-center cursor-pointer" (click)="changeRoute('/home/agenda')"
[class.active]="ActiveTabService.pages.agenda">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' || ThemeService.currentTheme == 'doneIt' "
class="font-40-rem" src='assets/images/icons-nav-agenda-inactive.svg'></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="font-40-rem"
src='assets/images/theme/gov/icons-nav-agenda-inactive.svg'></ion-icon>
<span>Agenda</span>
</div>
<div *ngIf="p.userPermission([permissionList.Gabinete.access])"
class="tab mr-20 d-flex align-center cursor-pointer" (click)="changeRoute('/home/gabinete-digital')"
[class.active]="ActiveTabService.pages.gabinete">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' || ThemeService.currentTheme == 'doneIt' "
class="font-40-rem" src='assets/images/icons-nav-home-dk.svg'></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="font-40-rem"
src='assets/images/theme/gov/icons-nav-home-dk.svg'></ion-icon>
<span>Gabinete</span>
</div>
<div *ngIf="p.userPermission([permissionList.Actions.access])"
class="tab mr-20 d-flex align-center cursor-pointer" (click)="changeRoute('/home/publications')"
[class.active]="ActiveTabService.pages.publication">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' || ThemeService.currentTheme == 'doneIt' "
class="font-40-rem" src='assets/images/icons-nav-a-es-inactive.svg'></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="font-40-rem"
src='assets/images/theme/gov/icons-nav-a-es-inactive.svg'></ion-icon>
<span>Acções</span>
</div>
<div *ngIf="p.userPermission([permissionList.Chat.access])"
class="tab mr-20 d-flex align-center cursor-pointer" (click)="changeRoute('/home/chat')"
[class.active]="ActiveTabService.pages.chat">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' || ThemeService.currentTheme == 'doneIt' "
class="font-40-rem" src='assets/images/icons-nav-grupos-inactive-dk-white.svg'></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="font-40-rem"
src='assets/images/theme/gov/icons-nav-grupos-inactive-dk-white.svg'></ion-icon>
<span>Chat</span>
</div>
</div>
<div class="header-btns d-flex">
<div *ngIf="PublicationHolderService.count != 0" style="color: black" >
<span *ngIf="!PublicationHolderService.PublicationFormMV?.[0]?.retry">{{ PublicationHolderService.count }}%</span>
<span style="padding-right: 12px" *ngIf="PublicationHolderService.PublicationFormMV?.[0]?.retry" (click)="PublicationHolderService.PublicationFormMV?.[0]?.retryFunction()" ><ion-icon src="assets/images/retry-svgrepo-com.svg" > </ion-icon></span>
<span style="padding-right: 7px" *ngIf="PublicationHolderService.PublicationFormMV?.[0]?.retry" (click)="PublicationHolderService.remove(PublicationHolderService.PublicationFormMV?.[0]?.id)">X</span>
</div>
<div title="Pesquisa" *ngIf="!hideSearchBtn" class="mr-20 d-flex align-center cursor-pointer">
<div style="padding-top: 5px;" (click)="openSearch();showSearch=true" *ngIf="!showSearch">
<ion-icon title="Perfil" *ngIf="ThemeService.currentTheme == 'doneIt' " class="font-45-rem"
src="assets/images/theme/doneIt/icons-search.svg"></ion-icon>
<ion-icon title="Perfil" *ngIf="ThemeService.currentTheme == 'default' " class="font-45-rem"
src='assets/images/icons-search.svg'></ion-icon>
<ion-icon title="Perfil" *ngIf="ThemeService.currentTheme == 'gov' " class="font-45-rem"
src='assets/images/theme/gov/icons-search.svg'></ion-icon>
</div>
<button title="Fechar" class="btn-no-color" (click)="closeSearch();showSearch=false;searchSubject=''"
*ngIf="showSearch">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' || ThemeService.currentTheme == 'doneIt' "
class="font-40-rem" name="restaurant-outline" src="assets/images/icons-search-close.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="font-40-rem" name="restaurant-outline"
src="assets/images/theme/gov/icons-search-close.svg"></ion-icon>
</button>
<div *ngIf="showSearch">
<div class="d-flex search-input-container ml-10 justify-between" *ngIf="showSearch">
<!-- <div class="icon" (click)="basicSearch()">
<ion-icon class="icon-z" slot="end" name="search"></ion-icon>
</div> -->
<!-- <div class="input-text d-flex ion-align-items-center">
<ion-input (keyup.enter)="basicSearch()" [(ngModel)]='searchSubject' (ngModelChange)="dynamicSearch()"
class="search-input text-black" type="search" placeholder="Pesquisar assunto"></ion-input>
</div> -->
<!-- <div class="icon" (click)="clearSearchInput()">
<ion-icon title="Limpar" *ngIf="ThemeService.currentTheme == 'default' "name="restaurant-outline" src="assets/images/icons-search-close.svg"></ion-icon>
<ion-icon title="Limpar" *ngIf="ThemeService.currentTheme == 'doneIt' "name="restaurant-outline" src="assets/images/theme/doneIt/icons-search.svg"></ion-icon>
<ion-icon title="Limpar" *ngIf="ThemeService.currentTheme == 'gov' " name="restaurant-outline" src="assets/images/theme/gov/icons-search-close.svg"></ion-icon>
</div> -->
<!-- <div (click)="basicSearch()" class="d-flex align-center icon">
<ion-icon class="icon-z" slot="end" src="assets/images/theme/gov/search.svg"></ion-icon>
</div> -->
</div>
</div>
</div>
<div title="Perfil" class="div-profile d-flex cursor-pointer font-45-rem" (click)="openProfile()">
<!-- <ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="icon" src='assets/images/icons-profile.svg'></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " class="icon" src='assets/images/theme/doneIt/icons-profile.svg'></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " class="icon" src='assets/images/theme/gov/icons-profile.svg'></ion-icon> -->
<div *ngIf="profilePictureSubject == undefined " class="profile-image">
<!-- <img *ngIf="loggeduser.RoleDescription == 'Presidente da República' " class="profile-image"
src='assets/images/presidente.png'>
<img *ngIf="loggeduser.RoleDescription == 'Ministro e Director do Gabinete do PR' " class="profile-image"
src='assets/images/ministro.png'>
<img *ngIf="loggeduser.RoleDescription == 'Secretário Geral' " class="profile-image"
src='assets/images/secretaria_geral.png'> -->
<ion-icon
class="icon" src='assets/images/theme/gov/icons-profile.svg'></ion-icon>
</div>
<div *ngIf="(profilePictureSubject | async) as calendarData" class="profile-image">
<img class="profile-image font-45-em image-prety" src={{calendarData.base64}}>
</div>
<div class="profile-text" *ngIf="(notificationCount$ | async) as notificationCount ">
<div *ngIf="notificationCount > 0" class="icon-badge" style="right: -6px;top: 38px;top: -6px;">
{{notificationCount}} </div>
</div>
</div>
</div>
</div>
</div>
</div>
<div [class.header-bottom-line]="ThemeService.currentTheme == 'gov'" style="height: 5px;"></div>
</div>
@@ -0,0 +1,180 @@
@import "~src/function.scss";
.div-top-header {
margin: 0 em(20);
// background-color: #0782c9;
//padding-top: em(15px);
border: 0 !important;
}
.profile-image {
vertical-align: middle;
width: 40px;
height: 40px;
border-radius: 50%;
display: block; /* Torna a imagem um elemento de bloco */
margin: 0 auto;
}
.div-logo {
background: transparent;
width: em(140);
justify-content: center;
display: flex;
color: black;
overflow: auto;
.logo-icon {
width: 25.33%;
overflow: auto;
img {
width: 100%;
margin: 0px auto;
}
}
.logo-description {
width: 74.67%;
margin: 0 auto;
overflow: auto;
font-size: 8.5px;
font-family: Bahnschrift;
.logo-description-content {
width: 100%;
.logo-description-text {
font-weight: 700;
text-align: center;
width: 100%;
margin: 0 !important;
padding: 0 !important;
}
.add-line {
width: 100%;
border-bottom: 1px solid #000;
margin-bottom: 2.5px !important;
padding: 0 !important;
}
.add-line-white {
width: 100%;
border-bottom: 1px solid #fff;
margin-bottom: 2.5px !important;
padding: 0 !important;
}
}
.color-white {
color: #fff !important;
}
.add-botton-border {
border-bottom: 1px solid #000;
}
.add-botton-border-white {
border-bottom: 1px solid #fff;
}
}
}
.header-btns {
justify-content: center;
align-items: center;
}
.div-profile {
text-align: center;
background-color: transparent;
display: flex !important;
justify-content:space-around;
border-radius: 50px;
.icon {
position: relative;
border: none !important;
}
.icon-badge {
background-color: red;
font-size: rem(12);
color: white;
text-align: center;
width: 20px;
height: 20px;
border-radius: 35%;
position: absolute; /* changed */
top: 5px; /* changed */
right: 27px; /* changed */
}
.profile-text {
font-size: rem(20);
font-weight: 300;
width: fit-content;
position: absolute;
color: var(--profile-text-color);
}
}
.main-tab {
//border: 1px solid red;
}
.desktop {
display: none;
}
@media only screen and (min-width: 1366px) {
.mobile {
display: none !important;
}
.desktop {
display: block;
}
}
.tab {
height: 65px;
cursor: pointer;
user-select: none;
}
.tab:hover {
border-top: 7px solid var(--header-tab-text-white);
}
.active {
border-top: 7px solid var(--header-tab-text-white);
span {
font-weight: 650;
}
}
.search-input-container {
background-color: white;
border-radius: 27.5px;
border: solid 1px #ebebeb;
.icon {
color: #797979;
width: rem(45);
height: rem(45);
display: flex;
justify-content: center;
font-size: rem(25);
align-items: center;
}
.input-text {
width: 100%;
}
.icon-z {
width: 20px;
}
}
.tab {
color: var(--header-tab-text-white);
}
@@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { HeaderPage } from './header.page';
describe('HeaderPage', () => {
let component: HeaderPage;
let fixture: ComponentFixture<HeaderPage>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ HeaderPage ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(HeaderPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,317 @@
import { Component, OnInit, ChangeDetectorRef, NgZone } from '@angular/core';
import { AnimationController, ModalController, Platform } from '@ionic/angular';
import { SearchPage } from 'src/app/pages/search/search.page';
import { Router } from '@angular/router';
import { LoginUserRespose } from 'src/app/models/user.model';
import { ProfilePage } from 'src/app/modals/profile/profile.page';
import { StorageService } from '../../../../services/storage.service';
import { SessionStore } from 'src/app/store/session.service';
import { environment } from 'src/environments/environment';
import { ThemeService } from '../../../../services/theme.service';
import { RouteService } from 'src/app/services/route.service';
import { PermissionList } from 'src/app/models/permission/permissionList';
import { PermissionService } from 'src/app/services/permission.service';
import { ActiveTabService } from 'src/app/services/active-tab.service';
import { AttachmentsService } from 'src/app/services/attachments.service';
import { NotificationHolderService } from 'src/app/store/notification-holder.service';
import { HeaderSettingsService } from "src/app/services/header-settings.service"
import { PublicationHolderService } from 'src/app/services/publication/publication-holder.service'
import { Cy } from 'cypress/enum'
import { NotificationRepositoryService } from 'src/app/module/notification/data/notification-repository.service';
import { Observable } from 'rxjs';
import { UserRepositoryService } from 'src/app/module/user/data/user-repository.service';
import { UserProfilePicture } from 'src/app/module/user/data/datasource/user-local-repository.service';
import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
import { isHttpError } from 'src/app/services/http.service';
@Component({
selector: 'app-header',
templateUrl: './header.page.html',
styleUrls: ['./header.page.scss'],
})
export class HeaderPage implements OnInit {
searchSubject: string = '';
showSearch = false;
loggeduser: LoginUserRespose;
hideSearchBtn: boolean = false;
notificationdata: any[] = [];
DataArray: Array<object> = [];
notificationLength: number = 0;
SessionStore = SessionStore
check: boolean;
production = environment.production
environment = environment
canOpenSearch = false
showProfileModal = false
permissionList = new PermissionList();
notificationCount: number = 0;
profilePicture = "";
hideHeader = false
hideHeaderValidation() {
const result = this.HeaderSettingsService.hideHeader && this.ActiveTabService.pages.gabineteDetails
if(result != this.hideHeader) {
this.hideHeader = true
}
}
Cy = Cy
notificationCount$: Observable<number>
profilePictureSubject: Observable<UserProfilePicture>
constructor(
private router: Router,
private modalController: ModalController,
private animationController: AnimationController,
public platform: Platform,
public ThemeService: ThemeService,
public RouteService: RouteService,
public p: PermissionService,
public ActiveTabService: ActiveTabService,
private storageService: StorageService,
private zone: NgZone,
private attachmentService: AttachmentsService,
public NotificationHolderService: NotificationHolderService,
public HeaderSettingsService: HeaderSettingsService,
public PublicationHolderService: PublicationHolderService,
private notificationRepositoryService: NotificationRepositoryService,
private UserRepositoryService: UserRepositoryService
) {
this.profilePictureSubject = this.UserRepositoryService.getProfilePictureLive() as any
this.notificationCount$ = this.notificationRepositoryService.getNotificationLiveCount()
this.loggeduser = SessionStore.user;
router.events.subscribe((val) => {
this.hideSearch();
this.showSearch = false;
this.canOpenSearch = true;
this.showProfileModal = false
});
this.updateReciveNotification();
this.updateDeleteNotification();
/* this.notificationService.notificationReceived.subscribe(() => {
console.log('header', 'event.notification')
this.notificationLengthData()
}); */
window['header-updateCount'] = () => {
this.updateCount()
}
}
updateCount = () => {
}
ngOnInit() {
this.hideSearch();
// console.log('Profile picture guid ', this.SessionStore.user.UserPhoto)
this.getProfilpicture();
}
reloadComponent(self: boolean, urlToNavigateTo?: string) {
//skipLocationChange:true means dont update the url to / when navigating
console.log("Current route I am on header:", this.router.url);
const url = self ? this.router.url : urlToNavigateTo;
this.zone.run(() => this.router.navigateByUrl('/', { skipLocationChange: true }).then(() => {
this.zone.run(() => this.router.navigate([`/${url}`]).then(() => {
console.log(`After navigation I am on header:${this.router.url}`)
}))
}))
}
@XTracerAsync({name:'header/getPrfilePicture', bugPrint: true})
async getProfilpicture(tracing?: TracingType) {
if (this.SessionStore.user.UserPhoto) {
const base = await this.UserRepositoryService.getUserProfilePhoto(this.SessionStore.user.UserPhoto, tracing)
if(base.isOk()) {
tracing.addEvent('download image')
this.profilePicture = 'data:image/jpeg;base64,' + base.value;
tracing.setAttribute("picture.save", "true")
tracing.setAttribute("outcome", "success")
} else {
if(!isHttpError(base.error)) {
// this.toastService._badRequest('Pedimos desculpa mas não foi possível executar a acção. Por favor, contacte o apoio técnico.')
} else {
// this.httpErrorHandle.httpStatusHandle(base.error)
}
}
}
}
updateReciveNotification() {
}
updateDeleteNotification() {
}
hideSearch() {
if (this.router.url.startsWith('/home/events') || this.router.url.startsWith('/home/chat')) {
this.hideSearchBtn = true;
} else {
this.hideSearchBtn = false;
}
}
async openSearch() {
let classs, showSearchInput, type;
if (window.innerWidth < 1366) {
classs = 'modal modal-width-100'
showSearchInput = true
} else {
classs = 'modal modal-desktop desktop-search'
showSearchInput = false
}
if (window.location.pathname.startsWith('/home/agenda')) {
type = "Agenda"
} else if (window.location.pathname.startsWith('/home/gabinete-digital')) {
type = "AccoesPresidenciais & ArquivoDespachoElect"
} else if (window.location.pathname.startsWith('/home/publications')) {
type = "AccoesPresidenciais"
}
if (this.canOpenSearch) {
this.canOpenSearch = false
const modal = await this.modalController.create({
component: SearchPage,
cssClass: classs,
componentProps: {
type: type,
showSearchInput: showSearchInput,
select: false
}
});
modal.onDidDismiss().then(() => {
this.canOpenSearch = true;
});
await modal.present();
}
}
changeRoute(path) {
this.router.navigateByUrl(path)
}
async openProfile() {
const enterAnimation = (baseEl: any) => {
const backdropAnimation = this.animationController.create()
.addElement(baseEl.querySelector('ion-backdrop')!)
.fromTo('opacity', '0.01', 'var(--backdrop-opacity)');
const wrapperAnimation = this.animationController.create()
.addElement(baseEl.querySelector('.modal-wrapper')!)
.keyframes([
{ offset: 0, opacity: '1', right: '-100%' },
{ offset: 1, opacity: '1', right: '0px' }
]);
return this.animationController.create()
.addElement(baseEl)
.easing('ease-out')
.duration(500)
.addAnimation([backdropAnimation, wrapperAnimation]);
}
const leaveAnimation = (baseEl: any) => {
return enterAnimation(baseEl).direction('reverse');
}
if (!this.showProfileModal) {
this.showProfileModal = true
const modal = await this.modalController.create({
component: ProfilePage,
cssClass: 'model profile-modal search-submodal',
componentProps: {
}
});
modal.onDidDismiss().then(() => {
this.showProfileModal = false
})
await modal.present();
}
}
async dynamicSearch() {
if (window['dynamicSearch']) {
window['dynamicSearch'](this.searchSubject)
} else {
setTimeout(() => {
this.dynamicSearch()
}, 100)
}
}
async closeSearch() {
this.modalController.dismiss()
}
/**
* @description set empty value to searchSubject
*/
clearSearchInput() {
this.searchSubject = "";
window['dynamicSearch'](this.searchSubject)
}
async basicSearch() {
if (window['searchTriger']) {
window['searchTriger']()
} else {
setTimeout(() => {
this.basicSearch()
}, 100)
}
}
getProfilePictureSorage() {
this.storageService.get(this.SessionStore.user.RoleID.toString()).then((picture) => {
/* console.log(picture) */
this.profilePicture = picture
}).catch((error) => {
this.profilePicture = "";
})
}
}