@equinor/fusion-framework-react-components-bookmark 0.5.3 → 1.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.
- package/CHANGELOG.md +20 -0
- package/dist/esm/components/Bookmark.js +29 -17
- package/dist/esm/components/Bookmark.js.map +1 -1
- package/dist/esm/components/BookmarkProvider.js +47 -9
- package/dist/esm/components/BookmarkProvider.js.map +1 -1
- package/dist/esm/components/create-bookmark/CreateBookmark.js +31 -12
- package/dist/esm/components/create-bookmark/CreateBookmark.js.map +1 -1
- package/dist/esm/components/create-bookmark/index.js +1 -1
- package/dist/esm/components/create-bookmark/index.js.map +1 -1
- package/dist/esm/components/edit-bookmark/EditBookmark.js +44 -19
- package/dist/esm/components/edit-bookmark/EditBookmark.js.map +1 -1
- package/dist/esm/components/import-bookmark/ImportBookmark.js +42 -13
- package/dist/esm/components/import-bookmark/ImportBookmark.js.map +1 -1
- package/dist/esm/components/row/Row.js +3 -3
- package/dist/esm/components/row/Row.js.map +1 -1
- package/dist/esm/components/sectionList/SectionList.js +69 -67
- package/dist/esm/components/sectionList/SectionList.js.map +1 -1
- package/dist/esm/hooks/useBookmarkGrouping.js.map +1 -1
- package/dist/esm/utils/utils.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/components/BookmarkProvider.d.ts +16 -1
- package/dist/types/components/create-bookmark/index.d.ts +1 -1
- package/dist/types/components/edit-bookmark/EditBookmark.d.ts +1 -1
- package/dist/types/hooks/useBookmarkGrouping.d.ts +40 -4
- package/dist/types/utils/utils.d.ts +3 -3
- package/dist/types/version.d.ts +1 -1
- package/package.json +6 -4
- package/src/components/Bookmark.tsx +42 -31
- package/src/components/BookmarkProvider.tsx +74 -14
- package/src/components/create-bookmark/CreateBookmark.tsx +30 -13
- package/src/components/create-bookmark/index.ts +1 -1
- package/src/components/edit-bookmark/EditBookmark.tsx +60 -23
- package/src/components/import-bookmark/ImportBookmark.tsx +35 -15
- package/src/components/row/Row.tsx +3 -3
- package/src/components/sectionList/SectionList.tsx +77 -97
- package/src/hooks/useBookmarkGrouping.ts +6 -6
- package/src/utils/utils.ts +4 -3
- package/src/version.ts +1 -1
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import type { FrameworkEvent, FrameworkEventInit } from '@equinor/fusion-framework-module-event';
|
|
2
2
|
import { PropsWithChildren } from 'react';
|
|
3
|
-
|
|
3
|
+
import { type BookmarkProvider as IBookmarkProvider } from '@equinor/fusion-framework-module-bookmark';
|
|
4
|
+
type BookmarkApp = {
|
|
5
|
+
appKey: string;
|
|
6
|
+
name?: string;
|
|
7
|
+
};
|
|
8
|
+
type ProviderState = {
|
|
9
|
+
provider: IBookmarkProvider;
|
|
10
|
+
currentApp?: BookmarkApp | null;
|
|
11
|
+
};
|
|
12
|
+
type BookmarkProviderProps = {
|
|
13
|
+
readonly provider?: IBookmarkProvider | null;
|
|
14
|
+
};
|
|
15
|
+
export declare const useBookmarkComponentContext: () => ProviderState;
|
|
16
|
+
export declare const useBookmarkProvider: () => IBookmarkProvider;
|
|
17
|
+
export declare const BookmarkProvider: (props: PropsWithChildren<BookmarkProviderProps>) => import("react/jsx-runtime").JSX.Element | null;
|
|
4
18
|
declare module '@equinor/fusion-framework-module-event' {
|
|
5
19
|
interface FrameworkEventMap {
|
|
6
20
|
onBookmarkOpen: FrameworkEvent<FrameworkEventInit<boolean, unknown>>;
|
|
@@ -12,3 +26,4 @@ declare module '@equinor/fusion-framework-module-event' {
|
|
|
12
26
|
}, unknown>>;
|
|
13
27
|
}
|
|
14
28
|
}
|
|
29
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { CreateBookmarkModal } from './CreateBookmark';
|
|
@@ -1,13 +1,49 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Bookmarks, BookmarkWithoutData } from '@equinor/fusion-framework-module-bookmark';
|
|
2
2
|
export type GroupingKeys = 'Group by app' | 'Created by' | 'Group by Context';
|
|
3
|
-
export declare const useBookmarkGrouping: (bookmarks?:
|
|
3
|
+
export declare const useBookmarkGrouping: (bookmarks?: Bookmarks) => {
|
|
4
4
|
setGroupBy: import("react").Dispatch<import("react").SetStateAction<GroupingKeys>>;
|
|
5
5
|
setSearchText: import("react").Dispatch<import("react").SetStateAction<string | null>>;
|
|
6
6
|
searchText: string | null;
|
|
7
7
|
bookmarkGroups: {
|
|
8
8
|
groupingProperty: string;
|
|
9
|
-
values:
|
|
9
|
+
values: {
|
|
10
|
+
name: string;
|
|
11
|
+
id: string;
|
|
12
|
+
appKey: string;
|
|
13
|
+
created: Date;
|
|
14
|
+
createdBy: {
|
|
15
|
+
azureUniqueId: string;
|
|
16
|
+
name: string;
|
|
17
|
+
mail?: string | undefined;
|
|
18
|
+
phoneNumber?: string | undefined;
|
|
19
|
+
jobTitle?: string | undefined;
|
|
20
|
+
accountType?: "Employee" | "Consultant" | "External" | "Application" | "Local" | undefined;
|
|
21
|
+
accountClassification?: "External" | "Unclassified" | "Internal" | undefined;
|
|
22
|
+
};
|
|
23
|
+
description?: string | undefined;
|
|
24
|
+
isShared?: boolean | undefined;
|
|
25
|
+
updated?: Date | undefined;
|
|
26
|
+
updatedBy?: {
|
|
27
|
+
azureUniqueId: string;
|
|
28
|
+
name: string;
|
|
29
|
+
mail?: string | undefined;
|
|
30
|
+
phoneNumber?: string | undefined;
|
|
31
|
+
jobTitle?: string | undefined;
|
|
32
|
+
accountType?: "Employee" | "Consultant" | "External" | "Application" | "Local" | undefined;
|
|
33
|
+
accountClassification?: "External" | "Unclassified" | "Internal" | undefined;
|
|
34
|
+
} | undefined;
|
|
35
|
+
context?: {
|
|
36
|
+
id: string;
|
|
37
|
+
name?: string | undefined;
|
|
38
|
+
type?: string | undefined;
|
|
39
|
+
} | undefined;
|
|
40
|
+
sourceSystem?: {
|
|
41
|
+
identifier: string;
|
|
42
|
+
name?: string | undefined;
|
|
43
|
+
subSystem?: string | undefined;
|
|
44
|
+
} | undefined;
|
|
45
|
+
}[];
|
|
10
46
|
}[];
|
|
11
|
-
groupingModes: Record<GroupingKeys, (_item:
|
|
47
|
+
groupingModes: Record<GroupingKeys, (_item: BookmarkWithoutData) => string>;
|
|
12
48
|
groupByKey: GroupingKeys;
|
|
13
49
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Bookmarks, BookmarkWithoutData } from '@equinor/fusion-framework-module-bookmark';
|
|
2
2
|
/** Helpers.. */
|
|
3
3
|
export declare const filterEmptyGroups: (i: {
|
|
4
|
-
values:
|
|
4
|
+
values: Bookmarks;
|
|
5
5
|
}) => number;
|
|
6
|
-
export declare const sortByName: (a:
|
|
6
|
+
export declare const sortByName: (a: BookmarkWithoutData, b: BookmarkWithoutData) => number;
|
|
7
7
|
export declare const toHumanReadable: (val: string) => string;
|
package/dist/types/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "0.
|
|
1
|
+
export declare const version = "1.0.0";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@equinor/fusion-framework-react-components-bookmark",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/esm/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -22,8 +22,10 @@
|
|
|
22
22
|
"directory": "packages/react/components/bookmark"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@equinor/fusion-
|
|
26
|
-
"
|
|
25
|
+
"@equinor/fusion-observable": "^8.3.3",
|
|
26
|
+
"rxjs": "^7.8.1",
|
|
27
|
+
"@equinor/fusion-framework-react": "^7.3.2",
|
|
28
|
+
"@equinor/fusion-framework-react-module-bookmark": "^2.2.0"
|
|
27
29
|
},
|
|
28
30
|
"devDependencies": {
|
|
29
31
|
"@equinor/eds-core-react": "^0.42.0",
|
|
@@ -35,7 +37,7 @@
|
|
|
35
37
|
"styled-components": "^6.0.7",
|
|
36
38
|
"typescript": "^5.5.4",
|
|
37
39
|
"@equinor/fusion-framework-module-app": "^6.0.2",
|
|
38
|
-
"@equinor/fusion-framework-module-bookmark": "^
|
|
40
|
+
"@equinor/fusion-framework-module-bookmark": "^2.0.0",
|
|
39
41
|
"@equinor/fusion-framework-module-event": "^4.2.4"
|
|
40
42
|
},
|
|
41
43
|
"peerDependencies": {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EMPTY } from 'rxjs';
|
|
2
2
|
import { useBookmarkGrouping } from '../hooks';
|
|
3
3
|
import { BookmarkFilter } from './filter/Filter';
|
|
4
4
|
import { SectionList } from './sectionList/SectionList';
|
|
5
|
-
import { useEffect, useState } from 'react';
|
|
5
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
6
6
|
|
|
7
7
|
import { Icon } from '@equinor/eds-core-react';
|
|
8
8
|
import { chevron_down, chevron_right, share, more_vertical, add } from '@equinor/eds-icons';
|
|
@@ -10,7 +10,8 @@ import { chevron_down, chevron_right, share, more_vertical, add } from '@equinor
|
|
|
10
10
|
import styled from 'styled-components';
|
|
11
11
|
import { Message } from './messages/Message';
|
|
12
12
|
import { Loading } from './loading/Loading';
|
|
13
|
-
import {
|
|
13
|
+
import { useBookmarkComponentContext } from './BookmarkProvider';
|
|
14
|
+
import { useObservableState } from '@equinor/fusion-observable/react';
|
|
14
15
|
|
|
15
16
|
Icon.add({
|
|
16
17
|
chevron_down,
|
|
@@ -42,30 +43,52 @@ const Styled = {
|
|
|
42
43
|
};
|
|
43
44
|
|
|
44
45
|
export const Bookmark = () => {
|
|
45
|
-
const {
|
|
46
|
+
const { provider } = useBookmarkComponentContext();
|
|
47
|
+
|
|
46
48
|
const [loading, setLoading] = useState(true);
|
|
49
|
+
const [error, setError] = useState<Error | null>(null);
|
|
47
50
|
|
|
48
|
-
const {
|
|
51
|
+
const { value: bookmarks } = useObservableState(
|
|
52
|
+
useMemo(() => provider?.bookmarks$ || EMPTY, [provider]),
|
|
53
|
+
{ initial: provider?.bookmarks },
|
|
54
|
+
);
|
|
49
55
|
|
|
50
56
|
useEffect(() => {
|
|
51
|
-
|
|
52
|
-
|
|
57
|
+
const sub = provider?.getAllBookmarks().subscribe({
|
|
58
|
+
complete: () => {
|
|
59
|
+
setLoading(false);
|
|
60
|
+
},
|
|
61
|
+
error: (err) => {
|
|
62
|
+
setError(err);
|
|
63
|
+
},
|
|
53
64
|
});
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
useEffect(() => {
|
|
57
|
-
if (bookmarks.length > 0) {
|
|
58
|
-
setLoading(false);
|
|
59
|
-
}
|
|
60
|
-
}, [bookmarks]);
|
|
61
|
-
|
|
62
|
-
useEffect(() => {
|
|
63
|
-
getAllBookmarks();
|
|
64
|
-
}, [getAllBookmarks]);
|
|
65
|
+
return () => sub?.unsubscribe();
|
|
66
|
+
}, [provider]);
|
|
65
67
|
|
|
66
68
|
const { bookmarkGroups, groupingModes, searchText, setGroupBy, setSearchText, groupByKey } =
|
|
67
69
|
useBookmarkGrouping(bookmarks);
|
|
68
70
|
|
|
71
|
+
const content = useMemo(() => {
|
|
72
|
+
if (error) {
|
|
73
|
+
return (
|
|
74
|
+
<Message title="Error" type="Error">
|
|
75
|
+
{error.message}
|
|
76
|
+
</Message>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
if (loading) {
|
|
80
|
+
return <Loading />;
|
|
81
|
+
}
|
|
82
|
+
if (bookmarkGroups.length === 0) {
|
|
83
|
+
return (
|
|
84
|
+
<Message title="No Bookmarks" type="NoContent">
|
|
85
|
+
You have not created any bookmarks yet.
|
|
86
|
+
</Message>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
return <SectionList bookmarkGroups={bookmarkGroups} />;
|
|
90
|
+
}, [error, loading, bookmarkGroups]);
|
|
91
|
+
|
|
69
92
|
return (
|
|
70
93
|
<Styled.Wrapper>
|
|
71
94
|
<BookmarkFilter
|
|
@@ -75,19 +98,7 @@ export const Bookmark = () => {
|
|
|
75
98
|
setGroupBy={setGroupBy}
|
|
76
99
|
setSearchText={setSearchText}
|
|
77
100
|
/>
|
|
78
|
-
<Styled.List>
|
|
79
|
-
{bookmarkGroups.length > 0 ? (
|
|
80
|
-
<SectionList bookmarkGroups={bookmarkGroups} />
|
|
81
|
-
) : loading ? (
|
|
82
|
-
<Loading />
|
|
83
|
-
) : (
|
|
84
|
-
<Styled.NoContentWrapper>
|
|
85
|
-
<Message title="No Bookmarks" type="NoContent">
|
|
86
|
-
You have not created any bookmarks yet.
|
|
87
|
-
</Message>
|
|
88
|
-
</Styled.NoContentWrapper>
|
|
89
|
-
)}
|
|
90
|
-
</Styled.List>
|
|
101
|
+
<Styled.List>{content}</Styled.List>
|
|
91
102
|
</Styled.Wrapper>
|
|
92
103
|
);
|
|
93
104
|
};
|
|
@@ -1,30 +1,84 @@
|
|
|
1
1
|
import { Snackbar } from '@equinor/eds-core-react';
|
|
2
2
|
import type { FrameworkEvent, FrameworkEventInit } from '@equinor/fusion-framework-module-event';
|
|
3
3
|
import { useFramework } from '@equinor/fusion-framework-react';
|
|
4
|
-
import { PropsWithChildren, useEffect, useState } from 'react';
|
|
4
|
+
import { PropsWithChildren, createContext, useContext, useEffect, useMemo, useState } from 'react';
|
|
5
5
|
import { CreateBookmarkModal } from './create-bookmark';
|
|
6
6
|
import { EditBookmarkModal } from './edit-bookmark';
|
|
7
7
|
import { ImportBookmarkModal } from './import-bookmark';
|
|
8
|
+
import {
|
|
9
|
+
BookmarkModule,
|
|
10
|
+
type BookmarkProvider as IBookmarkProvider,
|
|
11
|
+
} from '@equinor/fusion-framework-module-bookmark';
|
|
12
|
+
import { Observable, of } from 'rxjs';
|
|
13
|
+
import { useObservableState } from '@equinor/fusion-observable/react';
|
|
14
|
+
|
|
15
|
+
type BookmarkApp = {
|
|
16
|
+
appKey: string;
|
|
17
|
+
name?: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
type ProviderState = {
|
|
21
|
+
provider: IBookmarkProvider;
|
|
22
|
+
currentApp?: BookmarkApp | null;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const bookmarkProviderContext = createContext<ProviderState | null>(null);
|
|
26
|
+
|
|
27
|
+
type BookmarkProviderProps = {
|
|
28
|
+
readonly provider?: IBookmarkProvider | null;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const useBookmarkComponentContext = () =>
|
|
32
|
+
useContext(bookmarkProviderContext) as ProviderState;
|
|
33
|
+
|
|
34
|
+
export const useBookmarkProvider = () => useBookmarkComponentContext().provider;
|
|
35
|
+
|
|
36
|
+
export const BookmarkProvider = (props: PropsWithChildren<BookmarkProviderProps>) => {
|
|
37
|
+
const { event: eventProvider } = useFramework<[BookmarkModule]>().modules;
|
|
38
|
+
|
|
39
|
+
const { provider, children } = props;
|
|
8
40
|
|
|
9
|
-
export const BookmarkProvider = ({ children }: PropsWithChildren<unknown>) => {
|
|
10
41
|
const [isCreateBookmarkOpen, setIsCreateBookmarkOpen] = useState(false);
|
|
11
42
|
const [isEditBookmarkOpen, setIsEditBookmarkOpen] = useState(false);
|
|
12
43
|
const [editBookmarkId, setEditBookmarkId] = useState<string | undefined>();
|
|
13
44
|
const [isBookmarkCopy, setIsBookmarkCopy] = useState(false);
|
|
14
45
|
|
|
15
|
-
|
|
46
|
+
// get the current app
|
|
47
|
+
const { value: currentApp } = useObservableState(
|
|
48
|
+
useMemo(() => {
|
|
49
|
+
// if no provider, return null, this should not happen
|
|
50
|
+
if (!provider) {
|
|
51
|
+
return of(null);
|
|
52
|
+
}
|
|
53
|
+
return new Observable<BookmarkApp | null>((observer) => {
|
|
54
|
+
// resolve the application
|
|
55
|
+
const resolveApp = async () => {
|
|
56
|
+
// get the resolved application
|
|
57
|
+
const app = await provider.resolvedApplication();
|
|
58
|
+
// emit the resolved application
|
|
59
|
+
observer.next(app);
|
|
60
|
+
};
|
|
61
|
+
// re-resolve the application when the current app changes
|
|
62
|
+
eventProvider.addEventListener('onCurrentAppChanged', resolveApp);
|
|
63
|
+
|
|
64
|
+
// initial resolve
|
|
65
|
+
resolveApp();
|
|
66
|
+
});
|
|
67
|
+
}, [eventProvider, provider]),
|
|
68
|
+
{ initial: undefined },
|
|
69
|
+
);
|
|
16
70
|
|
|
17
71
|
useEffect(() => {
|
|
18
|
-
const subOnBookmarkOpen =
|
|
72
|
+
const subOnBookmarkOpen = eventProvider.addEventListener('onBookmarkOpen', (e) => {
|
|
19
73
|
setIsCreateBookmarkOpen(e.detail);
|
|
20
74
|
});
|
|
21
75
|
|
|
22
|
-
const subOnBookmarkEdit =
|
|
76
|
+
const subOnBookmarkEdit = eventProvider.addEventListener('onBookmarkEdit', (e) => {
|
|
23
77
|
setEditBookmarkId(e.detail.bookmarkId);
|
|
24
78
|
setIsEditBookmarkOpen(true);
|
|
25
79
|
});
|
|
26
80
|
|
|
27
|
-
const subOnBookmarkUrlCopy =
|
|
81
|
+
const subOnBookmarkUrlCopy = eventProvider.addEventListener('onBookmarkUrlCopy', () => {
|
|
28
82
|
setIsBookmarkCopy(true);
|
|
29
83
|
});
|
|
30
84
|
|
|
@@ -33,16 +87,22 @@ export const BookmarkProvider = ({ children }: PropsWithChildren<unknown>) => {
|
|
|
33
87
|
subOnBookmarkOpen();
|
|
34
88
|
subOnBookmarkUrlCopy();
|
|
35
89
|
};
|
|
36
|
-
}, [
|
|
90
|
+
}, [eventProvider]);
|
|
91
|
+
|
|
92
|
+
if (!provider) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
37
95
|
|
|
38
96
|
return (
|
|
39
|
-
|
|
97
|
+
<bookmarkProviderContext.Provider value={{ provider, currentApp }}>
|
|
40
98
|
<CreateBookmarkModal isOpen={isCreateBookmarkOpen} onClose={setIsCreateBookmarkOpen} />
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
99
|
+
{editBookmarkId && (
|
|
100
|
+
<EditBookmarkModal
|
|
101
|
+
isOpen={isEditBookmarkOpen}
|
|
102
|
+
onClose={setIsEditBookmarkOpen}
|
|
103
|
+
bookmarkId={editBookmarkId}
|
|
104
|
+
/>
|
|
105
|
+
)}
|
|
46
106
|
<ImportBookmarkModal />
|
|
47
107
|
<Snackbar
|
|
48
108
|
autoHideDuration={2000}
|
|
@@ -52,7 +112,7 @@ export const BookmarkProvider = ({ children }: PropsWithChildren<unknown>) => {
|
|
|
52
112
|
Bookmark url copied to clipboard
|
|
53
113
|
</Snackbar>
|
|
54
114
|
{children}
|
|
55
|
-
|
|
115
|
+
</bookmarkProviderContext.Provider>
|
|
56
116
|
);
|
|
57
117
|
};
|
|
58
118
|
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { ChangeEvent, useState } from 'react';
|
|
1
|
+
import { ChangeEvent, useCallback, useEffect, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import { BookmarkCreateArgs } from '@equinor/fusion-framework-module-bookmark';
|
|
4
|
+
import { useBookmarkComponentContext } from '../BookmarkProvider';
|
|
6
5
|
|
|
6
|
+
import { Button, Checkbox, Dialog, Input, Label, TextField } from '@equinor/eds-core-react';
|
|
7
7
|
import styled from 'styled-components';
|
|
8
|
+
|
|
8
9
|
// TODO
|
|
9
10
|
const StyledContent = styled(Dialog.Content)`
|
|
10
11
|
display: flex;
|
|
@@ -19,15 +20,33 @@ export const CreateBookmarkModal = ({
|
|
|
19
20
|
readonly isOpen: boolean;
|
|
20
21
|
readonly onClose: (b: boolean) => void;
|
|
21
22
|
}) => {
|
|
22
|
-
const
|
|
23
|
+
const { provider, currentApp } = useBookmarkComponentContext();
|
|
24
|
+
|
|
25
|
+
const [state, setState] = useState<BookmarkCreateArgs<never>>({
|
|
23
26
|
name: '',
|
|
24
27
|
description: '',
|
|
25
28
|
isShared: false,
|
|
26
29
|
});
|
|
27
30
|
|
|
28
|
-
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
setState((s) => ({ ...s, appKey: currentApp?.appKey || '' }));
|
|
33
|
+
}, [currentApp]);
|
|
29
34
|
|
|
30
|
-
const
|
|
35
|
+
const createBookmark = useCallback(
|
|
36
|
+
async (args: BookmarkCreateArgs<never>) => {
|
|
37
|
+
try {
|
|
38
|
+
await provider.createBookmarkAsync(args);
|
|
39
|
+
// TODO: Show success message
|
|
40
|
+
// TODO: should this call onCreated, with the new bookmark?
|
|
41
|
+
// TODO: should current bookmark be updated?
|
|
42
|
+
onClose(false);
|
|
43
|
+
} catch (error) {
|
|
44
|
+
console.error('Failed to create bookmark', error);
|
|
45
|
+
// TODO: Show error message
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
[onClose, provider],
|
|
49
|
+
);
|
|
31
50
|
|
|
32
51
|
return (
|
|
33
52
|
<Dialog style={{ width: '400px' }} open={isOpen}>
|
|
@@ -58,7 +77,7 @@ export const CreateBookmarkModal = ({
|
|
|
58
77
|
</div>
|
|
59
78
|
<div>
|
|
60
79
|
<Label htmlFor="app" label="App" />
|
|
61
|
-
<Input readOnly={true} value={
|
|
80
|
+
<Input readOnly={true} value={currentApp?.name || currentApp?.appKey || ''} />
|
|
62
81
|
</div>
|
|
63
82
|
|
|
64
83
|
<div>
|
|
@@ -77,11 +96,9 @@ export const CreateBookmarkModal = ({
|
|
|
77
96
|
Cancel
|
|
78
97
|
</Button>
|
|
79
98
|
<Button
|
|
99
|
+
disabled={!currentApp || !state.name}
|
|
80
100
|
onClick={() => {
|
|
81
|
-
state
|
|
82
|
-
createBookmark(state).then(() => {
|
|
83
|
-
onClose(false);
|
|
84
|
-
});
|
|
101
|
+
createBookmark(state);
|
|
85
102
|
}}
|
|
86
103
|
>
|
|
87
104
|
Create
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { CreateBookmarkModal } from './CreateBookmark';
|
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
import { ChangeEvent, useEffect, useState } from 'react';
|
|
1
|
+
import { ChangeEvent, useCallback, useEffect, useMemo, useState } from 'react';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { of } from 'rxjs';
|
|
4
|
+
|
|
5
|
+
import { useObservableState } from '@equinor/fusion-observable/react';
|
|
6
|
+
|
|
7
|
+
import { useFramework, useFrameworkModule } from '@equinor/fusion-framework-react';
|
|
4
8
|
import type { AppModule } from '@equinor/fusion-framework-module-app';
|
|
5
|
-
|
|
6
|
-
import type { PatchBookmark } from '@equinor/fusion-framework-module-bookmark';
|
|
7
|
-
import { useFramework } from '@equinor/fusion-framework-react';
|
|
8
|
-
import { useBookmark } from '@equinor/fusion-framework-react-module-bookmark';
|
|
9
|
-
import { appendBookmarkIdToUrl } from '../../utils/append-bookmark-to-uri';
|
|
9
|
+
import type { BookmarkUpdate } from '@equinor/fusion-framework-module-bookmark';
|
|
10
10
|
|
|
11
|
+
import { Button, Checkbox, Dialog, Input, Label, TextField } from '@equinor/eds-core-react';
|
|
11
12
|
import styled from 'styled-components';
|
|
12
13
|
|
|
14
|
+
import { useBookmarkComponentContext } from '../BookmarkProvider';
|
|
15
|
+
import { appendBookmarkIdToUrl } from '../../utils/append-bookmark-to-uri';
|
|
16
|
+
|
|
13
17
|
const Styled = {
|
|
14
18
|
Dialog: styled(Dialog)`
|
|
15
19
|
width: 500px;
|
|
@@ -36,11 +40,11 @@ export const EditBookmarkModal = ({
|
|
|
36
40
|
}: {
|
|
37
41
|
readonly isOpen: boolean;
|
|
38
42
|
readonly onClose: (b: boolean) => void;
|
|
39
|
-
readonly bookmarkId
|
|
43
|
+
readonly bookmarkId: string;
|
|
40
44
|
}) => {
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
45
|
+
const { provider } = useBookmarkComponentContext();
|
|
46
|
+
|
|
47
|
+
const [state, setState] = useState<BookmarkUpdate>({
|
|
44
48
|
name: '',
|
|
45
49
|
description: '',
|
|
46
50
|
isShared: false,
|
|
@@ -48,17 +52,52 @@ export const EditBookmarkModal = ({
|
|
|
48
52
|
|
|
49
53
|
const [updatePayload, setUpdatePayload] = useState(false);
|
|
50
54
|
|
|
51
|
-
const {
|
|
52
|
-
const { current } = app;
|
|
55
|
+
const { event } = useFramework<[AppModule]>().modules;
|
|
53
56
|
|
|
54
|
-
const
|
|
57
|
+
const bookmark$ = useMemo(
|
|
58
|
+
() => provider.getBookmark(bookmarkId, { excludePayload: true }),
|
|
59
|
+
[provider, bookmarkId],
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
const { value: bookmark, complete: isLoadingBookmark } = useObservableState(bookmark$);
|
|
55
63
|
|
|
64
|
+
// set the state when the bookmark is loaded
|
|
56
65
|
useEffect(() => {
|
|
57
|
-
const bookmark = bookmarks.find((b) => b.id === bookmarkId);
|
|
58
66
|
if (bookmark) {
|
|
59
|
-
setState(
|
|
67
|
+
setState({
|
|
68
|
+
name: bookmark.name,
|
|
69
|
+
description: bookmark.description,
|
|
70
|
+
isShared: bookmark.isShared,
|
|
71
|
+
});
|
|
60
72
|
}
|
|
61
|
-
}, [
|
|
73
|
+
}, [bookmark]);
|
|
74
|
+
|
|
75
|
+
// TODO - this should be on the bookmark object
|
|
76
|
+
const appProvider = useFrameworkModule<AppModule>('app');
|
|
77
|
+
const { value: appName } = useObservableState(
|
|
78
|
+
useMemo(
|
|
79
|
+
() =>
|
|
80
|
+
bookmark && appProvider
|
|
81
|
+
? appProvider.getAppManifest(bookmark.appKey)
|
|
82
|
+
: of(undefined),
|
|
83
|
+
[appProvider, bookmark],
|
|
84
|
+
),
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const updateBookmark = useCallback(
|
|
88
|
+
async (updates: BookmarkUpdate) => {
|
|
89
|
+
await provider.updateBookmarkAsync(bookmarkId, updates, {
|
|
90
|
+
excludePayloadGeneration: !updatePayload,
|
|
91
|
+
});
|
|
92
|
+
// TODO: Show success message
|
|
93
|
+
// TODO: should this call onUpdated, with the updated bookmark?
|
|
94
|
+
onClose(false);
|
|
95
|
+
},
|
|
96
|
+
[onClose, provider, bookmarkId, updatePayload],
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
// TODO - add loading spinner
|
|
100
|
+
isLoadingBookmark;
|
|
62
101
|
|
|
63
102
|
return (
|
|
64
103
|
<Styled.Dialog open={isOpen}>
|
|
@@ -90,7 +129,8 @@ export const EditBookmarkModal = ({
|
|
|
90
129
|
</div>
|
|
91
130
|
<div>
|
|
92
131
|
<Label htmlFor="app" label="App" />
|
|
93
|
-
|
|
132
|
+
{/** TODO - show ghost while loading app name */}
|
|
133
|
+
<Input readOnly={true} value={appName || ''} />
|
|
94
134
|
</div>
|
|
95
135
|
|
|
96
136
|
<Styled.CheckboxWrapper>
|
|
@@ -99,7 +139,7 @@ export const EditBookmarkModal = ({
|
|
|
99
139
|
checked={state.isShared}
|
|
100
140
|
onChange={(changeEvent: ChangeEvent<HTMLInputElement>) => {
|
|
101
141
|
if (changeEvent.target.checked) {
|
|
102
|
-
const url = appendBookmarkIdToUrl(
|
|
142
|
+
const url = appendBookmarkIdToUrl(bookmark?.id || '');
|
|
103
143
|
navigator.clipboard.writeText(url);
|
|
104
144
|
event.dispatchEvent('onBookmarkUrlCopy', { detail: { url } });
|
|
105
145
|
}
|
|
@@ -122,10 +162,7 @@ export const EditBookmarkModal = ({
|
|
|
122
162
|
</Button>
|
|
123
163
|
<Button
|
|
124
164
|
onClick={() => {
|
|
125
|
-
state
|
|
126
|
-
updateBookmark(state, { updatePayload }).then(() => {
|
|
127
|
-
onClose(false);
|
|
128
|
-
});
|
|
165
|
+
updateBookmark(state);
|
|
129
166
|
}}
|
|
130
167
|
>
|
|
131
168
|
Save
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { Button, Dialog } from '@equinor/eds-core-react';
|
|
2
|
-
import {
|
|
3
|
-
import { useEffect, useState } from 'react';
|
|
2
|
+
import { useObservableState } from '@equinor/fusion-observable/react';
|
|
3
|
+
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
4
4
|
|
|
5
5
|
import styled from 'styled-components';
|
|
6
|
+
import { useBookmarkComponentContext } from '../BookmarkProvider';
|
|
7
|
+
import { useCurrentBookmark } from '@equinor/fusion-framework-react-module-bookmark';
|
|
6
8
|
|
|
7
9
|
const Styled = {
|
|
8
10
|
Actions: styled.div`
|
|
@@ -14,15 +16,40 @@ const Styled = {
|
|
|
14
16
|
export const ImportBookmarkModal = () => {
|
|
15
17
|
const [isOpen, setIsOpen] = useState(false);
|
|
16
18
|
|
|
17
|
-
const {
|
|
19
|
+
const { provider } = useBookmarkComponentContext();
|
|
20
|
+
const { value: bookmarks, complete: bookmarksLoaded } = useObservableState(
|
|
21
|
+
useMemo(() => provider.bookmarks$, [provider]),
|
|
22
|
+
{ initial: [] },
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
const { currentBookmark } = useCurrentBookmark({ provider });
|
|
18
26
|
|
|
19
27
|
useEffect(() => {
|
|
20
|
-
if (
|
|
28
|
+
if (bookmarksLoaded && currentBookmark) {
|
|
29
|
+
// TODO: this should rather use the provider.isFavorite, but the bookmark should have flag for if the bookmark is created by the user
|
|
30
|
+
const hasBookmark = bookmarks.find(({ id }) => id === currentBookmark.id);
|
|
31
|
+
if (!hasBookmark) {
|
|
32
|
+
setIsOpen(true);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}, [bookmarks, currentBookmark, bookmarksLoaded]);
|
|
21
36
|
|
|
22
|
-
|
|
23
|
-
|
|
37
|
+
const onAddBookmarkFavorite = useCallback(async () => {
|
|
38
|
+
if (currentBookmark) {
|
|
39
|
+
try {
|
|
40
|
+
// TODO: missing state for disabling button
|
|
41
|
+
await provider.addBookmarkToFavoritesAsync(currentBookmark.id);
|
|
42
|
+
// TODO: Show success message
|
|
43
|
+
} catch (error) {
|
|
44
|
+
console.error('Failed to add bookmark to favorites', error);
|
|
45
|
+
// TODO: Show error message
|
|
46
|
+
}
|
|
47
|
+
await provider.addBookmarkToFavoritesAsync(currentBookmark.id);
|
|
48
|
+
} else {
|
|
49
|
+
console.error('No bookmark to add to favorites');
|
|
50
|
+
// TODO: Show error message
|
|
24
51
|
}
|
|
25
|
-
}, [
|
|
52
|
+
}, [provider, currentBookmark]);
|
|
26
53
|
|
|
27
54
|
return (
|
|
28
55
|
<Dialog style={{ width: '600px' }} open={isOpen}>
|
|
@@ -40,14 +67,7 @@ export const ImportBookmarkModal = () => {
|
|
|
40
67
|
>
|
|
41
68
|
No
|
|
42
69
|
</Button>
|
|
43
|
-
<Button
|
|
44
|
-
onClick={() => {
|
|
45
|
-
console.log(currentBookmark?.id);
|
|
46
|
-
currentBookmark && addBookmarkFavorite(currentBookmark.id);
|
|
47
|
-
setIsOpen(false);
|
|
48
|
-
}}
|
|
49
|
-
variant="ghost"
|
|
50
|
-
>
|
|
70
|
+
<Button onClick={onAddBookmarkFavorite} variant="ghost">
|
|
51
71
|
Import
|
|
52
72
|
</Button>
|
|
53
73
|
</Styled.Actions>
|