@ndla/ui 13.2.2 → 15.1.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/es/Article/Article.js +22 -3
- package/es/Article/ArticleFavoritesButton.js +38 -0
- package/es/Article/index.js +2 -1
- package/es/Breadcrumb/ActionBreadcrumb.js +57 -0
- package/es/Breadcrumb/index.js +1 -0
- package/es/Footer/FooterAuth.js +15 -22
- package/es/InfoBlock/InfoBlock.js +55 -0
- package/es/InfoBlock/index.js +1 -0
- package/es/LearningPaths/LearningPathMenu.js +3 -4
- package/es/Masthead/MastheadAuthModal.js +2 -2
- package/es/MyNdla/Navigation/VerticalNavigation.js +51 -0
- package/es/MyNdla/Navigation/index.js +2 -0
- package/es/MyNdla/Resource/Folder.js +86 -0
- package/es/MyNdla/Resource/FolderInput.js +96 -0
- package/{lib/MyNdla/ResourceDash/ResourcesView.d.ts → es/MyNdla/Resource/index.js} +3 -3
- package/es/MyNdla/index.js +4 -4
- package/es/Resource/BlockResource.js +73 -0
- package/es/Resource/ListResource.js +66 -0
- package/es/Resource/index.js +10 -0
- package/es/Resource/resourceComponents.js +97 -0
- package/es/ResourceGroup/ResourceGroup.js +7 -5
- package/es/ResourceGroup/ResourceItem.js +28 -30
- package/es/ResourceGroup/ResourceList.js +18 -6
- package/es/Search/ActiveFilters.js +6 -7
- package/es/Search/ContentTypeResult.js +6 -8
- package/es/SearchTypeResult/ActiveFilters.js +6 -10
- package/es/SnackBar/SnackBar.js +117 -0
- package/es/SnackBar/index.js +9 -0
- package/es/TagSelector/SuggestionInput.js +240 -0
- package/es/TagSelector/Suggestions.js +93 -0
- package/es/TagSelector/TagSelector.js +137 -0
- package/es/TagSelector/index.js +9 -0
- package/es/TopicIntroductionList/TopicIntroduction.js +2 -4
- package/es/TopicIntroductionList/TopicShortcutItem.js +1 -3
- package/es/TreeStructure/FolderItem.js +130 -0
- package/es/TreeStructure/FolderItems.js +123 -0
- package/es/TreeStructure/FolderNameInput.js +112 -0
- package/es/TreeStructure/TreeStructure.js +254 -0
- package/es/TreeStructure/TreeStructure.types.js +0 -0
- package/es/TreeStructure/TreeStructureWrapper.js +13 -0
- package/es/TreeStructure/helperFunctions.js +92 -0
- package/es/TreeStructure/index.js +9 -0
- package/es/TreeStructure/keyboardNavigation/keyboardNavigation.js +182 -0
- package/es/TreeStructure/keyboardNavigation/keyboardNavigation.types.js +0 -0
- package/es/User/AuthModal.js +15 -24
- package/es/User/UserInfo.js +70 -0
- package/es/User/apiTypes.js +0 -0
- package/es/User/index.js +2 -0
- package/es/User/parseUserObject.js +102 -0
- package/es/all.css +90 -0
- package/es/index.js +9 -3
- package/es/locale/messages-en.js +71 -4
- package/es/locale/messages-nb.js +70 -3
- package/es/locale/messages-nn.js +70 -3
- package/es/locale/messages-se.js +70 -3
- package/es/locale/messages-sma.js +70 -3
- package/lib/Article/Article.d.ts +3 -1
- package/lib/Article/Article.js +43 -23
- package/lib/Article/ArticleFavoritesButton.d.ts +15 -0
- package/lib/Article/ArticleFavoritesButton.js +56 -0
- package/lib/Article/index.d.ts +2 -1
- package/lib/Article/index.js +8 -0
- package/lib/Breadcrumb/ActionBreadcrumb.d.ts +16 -0
- package/lib/Breadcrumb/ActionBreadcrumb.js +72 -0
- package/lib/Breadcrumb/index.d.ts +1 -0
- package/lib/Breadcrumb/index.js +8 -0
- package/lib/Footer/FooterAuth.d.ts +1 -1
- package/lib/Footer/FooterAuth.js +17 -17
- package/lib/InfoBlock/InfoBlock.d.ts +8 -0
- package/lib/InfoBlock/InfoBlock.js +58 -0
- package/lib/InfoBlock/index.d.ts +1 -0
- package/lib/InfoBlock/index.js +13 -0
- package/lib/LearningPaths/LearningPathMenu.js +3 -4
- package/lib/Masthead/MastheadAuthModal.d.ts +3 -3
- package/lib/Masthead/MastheadAuthModal.js +3 -3
- package/lib/MyNdla/Navigation/VerticalNavigation.d.ts +10 -0
- package/lib/MyNdla/Navigation/VerticalNavigation.js +61 -0
- package/lib/MyNdla/Navigation/index.d.ts +2 -0
- package/lib/MyNdla/Navigation/index.js +15 -0
- package/lib/MyNdla/Resource/Folder.d.ts +20 -0
- package/lib/MyNdla/Resource/Folder.js +100 -0
- package/lib/MyNdla/Resource/FolderInput.d.ts +15 -0
- package/lib/MyNdla/Resource/FolderInput.js +116 -0
- package/lib/MyNdla/Resource/index.d.ts +10 -0
- package/lib/MyNdla/Resource/index.js +23 -0
- package/lib/MyNdla/index.d.ts +4 -4
- package/lib/MyNdla/index.js +13 -7
- package/lib/Resource/BlockResource.d.ts +20 -0
- package/lib/Resource/BlockResource.js +84 -0
- package/lib/Resource/ListResource.d.ts +20 -0
- package/lib/Resource/ListResource.js +78 -0
- package/lib/Resource/index.d.ts +11 -0
- package/lib/Resource/index.js +29 -0
- package/lib/Resource/resourceComponents.d.ts +24 -0
- package/lib/Resource/resourceComponents.js +106 -0
- package/lib/ResourceGroup/ResourceGroup.d.ts +2 -1
- package/lib/ResourceGroup/ResourceGroup.js +7 -5
- package/lib/ResourceGroup/ResourceItem.d.ts +5 -1
- package/lib/ResourceGroup/ResourceItem.js +29 -30
- package/lib/ResourceGroup/ResourceList.d.ts +3 -1
- package/lib/ResourceGroup/ResourceList.js +18 -6
- package/lib/Search/ActiveFilters.js +6 -7
- package/lib/Search/ContentTypeResult.js +6 -8
- package/lib/SearchTypeResult/ActiveFilters.js +6 -10
- package/lib/SnackBar/SnackBar.d.ts +23 -0
- package/lib/SnackBar/SnackBar.js +127 -0
- package/lib/SnackBar/index.d.ts +10 -0
- package/lib/SnackBar/index.js +15 -0
- package/lib/TagSelector/SuggestionInput.d.ts +19 -0
- package/lib/TagSelector/SuggestionInput.js +255 -0
- package/lib/TagSelector/Suggestions.d.ts +12 -0
- package/lib/TagSelector/Suggestions.js +96 -0
- package/lib/TagSelector/TagSelector.d.ts +16 -0
- package/lib/TagSelector/TagSelector.js +150 -0
- package/lib/TagSelector/index.d.ts +10 -0
- package/lib/TagSelector/index.js +19 -0
- package/lib/TopicIntroductionList/TopicIntroduction.js +2 -4
- package/lib/TopicIntroductionList/TopicShortcutItem.js +1 -3
- package/lib/TreeStructure/FolderItem.d.ts +27 -0
- package/lib/TreeStructure/FolderItem.js +140 -0
- package/lib/TreeStructure/FolderItems.d.ts +11 -0
- package/lib/TreeStructure/FolderItems.js +130 -0
- package/lib/TreeStructure/FolderNameInput.d.ts +15 -0
- package/lib/TreeStructure/FolderNameInput.js +125 -0
- package/lib/TreeStructure/TreeStructure.d.ts +12 -0
- package/lib/TreeStructure/TreeStructure.js +273 -0
- package/lib/TreeStructure/TreeStructure.types.d.ts +63 -0
- package/lib/TreeStructure/TreeStructure.types.js +1 -0
- package/lib/TreeStructure/TreeStructureWrapper.d.ts +12 -0
- package/lib/TreeStructure/TreeStructureWrapper.js +24 -0
- package/lib/TreeStructure/helperFunctions.d.ts +5 -0
- package/lib/TreeStructure/helperFunctions.js +103 -0
- package/lib/TreeStructure/index.d.ts +10 -0
- package/lib/TreeStructure/index.js +15 -0
- package/lib/TreeStructure/keyboardNavigation/keyboardNavigation.d.ts +11 -0
- package/lib/TreeStructure/keyboardNavigation/keyboardNavigation.js +186 -0
- package/lib/TreeStructure/keyboardNavigation/keyboardNavigation.types.d.ts +26 -0
- package/lib/TreeStructure/keyboardNavigation/keyboardNavigation.types.js +1 -0
- package/lib/User/AuthModal.d.ts +3 -3
- package/lib/User/AuthModal.js +16 -23
- package/lib/User/UserInfo.d.ts +13 -0
- package/lib/User/UserInfo.js +84 -0
- package/lib/User/apiTypes.d.ts +61 -0
- package/lib/User/apiTypes.js +1 -0
- package/lib/User/index.d.ts +4 -0
- package/lib/User/index.js +8 -0
- package/lib/User/parseUserObject.d.ts +32 -0
- package/lib/User/parseUserObject.js +105 -0
- package/lib/all.css +90 -0
- package/lib/index.d.ts +14 -3
- package/lib/index.js +83 -10
- package/lib/locale/messages-en.d.ts +67 -0
- package/lib/locale/messages-en.js +71 -4
- package/lib/locale/messages-nb.d.ts +67 -0
- package/lib/locale/messages-nb.js +70 -3
- package/lib/locale/messages-nn.d.ts +67 -0
- package/lib/locale/messages-nn.js +70 -3
- package/lib/locale/messages-se.d.ts +67 -0
- package/lib/locale/messages-se.js +70 -3
- package/lib/locale/messages-sma.d.ts +67 -0
- package/lib/locale/messages-sma.js +70 -3
- package/lib/types.d.ts +1 -1
- package/package.json +11 -11
- package/src/Article/Article.tsx +31 -0
- package/src/Article/ArticleFavoritesButton.tsx +40 -0
- package/src/Article/index.ts +2 -0
- package/src/Breadcrumb/ActionBreadcrumb.tsx +68 -0
- package/src/Breadcrumb/index.ts +2 -0
- package/src/Footer/FooterAuth.tsx +7 -9
- package/src/InfoBlock/InfoBlock.tsx +61 -0
- package/src/InfoBlock/index.ts +1 -0
- package/src/LearningPaths/LearningPathMenu.tsx +1 -1
- package/src/Masthead/MastheadAuthModal.tsx +4 -5
- package/src/MyNdla/Navigation/VerticalNavigation.tsx +93 -0
- package/src/MyNdla/Navigation/index.ts +2 -0
- package/src/MyNdla/Resource/Folder.tsx +145 -0
- package/src/MyNdla/Resource/FolderInput.tsx +104 -0
- package/src/MyNdla/Resource/index.ts +11 -0
- package/src/MyNdla/index.ts +4 -5
- package/src/Resource/BlockResource.tsx +101 -0
- package/src/Resource/ListResource.tsx +111 -0
- package/src/Resource/index.ts +12 -0
- package/src/Resource/resourceComponents.tsx +143 -0
- package/src/ResourceGroup/ResourceGroup.tsx +3 -0
- package/src/ResourceGroup/ResourceItem.tsx +20 -3
- package/src/ResourceGroup/ResourceList.tsx +16 -3
- package/src/Search/ActiveFilters.jsx +0 -1
- package/src/Search/ContentTypeResult.tsx +8 -9
- package/src/SearchTypeResult/ActiveFilters.tsx +1 -3
- package/src/SnackBar/SnackBar.tsx +183 -0
- package/src/SnackBar/index.ts +13 -0
- package/src/TagSelector/SuggestionInput.tsx +230 -0
- package/src/TagSelector/Suggestions.tsx +125 -0
- package/src/TagSelector/TagSelector.tsx +111 -0
- package/src/TagSelector/index.ts +13 -0
- package/src/TopicIntroductionList/TopicIntroduction.tsx +2 -2
- package/src/TopicIntroductionList/TopicShortcutItem.tsx +1 -5
- package/src/TreeStructure/FolderItem.tsx +160 -0
- package/src/TreeStructure/FolderItems.tsx +109 -0
- package/src/TreeStructure/FolderNameInput.tsx +109 -0
- package/src/TreeStructure/TreeStructure.tsx +184 -0
- package/src/TreeStructure/TreeStructure.types.ts +69 -0
- package/src/TreeStructure/TreeStructureWrapper.tsx +34 -0
- package/src/TreeStructure/helperFunctions.ts +52 -0
- package/src/TreeStructure/index.ts +11 -0
- package/src/TreeStructure/keyboardNavigation/keyboardNavigation.ts +161 -0
- package/src/TreeStructure/keyboardNavigation/keyboardNavigation.types.ts +28 -0
- package/src/User/AuthModal.tsx +5 -26
- package/src/User/UserInfo.tsx +80 -0
- package/src/User/__tests__/parseUserObject-test.ts +315 -0
- package/src/User/apiTypes.ts +74 -0
- package/src/User/index.ts +4 -0
- package/src/User/parseUserObject.ts +83 -0
- package/src/all.scss +2 -0
- package/src/index.ts +15 -4
- package/src/locale/messages-en.ts +65 -3
- package/src/locale/messages-nb.ts +64 -2
- package/src/locale/messages-nn.ts +64 -2
- package/src/locale/messages-se.ts +64 -2
- package/src/locale/messages-sma.ts +64 -2
- package/src/types.ts +1 -1
- package/es/MyNdla/ResourceDash/Breadcrumbs.js +0 -22
- package/es/MyNdla/ResourceDash/ResourceElement.js +0 -27
- package/es/MyNdla/ResourceDash/ResourcesView.js +0 -43
- package/es/MyNdla/ResourceDash/index.js +0 -4
- package/lib/MyNdla/ResourceDash/Breadcrumbs.d.ts +0 -15
- package/lib/MyNdla/ResourceDash/Breadcrumbs.js +0 -35
- package/lib/MyNdla/ResourceDash/ResourceElement.d.ts +0 -18
- package/lib/MyNdla/ResourceDash/ResourceElement.js +0 -38
- package/lib/MyNdla/ResourceDash/ResourcesView.js +0 -57
- package/lib/MyNdla/ResourceDash/index.d.ts +0 -4
- package/lib/MyNdla/ResourceDash/index.js +0 -31
- package/src/MyNdla/ResourceDash/Breadcrumbs.tsx +0 -31
- package/src/MyNdla/ResourceDash/ResourceElement.tsx +0 -50
- package/src/MyNdla/ResourceDash/ResourcesView.tsx +0 -42
- package/src/MyNdla/ResourceDash/index.ts +0 -5
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2022-present, NDLA.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the GPLv3 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { FolderStructureProps, SetFocusedFolderId } from '../TreeStructure.types';
|
|
10
|
+
import { KeyboardNavigationProps, ElementWithKeyFocusProps } from './keyboardNavigation.types';
|
|
11
|
+
import { MAX_LEVEL_FOR_FOLDERS } from '../TreeStructure';
|
|
12
|
+
|
|
13
|
+
export const KEYBOARD_KEYS_OF_INTEREST = ['ArrowDown', 'ArrowUp', 'ArrowRight', 'ArrowLeft', ' '];
|
|
14
|
+
|
|
15
|
+
// Traverse upwards, incase parent is last element of its parent..
|
|
16
|
+
const traverseUpwards = (
|
|
17
|
+
inital: FolderStructureProps[],
|
|
18
|
+
setFocusedFolderId: SetFocusedFolderId,
|
|
19
|
+
paths: number[],
|
|
20
|
+
index: number,
|
|
21
|
+
) => {
|
|
22
|
+
let findParent: FolderStructureProps[] = inital;
|
|
23
|
+
const parentNextIds: (string | false)[] = [];
|
|
24
|
+
paths.forEach((pathIndex) => {
|
|
25
|
+
const nextParent = findParent ? findParent[pathIndex + 1] : undefined;
|
|
26
|
+
parentNextIds.push(nextParent?.id || false);
|
|
27
|
+
findParent = findParent[pathIndex].data || [];
|
|
28
|
+
});
|
|
29
|
+
if (!parentNextIds.length) {
|
|
30
|
+
parentNextIds.push(findParent[index + 1]?.id || false);
|
|
31
|
+
}
|
|
32
|
+
// We use a reversed version of parentNextIds, filtered out falses, to find the next element
|
|
33
|
+
// No newId? We are at the end of the tree so we wont update.
|
|
34
|
+
const newId = parentNextIds.reverse().filter((id) => id)[0];
|
|
35
|
+
if (newId) {
|
|
36
|
+
setFocusedFolderId(newId);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const keyboardNavigation = ({
|
|
41
|
+
e,
|
|
42
|
+
data,
|
|
43
|
+
onToggleOpen,
|
|
44
|
+
setFocusedFolderId,
|
|
45
|
+
focusedFolderId: id,
|
|
46
|
+
openFolders,
|
|
47
|
+
}: KeyboardNavigationProps): string | undefined => {
|
|
48
|
+
if (e.key === ' ' && document.activeElement?.nodeName === 'INPUT') {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// We are navigating in the tree.
|
|
53
|
+
// We need to find the next folder in the tree
|
|
54
|
+
const elementWithKeyFocus: ElementWithKeyFocusProps = {
|
|
55
|
+
paths: [],
|
|
56
|
+
index: 0,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const updatePathToElementWithKeyFocus = (
|
|
60
|
+
data: FolderStructureProps[],
|
|
61
|
+
paths: number[],
|
|
62
|
+
parent: FolderStructureProps[],
|
|
63
|
+
parentId?: string,
|
|
64
|
+
): boolean =>
|
|
65
|
+
data.some(({ data: childData, id: dataId, url }, _index) => {
|
|
66
|
+
if (dataId === id) {
|
|
67
|
+
elementWithKeyFocus.paths = paths;
|
|
68
|
+
elementWithKeyFocus.index = _index;
|
|
69
|
+
elementWithKeyFocus.isOpen = openFolders.has(dataId) && childData && childData.length > 0;
|
|
70
|
+
elementWithKeyFocus.data = childData;
|
|
71
|
+
elementWithKeyFocus.parent = parent;
|
|
72
|
+
elementWithKeyFocus.parentId = parentId;
|
|
73
|
+
elementWithKeyFocus.url = url;
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
return childData ? updatePathToElementWithKeyFocus(childData, [...paths, _index], [...childData], dataId) : false;
|
|
77
|
+
});
|
|
78
|
+
if (!updatePathToElementWithKeyFocus(data, [], data)) {
|
|
79
|
+
// Couldn't find its location in the tree.
|
|
80
|
+
// This should not happen, reset its value to root.
|
|
81
|
+
setFocusedFolderId(e.key === 'ArrowDown' ? data[0].id : undefined);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
e.preventDefault();
|
|
85
|
+
e.stopPropagation();
|
|
86
|
+
|
|
87
|
+
if (e.key === ' ') {
|
|
88
|
+
const simulatedEvent = new MouseEvent('click', {
|
|
89
|
+
bubbles: true,
|
|
90
|
+
cancelable: true,
|
|
91
|
+
view: window,
|
|
92
|
+
});
|
|
93
|
+
document.activeElement && document.activeElement.dispatchEvent(simulatedEvent);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (e.key === 'ArrowRight') {
|
|
98
|
+
if (
|
|
99
|
+
!elementWithKeyFocus.isOpen &&
|
|
100
|
+
elementWithKeyFocus.data?.length &&
|
|
101
|
+
id &&
|
|
102
|
+
elementWithKeyFocus.paths.length < MAX_LEVEL_FOR_FOLDERS - 1
|
|
103
|
+
) {
|
|
104
|
+
onToggleOpen(id);
|
|
105
|
+
}
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (e.key === 'ArrowLeft') {
|
|
109
|
+
if (id && elementWithKeyFocus.isOpen) {
|
|
110
|
+
onToggleOpen(id);
|
|
111
|
+
}
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (!id && e.key === 'ArrowDown') {
|
|
116
|
+
setFocusedFolderId(data[0].id);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (!id) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
// Move up
|
|
123
|
+
if (e.key === 'ArrowUp') {
|
|
124
|
+
if (elementWithKeyFocus.index > 0) {
|
|
125
|
+
// Move upwards to the parent folder
|
|
126
|
+
setFocusedFolderId(
|
|
127
|
+
elementWithKeyFocus.parent ? elementWithKeyFocus.parent[elementWithKeyFocus.index - 1].id : undefined,
|
|
128
|
+
);
|
|
129
|
+
} else if (elementWithKeyFocus.paths.length > 0) {
|
|
130
|
+
elementWithKeyFocus.paths.pop();
|
|
131
|
+
let findParent = data;
|
|
132
|
+
elementWithKeyFocus.paths.forEach((index) => {
|
|
133
|
+
findParent = findParent[index].data as FolderStructureProps[];
|
|
134
|
+
});
|
|
135
|
+
const parentsCurrentIndex = findParent.findIndex(({ id }) => id === elementWithKeyFocus.parentId);
|
|
136
|
+
setFocusedFolderId(findParent[parentsCurrentIndex].id);
|
|
137
|
+
}
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (elementWithKeyFocus.isOpen) {
|
|
142
|
+
if (elementWithKeyFocus.data?.length) {
|
|
143
|
+
setFocusedFolderId(elementWithKeyFocus.data[0].id);
|
|
144
|
+
} else {
|
|
145
|
+
// move to next child of parent if any... need new traverse :-/
|
|
146
|
+
traverseUpwards(data, setFocusedFolderId, elementWithKeyFocus.paths, elementWithKeyFocus.index);
|
|
147
|
+
}
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (elementWithKeyFocus.parent && elementWithKeyFocus.index < elementWithKeyFocus.parent?.length - 1) {
|
|
152
|
+
// Move downwards to the next child
|
|
153
|
+
setFocusedFolderId(elementWithKeyFocus.parent[elementWithKeyFocus.index + 1].id);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
traverseUpwards(data, setFocusedFolderId, elementWithKeyFocus.paths, elementWithKeyFocus.index);
|
|
158
|
+
return;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
export default keyboardNavigation;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2022-present, NDLA.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the GPLv3 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { FolderStructureProps, SetFocusedFolderId } from '../TreeStructure.types';
|
|
10
|
+
|
|
11
|
+
export interface KeyboardNavigationProps {
|
|
12
|
+
e: React.KeyboardEvent<HTMLElement>;
|
|
13
|
+
data: FolderStructureProps[];
|
|
14
|
+
setFocusedFolderId: SetFocusedFolderId;
|
|
15
|
+
openFolders: Set<string>;
|
|
16
|
+
onToggleOpen: (id: string) => void;
|
|
17
|
+
focusedFolderId: string | undefined;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface ElementWithKeyFocusProps {
|
|
21
|
+
paths: number[];
|
|
22
|
+
index: number;
|
|
23
|
+
data?: FolderStructureProps[];
|
|
24
|
+
parent?: FolderStructureProps[];
|
|
25
|
+
parentId?: string;
|
|
26
|
+
isOpen?: boolean;
|
|
27
|
+
url?: string;
|
|
28
|
+
}
|
package/src/User/AuthModal.tsx
CHANGED
|
@@ -13,6 +13,8 @@ import Modal, { ModalCloseButton } from '@ndla/modal';
|
|
|
13
13
|
import Button from '@ndla/button';
|
|
14
14
|
import { FeideText, LogIn, LogOut, HumanMaleBoard } from '@ndla/icons/common';
|
|
15
15
|
import { fonts, spacing } from '@ndla/core';
|
|
16
|
+
import { UserInfo } from './UserInfo';
|
|
17
|
+
import { FeideUserApiType } from './apiTypes';
|
|
16
18
|
|
|
17
19
|
const StyledModalBody = styled.div`
|
|
18
20
|
padding: ${spacing.normal} ${spacing.medium} ${spacing.medium};
|
|
@@ -38,17 +40,6 @@ const StyledHeading = styled.h2`
|
|
|
38
40
|
}
|
|
39
41
|
`;
|
|
40
42
|
|
|
41
|
-
const StyledAuthorizedInfoList = styled.ul`
|
|
42
|
-
margin: 0;
|
|
43
|
-
padding: 0 0 0 ${spacing.normal};
|
|
44
|
-
list-style-image: unset;
|
|
45
|
-
|
|
46
|
-
li {
|
|
47
|
-
margin: 0;
|
|
48
|
-
font-weight: ${fonts.weight.semibold};
|
|
49
|
-
}
|
|
50
|
-
`;
|
|
51
|
-
|
|
52
43
|
const StyledHumanMaleBoardIconWrapper = styled.span`
|
|
53
44
|
margin-left: ${spacing.xsmall};
|
|
54
45
|
`;
|
|
@@ -63,9 +54,8 @@ const StyledButtonWrapper = styled.div`
|
|
|
63
54
|
|
|
64
55
|
export type AuthModalProps = {
|
|
65
56
|
isAuthenticated?: boolean;
|
|
57
|
+
user?: FeideUserApiType;
|
|
66
58
|
showGeneralMessage?: boolean;
|
|
67
|
-
authorizedRole?: string;
|
|
68
|
-
authorizedCollectedInfo?: string[];
|
|
69
59
|
onAuthenticateClick: () => void;
|
|
70
60
|
position?: 'top' | 'bottom';
|
|
71
61
|
activateButton?: ReactElement;
|
|
@@ -76,9 +66,8 @@ export type AuthModalProps = {
|
|
|
76
66
|
|
|
77
67
|
const AuthModal = ({
|
|
78
68
|
isAuthenticated,
|
|
69
|
+
user,
|
|
79
70
|
showGeneralMessage = true,
|
|
80
|
-
authorizedRole,
|
|
81
|
-
authorizedCollectedInfo,
|
|
82
71
|
onAuthenticateClick,
|
|
83
72
|
position = 'top',
|
|
84
73
|
activateButton,
|
|
@@ -104,17 +93,7 @@ const AuthModal = ({
|
|
|
104
93
|
<ModalCloseButton onClick={onClose} title="Lukk" />
|
|
105
94
|
</StyledModalHeader>
|
|
106
95
|
<StyledModalContent>
|
|
107
|
-
{
|
|
108
|
-
{authorizedCollectedInfo && authorizedCollectedInfo.length > 0 && (
|
|
109
|
-
<div>
|
|
110
|
-
{t('user.modal.collectedInfo')}
|
|
111
|
-
<StyledAuthorizedInfoList>
|
|
112
|
-
{authorizedCollectedInfo.map((value) => (
|
|
113
|
-
<li key={value}>{value}</li>
|
|
114
|
-
))}
|
|
115
|
-
</StyledAuthorizedInfoList>
|
|
116
|
-
</div>
|
|
117
|
-
)}
|
|
96
|
+
{user && <UserInfo user={user} />}
|
|
118
97
|
{children}
|
|
119
98
|
{showGeneralMessage && (
|
|
120
99
|
<p>
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2022-present, NDLA.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the GPLv3 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import styled from '@emotion/styled';
|
|
9
|
+
import { spacing } from '@ndla/core';
|
|
10
|
+
import React from 'react';
|
|
11
|
+
import { useTranslation } from 'react-i18next';
|
|
12
|
+
import { FeideUserApiType } from './apiTypes';
|
|
13
|
+
import { parseUserObject } from './parseUserObject';
|
|
14
|
+
|
|
15
|
+
const InfoList = styled.ul`
|
|
16
|
+
padding: 0 0 0 ${spacing.normal};
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
interface Props {
|
|
20
|
+
user: FeideUserApiType;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const ShortInfoDiv = styled.div`
|
|
24
|
+
margin: 2rem auto;
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
export const UserInfo = ({ user }: Props) => {
|
|
28
|
+
const { t } = useTranslation();
|
|
29
|
+
|
|
30
|
+
const parsedUser = parseUserObject(user);
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<div>
|
|
34
|
+
{
|
|
35
|
+
<p>
|
|
36
|
+
{t('user.loggedInAs', {
|
|
37
|
+
role: t(`user.role.${parsedUser.primaryAffiliation}`),
|
|
38
|
+
})}
|
|
39
|
+
</p>
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
<ShortInfoDiv>
|
|
43
|
+
<div>
|
|
44
|
+
{t('user.username')}: <b>{user.uid}</b>
|
|
45
|
+
</div>
|
|
46
|
+
<div>
|
|
47
|
+
{t('user.name')}: <b>{user.displayName}</b>
|
|
48
|
+
</div>
|
|
49
|
+
<div>
|
|
50
|
+
{t('user.mail')}: <b>{user.mail?.join(', ')}</b>
|
|
51
|
+
</div>
|
|
52
|
+
</ShortInfoDiv>
|
|
53
|
+
|
|
54
|
+
{t('user.modal.collectedInfo')}
|
|
55
|
+
|
|
56
|
+
<InfoList>
|
|
57
|
+
{parsedUser.organizations.map((org) => (
|
|
58
|
+
<li key={org.id}>
|
|
59
|
+
{`${org.displayName}${org.membership.primarySchool ? ` (${t('user.primarySchool')})` : ''}`}
|
|
60
|
+
<InfoList>
|
|
61
|
+
{Object.entries(org.children).map(([groupType, val]) => {
|
|
62
|
+
if (val.length < 1) return null;
|
|
63
|
+
return (
|
|
64
|
+
<li key={groupType}>
|
|
65
|
+
{t(`user.groupTypes.${groupType}`)}
|
|
66
|
+
<InfoList>
|
|
67
|
+
{val.map((group) => (
|
|
68
|
+
<li key={group.id}>{`${group.displayName}${group.grep ? ` (${group.grep.code})` : ''}`}</li>
|
|
69
|
+
))}
|
|
70
|
+
</InfoList>
|
|
71
|
+
</li>
|
|
72
|
+
);
|
|
73
|
+
})}
|
|
74
|
+
</InfoList>
|
|
75
|
+
</li>
|
|
76
|
+
))}
|
|
77
|
+
</InfoList>
|
|
78
|
+
</div>
|
|
79
|
+
);
|
|
80
|
+
};
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2022-present, NDLA.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the GPLv3 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { FeideUserApiType } from '../apiTypes';
|
|
10
|
+
import { parseUserObject } from '../parseUserObject';
|
|
11
|
+
|
|
12
|
+
const feideUserLaerer: FeideUserApiType = {
|
|
13
|
+
cn: ['David LærerVGS Jonsen'],
|
|
14
|
+
displayName: 'David LærerVGS Jonsen',
|
|
15
|
+
eduPersonAffiliation: ['member', 'employee', 'faculty'],
|
|
16
|
+
eduPersonPrimaryAffiliation: 'employee',
|
|
17
|
+
eduPersonPrincipalName: 'david_laerervgs@spusers.feide.no',
|
|
18
|
+
givenName: ['David LærerVGS'],
|
|
19
|
+
mail: ['david_laerervgs@feide.no'],
|
|
20
|
+
sn: ['Jonsen'],
|
|
21
|
+
uid: ['david_laerervgs'],
|
|
22
|
+
groups: [
|
|
23
|
+
{
|
|
24
|
+
id: 'fc:org:spusers.feide.no',
|
|
25
|
+
displayName: 'Rogn fylkeskommune',
|
|
26
|
+
type: 'fc:org',
|
|
27
|
+
public: false,
|
|
28
|
+
membership: {
|
|
29
|
+
basic: 'admin',
|
|
30
|
+
affiliation: ['member', 'employee', 'faculty'],
|
|
31
|
+
primaryAffiliation: 'employee',
|
|
32
|
+
displayName: 'Akademisk ansatt',
|
|
33
|
+
},
|
|
34
|
+
orgType: ['higher_education', 'upper_secondary_owner', 'primary_and_lower_secondary_owner'],
|
|
35
|
+
norEduOrgNIN: 'NO956326503',
|
|
36
|
+
eduOrgLegalName: 'Rogn fylkeskommune',
|
|
37
|
+
mail: 'support@feide.no',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
id: 'fc:org:spusers.feide.no:unit:NO956326504',
|
|
41
|
+
parent: 'fc:org:spusers.feide.no',
|
|
42
|
+
displayName: 'Lind VGS',
|
|
43
|
+
type: 'fc:org',
|
|
44
|
+
public: false,
|
|
45
|
+
membership: {
|
|
46
|
+
basic: 'member',
|
|
47
|
+
primarySchool: true,
|
|
48
|
+
},
|
|
49
|
+
orgType: ['primary_and_lower_secondary'],
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: 'fc:org:spusers.feide.no:unit:NO856326501',
|
|
53
|
+
parent: 'fc:org:spusers.feide.no',
|
|
54
|
+
displayName: 'Lerk VGS',
|
|
55
|
+
type: 'fc:org',
|
|
56
|
+
public: false,
|
|
57
|
+
membership: {
|
|
58
|
+
basic: 'member',
|
|
59
|
+
primarySchool: false,
|
|
60
|
+
},
|
|
61
|
+
orgType: ['primary_and_lower_secondary'],
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: 'fc:gogroup:spusers.feide.no:b:NO856326501:1sta:2000-07-01:2100-06-30',
|
|
65
|
+
displayName: 'Klasse 1STA',
|
|
66
|
+
type: 'fc:gogroup',
|
|
67
|
+
notBefore: '2000-06-30T22:00:00Z',
|
|
68
|
+
notAfter: '2100-06-30T23:00:00Z',
|
|
69
|
+
go_type: 'b',
|
|
70
|
+
parent: 'fc:org:spusers.feide.no:unit:NO856326501',
|
|
71
|
+
membership: {
|
|
72
|
+
basic: 'member',
|
|
73
|
+
affiliation: 'employee',
|
|
74
|
+
displayName: 'Ansatt',
|
|
75
|
+
},
|
|
76
|
+
go_type_displayName: 'basisgruppe',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: 'fc:gogroup:spusers.feide.no:a:NO856326501:1sta-lab1:2000-07-01:2100-06-30',
|
|
80
|
+
displayName: 'Laboratoriegruppe 1',
|
|
81
|
+
type: 'fc:gogroup',
|
|
82
|
+
notBefore: '2000-06-30T22:00:00Z',
|
|
83
|
+
notAfter: '2100-06-30T23:00:00Z',
|
|
84
|
+
go_type: 'a',
|
|
85
|
+
parent: 'fc:org:spusers.feide.no:unit:NO856326501',
|
|
86
|
+
membership: {
|
|
87
|
+
basic: 'member',
|
|
88
|
+
affiliation: 'employee',
|
|
89
|
+
displayName: 'Ansatt',
|
|
90
|
+
},
|
|
91
|
+
go_type_displayName: 'other groups',
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
id: 'fc:gogroup:spusers.feide.no:a:NO856326501:1sta-lab2:2000-07-01:2100-06-30',
|
|
95
|
+
displayName: 'Laboratoriegruppe 2',
|
|
96
|
+
type: 'fc:gogroup',
|
|
97
|
+
notBefore: '2000-06-30T22:00:00Z',
|
|
98
|
+
notAfter: '2100-06-30T23:00:00Z',
|
|
99
|
+
go_type: 'a',
|
|
100
|
+
parent: 'fc:org:spusers.feide.no:unit:NO856326501',
|
|
101
|
+
membership: {
|
|
102
|
+
basic: 'member',
|
|
103
|
+
affiliation: 'employee',
|
|
104
|
+
displayName: 'Ansatt',
|
|
105
|
+
},
|
|
106
|
+
go_type_displayName: 'other groups',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
id: 'fc:gogroup:spusers.feide.no:u:NO856326501:1mat11-1map1:2000-07-01:2100-06-30',
|
|
110
|
+
displayName: 'Matematikk 1P',
|
|
111
|
+
type: 'fc:gogroup',
|
|
112
|
+
notBefore: '2000-06-30T22:00:00Z',
|
|
113
|
+
notAfter: '2100-06-30T23:00:00Z',
|
|
114
|
+
go_type: 'u',
|
|
115
|
+
parent: 'fc:org:spusers.feide.no:unit:NO856326501',
|
|
116
|
+
membership: {
|
|
117
|
+
basic: 'member',
|
|
118
|
+
affiliation: 'employee',
|
|
119
|
+
displayName: 'Ansatt',
|
|
120
|
+
},
|
|
121
|
+
go_type_displayName: 'undervisningsgruppe',
|
|
122
|
+
grep: {
|
|
123
|
+
displayName: 'Mathematics 1P',
|
|
124
|
+
code: 'MAT1011',
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
id: 'fc:gogroup:spusers.feide.no:u:NO856326501:1mat13-1mat1:2000-07-01:2100-06-30',
|
|
129
|
+
displayName: 'Matematikk 1T',
|
|
130
|
+
type: 'fc:gogroup',
|
|
131
|
+
notBefore: '2000-06-30T22:00:00Z',
|
|
132
|
+
notAfter: '2100-06-30T23:00:00Z',
|
|
133
|
+
go_type: 'u',
|
|
134
|
+
parent: 'fc:org:spusers.feide.no:unit:NO856326501',
|
|
135
|
+
membership: {
|
|
136
|
+
basic: 'member',
|
|
137
|
+
affiliation: 'employee',
|
|
138
|
+
displayName: 'Ansatt',
|
|
139
|
+
},
|
|
140
|
+
go_type_displayName: 'undervisningsgruppe',
|
|
141
|
+
grep: {
|
|
142
|
+
displayName: 'Mathematics 1T',
|
|
143
|
+
code: 'MAT1013',
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
primarySchool: {
|
|
148
|
+
id: 'fc:org:spusers.feide.no:unit:NO956326504',
|
|
149
|
+
parent: 'fc:org:spusers.feide.no',
|
|
150
|
+
displayName: 'Lind VGS',
|
|
151
|
+
type: 'fc:org',
|
|
152
|
+
public: false,
|
|
153
|
+
membership: {
|
|
154
|
+
basic: 'member',
|
|
155
|
+
primarySchool: true,
|
|
156
|
+
},
|
|
157
|
+
orgType: ['primary_and_lower_secondary'],
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
describe('parseUserObject', () => {
|
|
162
|
+
it('Correctly parses Feide user', () => {
|
|
163
|
+
const expected = {
|
|
164
|
+
uid: ['david_laerervgs'],
|
|
165
|
+
primaryAffiliation: 'employee',
|
|
166
|
+
displayName: 'David LærerVGS Jonsen',
|
|
167
|
+
mail: ['david_laerervgs@feide.no'],
|
|
168
|
+
organizations: [
|
|
169
|
+
{
|
|
170
|
+
id: 'fc:org:spusers.feide.no',
|
|
171
|
+
displayName: 'Rogn fylkeskommune',
|
|
172
|
+
type: 'fc:org',
|
|
173
|
+
public: false,
|
|
174
|
+
membership: {
|
|
175
|
+
basic: 'admin',
|
|
176
|
+
affiliation: ['member', 'employee', 'faculty'],
|
|
177
|
+
primaryAffiliation: 'employee',
|
|
178
|
+
displayName: 'Akademisk ansatt',
|
|
179
|
+
},
|
|
180
|
+
orgType: ['higher_education', 'upper_secondary_owner', 'primary_and_lower_secondary_owner'],
|
|
181
|
+
norEduOrgNIN: 'NO956326503',
|
|
182
|
+
eduOrgLegalName: 'Rogn fylkeskommune',
|
|
183
|
+
mail: 'support@feide.no',
|
|
184
|
+
children: {
|
|
185
|
+
basic: [],
|
|
186
|
+
teaching: [],
|
|
187
|
+
other: [],
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
id: 'fc:org:spusers.feide.no:unit:NO956326504',
|
|
192
|
+
parent: 'fc:org:spusers.feide.no',
|
|
193
|
+
displayName: 'Lind VGS',
|
|
194
|
+
type: 'fc:org',
|
|
195
|
+
public: false,
|
|
196
|
+
membership: {
|
|
197
|
+
basic: 'member',
|
|
198
|
+
primarySchool: true,
|
|
199
|
+
},
|
|
200
|
+
orgType: ['primary_and_lower_secondary'],
|
|
201
|
+
children: {
|
|
202
|
+
basic: [],
|
|
203
|
+
teaching: [],
|
|
204
|
+
other: [],
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
id: 'fc:org:spusers.feide.no:unit:NO856326501',
|
|
209
|
+
parent: 'fc:org:spusers.feide.no',
|
|
210
|
+
displayName: 'Lerk VGS',
|
|
211
|
+
type: 'fc:org',
|
|
212
|
+
public: false,
|
|
213
|
+
membership: {
|
|
214
|
+
basic: 'member',
|
|
215
|
+
primarySchool: false,
|
|
216
|
+
},
|
|
217
|
+
orgType: ['primary_and_lower_secondary'],
|
|
218
|
+
children: {
|
|
219
|
+
basic: [
|
|
220
|
+
{
|
|
221
|
+
id: 'fc:gogroup:spusers.feide.no:b:NO856326501:1sta:2000-07-01:2100-06-30',
|
|
222
|
+
displayName: 'Klasse 1STA',
|
|
223
|
+
type: 'fc:gogroup',
|
|
224
|
+
notBefore: '2000-06-30T22:00:00Z',
|
|
225
|
+
notAfter: '2100-06-30T23:00:00Z',
|
|
226
|
+
go_type: 'b',
|
|
227
|
+
parent: 'fc:org:spusers.feide.no:unit:NO856326501',
|
|
228
|
+
membership: {
|
|
229
|
+
basic: 'member',
|
|
230
|
+
affiliation: 'employee',
|
|
231
|
+
displayName: 'Ansatt',
|
|
232
|
+
},
|
|
233
|
+
go_type_displayName: 'basisgruppe',
|
|
234
|
+
},
|
|
235
|
+
],
|
|
236
|
+
teaching: [
|
|
237
|
+
{
|
|
238
|
+
id: 'fc:gogroup:spusers.feide.no:u:NO856326501:1mat11-1map1:2000-07-01:2100-06-30',
|
|
239
|
+
displayName: 'Matematikk 1P',
|
|
240
|
+
type: 'fc:gogroup',
|
|
241
|
+
notBefore: '2000-06-30T22:00:00Z',
|
|
242
|
+
notAfter: '2100-06-30T23:00:00Z',
|
|
243
|
+
go_type: 'u',
|
|
244
|
+
parent: 'fc:org:spusers.feide.no:unit:NO856326501',
|
|
245
|
+
membership: {
|
|
246
|
+
basic: 'member',
|
|
247
|
+
affiliation: 'employee',
|
|
248
|
+
displayName: 'Ansatt',
|
|
249
|
+
},
|
|
250
|
+
go_type_displayName: 'undervisningsgruppe',
|
|
251
|
+
grep: {
|
|
252
|
+
displayName: 'Mathematics 1P',
|
|
253
|
+
code: 'MAT1011',
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
id: 'fc:gogroup:spusers.feide.no:u:NO856326501:1mat13-1mat1:2000-07-01:2100-06-30',
|
|
258
|
+
displayName: 'Matematikk 1T',
|
|
259
|
+
type: 'fc:gogroup',
|
|
260
|
+
notBefore: '2000-06-30T22:00:00Z',
|
|
261
|
+
notAfter: '2100-06-30T23:00:00Z',
|
|
262
|
+
go_type: 'u',
|
|
263
|
+
parent: 'fc:org:spusers.feide.no:unit:NO856326501',
|
|
264
|
+
membership: {
|
|
265
|
+
basic: 'member',
|
|
266
|
+
affiliation: 'employee',
|
|
267
|
+
displayName: 'Ansatt',
|
|
268
|
+
},
|
|
269
|
+
go_type_displayName: 'undervisningsgruppe',
|
|
270
|
+
grep: {
|
|
271
|
+
displayName: 'Mathematics 1T',
|
|
272
|
+
code: 'MAT1013',
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
],
|
|
276
|
+
other: [
|
|
277
|
+
{
|
|
278
|
+
id: 'fc:gogroup:spusers.feide.no:a:NO856326501:1sta-lab1:2000-07-01:2100-06-30',
|
|
279
|
+
displayName: 'Laboratoriegruppe 1',
|
|
280
|
+
type: 'fc:gogroup',
|
|
281
|
+
notBefore: '2000-06-30T22:00:00Z',
|
|
282
|
+
notAfter: '2100-06-30T23:00:00Z',
|
|
283
|
+
go_type: 'a',
|
|
284
|
+
parent: 'fc:org:spusers.feide.no:unit:NO856326501',
|
|
285
|
+
membership: {
|
|
286
|
+
basic: 'member',
|
|
287
|
+
affiliation: 'employee',
|
|
288
|
+
displayName: 'Ansatt',
|
|
289
|
+
},
|
|
290
|
+
go_type_displayName: 'other groups',
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
id: 'fc:gogroup:spusers.feide.no:a:NO856326501:1sta-lab2:2000-07-01:2100-06-30',
|
|
294
|
+
displayName: 'Laboratoriegruppe 2',
|
|
295
|
+
type: 'fc:gogroup',
|
|
296
|
+
notBefore: '2000-06-30T22:00:00Z',
|
|
297
|
+
notAfter: '2100-06-30T23:00:00Z',
|
|
298
|
+
go_type: 'a',
|
|
299
|
+
parent: 'fc:org:spusers.feide.no:unit:NO856326501',
|
|
300
|
+
membership: {
|
|
301
|
+
basic: 'member',
|
|
302
|
+
affiliation: 'employee',
|
|
303
|
+
displayName: 'Ansatt',
|
|
304
|
+
},
|
|
305
|
+
go_type_displayName: 'other groups',
|
|
306
|
+
},
|
|
307
|
+
],
|
|
308
|
+
},
|
|
309
|
+
},
|
|
310
|
+
],
|
|
311
|
+
};
|
|
312
|
+
const actual = parseUserObject(feideUserLaerer);
|
|
313
|
+
expect(actual).toEqual(expected);
|
|
314
|
+
});
|
|
315
|
+
});
|