@ndla/ui 18.0.1 → 19.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/Breadcrumb/ActionBreadcrumb.js +9 -3
- package/es/MyNdla/Resource/Folder.js +11 -10
- package/es/Resource/BlockResource.js +14 -8
- package/es/Resource/ListResource.js +16 -10
- package/es/Resource/resourceComponents.js +12 -11
- package/es/TreeStructure/FolderItem.js +7 -6
- package/es/TreeStructure/FolderItems.js +7 -6
- package/es/TreeStructure/TreeStructure.js +16 -9
- package/es/locale/messages-en.js +11 -1
- package/es/locale/messages-nb.js +11 -1
- package/es/locale/messages-nn.js +11 -1
- package/es/locale/messages-se.js +11 -1
- package/es/locale/messages-sma.js +11 -1
- package/lib/Breadcrumb/ActionBreadcrumb.js +9 -3
- package/lib/MyNdla/Resource/Folder.d.ts +4 -3
- package/lib/MyNdla/Resource/Folder.js +11 -10
- package/lib/Resource/BlockResource.d.ts +4 -3
- package/lib/Resource/BlockResource.js +14 -7
- package/lib/Resource/ListResource.d.ts +4 -3
- package/lib/Resource/ListResource.js +16 -9
- package/lib/Resource/resourceComponents.d.ts +4 -1
- package/lib/Resource/resourceComponents.js +14 -13
- package/lib/TreeStructure/FolderItem.js +8 -6
- package/lib/TreeStructure/FolderItems.d.ts +1 -1
- package/lib/TreeStructure/FolderItems.js +7 -7
- package/lib/TreeStructure/TreeStructure.d.ts +6 -1
- package/lib/TreeStructure/TreeStructure.js +16 -9
- package/lib/TreeStructure/TreeStructure.types.d.ts +3 -1
- package/lib/locale/messages-en.d.ts +11 -1
- package/lib/locale/messages-en.js +11 -1
- package/lib/locale/messages-nb.d.ts +11 -1
- package/lib/locale/messages-nb.js +11 -1
- package/lib/locale/messages-nn.d.ts +11 -1
- package/lib/locale/messages-nn.js +11 -1
- package/lib/locale/messages-se.d.ts +11 -1
- package/lib/locale/messages-se.js +11 -1
- package/lib/locale/messages-sma.d.ts +11 -1
- package/lib/locale/messages-sma.js +11 -1
- package/package.json +5 -5
- package/src/Breadcrumb/ActionBreadcrumb.tsx +3 -0
- package/src/MyNdla/Resource/Folder.tsx +6 -6
- package/src/Resource/BlockResource.tsx +7 -6
- package/src/Resource/ListResource.tsx +11 -8
- package/src/Resource/resourceComponents.tsx +5 -1
- package/src/TreeStructure/FolderItem.tsx +3 -2
- package/src/TreeStructure/FolderItems.tsx +3 -2
- package/src/TreeStructure/TreeStructure.tsx +21 -7
- package/src/TreeStructure/TreeStructure.types.ts +3 -1
- package/src/locale/messages-en.ts +11 -1
- package/src/locale/messages-nb.ts +11 -1
- package/src/locale/messages-nn.ts +11 -1
- package/src/locale/messages-se.ts +11 -1
- package/src/locale/messages-sma.ts +11 -1
|
@@ -58,7 +58,13 @@ declare const messages: {
|
|
|
58
58
|
resources_plural: string;
|
|
59
59
|
folders: string;
|
|
60
60
|
folders_plural: string;
|
|
61
|
-
folder:
|
|
61
|
+
folder: {
|
|
62
|
+
folder: string;
|
|
63
|
+
delete: string;
|
|
64
|
+
edit: string;
|
|
65
|
+
};
|
|
66
|
+
confirmDeleteFolder: string;
|
|
67
|
+
confirmDeleteTag: string;
|
|
62
68
|
myFolders: string;
|
|
63
69
|
myTags: string;
|
|
64
70
|
newFolder: string;
|
|
@@ -104,6 +110,9 @@ declare const messages: {
|
|
|
104
110
|
};
|
|
105
111
|
};
|
|
106
112
|
resource: {
|
|
113
|
+
add: string;
|
|
114
|
+
remove: string;
|
|
115
|
+
copyLink: string;
|
|
107
116
|
addToMyNdla: string;
|
|
108
117
|
addedToMyNdla: string;
|
|
109
118
|
};
|
|
@@ -132,6 +141,7 @@ declare const messages: {
|
|
|
132
141
|
delete: string;
|
|
133
142
|
};
|
|
134
143
|
createFolder: string;
|
|
144
|
+
maxFoldersAlreadyAdded: string;
|
|
135
145
|
newFolder: {
|
|
136
146
|
placeholder: string;
|
|
137
147
|
defaultName: string;
|
|
@@ -34,6 +34,7 @@ var messages = _objectSpread(_objectSpread({
|
|
|
34
34
|
"delete": 'Slett'
|
|
35
35
|
},
|
|
36
36
|
createFolder: 'Lag mappe',
|
|
37
|
+
maxFoldersAlreadyAdded: 'Maks nivå av undermapper nådd',
|
|
37
38
|
newFolder: {
|
|
38
39
|
placeholder: 'Skriv namn på mappe',
|
|
39
40
|
defaultName: 'Ny mappe'
|
|
@@ -950,7 +951,13 @@ var messages = _objectSpread(_objectSpread({
|
|
|
950
951
|
resources_plural: '{{count}} ressursar',
|
|
951
952
|
folders: '{{count}} mappe',
|
|
952
953
|
folders_plural: '{{count}} mapper',
|
|
953
|
-
folder:
|
|
954
|
+
folder: {
|
|
955
|
+
folder: 'Mappe',
|
|
956
|
+
"delete": 'Slett',
|
|
957
|
+
edit: 'Rediger'
|
|
958
|
+
},
|
|
959
|
+
confirmDeleteFolder: 'Er du sikker på at du vil slette mappa? Denne handlinga kan ikkje angres.',
|
|
960
|
+
confirmDeleteTag: 'Er du sikker på at du vil slette tag? Denne handlinga kan ikkje angres.',
|
|
954
961
|
myFolders: 'Mine mapper',
|
|
955
962
|
myTags: 'Mine tags',
|
|
956
963
|
newFolder: 'Ny mappe',
|
|
@@ -996,6 +1003,9 @@ var messages = _objectSpread(_objectSpread({
|
|
|
996
1003
|
}
|
|
997
1004
|
},
|
|
998
1005
|
resource: {
|
|
1006
|
+
add: 'Legg til mappe/tag',
|
|
1007
|
+
remove: 'Fjern',
|
|
1008
|
+
copyLink: 'Kopier lenke til sida',
|
|
999
1009
|
addToMyNdla: 'Legg i Min NDLA',
|
|
1000
1010
|
addedToMyNdla: 'Lagt i Min NDLA'
|
|
1001
1011
|
}
|
|
@@ -58,7 +58,13 @@ declare const messages: {
|
|
|
58
58
|
resources_plural: string;
|
|
59
59
|
folders: string;
|
|
60
60
|
folders_plural: string;
|
|
61
|
-
folder:
|
|
61
|
+
folder: {
|
|
62
|
+
folder: string;
|
|
63
|
+
delete: string;
|
|
64
|
+
edit: string;
|
|
65
|
+
};
|
|
66
|
+
confirmDeleteFolder: string;
|
|
67
|
+
confirmDeleteTag: string;
|
|
62
68
|
myFolders: string;
|
|
63
69
|
myTags: string;
|
|
64
70
|
newFolder: string;
|
|
@@ -104,6 +110,9 @@ declare const messages: {
|
|
|
104
110
|
};
|
|
105
111
|
};
|
|
106
112
|
resource: {
|
|
113
|
+
add: string;
|
|
114
|
+
remove: string;
|
|
115
|
+
copyLink: string;
|
|
107
116
|
addToMyNdla: string;
|
|
108
117
|
addedToMyNdla: string;
|
|
109
118
|
};
|
|
@@ -132,6 +141,7 @@ declare const messages: {
|
|
|
132
141
|
delete: string;
|
|
133
142
|
};
|
|
134
143
|
createFolder: string;
|
|
144
|
+
maxFoldersAlreadyAdded: string;
|
|
135
145
|
newFolder: {
|
|
136
146
|
placeholder: string;
|
|
137
147
|
defaultName: string;
|
|
@@ -34,6 +34,7 @@ var messages = _objectSpread(_objectSpread({
|
|
|
34
34
|
"delete": 'Slett'
|
|
35
35
|
},
|
|
36
36
|
createFolder: 'Lag mappe',
|
|
37
|
+
maxFoldersAlreadyAdded: 'Maks nivå av undermapper nådd',
|
|
37
38
|
newFolder: {
|
|
38
39
|
placeholder: 'Skriv navn på mappe',
|
|
39
40
|
defaultName: 'Ny mappe'
|
|
@@ -950,7 +951,13 @@ var messages = _objectSpread(_objectSpread({
|
|
|
950
951
|
resources_plural: '{{count}} ressurser',
|
|
951
952
|
folders: '{{count}} mappe',
|
|
952
953
|
folders_plural: '{{count}} mapper',
|
|
953
|
-
folder:
|
|
954
|
+
folder: {
|
|
955
|
+
folder: 'Mappe',
|
|
956
|
+
"delete": 'Slett',
|
|
957
|
+
edit: 'Rediger'
|
|
958
|
+
},
|
|
959
|
+
confirmDeleteFolder: 'Er du sikker på at du vil slette mappen? Denne handlingen kan ikke angres.',
|
|
960
|
+
confirmDeleteTag: 'Er du sikker på at du vil slette tag? Denne handlingen kan ikke angres.',
|
|
954
961
|
myFolders: 'Mine mapper',
|
|
955
962
|
myTags: 'Mine tags',
|
|
956
963
|
newFolder: 'Ny mappe',
|
|
@@ -996,6 +1003,9 @@ var messages = _objectSpread(_objectSpread({
|
|
|
996
1003
|
}
|
|
997
1004
|
},
|
|
998
1005
|
resource: {
|
|
1006
|
+
add: 'Legg til mappe/tag',
|
|
1007
|
+
remove: 'Fjern',
|
|
1008
|
+
copyLink: 'Kopier lenke til siden',
|
|
999
1009
|
addToMyNdla: 'Legg i Min NDLA',
|
|
1000
1010
|
addedToMyNdla: 'Lagt i Min NDLA'
|
|
1001
1011
|
}
|
|
@@ -58,7 +58,13 @@ declare const messages: {
|
|
|
58
58
|
resources_plural: string;
|
|
59
59
|
folders: string;
|
|
60
60
|
folders_plural: string;
|
|
61
|
-
folder:
|
|
61
|
+
folder: {
|
|
62
|
+
folder: string;
|
|
63
|
+
delete: string;
|
|
64
|
+
edit: string;
|
|
65
|
+
};
|
|
66
|
+
confirmDeleteFolder: string;
|
|
67
|
+
confirmDeleteTag: string;
|
|
62
68
|
myFolders: string;
|
|
63
69
|
myTags: string;
|
|
64
70
|
newFolder: string;
|
|
@@ -104,6 +110,9 @@ declare const messages: {
|
|
|
104
110
|
};
|
|
105
111
|
};
|
|
106
112
|
resource: {
|
|
113
|
+
add: string;
|
|
114
|
+
remove: string;
|
|
115
|
+
copyLink: string;
|
|
107
116
|
addToMyNdla: string;
|
|
108
117
|
addedToMyNdla: string;
|
|
109
118
|
};
|
|
@@ -132,6 +141,7 @@ declare const messages: {
|
|
|
132
141
|
delete: string;
|
|
133
142
|
};
|
|
134
143
|
createFolder: string;
|
|
144
|
+
maxFoldersAlreadyAdded: string;
|
|
135
145
|
newFolder: {
|
|
136
146
|
placeholder: string;
|
|
137
147
|
defaultName: string;
|
|
@@ -34,6 +34,7 @@ var messages = _objectSpread(_objectSpread({
|
|
|
34
34
|
"delete": 'Slett'
|
|
35
35
|
},
|
|
36
36
|
createFolder: 'Lag mappe',
|
|
37
|
+
maxFoldersAlreadyAdded: 'Maks nivå av undermapper nådd',
|
|
37
38
|
newFolder: {
|
|
38
39
|
placeholder: 'Skriv navn på mappe',
|
|
39
40
|
defaultName: 'Ny mappe'
|
|
@@ -950,7 +951,13 @@ var messages = _objectSpread(_objectSpread({
|
|
|
950
951
|
resources_plural: '{{count}} ressurser',
|
|
951
952
|
folders: '{{count}} mappe',
|
|
952
953
|
folders_plural: '{{count}} mapper',
|
|
953
|
-
folder:
|
|
954
|
+
folder: {
|
|
955
|
+
folder: 'Mappe',
|
|
956
|
+
"delete": 'Slett',
|
|
957
|
+
edit: 'Rediger'
|
|
958
|
+
},
|
|
959
|
+
confirmDeleteFolder: 'Er du sikker på at du vil slette mappen? Denne handlingen kan ikke angres.',
|
|
960
|
+
confirmDeleteTag: 'Er du sikker på at du vil slette tag? Denne handlingen kan ikke angres.',
|
|
954
961
|
myFolders: 'Mine mapper',
|
|
955
962
|
myTags: 'Mine tags',
|
|
956
963
|
newFolder: 'Ny mappe',
|
|
@@ -996,6 +1003,9 @@ var messages = _objectSpread(_objectSpread({
|
|
|
996
1003
|
}
|
|
997
1004
|
},
|
|
998
1005
|
resource: {
|
|
1006
|
+
add: 'Legg til mappe/tag',
|
|
1007
|
+
remove: 'Fjern',
|
|
1008
|
+
copyLink: 'Kopier lenke til siden',
|
|
999
1009
|
addToMyNdla: 'Legg i Min NDLA',
|
|
1000
1010
|
addedToMyNdla: 'Lagt i Min NDLA'
|
|
1001
1011
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ndla/ui",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "19.1.0",
|
|
4
4
|
"description": "UI component library for NDLA.",
|
|
5
5
|
"license": "GPL-3.0",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -31,15 +31,15 @@
|
|
|
31
31
|
"types"
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@ndla/button": "^
|
|
34
|
+
"@ndla/button": "^3.1.0",
|
|
35
35
|
"@ndla/carousel": "^1.2.11",
|
|
36
36
|
"@ndla/core": "^2.3.0",
|
|
37
37
|
"@ndla/hooks": "^1.1.4",
|
|
38
38
|
"@ndla/icons": "^1.10.0",
|
|
39
39
|
"@ndla/licenses": "^5.0.2",
|
|
40
40
|
"@ndla/modal": "^1.2.12",
|
|
41
|
-
"@ndla/notion": "^3.1.
|
|
42
|
-
"@ndla/safelink": "^2.
|
|
41
|
+
"@ndla/notion": "^3.1.20",
|
|
42
|
+
"@ndla/safelink": "^2.1.1",
|
|
43
43
|
"@ndla/switch": "^0.1.7",
|
|
44
44
|
"@ndla/tabs": "^1.1.10",
|
|
45
45
|
"@ndla/tooltip": "^2.1.2",
|
|
@@ -81,5 +81,5 @@
|
|
|
81
81
|
"publishConfig": {
|
|
82
82
|
"access": "public"
|
|
83
83
|
},
|
|
84
|
-
"gitHead": "
|
|
84
|
+
"gitHead": "74b5027e25a33f81802c72b11901d59085bb290a"
|
|
85
85
|
}
|
|
@@ -44,6 +44,9 @@ interface Props {
|
|
|
44
44
|
|
|
45
45
|
const ActionBreadcrumb = ({ items, actionItems }: Props) => {
|
|
46
46
|
const renderItem = (item: IndexedBreadcrumbItem, totalCount: number) => {
|
|
47
|
+
if (totalCount === 1) {
|
|
48
|
+
return <StyledSpan title={item.name}>{item.name}</StyledSpan>;
|
|
49
|
+
}
|
|
47
50
|
if (item.index === totalCount - 1) {
|
|
48
51
|
return (
|
|
49
52
|
<MenuButton menuItems={actionItems} size="small">
|
|
@@ -7,14 +7,14 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import styled from '@emotion/styled';
|
|
10
|
-
import React
|
|
10
|
+
import React from 'react';
|
|
11
11
|
import { FolderOutlined } from '@ndla/icons/contentType';
|
|
12
12
|
import { FileDocumentOutline } from '@ndla/icons/common';
|
|
13
13
|
import { fonts, spacing, colors, mq, breakpoints } from '@ndla/core';
|
|
14
14
|
import { css } from '@emotion/core';
|
|
15
15
|
import { useTranslation } from 'react-i18next';
|
|
16
16
|
import SafeLink from '@ndla/safelink';
|
|
17
|
-
import { MenuButton } from '@ndla/button';
|
|
17
|
+
import { MenuButton, MenuItemProps } from '@ndla/button';
|
|
18
18
|
|
|
19
19
|
interface FolderIconWrapperProps {
|
|
20
20
|
type?: LayoutType;
|
|
@@ -84,7 +84,7 @@ interface Props {
|
|
|
84
84
|
description?: string;
|
|
85
85
|
link: string;
|
|
86
86
|
type: LayoutType;
|
|
87
|
-
|
|
87
|
+
menuItems?: MenuItemProps[];
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
interface IconCountProps {
|
|
@@ -131,17 +131,17 @@ const IconCount = ({ type, count, layoutType }: IconCountProps) => {
|
|
|
131
131
|
|
|
132
132
|
type LayoutType = 'list' | 'block';
|
|
133
133
|
|
|
134
|
-
const Folder = ({ link, title, subFolders, subResources, type = 'list',
|
|
134
|
+
const Folder = ({ link, title, subFolders, subResources, type = 'list', menuItems }: Props) => {
|
|
135
135
|
const { t } = useTranslation();
|
|
136
136
|
return (
|
|
137
137
|
<FolderWrapper to={link}>
|
|
138
138
|
<FolderIconWrapper type={type}>
|
|
139
|
-
<FolderOutlined aria-label={t('myNdla.folder')} />
|
|
139
|
+
<FolderOutlined aria-label={t('myNdla.folder.folder')} />
|
|
140
140
|
</FolderIconWrapper>
|
|
141
141
|
<FolderTitle>{title}</FolderTitle>
|
|
142
142
|
<IconCount layoutType={type} type={'folder'} count={subFolders} />
|
|
143
143
|
<IconCount layoutType={type} type={'resource'} count={subResources} />
|
|
144
|
-
<MenuButton size="small" />
|
|
144
|
+
{menuItems && menuItems.length > 0 && <MenuButton size="small" menuItems={menuItems} />}
|
|
145
145
|
</FolderWrapper>
|
|
146
146
|
);
|
|
147
147
|
};
|
|
@@ -7,11 +7,12 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import styled from '@emotion/styled';
|
|
10
|
-
import React
|
|
10
|
+
import React from 'react';
|
|
11
11
|
import SafeLink from '@ndla/safelink';
|
|
12
12
|
import { colors, fonts, spacing } from '@ndla/core';
|
|
13
|
+
import { MenuButton, MenuItemProps } from '@ndla/button';
|
|
13
14
|
import Image from '../Image';
|
|
14
|
-
import {
|
|
15
|
+
import { CompressedTagList, ResourceImageProps, ResourceTitle, Row, TopicList } from './resourceComponents';
|
|
15
16
|
|
|
16
17
|
interface BlockResourceProps {
|
|
17
18
|
link: string;
|
|
@@ -20,7 +21,7 @@ interface BlockResourceProps {
|
|
|
20
21
|
topics: string[];
|
|
21
22
|
tags?: string[];
|
|
22
23
|
description?: string;
|
|
23
|
-
|
|
24
|
+
menuItems?: MenuItemProps[];
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
const BlockElementWrapper = styled(SafeLink)`
|
|
@@ -77,7 +78,7 @@ const ImageWrapper = styled.div`
|
|
|
77
78
|
}
|
|
78
79
|
`;
|
|
79
80
|
|
|
80
|
-
const BlockResource = ({ link, title, tags, resourceImage, topics, description,
|
|
81
|
+
const BlockResource = ({ link, title, tags, resourceImage, topics, description, menuItems }: BlockResourceProps) => {
|
|
81
82
|
return (
|
|
82
83
|
<BlockElementWrapper to={link}>
|
|
83
84
|
<ImageWrapper>
|
|
@@ -90,8 +91,8 @@ const BlockResource = ({ link, title, tags, resourceImage, topics, description,
|
|
|
90
91
|
<TopicList topics={topics} />
|
|
91
92
|
<BlockDescription>{description}</BlockDescription>
|
|
92
93
|
<RightRow>
|
|
93
|
-
{tags &&
|
|
94
|
-
{
|
|
94
|
+
{tags && <CompressedTagList tags={tags} />}
|
|
95
|
+
{menuItems && menuItems.length > 0 && <MenuButton size="small" menuItems={menuItems} />}
|
|
95
96
|
</RightRow>
|
|
96
97
|
</BlockInfoWrapper>
|
|
97
98
|
</BlockElementWrapper>
|
|
@@ -7,11 +7,12 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import styled from '@emotion/styled';
|
|
10
|
-
import React
|
|
10
|
+
import React from 'react';
|
|
11
11
|
import SafeLink from '@ndla/safelink';
|
|
12
12
|
import { fonts, spacing, colors, breakpoints, mq } from '@ndla/core';
|
|
13
|
+
import { MenuButton, MenuItemProps } from '@ndla/button';
|
|
13
14
|
import Image from '../Image';
|
|
14
|
-
import {
|
|
15
|
+
import { CompressedTagList, ResourceImageProps, ResourceTitle, TopicList } from './resourceComponents';
|
|
15
16
|
|
|
16
17
|
const ResourceDescription = styled.p`
|
|
17
18
|
grid-area: description;
|
|
@@ -30,12 +31,13 @@ const ResourceDescription = styled.p`
|
|
|
30
31
|
`;
|
|
31
32
|
|
|
32
33
|
const ResourceWrapper = styled(SafeLink)`
|
|
33
|
-
display: grid;
|
|
34
34
|
flex: 1;
|
|
35
|
+
display: grid;
|
|
36
|
+
grid-template-columns: auto 1fr auto;
|
|
35
37
|
grid-template-areas:
|
|
36
38
|
'image topicAndTitle tags'
|
|
37
39
|
'image description description';
|
|
38
|
-
|
|
40
|
+
|
|
39
41
|
${mq.range({ until: breakpoints.mobileWide })} {
|
|
40
42
|
grid-template-columns: auto 1fr;
|
|
41
43
|
grid-template-areas:
|
|
@@ -51,6 +53,7 @@ const ResourceWrapper = styled(SafeLink)`
|
|
|
51
53
|
border-radius: 2px;
|
|
52
54
|
color: ${colors.brand.greyDark};
|
|
53
55
|
gap: 0 ${spacing.small};
|
|
56
|
+
|
|
54
57
|
&:hover {
|
|
55
58
|
box-shadow: 1px 1px 6px 2px rgba(9, 55, 101, 0.08);
|
|
56
59
|
transition-duration: 0.2s;
|
|
@@ -109,10 +112,10 @@ export interface ListResourceProps {
|
|
|
109
112
|
topics: string[];
|
|
110
113
|
tags?: string[];
|
|
111
114
|
description?: string;
|
|
112
|
-
|
|
115
|
+
menuItems?: MenuItemProps[];
|
|
113
116
|
}
|
|
114
117
|
|
|
115
|
-
const ListResource = ({ link, title, tags, resourceImage, topics, description,
|
|
118
|
+
const ListResource = ({ link, title, tags, resourceImage, topics, description, menuItems }: ListResourceProps) => {
|
|
116
119
|
const showDescription = description !== undefined;
|
|
117
120
|
|
|
118
121
|
return (
|
|
@@ -126,8 +129,8 @@ const ListResource = ({ link, title, tags, resourceImage, topics, description, a
|
|
|
126
129
|
</TopicAndTitle>
|
|
127
130
|
{showDescription && <ResourceDescription>{description}</ResourceDescription>}
|
|
128
131
|
<TagsandActionMenu>
|
|
129
|
-
{tags &&
|
|
130
|
-
{
|
|
132
|
+
{tags && <CompressedTagList tags={tags} />}
|
|
133
|
+
{menuItems && menuItems.length > 0 && <MenuButton size="small" menuItems={menuItems} />}
|
|
131
134
|
</TagsandActionMenu>
|
|
132
135
|
</ResourceWrapper>
|
|
133
136
|
);
|
|
@@ -103,7 +103,11 @@ export const TagList = ({ tags }: TagListProps) => {
|
|
|
103
103
|
);
|
|
104
104
|
};
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
interface CompressedTagListProps {
|
|
107
|
+
tags: string[];
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export const CompressedTagList = ({ tags }: CompressedTagListProps) => {
|
|
107
111
|
const visibleTags = tags.slice(0, 3);
|
|
108
112
|
const remainingTags = tags.slice(3, tags.length).map((tag) => {
|
|
109
113
|
return {
|
|
@@ -11,6 +11,7 @@ import styled from '@emotion/styled';
|
|
|
11
11
|
import { ArrowDropDown } from '@ndla/icons/common';
|
|
12
12
|
import { FolderOutlined } from '@ndla/icons/contentType';
|
|
13
13
|
import { colors, spacing, misc, animations } from '@ndla/core';
|
|
14
|
+
import SafeLink from '@ndla/safelink';
|
|
14
15
|
import { SetFocusedFolderId, FolderChildFuncType } from './TreeStructure.types';
|
|
15
16
|
|
|
16
17
|
const OpenButton = styled.button<{ isOpen: boolean }>`
|
|
@@ -75,7 +76,7 @@ const FolderName = styled.button<{ marked: boolean; noArrow?: boolean }>`
|
|
|
75
76
|
text-align: left;
|
|
76
77
|
`;
|
|
77
78
|
|
|
78
|
-
const FolderNameLink = FolderName.withComponent(
|
|
79
|
+
const FolderNameLink = FolderName.withComponent(SafeLink);
|
|
79
80
|
|
|
80
81
|
interface Props {
|
|
81
82
|
name: string;
|
|
@@ -135,9 +136,9 @@ const FolderItem = ({
|
|
|
135
136
|
<FolderNameLink
|
|
136
137
|
ref={folderNameLinkRef}
|
|
137
138
|
noArrow={hideArrow}
|
|
139
|
+
to={loading ? '' : url}
|
|
138
140
|
tabIndex={marked ? 0 : -1}
|
|
139
141
|
marked={marked}
|
|
140
|
-
href={loading ? undefined : url}
|
|
141
142
|
onFocus={() => {
|
|
142
143
|
setFocusedFolderId(id);
|
|
143
144
|
}}
|
|
@@ -12,7 +12,6 @@ import { animations, spacing } from '@ndla/core';
|
|
|
12
12
|
import FolderItem from './FolderItem';
|
|
13
13
|
import FolderNameInput from './FolderNameInput';
|
|
14
14
|
import { FolderItemsProps } from './TreeStructure.types';
|
|
15
|
-
import { MAX_LEVEL_FOR_FOLDERS } from './TreeStructure';
|
|
16
15
|
|
|
17
16
|
const StyledUL = styled.ul<{ firstLevel?: boolean }>`
|
|
18
17
|
${animations.fadeInLeft(animations.durations.fast)};
|
|
@@ -49,6 +48,7 @@ const FolderItems = ({
|
|
|
49
48
|
setFocusedFolderId,
|
|
50
49
|
firstLevel,
|
|
51
50
|
folderChild,
|
|
51
|
+
maximumLevelsOfFoldersAllowed,
|
|
52
52
|
}: FolderItemsProps) => (
|
|
53
53
|
<StyledUL role="group" firstLevel={firstLevel}>
|
|
54
54
|
{data.map(({ name, data: dataChildren, id, url, icon }, _index) => {
|
|
@@ -69,7 +69,7 @@ const FolderItems = ({
|
|
|
69
69
|
focusedFolderId={focusedFolderId}
|
|
70
70
|
onToggleOpen={onToggleOpen}
|
|
71
71
|
onMarkFolder={onMarkFolder}
|
|
72
|
-
hideArrow={dataChildren?.length === 0 || newIdPaths.length >=
|
|
72
|
+
hideArrow={dataChildren?.length === 0 || newIdPaths.length >= maximumLevelsOfFoldersAllowed}
|
|
73
73
|
noPaddingWhenArrowIsHidden={editable && firstLevel && dataChildren?.length === 0}
|
|
74
74
|
setFocusedFolderId={setFocusedFolderId}
|
|
75
75
|
folderChild={folderChild}
|
|
@@ -101,6 +101,7 @@ const FolderItems = ({
|
|
|
101
101
|
setFocusedFolderId={setFocusedFolderId}
|
|
102
102
|
firstLevel={false}
|
|
103
103
|
folderChild={folderChild}
|
|
104
|
+
maximumLevelsOfFoldersAllowed={maximumLevelsOfFoldersAllowed}
|
|
104
105
|
/>
|
|
105
106
|
)}
|
|
106
107
|
</StyledLI>
|
|
@@ -42,6 +42,7 @@ const TreeStructure = ({
|
|
|
42
42
|
folderIdMarkedByDefault,
|
|
43
43
|
defaultOpenFolders,
|
|
44
44
|
folderChild,
|
|
45
|
+
maximumLevelsOfFoldersAllowed,
|
|
45
46
|
}: TreeStructureProps) => {
|
|
46
47
|
const { t } = useTranslation();
|
|
47
48
|
const [newFolder, setNewFolder] = useState<NewFolderProps | undefined>();
|
|
@@ -117,6 +118,9 @@ const TreeStructure = ({
|
|
|
117
118
|
setFocusedFolderId(id);
|
|
118
119
|
};
|
|
119
120
|
|
|
121
|
+
const paths = getPathOfFolder(data, markedFolderId || '');
|
|
122
|
+
const canAddFolder = editable && paths.length < (maximumLevelsOfFoldersAllowed || 1);
|
|
123
|
+
|
|
120
124
|
return (
|
|
121
125
|
<div
|
|
122
126
|
ref={treestructureRef}
|
|
@@ -132,7 +136,7 @@ const TreeStructure = ({
|
|
|
132
136
|
});
|
|
133
137
|
}
|
|
134
138
|
}}>
|
|
135
|
-
<StyledLabel htmlFor={rootLevelId}>{label}</StyledLabel>
|
|
139
|
+
{label && <StyledLabel htmlFor={rootLevelId}>{label}</StyledLabel>}
|
|
136
140
|
<TreeStructureStyledWrapper ref={wrapperRef} id={rootLevelId} aria-label="Menu tree" role="tree" framed={framed}>
|
|
137
141
|
<FolderItems
|
|
138
142
|
idPaths={[]}
|
|
@@ -152,22 +156,28 @@ const TreeStructure = ({
|
|
|
152
156
|
setFocusedFolderId={setFocusedFolderId}
|
|
153
157
|
firstLevel
|
|
154
158
|
folderChild={folderChild}
|
|
159
|
+
maximumLevelsOfFoldersAllowed={maximumLevelsOfFoldersAllowed}
|
|
155
160
|
/>
|
|
156
161
|
</TreeStructureStyledWrapper>
|
|
157
162
|
{editable && (
|
|
158
163
|
<AddFolderWrapper>
|
|
159
164
|
<Tooltip
|
|
160
|
-
tooltip={
|
|
161
|
-
|
|
162
|
-
|
|
165
|
+
tooltip={
|
|
166
|
+
canAddFolder
|
|
167
|
+
? t('myNdla.newFolderUnder', {
|
|
168
|
+
folderName: getFolderName(data, markedFolderId),
|
|
169
|
+
})
|
|
170
|
+
: t('myNdla.maxFoldersAlreadyAdded')
|
|
171
|
+
}>
|
|
163
172
|
<AddButton
|
|
173
|
+
disabled={!canAddFolder}
|
|
164
174
|
aria-label={t('myNdla.newFolder')}
|
|
165
175
|
onClick={() => {
|
|
166
|
-
const paths = getPathOfFolder(data, markedFolderId || '');
|
|
167
176
|
const idPaths = getIdPathsOfFolder(data, markedFolderId || '');
|
|
168
177
|
setNewFolder({ idPaths, parentId: paths[paths.length - 1] });
|
|
169
|
-
}}
|
|
170
|
-
|
|
178
|
+
}}>
|
|
179
|
+
{t('myNdla.newFolder')}
|
|
180
|
+
</AddButton>
|
|
171
181
|
</Tooltip>
|
|
172
182
|
</AddFolderWrapper>
|
|
173
183
|
)}
|
|
@@ -175,4 +185,8 @@ const TreeStructure = ({
|
|
|
175
185
|
);
|
|
176
186
|
};
|
|
177
187
|
|
|
188
|
+
TreeStructure.defaultProps = {
|
|
189
|
+
maximumLevelsOfFoldersAllowed: MAX_LEVEL_FOR_FOLDERS,
|
|
190
|
+
};
|
|
191
|
+
|
|
178
192
|
export default TreeStructure;
|
|
@@ -34,11 +34,12 @@ interface CommonFolderProps {
|
|
|
34
34
|
|
|
35
35
|
export interface TreeStructureProps extends CommonFolderProps {
|
|
36
36
|
framed?: boolean;
|
|
37
|
-
label
|
|
37
|
+
label?: string;
|
|
38
38
|
folderIdMarkedByDefault?: string;
|
|
39
39
|
onNewFolder: (props: { value: string; parentId?: string; idPaths: number[] }) => Promise<string>;
|
|
40
40
|
defaultOpenFolders?: string[];
|
|
41
41
|
folderChild?: FolderChildFuncType;
|
|
42
|
+
maximumLevelsOfFoldersAllowed: number;
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
export type onCreateNewFolderProp = ({
|
|
@@ -70,4 +71,5 @@ export interface FolderItemsProps extends CommonFolderProps {
|
|
|
70
71
|
keyNavigationFocusIsCreateFolderButton?: boolean;
|
|
71
72
|
icon?: ReactNode;
|
|
72
73
|
folderChild?: FolderChildFuncType;
|
|
74
|
+
maximumLevelsOfFoldersAllowed: number;
|
|
73
75
|
}
|
|
@@ -20,6 +20,7 @@ const messages = {
|
|
|
20
20
|
delete: 'Delete',
|
|
21
21
|
},
|
|
22
22
|
createFolder: 'Create folder',
|
|
23
|
+
maxFoldersAlreadyAdded: 'Maximum subfolders reached',
|
|
23
24
|
newFolder: {
|
|
24
25
|
placeholder: 'Add foldername',
|
|
25
26
|
defaultName: 'New folder',
|
|
@@ -988,7 +989,13 @@ const messages = {
|
|
|
988
989
|
resources_plural: '{{count}} Resources',
|
|
989
990
|
folders: '{{count}} Folder',
|
|
990
991
|
folders_plural: '{{count}} Folders',
|
|
991
|
-
folder:
|
|
992
|
+
folder: {
|
|
993
|
+
folder: 'Folder',
|
|
994
|
+
delete: 'Delete',
|
|
995
|
+
edit: 'Edit',
|
|
996
|
+
},
|
|
997
|
+
confirmDeleteFolder: 'Are you sure you want to delete this folder? This process cannot be undone.',
|
|
998
|
+
confirmDeleteTag: 'Are you sure you want to delete this tag? This process cannot be undone.',
|
|
992
999
|
myFolders: 'My folders',
|
|
993
1000
|
myTags: 'My tags',
|
|
994
1001
|
newFolder: 'New folder',
|
|
@@ -1030,6 +1037,9 @@ const messages = {
|
|
|
1030
1037
|
},
|
|
1031
1038
|
},
|
|
1032
1039
|
resource: {
|
|
1040
|
+
add: 'Add folder/tag',
|
|
1041
|
+
remove: 'Remove',
|
|
1042
|
+
copyLink: 'Copy link to this page',
|
|
1033
1043
|
addToMyNdla: 'Add to My NDLA',
|
|
1034
1044
|
addedToMyNdla: 'Added to My NDLA',
|
|
1035
1045
|
},
|
|
@@ -20,6 +20,7 @@ const messages = {
|
|
|
20
20
|
delete: 'Slett',
|
|
21
21
|
},
|
|
22
22
|
createFolder: 'Lag mappe',
|
|
23
|
+
maxFoldersAlreadyAdded: 'Maks nivå av undermapper nådd',
|
|
23
24
|
newFolder: {
|
|
24
25
|
placeholder: 'Skriv navn på mappe',
|
|
25
26
|
defaultName: 'Ny mappe',
|
|
@@ -986,7 +987,13 @@ const messages = {
|
|
|
986
987
|
resources_plural: '{{count}} ressurser',
|
|
987
988
|
folders: '{{count}} mappe',
|
|
988
989
|
folders_plural: '{{count}} mapper',
|
|
989
|
-
folder:
|
|
990
|
+
folder: {
|
|
991
|
+
folder: 'Mappe',
|
|
992
|
+
delete: 'Slett',
|
|
993
|
+
edit: 'Rediger',
|
|
994
|
+
},
|
|
995
|
+
confirmDeleteFolder: 'Er du sikker på at du vil slette mappen? Denne handlingen kan ikke angres.',
|
|
996
|
+
confirmDeleteTag: 'Er du sikker på at du vil slette tag? Denne handlingen kan ikke angres.',
|
|
990
997
|
myFolders: 'Mine mapper',
|
|
991
998
|
myTags: 'Mine tags',
|
|
992
999
|
newFolder: 'Ny mappe',
|
|
@@ -1027,6 +1034,9 @@ const messages = {
|
|
|
1027
1034
|
},
|
|
1028
1035
|
},
|
|
1029
1036
|
resource: {
|
|
1037
|
+
add: 'Legg til mappe/tag',
|
|
1038
|
+
remove: 'Fjern',
|
|
1039
|
+
copyLink: 'Kopier lenke til siden',
|
|
1030
1040
|
addToMyNdla: 'Legg i Min NDLA',
|
|
1031
1041
|
addedToMyNdla: 'Lagt i Min NDLA',
|
|
1032
1042
|
},
|
|
@@ -20,6 +20,7 @@ const messages = {
|
|
|
20
20
|
delete: 'Slett',
|
|
21
21
|
},
|
|
22
22
|
createFolder: 'Lag mappe',
|
|
23
|
+
maxFoldersAlreadyAdded: 'Maks nivå av undermapper nådd',
|
|
23
24
|
newFolder: {
|
|
24
25
|
placeholder: 'Skriv namn på mappe',
|
|
25
26
|
defaultName: 'Ny mappe',
|
|
@@ -987,7 +988,13 @@ const messages = {
|
|
|
987
988
|
resources_plural: '{{count}} ressursar',
|
|
988
989
|
folders: '{{count}} mappe',
|
|
989
990
|
folders_plural: '{{count}} mapper',
|
|
990
|
-
folder:
|
|
991
|
+
folder: {
|
|
992
|
+
folder: 'Mappe',
|
|
993
|
+
delete: 'Slett',
|
|
994
|
+
edit: 'Rediger',
|
|
995
|
+
},
|
|
996
|
+
confirmDeleteFolder: 'Er du sikker på at du vil slette mappa? Denne handlinga kan ikkje angres.',
|
|
997
|
+
confirmDeleteTag: 'Er du sikker på at du vil slette tag? Denne handlinga kan ikkje angres.',
|
|
991
998
|
myFolders: 'Mine mapper',
|
|
992
999
|
myTags: 'Mine tags',
|
|
993
1000
|
newFolder: 'Ny mappe',
|
|
@@ -1028,6 +1035,9 @@ const messages = {
|
|
|
1028
1035
|
},
|
|
1029
1036
|
},
|
|
1030
1037
|
resource: {
|
|
1038
|
+
add: 'Legg til mappe/tag',
|
|
1039
|
+
remove: 'Fjern',
|
|
1040
|
+
copyLink: 'Kopier lenke til sida',
|
|
1031
1041
|
addToMyNdla: 'Legg i Min NDLA',
|
|
1032
1042
|
addedToMyNdla: 'Lagt i Min NDLA',
|
|
1033
1043
|
},
|