@uxland/primary-shell 4.2.0 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/index.js +1786 -1590
  2. package/dist/index.js.map +1 -1
  3. package/dist/index.umd.cjs +226 -208
  4. package/dist/index.umd.cjs.map +1 -1
  5. package/dist/primary/shell/src/UI/components/shell-header/shell-header.d.ts +1 -0
  6. package/dist/primary/shell/src/api/api.d.ts +2 -0
  7. package/dist/primary/shell/src/api/http-client/http-client.d.ts +3 -2
  8. package/dist/primary/shell/src/api/plugin-busy-manager/plugin-busy-list/component.d.ts +12 -0
  9. package/dist/primary/shell/src/api/plugin-busy-manager/plugin-busy-list/template.d.ts +3 -0
  10. package/dist/primary/shell/src/api/plugin-busy-manager/plugin-busy-manager.d.ts +19 -0
  11. package/dist/primary/shell/src/api/plugin-busy-manager/plugin-busy-manager.test.d.ts +1 -0
  12. package/dist/primary/shell/src/api/token-manager/token-manager.d.ts +1 -1
  13. package/dist/primary/shell/src/events.d.ts +1 -0
  14. package/dist/primary/shell/src/features/exit/bootstrapper.d.ts +2 -0
  15. package/dist/primary/shell/src/features/exit/handler.d.ts +10 -0
  16. package/dist/primary/shell/src/features/exit/request.d.ts +4 -0
  17. package/dist/primary/shell/src/handle-plugins.d.ts +2 -2
  18. package/dist/primary/shell/src/internal-plugins/activity-history/activity-history-item/add/add-async-history-items/validate-add-async-items-command.d.ts +4 -0
  19. package/dist/primary/shell/src/internal-plugins/activity-history/activity-history-item/add/add-history-items/reducer.d.ts +1 -1
  20. package/dist/primary/shell/src/internal-plugins/activity-history/activity-history-item/domain/model.d.ts +3 -0
  21. package/dist/primary/shell/src/internal-plugins/activity-history/activity-history-item/filter/UI/active-filters-badges/active-filters-badges.d.ts +4 -1
  22. package/dist/primary/shell/src/internal-plugins/activity-history/activity-history-item/filter/UI/active-filters-header/active-filters-header.d.ts +1 -2
  23. package/dist/primary/shell/src/internal-plugins/activity-history/activity-history-item/filter/common-filters/selectors.d.ts +152 -0
  24. package/dist/primary/shell/src/internal-plugins/activity-history/activity-history-item/filter/utils.d.ts +2 -0
  25. package/dist/primary/shell/src/internal-plugins/activity-history/activity-history-item/list/UI/timeline/activity-history-timeline.d.ts +2 -0
  26. package/dist/primary/shell/src/internal-plugins/activity-history/handle-views.d.ts +4 -0
  27. package/dist/primary/shell/src/internal-plugins/activity-history/infrastructure/ioc/container.d.ts +1 -0
  28. package/dist/primary/shell/src/internal-plugins/activity-history/infrastructure/ioc/types.d.ts +0 -1
  29. package/dist/primary/shell/src/internal-plugins/activity-history/localization.d.ts +1 -0
  30. package/dist/primary/shell/src/internal-plugins/activity-history/main.d.ts +0 -1
  31. package/dist/primary/shell/src/locales.d.ts +4 -0
  32. package/package.json +1 -1
  33. package/src/UI/components/index.ts +3 -2
  34. package/src/UI/components/shell-header/shell-header.ts +5 -0
  35. package/src/UI/components/shell-header/template.ts +2 -2
  36. package/src/api/api.ts +10 -3
  37. package/src/api/broker/factory.ts +1 -1
  38. package/src/api/http-client/http-client.test.ts +60 -6
  39. package/src/api/http-client/http-client.ts +17 -10
  40. package/src/api/plugin-busy-manager/plugin-busy-list/component.ts +19 -0
  41. package/src/api/plugin-busy-manager/plugin-busy-list/styles.css +20 -0
  42. package/src/api/plugin-busy-manager/plugin-busy-list/template.ts +13 -0
  43. package/src/api/plugin-busy-manager/plugin-busy-manager.test.ts +49 -0
  44. package/src/api/plugin-busy-manager/plugin-busy-manager.ts +38 -0
  45. package/src/api/token-manager/token-manager.test.ts +0 -12
  46. package/src/api/token-manager/token-manager.ts +12 -7
  47. package/src/disposer.ts +0 -1
  48. package/src/events.ts +1 -0
  49. package/src/features/bootstrapper.ts +3 -0
  50. package/src/features/exit/bootstrapper.ts +17 -0
  51. package/src/features/exit/handler.ts +51 -0
  52. package/src/features/exit/request.ts +3 -0
  53. package/src/handle-plugins.ts +7 -6
  54. package/src/handle-views.ts +4 -1
  55. package/src/internal-plugins/activity-history/activity-history-item/add/add-async-history-items/handler.ts +2 -0
  56. package/src/internal-plugins/activity-history/activity-history-item/add/add-async-history-items/validate-add-async-items-command.ts +15 -0
  57. package/src/internal-plugins/activity-history/activity-history-item/add/add-history-items/reducer.ts +10 -7
  58. package/src/internal-plugins/activity-history/activity-history-item/domain/model.ts +4 -0
  59. package/src/internal-plugins/activity-history/activity-history-item/filter/UI/active-filters-badges/active-filters-badges.ts +13 -5
  60. package/src/internal-plugins/activity-history/activity-history-item/filter/UI/active-filters-badges/template.ts +26 -2
  61. package/src/internal-plugins/activity-history/activity-history-item/filter/UI/active-filters-header/active-filters-header.ts +5 -8
  62. package/src/internal-plugins/activity-history/activity-history-item/filter/UI/active-filters-header/template.ts +6 -1
  63. package/src/internal-plugins/activity-history/activity-history-item/filter/common-filters/selectors.ts +10 -0
  64. package/src/internal-plugins/activity-history/activity-history-item/filter/custom-filters/set-custom-filter-value/reducer.ts +7 -1
  65. package/src/internal-plugins/activity-history/activity-history-item/filter/utils.ts +9 -0
  66. package/src/internal-plugins/activity-history/activity-history-item/list/UI/timeline/activity-history-timeline.ts +30 -0
  67. package/src/internal-plugins/activity-history/activity-history-item/list/UI/timeline/template.ts +7 -4
  68. package/src/internal-plugins/activity-history/handle-views.ts +17 -0
  69. package/src/internal-plugins/activity-history/infrastructure/ioc/container.ts +5 -0
  70. package/src/internal-plugins/activity-history/infrastructure/ioc/types.ts +0 -1
  71. package/src/internal-plugins/activity-history/localization.ts +7 -8
  72. package/src/internal-plugins/activity-history/main.ts +4 -10
  73. package/src/locales.ts +8 -4
  74. package/dist/primary/shell/src/internal-plugins/activity-history/utils/get-locale-manager-dependency.d.ts +0 -1
  75. package/src/internal-plugins/activity-history/utils/get-locale-manager-dependency.ts +0 -7
@@ -10,6 +10,7 @@ export declare class ShellHeader extends ShellHeader_base {
10
10
  professional: IUserInfo;
11
11
  menuOpened: boolean;
12
12
  toggleMenu(): void;
13
+ logout(): void;
13
14
  connectedCallback(): void;
14
15
  }
15
16
  export {};
@@ -6,6 +6,7 @@ import { HttpClient } from './http-client/http-client';
6
6
  import { PrimariaInteractionManager } from './interaction-manager/interaction';
7
7
  import { TokenManager } from './token-manager/token-manager';
8
8
  import { EcapEventManager } from './ecap-event-manager/ecap-event-manager';
9
+ import { PluginBusyManager } from './plugin-busy-manager/plugin-busy-manager';
9
10
 
10
11
  export interface PrimariaApi extends HarmonixApi {
11
12
  httpClient: HttpClient;
@@ -15,6 +16,7 @@ export interface PrimariaApi extends HarmonixApi {
15
16
  globalStateManager: PrimariaGlobalStateManager;
16
17
  tokenManager: TokenManager;
17
18
  ecapEventManager: EcapEventManager;
19
+ pluginBusyManager: PluginBusyManager;
18
20
  }
19
21
  export declare const PrimariaRegionHost: any;
20
22
  /**
@@ -1,8 +1,9 @@
1
1
  import { AxiosRequestConfig, AxiosResponse } from 'axios';
2
2
  import { TokenManager } from '../token-manager/token-manager';
3
+ import { PrimariaBroker } from '../broker/primaria-broker';
3
4
 
4
- export declare const createAxiosInstance: (tokenManager: TokenManager) => import('axios').AxiosInstance;
5
+ export declare const createAxiosInstance: (tokenManager: TokenManager, broker: PrimariaBroker) => import('axios').AxiosInstance;
5
6
  export interface HttpClient {
6
7
  request<T = any, R = AxiosResponse<T>, D = any>(config: AxiosRequestConfig<D>): Promise<R>;
7
8
  }
8
- export declare const createHttpClient: (tokenManager: TokenManager) => HttpClient;
9
+ export declare const createHttpClient: (tokenManager: TokenManager, broker: PrimariaBroker) => HttpClient;
@@ -0,0 +1,12 @@
1
+ import { LitElement } from 'lit';
2
+ import { PluginBusyTask } from '../plugin-busy-manager';
3
+
4
+ declare const PluginBusyList_base: import('../../..').Constructor<import('../../..').ConfirmMixinBase> & typeof LitElement;
5
+ export declare class PluginBusyList extends PluginBusyList_base {
6
+ static styles: import('lit').CSSResult;
7
+ render(): import('lit').TemplateResult<1>;
8
+ model: {
9
+ busyTasks: PluginBusyTask[];
10
+ };
11
+ }
12
+ export {};
@@ -0,0 +1,3 @@
1
+ import { PluginBusyList } from './component';
2
+
3
+ export declare const template: (props: PluginBusyList) => import('lit').TemplateResult<1>;
@@ -0,0 +1,19 @@
1
+ export interface PluginBusyTask {
2
+ taskId: string;
3
+ taskDescription: string;
4
+ }
5
+ export declare abstract class PluginBusyManager {
6
+ abstract addBusyPluginTask(busyTask: PluginBusyTask): void;
7
+ abstract removeBusyPluginTask(taskId: string): any;
8
+ abstract clearAllBusyPlugins(): void;
9
+ abstract isAnyPluginBusy(): boolean;
10
+ abstract getBusyPluginTasks(): PluginBusyTask[];
11
+ }
12
+ export declare class PluginBusyManagerImpl implements PluginBusyManager {
13
+ private busyPluginTasks;
14
+ addBusyPluginTask(busyTask: PluginBusyTask): void;
15
+ removeBusyPluginTask(taskId: string): any;
16
+ isAnyPluginBusy(): boolean;
17
+ clearAllBusyPlugins(): void;
18
+ getBusyPluginTasks(): PluginBusyTask[];
19
+ }
@@ -2,7 +2,7 @@ export interface TokenManager {
2
2
  getToken: () => string;
3
3
  refreshToken: () => Promise<string>;
4
4
  }
5
- export declare class TokenManagerSimulator implements TokenManager {
5
+ export declare class TokenManagerImpl implements TokenManager {
6
6
  getUrlParams: () => URLSearchParams;
7
7
  initToken: () => string;
8
8
  getToken: () => string;
@@ -2,4 +2,5 @@ export declare const shellEvents: {
2
2
  openClinicalMonitoringRequested: string;
3
3
  appCrashed: string;
4
4
  mainViewChanged: string;
5
+ refreshTokenFailed: string;
5
6
  };
@@ -0,0 +1,2 @@
1
+ export declare const bootstrapExitShell: () => void;
2
+ export declare const teardownExitShell: () => void;
@@ -0,0 +1,10 @@
1
+ import { PrimariaApi } from '../..';
2
+ import { ExitShell } from './request';
3
+
4
+ export declare class ExitShellHandler {
5
+ private api;
6
+ constructor(api: PrimariaApi);
7
+ handle(message: ExitShell): Promise<void>;
8
+ private askForClose;
9
+ private timeout;
10
+ }
@@ -0,0 +1,4 @@
1
+ import { IRequest } from '../..';
2
+
3
+ export declare class ExitShell implements IRequest<void> {
4
+ }
@@ -2,6 +2,6 @@ import { PluginDefinition, Plugin as PluginType } from '@uxland/harmonix';
2
2
  import { PrimariaApi } from './api/api';
3
3
 
4
4
  export type { PluginDefinition, PluginInfo } from '@uxland/harmonix';
5
- export declare const bootstrapPlugins: (plugins: PluginDefinition[]) => Promise<Plugin[]>;
6
- export declare const disposePlugins: (plugins: Plugin[]) => Promise<void[]>;
5
+ export declare const bootstrapPlugins: (plugins: PluginDefinition[]) => Promise<void>;
6
+ export declare const disposePlugins: () => Promise<void[]>;
7
7
  export type Plugin = PluginType<PrimariaApi>;
@@ -0,0 +1,4 @@
1
+ import { IActivityHistoryItem } from '../../domain/model';
2
+ import { InjectAsyncHistoryItemsPayload } from './request';
3
+
4
+ export declare const validateAddAsyncCommand: (payload: InjectAsyncHistoryItemsPayload, items: IActivityHistoryItem[]) => void;
@@ -6,4 +6,4 @@ export declare function addActivityHistoryItemsReducer(state: any, action: Paylo
6
6
  items: IActivityHistoryItem[];
7
7
  componentFactory?: (item: IActivityHistoryItem) => HTMLElement;
8
8
  searchPredicate?: TSearchActivityHistoryItemPredicate;
9
- }>): void;
9
+ }>): any;
@@ -22,6 +22,9 @@ export interface IActivityHistoryItem {
22
22
  searchPredicate: TSearchActivityHistoryItemPredicate;
23
23
  type?: string;
24
24
  }
25
+ export interface IActivityHistoryItemWithComponent extends IActivityHistoryItem {
26
+ component: HTMLElement;
27
+ }
25
28
  export interface IActivityHistoryItemCollection {
26
29
  id: string;
27
30
  items: IActivityHistoryItem[];
@@ -1,11 +1,14 @@
1
1
  import { LitElement } from 'lit';
2
2
  import { PrimariaApi } from '../../../../../../api/api';
3
- import { IActivityHistoryCustomFilterGroup } from '../../model';
3
+ import { IActivityHistoryCustomFilterGroup, IActivityHistoryFilterGroup } from '../../model';
4
4
 
5
5
  export declare class ActiveFiltersBadges extends LitElement {
6
6
  render(): import('lit').TemplateResult<1>;
7
7
  static styles: import('lit').CSSResult;
8
8
  api: PrimariaApi;
9
+ activityHistoryCommonFiltersSelector: any;
10
+ enabledCommonFilters: IActivityHistoryFilterGroup[];
9
11
  enabledFilters: IActivityHistoryCustomFilterGroup[];
10
12
  _onDeleteFilterValue(filterGroupId: string, filterId: string, optionId: string, value: boolean): void;
13
+ _onDeleteCommonFilterValue(filterId: string): void;
11
14
  }
@@ -1,10 +1,9 @@
1
1
  import { LitElement } from 'lit';
2
- import { IActivityHistoryCustomFilterGroup } from '../../model';
3
2
 
4
3
  export declare class ActiveFiltersHeader extends LitElement {
5
4
  render(): import('lit').TemplateResult<1>;
6
5
  static styles: import('lit').CSSResult;
7
6
  searchString: string;
8
- filters: IActivityHistoryCustomFilterGroup[];
9
7
  areCustomFiltersActive: boolean;
8
+ areCommonFiltersActive: boolean;
10
9
  }
@@ -90,3 +90,155 @@ export declare const isEnabledCommonFilterSelector: (filterId: string) => ((stat
90
90
  argsMemoize: typeof import('@reduxjs/toolkit').weakMapMemoize;
91
91
  memoize: typeof import('@reduxjs/toolkit').weakMapMemoize;
92
92
  };
93
+ export declare const activityHistoryEnabledCommonFiltersSelector: ((state: {
94
+ activityHistoryCollections: {
95
+ busy: import('../../..').IBusyHistoryItem[];
96
+ error: import('../../..').IErrorHistoryItem[];
97
+ collections: Record<string, import('../../..').IActivityHistoryItemCollection>;
98
+ };
99
+ activityHistoryFilters: {
100
+ searchString: string;
101
+ filters: import('..').IActivityHistoryFilterGroup[];
102
+ };
103
+ }) => (import('..').IActivityHistoryCommonFilter | import('..').IActivityHistoryCustomFilter)[]) & {
104
+ clearCache: () => void;
105
+ resultsCount: () => number;
106
+ resetResultsCount: () => void;
107
+ } & {
108
+ resultFunc: (resultFuncArgs_0: import('..').IActivityHistoryCommonFilter[] | import('..').IActivityHistoryCustomFilter[]) => (import('..').IActivityHistoryCommonFilter | import('..').IActivityHistoryCustomFilter)[];
109
+ memoizedResultFunc: ((resultFuncArgs_0: import('..').IActivityHistoryCommonFilter[] | import('..').IActivityHistoryCustomFilter[]) => (import('..').IActivityHistoryCommonFilter | import('..').IActivityHistoryCustomFilter)[]) & {
110
+ clearCache: () => void;
111
+ resultsCount: () => number;
112
+ resetResultsCount: () => void;
113
+ };
114
+ lastResult: () => (import('..').IActivityHistoryCommonFilter | import('..').IActivityHistoryCustomFilter)[];
115
+ dependencies: [((state: {
116
+ activityHistoryCollections: {
117
+ busy: import('../../..').IBusyHistoryItem[];
118
+ error: import('../../..').IErrorHistoryItem[];
119
+ collections: Record<string, import('../../..').IActivityHistoryItemCollection>;
120
+ };
121
+ activityHistoryFilters: {
122
+ searchString: string;
123
+ filters: import('..').IActivityHistoryFilterGroup[];
124
+ };
125
+ }) => import('..').IActivityHistoryCommonFilter[] | import('..').IActivityHistoryCustomFilter[]) & {
126
+ clearCache: () => void;
127
+ resultsCount: () => number;
128
+ resetResultsCount: () => void;
129
+ } & {
130
+ resultFunc: (resultFuncArgs_0: import('..').IActivityHistoryFilterGroup[]) => import('..').IActivityHistoryCommonFilter[] | import('..').IActivityHistoryCustomFilter[];
131
+ memoizedResultFunc: ((resultFuncArgs_0: import('..').IActivityHistoryFilterGroup[]) => import('..').IActivityHistoryCommonFilter[] | import('..').IActivityHistoryCustomFilter[]) & {
132
+ clearCache: () => void;
133
+ resultsCount: () => number;
134
+ resetResultsCount: () => void;
135
+ };
136
+ lastResult: () => import('..').IActivityHistoryCommonFilter[] | import('..').IActivityHistoryCustomFilter[];
137
+ dependencies: [(state: import('../../../infrastructure/state/store').RootState) => import('..').IActivityHistoryFilterGroup[]];
138
+ recomputations: () => number;
139
+ resetRecomputations: () => void;
140
+ dependencyRecomputations: () => number;
141
+ resetDependencyRecomputations: () => void;
142
+ } & {
143
+ argsMemoize: typeof import('@reduxjs/toolkit').weakMapMemoize;
144
+ memoize: typeof import('@reduxjs/toolkit').weakMapMemoize;
145
+ }];
146
+ recomputations: () => number;
147
+ resetRecomputations: () => void;
148
+ dependencyRecomputations: () => number;
149
+ resetDependencyRecomputations: () => void;
150
+ } & {
151
+ argsMemoize: typeof import('@reduxjs/toolkit').weakMapMemoize;
152
+ memoize: typeof import('@reduxjs/toolkit').weakMapMemoize;
153
+ };
154
+ export declare const areCommonFiltersActive: ((state: {
155
+ activityHistoryCollections: {
156
+ busy: import('../../..').IBusyHistoryItem[];
157
+ error: import('../../..').IErrorHistoryItem[];
158
+ collections: Record<string, import('../../..').IActivityHistoryItemCollection>;
159
+ };
160
+ activityHistoryFilters: {
161
+ searchString: string;
162
+ filters: import('..').IActivityHistoryFilterGroup[];
163
+ };
164
+ }) => boolean) & {
165
+ clearCache: () => void;
166
+ resultsCount: () => number;
167
+ resetResultsCount: () => void;
168
+ } & {
169
+ resultFunc: (resultFuncArgs_0: (import('..').IActivityHistoryCommonFilter | import('..').IActivityHistoryCustomFilter)[]) => boolean;
170
+ memoizedResultFunc: ((resultFuncArgs_0: (import('..').IActivityHistoryCommonFilter | import('..').IActivityHistoryCustomFilter)[]) => boolean) & {
171
+ clearCache: () => void;
172
+ resultsCount: () => number;
173
+ resetResultsCount: () => void;
174
+ };
175
+ lastResult: () => boolean;
176
+ dependencies: [((state: {
177
+ activityHistoryCollections: {
178
+ busy: import('../../..').IBusyHistoryItem[];
179
+ error: import('../../..').IErrorHistoryItem[];
180
+ collections: Record<string, import('../../..').IActivityHistoryItemCollection>;
181
+ };
182
+ activityHistoryFilters: {
183
+ searchString: string;
184
+ filters: import('..').IActivityHistoryFilterGroup[];
185
+ };
186
+ }) => (import('..').IActivityHistoryCommonFilter | import('..').IActivityHistoryCustomFilter)[]) & {
187
+ clearCache: () => void;
188
+ resultsCount: () => number;
189
+ resetResultsCount: () => void;
190
+ } & {
191
+ resultFunc: (resultFuncArgs_0: import('..').IActivityHistoryCommonFilter[] | import('..').IActivityHistoryCustomFilter[]) => (import('..').IActivityHistoryCommonFilter | import('..').IActivityHistoryCustomFilter)[];
192
+ memoizedResultFunc: ((resultFuncArgs_0: import('..').IActivityHistoryCommonFilter[] | import('..').IActivityHistoryCustomFilter[]) => (import('..').IActivityHistoryCommonFilter | import('..').IActivityHistoryCustomFilter)[]) & {
193
+ clearCache: () => void;
194
+ resultsCount: () => number;
195
+ resetResultsCount: () => void;
196
+ };
197
+ lastResult: () => (import('..').IActivityHistoryCommonFilter | import('..').IActivityHistoryCustomFilter)[];
198
+ dependencies: [((state: {
199
+ activityHistoryCollections: {
200
+ busy: import('../../..').IBusyHistoryItem[];
201
+ error: import('../../..').IErrorHistoryItem[];
202
+ collections: Record<string, import('../../..').IActivityHistoryItemCollection>;
203
+ };
204
+ activityHistoryFilters: {
205
+ searchString: string;
206
+ filters: import('..').IActivityHistoryFilterGroup[];
207
+ };
208
+ }) => import('..').IActivityHistoryCommonFilter[] | import('..').IActivityHistoryCustomFilter[]) & {
209
+ clearCache: () => void;
210
+ resultsCount: () => number;
211
+ resetResultsCount: () => void;
212
+ } & {
213
+ resultFunc: (resultFuncArgs_0: import('..').IActivityHistoryFilterGroup[]) => import('..').IActivityHistoryCommonFilter[] | import('..').IActivityHistoryCustomFilter[];
214
+ memoizedResultFunc: ((resultFuncArgs_0: import('..').IActivityHistoryFilterGroup[]) => import('..').IActivityHistoryCommonFilter[] | import('..').IActivityHistoryCustomFilter[]) & {
215
+ clearCache: () => void;
216
+ resultsCount: () => number;
217
+ resetResultsCount: () => void;
218
+ };
219
+ lastResult: () => import('..').IActivityHistoryCommonFilter[] | import('..').IActivityHistoryCustomFilter[];
220
+ dependencies: [(state: import('../../../infrastructure/state/store').RootState) => import('..').IActivityHistoryFilterGroup[]];
221
+ recomputations: () => number;
222
+ resetRecomputations: () => void;
223
+ dependencyRecomputations: () => number;
224
+ resetDependencyRecomputations: () => void;
225
+ } & {
226
+ argsMemoize: typeof import('@reduxjs/toolkit').weakMapMemoize;
227
+ memoize: typeof import('@reduxjs/toolkit').weakMapMemoize;
228
+ }];
229
+ recomputations: () => number;
230
+ resetRecomputations: () => void;
231
+ dependencyRecomputations: () => number;
232
+ resetDependencyRecomputations: () => void;
233
+ } & {
234
+ argsMemoize: typeof import('@reduxjs/toolkit').weakMapMemoize;
235
+ memoize: typeof import('@reduxjs/toolkit').weakMapMemoize;
236
+ }];
237
+ recomputations: () => number;
238
+ resetRecomputations: () => void;
239
+ dependencyRecomputations: () => number;
240
+ resetDependencyRecomputations: () => void;
241
+ } & {
242
+ argsMemoize: typeof import('@reduxjs/toolkit').weakMapMemoize;
243
+ memoize: typeof import('@reduxjs/toolkit').weakMapMemoize;
244
+ };
@@ -0,0 +1,2 @@
1
+ export declare const formatShowFilterTitle: (title: string) => string;
2
+ export declare const normalizeDeletedFilterBooleanValue: (value: any) => any;
@@ -10,6 +10,8 @@ export declare class ActivityHistoryTimeline extends LitElement {
10
10
  searchString: string;
11
11
  _hasUpdatedOnce: boolean;
12
12
  firstUpdated(): void;
13
+ updated(changedProperties: any): Promise<void>;
14
+ prepareComponents(historyGroups: any): Promise<void>;
13
15
  highlightMatch(text: string, searchString: string): string;
14
16
  _scrollIntoDate(selectedDate: number): void;
15
17
  }
@@ -0,0 +1,4 @@
1
+ import { PrimariaApi } from '../../api/api';
2
+
3
+ export declare const registerViews: (api: PrimariaApi) => void;
4
+ export declare const unregisterViews: () => void;
@@ -5,3 +5,4 @@ declare const container: Container;
5
5
  declare const lazyInject: (serviceIdentifier: string | symbol | import("inversify").interfaces.Newable<any> | import("inversify").interfaces.Abstract<any>) => (proto: any, key: string) => void;
6
6
  export { container, lazyInject };
7
7
  export declare const bindDeps: (api: PrimariaApi) => void;
8
+ export declare const unbindDeps: () => void;
@@ -1,5 +1,4 @@
1
1
  export declare const TYPES: {
2
2
  primaryApi: symbol;
3
3
  store: symbol;
4
- localeManager: symbol;
5
4
  };
@@ -50,6 +50,7 @@ export declare const locales: {
50
50
  clinicalCourseType: string;
51
51
  selected: string;
52
52
  applyFilters: string;
53
+ deleted: string;
53
54
  };
54
55
  tooltips: {
55
56
  subjective: string;
@@ -2,4 +2,3 @@ import { PrimariaApi } from '../../api/api';
2
2
 
3
3
  export declare const initialize: (api: PrimariaApi) => Promise<void>;
4
4
  export declare const dispose: () => Promise<void>;
5
- export declare const registerViews: (api: PrimariaApi) => void;
@@ -17,6 +17,7 @@ export declare const locales: {
17
17
  create: string;
18
18
  toggleMenuClose: string;
19
19
  toggleMenuOpen: string;
20
+ askExit: string;
20
21
  };
21
22
  clinicalMonitoring: {
22
23
  title: string;
@@ -26,6 +27,9 @@ export declare const locales: {
26
27
  role: string;
27
28
  speciality: string;
28
29
  };
30
+ busyManager: {
31
+ title: string;
32
+ };
29
33
  };
30
34
  };
31
35
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uxland/primary-shell",
3
- "version": "4.2.0",
3
+ "version": "4.3.0",
4
4
  "description": "Primaria Shell",
5
5
  "author": "UXLand <dev@uxland.es>",
6
6
  "homepage": "https://github.com/uxland/harmonix/tree/app#readme",
@@ -1,5 +1,6 @@
1
1
  import "./primaria-shell/primaria-shell";
2
2
  import "./clinical-monitoring/clinical-monitoring";
3
3
  import "../shared-components";
4
- import "../components/shell-header/shell-header";
5
- import "../components/quick-actions-menu/quick-actions-menu";
4
+ import "./shell-header/shell-header";
5
+ import "./quick-actions-menu/quick-actions-menu";
6
+ import "../../api/plugin-busy-manager/plugin-busy-list/component";
@@ -7,6 +7,7 @@ import { GetUserInfo } from "../../../features/get-user-info/request";
7
7
  import styles from "./styles.css?inline";
8
8
  import { shellRegions } from "../../../api/region-manager/regions";
9
9
  import { IRegion, region } from "@uxland/regions";
10
+ import { ExitShell } from "../../../features/exit/request";
10
11
 
11
12
  @customElement("shell-header")
12
13
  export class ShellHeader extends PrimariaRegionHost(LitElement) {
@@ -34,6 +35,10 @@ export class ShellHeader extends PrimariaRegionHost(LitElement) {
34
35
  this.menuOpened = !this.menuOpened;
35
36
  }
36
37
 
38
+ logout() {
39
+ shellApi.broker.send(new ExitShell());
40
+ }
41
+
37
42
  connectedCallback() {
38
43
  super.connectedCallback();
39
44
  shellApi.broker.send(new GetUserInfo()).then((response: IUserInfo) => {
@@ -2,7 +2,7 @@ import { html } from "lit";
2
2
  import salutLogo from "../../../UI/images/Salut_Logotip.svg";
3
3
  import { ShellHeader } from "./shell-header";
4
4
  import { when } from "lit/directives/when.js";
5
- import {translate} from '../../../locales';
5
+ import { translate } from "../../../locales";
6
6
 
7
7
  export const template = (props: ShellHeader) => {
8
8
  const workCenterElements = [{ label: props.professional?.workCenter, value: "1" }];
@@ -21,7 +21,7 @@ export const template = (props: ShellHeader) => {
21
21
  <div id="header-actions-region-container"></div>
22
22
  ${when(
23
23
  props.professional,
24
- () => html`<dss-header-menu-professional slot="professional-menu" name="${props.professional.firstName} ${props.professional?.familyName} ${props.professional?.lastName}" center="${props.professional.workCenter}" collegiate="${props.professional.registrationNumber}">
24
+ () => html`<dss-header-menu-professional @onLogout=${props.logout} slot="professional-menu" name="${props.professional.firstName} ${props.professional?.familyName} ${props.professional?.lastName}" center="${props.professional.workCenter}" collegiate="${props.professional.registrationNumber}">
25
25
  <dss-avatar size="xl" name="${props.professional.firstName}" surname="${props.professional?.familyName}" slot="avatar"></dss-avatar>
26
26
  <dss-input-dropdown icon="maps_home_work" type="default" .elements=${workCenterElements} selectedvalue="[&quot;1&quot;]">
27
27
  <label slot="label" for="preferences1">${translate("header.workCenter")}</label>
package/src/api/api.ts CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  createRegionManager,
8
8
  } from "@uxland/harmonix";
9
9
  import { PrimariaRegionManager, createRegionManagerProxy } from "./region-manager/region-manager";
10
- import { createBroker } from "./broker/factory";
10
+ import { broker, createBroker } from "./broker/factory";
11
11
  import { PrimariaBroker } from "./broker/primaria-broker";
12
12
  import { PrimariaGlobalStateManager, createGlobalStateManager } from "./global-state/global-state";
13
13
  import { HttpClient, createHttpClient } from "./http-client/http-client";
@@ -18,9 +18,13 @@ import {
18
18
  import { createLocaleManager } from "./localization/localization";
19
19
  import { TokenManager, createTokenManager } from "./token-manager/token-manager";
20
20
  import { EcapEventManager, createEcapEventManager } from "./ecap-event-manager/ecap-event-manager";
21
+ import {
22
+ PluginBusyManager,
23
+ PluginBusyManagerImpl,
24
+ } from "./plugin-busy-manager/plugin-busy-manager";
21
25
 
22
- const broker = createBroker();
23
26
 
27
+ const broker = createBroker();
24
28
  export interface PrimariaApi extends HarmonixApi {
25
29
  httpClient: HttpClient;
26
30
  interactionManager: PrimariaInteractionManager;
@@ -29,12 +33,14 @@ export interface PrimariaApi extends HarmonixApi {
29
33
  globalStateManager: PrimariaGlobalStateManager;
30
34
  tokenManager: TokenManager;
31
35
  ecapEventManager: EcapEventManager;
36
+ pluginBusyManager: PluginBusyManager;
32
37
  }
33
38
 
34
39
  const regionManager: IRegionManager = createRegionManager("primaria");
35
40
  export const PrimariaRegionHost: any = createRegionHost(regionManager as any);
36
41
  const tokenManager = createTokenManager();
37
42
  const globalStateManager: PrimariaGlobalStateManager = createGlobalStateManager(broker);
43
+ const pluginBusyManager = new PluginBusyManagerImpl();
38
44
 
39
45
  /**
40
46
  * Factory function that creates a Primaria API instance.
@@ -48,13 +54,14 @@ export const primariaApiFactory: ApiFactory<PrimariaApi> = (
48
54
  return {
49
55
  pluginInfo: pluginInfo,
50
56
  regionManager: createRegionManagerProxy(pluginInfo, regionManager, broker),
51
- httpClient: createHttpClient(tokenManager),
57
+ httpClient: createHttpClient(tokenManager, broker),
52
58
  interactionManager: { ...createInteractionManager() },
53
59
  broker: broker,
54
60
  createLocaleManager: createLocaleManager(pluginInfo.pluginId) as any,
55
61
  globalStateManager,
56
62
  tokenManager,
57
63
  ecapEventManager: createEcapEventManager(),
64
+ pluginBusyManager,
58
65
  };
59
66
  };
60
67
 
@@ -154,4 +154,4 @@ const createDynamicMessageHandler = (handler: messageHandler, classPrefix: strin
154
154
  )(handler);
155
155
  };
156
156
 
157
- export const createBroker = (): PrimariaBroker => new Broker();
157
+ export const createBroker = (): PrimariaBroker => new Broker();
@@ -3,24 +3,32 @@ import AxiosMockAdapter from "axios-mock-adapter";
3
3
  import { Mock, beforeEach, describe, expect, it, vi } from "vitest";
4
4
  import { TokenManager, createTokenManager } from "../token-manager/token-manager";
5
5
  import { createAxiosInstance } from "./http-client";
6
+ import { shellEvents } from "../../events";
7
+ import { createBroker } from "../broker/factory";
6
8
 
7
9
  const access_token = 'eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJidFZxNnRMWGpmcXdzbm5MR2FXMXdhdU9McDNiTmY4bWZ3Rm1SZ0lBS2VJIn0.eyJleHAiOjE3Mzg2NjcxODIsImlhdCI6MTczODY2NjI4MiwianRpIjoiY2I0M2M2ZmItY2MyMS00M2Y2LTk5M2UtNDM3ZTJjNDU3YWMzIiwiaXNzIjoiaHR0cHM6Ly9wcmVwcm9kdWNjaW8ucGRzLmhlcy5jYXRzYWx1dC5nZW5jYXQuY2F0L2F1dGgvcmVhbG1zL0hFUyIsInN1YiI6Ijk1OGUyZWQ5LTJkNmUtNDZjOC1hOTE5LTU5MDQ0ZTYwMzVjMiIsInR5cCI6IkJlYXJlciIsImF6cCI6ImV0Yy1jY2YtcHJlIiwic2Vzc2lvbl9zdGF0ZSI6ImU3MzIzYWIyLTU3MDktNGY1ZS05ZGU4LWU1MzM3ZTBhOTMxNiIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLWhlcyIsIlJPTEVfSEVTX0VUQyIsIlJPTEVfSEVTX0xBTkRJTkciXX0sInNjb3BlIjoiIiwic2lkIjoiZTczMjNhYjItNTcwOS00ZjVlLTlkZTgtZTUzMzdlMGE5MzE2IiwiY2xpZW50SG9zdCI6IjEwLjUzLjI1NC4xNTAiLCJhY2Nlc3NfcnVsZXMiOnt9LCJhY2Nlc3NfaW5mbyI6eyJtb2R1bGVfY29kZSI6IkEwMDEiLCJyb2xlX3R5cGUiOiJOT1JNIiwidHJhY2VfdXNlcl9pZCI6IlVzZXJfSUQiLCJjZW50ZXJfdHlwZSI6IkUiLCJ1cF9jb2RlIjoiMDc3MzMiLCJ0cmFjZV91c2VyX2dpdmVuX25hbWUiOiJHaXZlbiBOYW1lIiwidHJhY2VfdXNlcl9mYW1pbHlfbmFtZSI6IkZhbWlseSBOYW1lIiwidXNlcl90eXBlIjoiQURNIiwiY2VudGVyX2NvZGUiOiJFMDg1ODY5NjMiLCJwcm9mZXNzaW9uYWxfY2F0ZWdvcnkiOiIzMDkzNDMwMDYiLCJzZXJ2aWNlX2NvZGUiOiI1UzA4OSIsImVwX2NvZGUiOiIwMjA4IiwiaWRlbnRpZmllciI6W3sidHlwZSI6IkROSSIsInZhbHVlIjoiNzMyODgyMTlBIn0seyJ0eXBlIjoiTlVNQ09MIiwidmFsdWUiOiIyIn1dLCJhbHRfaWRlbnRpZmllciI6W3sidHlwZSI6Ik1QSSIsInZhbHVlIjoiMDYyMWNmN2QtN2Q2My00OWVjLTgwMDYtOGMwNTY5MmVkMzc3In1dfSwiY2xpZW50QWRkcmVzcyI6IjEwLjUzLjI1NC4xNTAiLCJjbGllbnRfaWQiOiJldGMtY2NmLXByZSJ9.WYF6VvIVqzW71MdOcvRJnKNBEe8BoD43Ql_hyGyqBC1wbNDNcbqucX-2wPbSOpHaHv5iogYNTVp1eEkHvrnryQ4koHXf4U3inTxoZR94qAzIt8XGgBVxpYlArc-XrFX1FAwkdfsNmYE_L6G7q5wfzaP0y1YrFH6u9TPTBl1w2us8O8xKPB6B652NUphNHFWmPWv6t6Zq97sjHPIHMZsDeBdolK5RlG5J3u8K-quJeKLByZhA2kYAJMGyCzR6jLLrup5w-WdYNJRyGopeFSDVp-lECmaiYIXmhQOJzzJQqhARrwYN8ZxqTOyD5u24HOB7Q1ZCMnAp4vAL6OphWyRZuw';
8
10
  const refresh_token = 'eyJhbGciOiJIUzUxMiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIwMjUzZGM1MC1hY2FmLTQ5ZDctYTYzNi0xN2NkMTlmOWEwOTAifQ.eyJleHAiOjE3Mzg2NjgwODIsImlhdCI6MTczODY2NjI4MiwianRpIjoiZWM5OGE2OWMtMDJkNS00Yjc0LWIwZWYtNzcwMGU4OTc3YWY1IiwiaXNzIjoiaHR0cHM6Ly9wcmVwcm9kdWNjaW8ucGRzLmhlcy5jYXRzYWx1dC5nZW5jYXQuY2F0L2F1dGgvcmVhbG1zL0hFUyIsImF1ZCI6Imh0dHBzOi8vcHJlcHJvZHVjY2lvLnBkcy5oZXMuY2F0c2FsdXQuZ2VuY2F0LmNhdC9hdXRoL3JlYWxtcy9IRVMiLCJzdWIiOiI5NThlMmVkOS0yZDZlLTQ2YzgtYTkxOS01OTA0NGU2MDM1YzIiLCJ0eXAiOiJSZWZyZXNoIiwiYXpwIjoiZXRjLWNjZi1wcmUiLCJzZXNzaW9uX3N0YXRlIjoiZTczMjNhYjItNTcwOS00ZjVlLTlkZTgtZTUzMzdlMGE5MzE2Iiwic2NvcGUiOiIiLCJzaWQiOiJlNzMyM2FiMi01NzA5LTRmNWUtOWRlOC1lNTMzN2UwYTkzMTYifQ.KOO0Ulbed4640-obEr3Xg8qavGeXhU25o6ZUfsq0SoQpzMjhcx8GTgOH-PiIR88ksrjtTnpbmzw2D29xuugv4A';
9
11
 
10
12
 
11
13
  describe("HTTP Client", () => {
12
- vi.spyOn(window, 'location', 'get').mockReturnValue({
13
- search: `?access_token=${access_token}&refresh_token=${refresh_token}`
14
- } as unknown as Location);
14
+
15
+ let broker = createBroker();
15
16
  let tokenManager: TokenManager;
16
17
  let axiosInstance: AxiosInstance;
17
18
  let axiosMockInstance: AxiosMockAdapter;
19
+
18
20
  beforeEach(() => {
21
+ vi.restoreAllMocks(); // Reset all spies before each test
22
+ vi.spyOn(window, 'location', 'get').mockReturnValue({
23
+ search: `?access_token=${access_token}&refresh_token=${refresh_token}`
24
+ } as unknown as Location);
25
+
19
26
  tokenManager = createTokenManager();
20
- axiosInstance = createAxiosInstance(tokenManager);
27
+ axiosInstance = createAxiosInstance(tokenManager, broker);
21
28
  axiosMockInstance = new AxiosMockAdapter(axiosInstance);
22
29
  axiosMockInstance.reset();
23
30
  });
31
+
24
32
  it("should make a request with header", async () => {
25
33
  axiosMockInstance.onGet("/api/clinical-course").reply(200, "success");
26
34
  // Perform the request
@@ -34,22 +42,68 @@ describe("HTTP Client", () => {
34
42
  `Bearer ${access_token}`,
35
43
  );
36
44
  });
37
- it("should retry request after token refresh", async () => {
45
+
46
+ it("should retry request with new token if failed with 401 after token refresh, and requests after that have new token", async () => {
47
+
38
48
  axiosMockInstance
39
49
  .onGet("/api/clinical-course")
40
50
  .replyOnce(401, "Unauthorized")
41
51
  .onGet("/api/clinical-course")
52
+ .replyOnce(200, "success")
53
+ .onGet("/api/clinical-course/2")
42
54
  .replyOnce(200, "success");
55
+
56
+ vi.spyOn(axios, "post").mockResolvedValueOnce({
57
+ data: {
58
+ access_token: "new-auth-token",
59
+ refresh_token: "new-refresh-token"
60
+ }
61
+ });
62
+
43
63
  // Perform the request
44
64
  const response = await axiosInstance.get("/api/clinical-course");
65
+ const secondResponse = await axiosInstance.get("/api/clinical-course/2");
45
66
 
46
67
  console.log("response", response.status);
47
68
  // Assertions
48
69
  expect(response.status).toBe(200);
49
70
  expect(response.data).toBe("success");
50
- expect(axiosMockInstance.history.get?.length).toBe(2);
71
+ expect(axiosMockInstance.history.get?.length).toBe(3); // 3 Calls 2 for the first request (request and retry), 1 for the second request
51
72
  expect(axiosMockInstance.history.get?.[1]?.headers?.Authorization).toBe(
52
73
  "Bearer new-auth-token",
53
74
  );
75
+ expect(axiosMockInstance.history.get?.[2]?.headers?.Authorization).toBe(
76
+ "Bearer new-auth-token",
77
+ );
78
+
79
+ });
80
+
81
+ it("should fail request if token refresh fails and publish an event", async () => {
82
+ vi.spyOn(axios, "post").mockRejectedValueOnce({
83
+ response: { status: 400, statusText: "Bad Request" },
84
+ });
85
+ const brokerSpy = vi.spyOn(broker, "publish")
86
+ axiosMockInstance.onGet("/api/clinical-course").replyOnce(401, "Unauthorized");
87
+
88
+ await expect(axiosInstance.get("/api/clinical-course")).rejects.toThrow("Request failed with status code 401");
89
+
90
+ expect(axiosMockInstance.history.get?.length).toBe(1); // No retry happened
91
+ expect(brokerSpy).toHaveBeenCalledWith(shellEvents.refreshTokenFailed, expect.any(Object));
92
+ expect(brokerSpy).toHaveBeenCalledWith(shellEvents.refreshTokenFailed, {
93
+ request: expect.objectContaining({ url: "/api/clinical-course" }),
94
+ });
95
+ });
96
+
97
+ it("should fail request with error != 401 and should not retry", async () => {
98
+ const refreshTokenSpy = vi.spyOn(tokenManager, "refreshToken");
99
+ const brokerSpy = vi.spyOn(broker, "publish");
100
+ axiosMockInstance.onGet("/api/clinical-course").replyOnce(500, "Internal Server Error");
101
+ await expect(axiosInstance.get("/api/clinical-course")).rejects.toMatchObject({
102
+ response: { status: 500 },
103
+ });
104
+ expect(axiosMockInstance.history.get?.length).toBe(1);
105
+ expect(refreshTokenSpy).not.toHaveBeenCalled();
106
+ expect(brokerSpy).not.toHaveBeenCalled();
54
107
  });
108
+
55
109
  });