@equinor/fusion-framework-react-components-people-provider 0.0.0-context-error-20240131144633
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.
- package/CHANGELOG.md +201 -0
- package/LICENSE +21 -0
- package/README.md +35 -0
- package/dist/esm/PeopleResolver.js +19 -0
- package/dist/esm/PeopleResolver.js.map +1 -0
- package/dist/esm/PeopleResolverProvider.js +15 -0
- package/dist/esm/PeopleResolverProvider.js.map +1 -0
- package/dist/esm/PersonController.js +146 -0
- package/dist/esm/PersonController.js.map +1 -0
- package/dist/esm/create-resolver.js +17 -0
- package/dist/esm/create-resolver.js.map +1 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/makeResolver.js +26 -0
- package/dist/esm/makeResolver.js.map +1 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/version.js +2 -0
- package/dist/esm/version.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/PeopleResolver.d.ts +5 -0
- package/dist/types/PeopleResolverProvider.d.ts +7 -0
- package/dist/types/PersonController.d.ts +54 -0
- package/dist/types/create-resolver.d.ts +4 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/makeResolver.d.ts +6 -0
- package/dist/types/types.d.ts +5 -0
- package/dist/types/version.d.ts +1 -0
- package/package.json +50 -0
- package/src/PeopleResolver.tsx +31 -0
- package/src/PeopleResolverProvider.tsx +25 -0
- package/src/PersonController.ts +248 -0
- package/src/create-resolver.ts +47 -0
- package/src/index.ts +1 -0
- package/src/makeResolver.tsx +19 -0
- package/src/types.ts +6 -0
- package/src/version.ts +2 -0
- package/tsconfig.json +23 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
2
|
+
import type { ApiPerson, PeopleApiClient } from '@equinor/fusion-framework-module-services/people';
|
|
3
|
+
import type { ApiResponse as GetPersonApiResponse } from '@equinor/fusion-framework-module-services/people/get';
|
|
4
|
+
import type { ApiResponse as QueryPersonApiResponse } from '@equinor/fusion-framework-module-services/people/query';
|
|
5
|
+
type GetPersonResult = GetPersonApiResponse<'v4', {
|
|
6
|
+
azureId: '';
|
|
7
|
+
expand: ['positions', 'manager'];
|
|
8
|
+
}>;
|
|
9
|
+
type PersonSearchResult = QueryPersonApiResponse<'v2'>;
|
|
10
|
+
type MatcherArgs = {
|
|
11
|
+
upn: string;
|
|
12
|
+
azureId?: string;
|
|
13
|
+
} | {
|
|
14
|
+
upn?: string;
|
|
15
|
+
azureId: string;
|
|
16
|
+
};
|
|
17
|
+
type ResolverArgs<T> = T extends object ? {
|
|
18
|
+
[K in keyof T]: T[K];
|
|
19
|
+
} & {
|
|
20
|
+
signal?: AbortSignal;
|
|
21
|
+
} : {
|
|
22
|
+
signal?: AbortSignal;
|
|
23
|
+
};
|
|
24
|
+
export interface IPersonController {
|
|
25
|
+
getPerson(args: ResolverArgs<MatcherArgs>): Observable<GetPersonResult>;
|
|
26
|
+
getPersonInfo(args: ResolverArgs<MatcherArgs>): Observable<ApiPerson<'v2'>>;
|
|
27
|
+
getPhoto(args: ResolverArgs<MatcherArgs>): Observable<string>;
|
|
28
|
+
search(args: ResolverArgs<{
|
|
29
|
+
search: string;
|
|
30
|
+
}>): Observable<PersonSearchResult>;
|
|
31
|
+
}
|
|
32
|
+
export type PersonControllerOptions = {
|
|
33
|
+
fallbackImage?: Blob;
|
|
34
|
+
};
|
|
35
|
+
export declare class PersonController implements IPersonController {
|
|
36
|
+
#private;
|
|
37
|
+
constructor(client: PeopleApiClient, options?: PersonControllerOptions);
|
|
38
|
+
search(args: {
|
|
39
|
+
search: string;
|
|
40
|
+
signal?: AbortSignal;
|
|
41
|
+
}): Observable<PersonSearchResult>;
|
|
42
|
+
getPhoto(args: ResolverArgs<MatcherArgs>): Observable<string>;
|
|
43
|
+
getPerson(args: ResolverArgs<MatcherArgs>): Observable<GetPersonResult>;
|
|
44
|
+
getPersonInfo(args: ResolverArgs<MatcherArgs>): Observable<ApiPerson<'v2'>>;
|
|
45
|
+
protected _getPersonByUpn(upn: string, signal?: AbortSignal): Observable<GetPersonResult>;
|
|
46
|
+
_getPersonByAzureId(azureId: string, signal?: AbortSignal): Observable<GetPersonResult>;
|
|
47
|
+
protected _getPersonInfoById(azureId: string, signal?: AbortSignal): Observable<ApiPerson<'v2'>>;
|
|
48
|
+
protected _getPersonInfoByUpn(upn: string, signal?: AbortSignal): Observable<ApiPerson<'v2'>>;
|
|
49
|
+
protected _getPersonPhotoByAzureId(azureId: string, signal?: AbortSignal): Observable<string>;
|
|
50
|
+
protected _getPersonPhotoByUpn(upn: string, signal?: AbortSignal): Observable<string>;
|
|
51
|
+
protected _personCache$(args: MatcherArgs): Observable<GetPersonResult>;
|
|
52
|
+
protected _queryCache$(args: MatcherArgs): Observable<ApiPerson<'v2'>>;
|
|
53
|
+
}
|
|
54
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { PeopleResolverProvider, default } from './PeopleResolverProvider';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { PersonControllerOptions } from './PersonController';
|
|
3
|
+
import { IApiProvider } from '@equinor/fusion-framework-module-services';
|
|
4
|
+
export declare const makeResolver: (services: IApiProvider, options?: PersonControllerOptions) => import("react").LazyExoticComponent<({ children }: {
|
|
5
|
+
readonly children?: React.ReactNode;
|
|
6
|
+
}) => import("react/jsx-runtime").JSX.Element>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const version = "1.1.12";
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@equinor/fusion-framework-react-components-people-provider",
|
|
3
|
+
"version": "0.0.0-context-error-20240131144633",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "dist/esm/index.js",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": "./dist/esm/index.js"
|
|
8
|
+
},
|
|
9
|
+
"types": "./dist/types/index.d.ts",
|
|
10
|
+
"keywords": [],
|
|
11
|
+
"author": "",
|
|
12
|
+
"license": "ISC",
|
|
13
|
+
"publishConfig": {
|
|
14
|
+
"access": "public"
|
|
15
|
+
},
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/equinor/fusion-framework.git",
|
|
19
|
+
"directory": "packages/react/components/people-provider"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"rxjs": "^7.8.1",
|
|
23
|
+
"@equinor/fusion-framework-module-services": "^3.2.3",
|
|
24
|
+
"@equinor/fusion-framework-react": "^0.0.0-context-error-20240131144633",
|
|
25
|
+
"@equinor/fusion-framework-react-module": "^3.0.7",
|
|
26
|
+
"@equinor/fusion-framework-react-module-bookmark": "^0.0.0-context-error-20240131144633",
|
|
27
|
+
"@equinor/fusion-query": "^4.0.5"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@equinor/fusion-wc-person": "^2.2.0",
|
|
31
|
+
"@types/react": "^18.2.20",
|
|
32
|
+
"react": "^18.2.0",
|
|
33
|
+
"typescript": "^5.1.3",
|
|
34
|
+
"@equinor/fusion-framework-module-app": "^5.2.12",
|
|
35
|
+
"@equinor/fusion-framework-module-bookmark": "^1.1.0",
|
|
36
|
+
"@equinor/fusion-framework-module-event": "^4.0.7"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"@types/react": "^17.0.0 || ^18.0.0",
|
|
40
|
+
"react": "^17.0.0 || ^18.0.0"
|
|
41
|
+
},
|
|
42
|
+
"peerDependenciesMeta": {
|
|
43
|
+
"@types/react": {
|
|
44
|
+
"optional": true
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "tsc -b"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
PersonProviderElement,
|
|
5
|
+
PersonAvatarElement,
|
|
6
|
+
PersonCardElement,
|
|
7
|
+
PersonResolver,
|
|
8
|
+
PersonListItemElement,
|
|
9
|
+
PersonSelectElement,
|
|
10
|
+
} from '@equinor/fusion-wc-person';
|
|
11
|
+
|
|
12
|
+
PersonProviderElement;
|
|
13
|
+
PersonAvatarElement;
|
|
14
|
+
PersonCardElement;
|
|
15
|
+
PersonListItemElement;
|
|
16
|
+
PersonSelectElement;
|
|
17
|
+
|
|
18
|
+
export { PersonResolver };
|
|
19
|
+
|
|
20
|
+
export const PeopleResolverComponent = (
|
|
21
|
+
props: React.PropsWithChildren<{ resolver: PersonResolver }>,
|
|
22
|
+
) => {
|
|
23
|
+
const { resolver, children } = props;
|
|
24
|
+
const ref = useRef<PersonProviderElement | null>(null);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (ref.current && resolver) {
|
|
27
|
+
ref.current.resolver = resolver;
|
|
28
|
+
}
|
|
29
|
+
}, [ref, resolver]);
|
|
30
|
+
return <fwc-person-provider ref={ref}>{children}</fwc-person-provider>;
|
|
31
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { PropsWithChildren, Suspense, useMemo } from 'react';
|
|
2
|
+
import { ServicesModule } from '@equinor/fusion-framework-module-services';
|
|
3
|
+
import { useModule } from '@equinor/fusion-framework-react-module';
|
|
4
|
+
import { makeResolver } from './makeResolver';
|
|
5
|
+
import { PersonControllerOptions } from './PersonController';
|
|
6
|
+
|
|
7
|
+
type PeopleResolverProviderProps = PropsWithChildren<{
|
|
8
|
+
readonly options?: PersonControllerOptions;
|
|
9
|
+
}>;
|
|
10
|
+
|
|
11
|
+
export const PeopleResolverProvider = (props: PeopleResolverProviderProps) => {
|
|
12
|
+
const { children, options } = props;
|
|
13
|
+
const services = useModule<ServicesModule>('services');
|
|
14
|
+
if (!services) {
|
|
15
|
+
throw Error('missing service module');
|
|
16
|
+
}
|
|
17
|
+
const Component = useMemo(() => makeResolver(services, options), [services, options]);
|
|
18
|
+
return (
|
|
19
|
+
<Suspense fallback={<span>TODO</span>}>
|
|
20
|
+
<Component>{children}</Component>
|
|
21
|
+
</Suspense>
|
|
22
|
+
);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default PeopleResolverProvider;
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { EMPTY, Observable, concat, from, fromEvent, of } from 'rxjs';
|
|
2
|
+
import { catchError, filter, find, map, switchMap, take, takeUntil } from 'rxjs/operators';
|
|
3
|
+
|
|
4
|
+
import type { ApiPerson, PeopleApiClient } from '@equinor/fusion-framework-module-services/people';
|
|
5
|
+
import { isApiPerson } from '@equinor/fusion-framework-module-services/people/utils';
|
|
6
|
+
import type { ApiResponse as GetPersonApiResponse } from '@equinor/fusion-framework-module-services/people/get';
|
|
7
|
+
import type { ApiResponse as QueryPersonApiResponse } from '@equinor/fusion-framework-module-services/people/query';
|
|
8
|
+
import { Query } from '@equinor/fusion-query';
|
|
9
|
+
import { queryValue } from '@equinor/fusion-query/operators';
|
|
10
|
+
|
|
11
|
+
import { ApiProviderError } from '@equinor/fusion-framework-module-services/provider';
|
|
12
|
+
|
|
13
|
+
type GetPersonResult = GetPersonApiResponse<
|
|
14
|
+
'v4',
|
|
15
|
+
{ azureId: ''; expand: ['positions', 'manager'] }
|
|
16
|
+
>;
|
|
17
|
+
|
|
18
|
+
type PersonSearchResult = QueryPersonApiResponse<'v2'>;
|
|
19
|
+
|
|
20
|
+
type MatcherArgs = { upn: string; azureId?: string } | { upn?: string; azureId: string };
|
|
21
|
+
|
|
22
|
+
type ResolverArgs<T> = T extends object
|
|
23
|
+
? { [K in keyof T]: T[K] } & { signal?: AbortSignal }
|
|
24
|
+
: { signal?: AbortSignal };
|
|
25
|
+
|
|
26
|
+
const personMatcher =
|
|
27
|
+
(args: MatcherArgs) =>
|
|
28
|
+
<T extends { azureUniqueId?: string; upn?: string }>(value: T): value is T => {
|
|
29
|
+
const { azureId, upn } = args;
|
|
30
|
+
if (azureId && upn) {
|
|
31
|
+
return (
|
|
32
|
+
value.upn?.toLocaleLowerCase() === upn.toLocaleLowerCase() &&
|
|
33
|
+
value.azureUniqueId === azureId
|
|
34
|
+
);
|
|
35
|
+
} else if (azureId) {
|
|
36
|
+
return value.azureUniqueId === azureId;
|
|
37
|
+
} else if (upn) {
|
|
38
|
+
return value.upn?.toLocaleLowerCase() === upn.toLocaleLowerCase();
|
|
39
|
+
}
|
|
40
|
+
return false;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export interface IPersonController {
|
|
44
|
+
getPerson(args: ResolverArgs<MatcherArgs>): Observable<GetPersonResult>;
|
|
45
|
+
getPersonInfo(args: ResolverArgs<MatcherArgs>): Observable<ApiPerson<'v2'>>;
|
|
46
|
+
getPhoto(args: ResolverArgs<MatcherArgs>): Observable<string>;
|
|
47
|
+
search(args: ResolverArgs<{ search: string }>): Observable<PersonSearchResult>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export type PersonControllerOptions = {
|
|
51
|
+
fallbackImage?: Blob;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export class PersonController implements IPersonController {
|
|
55
|
+
#personQuery: Query<GetPersonResult, ResolverArgs<{ azureId: string }>>;
|
|
56
|
+
#personSearchQuery: Query<PersonSearchResult, ResolverArgs<{ search: string }>>;
|
|
57
|
+
#personPhotoQuery: Query<Blob, ResolverArgs<{ azureId: string }>>;
|
|
58
|
+
|
|
59
|
+
constructor(client: PeopleApiClient, options?: PersonControllerOptions) {
|
|
60
|
+
const expire = 3 * 60 * 1000;
|
|
61
|
+
this.#personQuery = new Query({
|
|
62
|
+
expire,
|
|
63
|
+
queueOperator: 'merge',
|
|
64
|
+
key: ({ azureId }) => azureId,
|
|
65
|
+
client: {
|
|
66
|
+
fn: ({ azureId }, signal): Observable<GetPersonResult> => {
|
|
67
|
+
return client.get(
|
|
68
|
+
'v4',
|
|
69
|
+
'json$',
|
|
70
|
+
{ azureId, expand: ['manager', 'positions'] },
|
|
71
|
+
{ signal },
|
|
72
|
+
);
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
this.#personSearchQuery = new Query({
|
|
77
|
+
expire,
|
|
78
|
+
queueOperator: 'merge',
|
|
79
|
+
key: ({ search }) => search,
|
|
80
|
+
client: {
|
|
81
|
+
fn: ({ search }, signal) => {
|
|
82
|
+
return client.query('v2', 'json$', { search }, { signal });
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
this.#personPhotoQuery = new Query({
|
|
87
|
+
expire,
|
|
88
|
+
queueOperator: 'merge',
|
|
89
|
+
key: ({ azureId }) => azureId,
|
|
90
|
+
client: {
|
|
91
|
+
fn: ({ azureId }, signal) => {
|
|
92
|
+
return client.photo('v2', 'blob$', { azureId }, { signal }).pipe(
|
|
93
|
+
catchError((err) => {
|
|
94
|
+
const apiError = err as ApiProviderError;
|
|
95
|
+
if (apiError.response.status === 404 && options?.fallbackImage) {
|
|
96
|
+
return of(options?.fallbackImage);
|
|
97
|
+
}
|
|
98
|
+
return of(err);
|
|
99
|
+
}),
|
|
100
|
+
);
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
public search(args: { search: string; signal?: AbortSignal }): Observable<PersonSearchResult> {
|
|
107
|
+
const { search, signal } = args;
|
|
108
|
+
return this.#personSearchQuery.query({ search }, { signal }).pipe(queryValue);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** TODO why does this need to have data?!? */
|
|
112
|
+
public getPhoto(args: ResolverArgs<MatcherArgs>): Observable<string> {
|
|
113
|
+
const { azureId, upn, signal } = args;
|
|
114
|
+
|
|
115
|
+
if (azureId) {
|
|
116
|
+
return this._getPersonPhotoByAzureId(azureId, signal);
|
|
117
|
+
} else if (upn) {
|
|
118
|
+
return this._getPersonPhotoByUpn(upn, signal);
|
|
119
|
+
}
|
|
120
|
+
throw Error('invalid args provided');
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
public getPerson(args: ResolverArgs<MatcherArgs>): Observable<GetPersonResult> {
|
|
124
|
+
const { azureId, upn, signal } = args;
|
|
125
|
+
if (azureId) {
|
|
126
|
+
return this._getPersonByAzureId(azureId, signal);
|
|
127
|
+
} else if (upn) {
|
|
128
|
+
return this._getPersonByUpn(upn, signal);
|
|
129
|
+
}
|
|
130
|
+
throw Error('invalid args provided');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
public getPersonInfo(args: ResolverArgs<MatcherArgs>): Observable<ApiPerson<'v2'>> {
|
|
134
|
+
const { azureId, upn, signal } = args;
|
|
135
|
+
if (azureId) {
|
|
136
|
+
return this._getPersonInfoById(azureId, signal);
|
|
137
|
+
} else if (upn) {
|
|
138
|
+
return this._getPersonInfoByUpn(upn, signal);
|
|
139
|
+
}
|
|
140
|
+
throw Error('invalid args provided');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
protected _getPersonByUpn(upn: string, signal?: AbortSignal): Observable<GetPersonResult> {
|
|
144
|
+
const abort$ = signal ? fromEvent(signal, 'abort') : EMPTY;
|
|
145
|
+
return concat(
|
|
146
|
+
this._personCache$({ upn }),
|
|
147
|
+
this._getPersonInfoByUpn(upn, signal).pipe(
|
|
148
|
+
filter(isApiPerson('v2')),
|
|
149
|
+
switchMap(({ azureUniqueId: azureId }) => {
|
|
150
|
+
return this._getPersonByAzureId(azureId, signal);
|
|
151
|
+
}),
|
|
152
|
+
),
|
|
153
|
+
).pipe(
|
|
154
|
+
/** */
|
|
155
|
+
filter(isApiPerson('v4')),
|
|
156
|
+
takeUntil(abort$),
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
public _getPersonByAzureId(azureId: string, signal?: AbortSignal): Observable<GetPersonResult> {
|
|
161
|
+
return this.#personQuery.query({ azureId }, { signal }).pipe(queryValue);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
protected _getPersonInfoById(
|
|
165
|
+
azureId: string,
|
|
166
|
+
signal?: AbortSignal,
|
|
167
|
+
): Observable<ApiPerson<'v2'>> {
|
|
168
|
+
const abort$ = signal ? fromEvent(signal, 'abort') : EMPTY;
|
|
169
|
+
return concat(
|
|
170
|
+
/** */
|
|
171
|
+
this._personCache$({ azureId }),
|
|
172
|
+
this._queryCache$({ azureId }),
|
|
173
|
+
this._getPersonByAzureId(azureId, signal),
|
|
174
|
+
).pipe(
|
|
175
|
+
/** */
|
|
176
|
+
filter(isApiPerson('v2')),
|
|
177
|
+
takeUntil(abort$),
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
protected _getPersonInfoByUpn(upn: string, signal?: AbortSignal): Observable<ApiPerson<'v2'>> {
|
|
182
|
+
const matcher = personMatcher({ upn });
|
|
183
|
+
const abort$ = signal ? fromEvent(signal, 'abort') : EMPTY;
|
|
184
|
+
return concat(
|
|
185
|
+
this._personCache$({ upn }),
|
|
186
|
+
this._queryCache$({ upn }),
|
|
187
|
+
this.#personSearchQuery.query({ search: upn }, { signal }).pipe(
|
|
188
|
+
/** extract first match, should only be 0 or 1 */
|
|
189
|
+
map((x) => x.value.find(matcher)),
|
|
190
|
+
/** type cast and end stream */
|
|
191
|
+
find(isApiPerson('v2')),
|
|
192
|
+
),
|
|
193
|
+
).pipe(
|
|
194
|
+
/** */
|
|
195
|
+
find(isApiPerson('v2')),
|
|
196
|
+
filter(isApiPerson('v2')),
|
|
197
|
+
filter(isApiPerson('v2')),
|
|
198
|
+
takeUntil(abort$),
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
protected _getPersonPhotoByAzureId(azureId: string, signal?: AbortSignal): Observable<string> {
|
|
203
|
+
return this.#personPhotoQuery.query({ azureId }, { signal }).pipe(
|
|
204
|
+
/** */
|
|
205
|
+
take(1),
|
|
206
|
+
map((result) => URL.createObjectURL(result.value)),
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
protected _getPersonPhotoByUpn(upn: string, signal?: AbortSignal) {
|
|
211
|
+
return this._getPersonInfoByUpn(upn, signal).pipe(
|
|
212
|
+
/** */
|
|
213
|
+
take(1),
|
|
214
|
+
switchMap((x) => this._getPersonPhotoByAzureId(x.azureUniqueId, signal)),
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
protected _personCache$(args: MatcherArgs): Observable<GetPersonResult> {
|
|
219
|
+
const mather = personMatcher(args);
|
|
220
|
+
return this.#personQuery.cache.state$.pipe(
|
|
221
|
+
/** make subscription cold */
|
|
222
|
+
take(1),
|
|
223
|
+
/** map out cached ApiPerson_v2 which matches upn */
|
|
224
|
+
map((x) => Object.values(x).find((x) => mather(x.value))?.value),
|
|
225
|
+
find(isApiPerson('v4')),
|
|
226
|
+
filter(isApiPerson('v4')),
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
protected _queryCache$(args: MatcherArgs): Observable<ApiPerson<'v2'>> {
|
|
231
|
+
const mather = personMatcher(args);
|
|
232
|
+
return this.#personSearchQuery.cache.state$.pipe(
|
|
233
|
+
/** make subscription cold */
|
|
234
|
+
take(1),
|
|
235
|
+
switchMap((entry) => {
|
|
236
|
+
/** expand cache records */
|
|
237
|
+
return from(Object.values(entry)).pipe(
|
|
238
|
+
/** find matching cache record item */
|
|
239
|
+
map((x) => x.value.find((x) => mather(x))),
|
|
240
|
+
/** type cast and end stream */
|
|
241
|
+
find(isApiPerson('v2')),
|
|
242
|
+
);
|
|
243
|
+
}),
|
|
244
|
+
find(isApiPerson('v2')),
|
|
245
|
+
filter(isApiPerson('v2')),
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { firstValueFrom, map } from 'rxjs';
|
|
2
|
+
|
|
3
|
+
import { PersonDetails, PersonInfo, PersonResolver } from '@equinor/fusion-wc-person';
|
|
4
|
+
import { IPersonController } from './PersonController';
|
|
5
|
+
|
|
6
|
+
export const createResolver = (controller: IPersonController): PersonResolver => ({
|
|
7
|
+
getDetails(args) {
|
|
8
|
+
return firstValueFrom(
|
|
9
|
+
controller.getPerson(args).pipe(
|
|
10
|
+
/** TODO */
|
|
11
|
+
map((x) => ({ ...x, azureId: x.azureUniqueId }) as unknown as PersonDetails),
|
|
12
|
+
),
|
|
13
|
+
);
|
|
14
|
+
},
|
|
15
|
+
getInfo(args) {
|
|
16
|
+
return firstValueFrom(
|
|
17
|
+
controller.getPersonInfo(args).pipe(
|
|
18
|
+
/** TODO */
|
|
19
|
+
map((x) => ({ ...x, azureId: x.azureUniqueId }) as unknown as PersonInfo),
|
|
20
|
+
),
|
|
21
|
+
);
|
|
22
|
+
},
|
|
23
|
+
getPhoto(args) {
|
|
24
|
+
return firstValueFrom(controller.getPhoto(args));
|
|
25
|
+
},
|
|
26
|
+
search(args) {
|
|
27
|
+
return firstValueFrom(
|
|
28
|
+
controller.search(args).pipe(
|
|
29
|
+
map((x) =>
|
|
30
|
+
x.map(
|
|
31
|
+
(x) =>
|
|
32
|
+
({
|
|
33
|
+
...x,
|
|
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
|
+
}) as unknown as PersonInfo,
|
|
40
|
+
),
|
|
41
|
+
),
|
|
42
|
+
),
|
|
43
|
+
);
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
export default createResolver;
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { PeopleResolverProvider, default } from './PeopleResolverProvider';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { lazy } from 'react';
|
|
2
|
+
import { PeopleResolverComponent } from './PeopleResolver';
|
|
3
|
+
import { PersonController, PersonControllerOptions } from './PersonController';
|
|
4
|
+
import { createResolver } from './create-resolver';
|
|
5
|
+
import { IApiProvider } from '@equinor/fusion-framework-module-services';
|
|
6
|
+
|
|
7
|
+
export const makeResolver = (services: IApiProvider, options?: PersonControllerOptions) => {
|
|
8
|
+
return lazy(async () => {
|
|
9
|
+
const client = await services.createPeopleClient();
|
|
10
|
+
const controller = new PersonController(client, options);
|
|
11
|
+
const resolver = createResolver(controller);
|
|
12
|
+
const Component = ({ children }: { readonly children?: React.ReactNode }) => (
|
|
13
|
+
<PeopleResolverComponent resolver={resolver}>{children}</PeopleResolverComponent>
|
|
14
|
+
);
|
|
15
|
+
return {
|
|
16
|
+
default: Component,
|
|
17
|
+
};
|
|
18
|
+
});
|
|
19
|
+
};
|
package/src/types.ts
ADDED
package/src/version.ts
ADDED
package/tsconfig.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig.react.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "dist/esm",
|
|
5
|
+
"rootDir": "src",
|
|
6
|
+
"declarationDir": "./dist/types"
|
|
7
|
+
},
|
|
8
|
+
"references": [
|
|
9
|
+
{
|
|
10
|
+
"path": "../../framework"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"path": "../../../modules/services"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"include": [
|
|
17
|
+
"src/**/*"
|
|
18
|
+
],
|
|
19
|
+
"exclude": [
|
|
20
|
+
"node_modules",
|
|
21
|
+
"lib"
|
|
22
|
+
]
|
|
23
|
+
}
|