@ndla/ui 13.2.1 → 15.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.
Files changed (245) hide show
  1. package/es/Article/Article.js +22 -3
  2. package/es/Article/ArticleFavoritesButton.js +38 -0
  3. package/es/Article/index.js +2 -1
  4. package/es/Breadcrumb/ActionBreadcrumb.js +57 -0
  5. package/es/Breadcrumb/index.js +1 -0
  6. package/es/Footer/FooterAuth.js +15 -22
  7. package/es/InfoBlock/InfoBlock.js +55 -0
  8. package/es/InfoBlock/index.js +1 -0
  9. package/es/LearningPaths/LearningPathMenu.js +3 -4
  10. package/es/Masthead/MastheadAuthModal.js +2 -2
  11. package/es/MyNdla/Navigation/VerticalNavigation.js +51 -0
  12. package/es/MyNdla/Navigation/index.js +2 -0
  13. package/es/MyNdla/Resource/Folder.js +86 -0
  14. package/{lib/MyNdla/ResourceDash/ResourcesView.d.ts → es/MyNdla/Resource/index.js} +2 -3
  15. package/es/MyNdla/index.js +3 -4
  16. package/es/Notion/ConceptNotion.js +2 -1
  17. package/es/Notion/FigureNotion.js +13 -9
  18. package/es/Notion/NotionVisualElement.js +3 -2
  19. package/es/Resource/BlockResource.js +73 -0
  20. package/es/Resource/ListResource.js +66 -0
  21. package/es/Resource/index.js +10 -0
  22. package/es/Resource/resourceComponents.js +97 -0
  23. package/es/ResourceGroup/ResourceGroup.js +7 -5
  24. package/es/ResourceGroup/ResourceItem.js +28 -30
  25. package/es/ResourceGroup/ResourceList.js +18 -6
  26. package/es/Search/ActiveFilters.js +6 -7
  27. package/es/Search/ContentTypeResult.js +6 -8
  28. package/es/SearchTypeResult/ActiveFilters.js +6 -10
  29. package/es/SearchTypeResult/SearchViewType.js +5 -5
  30. package/es/SnackBar/SnackBar.js +117 -0
  31. package/es/SnackBar/index.js +9 -0
  32. package/es/TagSelector/SuggestionInput.js +240 -0
  33. package/es/TagSelector/Suggestions.js +93 -0
  34. package/es/TagSelector/TagSelector.js +137 -0
  35. package/es/TagSelector/index.js +9 -0
  36. package/es/TopicIntroductionList/TopicIntroduction.js +2 -4
  37. package/es/TopicIntroductionList/TopicShortcutItem.js +1 -3
  38. package/es/TreeStructure/FolderItem.js +130 -0
  39. package/es/TreeStructure/FolderItems.js +123 -0
  40. package/es/TreeStructure/FolderNameInput.js +112 -0
  41. package/es/TreeStructure/TreeStructure.js +254 -0
  42. package/es/TreeStructure/TreeStructure.types.js +0 -0
  43. package/es/TreeStructure/TreeStructureWrapper.js +13 -0
  44. package/es/TreeStructure/helperFunctions.js +92 -0
  45. package/es/TreeStructure/index.js +9 -0
  46. package/es/TreeStructure/keyboardNavigation/keyboardNavigation.js +182 -0
  47. package/es/TreeStructure/keyboardNavigation/keyboardNavigation.types.js +0 -0
  48. package/es/User/AuthModal.js +15 -24
  49. package/es/User/UserInfo.js +70 -0
  50. package/es/User/apiTypes.js +0 -0
  51. package/es/User/index.js +2 -0
  52. package/es/User/parseUserObject.js +102 -0
  53. package/es/all.css +90 -0
  54. package/es/index.js +9 -3
  55. package/es/locale/messages-en.js +75 -8
  56. package/es/locale/messages-nb.js +74 -7
  57. package/es/locale/messages-nn.js +74 -7
  58. package/es/locale/messages-se.js +74 -7
  59. package/es/locale/messages-sma.js +74 -7
  60. package/lib/Article/Article.d.ts +3 -1
  61. package/lib/Article/Article.js +43 -23
  62. package/lib/Article/ArticleFavoritesButton.d.ts +15 -0
  63. package/lib/Article/ArticleFavoritesButton.js +56 -0
  64. package/lib/Article/index.d.ts +2 -1
  65. package/lib/Article/index.js +8 -0
  66. package/lib/Breadcrumb/ActionBreadcrumb.d.ts +16 -0
  67. package/lib/Breadcrumb/ActionBreadcrumb.js +72 -0
  68. package/lib/Breadcrumb/index.d.ts +1 -0
  69. package/lib/Breadcrumb/index.js +8 -0
  70. package/lib/Footer/FooterAuth.d.ts +1 -1
  71. package/lib/Footer/FooterAuth.js +17 -17
  72. package/lib/InfoBlock/InfoBlock.d.ts +8 -0
  73. package/lib/InfoBlock/InfoBlock.js +58 -0
  74. package/lib/InfoBlock/index.d.ts +1 -0
  75. package/lib/InfoBlock/index.js +13 -0
  76. package/lib/LearningPaths/LearningPathMenu.js +3 -4
  77. package/lib/Masthead/MastheadAuthModal.d.ts +3 -3
  78. package/lib/Masthead/MastheadAuthModal.js +3 -3
  79. package/lib/MyNdla/Navigation/VerticalNavigation.d.ts +10 -0
  80. package/lib/MyNdla/Navigation/VerticalNavigation.js +61 -0
  81. package/lib/MyNdla/Navigation/index.d.ts +2 -0
  82. package/lib/MyNdla/Navigation/index.js +15 -0
  83. package/lib/MyNdla/Resource/Folder.d.ts +20 -0
  84. package/lib/MyNdla/Resource/Folder.js +100 -0
  85. package/lib/MyNdla/Resource/index.d.ts +9 -0
  86. package/lib/MyNdla/Resource/index.js +15 -0
  87. package/lib/MyNdla/index.d.ts +3 -4
  88. package/lib/MyNdla/index.js +9 -11
  89. package/lib/Notion/ConceptNotion.js +2 -1
  90. package/lib/Notion/FigureNotion.d.ts +1 -1
  91. package/lib/Notion/FigureNotion.js +12 -8
  92. package/lib/Notion/NotionVisualElement.js +3 -2
  93. package/lib/Resource/BlockResource.d.ts +20 -0
  94. package/lib/Resource/BlockResource.js +84 -0
  95. package/lib/Resource/ListResource.d.ts +20 -0
  96. package/lib/Resource/ListResource.js +78 -0
  97. package/lib/Resource/index.d.ts +11 -0
  98. package/lib/Resource/index.js +29 -0
  99. package/lib/Resource/resourceComponents.d.ts +24 -0
  100. package/lib/Resource/resourceComponents.js +106 -0
  101. package/lib/ResourceGroup/ResourceGroup.d.ts +2 -1
  102. package/lib/ResourceGroup/ResourceGroup.js +7 -5
  103. package/lib/ResourceGroup/ResourceItem.d.ts +5 -1
  104. package/lib/ResourceGroup/ResourceItem.js +29 -30
  105. package/lib/ResourceGroup/ResourceList.d.ts +3 -1
  106. package/lib/ResourceGroup/ResourceList.js +18 -6
  107. package/lib/Search/ActiveFilters.js +6 -7
  108. package/lib/Search/ContentTypeResult.js +6 -8
  109. package/lib/SearchTypeResult/ActiveFilters.js +6 -10
  110. package/lib/SearchTypeResult/SearchViewType.js +5 -5
  111. package/lib/SnackBar/SnackBar.d.ts +23 -0
  112. package/lib/SnackBar/SnackBar.js +127 -0
  113. package/lib/SnackBar/index.d.ts +10 -0
  114. package/lib/SnackBar/index.js +15 -0
  115. package/lib/TagSelector/SuggestionInput.d.ts +19 -0
  116. package/lib/TagSelector/SuggestionInput.js +255 -0
  117. package/lib/TagSelector/Suggestions.d.ts +12 -0
  118. package/lib/TagSelector/Suggestions.js +96 -0
  119. package/lib/TagSelector/TagSelector.d.ts +16 -0
  120. package/lib/TagSelector/TagSelector.js +150 -0
  121. package/lib/TagSelector/index.d.ts +10 -0
  122. package/lib/TagSelector/index.js +19 -0
  123. package/lib/TopicIntroductionList/TopicIntroduction.js +2 -4
  124. package/lib/TopicIntroductionList/TopicShortcutItem.js +1 -3
  125. package/lib/TreeStructure/FolderItem.d.ts +27 -0
  126. package/lib/TreeStructure/FolderItem.js +140 -0
  127. package/lib/TreeStructure/FolderItems.d.ts +11 -0
  128. package/lib/TreeStructure/FolderItems.js +130 -0
  129. package/lib/TreeStructure/FolderNameInput.d.ts +15 -0
  130. package/lib/TreeStructure/FolderNameInput.js +125 -0
  131. package/lib/TreeStructure/TreeStructure.d.ts +12 -0
  132. package/lib/TreeStructure/TreeStructure.js +273 -0
  133. package/lib/TreeStructure/TreeStructure.types.d.ts +63 -0
  134. package/lib/TreeStructure/TreeStructure.types.js +1 -0
  135. package/lib/TreeStructure/TreeStructureWrapper.d.ts +12 -0
  136. package/lib/TreeStructure/TreeStructureWrapper.js +24 -0
  137. package/lib/TreeStructure/helperFunctions.d.ts +5 -0
  138. package/lib/TreeStructure/helperFunctions.js +103 -0
  139. package/lib/TreeStructure/index.d.ts +10 -0
  140. package/lib/TreeStructure/index.js +15 -0
  141. package/lib/TreeStructure/keyboardNavigation/keyboardNavigation.d.ts +11 -0
  142. package/lib/TreeStructure/keyboardNavigation/keyboardNavigation.js +186 -0
  143. package/lib/TreeStructure/keyboardNavigation/keyboardNavigation.types.d.ts +26 -0
  144. package/lib/TreeStructure/keyboardNavigation/keyboardNavigation.types.js +1 -0
  145. package/lib/User/AuthModal.d.ts +3 -3
  146. package/lib/User/AuthModal.js +16 -23
  147. package/lib/User/UserInfo.d.ts +13 -0
  148. package/lib/User/UserInfo.js +84 -0
  149. package/lib/User/apiTypes.d.ts +61 -0
  150. package/lib/User/apiTypes.js +1 -0
  151. package/lib/User/index.d.ts +4 -0
  152. package/lib/User/index.js +8 -0
  153. package/lib/User/parseUserObject.d.ts +32 -0
  154. package/lib/User/parseUserObject.js +105 -0
  155. package/lib/all.css +90 -0
  156. package/lib/index.d.ts +14 -3
  157. package/lib/index.js +76 -10
  158. package/lib/locale/messages-en.d.ts +67 -0
  159. package/lib/locale/messages-en.js +75 -8
  160. package/lib/locale/messages-nb.d.ts +67 -0
  161. package/lib/locale/messages-nb.js +74 -7
  162. package/lib/locale/messages-nn.d.ts +67 -0
  163. package/lib/locale/messages-nn.js +74 -7
  164. package/lib/locale/messages-se.d.ts +67 -0
  165. package/lib/locale/messages-se.js +74 -7
  166. package/lib/locale/messages-sma.d.ts +67 -0
  167. package/lib/locale/messages-sma.js +74 -7
  168. package/lib/types.d.ts +1 -1
  169. package/package.json +11 -11
  170. package/src/Article/Article.tsx +31 -0
  171. package/src/Article/ArticleFavoritesButton.tsx +40 -0
  172. package/src/Article/index.ts +2 -0
  173. package/src/Breadcrumb/ActionBreadcrumb.tsx +68 -0
  174. package/src/Breadcrumb/index.ts +2 -0
  175. package/src/Footer/FooterAuth.tsx +7 -9
  176. package/src/InfoBlock/InfoBlock.tsx +61 -0
  177. package/src/InfoBlock/index.ts +1 -0
  178. package/src/LearningPaths/LearningPathMenu.tsx +1 -1
  179. package/src/Masthead/MastheadAuthModal.tsx +4 -5
  180. package/src/MyNdla/Navigation/VerticalNavigation.tsx +93 -0
  181. package/src/MyNdla/Navigation/index.ts +2 -0
  182. package/src/MyNdla/Resource/Folder.tsx +143 -0
  183. package/src/MyNdla/Resource/index.ts +10 -0
  184. package/src/MyNdla/index.ts +3 -5
  185. package/src/Notion/ConceptNotion.tsx +1 -0
  186. package/src/Notion/FigureNotion.tsx +12 -5
  187. package/src/Notion/NotionVisualElement.tsx +1 -1
  188. package/src/Resource/BlockResource.tsx +101 -0
  189. package/src/Resource/ListResource.tsx +111 -0
  190. package/src/Resource/index.ts +12 -0
  191. package/src/Resource/resourceComponents.tsx +143 -0
  192. package/src/ResourceGroup/ResourceGroup.tsx +3 -0
  193. package/src/ResourceGroup/ResourceItem.tsx +20 -3
  194. package/src/ResourceGroup/ResourceList.tsx +16 -3
  195. package/src/Search/ActiveFilters.jsx +0 -1
  196. package/src/Search/ContentTypeResult.tsx +8 -9
  197. package/src/SearchTypeResult/ActiveFilters.tsx +1 -3
  198. package/src/SearchTypeResult/SearchViewType.tsx +1 -1
  199. package/src/SnackBar/SnackBar.tsx +183 -0
  200. package/src/SnackBar/index.ts +13 -0
  201. package/src/TagSelector/SuggestionInput.tsx +230 -0
  202. package/src/TagSelector/Suggestions.tsx +125 -0
  203. package/src/TagSelector/TagSelector.tsx +111 -0
  204. package/src/TagSelector/index.ts +13 -0
  205. package/src/TopicIntroductionList/TopicIntroduction.tsx +2 -2
  206. package/src/TopicIntroductionList/TopicShortcutItem.tsx +1 -5
  207. package/src/TreeStructure/FolderItem.tsx +160 -0
  208. package/src/TreeStructure/FolderItems.tsx +109 -0
  209. package/src/TreeStructure/FolderNameInput.tsx +109 -0
  210. package/src/TreeStructure/TreeStructure.tsx +184 -0
  211. package/src/TreeStructure/TreeStructure.types.ts +69 -0
  212. package/src/TreeStructure/TreeStructureWrapper.tsx +34 -0
  213. package/src/TreeStructure/helperFunctions.ts +52 -0
  214. package/src/TreeStructure/index.ts +11 -0
  215. package/src/TreeStructure/keyboardNavigation/keyboardNavigation.ts +161 -0
  216. package/src/TreeStructure/keyboardNavigation/keyboardNavigation.types.ts +28 -0
  217. package/src/User/AuthModal.tsx +5 -26
  218. package/src/User/UserInfo.tsx +80 -0
  219. package/src/User/__tests__/parseUserObject-test.ts +315 -0
  220. package/src/User/apiTypes.ts +74 -0
  221. package/src/User/index.ts +4 -0
  222. package/src/User/parseUserObject.ts +83 -0
  223. package/src/all.scss +2 -0
  224. package/src/index.ts +15 -4
  225. package/src/locale/messages-en.ts +69 -7
  226. package/src/locale/messages-nb.ts +68 -6
  227. package/src/locale/messages-nn.ts +68 -6
  228. package/src/locale/messages-se.ts +68 -6
  229. package/src/locale/messages-sma.ts +68 -6
  230. package/src/types.ts +1 -1
  231. package/es/MyNdla/ResourceDash/Breadcrumbs.js +0 -22
  232. package/es/MyNdla/ResourceDash/ResourceElement.js +0 -27
  233. package/es/MyNdla/ResourceDash/ResourcesView.js +0 -43
  234. package/es/MyNdla/ResourceDash/index.js +0 -4
  235. package/lib/MyNdla/ResourceDash/Breadcrumbs.d.ts +0 -15
  236. package/lib/MyNdla/ResourceDash/Breadcrumbs.js +0 -35
  237. package/lib/MyNdla/ResourceDash/ResourceElement.d.ts +0 -18
  238. package/lib/MyNdla/ResourceDash/ResourceElement.js +0 -38
  239. package/lib/MyNdla/ResourceDash/ResourcesView.js +0 -57
  240. package/lib/MyNdla/ResourceDash/index.d.ts +0 -4
  241. package/lib/MyNdla/ResourceDash/index.js +0 -31
  242. package/src/MyNdla/ResourceDash/Breadcrumbs.tsx +0 -31
  243. package/src/MyNdla/ResourceDash/ResourceElement.tsx +0 -50
  244. package/src/MyNdla/ResourceDash/ResourcesView.tsx +0 -42
  245. package/src/MyNdla/ResourceDash/index.ts +0 -5
@@ -0,0 +1,52 @@
1
+ import { FolderStructureProps } from './TreeStructure.types';
2
+
3
+ const getPathOfFolder = (data: FolderStructureProps[], findId: string): string[] => {
4
+ const paths = (dataChildren: FolderStructureProps[], path: string[]): string[] => {
5
+ for (const { id, data: dataChildrenSub } of dataChildren) {
6
+ if (id === findId) {
7
+ return [...path, id];
8
+ } else if (dataChildrenSub?.length) {
9
+ return paths(dataChildrenSub, [...path, id]);
10
+ }
11
+ }
12
+ return [];
13
+ };
14
+ return paths(data, []);
15
+ };
16
+
17
+ const getIdPathsOfFolder = (data: FolderStructureProps[], findId: string): number[] => {
18
+ let currentPath: number[] = [];
19
+ const paths = (dataChildren: FolderStructureProps[], path: number[]) => {
20
+ dataChildren.forEach(({ id, data: dataChildrenSub }, _index) => {
21
+ if (id === findId) {
22
+ currentPath = [...path, _index];
23
+ } else if (dataChildrenSub?.length) {
24
+ paths(dataChildrenSub, [...path, _index]);
25
+ }
26
+ });
27
+ };
28
+ paths(data, []);
29
+ return currentPath;
30
+ };
31
+
32
+ const getFolderName = (data: FolderStructureProps[], findId: string | undefined): string | undefined => {
33
+ if (!findId) {
34
+ return undefined;
35
+ }
36
+ let folderName: string | undefined;
37
+ const paths = (dataChildren: FolderStructureProps[]) => {
38
+ dataChildren.some(({ id, name, data: dataChildrenSub }, _index) => {
39
+ if (id === findId) {
40
+ folderName = name;
41
+ return true;
42
+ } else if (dataChildrenSub?.length) {
43
+ return paths(dataChildrenSub);
44
+ }
45
+ return false;
46
+ });
47
+ };
48
+ paths(data);
49
+ return folderName;
50
+ };
51
+
52
+ export { getPathOfFolder, getIdPathsOfFolder, getFolderName };
@@ -0,0 +1,11 @@
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 TreeStructure from './TreeStructure';
10
+ export type { FolderStructureProps, TreeStructureProps } from './TreeStructure.types';
11
+ export { TreeStructure };
@@ -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
+ }
@@ -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
- {authorizedRole && <p>{t('user.loggedInAs', { role: authorizedRole })}</p>}
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
+ };