@equinor/fusion-framework-react-components-bookmark 0.0.0-next-20230915111233

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 (90) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/CHANGELOG.md +199 -0
  3. package/LICENSE +21 -0
  4. package/dist/esm/components/Bookmark.js +39 -0
  5. package/dist/esm/components/Bookmark.js.map +1 -0
  6. package/dist/esm/components/BookmarkProvider.js +33 -0
  7. package/dist/esm/components/BookmarkProvider.js.map +1 -0
  8. package/dist/esm/components/create-bookmark/CreateBookmark.js +34 -0
  9. package/dist/esm/components/create-bookmark/CreateBookmark.js.map +1 -0
  10. package/dist/esm/components/create-bookmark/index.js +2 -0
  11. package/dist/esm/components/create-bookmark/index.js.map +1 -0
  12. package/dist/esm/components/edit-bookmark/EditBookmark.js +65 -0
  13. package/dist/esm/components/edit-bookmark/EditBookmark.js.map +1 -0
  14. package/dist/esm/components/edit-bookmark/index.js +2 -0
  15. package/dist/esm/components/edit-bookmark/index.js.map +1 -0
  16. package/dist/esm/components/filter/Filter.js +19 -0
  17. package/dist/esm/components/filter/Filter.js.map +1 -0
  18. package/dist/esm/components/import-bookmark/ImportBookmark.js +28 -0
  19. package/dist/esm/components/import-bookmark/ImportBookmark.js.map +1 -0
  20. package/dist/esm/components/import-bookmark/index.js +2 -0
  21. package/dist/esm/components/import-bookmark/index.js.map +1 -0
  22. package/dist/esm/components/loading/Loading.js +10 -0
  23. package/dist/esm/components/loading/Loading.js.map +1 -0
  24. package/dist/esm/components/row/MoreMenu.js +11 -0
  25. package/dist/esm/components/row/MoreMenu.js.map +1 -0
  26. package/dist/esm/components/row/Row.js +47 -0
  27. package/dist/esm/components/row/Row.js.map +1 -0
  28. package/dist/esm/components/section/Section.js +41 -0
  29. package/dist/esm/components/section/Section.js.map +1 -0
  30. package/dist/esm/components/sectionList/SectionList.js +103 -0
  31. package/dist/esm/components/sectionList/SectionList.js.map +1 -0
  32. package/dist/esm/components/shared/SharedIcon.js +28 -0
  33. package/dist/esm/components/shared/SharedIcon.js.map +1 -0
  34. package/dist/esm/hooks/index.js +2 -0
  35. package/dist/esm/hooks/index.js.map +1 -0
  36. package/dist/esm/hooks/useBookmarkGrouping.js +35 -0
  37. package/dist/esm/hooks/useBookmarkGrouping.js.map +1 -0
  38. package/dist/esm/index.js +3 -0
  39. package/dist/esm/index.js.map +1 -0
  40. package/dist/esm/utils/append-bookmark-to-uri.js +6 -0
  41. package/dist/esm/utils/append-bookmark-to-uri.js.map +1 -0
  42. package/dist/esm/utils/utils.js +7 -0
  43. package/dist/esm/utils/utils.js.map +1 -0
  44. package/dist/esm/version.js +2 -0
  45. package/dist/esm/version.js.map +1 -0
  46. package/dist/tsconfig.tsbuildinfo +1 -0
  47. package/dist/types/components/Bookmark.d.ts +2 -0
  48. package/dist/types/components/BookmarkProvider.d.ts +14 -0
  49. package/dist/types/components/create-bookmark/CreateBookmark.d.ts +4 -0
  50. package/dist/types/components/create-bookmark/index.d.ts +1 -0
  51. package/dist/types/components/edit-bookmark/EditBookmark.d.ts +5 -0
  52. package/dist/types/components/edit-bookmark/index.d.ts +1 -0
  53. package/dist/types/components/filter/Filter.d.ts +10 -0
  54. package/dist/types/components/import-bookmark/ImportBookmark.d.ts +1 -0
  55. package/dist/types/components/import-bookmark/index.d.ts +1 -0
  56. package/dist/types/components/loading/Loading.d.ts +1 -0
  57. package/dist/types/components/row/MoreMenu.d.ts +10 -0
  58. package/dist/types/components/row/Row.d.ts +17 -0
  59. package/dist/types/components/section/Section.d.ts +7 -0
  60. package/dist/types/components/sectionList/SectionList.d.ts +6 -0
  61. package/dist/types/components/shared/SharedIcon.d.ts +6 -0
  62. package/dist/types/hooks/index.d.ts +1 -0
  63. package/dist/types/hooks/useBookmarkGrouping.d.ts +14 -0
  64. package/dist/types/index.d.ts +2 -0
  65. package/dist/types/utils/append-bookmark-to-uri.d.ts +1 -0
  66. package/dist/types/utils/utils.d.ts +6 -0
  67. package/dist/types/version.d.ts +1 -0
  68. package/package.json +55 -0
  69. package/src/components/Bookmark.tsx +60 -0
  70. package/src/components/BookmarkProvider.tsx +65 -0
  71. package/src/components/create-bookmark/CreateBookmark.tsx +93 -0
  72. package/src/components/create-bookmark/index.ts +1 -0
  73. package/src/components/edit-bookmark/EditBookmark.tsx +137 -0
  74. package/src/components/edit-bookmark/index.ts +1 -0
  75. package/src/components/filter/Filter.tsx +58 -0
  76. package/src/components/import-bookmark/ImportBookmark.tsx +57 -0
  77. package/src/components/import-bookmark/index.ts +1 -0
  78. package/src/components/loading/Loading.tsx +16 -0
  79. package/src/components/row/MoreMenu.tsx +34 -0
  80. package/src/components/row/Row.tsx +92 -0
  81. package/src/components/section/Section.tsx +57 -0
  82. package/src/components/sectionList/SectionList.tsx +172 -0
  83. package/src/components/shared/SharedIcon.tsx +45 -0
  84. package/src/hooks/index.ts +1 -0
  85. package/src/hooks/useBookmarkGrouping.ts +54 -0
  86. package/src/index.ts +2 -0
  87. package/src/utils/append-bookmark-to-uri.ts +5 -0
  88. package/src/utils/utils.ts +12 -0
  89. package/src/version.ts +2 -0
  90. package/tsconfig.json +23 -0
@@ -0,0 +1,57 @@
1
+ import { Button, Dialog } from '@equinor/eds-core-react';
2
+ import { useBookmark } from '@equinor/fusion-framework-react-module-bookmark';
3
+ import { useEffect, useState } from 'react';
4
+
5
+ import styled from 'styled-components';
6
+
7
+ const Styled = {
8
+ Actions: styled.div`
9
+ display: flex;
10
+ gap: 1rem;
11
+ `,
12
+ };
13
+
14
+ export const ImportBookmarkModal = () => {
15
+ const [isOpen, setIsOpen] = useState(false);
16
+
17
+ const { currentBookmark, bookmarks, addBookmarkFavorite } = useBookmark();
18
+
19
+ useEffect(() => {
20
+ if (!bookmarks || !currentBookmark || bookmarks.length === 0) return;
21
+
22
+ if (bookmarks.findIndex(({ id }) => id === currentBookmark.id) === -1) {
23
+ setIsOpen(true);
24
+ }
25
+ }, [bookmarks, currentBookmark]);
26
+
27
+ return (
28
+ <Dialog style={{ width: '600px' }} open={isOpen}>
29
+ <Dialog.Header>Import bookmark</Dialog.Header>
30
+ <Dialog.Content>
31
+ <p>This bookmark was created by {currentBookmark?.createdBy.name}</p>
32
+ <p>Would you like to import it?</p>
33
+ </Dialog.Content>
34
+ <Dialog.Actions>
35
+ <Styled.Actions>
36
+ <Button
37
+ onClick={() => setIsOpen(false)}
38
+ variant={'ghost'}
39
+ style={{ width: '70px' }}
40
+ >
41
+ No
42
+ </Button>
43
+ <Button
44
+ onClick={() => {
45
+ console.log(currentBookmark?.id);
46
+ currentBookmark && addBookmarkFavorite(currentBookmark.id);
47
+ setIsOpen(false);
48
+ }}
49
+ variant="ghost"
50
+ >
51
+ Import
52
+ </Button>
53
+ </Styled.Actions>
54
+ </Dialog.Actions>
55
+ </Dialog>
56
+ );
57
+ };
@@ -0,0 +1 @@
1
+ export * from './ImportBookmark';
@@ -0,0 +1,16 @@
1
+ import { CircularProgress } from '@equinor/eds-core-react';
2
+ import React from 'react';
3
+
4
+ export const Loading = () => (
5
+ <div
6
+ style={{
7
+ display: 'flex',
8
+ alignItems: 'center',
9
+ justifyContent: 'center',
10
+ height: '100%',
11
+ width: '100%',
12
+ }}
13
+ >
14
+ <CircularProgress />
15
+ </div>
16
+ );
@@ -0,0 +1,34 @@
1
+ import { Menu } from '@equinor/eds-core-react';
2
+ import { MutableRefObject } from 'react';
3
+ import { MenuOption } from './Row';
4
+
5
+ type MenuProps = {
6
+ readonly pRef: MutableRefObject<HTMLElement | null>;
7
+ readonly onClose: VoidFunction;
8
+ readonly open: boolean;
9
+ readonly options: MenuOption[];
10
+ };
11
+
12
+ export const MoreMenu = ({ pRef, onClose, open, options }: MenuProps) => {
13
+ return (
14
+ <Menu open={open} anchorEl={pRef.current}>
15
+ {options.map(({ onClick, name, disabled, Icon }) => (
16
+ <Menu.Item
17
+ disabled={disabled}
18
+ onClick={(e) => {
19
+ e.stopPropagation();
20
+ e.preventDefault();
21
+ onClick();
22
+ onClose();
23
+ }}
24
+ key={name}
25
+ >
26
+ <>
27
+ {Icon && Icon}
28
+ {name}
29
+ </>
30
+ </Menu.Item>
31
+ ))}
32
+ </Menu>
33
+ );
34
+ };
@@ -0,0 +1,92 @@
1
+ import { Icon, Typography } from '@equinor/eds-core-react';
2
+ import { tokens } from '@equinor/eds-tokens';
3
+ import { useOutsideClick } from '@equinor/eds-utils';
4
+ import { useBookmark } from '@equinor/fusion-framework-react-module-bookmark';
5
+ import { MutableRefObject, ReactNode, useRef } from 'react';
6
+ import { MoreMenu } from './MoreMenu';
7
+
8
+ import styled from 'styled-components';
9
+
10
+ export type MenuOption = {
11
+ name: string;
12
+ disabled: boolean;
13
+ onClick: VoidFunction;
14
+ Icon?: ReactNode;
15
+ };
16
+
17
+ type RowProps = {
18
+ readonly name: string;
19
+ readonly id: string;
20
+ readonly menuOpen: boolean;
21
+ readonly onMenuOpen: (id: string) => void;
22
+ readonly menuOptions: MenuOption[];
23
+ readonly children?: ReactNode;
24
+ };
25
+
26
+ const Styled = {
27
+ Icons: styled.div`
28
+ display: flex;
29
+ flex-direction: row;
30
+ gap: 0.2em;
31
+ align-items: center;
32
+ `,
33
+ ListItem: styled.div`
34
+ cursor: pointer;
35
+ &:hover {
36
+ background-color: ${tokens.colors.ui.background__light.hex};
37
+ }
38
+
39
+ display: flex;
40
+ align-items: center;
41
+ height: 32px;
42
+ min-height: 32px;
43
+ max-height: 32px;
44
+ justify-content: space-between;
45
+ border-bottom: 1px solid ${tokens.colors.ui.background__medium.hex};
46
+ `,
47
+ };
48
+
49
+ export const Row = ({ name, menuOptions, children, id, menuOpen, onMenuOpen }: RowProps) => {
50
+ const pRef = useRef<HTMLElement | null>(null);
51
+ const { setCurrentBookmark } = useBookmark();
52
+
53
+ useOutsideClick(pRef.current, () => onMenuOpen(''));
54
+
55
+ // TODO: @noggling fix this
56
+ return (
57
+ /* eslint-disable-next-line styled-components-a11y/click-events-have-key-events, styled-components-a11y/no-static-element-interactions*/
58
+ <Styled.ListItem
59
+ onClick={(e) => {
60
+ e.preventDefault();
61
+ e.stopPropagation();
62
+ setCurrentBookmark(id);
63
+ }}
64
+ >
65
+ <Typography>{name}</Typography>
66
+ <Styled.Icons>
67
+ {children}
68
+ {!!menuOptions?.length && (
69
+ <Icon
70
+ name="more_vertical"
71
+ onClick={(e) => {
72
+ e.preventDefault();
73
+ e.stopPropagation();
74
+ onMenuOpen(id);
75
+ }}
76
+ color={tokens.colors.interactive.primary__resting.hex}
77
+ ref={pRef as unknown as MutableRefObject<SVGSVGElement>}
78
+ />
79
+ )}
80
+
81
+ <MoreMenu
82
+ open={menuOpen}
83
+ options={menuOptions}
84
+ onClose={() => {
85
+ onMenuOpen('');
86
+ }}
87
+ pRef={pRef}
88
+ />
89
+ </Styled.Icons>
90
+ </Styled.ListItem>
91
+ );
92
+ };
@@ -0,0 +1,57 @@
1
+ import { useState } from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { Button, Icon, Typography } from '@equinor/eds-core-react';
4
+ import { chevron_down, chevron_right } from '@equinor/eds-icons';
5
+
6
+ import { tokens } from '@equinor/eds-tokens';
7
+ import styled from 'styled-components';
8
+
9
+ const Styled = {
10
+ Button: styled(Button)`
11
+ width: 100%;
12
+ padding: 0;
13
+ padding-top: 0.5rem;
14
+ margin-bottom: 0.5rem;
15
+ display: flex;
16
+ justify-content: space-between;
17
+ align-items: center;
18
+ background: none;
19
+ border: none;
20
+ color: ${tokens.colors.infographic.primary__moss_green_100.hex};
21
+ cursor: pointer;
22
+ :hover {
23
+ background: none;
24
+ }
25
+ `,
26
+ List: styled.ol`
27
+ margin-left: 0.7rem;
28
+ padding-left: 1rem;
29
+ display: flex;
30
+ flex-direction: column;
31
+ gap: 1rem;
32
+ border-left: 1px solid ${tokens.colors.infographic.primary__moss_green_100.hex};
33
+ `,
34
+ };
35
+
36
+ Icon.add({
37
+ chevron_down,
38
+ chevron_right,
39
+ });
40
+
41
+ type SectionProps = {
42
+ readonly name: string;
43
+ readonly children: ReactNode;
44
+ };
45
+ export const Section = ({ children, name }: SectionProps) => {
46
+ const [isExpanded, setIsExpanded] = useState(true);
47
+
48
+ return (
49
+ <div>
50
+ <Styled.Button variant="ghost" onClick={() => setIsExpanded((s) => !s)}>
51
+ <Icon name={isExpanded ? chevron_down.name : chevron_right.name} />
52
+ <Typography variant="h6">{name}</Typography>
53
+ </Styled.Button>
54
+ {isExpanded && <Styled.List>{children}</Styled.List>}
55
+ </div>
56
+ );
57
+ };
@@ -0,0 +1,172 @@
1
+ import { Icon } from '@equinor/eds-core-react';
2
+ import { useBookmarkGrouping } from '../../hooks';
3
+ import { Row } from '../row/Row';
4
+ import { Section } from '../section/Section';
5
+ import { SharedIcon } from '../shared/SharedIcon';
6
+ // TODO - export from `@equinor/fusion-framework-react-module-bookmark`
7
+ import type { Bookmark } from '@equinor/fusion-framework-module-bookmark';
8
+ import { useBookmark } from '@equinor/fusion-framework-react-module-bookmark';
9
+ import { useCurrentUser } from '@equinor/fusion-framework-react/hooks';
10
+ import { useCallback, useEffect, useState } from 'react';
11
+ import { delete_to_trash, share, edit, close, update } from '@equinor/eds-icons';
12
+ import { useFramework } from '@equinor/fusion-framework-react';
13
+ import { appendBookmarkIdToUrl } from '../../utils/append-bookmark-to-uri';
14
+ import { filterEmptyGroups, sortByName, toHumanReadable } from '../../utils/utils';
15
+ import { Loading } from '../loading/Loading';
16
+
17
+ Icon.add({
18
+ delete_to_trash,
19
+ edit,
20
+ share,
21
+ close,
22
+ update,
23
+ });
24
+
25
+ type SectionListProps = {
26
+ readonly bookmarkGroups: ReturnType<typeof useBookmarkGrouping>['bookmarkGroups'];
27
+ };
28
+
29
+ export const SectionList = ({ bookmarkGroups }: SectionListProps) => {
30
+ const { deleteBookmarkById, getCurrentAppKey, updateBookmark, removeBookmarkFavorite } =
31
+ useBookmark();
32
+
33
+ const [loading, setLoading] = useState(true);
34
+
35
+ const user = useCurrentUser();
36
+ const [isMenuByIdOpen, setIsMenuByIdOpen] = useState('');
37
+
38
+ const { event } = useFramework().modules;
39
+
40
+ useEffect(() => {
41
+ return event.addEventListener('onBookmarksChanged', () => {
42
+ setLoading(false);
43
+ });
44
+ }, [event]);
45
+
46
+ const editBookmark = useCallback(
47
+ (bookmarkId: string) => {
48
+ event.dispatchEvent('onBookmarkEdit', { detail: { bookmarkId } });
49
+ },
50
+ [event],
51
+ );
52
+
53
+ const shareBookmark = useCallback(
54
+ (bookmark: Bookmark) => {
55
+ if (!bookmark.isShared) {
56
+ const url = appendBookmarkIdToUrl(bookmark.id);
57
+ navigator.clipboard.writeText(url);
58
+ event.dispatchEvent('onBookmarkUrlCopy', { detail: { url } });
59
+ }
60
+ updateBookmark({ ...bookmark, isShared: !bookmark.isShared });
61
+ },
62
+ [event, updateBookmark],
63
+ );
64
+
65
+ const updateBookmarkWithCurrentView = useCallback(
66
+ (bookmark: Bookmark) => {
67
+ updateBookmark({ ...bookmark }, { updatePayload: true });
68
+ },
69
+ [updateBookmark],
70
+ );
71
+
72
+ const createMenuOptions = (bookmark: Bookmark) =>
73
+ createBookmarkActions(
74
+ bookmark,
75
+ deleteBookmarkById,
76
+ editBookmark,
77
+ shareBookmark,
78
+ removeBookmarkFavorite,
79
+ updateBookmarkWithCurrentView,
80
+ getCurrentAppKey(),
81
+ user?.localAccountId,
82
+ );
83
+
84
+ if (loading) return <Loading />;
85
+
86
+ return (
87
+ <>
88
+ {bookmarkGroups.filter(filterEmptyGroups).map(({ groupingProperty, values }) => (
89
+ <Section key={groupingProperty} name={toHumanReadable(groupingProperty)}>
90
+ {values.sort(sortByName).map((b) => (
91
+ <Row
92
+ menuOptions={createMenuOptions(b)}
93
+ key={b.id}
94
+ name={b.name}
95
+ id={b.id}
96
+ menuOpen={isMenuByIdOpen === b.id}
97
+ onMenuOpen={(id: string) => {
98
+ setIsMenuByIdOpen(id);
99
+ }}
100
+ >
101
+ {b.isShared && (
102
+ <SharedIcon
103
+ createdById={b.createdBy.azureUniqueId}
104
+ createdBy={b.createdBy.name}
105
+ />
106
+ )}
107
+ </Row>
108
+ ))}
109
+ </Section>
110
+ ))}
111
+ </>
112
+ );
113
+ };
114
+
115
+ function createBookmarkActions(
116
+ bookmark: Bookmark,
117
+ deleteBookmarkById: (bookmarkId: string) => Promise<string | undefined>,
118
+ editBookmark: (bookmark: string) => void,
119
+ shareBookmark: (bookmark: Bookmark) => void,
120
+ removeBookmarkFavorite: (bookmarkId: string) => void,
121
+ updateBookmarkWithCurrentView: (bookmark: Bookmark) => void,
122
+ appKey?: string,
123
+ localAccountId?: string,
124
+ ) {
125
+ if (bookmark.createdBy.azureUniqueId === localAccountId) {
126
+ return [
127
+ {
128
+ name: 'Edit',
129
+ disabled: appKey !== bookmark.appKey,
130
+ onClick: () => {
131
+ editBookmark(bookmark.id);
132
+ },
133
+ Icon: <Icon name="edit" />,
134
+ },
135
+ {
136
+ name: 'Update with current view',
137
+ disabled: appKey !== bookmark.appKey,
138
+ onClick: () => {
139
+ updateBookmarkWithCurrentView(bookmark);
140
+ },
141
+ Icon: <Icon name="update" />,
142
+ },
143
+ {
144
+ name: 'Remove',
145
+ disabled: false,
146
+ onClick: () => {
147
+ deleteBookmarkById(bookmark.id);
148
+ },
149
+ Icon: <Icon name="delete_to_trash" />,
150
+ },
151
+ {
152
+ name: bookmark.isShared ? 'Unshare' : 'Share',
153
+ disabled: false,
154
+ onClick: () => {
155
+ shareBookmark(bookmark);
156
+ },
157
+ Icon: <Icon name="share" />,
158
+ },
159
+ ];
160
+ } else {
161
+ return [
162
+ {
163
+ name: 'Unfavourite',
164
+ disabled: false,
165
+ onClick: () => {
166
+ removeBookmarkFavorite(bookmark.id);
167
+ },
168
+ Icon: <Icon name="close" />,
169
+ },
170
+ ];
171
+ }
172
+ }
@@ -0,0 +1,45 @@
1
+ import { Icon } from '@equinor/eds-core-react';
2
+ import { tokens } from '@equinor/eds-tokens';
3
+ import { useFramework } from '@equinor/fusion-framework-react';
4
+
5
+ import styled from 'styled-components';
6
+
7
+ const Styled = {
8
+ Row: styled.div`
9
+ display: flex;
10
+ align-items: center;
11
+ gap: 0.2em;
12
+ `,
13
+ CreatedBy: styled.p`
14
+ font-size: 12px;
15
+ font-weight: 500;
16
+ line-height: 16px;
17
+ letter-spacing: 0em;
18
+ text-align: right;
19
+ `,
20
+ };
21
+
22
+ type SharedIconProps = {
23
+ readonly createdBy: string;
24
+ readonly createdById: string;
25
+ };
26
+
27
+ export const SharedIcon = ({ createdBy, createdById }: SharedIconProps) => {
28
+ const myId = useFramework().modules.auth.defaultAccount?.localAccountId;
29
+
30
+ const isMe = createdById === myId;
31
+
32
+ return (
33
+ <Styled.Row>
34
+ {!isMe && <Styled.CreatedBy>shared by {createdBy}</Styled.CreatedBy>}
35
+ <Icon
36
+ name="share"
37
+ color={
38
+ isMe
39
+ ? tokens.colors.interactive.primary__resting.hex
40
+ : tokens.colors.interactive.disabled__border.hex
41
+ }
42
+ />
43
+ </Styled.Row>
44
+ );
45
+ };
@@ -0,0 +1 @@
1
+ export * from './useBookmarkGrouping';
@@ -0,0 +1,54 @@
1
+ import { Bookmark } from '@equinor/fusion-framework-module-bookmark';
2
+
3
+ import { useState } from 'react';
4
+
5
+ export type GroupingKeys = 'Group by app' | 'Created by' | 'Group by Context';
6
+
7
+ const groupingModes: Record<GroupingKeys, (_item: Bookmark) => string> = {
8
+ 'Group by app': (item: Bookmark) => item.appKey,
9
+ 'Created by': (item: Bookmark) => item.createdBy.name,
10
+ 'Group by Context': (item: Bookmark) => item?.context?.name ?? 'Unknown',
11
+ } as const;
12
+
13
+ export const useBookmarkGrouping = (bookmarks?: Bookmark[]) => {
14
+ const [searchText, setSearchText] = useState<string | null>(null);
15
+
16
+ const [groupByKey, setGroupBy] = useState<keyof typeof groupingModes>('Group by app');
17
+
18
+ const bookmarkGroups = groupBy(bookmarks || [], groupingModes[groupByKey], searchText, 'name');
19
+
20
+ return {
21
+ setGroupBy,
22
+ setSearchText,
23
+ searchText,
24
+ bookmarkGroups,
25
+ groupingModes,
26
+ groupByKey,
27
+ };
28
+ };
29
+
30
+ const groupBy = <T>(
31
+ array: T[],
32
+ getKey: (item: T) => string,
33
+ searchText: string | null,
34
+ field: keyof T,
35
+ ) => {
36
+ return (
37
+ array
38
+ ?.map(getKey)
39
+ .filter((v, i, a) => a.indexOf(v) === i)
40
+ .map((groupingProperty) => ({
41
+ groupingProperty,
42
+ values: array
43
+ .filter((s) => getKey(s) === groupingProperty)
44
+ .filter((s) => {
45
+ const fieldData = s[field];
46
+ if (typeof fieldData === 'string' && searchText) {
47
+ return fieldData.includes(searchText);
48
+ }
49
+
50
+ return true;
51
+ }),
52
+ })) ?? []
53
+ );
54
+ };
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { Bookmark } from './components/Bookmark';
2
+ export { BookmarkProvider } from './components/BookmarkProvider';
@@ -0,0 +1,5 @@
1
+ export const appendBookmarkIdToUrl = (id: string): string => {
2
+ const url = new URL(window.location.toString());
3
+ url.searchParams.set('bookmarkId', id);
4
+ return url.toString();
5
+ };
@@ -0,0 +1,12 @@
1
+ import { Bookmark } from '@equinor/fusion-framework-module-bookmark';
2
+
3
+ /** Helpers.. */
4
+ export const filterEmptyGroups = (i: { values: Bookmark[] }) => i.values.length;
5
+ export const sortByName = (a: Bookmark, b: Bookmark) => a.name.localeCompare(b.name);
6
+ // const extractNameFromMail = (mail: string) => mail.split('@')[0].toLowerCase();
7
+
8
+ export const toHumanReadable = (val: string) =>
9
+ val
10
+ .split('-')
11
+ .map((s) => `${s[0].toUpperCase()}${s.slice(1)}`)
12
+ .join(' ');
package/src/version.ts ADDED
@@ -0,0 +1,2 @@
1
+ // Generated by genversion.
2
+ export const version = '0.2.6';
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/bookmark"
14
+ }
15
+ ],
16
+ "include": [
17
+ "src/**/*"
18
+ ],
19
+ "exclude": [
20
+ "node_modules",
21
+ "lib"
22
+ ]
23
+ }