Skip to content

Commit da33770

Browse files
committed
fix(systemtags): support new attribute parsing of webdav props
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
1 parent 321254f commit da33770

3 files changed

Lines changed: 110 additions & 10 deletions

File tree

apps/systemtags/src/files_actions/bulkSystemTagsAction.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ import { loadState } from '@nextcloud/initial-state'
1414

1515
import TagMultipleSvg from '@mdi/svg/svg/tag-multiple.svg?raw'
1616

17+
const restrictSystemTagsCreationToAdmin = loadState<'0'|'1'>('settings', 'restrictSystemTagsCreationToAdmin', '0') === '1'
18+
1719
/**
18-
*
19-
* @param nodes
20+
* Spawn a dialog to add or remove tags from multiple nodes.
21+
* @param nodes Nodes to modify tags for
2022
*/
2123
async function execBatch(nodes: Node[]): Promise<(null|boolean)[]> {
2224
const response = await new Promise<null|boolean>((resolve) => {
@@ -37,7 +39,7 @@ export const action = new FileAction({
3739
// If the app is disabled, the action is not available anyway
3840
enabled(nodes) {
3941
// By default, everyone can create system tags
40-
if (loadState('settings', 'restrictSystemTagsCreationToAdmin', '0') === '1' && getCurrentUser()?.isAdmin !== true) {
42+
if (restrictSystemTagsCreationToAdmin && getCurrentUser()?.isAdmin !== true) {
4143
return false
4244
}
4345

@@ -50,7 +52,7 @@ export const action = new FileAction({
5052
}
5153

5254
// Disabled for non dav resources
53-
if (nodes.some((node) => !node.isDavRessource)) {
55+
if (nodes.some((node) => !node.isDavResource)) {
5456
return false
5557
}
5658

apps/systemtags/src/utils.spec.ts

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55

66
import type { DAVResultResponseProps } from 'webdav'
77
import type { ServerTag, Tag } from './types.js'
8-
import { describe, expect, it } from 'vitest'
98

10-
import { formatTag, parseIdFromLocation, parseTags } from './utils'
9+
import { describe, expect, it } from 'vitest'
10+
import { formatTag, getNodeSystemTags, parseIdFromLocation, parseTags } from './utils'
11+
import { Folder } from '@nextcloud/files'
1112

1213
describe('systemtags - utils', () => {
1314
describe('parseTags', () => {
@@ -85,4 +86,92 @@ describe('systemtags - utils', () => {
8586
})
8687
})
8788
})
89+
90+
describe('getNodeSystemTags', () => {
91+
it('parses a plain tag', () => {
92+
const node = new Folder({
93+
owner: 'test',
94+
source: 'https://example.com/remote.php/dav/files/test/folder',
95+
attributes: {
96+
'system-tags': {
97+
'system-tag': 'tag',
98+
},
99+
},
100+
})
101+
expect(getNodeSystemTags(node)).toStrictEqual(['tag'])
102+
})
103+
104+
it('parses plain tags', () => {
105+
const node = new Folder({
106+
owner: 'test',
107+
source: 'https://example.com/remote.php/dav/files/test/folder',
108+
attributes: {
109+
'system-tags': {
110+
'system-tag': [
111+
'tag',
112+
'my-tag',
113+
],
114+
},
115+
},
116+
})
117+
expect(getNodeSystemTags(node)).toStrictEqual(['tag', 'my-tag'])
118+
})
119+
120+
it('parses tag with attributes', () => {
121+
const node = new Folder({
122+
owner: 'test',
123+
source: 'https://example.com/remote.php/dav/files/test/folder',
124+
attributes: {
125+
'system-tags': {
126+
'system-tag': {
127+
text: 'tag',
128+
'@can-assign': true,
129+
},
130+
},
131+
},
132+
})
133+
expect(getNodeSystemTags(node)).toStrictEqual(['tag'])
134+
})
135+
136+
it('parses tags with attributes', () => {
137+
const node = new Folder({
138+
owner: 'test',
139+
source: 'https://example.com/remote.php/dav/files/test/folder',
140+
attributes: {
141+
'system-tags': {
142+
'system-tag': [
143+
{
144+
text: 'tag',
145+
'@can-assign': true,
146+
},
147+
{
148+
text: 'my-tag',
149+
'@can-assign': false,
150+
},
151+
],
152+
},
153+
},
154+
})
155+
expect(getNodeSystemTags(node)).toStrictEqual(['tag', 'my-tag'])
156+
})
157+
158+
it('parses tags mixed with and without attributes', () => {
159+
const node = new Folder({
160+
owner: 'test',
161+
source: 'https://example.com/remote.php/dav/files/test/folder',
162+
attributes: {
163+
'system-tags': {
164+
'system-tag': [
165+
'tag',
166+
{
167+
text: 'my-tag',
168+
'@can-assign': false,
169+
},
170+
],
171+
},
172+
},
173+
})
174+
expect(getNodeSystemTags(node)).toStrictEqual(['tag', 'my-tag'])
175+
})
176+
})
88177
})

apps/systemtags/src/utils.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,22 @@ export const formatTag = (initialTag: Tag | ServerTag): ServerTag => {
5959
}
6060

6161
export const getNodeSystemTags = function(node: Node): string[] {
62-
const tags = node.attributes?.['system-tags']?.['system-tag'] as string|string[]|undefined
63-
64-
if (tags === undefined) {
62+
const attribute = node.attributes?.['system-tags']?.['system-tag']
63+
if (attribute === undefined) {
6564
return []
6665
}
6766

68-
return [tags].flat()
67+
// if there is only one tag it is a single string or prop object
68+
// if there are multiple then its an array - so we flatten it to be always an array of string or prop objects
69+
return [attribute]
70+
.flat()
71+
.map((tag: string|{ text: string }) => (
72+
typeof tag === 'string'
73+
// its a plain text prop (the tag name) without prop attributes
74+
? tag
75+
// its a prop object with attributes, the tag name is in the 'text' attribute
76+
: tag.text
77+
))
6978
}
7079

7180
export const setNodeSystemTags = function(node: Node, tags: string[]): void {

0 commit comments

Comments
 (0)