merge ios

This commit is contained in:
Equilibrium ITO
2024-06-27 16:58:03 +01:00
74 changed files with 1725 additions and 705 deletions
+2 -2
View File
@@ -54,7 +54,7 @@
"vendorChunk": true,
"extractLicenses": false,
"buildOptimizer": false,
"sourceMap": false,
"sourceMap": true,
"optimization": false,
"namedChunks": true
},
@@ -68,7 +68,7 @@
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"sourceMap": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
+3
View File
@@ -11,6 +11,9 @@
},
{
"path": "../../../Downloads/opentelemetry-js-main/opentelemetry-js-main"
},
{
"path": "../grayLog"
}
],
"settings": {
+83 -69
View File
@@ -163,6 +163,7 @@
"ionicons": "^5.5.3",
"jest-puppeteer": "^7.0.1",
"lite-server": "^2.6.1",
"log4js": "^6.9.1",
"minisearch": "^6.0.1",
"moment": "^2.29.3",
"neverthrow": "^6.1.0",
@@ -14522,10 +14523,9 @@
}
},
"node_modules/date-format": {
"version": "4.0.11",
"resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.11.tgz",
"integrity": "sha512-VS20KRyorrbMCQmpdl2hg5KaOUsda1RbnsJg461FfrcyCUg+pkd0b40BSW4niQyTheww4DBXQnS7HwSrKkipLw==",
"dev": true,
"version": "4.0.14",
"resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz",
"integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==",
"engines": {
"node": ">=4.0"
}
@@ -17063,10 +17063,9 @@
}
},
"node_modules/flatted": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz",
"integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==",
"dev": true
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
"integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw=="
},
"node_modules/flatten": {
"version": "1.0.3",
@@ -26587,16 +26586,15 @@
}
},
"node_modules/log4js": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/log4js/-/log4js-6.5.2.tgz",
"integrity": "sha512-DXtpNtt+KDOMT7RHUDIur/WsSA3rntlUh9Zg4XCdV42wUuMmbFkl38+LZ92Z5QvQA7mD5kAVkLiBSEH/tvUB8A==",
"dev": true,
"version": "6.9.1",
"resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz",
"integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==",
"dependencies": {
"date-format": "^4.0.10",
"date-format": "^4.0.14",
"debug": "^4.3.4",
"flatted": "^3.2.5",
"flatted": "^3.2.7",
"rfdc": "^1.3.0",
"streamroller": "^3.1.1"
"streamroller": "^3.1.5"
},
"engines": {
"node": ">=8.0"
@@ -26606,7 +26604,6 @@
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dev": true,
"dependencies": {
"ms": "2.1.2"
},
@@ -33376,8 +33373,7 @@
"node_modules/rfdc": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz",
"integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==",
"dev": true
"integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA=="
},
"node_modules/right-align": {
"version": "0.1.3",
@@ -35535,24 +35531,22 @@
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
},
"node_modules/streamroller": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.1.tgz",
"integrity": "sha512-iPhtd9unZ6zKdWgMeYGfSBuqCngyJy1B/GPi/lTpwGpa3bajuX30GjUVd0/Tn/Xhg0mr4DOSENozz9Y06qyonQ==",
"dev": true,
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz",
"integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==",
"dependencies": {
"date-format": "^4.0.10",
"date-format": "^4.0.14",
"debug": "^4.3.4",
"fs-extra": "^10.1.0"
"fs-extra": "^8.1.0"
},
"engines": {
"node": ">=8.0"
}
},
"node_modules/streamroller/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dev": true,
"version": "4.3.5",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
"integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
"dependencies": {
"ms": "2.1.2"
},
@@ -35566,17 +35560,32 @@
}
},
"node_modules/streamroller/node_modules/fs-extra": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
"dev": true,
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^2.0.0"
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
},
"engines": {
"node": ">=12"
"node": ">=6 <7 || >=8"
}
},
"node_modules/streamroller/node_modules/jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
"optionalDependencies": {
"graceful-fs": "^4.1.6"
}
},
"node_modules/streamroller/node_modules/universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
"engines": {
"node": ">= 4.0.0"
}
},
"node_modules/string_decoder": {
@@ -55162,10 +55171,9 @@
"integrity": "sha512-6ujwvwgPID6zbI0o7UbURi2vlLDR9uP26+tW6Lg+Ji3w7dd0i3DOcjcClLjLPranT60SSEFBwdSyYwn/ZkPIuw=="
},
"date-format": {
"version": "4.0.11",
"resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.11.tgz",
"integrity": "sha512-VS20KRyorrbMCQmpdl2hg5KaOUsda1RbnsJg461FfrcyCUg+pkd0b40BSW4niQyTheww4DBXQnS7HwSrKkipLw==",
"dev": true
"version": "4.0.14",
"resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz",
"integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg=="
},
"dayjs": {
"version": "1.11.8",
@@ -57117,10 +57125,9 @@
}
},
"flatted": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz",
"integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==",
"dev": true
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
"integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw=="
},
"flatten": {
"version": "1.0.3",
@@ -64567,23 +64574,21 @@
}
},
"log4js": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/log4js/-/log4js-6.5.2.tgz",
"integrity": "sha512-DXtpNtt+KDOMT7RHUDIur/WsSA3rntlUh9Zg4XCdV42wUuMmbFkl38+LZ92Z5QvQA7mD5kAVkLiBSEH/tvUB8A==",
"dev": true,
"version": "6.9.1",
"resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz",
"integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==",
"requires": {
"date-format": "^4.0.10",
"date-format": "^4.0.14",
"debug": "^4.3.4",
"flatted": "^3.2.5",
"flatted": "^3.2.7",
"rfdc": "^1.3.0",
"streamroller": "^3.1.1"
"streamroller": "^3.1.5"
},
"dependencies": {
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dev": true,
"requires": {
"ms": "2.1.2"
}
@@ -69731,8 +69736,7 @@
"rfdc": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz",
"integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==",
"dev": true
"integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA=="
},
"right-align": {
"version": "0.1.3",
@@ -71425,35 +71429,45 @@
}
},
"streamroller": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.1.tgz",
"integrity": "sha512-iPhtd9unZ6zKdWgMeYGfSBuqCngyJy1B/GPi/lTpwGpa3bajuX30GjUVd0/Tn/Xhg0mr4DOSENozz9Y06qyonQ==",
"dev": true,
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz",
"integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==",
"requires": {
"date-format": "^4.0.10",
"date-format": "^4.0.14",
"debug": "^4.3.4",
"fs-extra": "^10.1.0"
"fs-extra": "^8.1.0"
},
"dependencies": {
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dev": true,
"version": "4.3.5",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
"integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
"requires": {
"ms": "2.1.2"
}
},
"fs-extra": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
"dev": true,
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
"requires": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^2.0.0"
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
}
},
"jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
"requires": {
"graceful-fs": "^4.1.6"
}
},
"universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
}
}
},
+1
View File
@@ -179,6 +179,7 @@
"ionicons": "^5.5.3",
"jest-puppeteer": "^7.0.1",
"lite-server": "^2.6.1",
"log4js": "^6.9.1",
"minisearch": "^6.0.1",
"moment": "^2.29.3",
"neverthrow": "^6.1.0",
+4 -2
View File
@@ -17,6 +17,7 @@ import { RoleIdService } from 'src/app/services/role-id.service';
import { ActiveTabService } from 'src/app/services/active-tab.service';
import { Device } from '@capacitor/device';
import { RouteService } from 'src/app/services/route.service';
// import { LoggingService } from 'src/app/services/logger/log4js/logging.service';
import { CaptureLogService } from 'src/app/services/monitoring/capture-log/capture-log.service';
import { NetworkServiceService, ConnectionStatus } from 'src/app/services/network-service.service';
import { UserSession } from '../models/user.model';
@@ -104,7 +105,8 @@ export class HomePage implements OnInit {
private RoleIdService: RoleIdService,
private zone: NgZone,
public alertController: AlertController,
public CaptureLogService: CaptureLogService
public CaptureLogService: CaptureLogService,
// private LoggingService: LoggingService
// private ChunkService: ChunkService,
// private StreamService: StreamService
@@ -187,7 +189,7 @@ export class HomePage implements OnInit {
if ("serviceWorker" in navigator) {
navigator.serviceWorker.onmessage = (event) => {
console.log('Mensagem recebida do Service Worker:', event.data.data);
console.log('Mensagem recebida do Service Worker:', event.data);
let object = {
notification: event.data
}
+5 -27
View File
@@ -2,32 +2,8 @@ import { Injectable } from '@angular/core';
import { HTTP_INTERCEPTORS, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { metrics } from '@opentelemetry/api';
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
import { MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
import { meter, RequestCounter } from '../services/monitoring/opentelemetry/matrix';
// Initialize OpenTelemetry metrics
const meterProvider = new MeterProvider();
metrics.setGlobalMeterProvider(meterProvider);
if (window.location.protocol !== 'https:') {
const metricReader = new PeriodicExportingMetricReader({
exporter: new OTLPMetricExporter({
url: 'http://5-180-182-151.cloud-xip.com:4318/v1/metrics',
// headers: {
// 'Authorization': 'Basic ' + btoa('tabteste@006:tabteste@006'),
// }
}),
exportIntervalMillis: 3000,
});
meterProvider.addMetricReader(metricReader);
}
const meter = meterProvider.getMeter('example-exporter-collector');
const requestCounter = meter.createCounter('post_requests', {
description: 'Example of a Counter',
});
@Injectable()
export class MetricsInterceptor implements HttpInterceptor {
@@ -37,13 +13,15 @@ export class MetricsInterceptor implements HttpInterceptor {
if (event instanceof HttpResponse) {
// Capture the status code and check protocol
if (req.method !== 'GET' && !req.urlWithParams.includes('metrics')) {
console.log('response', event.body)
const path = req.urlWithParams;
const url = new URL(path);
if (window.location.protocol !== 'https:') {
let attributes = { path: url.pathname, method: req.method };
const statusCode = event.status;
const extendedAttributes = { ...attributes, status: statusCode };
requestCounter.add(1, extendedAttributes);
RequestCounter.add(1, extendedAttributes);
}
}
}
@@ -56,4 +34,4 @@ export const metricsInterceptor = {
provide: HTTP_INTERCEPTORS,
useClass: MetricsInterceptor,
multi: true
};
};
@@ -8,7 +8,6 @@ import {
HTTP_INTERCEPTORS,
HttpClient,
} from "@angular/common/http";
import { AuthService } from '../services/auth.service';
import { Observable, throwError, BehaviorSubject, of } from "rxjs";
import { catchError, filter, take, switchMap, tap } from "rxjs/operators";
import { SessionStore } from '../store/session.service';
+23 -16
View File
@@ -40,7 +40,7 @@
<div class="d-flex align-center flex-column">
<div *ngIf="profilePicture == ''">
<img
<img
class="profile-pic" src="assets/images/theme/gov/icons-profile.svg">
<!-- <img *ngIf="SessionStore.user.RoleDescription == 'Presidente da República' " class="profile-pic"
@@ -55,7 +55,7 @@
<img class="profile-pic"
src={{profilePicture}}>
</div>
<!-- <ion-icon *ngIf="ThemeService.currentTheme == 'default' " class="profile-pic"
src="assets/images/icons-default-profile.svg"></ion-icon>
@@ -93,25 +93,32 @@
<div class="notifications-content height-100">
<ion-list>
<ion-list *ngIf="(notificationList$ | async) as notificationList">
<div class="item cursor-pointer ion-no-padding ion-no-margin" lines="none"
*ngFor="let item of NotificationHolderService.notificationList; let i = index">
*ngFor="let item of notificationList; let i = index">
<div *ngIf="item.status==false" class="item-conten1 item-conten-{{item.service}}-{{item.typeAgenda}}-{{item.role}}" (click)="notificatinsRoutes(item.index, item)">
<div *ngIf="item.read == false" class="item-conten-{{item.Service}}-{{item.TypeAgenda}}-{{item.Role}}" (click)="notificatinsRoutes(item.index,item.Service,item.Object,item.IdObject,item.FolderId,i)">
<div class="notification-item">
<img class="notification-icon" slot="end" *ngIf = "item.Service == 'agenda'" src="assets/images/icons-default-agenda.svg" >
<img class="notification-icon" slot="end" *ngIf = "item.Service == 'gabinete-digital'" src="assets/images/icons-correspondencias.svg" >
<img class="notification-icon" slot="end" *ngIf = "item.Service == 'accoes'" src="assets/images/icons-nav-accoes-active.svg" >
<img class="notification-icon" slot="end" *ngIf = "item.Service == 'chat'" src="assets/images/icons-nav-agenda-active.svg" >
<img class="notification-icon" slot="end" *ngIf = "item.service == 'agenda'" src="assets/images/icons-default-agenda.svg" >
<img class="notification-icon" slot="end" *ngIf = "item.service == 'gabinete-digital'" src="assets/images/icons-correspondencias.svg" >
<img class="notification-icon" slot="end" *ngIf = "item.service == 'accoes'" src="assets/images/icons-nav-accoes-active.svg" >
<img class="notification-icon" slot="end" *ngIf = "item.service == 'chat'" src="assets/images/icons-nav-agenda-active.svg" >
</div>
<div class="approve-event-time">
<p *ngIf = "item.Service == 'agenda'">{{item.dateInit}}</p>
<p *ngIf = "item.Service == 'agenda'">{{item.dateEnd}}</p>
<div class="approve-event-time" *ngIf = "item.service == 'agenda'">
<div *ngIf="isValidDate(item.dateInit)">
<p *ngIf="toDateString(item.dateInit) == toDateString(item.dateEnd)">{{item.dateInit | date: 'HH:mm'}} </p>
<p *ngIf="toDateString(item.dateInit) == toDateString(item.dateEnd)">{{item.dateEnd | date: 'HH:mm'}}</p>
<p *ngIf="toDateString(item.dateInit) != toDateString(item.dateEnd)">{{item.dateInit | date: 'd/M/yy' }}</p>
<p *ngIf="toDateString(item.dateInit) != toDateString(item.dateEnd)">{{ item.dateEnd | date: 'dd/M/yy'}} </p>
</div>
</div>
<div class="approve-event-detail">
<h3 id="profile-title">{{item.title}}</h3>
<p *ngIf = "item.Service == 'agenda'">{{item.Location}}</p>
<p id="profile-title" *ngIf = "item.Service != 'agenda'">{{item.body}}</p>
<p *ngIf = "item.service == 'agenda'">{{item.location}}</p>
<p id="profile-title" *ngIf = "item.service != 'agenda'">{{item.body}}</p>
</div>
</div>
@@ -119,7 +126,7 @@
<div class="notification-item">
<img class="notification-icon-error" slot="end" src="assets/images/exclamation_mark.svg" >
</div>
<div class="approve-event-detail-error">
<p id="profile-title-error">Possivelmente esta tarefa não foi criada ou já foi executada. Deseja dar a notificação como lida?</p>
</div>
@@ -143,4 +150,4 @@
</div>
</ion-content>
</ion-content>
+12 -9
View File
@@ -136,16 +136,19 @@ ion-list {
.notifications-content {
padding: 0px 20px;
.item {
border-radius: 15px;
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.07);
border: solid 1px #e9e9e9;
background-color: var(--white);
margin: 0 auto;
padding: 10px;
margin-bottom: 10px;
color: #000;
overflow: hidden;
.item-conten1{
border-radius: 15px;
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.07);
border: solid 1px #e9e9e9;
background-color: var(--white);
margin: 0 auto;
padding: 10px;
margin-bottom: 10px;
color: #000;
overflow: hidden;
}
.notification-item {
width: fit-content;
float: left;
+122 -75
View File
@@ -1,7 +1,6 @@
import { Component, OnInit, NgZone } from '@angular/core';
import { NavigationExtras, Router } from '@angular/router';
import { AnimationController, ModalController, Platform } from '@ionic/angular';
import { LoginUserRespose } from 'src/app/models/user.model';
import { AuthService } from 'src/app/services/auth.service';
import { EditProfilePage } from './edit-profile/edit-profile.page';
import { StorageService } from '../../services/storage.service';
@@ -13,7 +12,13 @@ import { environment } from 'src/environments/environment';
import { ProcessesService } from 'src/app/services/processes.service';
import { EventsService } from 'src/app/services/events.service';
import { NotificationHolderService } from 'src/app/store/notification-holder.service';
import { TracingType, XTracer } from 'src/app/services/monitoring/opentelemetry/tracer';
import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
import { AgendaDataRepositoryService } from 'src/app/services/Repositorys/Agenda/agenda-data-repository.service';
import { ToastService } from 'src/app/services/toast.service';
import { NotificationRepositoryService } from 'src/app/module/notification/data/notification-repository.service';
import { Observable } from 'rxjs';
import { NotificationTable } from 'src/app/module/notification/data/infra/db/notification.db';
import { isHttpError } from 'src/app/services/http.service';
@Component({
selector: 'app-profile',
@@ -44,6 +49,9 @@ export class ProfilePage implements OnInit {
SessionStore = SessionStore;
notificationList$: Observable<NotificationTable[]>
constructor(
private modalController: ModalController,
private animationController: AnimationController,
@@ -58,44 +66,46 @@ export class ProfilePage implements OnInit {
private eventsService: EventsService,
private storageService: StorageService,
public NotificationHolderService: NotificationHolderService,
private authservice: AuthService
private authservice: AuthService,
private agendaDataRepository: AgendaDataRepositoryService,
private toastService: ToastService,
private notificationRepositoryService: NotificationRepositoryService
) {
this.notificationList$ = this.notificationRepositoryService.getNotificationLive()
window['e'] = () => {
console.log(
this.zone.run(() => this.router.navigate(['/home/chat']))
)
}
router.events.subscribe((val) => {
this.isProfileOpen = false
this.logoutOut = true
});
/* this.eventTriger.getObservable().subscribe((event) => {
if (event.notification == "recive") {
this.getNotificationData();
} else if (event.notification == "deleted") {
console.log('header', event.notification)
this.getNotificationData();
}
}); */
/* this.notificationService.notificationReceived.subscribe(() => {
this.getNotificationData();
}); */
setTimeout(() => {
this.hideImage = true
}, 2000)
this.notificationRepositoryService.init()
}
ngOnInit() {
// this.getNotificationData();
this.getProfilpicture();
}
toDateString(e) {
return new Date(e).toDateString()
}
isValidDate(dateString) {
const date = new Date(dateString);
return !isNaN(date.getTime());
}
getProfilpicture() {
@@ -212,99 +222,136 @@ export class ProfilePage implements OnInit {
return time;
}
@XTracer({name:'profile/notificatinsRoutes', bugPrint: true, module:'notification'})
notificatinsRoutes (index, Service, Object, IdObject, FolderId, i, tracing?: TracingType) {
@XTracerAsync({name:'profile/notificationClick', bugPrint: true, module:'notification'})
async notificatinsRoutes (index, item: NotificationTable, tracing?: TracingType) {
console.log(index, i)
console.log({item})
this.notificationRepositoryService.notificationStatus(item)
try {
if (Service === "agenda") {
if (item.service === "agenda") {
this.isloading = true
if (Service === "agenda" && IdObject.length > 10) {
this.eventsService.getEvent(IdObject).subscribe((task) => {
if (item.service === "agenda") {
this.zone.run(() => this.router.navigate(['/home/agenda', IdObject, 'agenda']));
this.deleteNotification(index);
this.isloading = false
let res = await this.agendaDataRepository.getEventById(item.idObject, tracing)
}, (error) => {
this.NotificationHolderService.notificationList[i].read = true;
this.isloading = false
})
}
if(item.idObject) {
if (Service === "agenda" && Object === "event-list") {
if(res.isOk()) {
this.zone.run(() => this.router.navigate(['/home/agenda', item.idObject, 'agenda']));
this.deleteNotification(index);
tracing.setAttribute('outcome', 'success')
} else {
tracing.setAttribute('outcome', 'success')
tracing.setAttribute('data.exist', 'false')
this.NotificationHolderService.notificationList[index].read = true;
if (isHttpError(res.error)) {
if(res.error.status == 404) {
this.toastService._badRequest('Este evento já não existe')
this.notificationRepositoryService.localNotificationStatus(item)
}
}
}
} else {
tracing.setAttribute('data.IdObject', 'false')
this.toastService._badRequest('Pedimos desculpa mas não foi possível executar a acção. Por favor, contacte o apoio técnico. #01')
}
this.isloading = false
} else if (item.service === "agenda" && item.object === "event-list") {
this.isloading = true
this.processesService.GetTask(IdObject).subscribe((task) => {
console.log('evento exist')
this.zone.run(() => this.router.navigate(['/home/agenda/event-list/approve-event', IdObject, 'agenda']));
this.deleteNotification(index);
this.isloading = false
}, (error) => {
console.log('evento não existe')
this.NotificationHolderService.notificationList[i].read = true;
this.isloading = false
})
if(item.idObject) {
let res = await this.agendaDataRepository.getEventById(item.idObject, tracing)
if(res.isOk()) {
console.log('evento exist')
tracing.setAttribute('outcome', 'success')
this.zone.run(() => this.router.navigate(['/home/agenda/event-list/approve-event', item.idObject, 'agenda']));
this.deleteNotification(index);
this.isloading = false
} else {
tracing.setAttribute('outcome', 'success')
console.log('evento não existe')
tracing.setAttribute('data.exist', 'false')
// this.NotificationHolderService.notificationList[index].read = true;
this.isloading = false
}
} else {
tracing.setAttribute('data.IdObject', 'false')
this.toastService._badRequest('Pedimos desculpa mas não foi possível executar a acção. Por favor, contacte o apoio técnico. #01')
}
this.isloading = false
} else {
tracing.setAttribute('notification.route', 'false')
tracing.setAttribute('outcome', 'failed')
tracing.setAttribute('parameters', JSON.stringify({Service:item.service, Object:item.object, IdObject:item.idObject, FolderId:item.folderId}))
}
} else if (Service === "gabinete-digital") {
} else if (item.service === "gabinete-digital") {
this.isloading = true
this.processesService.GetTask(IdObject).subscribe((task) => {
this.processesService.GetTask(item.idObject).subscribe((task) => {
if (Service === "gabinete-digital" && Object === "expedientes") {
this.zone.run(() => this.router.navigate(['/home/gabinete-digital/expediente', IdObject, 'gabinete-digital']));
} else if (Service === "gabinete-digital" && Object === "despachos") {
this.zone.run(() => this.router.navigate(['/home/gabinete-digital/despachos', IdObject, 'gabinete-digital'], { replaceUrl: true }));
} else if (Service === "gabinete-digital" && Object === "parecer") {
if (item.service === "gabinete-digital" && item.object === "expedientes") {
this.zone.run(() => this.router.navigate(['/home/gabinete-digital/expediente', item.idObject, 'gabinete-digital']));
} else if (item.service === "gabinete-digital" && item.object === "despachos") {
this.zone.run(() => this.router.navigate(['/home/gabinete-digital/despachos', item.idObject, 'gabinete-digital'], { replaceUrl: true }));
} else if (item.service === "gabinete-digital" && item.object === "parecer") {
this.zone.run(() => this.router.navigate(['/home/gabinete-digital/pedidos', IdObject, 'gabinete-digital']));
this.zone.run(() => this.router.navigate(['/home/gabinete-digital/pedidos', item.idObject, 'gabinete-digital']));
}
else if (Service === "gabinete-digital" && Object === "deferimento") {
else if (item.service === "gabinete-digital" && item.object === "deferimento") {
this.zone.run(() => this.router.navigate(['/home/gabinete-digital/pedidos', IdObject, 'gabinete-digital']));
this.zone.run(() => this.router.navigate(['/home/gabinete-digital/pedidos', item.idObject, 'gabinete-digital']));
}
else if (Service === "gabinete-digital" && Object === "despachos-pr") {
else if (item.service === "gabinete-digital" && item.object === "despachos-pr") {
this.zone.run(() => this.router.navigate(['/home/gabinete-digital/despachos-pr', IdObject, 'gabinete-digital']));
}else if (Service === "gabinete-digital" && Object === "diplomas") {
this.zone.run(() => this.router.navigate(['/home/gabinete-digital/diplomas', IdObject, 'gabinete-digital']));
this.zone.run(() => this.router.navigate(['/home/gabinete-digital/despachos-pr', item.idObject, 'gabinete-digital']));
}else if (item.service === "gabinete-digital" && item.object === "diplomas") {
this.zone.run(() => this.router.navigate(['/home/gabinete-digital/diplomas', item.idObject, 'gabinete-digital']));
}
else if (Service === "gabinete-digital" && Object === "diplomas-assinar") {
else if (item.service === "gabinete-digital" && item.object === "diplomas-assinar") {
this.zone.run(() => this.router.navigate(['/home/gabinete-digital/diplomas-assinar', IdObject, 'gabinete-digital']));
this.zone.run(() => this.router.navigate(['/home/gabinete-digital/diplomas-assinar', item.idObject, 'gabinete-digital']));
}
else if (Service === "gabinete-digital" && Object === "diploma-revisao") {
else if (item.service === "gabinete-digital" && item.object === "diploma-revisao") {
this.zone.run(() => this.router.navigate(['/home/gabinete-digital/diplomas', IdObject, 'gabinete-digital']));
this.zone.run(() => this.router.navigate(['/home/gabinete-digital/diplomas', item.idObject, 'gabinete-digital']));
}
else if (Service === "gabinete-digital" && Object === "expedientes-pr") {
this.zone.run(() => this.router.navigate(['/home/gabinete-digital/expedientes-pr', IdObject, 'gabinete-digital']));
else if (item.service === "gabinete-digital" && item.object === "expedientes-pr") {
this.zone.run(() => this.router.navigate(['/home/gabinete-digital/expedientes-pr', item.idObject, 'gabinete-digital']));
}
this.deleteNotification(index);
this.isloading = false
}, (error) => {
this.NotificationHolderService.notificationList[i].read = true;
// this.NotificationHolderService.notificationList[i].read = true;
this.isloading = false
})
} else if (Service === "accoes") {
if (Service === "accoes" && Object === "accao") {
this.zone.run(() => this.router.navigate(['/home/publications', IdObject]));
} else if (item.service === "accoes") {
if (item.service === "accoes" && item.idObject === "accao") {
this.zone.run(() => this.router.navigate(['/home/publications', item.idObject]));
this.deleteNotification(index);
}
else if (Service === "accoes" && Object === "publicacao") {
this.zone.run(() => this.router.navigate(['/home/publications/view-publications', FolderId, IdObject]));
else if (item.service === "accoes" && item.idObject === "publicacao") {
this.zone.run(() => this.router.navigate(['/home/publications/view-publications', item.folderId, item.idObject]));
this.deleteNotification(index);
}
} else if (Service === "chat") {
} else if (item.service === "chat") {
let navigationExtras: NavigationExtras = { queryParams: { "roomId": IdObject, } };
let navigationExtras: NavigationExtras = { queryParams: { "roomId": item.idObject, } };
this.zone.run(() => this.router.navigate(['/home/chat']));
@@ -316,18 +363,18 @@ export class ProfilePage implements OnInit {
this.deleteNotification(index);
} else {
console.log({Service, Object, IdObject, FolderId})
console.log({service:item.service, Object, IdObject:item.idObject, FolderId:item.folderId})
tracing.setAttribute('notification.route', 'false')
tracing.setAttribute('outcome', 'failed')
tracing.setAttribute('parameters', JSON.stringify({Service, Object, IdObject, FolderId}))
tracing.setAttribute('parameters', JSON.stringify({Service:item.service, Object, IdObject:item.idObject, FolderId:item.folderId}))
}
} catch(error) {
console.log({Service, Object, IdObject, FolderId})
console.log({service:item.service, Object, IdObject:item.idObject, FolderId: item.folderId})
tracing.setAttribute('outcome', 'failed')
tracing.setAttribute('parameters', JSON.stringify({Service, Object, IdObject, FolderId}))
tracing.setAttribute('parameters', JSON.stringify({service:item.service, Object, IdObject:item.idObject, FolderId:item.folderId}))
tracing.setAttribute('error', JSON.stringify(error))
}
@@ -92,6 +92,55 @@ export class ViewDocumentPage implements OnInit {
}
// @XTracerAsync({name:'view-document/LoadViewer', bugPrint: true, daley: 4000})
// async LoadViewer(tracing?: TracingType) {
// this.processes.GetViewer(this.docId, this.applicationId).subscribe(async(res)=> {
// const link: string = res.replace('//pdfjs/web/', '/pdfjs/web/')
// this.trustedUrl = this.sanitazer.bypassSecurityTrustResourceUrl(link);
// // const iframe = document.getElementById("iframe")
// // const handleLoad = () => {
// // this.loader = false
// // };
// // iframe.addEventListener('load', handleLoad, true)
// if(res == "") {
// const alert = await this.alertController.create({
// cssClass: 'my-custom-class',
// //header: 'Apagar evento!',
// message: 'Sem imagem',
// buttons: [
// {
// text: 'Sim',
// handler: () => {
// this.close();
// }
// }
// ]
// });
// }
// tracing.setAttribute('outcome', 'success')
// }, (error)=>{
// if(isHttpError(error)) {
// tracing?.setAttribute('status.code', error.status.toString())
// if (error.status == 400) {
// tracing?.bugFlag()
// tracing?.setAttribute('outcome', 'failed')
// }
// }
// tracing.setAttribute('outcome', 'failed')
// this.close();
// });
// }
close() {
this.modalController.dismiss();
}
+1 -1
View File
@@ -123,7 +123,7 @@ export class ViewEventPage implements OnInit {
ev.target.complete();
}
@XTracerAsync({name:'ViewEventPage/loadEvent', bugPrint: true})
@XTracerAsync({name:'mobile/loadEventDetails', bugPrint: true})
async loadEvent(tracing?: TracingType) {
const loader = this.toastService.loading();
+3 -2
View File
@@ -4,7 +4,7 @@ import { z } from 'zod';
const eventListSchema = z.array(z.object({
HasAttachments: z.boolean(),
IsAllDayEvent: z.boolean(),
EventId: z.string(),
EventId: z.any(),
Subject: z.string(),
Location: z.string().nullable(),
CalendarId: z.string(),
@@ -16,7 +16,8 @@ const eventListSchema = z.array(z.object({
OptionalAttendees: z.string().nullable(),
HumanDate: z.string(),
TimeZone: z.string(),
IsPrivate: z.boolean()
IsPrivate: z.boolean(),
createdAt: z.string()
}));
export type EventList = z.infer<typeof eventListSchema>
+1 -3
View File
@@ -2,9 +2,7 @@ export class SearchList {
ApplicationType: number | string;
Assunto: string;
Data: string;
DocTypeDesc: string;
EntidadeOrganicaId: number;
EntidadeOrganicaNome: string;
DocTypeDesc?: 'Acções' | 'Publicações';
Id: string;
appName?: string;
ApplicationName: string;
@@ -0,0 +1,37 @@
import { z } from "zod";
import { NotificationTable } from '../../infra/db/notification.db'
type Changes = {
insert: NotificationTable[];
update: NotificationTable[];
remove: NotificationTable[];
};
export function NotificationListChanges(
localList: NotificationTable[],
serverList: NotificationTable[]
): Changes {
const changes: Changes = { insert: [], update: [], remove: [] };
const localMap = new Map(localList.map(item => [item.notificationId, item]));
const serverMap = new Map(serverList.map(item => [item.notificationId, item]));
// Detect new or updated items
for (const [id, serverItem] of serverMap) {
const localItem = localMap.get(id);
if (!localItem) {
changes.insert.push(serverItem);
} else if (localItem.status !== serverItem.status) {
changes.update.push(serverItem);
}
}
// Detect deleted items
for (const [id, localItem] of localMap) {
if (!serverMap.has(id)) {
changes.remove.push(localItem);
}
}
return changes;
}
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { FirebasePushNotificationService } from './firebase-push-notification.service';
describe('FirebasePushNotificationService', () => {
let service: FirebasePushNotificationService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(FirebasePushNotificationService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
@@ -0,0 +1,80 @@
import { Injectable } from '@angular/core';
import { AlertController, Platform } from '@ionic/angular';
import { Capacitor } from '@capacitor/core';
import { ActionPerformed, PushNotifications, PushNotificationSchema } from '@capacitor/push-notifications';
import { AngularFireMessaging } from '@angular/fire/messaging';
@Injectable({
providedIn: 'root'
})
export class FirebasePushNotificationService {
isPushNotificationsAvailable = Capacitor.isPluginAvailable('PushNotifications');
active = false
constructor(
private platform: Platform,
private afMessaging: AngularFireMessaging,
) {}
onReceiveBackground(callback: Function) {
if (this.platform.is('mobile')) {
if (!this.isPushNotificationsAvailable) {
return false
}
PushNotifications.addListener('pushNotificationActionPerformed',
(notification: ActionPerformed) => {
this.active = true
callback(notification)
console.log('NOtification Listener Backgroud', notification)
}
);
} else {
try {
navigator.serviceWorker.onmessage = (event) => {
console.log('Mensagem recebida do Service Worker:', event.data);
let object = {
notification: event.data
}
callback(object)
if (event.data.notificationClicked) {
console.log('Notificação push do Firebase clicada em segundo plano!');
}
};
} catch(e) {
console.log(e)
}
}
}
onReceiveForeground(callback: Function) {
if (this.platform.is('mobile')) {
if (!this.isPushNotificationsAvailable) {
return false
}
PushNotifications.addListener('pushNotificationReceived',
(notification: PushNotificationSchema) => {
this.active = true
console.log('NOtification Listener', notification)
callback(notification)
}
);
} else {
this.afMessaging.messages.subscribe((notification) => {
console.log('NOtification Listener', notification)
callback(notification)
// Handle the received message, e.g., show a notification
});
}
}
}
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { LocalNotificationService } from './local-notification.service';
describe('LocalNotificationService', () => {
let service: LocalNotificationService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(LocalNotificationService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
@@ -0,0 +1,86 @@
import { Injectable } from '@angular/core';
import { NotificationDataSource, NotificationTable, NotificationTableSchema } from '../infra/db/notification.db';
import { err, ok } from 'neverthrow';
import { from } from 'rxjs';
import { liveQuery } from 'Dexie';
@Injectable({
providedIn: 'root'
})
export class LocalNotificationService {
constructor() { }
async addNotification(data: NotificationTable) {
// db.eve
try {
const result = await NotificationDataSource.notification.add(data)
return ok(result)
} catch (e) {
return err(false)
}
}
async updateNotification(data: NotificationTable) {
// db.eve
try {
const result = await NotificationDataSource.notification.update(data.notificationId, data)
return ok(result)
} catch (e) {
return err(false)
}
}
async updateNotifications(data: NotificationTable[]) {
// db.eve
try {
const result = await NotificationDataSource.notification.bulkUpdate(data.map(e => ({
key: e.notificationId,
changes: { status: e.status }
})))
return ok(result)
} catch (e) {
return err(false)
}
}
async addNotifications(notifications: NotificationTable[]) {
// Validate each notification
const failed = []
const validNotifications = notifications.filter(notification => {
const result = NotificationTableSchema.safeParse(notification);
if(!result.success) {
failed.push(notification)
}
return result.success;
});
// Add valid notifications to the database
if (validNotifications.length > 0) {
await NotificationDataSource.notification.bulkAdd(validNotifications);
} else {
console.log('No valid notifications to add.');
}
console.log({failed})
return ok(failed)
}
getNotificationLive() {
return from(liveQuery( () => {
return NotificationDataSource.notification.orderBy('createdAt').reverse().toArray()
}))
}
async getNotification() {
return NotificationDataSource.notification.toArray()
}
clear() {
return NotificationDataSource.notification.clear()
}
}
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { RemoteNotificationService } from './remote-notification.service';
describe('RemoteNotificationService', () => {
let service: RemoteNotificationService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(RemoteNotificationService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
@@ -0,0 +1,29 @@
import { Injectable } from '@angular/core';
import { HttpService } from 'src/app/services/http.service';
import { NotificationInputDTO } from '../dto/NotificationInputDTO';
import { NotificationOutputDTO, NotificationOutputDTOSchema } from '../dto/NotificationOutputDTO';
import { APIReturn } from 'src/app/services/decorator/api-validate-schema.decorator';
@Injectable({
providedIn: 'root'
})
export class RemoteNotificationService {
private baseUrl = 'https://gdapi-dev.dyndns.info/stage/api/v2';
constructor(
private httpService: HttpService
) { }
@APIReturn(NotificationOutputDTOSchema, 'Get/Notifications')
async getNotification(queryParameter: NotificationInputDTO) {
return await this.httpService.get<NotificationOutputDTO>(`${this.baseUrl}/Notifications`, queryParameter);
}
async notificationStatus(id: string) {
return await this.httpService.patch<NotificationOutputDTO>(`${this.baseUrl}/Notifications/${id}/status`);
}
}
@@ -0,0 +1,9 @@
import { z } from 'zod';
export const NotificationInputDTOSchema = z.object({
userId: z.string(),
PageNumber: z.string(),
PageSize: z.string(),
})
export type NotificationInputDTO = z.infer<typeof NotificationInputDTOSchema>;
@@ -0,0 +1,31 @@
import { z } from 'zod';
export const NotificationOutputDTOSchema = z.object({
success: z.boolean(),
message: z.string(),
data: z.object({
total: z.number(),
result: z.array(
z.object({
id: z.string(),
service: z.string(),
title: z.string(),
body: z.string(),
object: z.string(),
objectId: z.string(),
folderId: z.string().nullable(),
createdAt: z.string(),
viewDate: z.string().nullable(),
status: z.boolean(),
startDate: z.string().nullable(),
endDate: z.string().nullable(),
bodyEvent: z.string().nullable(),
location: z.string().optional().nullable(),
})
)
}),
})
export type NotificationOutputDTO = z.infer<typeof NotificationOutputDTOSchema>;
@@ -0,0 +1,25 @@
import { Dexie, EntityTable, liveQuery } from 'Dexie';
import { z } from 'zod';
export const NotificationTableSchema = z.object({
notificationId: z.string().nullable(),
title: z.string().optional().nullable(),
service: z.string().nullable(),
object: z.string().optional().nullable(),
idObject: z.string().nullable(),
folderId: z.string().optional().nullable(),
dateInit: z.string().optional().nullable(),
dateEnd: z.string().optional().nullable(),
location: z.string().optional().nullable(),
status: z.boolean().optional(),
})
export type NotificationTable = z.infer<typeof NotificationTableSchema>
// Database declaration (move this to its own module also)
export const NotificationDataSource = new Dexie('NotificationDataSource') as Dexie & {
notification: EntityTable<NotificationTable, 'notificationId'>;
};
NotificationDataSource.version(1).stores({
notification: 'notificationId, title, service, object, idObject, folderId, dateInit, dateEnd, location, createdAt'
});
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { NotificationRepositoryService } from './notification-repository.service';
describe('NotificationRepositoryService', () => {
let service: NotificationRepositoryService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(NotificationRepositoryService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
@@ -0,0 +1,83 @@
import { Injectable } from '@angular/core';
import { NotificationInputDTO } from './dto/NotificationInputDTO';
import { RemoteNotificationService } from './datasource/remote-notification.service'
import { FirebasePushNotificationService } from './datasource/firebase-push-notification.service'
import { LocalNotificationService } from './datasource/local-notification.service'
import { SessionStore } from 'src/app/store/session.service';
import { NotificationListMapper } from '../domain/mapper/notificationListMapper';
import { NotificationListChanges } from './async/changes/notificationListChange';
import { NotificationTable } from './infra/db/notification.db';
@Injectable({
providedIn: 'root'
})
export class NotificationRepositoryService {
constructor(
private RemoteNotificationService: RemoteNotificationService,
private FirebasePushNotificationService: FirebasePushNotificationService,
private LocalNotificationService: LocalNotificationService
) {
this.FirebasePushNotificationService.onReceiveForeground(async (data)=> {
console.log('FirebasePushNotificationService', data)
this.init()
})
this.init()
}
async init() {
const result = await this.getNotification({
PageNumber: "1",
PageSize: "50",
userId: SessionStore.user.UserId.toString()
})
if(result.isOk()) {
console.log('notification-list', result.value.data.result)
if(result.value.data.result.length >= 1) {
const localList = await this.LocalNotificationService.getNotification()
const serverList = NotificationListMapper(result.value)
const { insert, update } = NotificationListChanges(localList, serverList)
console.log({insert, update})
this.LocalNotificationService.addNotifications(insert)
this.LocalNotificationService.updateNotifications(update)
// this.LocalNotificationService.addNotifications.
} else {
this.LocalNotificationService.clear()
}
}
}
async getNotification(queryParameter: NotificationInputDTO) {
return await this.RemoteNotificationService.getNotification(queryParameter)
}
getNotificationLive() {
return this.LocalNotificationService.getNotificationLive()
}
async notificationStatus(item: NotificationTable) {
await this.RemoteNotificationService.notificationStatus(item.notificationId)
item.status = true
this.LocalNotificationService.updateNotification(item)
this
this.init()
return
}
async localNotificationStatus(item: NotificationTable) {
item.status = true
this.LocalNotificationService.updateNotification(item)
this.init()
return
}
}
@@ -0,0 +1,21 @@
import { NotificationTable } from "../../data/infra/db/notification.db";
import { NotificationOutputDTO } from '../../data/dto/NotificationOutputDTO'
export function NotificationListMapper(NotificationOutputDTO: NotificationOutputDTO): NotificationTable[] {
return NotificationOutputDTO.data.result.map( e => (
{
notificationId: e.id,
title: e.title,
service: e.service,
object: e.object,
idObject: e.objectId,
folderId: e.folderId,
dateInit: e.startDate,
dateEnd: e.endDate,
createdAt: e.createdAt,
status: e.status,
location: e.location
}
))
}
+37 -14
View File
@@ -236,13 +236,10 @@
<div *ngFor="let year of TimelineMDList " >
<!-- {{year.yearInfo.yearName}} -->
<div *ngFor="let month of year.months " class="header-day" >
<!-- {{ month.monthInfo.monthName | json }} -->
<!-- <hr> -->
<div *ngFor="let day of month.days; let i = index " class="EventListBox-container" >
<div class="day" *ngIf="!(i == 0 && isSelectedDayHasEvent)" >
{{ day.daysInfo.dayName }} <div style="text-transform: capitalize; display: inline;">{{month.monthInfo.monthName}}</div>
</div>
@@ -250,27 +247,45 @@
<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">
<div *ngIf="event.startMany && !event.middle" class="time-start labelb">Início</div>
<div *ngIf="event.endMany && !event.middle " class="time-end labelb">Fim</div>
<div class="schedule-time" *ngIf="event.event.IsAllDayEvent != true">
<div *ngIf="!(event.endMany && !event.middle) && !event.middle" class="time-start">{{event.event.StartDate | date: 'HH:mm'}}</div>
<div *ngIf="!(event.startMany && !event.middle) && !event.middle" class="time-end"> {{event.event.EndDate | date: 'HH:mm'}} </div>
<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" style="color:red !important;">{{ 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" style="color:red !important;"> {{ 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 style="color:red;" *ngIf="event.daysLeft >= 1">
{{ event.duration }}
</span>
</div>
</div>
<div class="schedule-time" *ngIf="event.event.IsAllDayEvent">
<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 && !event.middle)" class="time-start">Todo </div>
<div *ngIf="!event.middle && !(event.endMany && !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 && !event.middle" class="time-start">{{event.event.StartDate | date: 'HH:mm'}}</div>
<div *ngIf="event.endMany && !event.middle" class="time-end"> {{event.event.EndDate | date: 'HH:mm'}} </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">
@@ -278,7 +293,15 @@
<p class="m-0">{{event.event.Subject}}</p>
</div>
<div class="location">{{event.event.Location}}</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>
+19 -1
View File
@@ -678,7 +678,7 @@ export class AgendaPage implements OnInit {
});
};
@XTracerAsync({name:'AgendaPage/loadRangeEventRun', bugPrint: true})
@XTracerAsync({name:'AgendaPage/loadRange', bugPrint: true})
async loadRangeEventRun(startTime: Date, endTime: Date, tracing?: TracingType) {
tracing.addEvent('load range start')
@@ -1254,6 +1254,24 @@ export class AgendaPage implements OnInit {
}
diffHours(date1Str: string, date2Str: string) {
// Convert string dates to Date objects
const date1: any = new Date(date1Str);
const date2: any = new Date(date2Str);
date1.setHours(0, 0, 0, 0); // Set hours, minutes, seconds, and milliseconds to 0
// Calculate the difference in milliseconds
const timeDifferenceMs = date2 - date1;
// Convert difference to hours
const hoursDifference = timeDifferenceMs / (1000 * 60 * 60);
return hoursDifference
}
shoeEventDay(events: any[]) {
if (this.segment == 'Combinado') {
@@ -23,6 +23,7 @@ import { TableSharedCalendar } from 'src/app/services/Repositorys/Agenda/agenda-
import { Observable } from 'rxjs';
import { RoleIdService } from 'src/app/services/role-id.service'
import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
import { AttendeesLIstChangeDetector } from 'src/app/services/Repositorys/Agenda/async/change/attendeesLIstChangeDetector';
const CUSTOM_DATE_FORMATS: NgxMatDateFormats = {
parse: {
@@ -99,7 +100,7 @@ export class EditEventPage implements OnInit {
hasChangeCalendar = false
selectedUserCalendar:any;
SessionStore = SessionStore
serverCurrentList = []
constructor(
private modalController: ModalController,
private navParams: NavParams,
@@ -119,6 +120,8 @@ export class EditEventPage implements OnInit {
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.initCalendarName = this.postEvent.CalendarName;
@@ -425,11 +428,14 @@ export class EditEventPage implements OnInit {
}
}
@XTracerAsync({name:'desktop/create-event', bugPrint: true, daley: 4000})
@XTracerAsync({name:'mobile/create-event', bugPrint: true, daley: 4000})
async save_v2(editAllEvent, tracing?: TracingType) {
this.injectValidation()
this.runValidation()
if (this.Form.invalid) {
return false
}
@@ -449,17 +455,37 @@ export class EditEventPage implements OnInit {
console.log('edit event error: ', error)
}));
this.agendaDataRepository.addEventAttendee(this.postEvent.EventId, this.postEvent.Attendees).subscribe((value) => {
console.log(value)
}, ((error) => {
console.log('add Attendee error: ', 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) {
this.agendaDataRepository.addEventAttendee(this.postEvent.EventId, insert).subscribe((value) => {
console.log(value)
}, ((error) => {
tracing.setAttribute('failed.attendees', 'true')
console.log('add Attendee error: ', error)
}));
}
if(remove.length >= 1) {
this.agendaDataRepository.removeEventAttendee(this.postEvent.EventId, remove).subscribe((value) => {
console.log(value)
}, ((error) => {
tracing.setAttribute('failed.attendees', 'true')
console.log('add Attendee error: ', error)
}));
}
await this.saveDocument()
if (this.addedAttachmentsList.length > 0) {
this.agendaDataRepository.addEventAttachment(this.postEvent.EventId, this.loadedEventAttachments).subscribe((value) => {
this.agendaDataRepository.addEventAttachment(this.postEvent.EventId, this.loadedEventAttachments, tracing).subscribe((value) => {
console.log(value)
}, ((error) => {
console.log('add attachment error: ', error)
@@ -604,7 +630,7 @@ export class EditEventPage implements OnInit {
if (this.postEvent.HasAttachments) {
this.attachmentsService.getAttachmentsById(eventId).subscribe(res => {
this.loadedEventAttachments = res;
// this.loadedEventAttachments = res;
}, ((erro) => {
console.error('editgetAttchament', erro)
@@ -672,26 +698,21 @@ export class EditEventPage implements OnInit {
}
changeAgenda() {
async changeAgenda() {
setTimeout(() => {
const result = await this.agendaDataRepository.geCalendars()
if (this.eventsService.calendarNamesType[this.CalendarNameOwnerName]?.['Oficial'] && this.eventsService.calendarNamesType[this.CalendarNameOwnerName]?.['Pessoal']) {
const selectedCalendar = result.find(e => e.wxUserId == this.selectedUserCalendar)
this.CalendarNamesOptions = ['Oficial', 'Pessoal']
} else if (this.eventsService.calendarNamesType[this.CalendarNameOwnerName]?.['Oficial']) {
if(selectedCalendar) {
if(selectedCalendar.shareType == 1) {
this.CalendarNamesOptions = ['Oficial']
this.postEvent.CalendarName = 'Oficial'
} else if (this.eventsService.calendarNamesType[this.CalendarNameOwnerName]?.['Pessoal']) {
} else if(selectedCalendar.shareType == 2) {
this.CalendarNamesOptions = ['Pessoal']
this.postEvent.CalendarName = 'Pessoal'
} else {
} else if (selectedCalendar.shareType == 3) {
this.CalendarNamesOptions = ['Oficial', 'Pessoal']
}
}, 50)
}
}
@@ -537,26 +537,21 @@ export class NewEventPage implements OnInit {
}
}
changeAgenda() {
async changeAgenda() {
setTimeout(() => {
const result = await this.agendaDataRepository.geCalendars()
if (this.eventService.calendarNamesType[this.CalendarName]?.['Oficial'] && this.eventService.calendarNamesType[this.CalendarName]?.['Pessoal']) {
const selectedCalendar = result.find(e => e.wxUserId == this.selectedUserCalendar)
this.CalendarNamesOptions = ['Oficial', 'Pessoal']
} else if (this.eventService.calendarNamesType[this.CalendarName]?.['Oficial']) {
if(selectedCalendar) {
if(selectedCalendar.shareType == 1) {
this.CalendarNamesOptions = ['Oficial']
this.postEvent.CalendarName = 'Oficial'
} else if (this.eventService.calendarNamesType[this.CalendarName]?.['Pessoal']) {
} else if(selectedCalendar.shareType == 2) {
this.CalendarNamesOptions = ['Pessoal']
this.postEvent.CalendarName = 'Pessoal'
} else {
} else if (selectedCalendar.shareType == 3) {
this.CalendarNamesOptions = ['Oficial', 'Pessoal']
}
}, 50)
}
}
@@ -193,7 +193,7 @@ export class ViewEventPage implements OnInit {
this.TimeZoneString = this.loadedEvent.TimeZone
}
@XTracerAsync({name:'ViewEventPage/loadEvent', bugPrint: true})
@XTracerAsync({name:'mobile/loadEventDetails', bugPrint: true})
async loadEvent(tracing?: TracingType) {
const loader = this.toastService.loading();
+29 -19
View File
@@ -17,6 +17,7 @@ import { SessionStore } from 'src/app/store/session.service';
import { TaskService } from 'src/app/services/task.service';
import { AgendaDataRepositoryService } from 'src/app/services/Repositorys/Agenda/agenda-data-repository.service';
import { EEventFilterStatus } from 'src/app/services/Repositorys/Agenda/model/enums';
import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
@Component({
selector: 'app-events',
@@ -220,7 +221,8 @@ export class EventsPage implements OnInit {
}
async RefreshEvents() {
@XTracerAsync({name:'home/getTask', bugPrint: true})
async RefreshEvents(tracing?: TracingType) {
this.currentEvent = "";
this.showLoader = true;
@@ -232,29 +234,37 @@ export class EventsPage implements OnInit {
let start = date.getFullYear() + "-" + month + "-" + date.getDate() + " " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds();
let end = date.getFullYear() + "-" + month + "-" + date.getDate() + " 23:59:59";
if(SessionStore.user) {
try {
if(SessionStore.user) {
const response = await this.AgendaDataRepositoryService.EventList({
userId: SessionStore.user.UserId,
calendarOwnerName: SessionStore.user.FullName,
startDate: date.toISOString(),
endDate: new Date(end).toISOString(),
status: EEventFilterStatus.AllToCommunicate
})
const response = await this.AgendaDataRepositoryService.EventList({
userId: SessionStore.user.UserId,
calendarOwnerName: SessionStore.user.FullName,
startDate: date.toISOString(),
endDate: new Date(end).toISOString(),
status: EEventFilterStatus.AllToCommunicate
})
if(response.isOk()) {
this.listToPresent = response.value;
if(response.value?.length) {
this.totalEvent = response.value.length;
if(response.isOk()) {
this.listToPresent = response.value;
if(response.value?.length) {
this.totalEvent = response.value.length;
}
tracing.setAttribute('outcome', 'success')
} else {
tracing.setAttribute('outcome', 'failed')
}
this.showLoader = false;
this.showAgendaLoader = false;
this.storage.set('events', this.listToPresent)
} else {
tracing.setAttribute('session', 'false')
}
this.showLoader = false;
this.showAgendaLoader = false;
this.storage.set('events', this.listToPresent)
} catch (error) {
tracing.setAttribute('component.catch', 'true')
tracing.setAttribute('outcome', 'failed')
}
this.showLoader = false;
@@ -177,7 +177,7 @@ export class EventListPage implements OnInit {
this.LoadToApproveEvents();
}
@XTracerAsync({name:'EventListPage/LoadToApproveEvents', bugPrint: true})
@XTracerAsync({name:'EventListPage/LoadToApprove', bugPrint: true})
async LoadToApproveEvents(tracing?: TracingType) {
console.log('aprove event')
this.showLoader = true;
+10 -6
View File
@@ -303,18 +303,22 @@
<span class="app-name"
*ngIf="itemIcons() == 'AccoesPresidenciais & ArquivoDespachoElect' || itemIcons() == 'Correspondencia' ">
<span class="app-name" *ngIf="searchDocument.applicationId == '8' || searchDocument.applicationId == 8"> Correspondencia </span>
<span class="app-name" *ngIf="searchDocument.applicationId == '386' || searchDocument.applicationId == 386"> AccoesPresidenciais </span>
<span class="app-name" *ngIf="searchDocument.applicationId == '361' || searchDocument.applicationId == 361 "> ArquivoDespachoElect </span>
<span class="app-name" *ngIf="searchDocument.applicationId == '8' || searchDocument.applicationId == 8 || searchDocument.ApplicationType == 8"> Correspondencia </span>
<span class="app-name" *ngIf="searchDocument.applicationId == '386' || searchDocument.applicationId == 386 || searchDocument.ApplicationType == 386"> AccoesPresidenciais </span>
<span class="app-name" *ngIf="searchDocument.applicationId == '361' || searchDocument.applicationId == 361 || searchDocument.ApplicationType == 361 "> ArquivoDespachoElect </span>
</span>
</div>
<div class="d-flex ion-justify-content-between ">
<span class="organic-entity"></span>
<span class="organic-entity">{{ searchDocument.entity || searchDocument.EntidadeOrganicaNome }}</span>
<span class="documente-date">{{ formateIsoDate(searchDocument.dateEntry || searchDocument.Data) }}</span>
</div>
<div *ngIf="select" (click)="view(searchDocument)"> Ver</div>
<div *ngIf="select" (click)="view(searchDocument)" style="color: gray;">
<button mat-icon-button aria-label="Example icon-button with a menu">
<ion-icon src="assets/icon/iconmonstr-eye-9.svg" class=" font-25-em "></ion-icon>
</button>
</div>
</div>
</li>
@@ -323,7 +327,7 @@
<!-- <a href="#" class="previous">&laquo; Previous</a>
<a href="#" class="next">Next &raquo;</a> -->
<div class="nextAndPreviewDiv" >
<div class="nextAndPreviewDiv" *ngIf="type != 'Agenda' && select == true ">
<a href="#" class="previous round" (click)="previeweButton($event)">&#8249;</a>
<div>{{pageNumber + "/" + totalPage}}</div>
<a href="#" class="next round" (click)="nextButton($event)" >&#8250;</a>
+1 -1
View File
@@ -185,7 +185,7 @@ ion-slide {
margin-left: 10px;
.result-name {
margin: 0px;
width: 100%;
// width: 100%;
font-family: Roboto;
font-size: rem(15);
color: var(--title-text-color);
+66 -49
View File
@@ -20,6 +20,9 @@ import { momentG } from 'src/plugin/momentG';
import { Cy } from 'cypress/enum'
import { AgendaDataRepositoryService } from 'src/app/services/Repositorys/Agenda/agenda-data-repository.service';
import { SessionStore } from 'src/app/store/session.service';
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';
const CUSTOM_DATE_FORMATS: NgxMatDateFormats = {
parse: {
@@ -114,7 +117,9 @@ export class SearchPage implements OnInit {
public ThemeService: ThemeService,
private router: Router,
private httpErrorhandle: HttpErrorHandle,
private agendaDataRepository: AgendaDataRepositoryService) {
private agendaDataRepository: AgendaDataRepositoryService,
private toastService: ToastService,
) {
this.ordinance = "recent";
this.currentPath = window.location.pathname;
@@ -168,7 +173,7 @@ export class SearchPage implements OnInit {
console.log('doc item',item)
const ApplicationType = item.applicationId.toString()
const Id = item.docId
const Id = item.docId
if (ApplicationType == '8') {
@@ -363,7 +368,8 @@ export class SearchPage implements OnInit {
/**
* @description Basic search
*/
basicSearch() {
@XTracerAsync({name:'search/basicSearch', bugPrint: true})
async basicSearch(tracing?: TracingType) {
let searchDocumentDate
let searchDocumentDateEnd;
@@ -386,70 +392,81 @@ export class SearchPage implements OnInit {
if (this.searchSubject.trim() == "" && searchDocumentDate == null && searchDocumentDateEnd == null && this.searchSenderId == null && this.searchOrganicEntiryCode == null && this.searchDocTypeId == null) {
this.searchResult = "Campo de pesquisa esta vazio, entre com assunto que deseja pesquisa";
this.searchResult = "Campo de pesquisa está vazio, entre com assunto que deseja pesquisa";
console.log('enter text');
} else {
/* this.showLoader = true;
this.agendaDataRepository.getDocumentAttachments(361, SessionStore.user.UserId, this.searchSubject, this.pageNumber, this.pageSize).subscribe((values) => {
this.totalPage = values.data.total / this.pageSize;
this.totalPage = Math.round(this.totalPage)
console.log(values.data.result)
this.searchDocuments = this.sortArrayISODate(values.data.result);
const searchEvents = await this.agendaDataRepository.searchEvent({value: this.searchSubject.trim() }, tracing)
if(searchEvents.isOk()) {
this.showDocuments = true;
this.searchDocuments = searchEvents.value
this.searchDocuments = this.sortArrayISODate(this.searchDocuments);
this.reorderList(this.ordinance);
// hide show document
if (this.searchDocuments.length >= 1) {
this.showDocuments = true;
} else {
this.searchResult = "Registo não encontrado"
this.showDocuments = false
}
this.showLoader = false;
this.loadWordCloud();
}, error => {
this.showLoader = false;
// this.searchResult = "Registo não encontrado"
this.httpErrorhandle.httpStatusHandle(error)
// console.log(error)
})
return */
this.showLoader = true;
this.search.basicSearch(this.searchSubject, searchDocumentDate, searchDocumentDateEnd, this.searchSenderId
, this.searchOrganicEntiryCode, this.searchDocTypeId, '0').subscribe(res => {
console.log(res)
tracing.setAttribute('outcome', 'success');
} else {
if (!res.Categories.length) {
this.searchResult = "Não encontramos o que procura";
}
this.loadWordCloud();
this.showDocuments = true;
res.Categories.forEach(e => {
e['Active'] = false;
});
if(!isHttpError(searchEvents.error)) {
this.toastService._badRequest('Pedimos desculpa mas não foi possível executar a acção. Por favor, contacte o apoio técnico.')
// bind respose
this.searchCategories = res.Categories;
} else if (isHttpError(searchEvents.error)) {
this.httpErrorhandle.httpStatusHandle(searchEvents.error)
}
this.searchDocuments = this.sortArrayISODate(res.Documents);
tracing.setAttribute('outcome', 'failed');
console.log('create event error: ', searchEvents.error)
}
this.reorderList(this.ordinance);
// this.showLoader = true;
// this.search.basicSearch(this.searchSubject, searchDocumentDate, searchDocumentDateEnd, this.searchSenderId
// , this.searchOrganicEntiryCode, this.searchDocTypeId, '0').subscribe(res => {
// console.log(res)
// hide show document
if (this.searchDocuments.length >= 1) {
this.showDocuments = true;
} else {
this.showDocuments = false
}
// if (!res.Categories.length) {
// this.searchResult = "Não encontramos o que procura";
// }
this.showLoader = false;
this.loadWordCloud();
// res.Categories.forEach(e => {
// e['Active'] = false;
// });
}, error => {
this.showLoader = false;
// this.searchResult = "Registo não encontrado"
this.httpErrorhandle.httpStatusHandle(error)
// console.log(error)
});
// // bind respose
// this.searchCategories = res.Categories;
// this.searchDocuments = this.sortArrayISODate(res.Documents);
// this.reorderList(this.ordinance);
// // hide show document
// if (this.searchDocuments.length >= 1) {
// this.showDocuments = true;
// } else {
// this.showDocuments = false
// }
// this.showLoader = false;
// this.loadWordCloud();
// }, error => {
// this.showLoader = false;
// // this.searchResult = "Registo não encontrado"
// this.httpErrorhandle.httpStatusHandle(error)
// // console.log(error)
// });
}
}
else if (this.type == "AccoesPresidenciais & ArquivoDespachoElect" && this.eventAgenda == true) {
@@ -1073,9 +1090,9 @@ export class SearchPage implements OnInit {
async viewDetail(searchDocument: SearchList) {
const ApplicationType = searchDocument.ApplicationType.toString()
const ApplicationType = searchDocument?.ApplicationType?.toString()
const Id = searchDocument.Id
const CalendarId = searchDocument.ApplicationName.split(':')[1]
const CalendarId = searchDocument?.ApplicationName?.split(':')[1]
const DocTypeDesc = searchDocument.DocTypeDesc
if (this.select == false) {
@@ -15,13 +15,15 @@ import { EEventFilterStatus } from './model/enums';
import { isHttpError } from '../../http.service';
import { TracingType } from '../../monitoring/opentelemetry/tracer';
import { APINODReturn } from '../../decorator/api-validate-schema.decorator';
import { EventListDataOutputDTOSchema } from './model/eventListDTOOutput';
import { EventToApproveDataOutputDTOSchema } from './model/eventToApproveListOutputDTO';
import { EventOutputDTOSchema } from './model/eventDTOOutput';
import { SharedCalendarListDetectChanges } from './async/change/shareCalendarChangeDetector';
import { SharedCalendarListItemOutputDTO } from './model/sharedCalendarOutputDTO';
import { EventInputDTOSchema } from './agendaDataModels';
import { EventUpdateInputDTOSchema } from './model/eventUpdateInputDtO';
import { AttachInputDTOSchema } from './model/addAttachmentDTOInput';
import { EventListDataOutputDTOSchema } from './model/eventListDTOOutput';
import { EventSearchMapper } from './mapper/EventSearchMapper';
@Injectable({
providedIn: 'root'
@@ -106,6 +108,14 @@ export class AgendaDataRepositoryService {
}
async searchEvent(queryParameters: {value}, tracing?: TracingType) {
const result = await this.agendaDataService.searchEvent(queryParameters)
return result.map( response => {
APINODReturn(EventListDataOutputDTOSchema, response, 'get/Events', tracing)
return EventSearchMapper.toDomain(response, "calendarOwnerName", "userId")
})
}
async EventList({ userId, startDate, endDate, status = EEventFilterStatus.Approved, category = null, type = null, calendarOwnerName = '' }, tracing?: TracingType) {
try {
@@ -159,7 +169,6 @@ export class AgendaDataRepositoryService {
}
createEvent(eventData: Event, documents, calendar: TableSharedCalendar, tracing: TracingType) {
console.log('create repository 1',eventData, calendar)
let eventInput = {
userId: calendar.wxUserId,
@@ -181,8 +190,6 @@ export class AgendaDataRepositoryService {
isAllDayEvent: eventData.IsAllDayEvent,
}
console.log('create repository 2',eventInput)
APINODReturn(EventInputDTOSchema, eventInput, 'post/Events', tracing)
return this.agendaDataService.createEvent(eventInput)
}
@@ -221,16 +228,25 @@ export class AgendaDataRepositoryService {
return this.agendaDataService.updateEvent(eventId, eventInput)
}
addEventAttendee(id, attendeeData,) {
addEventAttendee(id, attendeeData) {
console.log(attendeeData)
console.log(this.utils.attendeesEdit(attendeeData))
return this.agendaDataService.addEventAttendee(id, { attendees: this.utils.attendeesAdded(attendeeData) });
}
addEventAttachment(id, attachmentData) {
removeEventAttendee(id, attendeeData: {Id : string}[]) {
return this.agendaDataService.removeEventAttendee(id, { attendees: attendeeData.map(e => e.Id || e['id']) } );
}
addEventAttachment(id, attachmentData, tracing: TracingType) {
console.log(attachmentData)
console.log('post attachment', this.utils.documentAdded(attachmentData))
return this.agendaDataService.addEventAttachment(id, { attachments: this.utils.documentAdded(attachmentData) });
const attachments = { attachments: this.utils.documentAdded(attachmentData) }
APINODReturn(AttachInputDTOSchema, attachments, `POST/${id}/Attendee`, tracing)
return this.agendaDataService.addEventAttachment(id, attachments);
}
deleteEvent(eventId,deleteAll) {
@@ -7,8 +7,9 @@ import { SharedCalendarListOutputDTO, SharedCalendarListOutputDTOSchema } from '
import { HttpService } from '../../http.service';
import { APIReturn } from '../../decorator/api-validate-schema.decorator';
import { TracingType } from '../../monitoring/opentelemetry/tracer';
import { EventListOutputDTO, EventListOutputDTOSchema } from './model/eventListDTOOutput';
import { EventOutputDTO } from './model/eventDTOOutput';
import { AttendeesRemoveInputDTO } from './model/attendeeRemoveInputDTO';
import { EventListOutputDTO } from './model/eventListDTOOutput';
@Injectable({
providedIn: 'root'
@@ -73,6 +74,10 @@ export class AgendaDataService {
return this.http.get<any>(`${this.baseUrl}/Events`, { params });
}
searchEvent(queryParameter: {value}) {
return this.httpService.get<EventListOutputDTO>(`${this.baseUrl}/Events`, queryParameter);
}
getEvent(id: string): Observable<EventOutputDTO> {
return this.http.get<any>(`${this.baseUrl}/Events/${id}`);
}
@@ -98,7 +103,8 @@ export class AgendaDataService {
return this.http.post<any>(`${this.baseUrl}/Events/${id}/Attendee`, attendeeData);
}
removeEventAttendee(id: string, attendeeData: any): Observable<any> {
removeEventAttendee(id: string, attendeeData: AttendeesRemoveInputDTO): Observable<any> {
return this.http.delete<any>(`${this.baseUrl}/Events/${id}/Attendee`, { body: attendeeData });
}
@@ -72,8 +72,8 @@ export const EventInputDTOSchema = z.object({
subject: z.string().min(1),
body: z.string().min(1),
location: z.string().nullable().optional(),
startDate: z.string().datetime(),
endDate: z.string().datetime(),
startDate: z.string(),
endDate: z.string(),
type: EEventTypeDTO,
category: EEventCategoryDTO,
attendees: z.array(AttendeeInputDTOSchema).nullable().optional(),
@@ -0,0 +1,41 @@
interface attendees {
EmailAddress : string
Name: string
UserType: string
attendeeType: string
wxUserId: string
Id: string
}
type Changes = {
insert: attendees[];
remove: attendees[];
};
export function AttendeesLIstChangeDetector(
localList: attendees[],
serverList: attendees[]
): Changes {
const changes: Changes = { insert: [], remove: [] };
const localMap = new Map(localList.map(item => [item.wxUserId, item]));
const serverMap = new Map(serverList.map(item => [item.wxUserId, item]));
// Detect new or updated items
for (const [id, serverItem] of serverMap) {
const localItem = localMap.get(id);
if (!localItem) {
changes.insert.push(serverItem);
}
}
// Detect deleted items
for (const [id, localItem] of localMap) {
if (!serverMap.has(id)) {
changes.remove.push(localItem);
}
}
return changes;
}
@@ -71,7 +71,7 @@ export class EventMapper {
"EndDate": dto.endDate,
"EventType": "Single",
"Attendees": dto.attendees.map((e) => ({
//Id: e.id,
Id: e.id,
wxUserId: e.wxUserId,
EmailAddress: e.emailAddress,
Name: e.name,
@@ -1,7 +1,7 @@
import { EventList } from "src/app/models/entiry/agenda/eventList"
import { EventListOutputDTO } from "../model/eventListDTOOutput"
import { EEventCategory, EEventOwnerType, EEventStatus, EEventType } from "../model/enums";
import { XTracer } from "src/app/services/monitoring/opentelemetry/tracer";
import { EventListOutputDTO } from "../model/eventListDTOOutput";
function getTextInsideParentheses(inputString): string {
var startIndex = inputString.indexOf('(');
@@ -60,16 +60,17 @@ export class ListEventMapper {
"EventId": e.id,
"Subject": e.subject,
"Location": e.location,
"CalendarId": userId,
"CalendarId": (e.owner.wxUserId) as any,
"CalendarName": category,
"StartDate": new Date(e.startDate) + '',
"EndDate": new Date(e.endDate)+ '',
"Schedule": calendarOwnerName,
"Schedule": (e.owner.wxFullName) as any,
"RequiredAttendees": null as any,
"OptionalAttendees": null as any,
"HumanDate": "2 semanas atrás" as any,
"TimeZone": getTextInsideParentheses(new Date(e.startDate)+ ''),
"IsPrivate": false as any
"IsPrivate": false as any,
"createdAt": e.createdAt
}
})
}
@@ -0,0 +1,37 @@
import { SearchList } from "src/app/models/search-document";
import { EventListOutputDTO } from "../model/eventListDTOOutput";
function getTextInsideParentheses(inputString): string {
var startIndex = inputString.indexOf('(');
var endIndex = inputString.indexOf(')');
if (startIndex !== -1 && endIndex !== -1) {
return inputString.substring(startIndex + 1, endIndex);
} else {
return null;
}
}
export class EventSearchMapper {
// @XTracer({name:'ListEventMapper/toDomain', log: false, bugPrint: false})
static toDomain(dto: EventListOutputDTO, calendarOwnerName: string, userId: string): SearchList[] {
return dto.data.map((e) => {
return {
Id: e.id as any,
subject: e.subject,
dateEntry: e.createdAt as any,
Data: e.createdAt as any,
entity: (e.owner.wxFullName),
ApplicationType: 0 as any,
Assunto: e.subject,
appName: "string",
ApplicationName: "",
docId: e.id as any,
applicationId: 0 as any
}
})
}
static toDTO() {}
}
@@ -127,6 +127,7 @@ export class EventToApproveDetailsMapper {
//"HasAttachments": true,
"ParticipantsList": [
...dto.attendees.map( e => ({
Id: e.id,
Name: e.name,
EmailAddress: e.emailAddress,
IsRequired: FEAttendeeType(e.attendeeType) == 'Required',
@@ -1,5 +1,3 @@
import { EventList } from "src/app/models/entiry/agenda/eventList"
import { EventListOutputDTO } from "../model/eventListDTOOutput"
import { EventToApproveListOutputDTO } from "../model/eventToApproveListOutputDTO";
import { EventToApproveList } from "src/app/models/entiry/agenda/eventToApproveList";
import { EEventCategory, EEventOwnerType, EEventStatus } from "../model/enums";
@@ -0,0 +1,13 @@
import { z } from 'zod';
export const AttachInputDTOSchema = z.object({
attachments: z.array(z.object({
docId: z.any(),
sourceName: z.any(),
description: z.any().nullable(),
applicationId: z.any(),
}))
})
export type AttachInputDTO = z.infer<typeof AttachInputDTOSchema>
@@ -0,0 +1,8 @@
import { z } from "zod"
export const AttendeesRemoveInputDTOSchema = z.object({
attendees: z.array(z.string()),
})
export type AttendeesRemoveInputDTO = z.infer<typeof AttendeesRemoveInputDTOSchema>
@@ -1,5 +1,5 @@
import { z } from 'zod';
import { EEventCategory, EEventOwnerType, EEventStatus, EEventType } from './enums';
import { EEventCategory, EEventOwnerType, EEventStatus, EEventType } from '../model/enums';
const OwnerSchema = z.object({
@@ -29,6 +29,7 @@ export const EventListOutputDTOSchema = z.object({
isAllDayEvent: z.boolean(),
// status: z.enum(['Approved']), // Assuming "Approved" is the only valid option based on provided data
status: z.nativeEnum(EEventStatus), // Assuming "Approved" is the only valid option based on provided data
createdAt: z.string().datetime({ offset: true }),
})
export const EventListDataOutputDTOSchema = z.object({
@@ -0,0 +1,12 @@
import { z } from 'zod';
import { EEventOwnerType } from './enums';
export const EventSearchOutputDTOSchema = z.object({
Id: z.string(),
subject: z.string(),
dateEntry: z.string(),
Data: z.string(),
entity: z.string().optional()
}).nullable();
export type EventSearchOutput = z.infer<typeof EventSearchOutputDTOSchema>;
+5 -3
View File
@@ -83,15 +83,17 @@ export class Utils {
let listupdate = []
documents.forEach(element => {
let object = {
docId: element.docId || element.DocId,
sourceName: element.subject || element.sourceNames || element.Description,
docId: element.docId || element.DocId || element.Id,
sourceName: element.subject || element.sourceNames || element.Description || element.SourceName,
description: "",
applicationId: element.applicationId || element.ApplicationId
}
listupdate.push(object)
});
return listupdate
return listupdate.filter( e=> typeof e.docId == 'number')
/* return documents.map((e) => {
return {
docId: e.docId,
+102 -54
View File
@@ -37,6 +37,7 @@ export class ListBoxService {
daysBetween(){ }
list(eventSource: EventListStore[], profile: 'md' | 'pr' | 'all', rangeStartDate, randEndDate, {segment = 'Combinado', selectedDate= null}): Year[] {
// // filter range
@@ -131,74 +132,70 @@ export class ListBoxService {
cloneSelectedDate.setMinutes(0)
cloneSelectedDate.setSeconds(0)
if (diffDays <= 150 ) {
if (diffDays >= 1) {
if (diffDays >= 1) {
const StartEvent = this.transForm(event, {startMany: true, endMany: false, middle: false})
const StartEvent = this.transForm(event, {startMany: true, endMany: false, middle: false, hasMany: true})
if(this.CanPush(event, selectedDate) && (new Date(event.start)).getTime() >= cloneSelectedDate.getTime()) {
days[day].push(StartEvent); this.push(StartEvent, year)
if(this.CanPush(event, selectedDate) && (new Date(event.start)).getTime() >= cloneSelectedDate.getTime()) {
days[day].push(StartEvent); this.push(StartEvent, year)
}
let i = 1;
//create event between date
while (startDate.getFullYear() != endDate.getFullYear() ||
startDate.getMonth() != endDate.getMonth() ||
startDate.getDate() != endDate.getDate()) {
const newDate = startDate.setDate(startDate.getDate()+ i)
let otherDays = this.dateService.getDay(newDate)
const cloneEvent = {...event}
cloneEvent['other'] = true
cloneEvent.start = new Date(startDate)
if(!days.hasOwnProperty(otherDays)) {
days[otherDays] = []
}
let i = 1;
if (!(startDate.getFullYear() != endDate.getFullYear() ||
startDate.getMonth() != endDate.getMonth() ||
startDate.getDate() != endDate.getDate())) {
// last push
const EndEvent = this.transForm(cloneEvent, {startMany: false, endMany: true, middle: false, hasMany: true})
if(this.CanPush(cloneEvent, selectedDate) && cloneEvent.start.getTime() >= cloneSelectedDate.getTime()) {
days[otherDays].push(EndEvent) ; this.push(EndEvent, year)
}
//create event between date
while (startDate.getFullYear() != endDate.getFullYear() ||
startDate.getMonth() != endDate.getMonth() ||
startDate.getDate() != endDate.getDate()) {
} else {
const newDate = startDate.setDate(startDate.getDate()+ i)
let otherDays = this.dateService.getDay(newDate)
const cloneEvent = {...event}
cloneEvent['other'] = true
cloneEvent.start = new Date(startDate)
if(!days.hasOwnProperty(otherDays)) {
days[otherDays] = []
}
if (!(startDate.getFullYear() != endDate.getFullYear() ||
startDate.getMonth() != endDate.getMonth() ||
startDate.getDate() != endDate.getDate())) {
// last push
const EndEvent = this.transForm(cloneEvent, {startMany: false, endMany: true, middle: false})
if(this.CanPush(cloneEvent, selectedDate) && cloneEvent.start.getTime() >= cloneSelectedDate.getTime()) {
days[otherDays].push(EndEvent) ; this.push(EndEvent, year)
}
} else {
const EndEvent = this.transForm(cloneEvent, {startMany: false,endMany: true, middle: true})
if(this.CanPush(cloneEvent, selectedDate) && cloneEvent.start.getTime() >= cloneSelectedDate.getTime()) {
const EndEvent = this.transForm(cloneEvent, {startMany: false,endMany: false, middle: true, hasMany: true})
if(this.CanPush(cloneEvent, selectedDate) && cloneEvent.start.getTime() >= cloneSelectedDate.getTime()) {
days[otherDays].push(EndEvent) ; this.push(EndEvent, year)
} else {
if( cloneEvent.start.getFullYear() == cloneSelectedDate.getFullYear() && cloneEvent.start.getDate() == cloneSelectedDate.getDate() && cloneEvent.start.getMonth() == cloneSelectedDate.getMonth()) {
// console.log("00_00")
days[otherDays].push(EndEvent) ; this.push(EndEvent, year)
} else {
if( cloneEvent.start.getFullYear() == cloneSelectedDate.getFullYear() && cloneEvent.start.getDate() == cloneSelectedDate.getDate() && cloneEvent.start.getMonth() == cloneSelectedDate.getMonth()) {
// console.log("00_00")
days[otherDays].push(EndEvent) ; this.push(EndEvent, year)
} else {
// console.log('0000000000000000000000000',cloneEvent.start.getTime(), cloneSelectedDate.getTime())
// console.log('0000000000000000000000000',cloneEvent.start, cloneSelectedDate)
}
// console.log('0000000000000000000000000',cloneEvent.start.getTime(), cloneSelectedDate.getTime())
// console.log('0000000000000000000000000',cloneEvent.start, cloneSelectedDate)
}
}
}
}
days[otherDays] = days[otherDays].reverse()
days[otherDays] = days[otherDays].reverse()
}
}
} else {
} else {
if(this.CanPush(event, selectedDate)) { days[day].push(event) ; this.push(event, year) }
}
if(this.CanPush(event, selectedDate)) { days[day].push(event) ; this.push(event, year) }
}
} else {
if(this.CanPush(event, selectedDate)) { days[day].push(event) ; this.push(event, year) }
}
} else {
event['sameDay'] = true
if(this.CanPush(event, selectedDate) && diffDays != 2) { days[day].push(event) ; this.push(event, year) }
}
@@ -309,7 +306,11 @@ export class ListBoxService {
return events;
}
transForm(event: CustomCalendarEvent, {startMany, endMany, middle}) {
transForm(event: CustomCalendarEvent, {startMany, endMany, middle, hasMany = false}) {
let daysLeft = this.daysToEndWithJS(event.start, event.end);
let eventTotalDuration = this.daysToEndWithJS(event.event.StartDate, event.event.EndDate);
return Object.assign({}, {
start: event.start,
end: event.end,
@@ -322,8 +323,13 @@ export class ListBoxService {
Location: event.event.Location,
EventId: event.event.EventId,
CalendarName: event.event.CalendarName,
CalendarId: event.event.CalendarId
CalendarId: event.event.CalendarId,
daysLeft
},
eventTotalDuration,
hasMany,
duration: this.duration(event.start, event.event.EndDate),
daysLeft,
Subject: event.event.Subject,
startMany: startMany,
endMany: endMany,
@@ -333,6 +339,48 @@ export class ListBoxService {
daysToEndWithJS(startDateStr: any, endDateStr: any) {
// Define the start and end dates
const startDate: any = new Date(startDateStr);
const endDate: any = new Date(endDateStr);
startDate.setHours(0, 0, 0, 0); // Set hours, minutes, seconds, and milliseconds to 0
endDate.setHours(0, 0, 0, 0); // Set hours, minutes, seconds, and milliseconds to 0
// 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
}
duration(date1Str, date2Str) {
// Convert string dates to Date objects
const date1: any = new Date(date1Str);
const date2: any = new Date(date2Str);
// Calculate the difference in milliseconds
const timeDifferenceMs = date2 - date1;
// Convert difference to days, hours, and minutes
const totalMinutes = Math.floor(timeDifferenceMs / (1000 * 60));
const days = Math.floor(totalMinutes / (60 * 24));
const hours = Math.floor((totalMinutes % (60 * 24)) / 60);
const minutes = totalMinutes % 60;
return `${days}d`
}
transformObjectKeyOrder(originalObject, keyOrder) {
const transformedObject = {};
+27 -3
View File
@@ -1,7 +1,7 @@
import { HttpClient, HttpErrorResponse, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { ok, err, Result } from 'neverthrow';
import { HttpParams } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
@@ -19,9 +19,23 @@ export class HttpService {
}
}
async get<T>(url: string): Promise<Result<T, HttpErrorResponse>> {
async get<T>(url: string, httpParamsObj = {} ): Promise<Result<T, HttpErrorResponse>> {
try {
const result = await this.http.get<T>(url).toPromise()
let httpParams = new HttpParams();
// Convert params object to HttpParams
if (httpParamsObj) {
Object.keys(httpParamsObj).forEach(key => {
httpParams = httpParams.set(key, httpParamsObj[key]);
})
}
let opts = {
params : httpParams
}
const result = await this.http.get<T>(url, opts).toPromise()
return ok (result as T)
} catch (e) {
return err(e as HttpErrorResponse)
@@ -48,6 +62,16 @@ export class HttpService {
return err(e as HttpErrorResponse)
}
}
async patch<T>(url: string, body ={}): Promise<Result<T, HttpErrorResponse>> {
try {
const result = await this.http.patch<T>(url, body).toPromise();
return ok(result as T);
} catch (e) {
return err(e as HttpErrorResponse);
}
}
}
@@ -0,0 +1,46 @@
// import { Injectable } from '@angular/core';
// import * as log4js from 'log4js';
// @Injectable({
// providedIn: 'root'
// })
// export class LoggingService {
// private logger;
// constructor() {
// log4js.configure({
// appenders: {
// graylog: {
// type: '@log4js-node/gelf',
// host: 'localhost', // Replace with your Graylog server hostname or IP
// port: 1514, // GELF TCP port configured in Graylog Docker Compose
// hostname: 'angular-app', // Optional: Name of your application or hostname
// facility: 'angular-app', // Optional: Facility for categorizing logs
// customFields: { // Optional: Additional fields you want to include
// app: 'AngularApp',
// env: 'development'
// }
// }
// },
// categories: {
// default: { appenders: ['graylog'], level: 'debug' }
// }
// });
// this.logger = log4js.getLogger();
// this.log("teste-123s")
// }
// log(message: string) {
// this.logger.info(message);
// }
// error(message: string) {
// this.logger.error(message);
// }
// debug(message: string) {
// this.logger.debug(message);
// }
// }
@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { Device } from '@capacitor/device';
import { SocketLog } from './worker.worker';
// import { SocketLog } from './worker.worker';
import { FCM } from '@capacitor-community/fcm';
import { ActionPerformed, PushNotificationSchema, PushNotifications, Token, } from '@capacitor/push-notifications';
import { AlertController, Platform } from '@ionic/angular';
@@ -14,7 +14,7 @@ export class CaptureLogService {
deviceName = ''
constructor(
public socket: SocketLog,
// public socket: SocketLog,
private platform: Platform,
private afMessaging: AngularFireMessaging,
) {
@@ -25,6 +25,13 @@ export class CaptureLogService {
this.deviceName = e.name
});
// Create a new
const worker = new Worker(new URL('./worker.worker', import.meta.url));
worker.onmessage = ({ data }) => {
console.log(`page got message: ${data}`);
};
worker.postMessage('hello');
}
setToken() {
@@ -1,13 +1,4 @@
// src/app/worker.worker.ts
// addEventListener('message', ({ data }) => {
// const response = `Worker response to ${data}`;
// postMessage(response);
// });
import { Injectable } from '@angular/core';
/// <reference lib="webworker" />
import { Observable, Subject, BehaviorSubject } from 'rxjs';
import { webSocket, WebSocketSubject } from 'rxjs/webSocket';
import { catchError, retryWhen, tap, delay } from 'rxjs/operators';
@@ -17,15 +8,7 @@ interface WebSocketMessage {
payload: any;
}
interface WebSocketError {
type: string;
error: any;
}
@Injectable({
providedIn: 'root'
})
export class SocketLog {
class SocketLog {
private socket$: WebSocketSubject<WebSocketMessage>;
private messageSubject$: Subject<WebSocketMessage>;
private connectionStatus$: BehaviorSubject<boolean>;
@@ -36,6 +19,8 @@ export class SocketLog {
this.messageSubject$ = new Subject<WebSocketMessage>();
this.connectionStatus$ = new BehaviorSubject<boolean>(false);
this.setupVisibilityChangeHandler();
// this.connect('https://5-180-182-151.cloud-xip.com:85/ws/')
//console.log('connect1')
}
public connect(url: string) {
@@ -61,12 +46,14 @@ export class SocketLog {
this.messageSubject$.next(message);
this.connectionStatus$.next(true);
this.reconnectAttempts = 0;
// console.log({message})
},
(err) => {
console.error('WebSocket connection error:', err);
// console.error('WebSocket connection error:', err);
},
() => {
console.log('WebSocket connection closed');
// console.log('WebSocket connection closed');
this.connectionStatus$.next(false);
}
);
@@ -150,3 +137,6 @@ export class SocketLog {
);
}
}
let _ = new SocketLog()
@@ -1,67 +1,30 @@
const { DiagConsoleLogger, DiagLogLevel, diag, metrics } = require('@opentelemetry/api');
const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-http');
const { MeterProvider, PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics');
import { metrics } from '@opentelemetry/api';
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
import { MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
import { environment } from 'src/environments/environment';
// Optional and only needed to see the internal diagnostic logging (during development)
// diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);
// Initialize OpenTelemetry metrics
const meterProvider = new MeterProvider();
metrics.setGlobalMeterProvider(meterProvider);
let interval;
let meter;
if (window.location.protocol !== 'https:' && environment.apiURL != 'https://gdqas-api.oapr.gov.ao/api/') {
const metricReader = new PeriodicExportingMetricReader({
exporter: new OTLPMetricExporter({
url: 'http://5-180-182-151.cloud-xip.com:4318/v1/metrics',
// headers: {
// 'Authorization': 'Basic ' + btoa('tabteste@006:tabteste@006'),
// }
}),
exportIntervalMillis: 3000,
});
// function stopMetrics() {
// console.log('STOPPING METRICS');
// clearInterval(interval);
// metrics.getMeterProvider().shutdown()
// .then(() => metrics.disable());
// }
meterProvider.addMetricReader(metricReader);
}
export const meter = meterProvider.getMeter('example-exporter-collector');
export const RequestCounter = meter.createCounter('post_requests', {
description: 'Example of a Counter',
});
// function startMetrics() {
// console.log('STARTING METRICS');
// const meterProvider = new MeterProvider();
// metrics.setGlobalMeterProvider(meterProvider);
// meterProvider.addMetricReader(new PeriodicExportingMetricReader({
// exporter: new OTLPMetricExporter({
// //url: 'http://localhost:8019/collector/v1/metrics',
// // url: 'http://localhost:4318/v1/metrics',
// url: 'http://5-180-182-151.cloud-xip.com:4318/v1/metrics', // Custom port 85
// //url: 'https://5-180-182-151.cloud-xip.com:85/collector/v1/metrics', // Custom port 85
// // headers: {
// // 'Authorization': 'Basic ' + btoa('tabteste@006:tabteste@006'),
// // }
// }),
// exportIntervalMillis: 2000
// }));
// meter = meterProvider.getMeter('example-exporter-collector')
// const requestCounter = meter.createCounter('requests', {
// description: 'Example of a Counter',
// });
// const upDownCounter = meter.createUpDownCounter('test_up_down_counter', {
// description: 'Example of a UpDownCounter',
// });
// const attributes = { environment: 'staging' };
// interval = setInterval(() => {
// requestCounter.add(1, attributes);
// requestCounter.add(1, {environment: 'testing'});
// requestCounter.add(1, {environment: 'ok'});
// upDownCounter.add(Math.random() > 0.5 ? 1 : -1, attributes);
// }, 1000);
// }
// const addClickEvents = () => {
// // const startBtn = document.getElementById('startBtn');
// // const stopBtn = document.getElementById('stopBtn');
// // startBtn.addEventListener('click', startMetrics);
// // stopBtn.addEventListener('click', stopMetrics);
// // startMetrics()
// };
// // addClickEvents();
export const UseCaseCounter = meter.createCounter('use_case', {
description: 'use case counter',
});
@@ -5,6 +5,8 @@ import { OpentelemetryAgendaProvider, OpentelemetryInterceptorProvider, Opentele
import { Device, DeviceInfo } from '@capacitor/device';
import { SessionStore } from 'src/app/store/session.service';
import { environment } from 'src/environments/environment';
import { UseCaseCounter } from './matrix';
// import { context, propagation } from '@opentelemetry/api';
const tracerInstance = OpentelemetryAgendaProvider.getTracer('example-tracer-hole', '111', {})
const tracerNotificationInstance = OpentelemetryNotificationProvider.getTracer('example-tracer-hole', '111', {})
@@ -58,10 +60,16 @@ const createTracingInstance = ({bugPrint, name, module, autoFinish}): TracingTyp
data.tags[key] = value;
span.setAttribute(key, value);
},
getAttribute: (key: string) => {
return data.tags[key]
},
finish: () => {
span.end();
if(environment.apiURL != 'https://gdqas-api.oapr.gov.ao/api/') {
span.end();
UseCaseCounter.add(1, {user: SessionStore?.user?.FullName, outcome:data.tags['outcome'], usecase: name})
}
if(bugPrint && hasBug) {
if(bugPrint && data.tags['outcome'] == 'failed') {
console.error(name, data)
}
},
@@ -92,12 +100,13 @@ export function XTracerAsync({ name, bugPrint, module = null, autoFinish = true,
tracing.setAttribute('commit.date', environment.version.lastCommitTime)
tracing.setAttribute('commit.branch', environment.version.branch)
args.push(tracing)
try {
const result = await originalMethod.apply(this, args);
if(autoFinish) {
if(autoFinish ) {
setTimeout(tracing.finish , daley)
}
@@ -167,6 +176,7 @@ export type TracingType = {
//logEvent: (name: string, attributesOrStartTime?: AttributeValue | TimeInput) => void;
addEvent: (context: string, message?: any, obj?: any) => void;
setAttribute: (key: string, value: string) => void;
getAttribute: (key: string) => string;
LocalLogEvent: (name: string, attributesOrStartTime: any, obj?:any) => void;
finish: () => void;
bugFlag:() => void;
@@ -36,64 +36,61 @@ export class NotificationHolderService {
const element = notification
const i = this.notificationList.length + 1
console.log({notification})
let notificationObject;
if (element.notification) {
notificationObject = {
index: i,
title: element.notification.title,
Service: element.data.Service,
Object: element.data.Object,
IdObject: element.data.IdObject,
FolderId: element.data.FolderId,
body: element.notification.body,
dateInit: this.getFormatedTime(element.data.dateInit),
dateEnd: this.getFormatedTime(element.data.dateEnd),
Location: element.data.Location,
TypeAgenda: element.data.TypeAgenda,
Role: element.data.Role,
Status: element.data.Status,
read: false,
index: i,
title: element.notification.title,
Service: element.data.Service || element.data.service ,
Object: element.data.Object || element.data.object ,
IdObject: element.data.IdObject || element.data.idObject ,
FolderId: element.data.FolderId || element.data.folderId ,
body: element.notification.body,
dateInit: this.getFormatedTime(element.data.dateInit),
dateEnd: this.getFormatedTime(element.data.dateEnd),
Location: element.data.Location || element.data.location ,
TypeAgenda: element.data.TypeAgenda || element.data.typeAgenda ,
Role: element.data.Role || element.data.role ,
Status: element.data.Status || element.data.status ,
read: false,
}
} else if (element.data) {
} else if (element.data) {
notificationObject = {
index: i,
title: element.title,
Service: element.data.Service,
Object: element.data.Object,
IdObject: element.data.IdObject,
FolderId: element.data.FolderId,
body: element.body,
dateInit: this.getFormatedTime(element.data.dateInit),
dateEnd: this.getFormatedTime(element.data.dateEnd),
Location: element.data.Location,
TypeAgenda: element.data.TypeAgenda,
Role: element.data.Role,
Status: element.data.Status,
read: false,
index: i,
title: element.title,
Service: element.data.Service || element.data.service ,
Object: element.data.Object || element.data.object ,
IdObject: element.data.IdObject || element.data.idObject ,
FolderId: element.data.FolderId || element.data.folderId ,
body: element.body,
dateInit: this.getFormatedTime(element.data.dateInit),
dateEnd: this.getFormatedTime(element.data.dateEnd),
Location: element.data.Location || element.data.location ,
TypeAgenda: element.data.TypeAgenda || element.data.typeAgenda ,
Role: element.data.Role || element.data.role ,
Status: element.data.Status || element.data.status ,
read: false,
}
} else {
{
notificationObject = {
FolderId: element.FolderId,
IdObject: element.IdObject,
Location: element.Location,
Object: element.Object,
Role: element.Role,
Service: element.Service,
Status: element.Status,
TypeAgenda: element.TypeAgenda,
} else {
notificationObject = {
FolderId: element.FolderId || element.folderId ,
IdObject: element.IdObject || element.idObject ,
Location: element.Location || element.location ,
Object: element.Object || element.object ,
Role: element.Role || element.role ,
Service: element.Service || element.service ,
Status: element.Status || element.status ,
TypeAgenda: element.TypeAgenda || element.typeAgenda ,
body: element.body,
dateEnd: element.dateEnd,
dateInit: element.dateInit,
index: element.index,
title: element.title,
read: false,
}
}
}
}
this.notificationList.push(notificationObject)
this.save()
@@ -6,6 +6,8 @@ import { environment } from 'src/environments/environment';
import { NotificationsEndsPointsService } from './notifications-ends-points.service'
import { AngularFireMessaging } from '@angular/fire/messaging';
import { NavigationExtras, Router } from '@angular/router';
import { NotificationRepositoryService } from 'src/app/module/notification/data/notification-repository.service'
@Injectable({
providedIn: 'root'
})
@@ -20,6 +22,7 @@ export class NotificationsService {
private afMessaging: AngularFireMessaging,
private router: Router,
private zone: NgZone,
private NotificationRepositoryService: NotificationRepositoryService
) { }
@@ -143,7 +146,7 @@ export class NotificationsService {
);
} else {
navigator.serviceWorker.onmessage = (event) => {
console.log('Mensagem recebida do Service Worker:', event.data.data);
console.log('Mensagem recebida do Service Worker:', event.data);
let object = {
notification: event.data
}
+6 -5
View File
@@ -20,7 +20,7 @@ import { ChatSystemService } from './chat/chat-system.service';
import {ChatController} from 'src/app/controller/chat'
import { TracingType, XTracer, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
import { z } from 'zod';
import { NotificationRepositoryService } from 'src/app/module/notification/data/notification-repository.service'
const notificationDataSchema = z.object({
Service: z.string(),
IdObject: z.string().optional(),
@@ -69,10 +69,11 @@ export class NotificationsService {
private zone: NgZone,
private eventtrigger: EventTrigger,
private afMessaging: AngularFireMessaging,
public NotificationHolderService: NotificationHolderService) {
public NotificationHolderService: NotificationHolderService,
private NotificationRepositoryService: NotificationRepositoryService) {
this.onReciveForeground();
this.onReciveBackground();
// this.onReciveForeground();
// this.onReciveBackground();
}
@@ -288,7 +289,7 @@ export class NotificationsService {
try {
navigator.serviceWorker.onmessage = (event) => {
console.log('Mensagem recebida do Service Worker:', event.data.data);
console.log('Mensagem recebida do Service Worker:', event.data);
let object = {
notification: event.data
}
+1 -1
View File
@@ -313,7 +313,7 @@ export class TaskService {
}
@XTracerAsync({name:'taskService/loadEventosParaAprovacao', bugPrint: true})
@XTracerAsync({name:'taskService/loadEventToAprove', bugPrint: true})
async loadEventosParaAprovacao(tracing?: TracingType) {
this.showLoaderNum++
console.log('PR')
+19 -2
View File
@@ -57,6 +57,23 @@ export class ToastService {
}
removeBeforeHash(text) {
const hashIndex = text.indexOf('#');
if (hashIndex !== -1) {
return text.substring(hashIndex);
}
return text;
}
getEverythingBeforeHash(text) {
const hashIndex = text.indexOf('#');
if (hashIndex !== -1) {
return text.substring(0, hashIndex).trim();
}
return text;
}
async _badRequest(message?: string, callback?) {
let notification = document.createElement('div')
@@ -73,9 +90,9 @@ export class ToastService {
`
notification.style.animationName = 'notification-top'
console.error(this.removeBeforeHash(message))
document.body.append(notification)
notification.querySelector('.text').innerHTML = message || 'Processo não efetuado'
notification.querySelector('.text').innerHTML = this.getEverythingBeforeHash(message) || 'Processo não efetuado'
setTimeout(()=>{
if (callback) {
callback()
@@ -353,9 +353,9 @@
<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"> Correspondencia </span>
<span class="app-name" *ngIf="document.ApplicationId == 386"> AccoesPresidenciais </span>
<span class="app-name" *ngIf="document.ApplicationId == 361 "> ArquivoDespachoElect </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>
@@ -17,6 +17,7 @@ import { ThemeService } from 'src/app/services/theme.service'
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service';
import { AgendaDataRepositoryService } from 'src/app/services/Repositorys/Agenda/agenda-data-repository.service';
import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
import { AttendeesLIstChangeDetector } from 'src/app/services/Repositorys/Agenda/async/change/attendeesLIstChangeDetector';
const CUSTOM_DATE_FORMATS: NgxMatDateFormats = {
parse: {
@@ -136,7 +137,8 @@ export class EditEventToApprovePage implements OnInit {
private toastService: ToastService,
public ThemeService: ThemeService,
public httpErrorHandler: HttpErrorHandle,
private agendaDataRepository: AgendaDataRepositoryService
private agendaDataRepository: AgendaDataRepositoryService,
private httpErroHalde: HttpErrorHandle,
) {
this.isEventEdited = false;
}
@@ -153,28 +155,43 @@ export class EditEventToApprovePage implements OnInit {
}
async getTask() {
const res: any = await this.agendaDataRepository.getEventToApproveById(this.serialNumber)
console.log('evento to apro to edit', res.value)
this.eventProcess = res.value;
@XTracerAsync({name:'edit-event-approve/getTask', bugPrint: true})
async getTask(tracing?: TracingType) {
this.eventProcess.workflowInstanceDataFields.LastOccurrence = new Date(this.eventProcess.workflowInstanceDataFields.LastOccurrence)
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.restoreDatepickerData()
this.eventProcess.workflowInstanceDataFields.LastOccurrence = new Date(this.eventProcess.workflowInstanceDataFields.LastOccurrence)
// description
let body: any = this.eventProcess.workflowInstanceDataFields.Body.replace(/<[^>]+>/g, '')
this.eventProcess.workflowInstanceDataFields.Body = body
this.eventProcess.workflowInstanceDataFields.Category = this.setEventType(this.eventProcess.workflowInstanceDataFields.EventType)
this.restoreDatepickerData()
this.InstanceId = this.eventProcess.workflowInstanceDataFields.InstanceId
this.loadedAttachments = res.value.Attachments;
console.log(this.loadedAttachments)
// description
this.setOtherData()
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')
tracing.bugFlag()
this.httpErroHalde.httpStatusHandle(res.error)
}
this.saveTemporaryData()
}
getRecurrenceTypes() {
@@ -322,11 +339,10 @@ export class EditEventToApprovePage implements OnInit {
if (this.Form.invalid) return false
// set dates to eventProcess object
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.restoreDatepickerData()
// this.getDatepickerData()
this.taskParticipantsCc.forEach(e => {
e.IsRequired = false
@@ -384,15 +400,35 @@ export class EditEventToApprovePage implements OnInit {
tracing.setAttribute('outcome', 'failed')
}));
this.agendaDataRepository.addEventAttendee(this.eventProcess.serialNumber, this.eventProcess.workflowInstanceDataFields.ParticipantsList).subscribe((value) => {
console.log(value)
}, ((error) => {
console.log('add Attendee error: ', error)
tracing.setAttribute('failed.attendees', 'true')
}));
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) {
this.agendaDataRepository.addEventAttendee(this.eventProcess.serialNumber, insert).subscribe((value) => {
console.log(value)
}, ((error) => {
console.log('add Attendee error: ', error)
tracing.setAttribute('failed.attendees', 'true')
}));
}
if(remove.length >= 1) {
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) {
this.agendaDataRepository.addEventAttachment(this.eventProcess.serialNumber, this.loadedAttachments).subscribe((value) => {
this.agendaDataRepository.addEventAttachment(this.eventProcess.serialNumber, this.loadedAttachments, tracing).subscribe((value) => {
console.log(value)
}, ((error) => {
this.showLoader = false
@@ -420,24 +456,24 @@ export class EditEventToApprovePage implements OnInit {
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()
})
}
// 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()
// })
// }
})
// })
}
@@ -20,6 +20,7 @@ import { Observable } from 'rxjs';
import { TableSharedCalendar } from 'src/app/services/Repositorys/Agenda/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/services/Repositorys/Agenda/async/change/attendeesLIstChangeDetector';
@Component({
selector: 'app-edit-event',
templateUrl: './edit-event.page.html',
@@ -96,13 +97,13 @@ export class EditEventPage implements OnInit {
SessionStore= SessionStore
CalendarNameOwnerName = ''
CalendarNamesOptions = []
allDayCheck: boolean = false;
addedAttachmentsList = [];
sharedCalendar: Observable<TableSharedCalendar[]>
hasChangeCalendar = false
selectedUserCalendar:any;
CalendarNamesOptions = ['Oficial', 'Pessoal']
constructor(
private modalController: ModalController,
@@ -132,10 +133,10 @@ export class EditEventPage implements OnInit {
}
ngOnInit() {
console.log('this.postEvent', this.postEvent)
this.selectedUserCalendar = this.postEvent.owner.wxUserId
this.loadedEventAttachments = this.postEvent.Attachments
console.log(this.postEvent.Category)
this._postEvent = this.postEvent
this._postEvent.Category = this.setEventType(this._postEvent.Category)
if (!this._postEvent.IsRecurring) {
@@ -423,6 +424,8 @@ export class EditEventPage implements OnInit {
return false
}
const serverCurrentList = this._postEvent.Attendees
this._postEvent.Attendees = this.taskParticipants.concat(this.taskParticipantsCc);
@@ -448,16 +451,36 @@ export class EditEventPage implements OnInit {
tracing.setAttribute('outcome', 'failed')
}));
this.agendaDataRepository.addEventAttendee(this._postEvent.EventId, this._postEvent.Attendees).subscribe((value) => {
console.log(value)
}, ((error) => {
tracing.setAttribute('failed.attendees', 'true')
console.log('add Attendee error: ', error)
}));
console.log({serverCurrentList, Attendees: this._postEvent.Attendees})
const { insert, remove } = AttendeesLIstChangeDetector(serverCurrentList as any, this._postEvent.Attendees as any)
console.log({ insert, remove });
if(insert.length >= 1) {
this.agendaDataRepository.addEventAttendee(this._postEvent.EventId, insert).subscribe((value) => {
console.log(value)
}, ((error) => {
tracing.setAttribute('failed.attendees', 'true')
console.log('add Attendee error: ', error)
}));
}
if(remove.length >= 1) {
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) {
this.agendaDataRepository.addEventAttachment(this._postEvent.EventId, this.loadedEventAttachments).subscribe((value) => {
if (this.addedAttachmentsList.length >= 1) {
this.agendaDataRepository.addEventAttachment(this._postEvent.EventId, this.loadedEventAttachments, tracing).subscribe((value) => {
console.log(value)
}, ((error) => {
this.showLoader = false
@@ -466,7 +489,7 @@ export class EditEventPage implements OnInit {
}));
}
if (this.deletedAttachmentsList.length > 0) {
if (this.deletedAttachmentsList.length >= 1) {
this.agendaDataRepository.removeEventAttachment(this._postEvent.EventId, { attachments: this.deletedAttachmentsList }).subscribe((value) => {
console.log(value)
}, ((error) => {
@@ -518,7 +541,7 @@ export class EditEventPage implements OnInit {
postEvent: this._postEvent,
eventBody: this.eventBody,
segment: this.segment,
loadedEventAttachments: this.loadedEventAttachments
loadedEventAttachments: this.loadedEventAttachments,
}
}
@@ -613,27 +636,21 @@ export class EditEventPage implements OnInit {
}
changeAgenda() {
async changeAgenda() {
setTimeout(() => {
console.log('selecione agenda', this.eventsService.calendarNamesType)
const result = await this.agendaDataRepository.geCalendars()
if (this.eventsService.calendarNamesType[this.CalendarNameOwnerName]?.['Oficial'] && this.eventsService.calendarNamesType[this.CalendarNameOwnerName]?.['Pessoal']) {
const selectedCalendar = result.find(e => e.wxUserId == this.selectedUserCalendar)
this.CalendarNamesOptions = ['Oficial', 'Pessoal']
} else if (this.eventsService.calendarNamesType[this.CalendarNameOwnerName]?.['Oficial']) {
if(selectedCalendar) {
if(selectedCalendar.shareType == 1) {
this.CalendarNamesOptions = ['Oficial']
this._postEvent.CalendarName = 'Oficial'
} else if (this.eventsService.calendarNamesType[this.CalendarNameOwnerName]?.['Pessoal']) {
} else if(selectedCalendar.shareType == 2) {
this.CalendarNamesOptions = ['Pessoal']
this._postEvent.CalendarName = 'Pessoal'
} else {
} else if (selectedCalendar.shareType == 3) {
this.CalendarNamesOptions = ['Oficial', 'Pessoal']
}
}, 50)
}
}
@@ -687,13 +704,19 @@ export class EditEventPage implements OnInit {
}
setEventType(eventType) {
var selectedEventType = {
1: 'Meeting',
2: 'Travel',
3: 'Conference',
4: 'Encontro'
if(typeof eventType == 'number') {
var selectedEventType = {
1: 'Meeting',
2: 'Travel',
3: 'Conference',
4: 'Encontro'
}
return selectedEventType[eventType];
} else {
return this._postEvent.Category
}
return selectedEventType[eventType];
}
}
@@ -185,6 +185,8 @@ export class NewEventPage implements OnInit {
this.selectedUserCalendar = SessionStore.user.UserId
}
this.changeAgenda()
}
}
@@ -408,34 +410,23 @@ export class NewEventPage implements OnInit {
this.hasChangeCalendar = true
}
changeAgenda() {
async changeAgenda() {
this.CalendarNameShow = false
setTimeout(() => {
const result = await this.agendaDataRepository.geCalendars()
this.CalendarNameShow = true
const selectedCalendar = result.find(e => e.wxUserId == this.selectedUserCalendar)
if (this.eventService.calendarNamesType[this.CalendarName]?.['Oficial'] && this.eventService.calendarNamesType[this.CalendarName]?.['Pessoal']) {
this.CalendarNamesOptions = ['Oficial', 'Pessoal']
console.log(this.postEvent.CalendarName)
} else if (this.eventService.calendarNamesType[this.CalendarName]?.['Oficial']) {
if(selectedCalendar) {
if(selectedCalendar.shareType == 1) {
this.CalendarNamesOptions = ['Oficial']
this.postEvent.CalendarName = 'Oficial'
console.log(this.postEvent.CalendarName)
} else if (this.eventService.calendarNamesType[this.CalendarName]?.['Pessoal']) {
} else if(selectedCalendar.shareType == 2) {
this.CalendarNamesOptions = ['Pessoal']
this.postEvent.CalendarName = 'Pessoal'
console.log(this.postEvent.CalendarName)
} else {
} else if (selectedCalendar.shareType == 3) {
this.CalendarNamesOptions = ['Oficial', 'Pessoal']
console.log(this.postEvent.CalendarName)
}
}, 50)
}
}
@@ -90,6 +90,9 @@
<span *ngIf="!loadedEvent.IsRecurring">(Não se repete)</span>
</p>
<!-- <p >
{{ daysToEnd }} dias para terminar o evento
</p> -->
</ion-label>
</div>
</div>
@@ -57,6 +57,7 @@ export class ViewEventPage implements OnInit {
sesseionStora = SessionStore
TimeZoneString = ''
daysToEnd = 0
constructor(
public eventsService: EventsService,
@@ -78,8 +79,36 @@ export class ViewEventPage implements OnInit {
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();
@@ -128,17 +157,30 @@ export class ViewEventPage implements OnInit {
setTimeZone() {
this.TimeZoneString = this.loadedEvent.TimeZone
}
@XTracerAsync({name:'ViewEventPage/loadEvent', bugPrint: true})
@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 {
@@ -285,15 +285,16 @@
</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 || 'Sem título'}}</span>
<span class="app-name" *ngIf="document.ApplicationId == 8"> Correspondencia </span>
<span class="app-name" *ngIf="document.ApplicationId == 386"> AccoesPresidenciais </span>
<span class="app-name" *ngIf="document.ApplicationId == 361 "> ArquivoDespachoElect </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>
@@ -16,6 +16,7 @@ import { ThemeService } from 'src/app/services/theme.service'
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service'
import { AgendaDataRepositoryService } from 'src/app/services/Repositorys/Agenda/agenda-data-repository.service';
import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
import { AttendeesLIstChangeDetector } from 'src/app/services/Repositorys/Agenda/async/change/attendeesLIstChangeDetector';
const CUSTOM_DATE_FORMATS: NgxMatDateFormats = {
parse: {
@@ -115,12 +116,8 @@ export class EditEventToApproveComponent implements OnInit {
constructor(
private modalController: ModalController,
private navParams: NavParams,
private eventsService: EventsService,
public alertController: AlertController,
private attachmentsService: AttachmentsService,
private processes: ProcessesService,
private toastService: ToastService,
private router: Router,
public ThemeService: ThemeService,
private httpErroHalde: HttpErrorHandle,
private agendaDataRepository: AgendaDataRepositoryService
@@ -149,7 +146,8 @@ export class EditEventToApproveComponent implements OnInit {
})
}, 1000);
async getTask() {
@XTracerAsync({name:'mobile/loadEventToApproveDetails', bugPrint: true})
async getTask(tracing?: TracingType) {
/* const result = await this.processes.GetTask(this.serialNumber).toPromise(); */
const res = await this.agendaDataRepository.getEventToApproveById(this.serialNumber)
@@ -164,8 +162,13 @@ export class EditEventToApproveComponent implements OnInit {
this.endDate = new Date(this.eventProcess.workflowInstanceDataFields.EndDate);
// description
let body: any = this.eventProcess.workflowInstanceDataFields.Body.replace(/<[^>]+>/g, '')
this.eventProcess.workflowInstanceDataFields.Body = body
try {
let body: any = this.eventProcess.workflowInstanceDataFields.Body.replace(/<[^>]+>/g, '')
this.eventProcess.workflowInstanceDataFields.Body = body
} catch (error) {}
this.Location = this.eventProcess.workflowInstanceDataFields.Location
this.InstanceId = this.eventProcess.workflowInstanceDataFields.InstanceId
@@ -189,7 +192,10 @@ export class EditEventToApproveComponent implements OnInit {
}
})
tracing.setAttribute('outcome', 'success')
} else {
tracing.setAttribute('outcome', 'failed')
tracing.bugFlag()
this.httpErroHalde.httpStatusHandle(res.error)
}
@@ -271,6 +277,7 @@ export class EditEventToApproveComponent implements OnInit {
e.IsRequired = false
})
const serverCurrentList = this.eventProcess.workflowInstanceDataFields.ParticipantsList
this.eventProcess.workflowInstanceDataFields.ParticipantsList = this.taskParticipants.concat(this.taskParticipantsCc)
this.eventProcess.workflowInstanceDataFields.ParticipantsList.forEach(e => {
@@ -325,16 +332,36 @@ export class EditEventToApproveComponent implements OnInit {
tracing.setAttribute('outcome', 'failed')
}));
this.agendaDataRepository.addEventAttendee(this.eventProcess.serialNumber, this.eventProcess.workflowInstanceDataFields.ParticipantsList).subscribe((value) => {
console.log({serverCurrentList, ParticipantsList:this.eventProcess.workflowInstanceDataFields.ParticipantsList})
const { insert, remove } = AttendeesLIstChangeDetector(serverCurrentList as any, this.eventProcess.workflowInstanceDataFields.ParticipantsList as any)
console.log({insert, remove})
if(insert.length >= 1) {
this.agendaDataRepository.addEventAttendee(this.eventProcess.serialNumber, insert).subscribe((value) => {
}, ((error) => {
console.log('add Attendee error: ', error)
tracing.setAttribute('failed.attendees', 'true')
}));
}
if(remove.length >= 1) {
this.agendaDataRepository.removeEventAttendee(this.eventProcess.serialNumber, remove).subscribe((value) => {
}, ((error) => {
console.log('add Attendee error: ', error)
tracing.setAttribute('failed.attendees', 'true')
}));
}
}, ((error) => {
console.log('add Attendee error: ', error)
tracing.setAttribute('failed.attendees', 'true')
}));
if (this.addedAttachmentsList.length > 0) {
this.agendaDataRepository.addEventAttachment(this.eventProcess.serialNumber, this.loadedAttachments).subscribe((value) => {
this.agendaDataRepository.addEventAttachment(this.eventProcess.serialNumber, this.loadedAttachments, tracing).subscribe((value) => {
console.log(value)
}, ((error) => {
this.showLoader = false
+3 -3
View File
@@ -53,9 +53,9 @@ export class CalendarService {
removeRangeForCalendar(rangeStartDate, rangeEndDate, profile, calendarId) {
this._eventSource = this._eventSource.filter((e)=> {
if(new Date(rangeStartDate).getTime() <= new Date(e.startTime).getTime() &&
new Date(rangeEndDate).getTime() >= new Date(e.endTime).getTime() && e.CalendarId == calendarId) {
this._eventSource = this._eventSource.filter((e) => {
if( new Date(e.endTime).getTime() >= new Date(rangeStartDate).getTime() &&
new Date(rangeEndDate).getTime() >= new Date(e.startTime).getTime() && e.CalendarId == calendarId) {
return false
}
return true
+24 -24
View File
@@ -54,10 +54,10 @@ export class NotificationHolderService {
id: notification?.id || uuidv4(),
index: i,
title: element.notification.title,
Service: element.data.Service,
Object: element.data.Object,
IdObject: element.data.IdObject,
FolderId: element.data.FolderId,
Service: element.data.Service || element.data.service,
Object: element.data.Object || element.data.object,
IdObject: element.data.IdObject || element.data.idObject,
FolderId: element.data.FolderId || element.data.folderId,
body: element.notification.body,
dateInit: this.getFormatedTime(element.data.dateInit),
dateEnd: this.getFormatedTime(element.data.dateEnd),
@@ -73,10 +73,10 @@ export class NotificationHolderService {
id: notification?.id || uuidv4(),
index: i,
title: element.title,
Service: element.data.Service,
Object: element.data.Object,
IdObject: element.data.IdObject,
FolderId: element.data.FolderId,
Service: element.data.Service || element.data.service,
Object: element.data.Object || element.data.object,
IdObject: element.data.IdObject || element.data.idObject,
FolderId: element.data.FolderId || element.data.folderId,
body: element.body,
dateInit: this.getFormatedTime(element.data.dateInit),
dateEnd: this.getFormatedTime(element.data.dateEnd),
@@ -91,12 +91,12 @@ export class NotificationHolderService {
{
notificationObject = {
id: notification?.id || uuidv4(),
FolderId: element.FolderId,
IdObject: element.IdObject,
FolderId: element.FolderId || element.data.folderId,
IdObject: element.IdObject || element.data.idObject,
Location: element.Location,
Object: element.Object,
Object: element.Object || element.data.object,
Role: element.Role,
Service: element.Service,
Service: element.Service || element.data.service,
Status: element.Status,
TypeAgenda: element.TypeAgenda,
body: element.body,
@@ -124,10 +124,10 @@ export class NotificationHolderService {
notificationObject = {
id: notification?.id || uuidv4(),
title: element.notification.title,
Service: element.data.Service,
Object: element.data.Object,
IdObject: element.data.IdObject,
FolderId: element.data.FolderId,
Service: element.data.Service || element.data.service,
Object: element.data.Object || element.data.object,
IdObject: element.data.IdObject || element.data.idObject,
FolderId: element.data.FolderId || element.data.folderId,
body: element.notification.body,
dateInit: this.getFormatedTime(element.data.dateInit),
dateEnd: this.getFormatedTime(element.data.dateEnd),
@@ -142,10 +142,10 @@ export class NotificationHolderService {
notificationObject = {
id: notification?.id || uuidv4(),
title: element.title,
Service: element.data.Service,
Object: element.data.Object,
IdObject: element.data.IdObject,
FolderId: element.data.FolderId,
Service: element.data.Service || element.data.service,
Object: element.data.Object || element.data.object,
IdObject: element.data.IdObject || element.data.idObject,
FolderId: element.data.FolderId || element.data.folderId,
body: element.body,
dateInit: this.getFormatedTime(element.data.dateInit),
dateEnd: this.getFormatedTime(element.data.dateEnd),
@@ -160,12 +160,12 @@ export class NotificationHolderService {
{
notificationObject = {
id: notification?.id || uuidv4(),
FolderId: element.FolderId,
IdObject: element.IdObject,
FolderId: element.FolderId || element.data.folderId,
IdObject: element.IdObject || element.data.idObject,
Location: element.Location,
Object: element.Object,
Object: element.Object || element.data.object,
Role: element.Role,
Service: element.Service,
Service: element.Service || element.data.service,
Status: element.Status,
TypeAgenda: element.TypeAgenda,
body: element.body,
+6 -6
View File
@@ -1,11 +1,11 @@
export let versionData = {
"shortSHA": "0c14b9be9",
"SHA": "0c14b9be979f22b13e627b978767be4a173d9768",
"shortSHA": "78c13d1bf",
"SHA": "78c13d1bfb0b5e24a79a101990ba73e50e831107",
"branch": "feature/agenda-api-peter",
"lastCommitAuthor": "'Peter Maquiran'",
"lastCommitTime": "'Fri Jun 21 23:33:29 2024 +0100'",
"lastCommitMessage": "fix ownertype and category type",
"lastCommitNumber": "5836",
"changeStatus": "On branch feature/agenda-api-peter\nYour branch is ahead of 'origin/feature/agenda-api-peter' by 7 commits.\n (use \"git push\" to publish your local commits)\n\nChanges to be committed:\n (use \"git restore --staged <file>...\" to unstage)\n\tmodified: angular.json\n\tmodified: src/app/interceptors/metter.interceptor.ts\n\tmodified: src/app/pages/agenda/edit-event/edit-event.page.html\n\tmodified: src/app/pages/agenda/edit-event/edit-event.page.ts\n\tmodified: src/app/pages/agenda/new-event/new-event.page.ts\n\tmodified: src/app/services/Repositorys/Agenda/agenda-data-repository.service.ts\n\tmodified: src/app/services/Repositorys/Agenda/model/eventInputDTO.ts\n\tmodified: src/app/services/Repositorys/Agenda/model/eventListDTOOutput.ts\n\tmodified: src/app/services/Repositorys/Agenda/model/eventToApproveListOutputDTO.ts\n\tnew file: src/app/services/Repositorys/Agenda/model/eventUpdateInputDtO.ts\n\tmodified: src/app/services/monitoring/opentelemetry/tracer.ts\n\tmodified: src/app/shared/agenda/edit-event-to-approve/edit-event-to-approve.page.ts\n\tmodified: src/app/shared/agenda/edit-event/edit-event.page.ts\n\tmodified: src/app/shared/agenda/new-event/new-event.page.ts\n\tmodified: src/app/shared/gabinete-digital/edit-event-to-approve/edit-event.page.html\n\tmodified: src/app/shared/gabinete-digital/edit-event-to-approve/edit-event.page.ts\n\tmodified: version/git-version.ts",
"lastCommitTime": "'Wed Jun 26 13:45:25 2024 +0100'",
"lastCommitMessage": "ITOTEAM-609 search event>",
"lastCommitNumber": "5844",
"changeStatus": "On branch feature/agenda-api-peter\nYour branch is ahead of 'origin/feature/agenda-api-peter' by 7 commits.\n (use \"git push\" to publish your local commits)\n\nChanges to be committed:\n (use \"git restore --staged <file>...\" to unstage)\n\tmodified: src/app/modals/profile/profile.page.html\n\tmodified: src/app/modals/profile/profile.page.scss\n\tmodified: src/app/modals/profile/profile.page.ts\n\tnew file: src/app/module/notification/data/async/changes/notificationListChange.ts\n\tnew file: src/app/module/notification/data/datasource/firebase-push-notification.service.spec.ts\n\tnew file: src/app/module/notification/data/datasource/firebase-push-notification.service.ts\n\tnew file: src/app/module/notification/data/datasource/local-notification.service.spec.ts\n\tnew file: src/app/module/notification/data/datasource/local-notification.service.ts\n\tnew file: src/app/module/notification/data/datasource/remote-notification.service.spec.ts\n\tnew file: src/app/module/notification/data/datasource/remote-notification.service.ts\n\tnew file: src/app/module/notification/data/dto/NotificationInputDTO.ts\n\tnew file: src/app/module/notification/data/dto/NotificationOutputDTO.ts\n\tnew file: src/app/module/notification/data/infra/db/notification.db.ts\n\tnew file: src/app/module/notification/data/notification-repository.service.spec.ts\n\tnew file: src/app/module/notification/data/notification-repository.service.ts\n\tnew file: src/app/module/notification/domain/mapper/notificationListMapper.ts\n\tmodified: src/app/pages/agenda/agenda.page.html\n\tmodified: src/app/pages/agenda/agenda.page.ts\n\tmodified: src/app/services/agenda/list-box.service.ts\n\tmodified: src/app/services/http.service.ts\n\tmodified: src/app/services/notification/notifications.service.ts\n\tmodified: src/app/services/notifications.service.ts",
"changeAuthor": "peter.maquiran"
}