diff --git a/api/net/Areas/Services/Controllers/ReportInstanceController.cs b/api/net/Areas/Services/Controllers/ReportInstanceController.cs index 863835e3d3..1ef2def7cd 100644 --- a/api/net/Areas/Services/Controllers/ReportInstanceController.cs +++ b/api/net/Areas/Services/Controllers/ReportInstanceController.cs @@ -115,7 +115,10 @@ public async Task UpdateAsync(ReportInstanceModel model, bool upd if (ownerId.HasValue) { var user = _userService.FindById(ownerId.Value) ?? throw new NotAuthorizedException(); - await _kafkaMessenger.SendMessageAsync(_kafkaHubOptions.HubTopic, new KafkaHubMessage(HubEvent.SendUser, user.Username, new KafkaInvocationMessage(MessageTarget.ReportStatus, new[] { new ReportMessageModel(result) }))); + await _kafkaMessenger.SendMessageAsync( + _kafkaHubOptions.HubTopic, + new KafkaHubMessage(HubEvent.SendUser, user.Username, new KafkaInvocationMessage(MessageTarget.ReportStatus, new[] { new ReportMessageModel(result) })) + ); } return new JsonResult(new ReportInstanceModel(result, _serializerOptions)); diff --git a/api/net/Areas/Subscriber/Controllers/ReportController.cs b/api/net/Areas/Subscriber/Controllers/ReportController.cs index cbd9186cc3..d5195e7ccb 100644 --- a/api/net/Areas/Subscriber/Controllers/ReportController.cs +++ b/api/net/Areas/Subscriber/Controllers/ReportController.cs @@ -47,6 +47,7 @@ public class ReportController : ControllerBase private readonly IKafkaMessenger _kafkaProducer; private readonly KafkaOptions _kafkaOptions; private readonly KafkaHubConfig _kafkaHubOptions; + private readonly IKafkaMessenger _kafkaMessenger; private readonly IImpersonationHelper _impersonate; private readonly JsonSerializerOptions _serializerOptions; private readonly ILogger _logger; @@ -66,6 +67,7 @@ public class ReportController : ControllerBase /// /// /// + /// /// /// /// @@ -81,6 +83,7 @@ public ReportController( IKafkaMessenger kafkaProducer, IOptions kafkaOptions, IOptions kafkaHubOptions, + IKafkaMessenger kafkaMessenger, IImpersonationHelper impersonateHelper, IOptions serializerOptions, ILogger logger, @@ -96,6 +99,7 @@ IChesService ches _kafkaProducer = kafkaProducer; _kafkaOptions = kafkaOptions.Value; _kafkaHubOptions = kafkaHubOptions.Value; + _kafkaMessenger = kafkaMessenger; _impersonate = impersonateHelper; _serializerOptions = serializerOptions.Value; _logger = logger; @@ -445,16 +449,31 @@ public async Task AddContentToReportAsync(int id, [FromBody] IEnu !report.SubscribersManyToMany.Any(s => s.IsSubscribed && s.UserId == user.Id) && // User is not subscribed to the report !report.IsPublic) throw new NotAuthorizedException("Not authorized to review this report"); // Report is not public - var result = await _reportService.AddContentToReportAsync(id, user.Id, content.Select((c) => (Entities.ReportInstanceContent)c)) ?? throw new NoContentException("Report does not exist"); + var addContent = content.Select((c) => (Entities.ReportInstanceContent)c); + if (addContent.Any()) + { + var result = await _reportService.AddContentToReportAsync(id, user.Id, addContent) ?? throw new NoContentException("Report does not exist"); - var instances = _reportService.GetLatestInstances(id, user.Id); - var currentInstance = instances.FirstOrDefault() ?? throw new InvalidOperationException("Unable to add content to a report without an instance"); - currentInstance.ContentManyToMany.Clear(); - currentInstance.ContentManyToMany.AddRange(_reportInstanceService.GetContentForInstance(currentInstance.Id)); - result.Instances.Clear(); - result.Instances.AddRange(instances); + var instances = _reportService.GetLatestInstances(id, user.Id); + var currentInstance = instances.FirstOrDefault() ?? throw new InvalidOperationException("Unable to add content to a report without an instance"); + currentInstance.ContentManyToMany.Clear(); + currentInstance.ContentManyToMany.AddRange(_reportInstanceService.GetContentForInstance(currentInstance.Id)); + result.Instances.Clear(); + result.Instances.AddRange(instances); - return new JsonResult(new ReportModel(result, _serializerOptions)); + var ownerId = result.OwnerId ?? currentInstance.OwnerId; + if (ownerId.HasValue) + { + user = _userService.FindById(ownerId.Value) ?? throw new NotAuthorizedException(); + await _kafkaMessenger.SendMessageAsync( + _kafkaHubOptions.HubTopic, + new KafkaHubMessage(HubEvent.SendUser, user.Username, new KafkaInvocationMessage(MessageTarget.ReportStatus, new[] { new ReportMessageModel(currentInstance) })) + ); + } + return new JsonResult(new ReportModel(result, _serializerOptions)); + } + + return new JsonResult(new ReportModel(report, _serializerOptions)); } /// diff --git a/app/editor/.yarn/cache/@types-quill-npm-1.3.10-4ddf84ba7e-e629157d11.zip b/app/editor/.yarn/cache/@types-quill-npm-1.3.10-4ddf84ba7e-e629157d11.zip deleted file mode 100644 index d7622f110e..0000000000 Binary files a/app/editor/.yarn/cache/@types-quill-npm-1.3.10-4ddf84ba7e-e629157d11.zip and /dev/null differ diff --git a/app/editor/.yarn/cache/clone-npm-2.1.2-1d491c6629-aaf106e9bc.zip b/app/editor/.yarn/cache/clone-npm-2.1.2-1d491c6629-aaf106e9bc.zip deleted file mode 100644 index 6ae29b32e5..0000000000 Binary files a/app/editor/.yarn/cache/clone-npm-2.1.2-1d491c6629-aaf106e9bc.zip and /dev/null differ diff --git a/app/editor/.yarn/cache/deep-equal-npm-1.1.2-3af5068c14-2d50f27fff.zip b/app/editor/.yarn/cache/deep-equal-npm-1.1.2-3af5068c14-2d50f27fff.zip deleted file mode 100644 index d33272c1c8..0000000000 Binary files a/app/editor/.yarn/cache/deep-equal-npm-1.1.2-3af5068c14-2d50f27fff.zip and /dev/null differ diff --git a/app/editor/.yarn/cache/eventemitter3-npm-2.0.3-71d4ac3a65-dfbf4a0714.zip b/app/editor/.yarn/cache/eventemitter3-npm-2.0.3-71d4ac3a65-dfbf4a0714.zip deleted file mode 100644 index 2cceee3509..0000000000 Binary files a/app/editor/.yarn/cache/eventemitter3-npm-2.0.3-71d4ac3a65-dfbf4a0714.zip and /dev/null differ diff --git a/app/editor/.yarn/cache/extend-npm-3.0.2-e1ca07ac54-a50a8309ca.zip b/app/editor/.yarn/cache/extend-npm-3.0.2-e1ca07ac54-a50a8309ca.zip deleted file mode 100644 index a33fb285f4..0000000000 Binary files a/app/editor/.yarn/cache/extend-npm-3.0.2-e1ca07ac54-a50a8309ca.zip and /dev/null differ diff --git a/app/editor/.yarn/cache/fast-diff-npm-1.1.2-907d4b29ef-2ef726603e.zip b/app/editor/.yarn/cache/fast-diff-npm-1.1.2-907d4b29ef-2ef726603e.zip deleted file mode 100644 index 6fafb684f7..0000000000 Binary files a/app/editor/.yarn/cache/fast-diff-npm-1.1.2-907d4b29ef-2ef726603e.zip and /dev/null differ diff --git a/app/editor/.yarn/cache/is-arguments-npm-1.1.1-eff4f6d4d7-7f02700ec2.zip b/app/editor/.yarn/cache/is-arguments-npm-1.1.1-eff4f6d4d7-7f02700ec2.zip deleted file mode 100644 index 9b956d8699..0000000000 Binary files a/app/editor/.yarn/cache/is-arguments-npm-1.1.1-eff4f6d4d7-7f02700ec2.zip and /dev/null differ diff --git a/app/editor/.yarn/cache/object-is-npm-1.1.6-bfafd361ee-3ea2275996.zip b/app/editor/.yarn/cache/object-is-npm-1.1.6-bfafd361ee-3ea2275996.zip deleted file mode 100644 index ff83b1ee40..0000000000 Binary files a/app/editor/.yarn/cache/object-is-npm-1.1.6-bfafd361ee-3ea2275996.zip and /dev/null differ diff --git a/app/editor/.yarn/cache/parchment-npm-1.1.4-a3bac35728-4799756742.zip b/app/editor/.yarn/cache/parchment-npm-1.1.4-a3bac35728-4799756742.zip deleted file mode 100644 index dea30b0bd9..0000000000 Binary files a/app/editor/.yarn/cache/parchment-npm-1.1.4-a3bac35728-4799756742.zip and /dev/null differ diff --git a/app/editor/.yarn/cache/quill-delta-npm-3.6.3-3ae240a64d-e62ed33983.zip b/app/editor/.yarn/cache/quill-delta-npm-3.6.3-3ae240a64d-e62ed33983.zip deleted file mode 100644 index 13ae0bfabf..0000000000 Binary files a/app/editor/.yarn/cache/quill-delta-npm-3.6.3-3ae240a64d-e62ed33983.zip and /dev/null differ diff --git a/app/editor/.yarn/cache/quill-npm-1.3.7-c79f7446fc-db3e265a84.zip b/app/editor/.yarn/cache/quill-npm-1.3.7-c79f7446fc-db3e265a84.zip deleted file mode 100644 index 9c20b754ee..0000000000 Binary files a/app/editor/.yarn/cache/quill-npm-1.3.7-c79f7446fc-db3e265a84.zip and /dev/null differ diff --git a/app/editor/.yarn/cache/react-quill-new-npm-3.3.2-2c14f30b2b-7fccfabb02.zip b/app/editor/.yarn/cache/react-quill-new-npm-3.3.2-2c14f30b2b-7fccfabb02.zip new file mode 100644 index 0000000000..9b5650debd Binary files /dev/null and b/app/editor/.yarn/cache/react-quill-new-npm-3.3.2-2c14f30b2b-7fccfabb02.zip differ diff --git a/app/editor/.yarn/cache/react-quill-npm-2.0.0-f2d141fe1d-568e28656a.zip b/app/editor/.yarn/cache/react-quill-npm-2.0.0-f2d141fe1d-568e28656a.zip deleted file mode 100644 index 0437e9a092..0000000000 Binary files a/app/editor/.yarn/cache/react-quill-npm-2.0.0-f2d141fe1d-568e28656a.zip and /dev/null differ diff --git a/app/editor/.yarn/cache/tno-core-npm-0.1.147-119e2663b3-d08ec78a13.zip b/app/editor/.yarn/cache/tno-core-npm-0.1.149-f4c21f3413-fa2d5b3400.zip similarity index 83% rename from app/editor/.yarn/cache/tno-core-npm-0.1.147-119e2663b3-d08ec78a13.zip rename to app/editor/.yarn/cache/tno-core-npm-0.1.149-f4c21f3413-fa2d5b3400.zip index 34b5cd366c..77f06ee5e0 100644 Binary files a/app/editor/.yarn/cache/tno-core-npm-0.1.147-119e2663b3-d08ec78a13.zip and b/app/editor/.yarn/cache/tno-core-npm-0.1.149-f4c21f3413-fa2d5b3400.zip differ diff --git a/app/editor/package.json b/app/editor/package.json index 9cbf78359b..36f368b459 100644 --- a/app/editor/package.json +++ b/app/editor/package.json @@ -60,7 +60,7 @@ "redux-logger": "3.0.6", "styled-components": "6.1.11", "stylis": "4.3.2", - "tno-core": "0.1.148" + "tno-core": "0.1.149" }, "devDependencies": { "@simbathesailor/use-what-changed": "2.0.0", diff --git a/app/editor/yarn.lock b/app/editor/yarn.lock index c93ae3e09b..0d9e53df4d 100644 --- a/app/editor/yarn.lock +++ b/app/editor/yarn.lock @@ -11009,7 +11009,7 @@ __metadata: sass-extract-loader: 1.1.0 styled-components: 6.1.11 stylis: 4.3.2 - tno-core: 0.1.148 + tno-core: 0.1.149 typescript: 4.9.5 languageName: unknown linkType: soft @@ -15184,9 +15184,9 @@ __metadata: languageName: node linkType: hard -"tno-core@npm:0.1.148": - version: 0.1.148 - resolution: "tno-core@npm:0.1.148" +"tno-core@npm:0.1.149": + version: 0.1.149 + resolution: "tno-core@npm:0.1.149" dependencies: "@elastic/elasticsearch": ^8.13.1 "@fortawesome/free-solid-svg-icons": ^6.4.2 @@ -15219,7 +15219,7 @@ __metadata: styled-components: ^6.1.11 stylis: ^4.3.2 yup: ^1.1.1 - checksum: 3210b1243a79473ebe30e508e187c11d7d4dae85cb7ee3d2b0ca81431fd22440eee76d3f538cbc78788b4e5cdaa60edab9c10031d136b28e7cbaeefbb1dfeec5 + checksum: fa2d5b34006e0fa08d5530ab9109680bf071e09e76db6d74be6ae1367ae38b292fb5be616948e30b041aa57dfe5c146a441161ee4f07a4a665ba05edd13a9dc6 languageName: node linkType: hard diff --git a/app/subscriber/.yarn/cache/@types-quill-npm-1.3.10-4ddf84ba7e-e629157d11.zip b/app/subscriber/.yarn/cache/@types-quill-npm-1.3.10-4ddf84ba7e-e629157d11.zip deleted file mode 100644 index d7622f110e..0000000000 Binary files a/app/subscriber/.yarn/cache/@types-quill-npm-1.3.10-4ddf84ba7e-e629157d11.zip and /dev/null differ diff --git a/app/subscriber/.yarn/cache/clone-npm-2.1.2-1d491c6629-aaf106e9bc.zip b/app/subscriber/.yarn/cache/clone-npm-2.1.2-1d491c6629-aaf106e9bc.zip deleted file mode 100644 index 6ae29b32e5..0000000000 Binary files a/app/subscriber/.yarn/cache/clone-npm-2.1.2-1d491c6629-aaf106e9bc.zip and /dev/null differ diff --git a/app/subscriber/.yarn/cache/deep-equal-npm-1.1.2-3af5068c14-2d50f27fff.zip b/app/subscriber/.yarn/cache/deep-equal-npm-1.1.2-3af5068c14-2d50f27fff.zip deleted file mode 100644 index d33272c1c8..0000000000 Binary files a/app/subscriber/.yarn/cache/deep-equal-npm-1.1.2-3af5068c14-2d50f27fff.zip and /dev/null differ diff --git a/app/subscriber/.yarn/cache/eventemitter3-npm-2.0.3-71d4ac3a65-dfbf4a0714.zip b/app/subscriber/.yarn/cache/eventemitter3-npm-2.0.3-71d4ac3a65-dfbf4a0714.zip deleted file mode 100644 index 2cceee3509..0000000000 Binary files a/app/subscriber/.yarn/cache/eventemitter3-npm-2.0.3-71d4ac3a65-dfbf4a0714.zip and /dev/null differ diff --git a/app/subscriber/.yarn/cache/eventemitter3-npm-5.0.1-5e423b7df3-543d6c858a.zip b/app/subscriber/.yarn/cache/eventemitter3-npm-5.0.1-5e423b7df3-543d6c858a.zip new file mode 100644 index 0000000000..d7bc3706f4 Binary files /dev/null and b/app/subscriber/.yarn/cache/eventemitter3-npm-5.0.1-5e423b7df3-543d6c858a.zip differ diff --git a/app/subscriber/.yarn/cache/extend-npm-3.0.2-e1ca07ac54-a50a8309ca.zip b/app/subscriber/.yarn/cache/extend-npm-3.0.2-e1ca07ac54-a50a8309ca.zip deleted file mode 100644 index a33fb285f4..0000000000 Binary files a/app/subscriber/.yarn/cache/extend-npm-3.0.2-e1ca07ac54-a50a8309ca.zip and /dev/null differ diff --git a/app/subscriber/.yarn/cache/fast-diff-npm-1.1.2-907d4b29ef-2ef726603e.zip b/app/subscriber/.yarn/cache/fast-diff-npm-1.1.2-907d4b29ef-2ef726603e.zip deleted file mode 100644 index 6fafb684f7..0000000000 Binary files a/app/subscriber/.yarn/cache/fast-diff-npm-1.1.2-907d4b29ef-2ef726603e.zip and /dev/null differ diff --git a/app/subscriber/.yarn/cache/is-arguments-npm-1.1.1-eff4f6d4d7-7f02700ec2.zip b/app/subscriber/.yarn/cache/is-arguments-npm-1.1.1-eff4f6d4d7-7f02700ec2.zip deleted file mode 100644 index 9b956d8699..0000000000 Binary files a/app/subscriber/.yarn/cache/is-arguments-npm-1.1.1-eff4f6d4d7-7f02700ec2.zip and /dev/null differ diff --git a/app/subscriber/.yarn/cache/lodash.clonedeep-npm-4.5.0-fbc3cda4e5-92c46f094b.zip b/app/subscriber/.yarn/cache/lodash.clonedeep-npm-4.5.0-fbc3cda4e5-92c46f094b.zip new file mode 100644 index 0000000000..5765f760d7 Binary files /dev/null and b/app/subscriber/.yarn/cache/lodash.clonedeep-npm-4.5.0-fbc3cda4e5-92c46f094b.zip differ diff --git a/app/subscriber/.yarn/cache/lodash.isequal-npm-4.5.0-f8b0f64d63-da27515dc5.zip b/app/subscriber/.yarn/cache/lodash.isequal-npm-4.5.0-f8b0f64d63-da27515dc5.zip new file mode 100644 index 0000000000..d011a65e17 Binary files /dev/null and b/app/subscriber/.yarn/cache/lodash.isequal-npm-4.5.0-f8b0f64d63-da27515dc5.zip differ diff --git a/app/subscriber/.yarn/cache/object-is-npm-1.1.6-bfafd361ee-3ea2275996.zip b/app/subscriber/.yarn/cache/object-is-npm-1.1.6-bfafd361ee-3ea2275996.zip deleted file mode 100644 index ff83b1ee40..0000000000 Binary files a/app/subscriber/.yarn/cache/object-is-npm-1.1.6-bfafd361ee-3ea2275996.zip and /dev/null differ diff --git a/app/subscriber/.yarn/cache/parchment-npm-1.1.4-a3bac35728-4799756742.zip b/app/subscriber/.yarn/cache/parchment-npm-1.1.4-a3bac35728-4799756742.zip deleted file mode 100644 index dea30b0bd9..0000000000 Binary files a/app/subscriber/.yarn/cache/parchment-npm-1.1.4-a3bac35728-4799756742.zip and /dev/null differ diff --git a/app/subscriber/.yarn/cache/parchment-npm-3.0.0-8af750d9d9-4d7962442c.zip b/app/subscriber/.yarn/cache/parchment-npm-3.0.0-8af750d9d9-4d7962442c.zip new file mode 100644 index 0000000000..8f5575f72c Binary files /dev/null and b/app/subscriber/.yarn/cache/parchment-npm-3.0.0-8af750d9d9-4d7962442c.zip differ diff --git a/app/subscriber/.yarn/cache/quill-delta-npm-3.6.3-3ae240a64d-e62ed33983.zip b/app/subscriber/.yarn/cache/quill-delta-npm-3.6.3-3ae240a64d-e62ed33983.zip deleted file mode 100644 index 13ae0bfabf..0000000000 Binary files a/app/subscriber/.yarn/cache/quill-delta-npm-3.6.3-3ae240a64d-e62ed33983.zip and /dev/null differ diff --git a/app/subscriber/.yarn/cache/quill-delta-npm-5.1.0-885ccecbe2-a9c8cfb6a7.zip b/app/subscriber/.yarn/cache/quill-delta-npm-5.1.0-885ccecbe2-a9c8cfb6a7.zip new file mode 100644 index 0000000000..df0ad99bf7 Binary files /dev/null and b/app/subscriber/.yarn/cache/quill-delta-npm-5.1.0-885ccecbe2-a9c8cfb6a7.zip differ diff --git a/app/subscriber/.yarn/cache/quill-npm-1.3.7-c79f7446fc-db3e265a84.zip b/app/subscriber/.yarn/cache/quill-npm-1.3.7-c79f7446fc-db3e265a84.zip deleted file mode 100644 index 9c20b754ee..0000000000 Binary files a/app/subscriber/.yarn/cache/quill-npm-1.3.7-c79f7446fc-db3e265a84.zip and /dev/null differ diff --git a/app/subscriber/.yarn/cache/quill-npm-2.0.2-135b4c32cb-3f5f20be6c.zip b/app/subscriber/.yarn/cache/quill-npm-2.0.2-135b4c32cb-3f5f20be6c.zip new file mode 100644 index 0000000000..d956baa124 Binary files /dev/null and b/app/subscriber/.yarn/cache/quill-npm-2.0.2-135b4c32cb-3f5f20be6c.zip differ diff --git a/app/subscriber/.yarn/cache/react-quill-new-npm-3.3.2-2c14f30b2b-7fccfabb02.zip b/app/subscriber/.yarn/cache/react-quill-new-npm-3.3.2-2c14f30b2b-7fccfabb02.zip new file mode 100644 index 0000000000..9b5650debd Binary files /dev/null and b/app/subscriber/.yarn/cache/react-quill-new-npm-3.3.2-2c14f30b2b-7fccfabb02.zip differ diff --git a/app/subscriber/.yarn/cache/react-quill-npm-2.0.0-f2d141fe1d-568e28656a.zip b/app/subscriber/.yarn/cache/react-quill-npm-2.0.0-f2d141fe1d-568e28656a.zip deleted file mode 100644 index 0437e9a092..0000000000 Binary files a/app/subscriber/.yarn/cache/react-quill-npm-2.0.0-f2d141fe1d-568e28656a.zip and /dev/null differ diff --git a/app/subscriber/.yarn/cache/tno-core-npm-0.1.147-119e2663b3-d08ec78a13.zip b/app/subscriber/.yarn/cache/tno-core-npm-0.1.149-f4c21f3413-fa2d5b3400.zip similarity index 83% rename from app/subscriber/.yarn/cache/tno-core-npm-0.1.147-119e2663b3-d08ec78a13.zip rename to app/subscriber/.yarn/cache/tno-core-npm-0.1.149-f4c21f3413-fa2d5b3400.zip index 34b5cd366c..77f06ee5e0 100644 Binary files a/app/subscriber/.yarn/cache/tno-core-npm-0.1.147-119e2663b3-d08ec78a13.zip and b/app/subscriber/.yarn/cache/tno-core-npm-0.1.149-f4c21f3413-fa2d5b3400.zip differ diff --git a/app/subscriber/package.json b/app/subscriber/package.json index ccf679f9ee..07c27666fe 100644 --- a/app/subscriber/package.json +++ b/app/subscriber/package.json @@ -45,7 +45,7 @@ "sheetjs": "file:packages/xlsx-0.20.1.tgz", "styled-components": "6.1.11", "stylis": "4.3.2", - "tno-core": "0.1.148" + "tno-core": "0.1.149" }, "devDependencies": { "@testing-library/jest-dom": "6.4.5", diff --git a/app/subscriber/src/components/content-list/ContentListContext.tsx b/app/subscriber/src/components/content-list/ContentListContext.tsx index 762fc15687..98e1573366 100644 --- a/app/subscriber/src/components/content-list/ContentListContext.tsx +++ b/app/subscriber/src/components/content-list/ContentListContext.tsx @@ -1,6 +1,6 @@ import { createContext, ReactNode, useState } from 'react'; import React from 'react'; -import { useApp, useReports } from 'store/hooks'; +import { useApp, useReports, useReportSync } from 'store/hooks'; import { useProfileStore } from 'store/slices'; import { defaultValueListContext } from './constants'; @@ -23,6 +23,7 @@ export const ContentListProvider: React.FC = ({ child // Make a request to reports to determine what content is in a report. const [, { getAllContentInMyReports }] = useReports(); const [, { storeReportContent }] = useProfileStore(); + useReportSync(); const [groupBy, setGroupBy] = useState('source'); diff --git a/app/subscriber/src/store/hooks/subscriber/index.ts b/app/subscriber/src/store/hooks/subscriber/index.ts index 40ccae62ac..c1bf2eabd6 100644 --- a/app/subscriber/src/store/hooks/subscriber/index.ts +++ b/app/subscriber/src/store/hooks/subscriber/index.ts @@ -8,6 +8,7 @@ export * from './useNavigateAndScroll'; export * from './useProducts'; export * from './useReportInstances'; export * from './useReports'; +export * from './useReportSync'; export * from './useReportTemplates'; export * from './useSystemMessages'; export * from './useUsers'; diff --git a/app/subscriber/src/store/hooks/subscriber/useReportSync.ts b/app/subscriber/src/store/hooks/subscriber/useReportSync.ts new file mode 100644 index 0000000000..9901c4b9f9 --- /dev/null +++ b/app/subscriber/src/store/hooks/subscriber/useReportSync.ts @@ -0,0 +1,55 @@ +import React from 'react'; +import { useProfileStore } from 'store/slices'; +import { IReportMessageModel, MessageTargetKey, useApiSubscriberReportInstances } from 'tno-core'; + +import { useApiHub } from '../signalr'; + +/** + * Hook provides a singleton way to ensure my reports are synced across tabs. + */ +export const useReportSync = () => { + const { getReportInstance } = useApiSubscriberReportInstances(); + const hub = useApiHub(); + const [{ myReports }, { storeMyReports }] = useProfileStore(); + + // When a report instance has been updated a message will be received. + const handleUpdateReportInstance = React.useCallback( + async (message: IReportMessageModel) => { + try { + const report = myReports.find((r) => r.id === message.reportId); + const instance = report?.instances.length ? report.instances[0] : undefined; + + // Only fetch the latest if the current report instance is older, or doesn't exist. + if (report && (!instance || instance.version !== message.version)) { + const response = await getReportInstance(message.id, true); + if (response.status === 200 && response.data) { + const instance = response.data; + storeMyReports((reports) => { + let addInstance = true; + let instances = report.instances.map((i) => { + if (i.id === message.id) { + addInstance = false; + return instance; + } + return i; + }); + if (addInstance) instances = [instance, ...instances]; + const results = reports.map((r) => + r.id === report.id + ? { + ...report, + instances, + } + : r, + ); + return results; + }); + } + } + } catch {} + }, + [getReportInstance, myReports, storeMyReports], + ); + + hub.useHubEffect(MessageTargetKey.ReportStatus, handleUpdateReportInstance); +}; diff --git a/app/subscriber/yarn.lock b/app/subscriber/yarn.lock index da67eb8dfb..e6f0ee696e 100644 --- a/app/subscriber/yarn.lock +++ b/app/subscriber/yarn.lock @@ -10665,7 +10665,7 @@ __metadata: sheetjs: "file:packages/xlsx-0.20.1.tgz" styled-components: 6.1.11 stylis: 4.3.2 - tno-core: 0.1.148 + tno-core: 0.1.149 typescript: 4.9.5 languageName: unknown linkType: soft @@ -14698,9 +14698,9 @@ __metadata: languageName: node linkType: hard -"tno-core@npm:0.1.148": - version: 0.1.148 - resolution: "tno-core@npm:0.1.148" +"tno-core@npm:0.1.149": + version: 0.1.149 + resolution: "tno-core@npm:0.1.149" dependencies: "@elastic/elasticsearch": ^8.13.1 "@fortawesome/free-solid-svg-icons": ^6.4.2 @@ -14733,7 +14733,7 @@ __metadata: styled-components: ^6.1.11 stylis: ^4.3.2 yup: ^1.1.1 - checksum: 3210b1243a79473ebe30e508e187c11d7d4dae85cb7ee3d2b0ca81431fd22440eee76d3f538cbc78788b4e5cdaa60edab9c10031d136b28e7cbaeefbb1dfeec5 + checksum: fa2d5b34006e0fa08d5530ab9109680bf071e09e76db6d74be6ae1367ae38b292fb5be616948e30b041aa57dfe5c146a441161ee4f07a4a665ba05edd13a9dc6 languageName: node linkType: hard diff --git a/libs/net/dal/Services/ReportService.cs b/libs/net/dal/Services/ReportService.cs index 8447944c49..bc7bc01ba7 100644 --- a/libs/net/dal/Services/ReportService.cs +++ b/libs/net/dal/Services/ReportService.cs @@ -660,18 +660,23 @@ public static ReportInstanceContent[] OrderBySectionField(IEnumerable report.Sections.Any(s => s.Name == c.SectionName) && !instance.ContentManyToMany.Any(ic => ic.SectionName == c.SectionName && ic.ContentId == c.ContentId)); - instance.ContentManyToMany.AddRange(addContent); + if (addContent.Any()) + { + instance.ContentManyToMany.AddRange(addContent); - instance = _reportInstanceService.AddAndSave(instance); - report.Instances.Add(instance); + instance = _reportInstanceService.AddAndSave(instance); + report.Instances.Add(instance); + } } else { // Add new content that does not already exist in the report and only for valid sections. var addContent = content.Where(c => report.Sections.Any(s => s.Name == c.SectionName) && !instance.ContentManyToMany.Any(ic => ic.SectionName == c.SectionName && ic.ContentId == c.ContentId)); - instance.ContentManyToMany.AddRange(addContent); - - instance = _reportInstanceService.UpdateAndSave(instance, true); + if (addContent.Any()) + { + instance.ContentManyToMany.AddRange(addContent); + instance = _reportInstanceService.UpdateAndSave(instance, true); + } } return report; @@ -1091,7 +1096,8 @@ public IEnumerable GetRelatedReportInstanceContentToExclude(int reportId) try { this.Context.SaveChanges(); - } catch (Exception ex) + } + catch (Exception ex) { this.Logger.LogError(ex, $"ReportService - ClearFoldersInReport Report Id: {report.Id} throws exception."); throw; diff --git a/libs/npm/core/package.json b/libs/npm/core/package.json index a134481fb3..f39ccdfe5d 100644 --- a/libs/npm/core/package.json +++ b/libs/npm/core/package.json @@ -1,7 +1,7 @@ { "name": "tno-core", "description": "TNO shared library", - "version": "0.1.148", + "version": "0.1.149", "homepage": "https://github.com/bcgov/tno", "license": "Apache-2.0", "files": [ diff --git a/libs/npm/core/src/hooks/api/interfaces/IReportMessageModel.ts b/libs/npm/core/src/hooks/api/interfaces/IReportMessageModel.ts index f260c80175..1f8860c0f4 100644 --- a/libs/npm/core/src/hooks/api/interfaces/IReportMessageModel.ts +++ b/libs/npm/core/src/hooks/api/interfaces/IReportMessageModel.ts @@ -1,6 +1,6 @@ -import { IUserModel, ReportStatusName } from '..'; +import { IAuditColumnsModel, IUserModel, ReportStatusName } from '..'; -export interface IReportMessageModel { +export interface IReportMessageModel extends IAuditColumnsModel { id: number; reportId: number; subject: string;