@ndla/ui 20.0.3 → 22.0.1
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/Breadcrumb/ActionBreadcrumb.js +4 -4
- package/es/LearningPaths/LearningPathInformation.js +21 -3
- package/es/LearningPaths/LearningPathMenuAsideCopyright.js +17 -4
- package/es/MyNdla/Resource/Folder.js +7 -6
- package/es/Resource/BlockResource.js +6 -5
- package/es/Resource/ListResource.js +7 -6
- package/es/ResourceGroup/ResourceGroup.js +3 -3
- package/es/ResourceGroup/ResourceItem.js +12 -12
- package/es/ResourceGroup/ResourceList.js +2 -2
- package/es/Search/ContentTypeResult.js +1 -2
- package/es/SearchTypeResult/SearchItem.js +8 -8
- package/es/TopicMenu/TopicMenuButton.js +4 -2
- package/es/TreeStructure/FolderItem.js +109 -68
- package/es/TreeStructure/FolderItems.js +34 -62
- package/es/TreeStructure/FolderNameInput.js +14 -13
- package/es/TreeStructure/TreeStructure.js +89 -98
- package/es/TreeStructure/helperFunctions.js +4 -73
- package/es/TreeStructure/{TreeStructure.types.js → types.js} +0 -0
- package/es/locale/messages-en.js +8 -0
- package/es/locale/messages-nb.js +8 -0
- package/es/locale/messages-nn.js +8 -0
- package/es/locale/messages-se.js +8 -0
- package/es/locale/messages-sma.js +8 -0
- package/lib/Breadcrumb/ActionBreadcrumb.js +4 -4
- package/lib/LearningPaths/LearningPathInformation.js +19 -2
- package/lib/LearningPaths/LearningPathMenuAsideCopyright.js +16 -3
- package/lib/MyNdla/Resource/Folder.js +7 -6
- package/lib/Resource/BlockResource.js +6 -5
- package/lib/Resource/ListResource.js +7 -6
- package/lib/ResourceGroup/ResourceGroup.d.ts +1 -1
- package/lib/ResourceGroup/ResourceGroup.js +3 -3
- package/lib/ResourceGroup/ResourceItem.d.ts +1 -1
- package/lib/ResourceGroup/ResourceItem.js +12 -12
- package/lib/ResourceGroup/ResourceList.d.ts +1 -1
- package/lib/ResourceGroup/ResourceList.js +2 -2
- package/lib/Search/ContentTypeResult.js +1 -2
- package/lib/SearchTypeResult/SearchItem.js +8 -8
- package/lib/TopicMenu/TopicMenuButton.js +3 -1
- package/lib/TreeStructure/FolderItem.d.ts +6 -20
- package/lib/TreeStructure/FolderItem.js +112 -68
- package/lib/TreeStructure/FolderItems.d.ts +11 -2
- package/lib/TreeStructure/FolderItems.js +34 -62
- package/lib/TreeStructure/FolderNameInput.js +14 -13
- package/lib/TreeStructure/TreeStructure.d.ts +12 -2
- package/lib/TreeStructure/TreeStructure.js +87 -96
- package/lib/TreeStructure/helperFunctions.d.ts +2 -4
- package/lib/TreeStructure/helperFunctions.js +5 -80
- package/lib/TreeStructure/index.d.ts +2 -1
- package/lib/TreeStructure/types.d.ts +33 -0
- package/lib/TreeStructure/{TreeStructure.types.js → types.js} +0 -0
- package/lib/index.d.ts +1 -1
- package/lib/locale/messages-en.d.ts +8 -0
- package/lib/locale/messages-en.js +8 -0
- package/lib/locale/messages-nb.d.ts +8 -0
- package/lib/locale/messages-nb.js +8 -0
- package/lib/locale/messages-nn.d.ts +8 -0
- package/lib/locale/messages-nn.js +8 -0
- package/lib/locale/messages-se.d.ts +8 -0
- package/lib/locale/messages-se.js +8 -0
- package/lib/locale/messages-sma.d.ts +8 -0
- package/lib/locale/messages-sma.js +8 -0
- package/package.json +15 -14
- package/src/.DS_Store +0 -0
- package/src/Breadcrumb/ActionBreadcrumb.tsx +1 -1
- package/src/LearningPaths/LearningPathInformation.tsx +27 -12
- package/src/LearningPaths/LearningPathMenuAsideCopyright.tsx +22 -20
- package/src/MyNdla/Resource/Folder.tsx +1 -1
- package/src/Resource/BlockResource.tsx +1 -1
- package/src/Resource/ListResource.tsx +1 -1
- package/src/ResourceGroup/ResourceGroup.tsx +1 -1
- package/src/ResourceGroup/ResourceItem.tsx +2 -2
- package/src/ResourceGroup/ResourceList.tsx +1 -1
- package/src/Search/ContentTypeResult.tsx +0 -1
- package/src/SearchTypeResult/SearchItem.tsx +0 -1
- package/src/TopicMenu/TopicMenuButton.jsx +5 -1
- package/src/TreeStructure/FolderItem.tsx +105 -94
- package/src/TreeStructure/FolderItems.tsx +33 -52
- package/src/TreeStructure/FolderNameInput.tsx +6 -11
- package/src/TreeStructure/TreeStructure.tsx +80 -73
- package/src/TreeStructure/helperFunctions.ts +3 -37
- package/src/TreeStructure/index.ts +2 -1
- package/src/TreeStructure/types.ts +38 -0
- package/src/index.ts +1 -1
- package/src/locale/messages-en.ts +8 -0
- package/src/locale/messages-nb.ts +8 -0
- package/src/locale/messages-nn.ts +8 -0
- package/src/locale/messages-se.ts +8 -0
- package/src/locale/messages-sma.ts +8 -0
- package/lib/TreeStructure/TreeStructure.types.d.ts +0 -61
- package/src/TreeStructure/TreeStructure.types.ts +0 -71
|
@@ -6,17 +6,18 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import React, { useEffect, useState,
|
|
9
|
+
import React, { useEffect, useState, useMemo } from 'react';
|
|
10
10
|
import { AddButton } from '@ndla/button';
|
|
11
11
|
import Tooltip from '@ndla/tooltip';
|
|
12
12
|
import { useTranslation } from 'react-i18next';
|
|
13
13
|
import styled from '@emotion/styled';
|
|
14
14
|
import { spacing, fonts } from '@ndla/core';
|
|
15
15
|
import { uniq } from 'lodash';
|
|
16
|
+
import { IFolder } from '@ndla/types-learningpath-api';
|
|
16
17
|
import TreeStructureStyledWrapper from './TreeStructureWrapper';
|
|
17
18
|
import FolderItems from './FolderItems';
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
19
|
+
import { flattenFolders } from './helperFunctions';
|
|
20
|
+
import { CommonTreeStructureProps, FolderType } from './types';
|
|
20
21
|
|
|
21
22
|
export const MAX_LEVEL_FOR_FOLDERS = 4;
|
|
22
23
|
|
|
@@ -29,42 +30,64 @@ const AddFolderWrapper = styled.div`
|
|
|
29
30
|
margin-top: ${spacing.xsmall};
|
|
30
31
|
`;
|
|
31
32
|
|
|
33
|
+
export interface TreeStructureProps extends CommonTreeStructureProps {
|
|
34
|
+
defaultOpenFolders?: string[];
|
|
35
|
+
folders: FolderType[];
|
|
36
|
+
editable?: boolean;
|
|
37
|
+
framed?: boolean;
|
|
38
|
+
label?: string;
|
|
39
|
+
maximumLevelsOfFoldersAllowed?: number;
|
|
40
|
+
onNewFolder?: (name: string, parentId: string) => Promise<IFolder>;
|
|
41
|
+
}
|
|
42
|
+
|
|
32
43
|
const TreeStructure = ({
|
|
44
|
+
defaultOpenFolders,
|
|
45
|
+
editable,
|
|
46
|
+
menuItems,
|
|
33
47
|
folders,
|
|
48
|
+
framed,
|
|
34
49
|
label,
|
|
35
|
-
editable,
|
|
36
50
|
loading,
|
|
51
|
+
maximumLevelsOfFoldersAllowed = MAX_LEVEL_FOR_FOLDERS,
|
|
37
52
|
onNewFolder,
|
|
38
53
|
onSelectFolder,
|
|
39
54
|
openOnFolderClick,
|
|
40
|
-
|
|
41
|
-
folderIdMarkedByDefault,
|
|
42
|
-
defaultOpenFolders,
|
|
43
|
-
folderChild,
|
|
44
|
-
maximumLevelsOfFoldersAllowed = MAX_LEVEL_FOR_FOLDERS,
|
|
55
|
+
targetResource,
|
|
45
56
|
}: TreeStructureProps) => {
|
|
46
57
|
const { t } = useTranslation();
|
|
47
|
-
|
|
58
|
+
|
|
59
|
+
const defaultSelectedFolderId = defaultOpenFolders && defaultOpenFolders[defaultOpenFolders.length - 1];
|
|
60
|
+
|
|
48
61
|
const [openFolders, setOpenFolders] = useState<string[]>(defaultOpenFolders || []);
|
|
49
|
-
|
|
50
|
-
const [
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
() => flattenFolders(folders, openFolders).map((folder) => folder.id),
|
|
57
|
-
[folders, openFolders],
|
|
58
|
-
);
|
|
62
|
+
|
|
63
|
+
const [newFolderParentId, setNewFolderParentId] = useState<string | undefined>();
|
|
64
|
+
const [focusedId, setFocusedId] = useState<string | undefined>();
|
|
65
|
+
const [selectedFolder, setSelectedFolder] = useState<FolderType | undefined>();
|
|
66
|
+
|
|
67
|
+
const flattenedFolders = useMemo(() => flattenFolders(folders, openFolders), [folders, openFolders]);
|
|
68
|
+
const visibleFolderIds = flattenedFolders.map((folder) => folder.id);
|
|
59
69
|
|
|
60
70
|
useEffect(() => {
|
|
61
71
|
if (defaultOpenFolders) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
72
|
+
if (!defaultOpenFolders.every((element) => openFolders.includes(element))) {
|
|
73
|
+
setOpenFolders((prev) => {
|
|
74
|
+
return uniq(defaultOpenFolders.concat(prev));
|
|
75
|
+
});
|
|
76
|
+
}
|
|
65
77
|
}
|
|
78
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
66
79
|
}, [defaultOpenFolders]);
|
|
67
80
|
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
if (defaultSelectedFolderId !== undefined) {
|
|
83
|
+
const selected = flattenFolders(folders).find((folder) => folder.id === defaultSelectedFolderId);
|
|
84
|
+
if (selected) {
|
|
85
|
+
setSelectedFolder(selected);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
89
|
+
}, [defaultSelectedFolderId]);
|
|
90
|
+
|
|
68
91
|
useEffect(() => {
|
|
69
92
|
if (!loading) {
|
|
70
93
|
setNewFolderParentId(undefined);
|
|
@@ -72,39 +95,30 @@ const TreeStructure = ({
|
|
|
72
95
|
}, [loading]);
|
|
73
96
|
|
|
74
97
|
const onCloseFolder = (id: string) => {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
const markedFolderIsSubPath = closingFolderPath.every(
|
|
81
|
-
(folderId, _index) => markedFolderPath[_index] === folderId,
|
|
82
|
-
);
|
|
83
|
-
if (markedFolderIsSubPath) {
|
|
98
|
+
const closedFolder = flattenedFolders.find((folder) => folder.id === id);
|
|
99
|
+
|
|
100
|
+
if (closedFolder) {
|
|
101
|
+
const subFolders = closedFolder.subfolders && flattenFolders(closedFolder.subfolders);
|
|
102
|
+
if (subFolders.some((folder) => folder.id === selectedFolder?.id)) {
|
|
84
103
|
if (onSelectFolder) {
|
|
85
|
-
|
|
86
|
-
onSelectFolder(
|
|
87
|
-
} else {
|
|
88
|
-
setFocusedFolderId(closingFolderPath[closingFolderPath.length - 1]);
|
|
104
|
+
setSelectedFolder(closedFolder);
|
|
105
|
+
onSelectFolder(closedFolder.id);
|
|
89
106
|
}
|
|
107
|
+
setFocusedId(closedFolder.id);
|
|
90
108
|
}
|
|
91
109
|
}
|
|
92
|
-
setOpenFolders(openFolders.filter((
|
|
110
|
+
setOpenFolders(openFolders.filter((folderId) => folderId !== id));
|
|
93
111
|
};
|
|
94
112
|
|
|
95
113
|
const onOpenFolder = (id: string) => {
|
|
96
114
|
setOpenFolders(uniq(openFolders.concat(id)));
|
|
97
115
|
};
|
|
98
116
|
|
|
99
|
-
const onCreateNewFolder = (parentId: string) => {
|
|
100
|
-
setNewFolderParentId(parentId);
|
|
101
|
-
};
|
|
102
|
-
|
|
103
117
|
const onSaveNewFolder = (name: string, parentId: string) => {
|
|
104
|
-
onNewFolder(name, parentId).then((
|
|
105
|
-
if (
|
|
106
|
-
|
|
107
|
-
|
|
118
|
+
onNewFolder?.(name, parentId).then((newFolder) => {
|
|
119
|
+
if (newFolder) {
|
|
120
|
+
setSelectedFolder(newFolder);
|
|
121
|
+
setFocusedId(newFolder.id);
|
|
108
122
|
setOpenFolders(uniq(openFolders.concat(parentId)));
|
|
109
123
|
}
|
|
110
124
|
});
|
|
@@ -114,39 +128,34 @@ const TreeStructure = ({
|
|
|
114
128
|
setNewFolderParentId(undefined);
|
|
115
129
|
};
|
|
116
130
|
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
setFocusedFolderId(id);
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
const paths = getPathOfFolder(folders, markedFolderId || '');
|
|
123
|
-
const canAddFolder = editable && paths.length < (maximumLevelsOfFoldersAllowed || 1);
|
|
131
|
+
const canAddFolder =
|
|
132
|
+
editable && selectedFolder && selectedFolder?.breadcrumbs.length < (maximumLevelsOfFoldersAllowed || 1);
|
|
124
133
|
|
|
125
134
|
return (
|
|
126
|
-
<div
|
|
127
|
-
{label && <StyledLabel
|
|
128
|
-
<TreeStructureStyledWrapper
|
|
135
|
+
<div>
|
|
136
|
+
{label && <StyledLabel>{label}</StyledLabel>}
|
|
137
|
+
<TreeStructureStyledWrapper aria-label="Menu tree" role="tree" framed={framed}>
|
|
129
138
|
<FolderItems
|
|
130
|
-
onSelectFolder={onSelectFolder}
|
|
131
|
-
level={1}
|
|
132
|
-
folders={folders}
|
|
133
139
|
editable={editable}
|
|
134
|
-
|
|
135
|
-
|
|
140
|
+
focusedFolderId={focusedId}
|
|
141
|
+
menuItems={menuItems}
|
|
142
|
+
folders={folders}
|
|
143
|
+
level={0}
|
|
144
|
+
loading={loading}
|
|
145
|
+
selectedFolder={selectedFolder}
|
|
146
|
+
maximumLevelsOfFoldersAllowed={maximumLevelsOfFoldersAllowed}
|
|
136
147
|
newFolderParentId={newFolderParentId}
|
|
137
|
-
onCreateNewFolder={onCreateNewFolder}
|
|
138
148
|
onCancelNewFolder={onCancelNewFolder}
|
|
149
|
+
onCloseFolder={onCloseFolder}
|
|
150
|
+
onOpenFolder={onOpenFolder}
|
|
139
151
|
onSaveNewFolder={onSaveNewFolder}
|
|
140
|
-
|
|
152
|
+
onSelectFolder={onSelectFolder}
|
|
141
153
|
openFolders={openFolders}
|
|
142
|
-
markedFolderId={markedFolderId}
|
|
143
|
-
onMarkFolder={onMarkFolder}
|
|
144
154
|
openOnFolderClick={openOnFolderClick}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
maximumLevelsOfFoldersAllowed={maximumLevelsOfFoldersAllowed}
|
|
155
|
+
setFocusedId={setFocusedId}
|
|
156
|
+
setSelectedFolder={setSelectedFolder}
|
|
157
|
+
targetResource={targetResource}
|
|
158
|
+
visibleFolders={visibleFolderIds}
|
|
150
159
|
/>
|
|
151
160
|
</TreeStructureStyledWrapper>
|
|
152
161
|
{editable && (
|
|
@@ -155,16 +164,14 @@ const TreeStructure = ({
|
|
|
155
164
|
tooltip={
|
|
156
165
|
canAddFolder
|
|
157
166
|
? t('myNdla.newFolderUnder', {
|
|
158
|
-
folderName:
|
|
167
|
+
folderName: selectedFolder?.name,
|
|
159
168
|
})
|
|
160
169
|
: t('treeStructure.maxFoldersAlreadyAdded')
|
|
161
170
|
}>
|
|
162
171
|
<AddButton
|
|
163
172
|
disabled={!canAddFolder}
|
|
164
173
|
aria-label={t('myNdla.newFolder')}
|
|
165
|
-
onClick={() =>
|
|
166
|
-
setNewFolderParentId(markedFolderId);
|
|
167
|
-
}}>
|
|
174
|
+
onClick={() => setNewFolderParentId(selectedFolder?.id)}>
|
|
168
175
|
{t('myNdla.newFolder')}
|
|
169
176
|
</AddButton>
|
|
170
177
|
</Tooltip>
|
|
@@ -1,44 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FolderType } from './types';
|
|
2
2
|
|
|
3
|
-
export const
|
|
4
|
-
const paths = (folders: FolderStructureProps[], path: string[]): string[] => {
|
|
5
|
-
for (const { id, subfolders } of folders) {
|
|
6
|
-
if (id === findId) {
|
|
7
|
-
return [...path, id];
|
|
8
|
-
} else if (subfolders?.length) {
|
|
9
|
-
return paths(subfolders, [...path, id]);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
return [];
|
|
13
|
-
};
|
|
14
|
-
return paths(data, []);
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export const getFolderName = (data: FolderStructureProps[], findId: string | undefined): string | undefined => {
|
|
18
|
-
if (!findId) {
|
|
19
|
-
return undefined;
|
|
20
|
-
}
|
|
21
|
-
let folderName: string | undefined;
|
|
22
|
-
const paths = (dataChildren: FolderStructureProps[]) => {
|
|
23
|
-
dataChildren.some(({ id, name, subfolders }, _index) => {
|
|
24
|
-
if (id === findId) {
|
|
25
|
-
folderName = name;
|
|
26
|
-
return true;
|
|
27
|
-
} else if (subfolders?.length) {
|
|
28
|
-
return paths(subfolders);
|
|
29
|
-
}
|
|
30
|
-
return false;
|
|
31
|
-
});
|
|
32
|
-
};
|
|
33
|
-
paths(data);
|
|
34
|
-
return folderName;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export const flattenFolders = (folders: FolderStructureProps[], openFolders?: string[]): FolderStructureProps[] => {
|
|
3
|
+
export const flattenFolders = (folders: FolderType[], openFolders?: string[]): FolderType[] => {
|
|
38
4
|
return folders.reduce((acc, { subfolders, id, ...rest }) => {
|
|
39
5
|
if (!subfolders || (openFolders && !openFolders.includes(id))) {
|
|
40
6
|
return acc.concat({ subfolders, id, ...rest });
|
|
41
7
|
}
|
|
42
8
|
return acc.concat({ subfolders, id, ...rest }, flattenFolders(subfolders, openFolders));
|
|
43
|
-
}, [] as
|
|
9
|
+
}, [] as FolderType[]);
|
|
44
10
|
};
|
|
@@ -7,5 +7,6 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import TreeStructure from './TreeStructure';
|
|
10
|
-
export type {
|
|
10
|
+
export type { FolderType, TreeStructureMenuProps } from './types';
|
|
11
|
+
export type { TreeStructureProps } from './TreeStructure';
|
|
11
12
|
export { TreeStructure };
|
|
@@ -0,0 +1,38 @@
|
|
|
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 { MouseEvent, ReactNode } from 'react';
|
|
10
|
+
import { IFolder, IResource } from '@ndla/types-learningpath-api';
|
|
11
|
+
import { MenuItemProps } from '@ndla/button/src';
|
|
12
|
+
|
|
13
|
+
export interface FolderType extends IFolder {
|
|
14
|
+
icon?: ReactNode;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface TreeStructureMenuProps extends Omit<MenuItemProps, 'onClick'> {
|
|
18
|
+
onClick: (e: MouseEvent<HTMLDivElement> | undefined, folder: FolderType) => void;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface CommonTreeStructureProps {
|
|
22
|
+
loading?: boolean;
|
|
23
|
+
onSelectFolder?: (id: string) => void;
|
|
24
|
+
openOnFolderClick?: boolean;
|
|
25
|
+
menuItems?: TreeStructureMenuProps[];
|
|
26
|
+
targetResource?: IResource;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface CommonFolderItemsProps extends CommonTreeStructureProps {
|
|
30
|
+
focusedFolderId?: string;
|
|
31
|
+
level: number;
|
|
32
|
+
selectedFolder?: FolderType;
|
|
33
|
+
onCloseFolder: (id: string) => void;
|
|
34
|
+
onOpenFolder: (id: string) => void;
|
|
35
|
+
setFocusedId: (id: string) => void;
|
|
36
|
+
setSelectedFolder: (id: FolderType) => void;
|
|
37
|
+
visibleFolders: string[];
|
|
38
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -244,4 +244,4 @@ export type { SnackBarItem } from './SnackBar';
|
|
|
244
244
|
export { SnackBar } from './SnackBar';
|
|
245
245
|
export { InfoBlock } from './InfoBlock';
|
|
246
246
|
export { TreeStructure } from './TreeStructure';
|
|
247
|
-
export type {
|
|
247
|
+
export type { FolderType, TreeStructureProps, TreeStructureMenuProps } from './TreeStructure';
|
|
@@ -997,6 +997,8 @@ const messages = {
|
|
|
997
997
|
edit: 'Edit',
|
|
998
998
|
missingName: 'Folder name required',
|
|
999
999
|
},
|
|
1000
|
+
tags: '{{count}} tag',
|
|
1001
|
+
tags_plural: '{{count}} tags',
|
|
1000
1002
|
confirmDeleteFolder: 'Are you sure you want to delete this folder? This process cannot be undone.',
|
|
1001
1003
|
confirmDeleteTag: 'Are you sure you want to delete this tag? This process cannot be undone.',
|
|
1002
1004
|
myFolders: 'My folders',
|
|
@@ -1007,6 +1009,7 @@ const messages = {
|
|
|
1007
1009
|
favourites: 'Favourites',
|
|
1008
1010
|
addToFavourites: 'Add to my favourites',
|
|
1009
1011
|
alreadyFavourited: 'Already in my favourites',
|
|
1012
|
+
alreadyInFolder: 'Already in folder',
|
|
1010
1013
|
help: 'Help',
|
|
1011
1014
|
more: 'More options',
|
|
1012
1015
|
listView: 'List view',
|
|
@@ -1015,6 +1018,9 @@ const messages = {
|
|
|
1015
1018
|
myPage: {
|
|
1016
1019
|
myPage: 'My page',
|
|
1017
1020
|
logout: 'Log out of My NDLA',
|
|
1021
|
+
loginTerms: 'Log in with Feide to receive access. By logging on your accept your terms of service',
|
|
1022
|
+
loginResourcePitch: 'Do you want to favorite this page?',
|
|
1023
|
+
loginWelcome: 'Welcome to My NDLA! This page allows you to organize your articles in your <i>own</i> way!',
|
|
1018
1024
|
deleteAccount: 'Delete My NDLA',
|
|
1019
1025
|
welcome:
|
|
1020
1026
|
'Welcome to my NDLA! You can now save your favourite resources from NDLA and organise them in folders with tags',
|
|
@@ -1047,6 +1053,8 @@ const messages = {
|
|
|
1047
1053
|
resource: {
|
|
1048
1054
|
add: 'Add folder/tag',
|
|
1049
1055
|
remove: 'Remove',
|
|
1056
|
+
removeTitle: 'Remove resource',
|
|
1057
|
+
confirmRemove: 'Are you sure you want to remove the resource from this folder?',
|
|
1050
1058
|
copyLink: 'Copy link to this page',
|
|
1051
1059
|
addToMyNdla: 'Add to My NDLA',
|
|
1052
1060
|
addedToMyNdla: 'Added to My NDLA',
|
|
@@ -995,6 +995,8 @@ const messages = {
|
|
|
995
995
|
edit: 'Rediger',
|
|
996
996
|
missingName: 'Mappenavn er påkrevd',
|
|
997
997
|
},
|
|
998
|
+
tags: '{{count}} tag',
|
|
999
|
+
tags_plural: '{{count}} tags',
|
|
998
1000
|
confirmDeleteFolder: 'Er du sikker på at du vil slette mappen? Denne handlingen kan ikke angres.',
|
|
999
1001
|
confirmDeleteTag: 'Er du sikker på at du vil slette tag? Denne handlingen kan ikke angres.',
|
|
1000
1002
|
myFolders: 'Mine mapper',
|
|
@@ -1005,6 +1007,7 @@ const messages = {
|
|
|
1005
1007
|
favourites: 'Favoritter',
|
|
1006
1008
|
addToFavourites: 'Legg til i mine favoritter',
|
|
1007
1009
|
alreadyFavourited: 'Allerede lagt til i mine favoritter',
|
|
1010
|
+
alreadyInFolder: 'Finnes allerede i mappen',
|
|
1008
1011
|
help: 'Hjelp',
|
|
1009
1012
|
more: 'Flere valg',
|
|
1010
1013
|
listView: 'Listevisning',
|
|
@@ -1014,6 +1017,9 @@ const messages = {
|
|
|
1014
1017
|
myPage: 'Min side',
|
|
1015
1018
|
deleteAccount: 'Slett Min NDLA',
|
|
1016
1019
|
logout: 'Logg ut av Min NDLA',
|
|
1020
|
+
loginTerms: 'Logg på med Feide for å få tilgang. Ved å logge på godkjenner du våre vilkår for bruk',
|
|
1021
|
+
loginResourcePitch: 'Ønsker du å favorittmerke denne siden?',
|
|
1022
|
+
loginWelcome: 'Velkommen til NDLA! Her kan du organisere fagstoffet på <i>din</i> måte!',
|
|
1017
1023
|
welcome:
|
|
1018
1024
|
'Velkommen til Min NDLA! Nå kan du lagre dine favorittressurser fra NDLA og organisere dem slik du ønsker i mapper og med tags.',
|
|
1019
1025
|
read: { our: 'Les våre', ours: 'Les vår' },
|
|
@@ -1045,6 +1051,8 @@ const messages = {
|
|
|
1045
1051
|
resource: {
|
|
1046
1052
|
add: 'Legg til mappe/tag',
|
|
1047
1053
|
remove: 'Fjern',
|
|
1054
|
+
removeTitle: 'Fjern ressurs',
|
|
1055
|
+
confirmRemove: 'Er du sikker på at du ønsker å fjerne ressursen fra denne mappen?',
|
|
1048
1056
|
copyLink: 'Kopier lenke til siden',
|
|
1049
1057
|
addToMyNdla: 'Legg i Min NDLA',
|
|
1050
1058
|
addedToMyNdla: 'Lagt i Min NDLA',
|
|
@@ -996,6 +996,8 @@ const messages = {
|
|
|
996
996
|
edit: 'Rediger',
|
|
997
997
|
missingName: 'Mappenavn er påkrevd',
|
|
998
998
|
},
|
|
999
|
+
tags: '{{count}} tag',
|
|
1000
|
+
tags_plural: '{{count}} tags',
|
|
999
1001
|
confirmDeleteFolder: 'Er du sikker på at du vil slette mappa? Denne handlinga kan ikkje angres.',
|
|
1000
1002
|
confirmDeleteTag: 'Er du sikker på at du vil slette tag? Denne handlinga kan ikkje angres.',
|
|
1001
1003
|
myFolders: 'Mine mapper',
|
|
@@ -1006,6 +1008,7 @@ const messages = {
|
|
|
1006
1008
|
favourites: 'Favorittar',
|
|
1007
1009
|
addToFavourites: 'Legg til i mine favorittar',
|
|
1008
1010
|
alreadyFavourited: 'Allereie lagt til i mine favorittar',
|
|
1011
|
+
alreadyInFolder: 'Finnes allereie i mappa',
|
|
1009
1012
|
help: 'Hjelp',
|
|
1010
1013
|
more: 'Fleire val',
|
|
1011
1014
|
listView: 'Listevisning',
|
|
@@ -1015,6 +1018,9 @@ const messages = {
|
|
|
1015
1018
|
myPage: 'Min side',
|
|
1016
1019
|
deleteAccount: 'Slett Min NDLA',
|
|
1017
1020
|
logout: 'Logg ut av Min NDLA',
|
|
1021
|
+
loginTerms: 'Logg på med Feide for å få tilgang. Ved å logge på godkjennar du våre vilkår for bruk',
|
|
1022
|
+
loginResourcePitch: 'Ønsker du å favorittmerke denne sida?',
|
|
1023
|
+
loginWelcome: 'Velkommen til NDLA! Her kan du organisere fagstoffet på <i>din</i> måte!',
|
|
1018
1024
|
welcome:
|
|
1019
1025
|
'Velkommen til Min NDLA! Nå kan du lagre dine favorittressurser fra NDLA og organisere dem slik du ønsker i mapper og med tags.',
|
|
1020
1026
|
read: { our: 'Les våre', ours: 'Les vår' },
|
|
@@ -1045,6 +1051,8 @@ const messages = {
|
|
|
1045
1051
|
resource: {
|
|
1046
1052
|
add: 'Legg til mappe/tag',
|
|
1047
1053
|
remove: 'Fjern',
|
|
1054
|
+
removeTitle: 'Fjern ressurs',
|
|
1055
|
+
confirmRemove: 'Er du sikker på at du ønsker å fjerne ressursen frå denne mappen?',
|
|
1048
1056
|
copyLink: 'Kopier lenke til sida',
|
|
1049
1057
|
addToMyNdla: 'Legg i Min NDLA',
|
|
1050
1058
|
addedToMyNdla: 'Lagt i Min NDLA',
|
|
@@ -995,6 +995,8 @@ const messages = {
|
|
|
995
995
|
edit: 'Rediger',
|
|
996
996
|
missingName: 'Mappenavn er påkrevd',
|
|
997
997
|
},
|
|
998
|
+
tags: '{{count}} tag',
|
|
999
|
+
tags_plural: '{{count}} tags',
|
|
998
1000
|
confirmDeleteFolder: 'Er du sikker på at du vil slette mappen? Denne handlingen kan ikke angres.',
|
|
999
1001
|
confirmDeleteTag: 'Er du sikker på at du vil slette tag? Denne handlingen kan ikke angres.',
|
|
1000
1002
|
myFolders: 'Mine mapper',
|
|
@@ -1005,6 +1007,7 @@ const messages = {
|
|
|
1005
1007
|
favourites: 'Favoritter',
|
|
1006
1008
|
addToFavourites: 'Legg til i mine favoritter',
|
|
1007
1009
|
alreadyFavourited: 'Allerede lagt til i mine favoritter',
|
|
1010
|
+
alreadyInFolder: 'Finnes allerede i mappen',
|
|
1008
1011
|
help: 'Hjelp',
|
|
1009
1012
|
more: 'Flere valg',
|
|
1010
1013
|
listView: 'Listevisning',
|
|
@@ -1014,6 +1017,9 @@ const messages = {
|
|
|
1014
1017
|
myPage: 'Min side',
|
|
1015
1018
|
deleteAccount: 'Slett Min NDLA',
|
|
1016
1019
|
logout: 'Logg ut av Min NDLA',
|
|
1020
|
+
loginTerms: 'Logg på med Feide for å få tilgang. Ved å logge på godkjennar du våre vilkår for bruk',
|
|
1021
|
+
loginResourcePitch: 'Ønsker du å favorittmerke denne sida?',
|
|
1022
|
+
loginWelcome: 'Velkommen til NDLA! Her kan du organisere fagstoffet på <i>din</i> måte!',
|
|
1017
1023
|
welcome:
|
|
1018
1024
|
'Velkommen til Min NDLA! Nå kan du lagre dine favorittressurser fra NDLA og organisere dem slik du ønsker i mapper og med tags.',
|
|
1019
1025
|
read: { our: 'Les våre', ours: 'Les vår' },
|
|
@@ -1045,6 +1051,8 @@ const messages = {
|
|
|
1045
1051
|
resource: {
|
|
1046
1052
|
add: 'Legg til mappe/tag',
|
|
1047
1053
|
remove: 'Fjern',
|
|
1054
|
+
removeTitle: 'Fjern ressurs',
|
|
1055
|
+
confirmRemove: 'Er du sikker på at du ønsker å fjerne ressursen frå denne mappen?',
|
|
1048
1056
|
copyLink: 'Kopier lenke til siden',
|
|
1049
1057
|
addToMyNdla: 'Legg i Min NDLA',
|
|
1050
1058
|
addedToMyNdla: 'Lagt i Min NDLA',
|
|
@@ -995,6 +995,8 @@ const messages = {
|
|
|
995
995
|
edit: 'Rediger',
|
|
996
996
|
missingName: 'Mappenavn er påkrevd',
|
|
997
997
|
},
|
|
998
|
+
tags: '{{count}} tag',
|
|
999
|
+
tags_plural: '{{count}} tags',
|
|
998
1000
|
confirmDeleteFolder: 'Er du sikker på at du vil slette mappen? Denne handlingen kan ikke angres.',
|
|
999
1001
|
confirmDeleteTag: 'Er du sikker på at du vil slette tag? Denne handlingen kan ikke angres.',
|
|
1000
1002
|
myFolders: 'Mine mapper',
|
|
@@ -1005,6 +1007,7 @@ const messages = {
|
|
|
1005
1007
|
favourites: 'Favoritter',
|
|
1006
1008
|
addToFavourites: 'Legg til i mine favoritter',
|
|
1007
1009
|
alreadyFavourited: 'Allerede lagt til i mine favoritter',
|
|
1010
|
+
alreadyInFolder: 'Finnes allerede i mappen',
|
|
1008
1011
|
help: 'Hjelp',
|
|
1009
1012
|
more: 'Flere valg',
|
|
1010
1013
|
listView: 'Listevisning',
|
|
@@ -1014,6 +1017,9 @@ const messages = {
|
|
|
1014
1017
|
myPage: 'Min side',
|
|
1015
1018
|
deleteAccount: 'Slett Min NDLA',
|
|
1016
1019
|
logout: 'Logg ut av Min NDLA',
|
|
1020
|
+
loginTerms: 'Logg på med Feide for å få tilgang. Ved å logge på godkjennar du våre vilkår for bruk',
|
|
1021
|
+
loginResourcePitch: 'Ønsker du å favorittmerke denne sida?',
|
|
1022
|
+
loginWelcome: 'Velkommen til NDLA! Her kan du organisere fagstoffet på <i>din</i> måte!',
|
|
1017
1023
|
welcome:
|
|
1018
1024
|
'Velkommen til Min NDLA! Nå kan du lagre dine favorittressurser fra NDLA og organisere dem slik du ønsker i mapper og med tags.',
|
|
1019
1025
|
read: { our: 'Les våre', ours: 'Les vår' },
|
|
@@ -1045,6 +1051,8 @@ const messages = {
|
|
|
1045
1051
|
resource: {
|
|
1046
1052
|
add: 'Legg til mappe/tag',
|
|
1047
1053
|
remove: 'Fjern',
|
|
1054
|
+
removeTitle: 'Fjern ressurs',
|
|
1055
|
+
confirmRemove: 'Er du sikker på at du ønsker å fjerne ressursen frå denne mappen?',
|
|
1048
1056
|
copyLink: 'Kopier lenke til siden',
|
|
1049
1057
|
addToMyNdla: 'Legg i Min NDLA',
|
|
1050
1058
|
addedToMyNdla: 'Lagt i Min NDLA',
|
|
@@ -1,61 +0,0 @@
|
|
|
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 React, { ReactNode } from 'react';
|
|
9
|
-
export interface FolderStructureProps {
|
|
10
|
-
id: string;
|
|
11
|
-
name: string;
|
|
12
|
-
subfolders: FolderStructureProps[];
|
|
13
|
-
isFavorite?: boolean;
|
|
14
|
-
status?: string;
|
|
15
|
-
openAsDefault?: boolean;
|
|
16
|
-
icon?: ReactNode;
|
|
17
|
-
}
|
|
18
|
-
interface CommonFolderProps {
|
|
19
|
-
editable?: boolean;
|
|
20
|
-
loading?: boolean;
|
|
21
|
-
openOnFolderClick?: boolean;
|
|
22
|
-
onSelectFolder?: (id: string) => void;
|
|
23
|
-
}
|
|
24
|
-
export interface TreeStructureProps extends CommonFolderProps {
|
|
25
|
-
folders: FolderStructureProps[];
|
|
26
|
-
framed?: boolean;
|
|
27
|
-
label?: string;
|
|
28
|
-
folderIdMarkedByDefault?: string;
|
|
29
|
-
onNewFolder: (name: string, parentId: string) => Promise<string>;
|
|
30
|
-
defaultOpenFolders?: string[];
|
|
31
|
-
folderChild?: FolderChildFuncType;
|
|
32
|
-
maximumLevelsOfFoldersAllowed?: number;
|
|
33
|
-
}
|
|
34
|
-
export declare type onCreateNewFolderProp = ({ idPaths, parentId, }: {
|
|
35
|
-
idPaths: number[];
|
|
36
|
-
parentId: string | undefined;
|
|
37
|
-
}) => void;
|
|
38
|
-
export declare type SetOpenFolderProp = React.Dispatch<React.SetStateAction<string[]>>;
|
|
39
|
-
export declare type SetFocusedFolderId = React.Dispatch<React.SetStateAction<string | undefined>>;
|
|
40
|
-
export declare type FolderChildFuncType = (id: string, tabIndex: number) => ReactNode;
|
|
41
|
-
export interface FolderItemsProps extends CommonFolderProps {
|
|
42
|
-
folders: FolderStructureProps[];
|
|
43
|
-
onCloseFolder: (id: string) => void;
|
|
44
|
-
onOpenFolder: (id: string) => void;
|
|
45
|
-
onSaveNewFolder: (name: string, parentId: string) => void;
|
|
46
|
-
onCancelNewFolder: () => void;
|
|
47
|
-
onCreateNewFolder: (parentId: string) => void;
|
|
48
|
-
newFolderParentId: string | undefined;
|
|
49
|
-
visibleFolders: string[];
|
|
50
|
-
openFolders: string[];
|
|
51
|
-
markedFolderId?: string;
|
|
52
|
-
onMarkFolder: (id: string) => void;
|
|
53
|
-
level: number;
|
|
54
|
-
focusedFolderId: string | undefined;
|
|
55
|
-
setFocusedFolderId: SetFocusedFolderId;
|
|
56
|
-
keyNavigationFocusIsCreateFolderButton?: boolean;
|
|
57
|
-
icon?: ReactNode;
|
|
58
|
-
folderChild?: FolderChildFuncType;
|
|
59
|
-
maximumLevelsOfFoldersAllowed: number;
|
|
60
|
-
}
|
|
61
|
-
export {};
|
|
@@ -1,71 +0,0 @@
|
|
|
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 React, { ReactNode } from 'react';
|
|
10
|
-
|
|
11
|
-
export interface FolderStructureProps {
|
|
12
|
-
id: string;
|
|
13
|
-
name: string;
|
|
14
|
-
subfolders: FolderStructureProps[];
|
|
15
|
-
isFavorite?: boolean;
|
|
16
|
-
status?: string;
|
|
17
|
-
openAsDefault?: boolean;
|
|
18
|
-
icon?: ReactNode;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
interface CommonFolderProps {
|
|
22
|
-
editable?: boolean;
|
|
23
|
-
loading?: boolean;
|
|
24
|
-
openOnFolderClick?: boolean;
|
|
25
|
-
onSelectFolder?: (id: string) => void;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export interface TreeStructureProps extends CommonFolderProps {
|
|
29
|
-
folders: FolderStructureProps[];
|
|
30
|
-
framed?: boolean;
|
|
31
|
-
label?: string;
|
|
32
|
-
folderIdMarkedByDefault?: string;
|
|
33
|
-
onNewFolder: (name: string, parentId: string) => Promise<string>;
|
|
34
|
-
defaultOpenFolders?: string[];
|
|
35
|
-
folderChild?: FolderChildFuncType;
|
|
36
|
-
maximumLevelsOfFoldersAllowed?: number;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export type onCreateNewFolderProp = ({
|
|
40
|
-
idPaths,
|
|
41
|
-
parentId,
|
|
42
|
-
}: {
|
|
43
|
-
idPaths: number[];
|
|
44
|
-
parentId: string | undefined;
|
|
45
|
-
}) => void;
|
|
46
|
-
|
|
47
|
-
export type SetOpenFolderProp = React.Dispatch<React.SetStateAction<string[]>>;
|
|
48
|
-
export type SetFocusedFolderId = React.Dispatch<React.SetStateAction<string | undefined>>;
|
|
49
|
-
|
|
50
|
-
export type FolderChildFuncType = (id: string, tabIndex: number) => ReactNode;
|
|
51
|
-
|
|
52
|
-
export interface FolderItemsProps extends CommonFolderProps {
|
|
53
|
-
folders: FolderStructureProps[];
|
|
54
|
-
onCloseFolder: (id: string) => void;
|
|
55
|
-
onOpenFolder: (id: string) => void;
|
|
56
|
-
onSaveNewFolder: (name: string, parentId: string) => void;
|
|
57
|
-
onCancelNewFolder: () => void;
|
|
58
|
-
onCreateNewFolder: (parentId: string) => void;
|
|
59
|
-
newFolderParentId: string | undefined;
|
|
60
|
-
visibleFolders: string[];
|
|
61
|
-
openFolders: string[];
|
|
62
|
-
markedFolderId?: string;
|
|
63
|
-
onMarkFolder: (id: string) => void;
|
|
64
|
-
level: number;
|
|
65
|
-
focusedFolderId: string | undefined;
|
|
66
|
-
setFocusedFolderId: SetFocusedFolderId;
|
|
67
|
-
keyNavigationFocusIsCreateFolderButton?: boolean;
|
|
68
|
-
icon?: ReactNode;
|
|
69
|
-
folderChild?: FolderChildFuncType;
|
|
70
|
-
maximumLevelsOfFoldersAllowed: number;
|
|
71
|
-
}
|