From 5f7295d41cac085ff8fa36261e31cfc40f2fb630 Mon Sep 17 00:00:00 2001 From: "peter.maquiran" Date: Thu, 11 Sep 2025 11:20:44 +0100 Subject: [PATCH] fix publication details --- package-lock.json | 267 ++++++++++++++++++ package.json | 2 + src/app/app.module.ts | 252 ++++++++++++++--- src/app/core/actions/entity/action.ts | 47 +++ .../actions/entity/publicationDocument.ts | 27 ++ .../core/actions/entity/publicationEntity.ts | 43 +++ .../actions-create-use-case.service.ts | 36 +++ .../actions-get-all-use-case.service.ts | 53 ++++ ...ication-file-get-by-document-id.service.ts | 105 +++++++ ...on-get-documents-by-document-id.service.ts | 32 +++ .../publication-list-by-process-id.service.ts | 134 +++++++++ src/app/core/chat/entity/group.ts | 2 +- .../action/member-local-repository.ts | 12 + .../member/member-add-use-case.service.ts | 1 + .../member/member-admin-use-case.service.ts | 1 + .../listen-message-by-roomId.service.ts | 2 +- .../message/listen-send-message.service.ts | 2 +- .../message-create-use-case.service.ts | 2 +- .../messages-send-offline-use-case.service.ts | 2 +- .../room/room-bold-sync-use-case.service.ts | 4 +- src/app/core/user/entity/userEntity.ts | 2 +- .../user/repository/user-remote-repository.ts | 2 +- .../dexie/instance/action/schema/action.ts | 27 ++ .../instance/action/schema/publication.ts | 24 ++ .../instance/action/schema/publicationFile.ts | 16 ++ .../database/dexie/instance/action/service.ts | 22 ++ src/app/infra/http/http.service.ts | 120 ++------ src/app/infra/http/type.ts | 9 +- .../interceptors/metter.interceptor.ts | 2 - .../dexie/dexie-repository.service.ts | 3 - .../entiry/agenda/eventToApproveDetails.ts | 2 +- .../action-local-repository.service.ts | 14 + .../action-remote-repository.service.ts | 47 +++ ...blication-file-local-repository.service.ts | 14 + ...lication-file-remote-repository.service.ts | 27 ++ .../publication-file-repository.service.ts | 9 + .../publication-local-repository.service.ts | 15 + .../publication-remote-repository.service.ts | 21 ++ .../change/shareCalendarChangeDetector.ts | 1 - .../module/agenda/data/dto/eventDTOOutput.ts | 4 +- .../agenda/data/dto/eventListDTOOutput.ts | 2 +- .../data/dto/eventToApproveListOutputDTO.ts | 2 +- .../member-list-remote-repository.service.ts | 3 +- .../room/room-remote-repository.service.ts | 1 + .../chat/domain/chat-service.service.ts | 4 +- .../service/room-last-message.service.ts | 2 +- .../async/changes/notificationListChange.ts | 1 - .../pages/publications/publications.page.html | 20 +- .../pages/publications/publications.page.ts | 122 ++------ .../view-publications.page.html | 37 --- .../view-publications.page.ts | 66 +---- .../publication/new-action/new-action.page.ts | 43 ++- .../upload/publication-from-mv.service.ts | 4 +- .../publication-detail.module.ts | 4 +- .../publication-detail.page copy.html | 92 ++++++ .../publication-detail.page.html | 62 ++-- .../publication-detail.page.ts | 75 +++-- .../show-more/show-more.page.ts | 2 +- .../view-publications.page.html | 77 ++--- .../view-publications.page.ts | 31 +- src/app/shared/swiper/swiper.page.html | 38 ++- src/app/shared/swiper/swiper.page.ts | 32 ++- src/app/store/publication-folder.service.ts | 115 ++++---- src/app/ui/agenda/agenda.page.ts | 5 - .../group-contacts/group-contacts.page.ts | 3 +- .../chat/component/messages/messages.page.ts | 7 +- .../group-contacts/group-contacts.page.ts | 4 +- .../ui/chat/modal/messages/messages.page.ts | 3 + .../shared/components/header/header.page.ts | 3 - src/environments/environment.ts | 1 - src/global.scss | 21 ++ src/index.html | 8 +- src/theme/variables.scss | 8 + version/git-version.ts | 12 +- 74 files changed, 1639 insertions(+), 678 deletions(-) create mode 100644 src/app/core/actions/entity/action.ts create mode 100644 src/app/core/actions/entity/publicationDocument.ts create mode 100644 src/app/core/actions/entity/publicationEntity.ts create mode 100644 src/app/core/actions/use-case/actions-create-use-case.service.ts create mode 100644 src/app/core/actions/use-case/actions-get-all-use-case.service.ts create mode 100644 src/app/core/actions/use-case/publication-file-get-by-document-id.service.ts create mode 100644 src/app/core/actions/use-case/publication-get-documents-by-document-id.service.ts create mode 100644 src/app/core/actions/use-case/publication-list-by-process-id.service.ts create mode 100644 src/app/core/chat/repository/action/member-local-repository.ts create mode 100644 src/app/infra/database/dexie/instance/action/schema/action.ts create mode 100644 src/app/infra/database/dexie/instance/action/schema/publication.ts create mode 100644 src/app/infra/database/dexie/instance/action/schema/publicationFile.ts create mode 100644 src/app/infra/database/dexie/instance/action/service.ts create mode 100644 src/app/module/actions/data/repository/action-local-repository.service.ts create mode 100644 src/app/module/actions/data/repository/action-remote-repository.service.ts create mode 100644 src/app/module/actions/data/repository/publication-file-local-repository.service.ts create mode 100644 src/app/module/actions/data/repository/publication-file-remote-repository.service.ts create mode 100644 src/app/module/actions/data/repository/publication-file-repository.service.ts create mode 100644 src/app/module/actions/data/repository/publication-local-repository.service.ts create mode 100644 src/app/module/actions/data/repository/publication-remote-repository.service.ts create mode 100644 src/app/shared/publication/view-publications/publication-detail/publication-detail.page copy.html diff --git a/package-lock.json b/package-lock.json index 4e688a2c2..35e1ba09f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -99,6 +99,8 @@ "@ngrx/store": "^10.1.2", "@ngx-translate/core": "^13.0.0", "@ngxs/store": "^3.8.2", + "@openreplay/tracker": "^16.4.8", + "@openreplay/tracker-assist": "^11.0.8", "@opentelemetry/exporter-metrics-otlp-http": "^0.52.1", "@opentelemetry/exporter-trace-otlp-http": "^0.52.1", "@opentelemetry/exporter-zipkin": "^1.25.1", @@ -7802,6 +7804,123 @@ "read-package-json-fast": "^2.0.1" } }, + "node_modules/@openreplay/network-proxy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@openreplay/network-proxy/-/network-proxy-1.2.0.tgz", + "integrity": "sha512-vIOzBWVKn+7/Dk4qFmRxR1fdOEnLt1hXkEYtc3m7eIA2nVwz+BSGW4Hbs/ygFLnNS0HkcBwuRgmXAwRMK5HCrQ==" + }, + "node_modules/@openreplay/tracker": { + "version": "16.4.8", + "resolved": "https://registry.npmjs.org/@openreplay/tracker/-/tracker-16.4.8.tgz", + "integrity": "sha512-IB/yIzquRQAYGch55tkwXm0dKN2eKAzLNbxD6I21bKOlcWy+PfOMqb7p4opKR+vE/BReGUG3q7Cl1S6BghDUWQ==", + "dependencies": { + "@openreplay/network-proxy": "^1.2.0", + "error-stack-parser": "^2.1.4", + "error-stack-parser-es": "^0.1.5", + "fflate": "^0.8.2", + "web-vitals": "^4.2.4" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/@openreplay/tracker-assist": { + "version": "11.0.8", + "resolved": "https://registry.npmjs.org/@openreplay/tracker-assist/-/tracker-assist-11.0.8.tgz", + "integrity": "sha512-Sj1q3MChiiWShGSKDcb10rCdlAVi0VqA+NUnEmdfdSYUlc/lQZWnU4EbpfwSiWd32Ns9pKIohlZPJoulcJ4sdg==", + "dependencies": { + "csstype": "^3.0.10", + "fflate": "^0.8.2", + "socket.io-client": "^4.8.1" + }, + "peerDependencies": { + "@openreplay/tracker": ">=14.0.14" + } + }, + "node_modules/@openreplay/tracker-assist/node_modules/engine.io-client": { + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.3.tgz", + "integrity": "sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1", + "xmlhttprequest-ssl": "~2.1.1" + } + }, + "node_modules/@openreplay/tracker-assist/node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@openreplay/tracker-assist/node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==" + }, + "node_modules/@openreplay/tracker-assist/node_modules/socket.io-client": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.1.tgz", + "integrity": "sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.6.1", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@openreplay/tracker-assist/node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@openreplay/tracker-assist/node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@openreplay/tracker-assist/node_modules/xmlhttprequest-ssl": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz", + "integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/@openreplay/tracker/node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==" + }, "node_modules/@opentelemetry/api": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", @@ -14393,6 +14512,11 @@ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, "node_modules/currently-unhandled": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", @@ -15811,6 +15935,22 @@ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, + "node_modules/error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "dependencies": { + "stackframe": "^1.3.4" + } + }, + "node_modules/error-stack-parser-es": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-0.1.5.tgz", + "integrity": "sha512-xHku1X40RO+fO8yJ8Wh2f2rZWVjqyhb1zgq1yZ8aZRQkv6OOKhKWRUaht3eSCUbAOBaKIgM+ykwFLE+QUxgGeg==", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/es-abstract": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.0.tgz", @@ -35822,6 +35962,11 @@ "node": ">=8" } }, + "node_modules/stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" + }, "node_modules/static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", @@ -43127,6 +43272,11 @@ "defaults": "^1.0.3" } }, + "node_modules/web-vitals": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz", + "integrity": "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==" + }, "node_modules/webdriver-js-extender": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-2.1.0.tgz", @@ -50488,6 +50638,95 @@ "read-package-json-fast": "^2.0.1" } }, + "@openreplay/network-proxy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@openreplay/network-proxy/-/network-proxy-1.2.0.tgz", + "integrity": "sha512-vIOzBWVKn+7/Dk4qFmRxR1fdOEnLt1hXkEYtc3m7eIA2nVwz+BSGW4Hbs/ygFLnNS0HkcBwuRgmXAwRMK5HCrQ==" + }, + "@openreplay/tracker": { + "version": "16.4.8", + "resolved": "https://registry.npmjs.org/@openreplay/tracker/-/tracker-16.4.8.tgz", + "integrity": "sha512-IB/yIzquRQAYGch55tkwXm0dKN2eKAzLNbxD6I21bKOlcWy+PfOMqb7p4opKR+vE/BReGUG3q7Cl1S6BghDUWQ==", + "requires": { + "@openreplay/network-proxy": "^1.2.0", + "error-stack-parser": "^2.1.4", + "error-stack-parser-es": "^0.1.5", + "fflate": "^0.8.2", + "web-vitals": "^4.2.4" + }, + "dependencies": { + "fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==" + } + } + }, + "@openreplay/tracker-assist": { + "version": "11.0.8", + "resolved": "https://registry.npmjs.org/@openreplay/tracker-assist/-/tracker-assist-11.0.8.tgz", + "integrity": "sha512-Sj1q3MChiiWShGSKDcb10rCdlAVi0VqA+NUnEmdfdSYUlc/lQZWnU4EbpfwSiWd32Ns9pKIohlZPJoulcJ4sdg==", + "requires": { + "csstype": "^3.0.10", + "fflate": "^0.8.2", + "socket.io-client": "^4.8.1" + }, + "dependencies": { + "engine.io-client": { + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.3.tgz", + "integrity": "sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==", + "requires": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1", + "xmlhttprequest-ssl": "~2.1.1" + } + }, + "engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==" + }, + "fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==" + }, + "socket.io-client": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.1.tgz", + "integrity": "sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==", + "requires": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.6.1", + "socket.io-parser": "~4.2.4" + } + }, + "socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "requires": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + } + }, + "ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "requires": {} + }, + "xmlhttprequest-ssl": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz", + "integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==" + } + } + }, "@opentelemetry/api": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", @@ -55568,6 +55807,11 @@ } } }, + "csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, "currently-unhandled": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", @@ -56658,6 +56902,19 @@ } } }, + "error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "requires": { + "stackframe": "^1.3.4" + } + }, + "error-stack-parser-es": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-0.1.5.tgz", + "integrity": "sha512-xHku1X40RO+fO8yJ8Wh2f2rZWVjqyhb1zgq1yZ8aZRQkv6OOKhKWRUaht3eSCUbAOBaKIgM+ykwFLE+QUxgGeg==" + }, "es-abstract": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.0.tgz", @@ -72104,6 +72361,11 @@ } } }, + "stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" + }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", @@ -77812,6 +78074,11 @@ "defaults": "^1.0.3" } }, + "web-vitals": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz", + "integrity": "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==" + }, "webdriver-js-extender": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-2.1.0.tgz", diff --git a/package.json b/package.json index b0b315285..158cd6c75 100644 --- a/package.json +++ b/package.json @@ -118,6 +118,8 @@ "@ngrx/store": "^10.1.2", "@ngx-translate/core": "^13.0.0", "@ngxs/store": "^3.8.2", + "@openreplay/tracker": "^16.4.8", + "@openreplay/tracker-assist": "^11.0.8", "@opentelemetry/exporter-metrics-otlp-http": "^0.52.1", "@opentelemetry/exporter-trace-otlp-http": "^0.52.1", "@opentelemetry/exporter-zipkin": "^1.25.1", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 82387e690..504f4df6b 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -103,49 +103,231 @@ import { registerLocaleData } from '@angular/common'; import localePt from '@angular/common/locales/pt'; import { LogsDatabase } from './infra/database/dexie/instance/logs/service'; import { UserModule } from './module/user/user.module'; +import { Logger } from './services/logger/main/service'; // Register the locale data registerLocaleData(localePt, 'pt'); - Sentry.init( - { - dsn: 'https://5b345a3ae70b4e4da463da65881b4aaa@o4504340905525248.ingest.sentry.io/4504345615794176', - // To set your release and dist versions - release: 'gabinetedigital@1.0.0', - dist: '1', - // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring. - // We recommend adjusting this value in production. - tracesSampleRate: 1.0, - integrations: [ - new BrowserTracing({ - tracingOrigins: ['localhost', 'https://gd-api.oapr.gov.ao/api/'], - }) as Integration, - ], - beforeSend(event) { - console.log('event.exception.values[0].value', event.exception.values[0].value); +// Sentry.init( +// { +// dsn: 'https://5b345a3ae70b4e4da463da65881b4aaa@o4504340905525248.ingest.sentry.io/4504345615794176', +// // To set your release and dist versions +// release: 'gabinetedigital@1.0.0', +// dist: '1', +// // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring. +// // We recommend adjusting this value in production. +// tracesSampleRate: 1.0, +// integrations: [ +// new BrowserTracing({ +// tracingOrigins: ['localhost', 'https://gd-api.oapr.gov.ao/api/'], +// }) as Integration, +// ], +// beforeSend(event) { +// console.log('event.exception.values[0].value', event.exception.values[0].value); - if (event.level === 'error') { +// if (event.level === 'error') { - LogsDatabase.sentryError.add(event as any).then(() => { - console.log('event', event) - }) +// LogsDatabase.sentryError.add(event as any).then(() => { +// console.log('event', event) +// }) - openTelemetryLogging.send({ - level: 'info', - message: event.exception.values[0].value, - payload: { - object: { - sentry: true, - error: event - } - }, - }) +// openTelemetryLogging.send({ +// level: 'info', +// message: event.exception.values[0].value, +// payload: { +// object: { +// sentry: true, +// error: event +// } +// }, +// }) +// } + +// console.log('Sentry Event', event); +// // Return event to send it to Sentry +// return event; +// }, +// } +// ); + + +import Tracker from '@openreplay/tracker'; +import trackerAssist from '@openreplay/tracker-assist'; // 👈 for errors, logs & stack traces +const tracker = new Tracker({ + projectKey: "g8HOZiBi5iUWEsK3Ajw5", + __DISABLE_SECURE_MODE: true, // ✅ allow HTTP + localhost +}); +tracker.start() +tracker.use(trackerAssist()); +tracker.setUserID('john@doe.com'); + + + +(function () { + const httpLogs = []; + + // --- Patch fetch --- + const originalFetch = window.fetch; + window.fetch = async (input, config = {}) => { + const url = typeof input === "string" ? input : (input as any).url; + const method = config?.method || "GET"; + + // Capture tracer header + let tracerHeader = null; + if (config?.headers) { + if (config.headers instanceof Headers) { + tracerHeader = config.headers.get("x-tracer"); + } else if (typeof config.headers === "object") { + tracerHeader = config.headers["x-tracer"] || config.headers["X-Tracer"]; + } } - // Return event to send it to Sentry - return event; - }, - } -); + + // Capture request body (payload) + let requestPayload = null; + if (config?.body) { + try { + requestPayload = typeof config.body === "string" + ? config.body + : JSON.stringify(config.body); + } catch { + requestPayload = "[Unserializable body]"; + } + } + + const start = Date.now(); + try { + const response = await originalFetch(input, config); + + // Clone response so we don’t consume it + const clone = response.clone(); + let responsePayload = null; + try { + const contentType = clone.headers.get("content-type") || ""; + if (contentType.includes("application/json")) { + responsePayload = await clone.json(); + } else if (contentType.includes("text")) { + responsePayload = await clone.text(); + } else { + responsePayload = "[Non-textual body]"; + } + } catch { + responsePayload = "[Unserializable response]"; + } + + const log = { + type: "fetch", + url, + method, + status: response.status, + xTracer: tracerHeader, + requestPayload, + responsePayload, + duration: Date.now() - start, + timestamp: new Date().toISOString(), + }; + if(response.status >= 400 || response.status === 0) { + Logger.error('XHR', log) + } + httpLogs.push(log); + + return response; + } catch (error) { + const log = { + type: "fetch", + url, + method, + status: "NETWORK_ERROR", + xTracer: tracerHeader, + requestPayload, + responsePayload: null, + duration: Date.now() - start, + timestamp: new Date().toISOString(), + }; + + if(!url.includes('petermaquiran.xyz') && url != "") { + Logger.error('XHR', log); + } + + httpLogs.push(log); + throw error; + } + }; + + // --- Patch XMLHttpRequest --- + const OriginalXHR = window.XMLHttpRequest; + function CustomXHR() { + const xhr: any = new OriginalXHR(); + const start = Date.now(); + xhr._xTracer = null; + xhr._requestPayload = null; + + const originalSetRequestHeader = xhr.setRequestHeader; + xhr.setRequestHeader = function (key, value) { + if (key.toLowerCase() === "x-tracer") { + xhr._xTracer = value; + } + return originalSetRequestHeader.call(xhr, key, value); + }; + + const originalSend = xhr.send; + xhr.send = function (body) { + if (body) { + try { + xhr._requestPayload = typeof body === "string" ? body : JSON.stringify(body); + } catch { + xhr._requestPayload = "[Unserializable body]"; + } + } + return originalSend.call(xhr, body); + }; + + xhr.addEventListener("loadend", function () { + let responsePayload = null; + try { + const contentType = xhr.getResponseHeader("content-type") || ""; + if (contentType.includes("application/json")) { + responsePayload = JSON.parse(xhr.responseText); + } else if (contentType.includes("text")) { + responsePayload = xhr.responseText; + } else { + responsePayload = "[Non-textual body]"; + } + } catch { + responsePayload = "[Unserializable response]"; + } + const log = { + type: "xhr", + url: xhr.responseURL, + method: xhr._method || "GET", + status: xhr.status, + xTracer: xhr._xTracer, + requestPayload: xhr._requestPayload, + responsePayload, + duration: Date.now() - start, + timestamp: new Date().toISOString(), + }; + + if(xhr.status >= 400 || xhr.status === 0) { + Logger.error('XHR', log) + } + + httpLogs.push(log); + }); + + const originalOpen = xhr.open; + xhr.open = function (method, url, ...rest) { + xhr._method = method; + return originalOpen.call(xhr, method, url, ...rest); + }; + + return xhr; + } + (window as any).XMLHttpRequest = CustomXHR; + + // Expose logs + (window as any).getHttpLogs = () => httpLogs; +})(); + @NgModule({ declarations: [AppComponent, PopupQuestionPipe, InputFilterDirective], diff --git a/src/app/core/actions/entity/action.ts b/src/app/core/actions/entity/action.ts new file mode 100644 index 000000000..2ab237fbe --- /dev/null +++ b/src/app/core/actions/entity/action.ts @@ -0,0 +1,47 @@ +import { BaseEntity } from "src/app/utils/entity"; +import { z } from "zod" + +export const ActionEntitySchema = z.object({ + processId: z.number(), + applicationId: z.number(), + organicEntityId: z.number(), + securityId: z.number(), + serieId: z.number(), + userId: z.number(), + dateIndex: z.string().datetime(), // ISO 8601 datetime + description: z.string(), + detail: z.string(), + dateBegin: z.string().datetime(), + dateEnd: z.string().datetime(), + actionType: z.number(), + location: z.string(), + isExported: z.boolean(), + sourceLocation: z.number(), + sourceProcessId: z.number(), +}) + +export type IAction = z.infer +export class ActionEntity extends BaseEntity(ActionEntitySchema) implements IAction{ + + processId: typeof ActionEntitySchema._input.processId + applicationId: typeof ActionEntitySchema._input.processId + organicEntityId: typeof ActionEntitySchema._input.processId + securityId: typeof ActionEntitySchema._input.processId + serieId: typeof ActionEntitySchema._input.processId + userId: typeof ActionEntitySchema._input.processId + dateIndex: typeof ActionEntitySchema._input.dateIndex + description: typeof ActionEntitySchema._input.description + detail: typeof ActionEntitySchema._input.detail + dateBegin: typeof ActionEntitySchema._input.dateBegin + dateEnd: typeof ActionEntitySchema._input.dateEnd + actionType: typeof ActionEntitySchema._input.processId + location: typeof ActionEntitySchema._input.location + isExported: typeof ActionEntitySchema._input.isExported + sourceLocation:typeof ActionEntitySchema._input.processId + sourceProcessId: typeof ActionEntitySchema._input.processId + + constructor(data: IAction) { + super(); + Object.assign(this, data) + } +} diff --git a/src/app/core/actions/entity/publicationDocument.ts b/src/app/core/actions/entity/publicationDocument.ts new file mode 100644 index 000000000..892fcfe73 --- /dev/null +++ b/src/app/core/actions/entity/publicationDocument.ts @@ -0,0 +1,27 @@ +import { z } from "zod" + +export const PublicationDocumentEntitySchema = z.object({ + id: z.number().optional(), + file: z.string(), + extension: z.string(), + name: z.string(), + path: z.string(), + documentId: z.number(), + datePublication: z.string(), +}) + +export type IPublicationDocument = z.infer +export class PublicationDocumentEntity implements IPublicationDocument{ + + file: typeof PublicationDocumentEntitySchema._input.file + extension: typeof PublicationDocumentEntitySchema._input.extension + name: typeof PublicationDocumentEntitySchema._input.name + path: typeof PublicationDocumentEntitySchema._input.path + documentId: typeof PublicationDocumentEntitySchema._input.documentId + datePublication: typeof PublicationDocumentEntitySchema._input.datePublication + id: typeof PublicationDocumentEntitySchema._input.id + + constructor(data: IPublicationDocument) { + Object.assign(this, data) + } +} diff --git a/src/app/core/actions/entity/publicationEntity.ts b/src/app/core/actions/entity/publicationEntity.ts new file mode 100644 index 000000000..c417bcc6d --- /dev/null +++ b/src/app/core/actions/entity/publicationEntity.ts @@ -0,0 +1,43 @@ +import { BaseEntity } from "src/app/utils/entity"; +import { z } from "zod" + +export const PublicationEntitySchema = z.object({ + processId: z.number(), + documentId: z.number(), + applicationId: z.number(), + organicEntityId: z.number(), + securityId: z.number(), + userId: z.number(), + dateIndex: z.string(), + phase: z.number(), + title: z.string(), + message: z.string(), + datePublication: z.string(), + isExported: z.boolean(), + sourceLocation: z.number(), + sourceProcessId: z.number(), + sourceDocumentId: z.number(), +}) + +export type IPublication = z.infer +export class PublicationEntity extends BaseEntity(PublicationEntitySchema) implements IPublication{ + + processId: typeof PublicationEntitySchema._input.processId + applicationId: typeof PublicationEntitySchema._input.processId + organicEntityId: typeof PublicationEntitySchema._input.processId + securityId: typeof PublicationEntitySchema._input.processId + serieId: typeof PublicationEntitySchema._input.processId + userId: typeof PublicationEntitySchema._input.processId + dateIndex: typeof PublicationEntitySchema._input.dateIndex + isExported: typeof PublicationEntitySchema._input.isExported + sourceLocation:typeof PublicationEntitySchema._input.processId + sourceProcessId: typeof PublicationEntitySchema._input.processId + sourceDocumentId:typeof PublicationEntitySchema._input.sourceDocumentId + documentId: typeof PublicationEntitySchema._input.documentId + datePublication: typeof PublicationEntitySchema._input.datePublication + + constructor(data: IPublication) { + super(); + Object.assign(this, data) + } +} diff --git a/src/app/core/actions/use-case/actions-create-use-case.service.ts b/src/app/core/actions/use-case/actions-create-use-case.service.ts new file mode 100644 index 000000000..624b5c741 --- /dev/null +++ b/src/app/core/actions/use-case/actions-create-use-case.service.ts @@ -0,0 +1,36 @@ +import { Injectable } from '@angular/core'; +import { ActionLocalRepositoryService } from 'src/app/module/actions/data/repository/action-local-repository.service'; +import { ActionRemoteRepositoryService } from 'src/app/module/actions/data/repository/action-remote-repository.service'; +import { z } from 'zod'; + + +export const ActionsCreateInputDTOSchema = z.object({ + userId: z.number(), + description: z.string(), + detail: z.string(), + location: z.string(), + dateBegin: z.string().refine((val) => !isNaN(Date.parse(val)), { + message: "Invalid ISO date string", + }), + dateEnd: z.string().refine((val) => !isNaN(Date.parse(val)), { + message: "Invalid ISO date string", + }), + actionType: z.string(), +}); +export type ActionsCreateInput = z.infer + + +@Injectable({ + providedIn: 'root' +}) +export class ActionsCreateUseCaseService { + + constructor( + private remote: ActionRemoteRepositoryService, + private local: ActionLocalRepositoryService + ) { } + + execute(input: ActionsCreateInput) { + this.remote.create(input); + } +} diff --git a/src/app/core/actions/use-case/actions-get-all-use-case.service.ts b/src/app/core/actions/use-case/actions-get-all-use-case.service.ts new file mode 100644 index 000000000..bbcf82b61 --- /dev/null +++ b/src/app/core/actions/use-case/actions-get-all-use-case.service.ts @@ -0,0 +1,53 @@ +import { Injectable } from '@angular/core'; +import { ActionLocalRepositoryService } from 'src/app/module/actions/data/repository/action-local-repository.service'; +import { ActionRemoteRepositoryService } from 'src/app/module/actions/data/repository/action-remote-repository.service'; +import { z } from "zod"; + +export const ActionGetAllOutPutSchema = z.array(z.object({ + processId: z.number(), + applicationId: z.number(), + organicEntityId: z.number(), + securityId: z.number(), + serieId: z.number(), + userId: z.number(), + dateIndex: z.string().datetime(), // ISO 8601 datetime + description: z.string(), + detail: z.string(), + dateBegin: z.string().datetime(), + dateEnd: z.string().datetime(), + actionType: z.number(), + location: z.string(), + isExported: z.boolean(), + sourceLocation: z.number(), + sourceProcessId: z.number(), +})); + +// Example usage: +export type ActionGetAllOutPut = z.infer; + +@Injectable({ + providedIn: 'root' +}) +export class ActionsGetAllUseCaseService { + + constructor( + private remote: ActionRemoteRepositoryService, + private local: ActionLocalRepositoryService + ) { } + + async execute() { + + var result = await this.remote.actionGetAll(); + + if(result.isOk()) { + const data = result.value.data.data; + + this.local.createTransaction( async (table) => { + // Clear the table before inserting new data + await table.clear(); + // Insert the new data + await table.bulkAdd(data); + }); + } + } +} diff --git a/src/app/core/actions/use-case/publication-file-get-by-document-id.service.ts b/src/app/core/actions/use-case/publication-file-get-by-document-id.service.ts new file mode 100644 index 000000000..84ff67f81 --- /dev/null +++ b/src/app/core/actions/use-case/publication-file-get-by-document-id.service.ts @@ -0,0 +1,105 @@ +import { Injectable } from '@angular/core'; +import { Result } from 'neverthrow'; +import { PublicationFileLocalRepositoryService } from 'src/app/module/actions/data/repository/publication-file-local-repository.service'; +import { PublicationFileRemoteRepositoryService } from 'src/app/module/actions/data/repository/publication-file-remote-repository.service'; +import { z } from 'zod'; +import { HttpErrorResponse } from '@angular/common/http'; + +export const PublicationFileGetByDocumentIdInputDTOSchema = z.object({ + datePublication: z.string(), + documentId: z.number(), + processId: z.number(), +}); +export type PublicationFileGetByDocumentIdInput = z.infer + +export const PublicationFileGetByDocumentIdOutPutDTOSchema = z.object({ + id: z.number().optional(), + file: z.string(), + extension: z.string(), + name: z.string(), + path: z.string(), + documentId: z.number(), + datePublication: z.string(), +}).array(); +export type PublicationFileGetByDocumentIdOutPut = z.infer + +export interface IPublicationFilesSyncResult { + added: PublicationFileGetByDocumentIdOutPut; + updated: PublicationFileGetByDocumentIdOutPut; + remove: PublicationFileGetByDocumentIdOutPut; +} + +@Injectable({ + providedIn: 'root' +}) +export class PublicationFileGetByDocumentIdService { + + constructor( + private local: PublicationFileLocalRepositoryService, + private remote: PublicationFileRemoteRepositoryService + ) { } + + async execute(input: PublicationFileGetByDocumentIdInput): Promise> { + var httpResult = await this.remote.FileListByDocumentId(input); + + if(httpResult.isOk()) { + var localResult = await this.local.findAll(); + if(localResult.isOk()) { + const serverFiles = httpResult.value.data + + const added = []; + const updated = []; + const remove = []; + + for (const localItem of localResult.value) { + if (localItem.datePublication !== input.datePublication!) { + localItem.datePublication = input.datePublication; + this.local.update(localItem.id, localItem); + } + } + + for (const file of serverFiles) { + const findLocally = await this.local.findOne({ name: file.name }); + + if (findLocally.isOk() && findLocally.value == null) { + added.push({ + ...file, + documentId: input.documentId!, + datePublication: input.datePublication, + }); + + const start = performance.now(); + this.local.insert({ + ...file, + documentId: input.documentId!, + datePublication: input.datePublication, + }).then(() => { + const end = performance.now(); + console.log(`Insert duration for file "${file.name}": ${(end - start).toFixed(2)} ms`); + }); + } + } + + for (const localFile of localResult.value) { + const found = httpResult.value.data.filter((e) => e.name === localFile.name); + if (found.length === 0 && localFile.name) { + remove.push(localFile); + this.local.delete(localFile.id); + } + } + + return httpResult.map(() =>({ + added, + updated, + remove + })) + } + } + + return httpResult.map(() =>({ + added: [], + updated: [], + remove: [] + })); + } +} diff --git a/src/app/core/actions/use-case/publication-get-documents-by-document-id.service.ts b/src/app/core/actions/use-case/publication-get-documents-by-document-id.service.ts new file mode 100644 index 000000000..683647ce1 --- /dev/null +++ b/src/app/core/actions/use-case/publication-get-documents-by-document-id.service.ts @@ -0,0 +1,32 @@ +import { Injectable } from '@angular/core'; +import { ActionLocalRepositoryService } from 'src/app/module/actions/data/repository/action-local-repository.service'; +import { ActionRemoteRepositoryService } from 'src/app/module/actions/data/repository/action-remote-repository.service'; +import { z } from 'zod'; + + +const PublicationGetDocumentByProcessIdOutPutSchema = z.object({ + file: z.string(), + extension: z.string(), + name: z.string(), + path: z.string(), + documentId: z.number() +}).array(); + +// Example usage: +export type PublicationGetDocumentByProcessIdOutPut = z.infer; + + +@Injectable({ + providedIn: 'root' +}) +export class PublicationGetDocumentByProcessIdService { + + constructor( + private remote: ActionRemoteRepositoryService, + private local: ActionLocalRepositoryService + ) {} + + execute(processId: string) { + this.remote + } +} diff --git a/src/app/core/actions/use-case/publication-list-by-process-id.service.ts b/src/app/core/actions/use-case/publication-list-by-process-id.service.ts new file mode 100644 index 000000000..c2206fac1 --- /dev/null +++ b/src/app/core/actions/use-case/publication-list-by-process-id.service.ts @@ -0,0 +1,134 @@ +import { Injectable } from '@angular/core'; +import { PublicationLocalRepositoryService } from 'src/app/module/actions/data/repository/publication-local-repository.service'; +import { PublicationRemoteRepositoryService } from 'src/app/module/actions/data/repository/publication-remote-repository.service'; +import { z } from 'zod'; +import { IPublication } from '../entity/publicationEntity'; +import { Result } from 'neverthrow'; +import { HttpErrorResponse } from '@angular/common/http'; + +const PublicationListByProcessIdOutPutSchema = z.object({ + processId: z.number(), + documentId: z.number(), + applicationId: z.number(), + organicEntityId: z.number(), + securityId: z.number(), + userId: z.number(), + dateIndex: z.string().datetime(), + phase: z.number(), + title: z.string(), + message: z.string(), + datePublication: z.string().datetime(), + isExported: z.boolean(), + sourceLocation: z.number(), + sourceProcessId: z.number(), + sourceDocumentId: z.number(), +}).array(); + +// Example usage: +export type PublicationListByProcessIdOutPut = z.infer; + + +export interface IPublicationSyncResult { + added: IPublication[]; + updated: IPublication[]; + remove: IPublication[]; +} + +@Injectable({ + providedIn: 'root' +}) +export class PublicationListByProcessIdService { + + constructor( + private remote: PublicationRemoteRepositoryService, + private local: PublicationLocalRepositoryService, + ) {} + + async execute(processId: number): Promise> { + const result = await this.remote.listByProcessId(processId); + + if(result.isOk()) { + const publications = result.value.data.data || []; + + var localList = await this.local.findAll(); + + if(localList.isOk()) { + + const localMap = new Map( + localList.value.map(item => [item.documentId.toString(), item]) + ); + + var serverMap = new Map( + publications.map(item => [item.documentId.toString(), item]) + ); + + const added = []; + const updated = []; + const remove = []; + + console.log("local::", localList.value.length); + console.log("server::", publications.length); + + // detect added & updated + for (const [id, serverItem] of serverMap) { + if (!localMap.has(id)) { + console.log(localList.value.map(item => item.documentId.toString()).join(","), id); + added.push(serverMap.get(id)); + } else if (serverItem.datePublication !== localMap.get(id).datePublication) { + updated.push(serverMap.get(id)); + console.log('update'); + } else { + console.log('else'); + console.log(localMap, serverMap); + } + } + + // detect removed + for (const [id, localItem] of Object.keys(localMap)) { + if (!serverMap.has(id)) { + remove.push(localMap.get(id)); + } + } + + console.log("update::", Object.keys(updated).length); + console.log("added::", added.length); + console.log("remove::", remove.length); + + // apply updates + if (updated.length > 0) { + await this.local.updateMany(Object.values(updated)); + } + + // apply removals + for (const deletedItem of remove) { + const findRequest = await this.local.findOne({ + documentId: deletedItem.documentId + }); + if (findRequest.isOk()) { + await this.local.delete(findRequest.value.documentId!); + } + } + + // apply inserts + if (added.length > 0) { + await this.local.insertMany(added); + } + + return result.map(()=>({ + added, + updated, + remove + })) + } + } + + return result.map(()=>({ + added: [], + updated: [], + remove: [] + })) + + } +} + + diff --git a/src/app/core/chat/entity/group.ts b/src/app/core/chat/entity/group.ts index 2660bd815..80fc04596 100644 --- a/src/app/core/chat/entity/group.ts +++ b/src/app/core/chat/entity/group.ts @@ -14,7 +14,7 @@ const UserSchema = z.object({ wxUserId: z.number(), wxFullName: z.string(), wxeMail: z.string(), - userPhoto: z.string().nullable(), + userPhoto: z.string().nullable().optional(), }); const MemberSchema = z.object({ diff --git a/src/app/core/chat/repository/action/member-local-repository.ts b/src/app/core/chat/repository/action/member-local-repository.ts new file mode 100644 index 000000000..5efb62bc6 --- /dev/null +++ b/src/app/core/chat/repository/action/member-local-repository.ts @@ -0,0 +1,12 @@ +import { DexieRepository } from "src/app/infra/repository/dexie/dexie-repository.service"; +import { Observable as DexieObservable, PromiseExtended } from 'Dexie'; +import { AttachmentTable } from "src/app/infra/database/dexie/instance/chat/schema/attachment"; +import { Result } from "neverthrow"; +import { MemberTable, MemberTableSchema } from "src/app/infra/database/dexie/instance/chat/schema/members"; +import { RepositoryResult } from "src/app/infra/repository"; +import { z } from "zod"; +import { MemberListUPdateStatusInputDTO } from "src/app/core/chat/usecase/socket/member-list-update-status-use-case.service"; +import { Observable } from "rxjs"; +import { ActionTable } from "src/app/infra/database/dexie/instance/action/schema/action"; + +export abstract class IActionLocalRepository extends DexieRepository {} diff --git a/src/app/core/chat/usecase/member/member-add-use-case.service.ts b/src/app/core/chat/usecase/member/member-add-use-case.service.ts index 4947e7132..99b0f1303 100644 --- a/src/app/core/chat/usecase/member/member-add-use-case.service.ts +++ b/src/app/core/chat/usecase/member/member-add-use-case.service.ts @@ -7,6 +7,7 @@ import { IMemberRemoteRepository } from 'src/app/core/chat/repository/member/mem export const AddMemberToRoomInputDTOSchema = z.object({ id: z.string(), members: z.array(z.number()), + userId: z.number() }); export type AddMemberToRoomInputDTO = z.infer diff --git a/src/app/core/chat/usecase/member/member-admin-use-case.service.ts b/src/app/core/chat/usecase/member/member-admin-use-case.service.ts index d037b5d09..aa9898e0c 100644 --- a/src/app/core/chat/usecase/member/member-admin-use-case.service.ts +++ b/src/app/core/chat/usecase/member/member-admin-use-case.service.ts @@ -5,6 +5,7 @@ import { IMemberRemoteRepository } from 'src/app/core/chat/repository/member/mem // Define the schema for the entire response const MemberSetAdminDTOSchema = z.object({ + senderId: z.number(), roomId: z.string(), memberId: z.string() }); diff --git a/src/app/core/chat/usecase/message/listen-message-by-roomId.service.ts b/src/app/core/chat/usecase/message/listen-message-by-roomId.service.ts index 5e60893bc..01deab59c 100644 --- a/src/app/core/chat/usecase/message/listen-message-by-roomId.service.ts +++ b/src/app/core/chat/usecase/message/listen-message-by-roomId.service.ts @@ -25,7 +25,7 @@ export class ListenMessageByRoomIdNewUseCase { return this.MessageSocketRepositoryService.listenToMessages().pipe( map(message => message.data), - filter((message) => message.deviceId != getInstanceId()), + filter((message) => message?.deviceId != getInstanceId()), map(message => { return Object.assign(new MessageEntity(), message) }) diff --git a/src/app/core/chat/usecase/message/listen-send-message.service.ts b/src/app/core/chat/usecase/message/listen-send-message.service.ts index f70cc1788..a5c86cf91 100644 --- a/src/app/core/chat/usecase/message/listen-send-message.service.ts +++ b/src/app/core/chat/usecase/message/listen-send-message.service.ts @@ -25,7 +25,7 @@ export class ListenSendMessageUseCase { return this.MessageSocketRepositoryService.listenToMessages().pipe( map(message => message.data), - filter((message) => message.deviceId != getInstanceId()), + filter((message) => message?.deviceId != getInstanceId()), map(message => message) ) diff --git a/src/app/core/chat/usecase/message/message-create-use-case.service.ts b/src/app/core/chat/usecase/message/message-create-use-case.service.ts index 9d1292e4c..9bdb3c3d9 100644 --- a/src/app/core/chat/usecase/message/message-create-use-case.service.ts +++ b/src/app/core/chat/usecase/message/message-create-use-case.service.ts @@ -138,7 +138,7 @@ export class MessageCreateUseCaseService { var a = await this.MessageRemoteRepository.messageAttachmentUpload({ fileType: att.fileType, source: att.source, - file: isWebtrix ? null : att.base64.replace(/^data:[a-zA-Z]+\/[a-zA-Z]+;base64,/, ''), + file: isWebtrix ? null : att.base64.split(",")[1], fileName: att.fileName, applicationId: att.applicationId || 0, docId: att.docId || 0, diff --git a/src/app/core/chat/usecase/message/messages-send-offline-use-case.service.ts b/src/app/core/chat/usecase/message/messages-send-offline-use-case.service.ts index eacbab169..20bff873a 100644 --- a/src/app/core/chat/usecase/message/messages-send-offline-use-case.service.ts +++ b/src/app/core/chat/usecase/message/messages-send-offline-use-case.service.ts @@ -83,7 +83,7 @@ export class SendLocalMessagesUseCaseService { var a = await this.MessageRemoteRepository.messageAttachmentUpload({ fileType: att.fileType, source: att.source, - file: isWebtrix ? null : att.base64.replace(/^data:[a-zA-Z]+\/[a-zA-Z]+;base64,/, ''), + file: isWebtrix ? null : att.base64.split(",")[1], fileName: att.fileName, applicationId: att.applicationId || 0, docId: att.docId || 0, diff --git a/src/app/core/chat/usecase/room/room-bold-sync-use-case.service.ts b/src/app/core/chat/usecase/room/room-bold-sync-use-case.service.ts index 4cc7e7c81..906cac4b6 100644 --- a/src/app/core/chat/usecase/room/room-bold-sync-use-case.service.ts +++ b/src/app/core/chat/usecase/room/room-bold-sync-use-case.service.ts @@ -37,7 +37,7 @@ export class RoomBoldSyncUseCaseService { private listenToIncomingMessage() { return this.MessageSocketRepositoryService.listenToMessages().pipe( map(message => message.data), - filter((message) => message.deviceId != getInstanceId()), + filter((message) => message?.deviceId != getInstanceId()), map(message => Object.assign(new MessageEntity(), message)), filter((message) => !message.meSender()) ).subscribe(async (message) => { @@ -59,7 +59,7 @@ export class RoomBoldSyncUseCaseService { */ private listenToUpdateMessages() { return this.MessageSocketRepositoryService.listenToUpdateMessages().pipe( - filter((message) => message.deviceId != getInstanceId()), + filter((message) => message?.deviceId != getInstanceId()), map(message => Object.assign(new MessageEntity(), message)) ).subscribe(async (message) => { diff --git a/src/app/core/user/entity/userEntity.ts b/src/app/core/user/entity/userEntity.ts index bf5c33c9e..906dc711c 100644 --- a/src/app/core/user/entity/userEntity.ts +++ b/src/app/core/user/entity/userEntity.ts @@ -98,7 +98,7 @@ const UserSessionSchema = z.object({ Inactivity: z.boolean(), UrlBeforeInactivity: z.string(), UserPermissions: z.unknown(), // Again, you can define it more explicitly if needed - UserPhoto: z.string().nullable(), + UserPhoto: z.string().nullable().optional(), RefreshToken: z.string(), }); diff --git a/src/app/core/user/repository/user-remote-repository.ts b/src/app/core/user/repository/user-remote-repository.ts index 51670b552..0306529ce 100644 --- a/src/app/core/user/repository/user-remote-repository.ts +++ b/src/app/core/user/repository/user-remote-repository.ts @@ -17,7 +17,7 @@ const UserSchema = z.object({ wxeMail: z.string(), role: z.string(), roleId: z.number(), - userPhoto: z.string().nullable(), + userPhoto: z.string().nullable().optional(), adUserSID: z.string(), }); diff --git a/src/app/infra/database/dexie/instance/action/schema/action.ts b/src/app/infra/database/dexie/instance/action/schema/action.ts new file mode 100644 index 000000000..067e8a67f --- /dev/null +++ b/src/app/infra/database/dexie/instance/action/schema/action.ts @@ -0,0 +1,27 @@ +import { EntityTable } from 'Dexie'; +import { z } from 'zod'; + +export enum ActionDetailsStatus { + editedLocal, + deletedLocal, + offline, + pending, + sending, + synced, +} + +export const ActionTableSchema = z.object({ + processId: z.number().nullable().optional(), + //localProcessId: z.string(), // unique identifier + dateIndex: z.string().transform((val) => new Date(val)), // store as ISO string, transform to Date + description: z.string(), + detail: z.string(), + dateBegin: z.string().transform((val) => new Date(val)), + dateEnd: z.string().transform((val) => new Date(val)), + statusIndex: z.number().int().min(0).max(Object.keys(ActionDetailsStatus).length / 2 - 1), + errorCreating: z.boolean().nullable().optional(), +}) + +export type ActionTable = z.infer; +export type DexieActionTable = EntityTable; +export const ActionTableColumn = 'processId, dateIndex, description, detail, dateBegin, dateEnd, statusIndex, errorCreating'; diff --git a/src/app/infra/database/dexie/instance/action/schema/publication.ts b/src/app/infra/database/dexie/instance/action/schema/publication.ts new file mode 100644 index 000000000..e95d3dfdd --- /dev/null +++ b/src/app/infra/database/dexie/instance/action/schema/publication.ts @@ -0,0 +1,24 @@ +import { EntityTable } from 'Dexie'; +import { z } from 'zod'; + +export const PublicationTableSchema = z.object({ + processId: z.number(), + documentId: z.number(), + applicationId: z.number(), + organicEntityId: z.number(), + securityId: z.number(), + userId: z.number(), + dateIndex: z.string(), + phase: z.number(), + title: z.string(), + message: z.string(), + datePublication: z.string(), + isExported: z.boolean(), + sourceLocation: z.number(), + sourceProcessId: z.number(), + sourceDocumentId: z.number(), +}) + +export type PublicationTable = z.infer; +export type DexiePublicationTable = EntityTable; +export const PublicationTableColumn = 'documentId, processId, applicationId, organicEntityId, securityId, userId, dateIndex, phase, title, message, datePublication, sourceLocation, sourceProcessId, isExported, sourceDocumentId'; diff --git a/src/app/infra/database/dexie/instance/action/schema/publicationFile.ts b/src/app/infra/database/dexie/instance/action/schema/publicationFile.ts new file mode 100644 index 000000000..7dd14aa45 --- /dev/null +++ b/src/app/infra/database/dexie/instance/action/schema/publicationFile.ts @@ -0,0 +1,16 @@ +import { EntityTable } from 'Dexie'; +import { z } from 'zod'; + +export const PublicationFileTableSchema = z.object({ + id: z.number().optional(), + file: z.string(), + extension: z.string(), + name: z.string(), + path: z.string(), + documentId: z.number(), + datePublication: z.string(), +}) + +export type PublicationFileTable = z.infer; +export type DexiePublicationFilesTable = EntityTable; +export const PublicationFileTableColumn = '++id, file, extension, name, path, documentId, datePublication'; diff --git a/src/app/infra/database/dexie/instance/action/service.ts b/src/app/infra/database/dexie/instance/action/service.ts new file mode 100644 index 000000000..2bd766a96 --- /dev/null +++ b/src/app/infra/database/dexie/instance/action/service.ts @@ -0,0 +1,22 @@ + +import { Dexie } from 'Dexie'; +import { ActionTableColumn, DexieActionTable } from './schema/action'; +import { DexiePublicationTable, PublicationTable, PublicationTableColumn } from './schema/publication'; +import { DexiePublicationFilesTable, PublicationFileTable, PublicationFileTableColumn } from './schema/publicationFile'; +import FDBFactory from 'fake-indexeddb/lib/FDBFactory'; +import FDBKeyRange from 'fake-indexeddb/lib/FDBKeyRange'; + +export const actionDatabase = new Dexie('action-database-v1', { + indexedDB: new FDBFactory, + IDBKeyRange: FDBKeyRange, // Mocking IDBKeyRange +}) as Dexie & { + action: DexieActionTable, + publication: DexiePublicationTable, + publicationFile: DexiePublicationFilesTable +}; + +actionDatabase.version(1).stores({ + action: ActionTableColumn, + publication: PublicationTableColumn, + publicationFile: PublicationFileTableColumn +}); diff --git a/src/app/infra/http/http.service.ts b/src/app/infra/http/http.service.ts index 0b9336bff..fee5e4a05 100644 --- a/src/app/infra/http/http.service.ts +++ b/src/app/infra/http/http.service.ts @@ -3,9 +3,9 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { ok, err, Result } from 'neverthrow'; import { HttpResult } from './type'; -import { BehaviorSubject, Observable } from 'rxjs'; -import { catchError, map } from 'rxjs/operators'; +import { BehaviorSubject } from 'rxjs'; import { IHttpOptions } from './adapter'; +import { TracingType } from 'src/app/services/monitoring/opentelemetry/tracer'; @Injectable({ providedIn: 'root' @@ -16,15 +16,15 @@ export class HttpService { constructor(private http: HttpClient) { } - async post(url: string, body: any): Promise, HttpErrorResponse>> { + private async handleRequest(fux: Function, tracing?: TracingType, url?: string, method?: string): Promise, HttpErrorResponse>> { + var response = await fux(tracing) as HttpResponse try { - const response = await this.http.post(url, body, { observe: 'response' }).toPromise(); const data = { data: response.body, status: response.status, headers: response.headers, url: response.url || url, - method: '', + method: method || '', } this.responseSubject.next(ok(data)) return ok(data); @@ -34,105 +34,45 @@ export class HttpService { } } - async get(url: string, options?: IHttpOptions): Promise, HttpErrorResponse>> { - try { - let httpParams = new HttpParams(); - if (options?.params) { - Object.keys(options.params).forEach(key => { - if(options.params[key]) { - httpParams = httpParams.append(key, options.params[key]); - } - - }); - } - - const httpOptions = { - params: httpParams, - headers: options?.headers as any || new HttpHeaders(), - responseType: options?.responseType || 'json' as any, - }; - - const response = await this.http.get(url, { ...httpOptions, observe: 'response', responseType: httpOptions.responseType }).toPromise(); - - const data = { - method: 'GET', - data: response.body, - status: response.status, - headers: response.headers, - url: response.url || url - } - - this.responseSubject.next(ok(data)) - return ok(data); - } catch (e) { - this.responseSubject.next(err(e)) - return err(e as HttpErrorResponse); - } + async post(url: string, body: any, tracing?: TracingType): Promise, HttpErrorResponse>> { + return await this.handleRequest(async () => await this.http.post(url, body, { observe: 'response' }).toPromise(), tracing, url, 'POST') } - async put(url: string, body: any): Promise, HttpErrorResponse>> { - try { - const response = await this.http.put(url, body, { observe: 'response' }).toPromise(); + async get(url: string, options?: IHttpOptions, tracing?: TracingType): Promise, HttpErrorResponse>> { - const data = { - data: response.body, - status: response.status, - headers: response.headers, - url: response.url || url, - method: '', - } + let httpParams = new HttpParams(); + if (options?.params) { + Object.keys(options.params).forEach(key => { + if(options.params[key]) { + httpParams = httpParams.append(key, options.params[key]); + } - this.responseSubject.next(ok(data)) - return ok(data); - } catch (e) { - this.responseSubject.next(err(e)) - return err(e as HttpErrorResponse); + }); } + + const httpOptions = { + params: httpParams, + headers: options?.headers as any || new HttpHeaders(), + responseType: options?.responseType || 'json' as any, + }; + return await this.handleRequest(async () => await this.http.get(url, { ...httpOptions, observe: 'response', responseType: httpOptions.responseType }).toPromise(), tracing, url, 'GET') } - async patch(url: string, body: any = {}): Promise, HttpErrorResponse>> { - try { - const response = await this.http.patch(url, body, { observe: 'response' }).toPromise(); - - const data = { - data: response.body, - status: response.status, - headers: response.headers, - url: response.url || url, - method: '', - } - - this.responseSubject.next(ok(data)) - return ok(data); - } catch (e) { - this.responseSubject.next(err(e)) - return err(e as HttpErrorResponse); - } + async put(url: string, body: any, tracing?: TracingType): Promise, HttpErrorResponse>> { + return await this.handleRequest(async () => await this.http.put(url, body, { observe: 'response' }).toPromise(), tracing, url, 'PUT') } - async delete(url: string, body = {}): Promise, HttpErrorResponse>> { + async patch(url: string, body: any = {}, tracing?: TracingType): Promise, HttpErrorResponse>> { + return await this.handleRequest(async () => await this.http.patch(url, body, { observe: 'response' }).toPromise(), tracing,url, 'PATCH'); + } + + async delete(url: string, body = {}, tracing?: TracingType): Promise, HttpErrorResponse>> { const options = { body: body, // Pass payload as the body of the request observe: 'response' as 'body' }; - try { - const response: any = await this.http.delete(url, options).toPromise(); - - const data = { - data: response?.body, - status: response?.status, - headers: response?.headers, - url: response?.url || url, - method: '', - } - - this.responseSubject.next(ok(data)) - return ok(data as any); - } catch (e) { - this.responseSubject.next(err(e)) - return err(e as HttpErrorResponse); - } + return await this.handleRequest(async () => await this.http.delete(url, options).toPromise(), tracing, url, 'DELETE'); } listen() { diff --git a/src/app/infra/http/type.ts b/src/app/infra/http/type.ts index cae486b71..51444fb3c 100644 --- a/src/app/infra/http/type.ts +++ b/src/app/infra/http/type.ts @@ -14,4 +14,11 @@ export interface HttpResult { method: string } -export type IHttPReturn = Promise, HttpErrorResponse>> \ No newline at end of file +export type IHttPReturn = Promise, HttpErrorResponse>> + + +export interface ApiResponse { + success: boolean, + message: string, + data: T +} diff --git a/src/app/infra/monitoring/interceptors/metter.interceptor.ts b/src/app/infra/monitoring/interceptors/metter.interceptor.ts index d5ac9e305..39c6e6b31 100644 --- a/src/app/infra/monitoring/interceptors/metter.interceptor.ts +++ b/src/app/infra/monitoring/interceptors/metter.interceptor.ts @@ -13,8 +13,6 @@ 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:') { diff --git a/src/app/infra/repository/dexie/dexie-repository.service.ts b/src/app/infra/repository/dexie/dexie-repository.service.ts index d9600f6c4..7928c57ff 100644 --- a/src/app/infra/repository/dexie/dexie-repository.service.ts +++ b/src/app/infra/repository/dexie/dexie-repository.service.ts @@ -4,9 +4,6 @@ import { ZodError, ZodObject, ZodSchema } from 'zod'; import { Logger } from 'src/app/services/logger/main/service'; import { IDexieRepository, ILocalModel, RepositoryResult } from '../adapter' import { IDBError, IDBErrorParams, IDexieError } from '../types'; - -// Define a type for the Result of repository operations - class DBError extends Error implements IDBError { zodError?: ZodError; parameters: T; diff --git a/src/app/models/entiry/agenda/eventToApproveDetails.ts b/src/app/models/entiry/agenda/eventToApproveDetails.ts index c03b2243d..bb2227eb9 100644 --- a/src/app/models/entiry/agenda/eventToApproveDetails.ts +++ b/src/app/models/entiry/agenda/eventToApproveDetails.ts @@ -160,7 +160,7 @@ const OwnerSchema = z.object({ wxUserId: z.number(), wxFullName: z.string(), wxeMail: z.string(), - userPhoto: z.string().nullable(), + userPhoto: z.string().nullable().optional(), }); diff --git a/src/app/module/actions/data/repository/action-local-repository.service.ts b/src/app/module/actions/data/repository/action-local-repository.service.ts new file mode 100644 index 000000000..fddb356a4 --- /dev/null +++ b/src/app/module/actions/data/repository/action-local-repository.service.ts @@ -0,0 +1,14 @@ +import { Injectable } from '@angular/core'; +import { IActionLocalRepository } from 'src/app/core/chat/repository/action/member-local-repository'; +import { ActionTable, ActionTableSchema } from 'src/app/infra/database/dexie/instance/action/schema/action'; +import { actionDatabase } from 'src/app/infra/database/dexie/instance/action/service'; +import { DexieRepository } from 'src/app/infra/repository/dexie/dexie-repository.service'; + +@Injectable({ + providedIn: 'root' +}) +export class ActionLocalRepositoryService extends DexieRepository implements IActionLocalRepository { + constructor() { + super(actionDatabase.action, ActionTableSchema, actionDatabase) + } +} diff --git a/src/app/module/actions/data/repository/action-remote-repository.service.ts b/src/app/module/actions/data/repository/action-remote-repository.service.ts new file mode 100644 index 000000000..f91f66146 --- /dev/null +++ b/src/app/module/actions/data/repository/action-remote-repository.service.ts @@ -0,0 +1,47 @@ +import { Injectable } from '@angular/core'; +import { ActionsCreateInput } from 'src/app/core/actions/use-case/actions-create-use-case.service'; +import { ActionGetAllOutPut } from 'src/app/core/actions/use-case/actions-get-all-use-case.service'; +import { PublicationGetDocumentByProcessIdOutPut } from 'src/app/core/actions/use-case/publication-get-documents-by-document-id.service'; +import { PublicationListByProcessIdOutPut } from 'src/app/core/actions/use-case/publication-list-by-process-id.service'; +import { HttpService } from 'src/app/infra/http/http.service'; +import { ApiResponse } from 'src/app/infra/http/type'; +import { environment } from 'src/environments/environment'; + + +@Injectable({ + providedIn: 'root' +}) +export class ActionRemoteRepositoryService { + + private baseUrl = `${environment.apiURLStage.slice(0, -1)}/PresidentialActions`; // Your base URL + + constructor( + private http: HttpService + ) { } + + async actionGetAll() { + return await this.http.get>(`${this.baseUrl}`); + } + + async create(input: ActionsCreateInput) { + return await this.http.post>(`${this.baseUrl}`, input); + } + + async postGetListByProcessId(processId: string) { + return await this.http.get>(`${this.baseUrl}/${processId}/Posts`); + } + + async postGetDocumentListByProcessId(documentId: number) { + var result = await this.http.get>(`${this.baseUrl}/Posts/${documentId}/file`); + + return result.map((e) => { + // Add a new attribute to each item + e.data.data = e.data.data.map((item) => ({ + ...item, + documentId, + })); + return e; + }); + } + +} diff --git a/src/app/module/actions/data/repository/publication-file-local-repository.service.ts b/src/app/module/actions/data/repository/publication-file-local-repository.service.ts new file mode 100644 index 000000000..9e280580f --- /dev/null +++ b/src/app/module/actions/data/repository/publication-file-local-repository.service.ts @@ -0,0 +1,14 @@ +import { Injectable } from '@angular/core'; +import { PublicationFileTable, PublicationFileTableSchema } from 'src/app/infra/database/dexie/instance/action/schema/publicationFile'; +import { actionDatabase } from 'src/app/infra/database/dexie/instance/action/service'; +import { DexieRepository } from 'src/app/infra/repository/dexie/dexie-repository.service'; + +@Injectable({ + providedIn: 'root' +}) +export class PublicationFileLocalRepositoryService extends DexieRepository { + + constructor() { + super(actionDatabase.publicationFile, PublicationFileTableSchema, actionDatabase) + } +} diff --git a/src/app/module/actions/data/repository/publication-file-remote-repository.service.ts b/src/app/module/actions/data/repository/publication-file-remote-repository.service.ts new file mode 100644 index 000000000..d6199f9de --- /dev/null +++ b/src/app/module/actions/data/repository/publication-file-remote-repository.service.ts @@ -0,0 +1,27 @@ +import { Injectable } from '@angular/core'; +import { PublicationFileGetByDocumentIdInput, PublicationFileGetByDocumentIdOutPut } from 'src/app/core/actions/use-case/publication-file-get-by-document-id.service'; +import { PublicationListByProcessIdOutPut } from 'src/app/core/actions/use-case/publication-list-by-process-id.service'; +import { ApiResponse } from 'src/app/infra/http/type'; +import { HttpService } from 'src/app/services/http.service'; +import { environment } from 'src/environments/environment'; + +@Injectable({ + providedIn: 'root' +}) +export class PublicationFileRemoteRepositoryService { + + private baseUrl = `${environment.apiURLStage.slice(0, -1)}/PresidentialActions`; // Your base URL + + constructor( + private http: HttpService + ) { } + + async listByProcessId(processId: string) { + console.log(this.baseUrl); + return await this.http.get>(`${this.baseUrl}/${processId}/Posts`); + } + + async FileListByDocumentId(input: PublicationFileGetByDocumentIdInput) { + return await this.http.get>(`${this.baseUrl}/Posts/${input.documentId}/file`); + } +} diff --git a/src/app/module/actions/data/repository/publication-file-repository.service.ts b/src/app/module/actions/data/repository/publication-file-repository.service.ts new file mode 100644 index 000000000..aaa917051 --- /dev/null +++ b/src/app/module/actions/data/repository/publication-file-repository.service.ts @@ -0,0 +1,9 @@ +import { Injectable } from '@angular/core'; + +@Injectable({ + providedIn: 'root' +}) +export class PublicationFileRepositoryService { + + constructor() { } +} diff --git a/src/app/module/actions/data/repository/publication-local-repository.service.ts b/src/app/module/actions/data/repository/publication-local-repository.service.ts new file mode 100644 index 000000000..fad486fa1 --- /dev/null +++ b/src/app/module/actions/data/repository/publication-local-repository.service.ts @@ -0,0 +1,15 @@ +import { Injectable } from '@angular/core'; +import { PublicationTable, PublicationTableSchema } from 'src/app/infra/database/dexie/instance/action/schema/publication'; +import { PublicationFileTable } from 'src/app/infra/database/dexie/instance/action/schema/publicationFile'; +import { actionDatabase } from 'src/app/infra/database/dexie/instance/action/service'; +import { DexieRepository } from 'src/app/infra/repository/dexie/dexie-repository.service'; + +@Injectable({ + providedIn: 'root' +}) +export class PublicationLocalRepositoryService extends DexieRepository { + + constructor() { + super(actionDatabase.publication, PublicationTableSchema, actionDatabase) + } +} diff --git a/src/app/module/actions/data/repository/publication-remote-repository.service.ts b/src/app/module/actions/data/repository/publication-remote-repository.service.ts new file mode 100644 index 000000000..acfbcc21d --- /dev/null +++ b/src/app/module/actions/data/repository/publication-remote-repository.service.ts @@ -0,0 +1,21 @@ +import { Injectable } from '@angular/core'; +import { PublicationListByProcessIdOutPut } from 'src/app/core/actions/use-case/publication-list-by-process-id.service'; +import { HttpService } from 'src/app/infra/http/http.service'; +import { ApiResponse } from 'src/app/infra/http/type'; +import { environment } from 'src/environments/environment'; + +@Injectable({ + providedIn: 'root' +}) +export class PublicationRemoteRepositoryService { + + private baseUrl = `${environment.apiURLStage.slice(0, -1)}/PresidentialActions`; // Your base URL + + constructor( + private http: HttpService + ) { } + + async listByProcessId(processId: number) { + return await this.http.get>(`${this.baseUrl}/${processId}/Posts`); + } +} diff --git a/src/app/module/agenda/data/async/change/shareCalendarChangeDetector.ts b/src/app/module/agenda/data/async/change/shareCalendarChangeDetector.ts index b2acf2f37..9a060fd43 100644 --- a/src/app/module/agenda/data/async/change/shareCalendarChangeDetector.ts +++ b/src/app/module/agenda/data/async/change/shareCalendarChangeDetector.ts @@ -1,4 +1,3 @@ -import { z } from "zod"; import { SharedCalendarListItemOutputDTO } from "../../dto/sharedCalendarOutputDTO"; type Changes = { diff --git a/src/app/module/agenda/data/dto/eventDTOOutput.ts b/src/app/module/agenda/data/dto/eventDTOOutput.ts index 39fdc5b39..f1335aa79 100644 --- a/src/app/module/agenda/data/dto/eventDTOOutput.ts +++ b/src/app/module/agenda/data/dto/eventDTOOutput.ts @@ -28,14 +28,14 @@ const OwnerSchema = z.object({ wxUserId: z.number(), wxFullName: z.string(), wxeMail: z.string(), - userPhoto: z.string().nullable(), + userPhoto: z.string().nullable().optional(), }); const OrganizerSchema = z.object({ wxUserId: z.number(), wxFullName: z.string(), wxeMail: z.string(), - userPhoto: z.string().nullable(), + userPhoto: z.string().nullable().optional(), }); const EventRecurrenceSchema = z.object({ diff --git a/src/app/module/agenda/data/dto/eventListDTOOutput.ts b/src/app/module/agenda/data/dto/eventListDTOOutput.ts index 7d995844e..967c5d64a 100644 --- a/src/app/module/agenda/data/dto/eventListDTOOutput.ts +++ b/src/app/module/agenda/data/dto/eventListDTOOutput.ts @@ -5,7 +5,7 @@ const OwnerSchema = z.object({ wxUserId: z.number(), wxFullName: z.string(), wxeMail: z.string(), - userPhoto: z.string().nullable(), + userPhoto: z.string().nullable().optional(), }); diff --git a/src/app/module/agenda/data/dto/eventToApproveListOutputDTO.ts b/src/app/module/agenda/data/dto/eventToApproveListOutputDTO.ts index 5669bf67d..32f876b70 100644 --- a/src/app/module/agenda/data/dto/eventToApproveListOutputDTO.ts +++ b/src/app/module/agenda/data/dto/eventToApproveListOutputDTO.ts @@ -5,7 +5,7 @@ const OwnerSchema = z.object({ wxUserId: z.number(), wxFullName: z.string(), wxeMail: z.string(), - userPhoto: z.string().nullable(), + userPhoto: z.string().nullable().optional(), }); diff --git a/src/app/module/chat/data/repository/member/member-list-remote-repository.service.ts b/src/app/module/chat/data/repository/member/member-list-remote-repository.service.ts index 6edb94545..b3f90e0fb 100644 --- a/src/app/module/chat/data/repository/member/member-list-remote-repository.service.ts +++ b/src/app/module/chat/data/repository/member/member-list-remote-repository.service.ts @@ -20,10 +20,9 @@ export class MemberListRemoteRepository implements IMemberRemoteRepository { @ValidateSchema(AddMemberToRoomInputDTOSchema) async addMemberToRoom(data: AddMemberToRoomInputDTO): DataSourceReturn { - return await this.httpService.post(`${this.baseUrl}/Room/${data.id}/Member`, { members:data.members }); + return await this.httpService.post(`${this.baseUrl}/Room/${data.id}/Member`, { members:data.members, userId: data.userId }); } - @ValidateSchema(UserRemoveListInputDTOSchema) async removeMemberFromRoom(data: UserRemoveListInputDTO): Promise> { return await this.httpService.delete(`${this.baseUrl}/Room/${data.id}/Member`, {} , {members:data.members}); diff --git a/src/app/module/chat/data/repository/room/room-remote-repository.service.ts b/src/app/module/chat/data/repository/room/room-remote-repository.service.ts index 329d6ab27..4a0979205 100644 --- a/src/app/module/chat/data/repository/room/room-remote-repository.service.ts +++ b/src/app/module/chat/data/repository/room/room-remote-repository.service.ts @@ -80,6 +80,7 @@ export class RoomRemoteDataSourceService implements IRoomRemoteRepository { const result = await this.socket.sendData({ method: 'AddRoomMember', data: { + userId: SessionStore.user.UserId, requestId: uuidv4(), roomId: data.id, members: data.members diff --git a/src/app/module/chat/domain/chat-service.service.ts b/src/app/module/chat/domain/chat-service.service.ts index 9699fa27e..014973fa1 100644 --- a/src/app/module/chat/domain/chat-service.service.ts +++ b/src/app/module/chat/domain/chat-service.service.ts @@ -126,7 +126,7 @@ export class ChatServiceService { }) this.MessageSocketRepositoryService.listenToUpdateMessages().pipe( - filter((message) => message.deviceId != getInstanceId()) + filter((message) => message?.deviceId != getInstanceId()) ).subscribe(async (message) => { if(message?.id) { this.SocketMessageUpdateUseCaseService.execute(message) @@ -135,7 +135,7 @@ export class ChatServiceService { this.MessageSocketRepositoryService.listenToMessages().pipe( map(message => message.data), - filter((message) => message.deviceId != getInstanceId()) + filter((message) => message?.deviceId != getInstanceId()) ).subscribe(async (message) => { if(message?.id) { this.SocketMessageCreateUseCaseService.execute(message) diff --git a/src/app/module/chat/domain/service/room-last-message.service.ts b/src/app/module/chat/domain/service/room-last-message.service.ts index 4fc4d7def..df3b24039 100644 --- a/src/app/module/chat/domain/service/room-last-message.service.ts +++ b/src/app/module/chat/domain/service/room-last-message.service.ts @@ -20,7 +20,7 @@ export class RoomLastMessageService { listenToIncomingMessage() { return this.MessageSocketRepositoryService.listenToMessages().pipe( map(message => message.data), - filter((message) => message.deviceId != getInstanceId()), + filter((message) => message?.deviceId != getInstanceId()), map(message => Object.assign(new MessageEntity(), message)) ).subscribe(async (message) => { this.roomLocalRepository.update(message.roomId, { diff --git a/src/app/module/notification/data/async/changes/notificationListChange.ts b/src/app/module/notification/data/async/changes/notificationListChange.ts index 503740c16..e7da309a4 100644 --- a/src/app/module/notification/data/async/changes/notificationListChange.ts +++ b/src/app/module/notification/data/async/changes/notificationListChange.ts @@ -1,4 +1,3 @@ -import { z } from "zod"; import { NotificationTable } from '../../infra/db/notification.db' type Changes = { diff --git a/src/app/pages/publications/publications.page.html b/src/app/pages/publications/publications.page.html index c6b1b08e9..0bf341612 100644 --- a/src/app/pages/publications/publications.page.html +++ b/src/app/pages/publications/publications.page.html @@ -48,22 +48,22 @@ *ngFor="let evento of publicationsEventFolderList"> + [class.item-active]="evento.processId == idSelected" + (click)="goToPublicationsList(evento.processId)">
- - - - + + + +
- -

{{evento.Description}}

+ +

{{evento.detail}}

- + - + diff --git a/src/app/pages/publications/publications.page.ts b/src/app/pages/publications/publications.page.ts index e60d73235..123e963b1 100644 --- a/src/app/pages/publications/publications.page.ts +++ b/src/app/pages/publications/publications.page.ts @@ -1,11 +1,9 @@ import { Component, OnInit } from '@angular/core'; import { Router, NavigationEnd } from '@angular/router'; -import { AlertController, ModalController, NavParams } from '@ionic/angular'; -import { PublicationFolder } from 'src/app/models/publicationfolder'; +import { ModalController } from '@ionic/angular'; import { PublicationsService } from 'src/app/services/publications.service'; import { NewActionPage } from './new-action/new-action.page'; import { ViewPublicationsPage } from './view-publications/view-publications.page'; - import { AnimationController } from '@ionic/angular'; import { Publication } from 'src/app/models/publication'; import { ActionsOptionsPage } from 'src/app/shared/popover/actions-options/actions-options.page'; @@ -15,15 +13,10 @@ import { ThemeService } from 'src/app/services/theme.service' import { PermissionService } from 'src/app/services/permission.service'; import { Storage } from '@ionic/storage'; import { NewPublicationPage } from './new-publication/new-publication.page'; -import { ChunkService } from 'src/app/services/stream/chunk.service' -import { StreamService } from 'src/app/services/stream/stream.service' -import { HttpClient, HttpHeaders, HttpEventType } from '@angular/common/http'; import { PublicationFolderService } from 'src/app/store/publication-folder.service'; - -// import { ActionModel } from 'src/app/models/beast-orm'; - - - +import { ActionsGetAllUseCaseService } from 'src/app/core/actions/use-case/actions-get-all-use-case.service'; +import { ActionRemoteRepositoryService } from 'src/app/module/actions/data/repository/action-remote-repository.service'; +import { ActionEntity, IAction } from 'src/app/core/actions/entity/action'; @Component({ selector: 'app-publications', templateUrl: './publications.page.html', @@ -31,12 +24,12 @@ import { PublicationFolderService } from 'src/app/store/publication-folder.servi }) export class PublicationsPage implements OnInit { showLoader: boolean = false - publicationFolder: PublicationFolder; + publicationFolder: IAction; publication: Publication; - publicationsEventFolderList: PublicationFolder[] = []; - actionsListStorage: PublicationFolder[] = new Array(); - publicationsTravelFolderList: PublicationFolder[] = []; + publicationsEventFolderList: IAction[] = []; + actionsListStorage: IAction[] = new Array(); + publicationsTravelFolderList: IAction[] = []; theDate: any; theEndDate: any; @@ -75,12 +68,9 @@ export class PublicationsPage implements OnInit { public ThemeService: ThemeService, public p: PermissionService, private storage: Storage, - private ChunkService: ChunkService, - private StreamService:StreamService, - private http: HttpClient, public publicationFolderService: PublicationFolderService, - - + private ActionsGetAllUseCaseService: ActionsGetAllUseCaseService, + private actionRemoteRepository: ActionRemoteRepositoryService ) { this.months = ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"]; this.days = ["Domingo", "Segunda-feira", "Terça-feira", "Quarta-feira", "Quinta-feira", "Sexta-feira", "Sábado"]; @@ -93,15 +83,11 @@ export class PublicationsPage implements OnInit { window['updateAction'] = () => { this.getActions() } - } - checkQueryParameter() { - // var urlSearchParams = new URLSearchParams(window.location.search); - // var folderId = urlSearchParams.get('folderId'); if (this.publicationFolderService.gotoAction) { const folderId = this.publicationFolderService.gotoAction this.goToPublicationsList(folderId) @@ -118,9 +104,8 @@ export class PublicationsPage implements OnInit { this.router.events.forEach((event) => { if (event instanceof NavigationEnd && event.url == pathname) { - console.log('=================', this.publicationFolderService.gotoAction) this.getActions(); - // this.checkQueryParameter() + this.ActionsGetAllUseCaseService.execute(); } this.intent = window['sharedContent'] }); @@ -187,16 +172,13 @@ export class PublicationsPage implements OnInit { getActions = () => { this.showLoader = true - this.publications.GetPublicationFolderList().subscribe(async res => { + this.actionRemoteRepository.actionGetAll().then(async res => { this.showLoader = false; - const folders: PublicationFolder[] = this.getPublicationFolderMap(res) - - this.publicationsEventFolderList = folders.filter((e)=>e.ActionType == 'Evento') - - await this.storage.set('actionsEvents', this.publicationsEventFolderList); - - this.showLoader = false; - + if(res.isOk()) { + const folders: IAction[] = res.value.data.data; + await this.storage.set('actionsEvents', this.publicationsEventFolderList); + this.publicationsEventFolderList = folders; + } }, (error) => { this.showLoader = false; this.getFromDB() @@ -204,89 +186,23 @@ export class PublicationsPage implements OnInit { } - getPublicationFolderMap(events: any):PublicationFolder[] { - return events.map((data) : PublicationFolder => { - return { - ProcessId: data.ProcessId, - Description: data.Description, - Detail: data.Detail, - DateBegin: data.DateBegin, - DateEnd: data.DateEnd, - ActionType: data.ActionType, - } - }); - } async getFromDB() { - - //const folders: PublicationFolder[] = await ActionModel.all() - //this.showLoader = false; - // this.publicationsEventFolderList = folders - - this.storage.get('actionsEvents').then((events = []) => { if(Array.isArray(events)) { - const folders: PublicationFolder[] = this.getPublicationFolderMap(events) - this.showLoader = false; - this.publicationsEventFolderList = folders + this.publicationsEventFolderList = events } }); this.storage.get('actionsViagens').then((viagens = []) => { if(Array.isArray(viagens)) { - const folders: PublicationFolder[] = this.getPublicationFolderMap(viagens) - - this.publicationsTravelFolderList = folders + this.publicationsTravelFolderList = viagens this.showLoader = false; } - }); - - } - - async onFileSelect(event: any) { - - const file:File = event.target.files[0]; - - - const chunkSize = 1024 * 1024; // Adjust the chunk size as needed - const chunks = []; - let offset = 0; - let i = 0; - let j = 0; - - function count () { - j++ - return j - } - - while (offset < file.size) { - const chunk = file.slice(offset, offset + chunkSize); - const reader = new FileReader(); - - reader.onload = async () => { - - const headers = new HttpHeaders() - .append('X-File-Name', "fileName") - .append('X-File-Extension', "mp4") - .append('X-File-Content-Length', i.toString()) - .append('X-File-Index', count().toString()); - - const a = new Uint8Array(reader.result as ArrayBuffer) - await this.http.post('http://localhost:3001/upload', a.buffer, { headers, responseType: 'blob' }).toPromise(); - - - }; - reader.readAsArrayBuffer(chunk); - offset += chunkSize; - i++; - } - - - } diff --git a/src/app/pages/publications/view-publications/view-publications.page.html b/src/app/pages/publications/view-publications/view-publications.page.html index a7ea49c36..3b438bc2d 100644 --- a/src/app/pages/publications/view-publications/view-publications.page.html +++ b/src/app/pages/publications/view-publications/view-publications.page.html @@ -51,43 +51,6 @@ > - - - - - - - - - -
diff --git a/src/app/pages/publications/view-publications/view-publications.page.ts b/src/app/pages/publications/view-publications/view-publications.page.ts index a1d76bf95..5bf638483 100644 --- a/src/app/pages/publications/view-publications/view-publications.page.ts +++ b/src/app/pages/publications/view-publications/view-publications.page.ts @@ -11,14 +11,10 @@ import { BackgroundService } from 'src/app/services/background.service'; import { ThemeService } from 'src/app/services/theme.service' import { ToastService } from 'src/app/services/toast.service'; import { PermissionService } from 'src/app/services/permission.service'; -import { HttpErrorHandle } from 'src/app/services/http-error-handle.service'; import { Storage } from '@ionic/storage'; import { PublicationFolderService } from 'src/app/store/publication-folder.service'; -// import { CapacitorVideoPlayer } from 'capacitor-video-player'; import { checkFileTypeService } from 'src/app/services/checkFileType.service'; -import { PublicationVideoManagerService } from "src/app/services/publication/publication-video-manager.service" import { StopvideoService } from "src/app/services/stopvideo.service" -import { Result } from 'neverthrow'; import { App } from '@capacitor/app'; import { ActiveTabService } from 'src/app/services/active-tab.service'; import { PublicationHolderService } from 'src/app/services/publication/publication-holder.service' @@ -29,7 +25,7 @@ import { PublicationHolderService } from 'src/app/services/publication/publicati styleUrls: ['./view-publications.page.scss'], }) export class ViewPublicationsPage implements OnInit { - showLoader = true; + showLoader = false; loading: any; @@ -80,26 +76,13 @@ export class ViewPublicationsPage implements OnInit { public activeTabService: ActiveTabService, public PublicationHolderService: PublicationHolderService) { - - /* this.publicationVideoManagerService.setContainer(this.VideoManager.nativeElement) */ - - - setTimeout(() => { - - console.log(this.VideoManager.nativeElement) - }, 2000) - this.createPublicationList() this.getFromDB(); - this.activatedRoute.paramMap.subscribe(params => { - if (params["params"]) { this.folderId = params["params"].folderId; - // } - window['app-view-publications-page-doRefresh'] = this.doRefresh }); } @@ -111,29 +94,12 @@ export class ViewPublicationsPage implements OnInit { } this.createPublicationList() - this.getFromDB(); - //this.testForkJoin() this.getPublicationDetail(); - this.getPublicationsIds(); - /* setTimeout(() => { - this.getPublications(); - }, 1000); */ - this.backgroundservice.registerBackService('Online', () => { this.getPublicationDetail(); - //this.testForkJoin() - }) - // console.log(this.publicationFolderService.publicationList[this.folderId]) - - setTimeout(()=> { - - // this.doRefresh({}) - - }, 1500) - } @@ -153,7 +119,6 @@ export class ViewPublicationsPage implements OnInit { video.pause(); }) - this.videoElements.forEach(videoElement => { // You can access the native HTML video element using videoElement.nativeElement const video: HTMLVideoElement = videoElement.nativeElement; @@ -174,12 +139,10 @@ export class ViewPublicationsPage implements OnInit { } this.createPublicationList() - this.getFromDB(); } createPublicationList(folderId = this.folderId) { - console.log('create') if (!this.publicationFolderService.publicationList[folderId]) { this.publicationFolderService.publicationList[folderId] = [] } @@ -192,7 +155,6 @@ export class ViewPublicationsPage implements OnInit { //setTimeout(() => { //this.testForkJoin() this.getPublicationDetail(); - this.getPublicationsIds(); try { event?.target?.complete(); } catch (error) { } @@ -215,10 +177,12 @@ export class ViewPublicationsPage implements OnInit { } getPublicationDetail() { + this.showLoader = true; const folderId = this.folderId this.publications.GetPresidentialAction(folderId).subscribe(res => { this.publicationFolderService.FolderDetails[folderId] = res this.storage.set(folderId + "name", res) + this.showLoader = false; }, (error) => { this.showLoader = false; // this.httpErroHandle.httpStatusHandle(error) @@ -230,26 +194,6 @@ export class ViewPublicationsPage implements OnInit { this.publicationFolderService.getFromDB(folderId) } - async getPublicationsIds() { - - this.showLoader = true; - const folderId = this.folderId - - await this.publicationFolderService.getPublicationsIds(folderId) - - this.showLoader = false; - - } - - publicationIsPresent(publicationId, folderId) { - return this.publicationFolderService.publicationList[folderId].find(e => e.DocumentId == publicationId) - } - publicationFind(publicationId, folderId) { - return this.publicationFolderService.publicationList[folderId].find(e => e.DocumentId == publicationId) - } - publicationFindIndex(publicationId, folderId) { - return this.publicationFolderService.publicationList[folderId].findIndex(e => e.DocumentId == publicationId) - } async AddPublication(publicationType: any, folderId: any) { @@ -307,10 +251,6 @@ export class ViewPublicationsPage implements OnInit { // backdropDismiss: false }); - modal.onDidDismiss().then(() => { - this.getPublicationsIds(); - }); - await modal.present(); } diff --git a/src/app/shared/publication/new-action/new-action.page.ts b/src/app/shared/publication/new-action/new-action.page.ts index 0e5e52b5e..72b0cea88 100644 --- a/src/app/shared/publication/new-action/new-action.page.ts +++ b/src/app/shared/publication/new-action/new-action.page.ts @@ -1,12 +1,12 @@ import { Component, EventEmitter, OnInit, Output } from '@angular/core'; import { FormControl, FormGroup, Validators } from '@angular/forms'; -import * as moment from 'moment'; import { PublicationFolder } from 'src/app/models/publicationfolder'; -import { PublicationsService } from 'src/app/services/publications.service'; import { ToastService } from 'src/app/services/toast.service'; import { HttpErrorHandle } from 'src/app/services/http-error-handle.service'; import { NgxMatDateFormats } from '@angular-material-components/datetime-picker'; import { NGX_MAT_DATE_FORMATS } from '@angular-material-components/datetime-picker'; +import { ActionRemoteRepositoryService } from 'src/app/module/actions/data/repository/action-remote-repository.service'; +import { SessionStore } from 'src/app/store/session.service'; const CUSTOM_DATE_FORMATS: NgxMatDateFormats = { parse: { @@ -53,13 +53,12 @@ export class NewActionPage implements OnInit { @Output() getActions= new EventEmitter(); constructor( - private publication: PublicationsService, private toastService: ToastService, private httpErrorHandle: HttpErrorHandle, + private actionRemoteRepository: ActionRemoteRepositoryService ) { this.folder = new PublicationFolder(); - this.setStartDate() this.setEndDate() } @@ -88,10 +87,6 @@ export class NewActionPage implements OnInit { } } - /* get dateValid() { - return new Date(this.folder.DateBegin).getTime() < new Date(this.folder.DateBegin).getTime() ? 'ok': null - } */ - runValidation() { this.validateFrom = true; console.log(this.folder.DateBegin) @@ -125,30 +120,28 @@ export class NewActionPage implements OnInit { if(this.Form.invalid) return false - this.folder = { - ProcessId: null, - Description: this.folder.Description, - Detail: this.folder.Detail, - DateBegin: this.folder.DateBegin, - DateEnd: this.folder.DateEnd, - ActionType: this.segment, - } - - const loader = this.toastService.loading() - try { - await this.publication.CreatePublicationFolder(this.folder).toPromise() + var result = await this.actionRemoteRepository.create({ + userId: SessionStore.user.UserId, + description: this.folder.Description, + detail: this.folder.Detail, + location: "string", + dateBegin: this.folder.DateBegin, + dateEnd: this.folder.DateEnd, + actionType: this.segment, + }); + + if(result.isOk()) { this.close(); this.httpErrorHandle.httpsSucessMessagge('Acção criada') - this.getActions.emit() - } catch (error) { - this.httpErrorHandle.httpStatusHandle(error) - } finally { - loader.remove() + } else { + this.httpErrorHandle.httpStatusHandle(result.error) } + loader.remove() + } close() { diff --git a/src/app/shared/publication/upload/publication-from-mv.service.ts b/src/app/shared/publication/upload/publication-from-mv.service.ts index 4158ddabc..f821a3538 100644 --- a/src/app/shared/publication/upload/publication-from-mv.service.ts +++ b/src/app/shared/publication/upload/publication-from-mv.service.ts @@ -142,11 +142,9 @@ export class PublicationFromMvService { window['publicationEdit']() } - this.publicationFolderService.getPublicationsIds(this.folderId) + // this.publicationFolderService.getPublicationsIds(this.folderId) window['upload-header-set-remove'](this.id); - // this.goBack(); - } catch (error) { this.httpErroHandle.httpStatusHandle(error) diff --git a/src/app/shared/publication/view-publications/publication-detail/publication-detail.module.ts b/src/app/shared/publication/view-publications/publication-detail/publication-detail.module.ts index 747c44f55..b64342618 100644 --- a/src/app/shared/publication/view-publications/publication-detail/publication-detail.module.ts +++ b/src/app/shared/publication/view-publications/publication-detail/publication-detail.module.ts @@ -7,13 +7,15 @@ import { IonicModule } from '@ionic/angular'; import { PublicationDetailPageRoutingModule } from './publication-detail-routing.module'; import { PublicationDetailPage } from './publication-detail.page'; +import { SwiperPageModule } from 'src/app/shared/swiper/swiper.module'; @NgModule({ imports: [ CommonModule, FormsModule, IonicModule, - PublicationDetailPageRoutingModule + PublicationDetailPageRoutingModule, + SwiperPageModule ], exports: [PublicationDetailPage], declarations: [PublicationDetailPage], diff --git a/src/app/shared/publication/view-publications/publication-detail/publication-detail.page copy.html b/src/app/shared/publication/view-publications/publication-detail/publication-detail.page copy.html new file mode 100644 index 000000000..4fa471c30 --- /dev/null +++ b/src/app/shared/publication/view-publications/publication-detail/publication-detail.page copy.html @@ -0,0 +1,92 @@ + +
+
+ + + +
+
+ {{publication.Title}} +

{{publication.DatePublication | date: 'dd-MM-yyyy | h:mm'}}

+
+
+ +
+
+ +
+
+ +

+
+
+ +
+ + +
+
+ + + + + +
+ + + +
+ sem image + + + +
+ sem contiudo +
+
+
+
+ + +
+
{{publication.Message}}
+
+
+
+
+
+
+ image +
+
+

+

+
+
+ +
+
+
+ + + + + + + + + + + diff --git a/src/app/shared/publication/view-publications/publication-detail/publication-detail.page.html b/src/app/shared/publication/view-publications/publication-detail/publication-detail.page.html index 4fa471c30..36a4d182a 100644 --- a/src/app/shared/publication/view-publications/publication-detail/publication-detail.page.html +++ b/src/app/shared/publication/view-publications/publication-detail/publication-detail.page.html @@ -1,17 +1,16 @@ -
+
- {{publication.Title}} -

{{publication.DatePublication | date: 'dd-MM-yyyy | h:mm'}}

+ {{publication.title}} +

{{publication.datePublication | date: 'dd-MM-yyyy | h:mm'}}

- -
+
@@ -25,54 +24,25 @@
-
- - - - - +
- - - -
- sem image - +
+ +
-
- sem contiudo -
-
-
-
- -
-
{{publication.Message}}
+
{{publication.message}}
-
-
-
- image -
-
-

-

-
-
- -
diff --git a/src/app/shared/publication/view-publications/publication-detail/publication-detail.page.ts b/src/app/shared/publication/view-publications/publication-detail/publication-detail.page.ts index 6349a16bb..25f5ab5ce 100644 --- a/src/app/shared/publication/view-publications/publication-detail/publication-detail.page.ts +++ b/src/app/shared/publication/view-publications/publication-detail/publication-detail.page.ts @@ -1,6 +1,5 @@ import { Component, OnInit, Input, Output, EventEmitter, ViewChild, ElementRef } from '@angular/core'; import { ModalController } from '@ionic/angular'; -import { Publication } from 'src/app/models/publication'; import { NewPublicationPage } from 'src/app/shared/publication/new-publication/new-publication.page'; import { PublicationsService } from 'src/app/services/publications.service'; import { ToastService } from 'src/app/services/toast.service'; @@ -12,6 +11,8 @@ import { PublicationFolderService } from 'src/app/store/publication-folder.servi import { PublicationPipe } from 'src/app/pipes/publication.pipe'; import { checkFileTypeService } from 'src/app/services/checkFileType.service'; import { PublicationHolderService } from 'src/app/services/publication/publication-holder.service' +import { IPublication } from 'src/app/core/actions/entity/publicationEntity'; +import { PublicationLocalRepositoryService } from 'src/app/module/actions/data/repository/publication-local-repository.service'; @Component({ selector: 'app-publication-detail-shared', @@ -21,7 +22,7 @@ import { PublicationHolderService } from 'src/app/services/publication/publicati export class PublicationDetailPage implements OnInit { showLoader: boolean; /* folderId: string; */ - publication: Publication; + publication: IPublication; @Input() publicationId: string; @Input() folderId: string; @Output() addNewPublication = new EventEmitter(); @@ -41,23 +42,9 @@ export class PublicationDetailPage implements OnInit { private httpErrorHandle: HttpErrorHandle, public publicationFolderService: PublicationFolderService, public checkFileType: checkFileTypeService, - public PublicationHolderService: PublicationHolderService - ) { - - /* this.folderId = this.navParams.get('folderIdId'); */ - this.publication = { - DateIndex: null, - DocumentId: null, - ProcessId:'', - Title:'', - Message: '', - /* image: null, */ - DatePublication: null, - Files: [], - OriginalFileName: '', - FileExtension: '', - }; - } + public PublicationHolderService: PublicationHolderService, + private publicationLocal: PublicationLocalRepositoryService, + ) {} @ViewChild('ScrollContainer', { static: true }) ScrollContainer: ElementRef; @@ -114,41 +101,47 @@ export class PublicationDetailPage implements OnInit { }, 2000); } - getPublicationDetail() { + async getPublicationDetail() { const folderId = this.folderId + + const result = await this.publicationLocal.findOne({ documentId: parseInt(this.publicationId) }) + if(result.isOk() && result.value) { + this.publication = result.value; + } + const localPublication = this.publicationFolderService.getLocalPublication(folderId, this.publicationId); - if(localPublication?.ProcessId) { - console.log('console.log local storage') - this.publication = localPublication - console.log('Local publication',this.publication) + // if(localPublication?.ProcessId) { - } else { + // this.publication = localPublication + // console.log('Local publication',this.publication) - console.log('API res') + // } else { - this.showLoader = true; - this.publications.GetPublicationWithArrayOfFilesById(this.publicationId).subscribe(res => { + // this.publications.GetPublications(this.publicationId); - this.publication = this.publicationPipe.itemList(res) + // this.showLoader = true; + // this.publications.GetPublicationWithArrayOfFilesById(this.publicationId).subscribe(res => { - console.log('API pub', this.publication) - this.showLoader = false; - }, (error) => { - this.showLoader = false; + // this.publication = this.publicationPipe.itemList(res) + + // console.log('API pub', this.publication) + // this.showLoader = false; + // }, (error) => { + // this.showLoader = false; - console.log(this.publication) - if(error.status == 404) { - this.publicationFolderService.deletePost(this.folderId, this.publicationId) - } + // console.log(this.publication) + // if(error.status == 404) { + // this.publicationFolderService.deletePost(this.folderId, this.publicationId) + // } - this.goBack(); - this.httpErrorHandle.httpStatusHandle(error) - }); - } + // this.goBack(); + // this.httpErrorHandle.httpStatusHandle(error) + // }); + // } } diff --git a/src/app/shared/publication/view-publications/show-more/show-more.page.ts b/src/app/shared/publication/view-publications/show-more/show-more.page.ts index de8b10272..8f9f17715 100644 --- a/src/app/shared/publication/view-publications/show-more/show-more.page.ts +++ b/src/app/shared/publication/view-publications/show-more/show-more.page.ts @@ -20,7 +20,7 @@ export class ShowMorePage implements OnInit { } run() { - let split = this.text.split(/\r?\n|\r|\n/g) + let split = (this.text || "").split(/\r?\n|\r|\n/g) let text = split[0] this.shortText = text.slice(0, 100) diff --git a/src/app/shared/publication/view-publications/view-publications.page.html b/src/app/shared/publication/view-publications/view-publications.page.html index 2fcc3597e..7cae9a018 100644 --- a/src/app/shared/publication/view-publications/view-publications.page.html +++ b/src/app/shared/publication/view-publications/view-publications.page.html @@ -5,9 +5,7 @@
{{publicationFolderService.FolderDetails[folderId].Description}}
-
-