mirror of
https://github.com/nextcloud/server.git
synced 2026-05-28 04:32:30 -04:00
Merge pull request #53545 from nextcloud/backport/53140/stable31
This commit is contained in:
commit
5f63c89955
4 changed files with 119 additions and 61 deletions
|
|
@ -8,52 +8,56 @@
|
|||
<NcLoadingIcon v-if="loadingTags"
|
||||
:name="t('systemtags', 'Loading collaborative tags …')"
|
||||
:size="32" />
|
||||
<template v-else>
|
||||
<NcSelectTags class="system-tags__select"
|
||||
:input-label="t('systemtags', 'Search or create collaborative tags')"
|
||||
:placeholder="t('systemtags', 'Collaborative tags …')"
|
||||
:options="sortedTags"
|
||||
:value="selectedTags"
|
||||
:create-option="createOption"
|
||||
:disabled="disabled"
|
||||
:taggable="true"
|
||||
:passthru="true"
|
||||
:fetch-tags="false"
|
||||
:loading="loading"
|
||||
@input="handleInput"
|
||||
@option:selected="handleSelect"
|
||||
@option:created="handleCreate"
|
||||
@option:deselected="handleDeselect">
|
||||
<template #no-options>
|
||||
{{ t('systemtags', 'No tags to select, type to create a new tag') }}
|
||||
</template>
|
||||
</NcSelectTags>
|
||||
</template>
|
||||
|
||||
<NcSelectTags v-show="!loadingTags"
|
||||
class="system-tags__select"
|
||||
:input-label="t('systemtags', 'Search or create collaborative tags')"
|
||||
:placeholder="t('systemtags', 'Collaborative tags …')"
|
||||
:options="sortedTags"
|
||||
:value="selectedTags"
|
||||
:create-option="createOption"
|
||||
:disabled="disabled"
|
||||
:taggable="true"
|
||||
:passthru="true"
|
||||
:fetch-tags="false"
|
||||
:loading="loading"
|
||||
@input="handleInput"
|
||||
@option:selected="handleSelect"
|
||||
@option:created="handleCreate"
|
||||
@option:deselected="handleDeselect">
|
||||
<template #no-options>
|
||||
{{ t('systemtags', 'No tags to select, type to create a new tag') }}
|
||||
</template>
|
||||
</NcSelectTags>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
// FIXME Vue TypeScript ESLint errors
|
||||
/* eslint-disable */
|
||||
import type { Node } from '@nextcloud/files'
|
||||
import type { Tag, TagWithId } from '../types.js'
|
||||
|
||||
import Vue from 'vue'
|
||||
import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
|
||||
import NcSelectTags from '@nextcloud/vue/dist/Components/NcSelectTags.js'
|
||||
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
import { emit, subscribe } from '@nextcloud/event-bus'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { showError } from '@nextcloud/dialogs'
|
||||
import { t } from '@nextcloud/l10n'
|
||||
|
||||
import { defaultBaseTag } from '../utils.js'
|
||||
import { fetchLastUsedTagIds, fetchTags } from '../services/api.js'
|
||||
import { fetchNode } from '../../../files/src/services/WebdavClient.js'
|
||||
import {
|
||||
createTagForFile,
|
||||
deleteTagForFile,
|
||||
fetchTagsForFile,
|
||||
setTagForFile,
|
||||
} from '../services/files.js'
|
||||
import logger from '../logger.js'
|
||||
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
|
||||
import type { Tag, TagWithId } from '../types.js'
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'SystemTags',
|
||||
|
|
@ -125,6 +129,10 @@ export default Vue.extend({
|
|||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
subscribe('systemtags:node:updated', this.onTagUpdated)
|
||||
},
|
||||
|
||||
methods: {
|
||||
t,
|
||||
|
||||
|
|
@ -179,6 +187,8 @@ export default Vue.extend({
|
|||
showError(t('systemtags', 'Failed to select tag'))
|
||||
}
|
||||
this.loading = false
|
||||
|
||||
this.updateAndDispatchNodeTagsEvent(this.fileId)
|
||||
},
|
||||
|
||||
async handleCreate(tag: Tag) {
|
||||
|
|
@ -197,6 +207,8 @@ export default Vue.extend({
|
|||
showError(t('systemtags', 'Failed to create tag'))
|
||||
}
|
||||
this.loading = false
|
||||
|
||||
this.updateAndDispatchNodeTagsEvent(this.fileId)
|
||||
},
|
||||
|
||||
async handleDeselect(tag: TagWithId) {
|
||||
|
|
@ -207,6 +219,35 @@ export default Vue.extend({
|
|||
showError(t('systemtags', 'Failed to delete tag'))
|
||||
}
|
||||
this.loading = false
|
||||
|
||||
this.updateAndDispatchNodeTagsEvent(this.fileId)
|
||||
},
|
||||
|
||||
async onTagUpdated(node: Node) {
|
||||
if (node.fileid !== this.fileId) {
|
||||
return
|
||||
}
|
||||
|
||||
this.loadingTags = true
|
||||
try {
|
||||
this.selectedTags = await fetchTagsForFile(this.fileId)
|
||||
} catch (error) {
|
||||
showError(t('systemtags', 'Failed to load selected tags'))
|
||||
}
|
||||
|
||||
this.loadingTags = false
|
||||
},
|
||||
|
||||
async updateAndDispatchNodeTagsEvent(fileId: number) {
|
||||
const path = window.OCA?.Files?.Sidebar?.file || ''
|
||||
try {
|
||||
const node = await fetchNode(path)
|
||||
if (node) {
|
||||
emit('systemtags:node:updated', node)
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Failed to fetch node for system tags update', { error, fileId })
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
|
|
|
|||
|
|
@ -22,8 +22,10 @@ describe('Systemtags: Files integration', { testIsolation: true }, () => {
|
|||
it('See first assigned tag in the file list', () => {
|
||||
const tag = randomBytes(8).toString('base64')
|
||||
|
||||
cy.intercept('PROPFIND', `**/remote.php/dav/files/${user.userId}/file.txt`).as('getNode')
|
||||
getRowForFile('file.txt').should('be.visible')
|
||||
triggerActionForFile('file.txt', 'details')
|
||||
cy.wait('@getNode')
|
||||
|
||||
cy.get('[data-cy-sidebar]')
|
||||
.should('be.visible')
|
||||
|
|
@ -36,13 +38,14 @@ describe('Systemtags: Files integration', { testIsolation: true }, () => {
|
|||
.click()
|
||||
|
||||
cy.intercept('PUT', '**/remote.php/dav/systemtags-relations/files/**').as('assignTag')
|
||||
cy.get('[data-cy-sidebar]')
|
||||
.findByRole('combobox', { name: /collaborative tags/i })
|
||||
.should('be.visible')
|
||||
.type(`${tag}{enter}`)
|
||||
cy.wait('@assignTag')
|
||||
closeSidebar()
|
||||
|
||||
getCollaborativeTagsInput()
|
||||
.type(`{selectAll}${tag}{enter}`)
|
||||
cy.wait('@assignTag')
|
||||
cy.wait('@getNode')
|
||||
|
||||
// Close the sidebar and reload to check the file list
|
||||
closeSidebar()
|
||||
cy.reload()
|
||||
|
||||
getRowForFile('file.txt')
|
||||
|
|
@ -56,8 +59,10 @@ describe('Systemtags: Files integration', { testIsolation: true }, () => {
|
|||
const tag1 = randomBytes(5).toString('base64')
|
||||
const tag2 = randomBytes(5).toString('base64')
|
||||
|
||||
cy.intercept('PROPFIND', `**/remote.php/dav/files/${user.userId}/file.txt`).as('getNode')
|
||||
getRowForFile('file.txt').should('be.visible')
|
||||
triggerActionForFile('file.txt', 'details')
|
||||
cy.wait('@getNode')
|
||||
|
||||
cy.get('[data-cy-sidebar]')
|
||||
.should('be.visible')
|
||||
|
|
@ -70,17 +75,20 @@ describe('Systemtags: Files integration', { testIsolation: true }, () => {
|
|||
.click()
|
||||
|
||||
cy.intercept('PUT', '**/remote.php/dav/systemtags-relations/files/**').as('assignTag')
|
||||
cy.get('[data-cy-sidebar]').within(() => {
|
||||
cy.findByRole('combobox', { name: /collaborative tags/i })
|
||||
.should('be.visible')
|
||||
.type(`${tag1}{enter}`)
|
||||
cy.wait('@assignTag')
|
||||
cy.findByRole('combobox', { name: /collaborative tags/i })
|
||||
.should('be.visible')
|
||||
.type(`${tag2}{enter}`)
|
||||
cy.wait('@assignTag')
|
||||
})
|
||||
|
||||
// Assign first tag
|
||||
getCollaborativeTagsInput()
|
||||
.type(`{selectAll}${tag1}{enter}`)
|
||||
cy.wait('@assignTag')
|
||||
cy.wait('@getNode')
|
||||
|
||||
// Assign second tag
|
||||
getCollaborativeTagsInput()
|
||||
.type(`{selectAll}${tag2}{enter}`)
|
||||
cy.wait('@assignTag')
|
||||
cy.wait('@getNode')
|
||||
|
||||
// Close the sidebar and reload to check the file list
|
||||
closeSidebar()
|
||||
cy.reload()
|
||||
|
||||
|
|
@ -97,11 +105,10 @@ describe('Systemtags: Files integration', { testIsolation: true }, () => {
|
|||
const tag2 = randomBytes(4).toString('base64')
|
||||
const tag3 = randomBytes(4).toString('base64')
|
||||
|
||||
cy.intercept('PROPFIND', `**/remote.php/dav/files/${user.userId}/file.txt`).as('getNode')
|
||||
getRowForFile('file.txt').should('be.visible')
|
||||
|
||||
cy.intercept('PROPFIND', '**/remote.php/dav/**').as('sidebarLoaded')
|
||||
triggerActionForFile('file.txt', 'details')
|
||||
cy.wait('@sidebarLoaded')
|
||||
cy.wait('@getNode')
|
||||
|
||||
cy.get('[data-cy-sidebar]')
|
||||
.should('be.visible')
|
||||
|
|
@ -114,23 +121,26 @@ describe('Systemtags: Files integration', { testIsolation: true }, () => {
|
|||
.click()
|
||||
|
||||
cy.intercept('PUT', '**/remote.php/dav/systemtags-relations/files/**').as('assignTag')
|
||||
cy.get('[data-cy-sidebar]').within(() => {
|
||||
cy.findByRole('combobox', { name: /collaborative tags/i })
|
||||
.should('be.visible')
|
||||
.type(`${tag1}{enter}`)
|
||||
cy.wait('@assignTag')
|
||||
|
||||
cy.findByRole('combobox', { name: /collaborative tags/i })
|
||||
.should('be.visible')
|
||||
.type(`${tag2}{enter}`)
|
||||
cy.wait('@assignTag')
|
||||
// Assign first tag
|
||||
getCollaborativeTagsInput()
|
||||
.type(`{selectAll}${tag1}{enter}`)
|
||||
cy.wait('@assignTag')
|
||||
cy.wait('@getNode')
|
||||
|
||||
cy.findByRole('combobox', { name: /collaborative tags/i })
|
||||
.should('be.visible')
|
||||
.type(`${tag3}{enter}`)
|
||||
cy.wait('@assignTag')
|
||||
})
|
||||
// Assign second tag
|
||||
getCollaborativeTagsInput()
|
||||
.type(`{selectAll}${tag2}{enter}`)
|
||||
cy.wait('@assignTag')
|
||||
cy.wait('@getNode')
|
||||
|
||||
// Assign third tag
|
||||
getCollaborativeTagsInput()
|
||||
.type(`{selectAll}${tag3}{enter}`)
|
||||
cy.wait('@assignTag')
|
||||
cy.wait('@getNode')
|
||||
|
||||
// Close the sidebar and reload to check the file list
|
||||
closeSidebar()
|
||||
cy.reload()
|
||||
|
||||
|
|
@ -153,3 +163,10 @@ describe('Systemtags: Files integration', { testIsolation: true }, () => {
|
|||
})
|
||||
})
|
||||
})
|
||||
|
||||
function getCollaborativeTagsInput(): Cypress.Chainable<JQuery<HTMLElement>> {
|
||||
return cy.get('[data-cy-sidebar]')
|
||||
.findByRole('combobox', { name: /collaborative tags/i })
|
||||
.should('be.visible')
|
||||
.should('not.have.attr', 'disabled', { timeout: 5000 })
|
||||
}
|
||||
|
|
|
|||
4
dist/files-sidebar.js
vendored
4
dist/files-sidebar.js
vendored
File diff suppressed because one or more lines are too long
2
dist/files-sidebar.js.map
vendored
2
dist/files-sidebar.js.map
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue