diff --git a/apps/systemtags/src/services/api.ts b/apps/systemtags/src/services/api.ts
index 91393e0afe4..0e3b7e09c6e 100644
--- a/apps/systemtags/src/services/api.ts
+++ b/apps/systemtags/src/services/api.ts
@@ -19,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
import type { FileStat, ResponseDataDetailed } from 'webdav'
import type { ServerTag, Tag, TagWithId } from '../types.js'
@@ -30,7 +31,7 @@ import { davClient } from './davClient.js'
import { formatTag, parseIdFromLocation, parseTags } from '../utils'
import { logger } from '../logger.js'
-const fetchTagsBody = `
+export const fetchTagsBody = `
@@ -67,39 +68,10 @@ export const fetchLastUsedTagIds = async (): Promise => {
}
}
-export const fetchSelectedTags = async (fileId: number): Promise => {
- const path = '/systemtags-relations/files/' + fileId
- try {
- const { data: tags } = await davClient.getDirectoryContents(path, {
- data: fetchTagsBody,
- details: true,
- glob: '/systemtags-relations/files/*/*', // Filter out first empty tag
- }) as ResponseDataDetailed[]>
- return parseTags(tags)
- } catch (error) {
- logger.error(t('systemtags', 'Failed to load selected tags'), { error })
- throw new Error(t('systemtags', 'Failed to load selected tags'))
- }
-}
-
-export const selectTag = async (fileId: number, tag: Tag | ServerTag): Promise => {
- const path = '/systemtags-relations/files/' + fileId + '/' + tag.id
- const tagToPut = formatTag(tag)
- try {
- await davClient.customRequest(path, {
- method: 'PUT',
- data: tagToPut,
- })
- } catch (error) {
- logger.error(t('systemtags', 'Failed to select tag'), { error })
- throw new Error(t('systemtags', 'Failed to select tag'))
- }
-}
-
/**
* @return created tag id
*/
-export const createTag = async (fileId: number, tag: Tag): Promise => {
+export const createTag = async (tag: Tag | ServerTag): Promise => {
const path = '/systemtags'
const tagToPost = formatTag(tag)
try {
@@ -109,12 +81,7 @@ export const createTag = async (fileId: number, tag: Tag): Promise => {
})
const contentLocation = headers.get('content-location')
if (contentLocation) {
- const tagToPut = {
- ...tagToPost,
- id: parseIdFromLocation(contentLocation),
- }
- await selectTag(fileId, tagToPut)
- return tagToPut.id
+ return parseIdFromLocation(contentLocation)
}
logger.error(t('systemtags', 'Missing "Content-Location" header'))
throw new Error(t('systemtags', 'Missing "Content-Location" header'))
@@ -124,8 +91,32 @@ export const createTag = async (fileId: number, tag: Tag): Promise => {
}
}
-export const deleteTag = async (fileId: number, tag: Tag): Promise => {
- const path = '/systemtags-relations/files/' + fileId + '/' + tag.id
+export const updateTag = async (tag: TagWithId): Promise => {
+ const path = '/systemtags/' + tag.id
+ const data = `
+
+
+
+ ${tag.displayName}
+ ${tag.userVisible}
+ ${tag.userAssignable}
+
+
+ `
+
+ try {
+ await davClient.customRequest(path, {
+ method: 'PROPPATCH',
+ data,
+ })
+ } catch (error) {
+ logger.error(t('systemtags', 'Failed to update tag'), { error })
+ throw new Error(t('systemtags', 'Failed to update tag'))
+ }
+}
+
+export const deleteTag = async (tag: TagWithId): Promise => {
+ const path = '/systemtags/' + tag.id
try {
await davClient.deleteFile(path)
} catch (error) {
diff --git a/apps/systemtags/src/services/files.ts b/apps/systemtags/src/services/files.ts
new file mode 100644
index 00000000000..7dbd04c5350
--- /dev/null
+++ b/apps/systemtags/src/services/files.ts
@@ -0,0 +1,82 @@
+/**
+ * @copyright 2023 Christopher Ng
+ *
+ * @author Christopher Ng
+ *
+ * @license AGPL-3.0-or-later
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+import type { FileStat, ResponseDataDetailed } from 'webdav'
+import type { ServerTagWithId, Tag, TagWithId } from '../types.js'
+
+import { davClient } from './davClient.js'
+import { createTag, fetchTagsBody } from './api.js'
+import { formatTag, parseTags } from '../utils.js'
+import { logger } from '../logger.js'
+
+export const fetchTagsForFile = async (fileId: number): Promise => {
+ const path = '/systemtags-relations/files/' + fileId
+ try {
+ const { data: tags } = await davClient.getDirectoryContents(path, {
+ data: fetchTagsBody,
+ details: true,
+ glob: '/systemtags-relations/files/*/*', // Filter out first empty tag
+ }) as ResponseDataDetailed[]>
+ return parseTags(tags)
+ } catch (error) {
+ logger.error(t('systemtags', 'Failed to load tags for file'), { error })
+ throw new Error(t('systemtags', 'Failed to load tags for file'))
+ }
+}
+
+/**
+ * @return created tag id
+ */
+export const createTagForFile = async (tag: Tag, fileId: number): Promise => {
+ const tagToCreate = formatTag(tag)
+ const tagId = await createTag(tagToCreate)
+ const tagToSet: ServerTagWithId = {
+ ...tagToCreate,
+ id: tagId,
+ }
+ await setTagForFile(tagToSet, fileId)
+ return tagToSet.id
+}
+
+export const setTagForFile = async (tag: TagWithId | ServerTagWithId, fileId: number): Promise => {
+ const path = '/systemtags-relations/files/' + fileId + '/' + tag.id
+ const tagToPut = formatTag(tag)
+ try {
+ await davClient.customRequest(path, {
+ method: 'PUT',
+ data: tagToPut,
+ })
+ } catch (error) {
+ logger.error(t('systemtags', 'Failed to set tag for file'), { error })
+ throw new Error(t('systemtags', 'Failed to set tag for file'))
+ }
+}
+
+export const deleteTagForFile = async (tag: TagWithId, fileId: number): Promise => {
+ const path = '/systemtags-relations/files/' + fileId + '/' + tag.id
+ try {
+ await davClient.deleteFile(path)
+ } catch (error) {
+ logger.error(t('systemtags', 'Failed to delete tag for file'), { error })
+ throw new Error(t('systemtags', 'Failed to delete tag for file'))
+ }
+}
diff --git a/apps/systemtags/src/types.ts b/apps/systemtags/src/types.ts
index c38a360c1fe..f2cff9b06c2 100644
--- a/apps/systemtags/src/types.ts
+++ b/apps/systemtags/src/types.ts
@@ -36,3 +36,5 @@ export type TagWithId = Required
export type ServerTag = BaseTag & {
name: string
}
+
+export type ServerTagWithId = Required