@equinor/fusion-framework-react-components-people-provider 2.0.0-next.0 → 2.0.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.
@@ -2,6 +2,8 @@ import { type Observable } from 'rxjs';
2
2
  import type { ApiPerson, PeopleApiClient } from '@equinor/fusion-framework-module-services/people';
3
3
  import type { ApiResponse as GetPersonApiResponse } from '@equinor/fusion-framework-module-services/people/get';
4
4
  import type { ApiResponse as QueryPersonApiResponse } from '@equinor/fusion-framework-module-services/people/query';
5
+ import type { ApiResponse as SuggestPersonApiResponse } from '@equinor/fusion-framework-module-services/people/suggest';
6
+ import type { ApiResponse as ResolvePersonApiResponse } from '@equinor/fusion-framework-module-services/people/resolve';
5
7
  type GetPersonResult = GetPersonApiResponse<'v4', {
6
8
  azureId: '';
7
9
  expand: ['positions', 'manager'];
@@ -28,6 +30,13 @@ export interface IPersonController {
28
30
  search(args: ResolverArgs<{
29
31
  search: string;
30
32
  }>): Observable<PersonSearchResult>;
33
+ suggest(args: ResolverArgs<{
34
+ search: string;
35
+ systemAccounts: boolean;
36
+ }>): Observable<SuggestPersonApiResponse>;
37
+ resolve(args: ResolverArgs<{
38
+ resolveIds: string[];
39
+ }>): Observable<ResolvePersonApiResponse>;
31
40
  }
32
41
  export type PersonControllerOptions = {
33
42
  fallbackImage?: Blob;
@@ -35,6 +44,21 @@ export type PersonControllerOptions = {
35
44
  export declare class PersonController implements IPersonController {
36
45
  #private;
37
46
  constructor(client: PeopleApiClient, options?: PersonControllerOptions);
47
+ /**
48
+ * Suggest persons matching the given search string.
49
+ * Search string can be a part of display name, mail, upn or the full azureId.
50
+ * If systemAccounts is true, it will also include system accounts in the result.
51
+ */
52
+ suggest(args: ResolverArgs<{
53
+ search: string;
54
+ systemAccounts: boolean;
55
+ }>): Observable<SuggestPersonApiResponse>;
56
+ /**
57
+ * Resolve person details for given identifiers, which can be a mix of azureIds and upns.
58
+ */
59
+ resolve(args: ResolverArgs<{
60
+ resolveIds: string[];
61
+ }>): Observable<ResolvePersonApiResponse>;
38
62
  search(args: {
39
63
  search: string;
40
64
  signal?: AbortSignal;
@@ -1 +1 @@
1
- export declare const version = "2.0.0-next.0";
1
+ export declare const version = "2.0.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@equinor/fusion-framework-react-components-people-provider",
3
- "version": "2.0.0-next.0",
3
+ "version": "2.0.0",
4
4
  "description": "",
5
5
  "main": "dist/esm/index.js",
6
6
  "exports": {
@@ -19,23 +19,23 @@
19
19
  "repository": {
20
20
  "type": "git",
21
21
  "url": "git+https://github.com/equinor/fusion-framework.git",
22
- "directory": "packages/react/components/people-provider"
22
+ "directory": "packages/react/components/people-resolver"
23
23
  },
24
24
  "dependencies": {
25
25
  "rxjs": "^7.8.1",
26
- "@equinor/fusion-framework-module-services": "^7.1.6-next.0",
27
- "@equinor/fusion-framework-react": "^8.0.0-next.0",
28
- "@equinor/fusion-query": "^7.0.0-next.0",
29
- "@equinor/fusion-framework-react-module": "^4.0.0-next.0"
26
+ "@equinor/fusion-framework-module-services": "^8.0.0",
27
+ "@equinor/fusion-framework-react": "^8.0.0",
28
+ "@equinor/fusion-query": "^7.0.0",
29
+ "@equinor/fusion-framework-react-module": "^4.0.0"
30
30
  },
31
31
  "devDependencies": {
32
- "@equinor/fusion-wc-person": "^3.2.4",
32
+ "@equinor/fusion-wc-person": "^3.4.0",
33
33
  "@types/react": "^19.2.7",
34
34
  "react": "^19.2.1",
35
- "typescript": "^5.8.2",
36
- "@equinor/fusion-framework-module-app": "^7.2.0-next.0",
37
- "@equinor/fusion-framework-module-event": "^4.4.1-next.0",
38
- "@equinor/fusion-framework-module-bookmark": "^3.0.5-next.0"
35
+ "typescript": "^5.9.3",
36
+ "@equinor/fusion-framework-module-app": "^8.0.0",
37
+ "@equinor/fusion-framework-module-bookmark": "^4.0.0",
38
+ "@equinor/fusion-framework-module-event": "^6.0.0"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "@types/react": "^18.0.0 || ^19.0.0",
@@ -5,6 +5,8 @@ import type { ApiPerson, PeopleApiClient } from '@equinor/fusion-framework-modul
5
5
  import { isApiPerson } from '@equinor/fusion-framework-module-services/people/utils';
6
6
  import type { ApiResponse as GetPersonApiResponse } from '@equinor/fusion-framework-module-services/people/get';
7
7
  import type { ApiResponse as QueryPersonApiResponse } from '@equinor/fusion-framework-module-services/people/query';
8
+ import type { ApiResponse as SuggestPersonApiResponse } from '@equinor/fusion-framework-module-services/people/suggest';
9
+ import type { ApiResponse as ResolvePersonApiResponse } from '@equinor/fusion-framework-module-services/people/resolve';
8
10
  import { Query } from '@equinor/fusion-query';
9
11
  import { queryValue } from '@equinor/fusion-query/operators';
10
12
 
@@ -45,6 +47,10 @@ export interface IPersonController {
45
47
  getPersonInfo(args: ResolverArgs<MatcherArgs>): Observable<ApiPerson<'v2'>>;
46
48
  getPhoto(args: ResolverArgs<MatcherArgs>): Observable<string>;
47
49
  search(args: ResolverArgs<{ search: string }>): Observable<PersonSearchResult>;
50
+ suggest(
51
+ args: ResolverArgs<{ search: string; systemAccounts: boolean }>,
52
+ ): Observable<SuggestPersonApiResponse>;
53
+ resolve(args: ResolverArgs<{ resolveIds: string[] }>): Observable<ResolvePersonApiResponse>;
48
54
  }
49
55
 
50
56
  export type PersonControllerOptions = {
@@ -55,6 +61,11 @@ export class PersonController implements IPersonController {
55
61
  #personQuery: Query<GetPersonResult, ResolverArgs<{ azureId: string }>>;
56
62
  #personSearchQuery: Query<PersonSearchResult, ResolverArgs<{ search: string }>>;
57
63
  #personPhotoQuery: Query<Blob, ResolverArgs<{ azureId: string }>>;
64
+ #personSuggestQuery: Query<
65
+ SuggestPersonApiResponse,
66
+ ResolverArgs<{ search: string; systemAccounts: boolean }>
67
+ >;
68
+ #personResolveQuery: Query<ResolvePersonApiResponse, ResolverArgs<{ resolveIds: string[] }>>;
58
69
 
59
70
  constructor(client: PeopleApiClient, options?: PersonControllerOptions) {
60
71
  const expire = 3 * 60 * 1000;
@@ -112,6 +123,60 @@ export class PersonController implements IPersonController {
112
123
  },
113
124
  },
114
125
  });
126
+ this.#personSuggestQuery = new Query({
127
+ expire,
128
+ queueOperator: 'merge',
129
+ key: ({ search, systemAccounts }) => `${search}-${systemAccounts}`,
130
+ client: {
131
+ fn: ({ search, systemAccounts }, signal) => {
132
+ const types = ['Person'];
133
+ if (systemAccounts) {
134
+ types.push('SystemAccount');
135
+ }
136
+ return client.suggest('json$', {
137
+ method: 'POST',
138
+ body: JSON.stringify({ queryString: search, types }),
139
+ signal,
140
+ });
141
+ },
142
+ },
143
+ });
144
+ this.#personResolveQuery = new Query({
145
+ expire,
146
+ queueOperator: 'merge',
147
+ key: ({ resolveIds }) => JSON.stringify([...resolveIds].sort()),
148
+ client: {
149
+ fn: ({ resolveIds }, signal) => {
150
+ return client.resolve('json$', {
151
+ method: 'POST',
152
+ body: JSON.stringify({ identifiers: resolveIds }),
153
+ signal,
154
+ });
155
+ },
156
+ },
157
+ });
158
+ }
159
+
160
+ /**
161
+ * Suggest persons matching the given search string.
162
+ * Search string can be a part of display name, mail, upn or the full azureId.
163
+ * If systemAccounts is true, it will also include system accounts in the result.
164
+ */
165
+ public suggest(
166
+ args: ResolverArgs<{ search: string; systemAccounts: boolean }>,
167
+ ): Observable<SuggestPersonApiResponse> {
168
+ const { search, systemAccounts, signal } = args;
169
+ return this.#personSuggestQuery.query({ search, systemAccounts }, { signal }).pipe(queryValue);
170
+ }
171
+
172
+ /**
173
+ * Resolve person details for given identifiers, which can be a mix of azureIds and upns.
174
+ */
175
+ public resolve(
176
+ args: ResolverArgs<{ resolveIds: string[] }>,
177
+ ): Observable<ResolvePersonApiResponse> {
178
+ const { resolveIds, signal } = args;
179
+ return this.#personResolveQuery.query({ resolveIds }, { signal }).pipe(queryValue);
115
180
  }
116
181
 
117
182
  public search(args: { search: string; signal?: AbortSignal }): Observable<PersonSearchResult> {
@@ -198,18 +263,12 @@ export class PersonController implements IPersonController {
198
263
  /** type cast and end stream */
199
264
  find(isApiPerson('v2')),
200
265
  ),
201
- ).pipe(
202
- /** */
203
- find(isApiPerson('v2')),
204
- filter(isApiPerson('v2')),
205
- filter(isApiPerson('v2')),
206
- takeUntil(abort$),
207
- );
266
+ ).pipe(find(isApiPerson('v2')), filter(isApiPerson('v2')), takeUntil(abort$));
208
267
  }
209
268
 
210
269
  protected _getPersonPhotoByAzureId(azureId: string, signal?: AbortSignal): Observable<string> {
211
270
  return this.#personPhotoQuery.query({ azureId }, { signal }).pipe(
212
- /** */
271
+ /** make subscription cold */
213
272
  take(1),
214
273
  map((result) => URL.createObjectURL(result.value)),
215
274
  );
@@ -217,7 +276,7 @@ export class PersonController implements IPersonController {
217
276
 
218
277
  protected _getPersonPhotoByUpn(upn: string, signal?: AbortSignal) {
219
278
  return this._getPersonInfoByUpn(upn, signal).pipe(
220
- /** */
279
+ /** make subscription cold */
221
280
  take(1),
222
281
  switchMap((x) => this._getPersonPhotoByAzureId(x.azureUniqueId, signal)),
223
282
  );
@@ -32,16 +32,18 @@ export const createResolver = (controller: IPersonController): PersonResolver =>
32
32
  ({
33
33
  ...x,
34
34
  azureId: x.azureUniqueId,
35
- // TODO
36
- // @asbjornhaland
37
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
38
- // @ts-ignore https://github.com/equinor/fusion-web-components/issues/804
39
35
  }) as unknown as PersonInfo,
40
36
  ),
41
37
  ),
42
38
  ),
43
39
  );
44
40
  },
41
+ suggest(args) {
42
+ return firstValueFrom(controller.suggest(args));
43
+ },
44
+ resolve(args) {
45
+ return firstValueFrom(controller.resolve(args));
46
+ },
45
47
  });
46
48
 
47
49
  export default createResolver;
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated by genversion.
2
- export const version = '2.0.0-next.0';
2
+ export const version = '2.0.0';