Skip to content

Commit

Permalink
fixup! feat(systemtags): add bulk tagging action
Browse files Browse the repository at this point in the history
Signed-off-by: skjnldsv <[email protected]>
  • Loading branch information
skjnldsv committed Oct 18, 2024
1 parent e2878a6 commit ee3e7cb
Showing 1 changed file with 131 additions and 15 deletions.
146 changes: 131 additions & 15 deletions apps/systemtags/src/components/SystemTagPicker.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<template>
<NcDialog data-cy-systemtags-picker
:name="t('systemtags', 'Manage tags')"
:open="true"
:open="opened"
class="systemtags-picker"
close-on-click-outside
out-transition
@update:open="emit('close', null)">
@update:open="onCancel">
<!-- Search or create input -->
<div class="systemtags-picker__create">
<NcTextField :value.sync="input"
Expand All @@ -30,12 +30,22 @@
</NcCheckboxRadioSwitch>
</div>

<!-- Note -->
<div class="systemtags-picker__note">
<NcNoteCard v-if="!hasChanges" type="info">
{{ t('systemtags', 'Select or create tags to apply to all selected files') }}
</NcNoteCard>
<NcNoteCard v-else type="info">
<span v-html="statusMessage" />
</NcNoteCard>
</div>

<template #actions>
<NcButton @click="emit('close', null)">
<NcButton type="tertiary" @click="onCancel">
{{ t('systemtags', 'Cancel') }}
</NcButton>
<NcButton type="tertiary" @click="onSubmit">
{{ t('systemtags', 'Close') }}
<NcButton :disabled="!hasChanges" @click="onSubmit">
{{ t('systemtags', 'Apply changes') }}
</NcButton>
</template>
</NcDialog>
Expand All @@ -53,11 +63,13 @@ import { t } from '@nextcloud/l10n'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
import NcDialog from '@nextcloud/vue/dist/Components/NcDialog.js'
import NcNoteCard from '@nextcloud/vue/dist/Components/NcNoteCard.js'
import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'
import TagIcon from 'vue-material-design-icons/Tag.vue'
import logger from '../services/logger'
import { getNodeSystemTags } from '../utils'
import { showInfo } from '@nextcloud/dialogs'
type TagListCount = {
string: number
Expand All @@ -70,6 +82,7 @@ export default defineComponent({
NcButton,
NcCheckboxRadioSwitch,
NcDialog,
NcNoteCard,
NcTextField,
TagIcon,
},
Expand All @@ -96,7 +109,11 @@ export default defineComponent({
data() {
return {
input: '',
opened: true,
tagList: {} as TagListCount,
toAdd: [] as TagWithId[],
toRemove: [] as TagWithId[],
}
},
Expand All @@ -109,6 +126,74 @@ export default defineComponent({
return this.tags
.filter(tag => tag.displayName.normalize().includes(this.input.normalize()))
},
hasChanges(): boolean {
return this.toAdd.length > 0 || this.toRemove.length > 0
},
statusMessage(): string {
if (this.toAdd.length === 1 && this.toRemove.length === 1) {
return t('systemtags', '{tag1} will be set and {tag2} will be removed from {count} files.', {
tag1: this.toAdd[0].displayName,
tag2: this.toRemove[0].displayName,
count: this.nodes.length,
})
}
const tagsAdd = this.toAdd.map(tag => tag.displayName)
const lastTagAdd = tagsAdd.pop() as string
const tagsRemove = this.toRemove.map(tag => tag.displayName)
const lastTagRemove = tagsRemove.pop() as string
const addStringSingular = t('systemtags', '{tag} will be set to {count} files.', {
tag: this.toAdd[0]?.displayName,
count: this.nodes.length,
})
const removeStringSingular = t('systemtags', '{tag} will be removed from {count} files.', {
tag: this.toRemove[0]?.displayName,
count: this.nodes.length,
})
const addStringPlural = t('systemtags', '{tags} and {lastTag} will be set to {count} files.', {
tags: tagsAdd.join(', '),
lastTag: lastTagAdd,
count: this.nodes.length,
})
const removeStringPlural = t('systemtags', '{tags} and {lastTag} will be removed from {count} files.', {
tags: tagsRemove.join(', '),
lastTag: lastTagRemove,
count: this.nodes.length,
})
// Singular
if (this.toAdd.length === 1 && this.toRemove.length === 0) {
return addStringSingular
}
if (this.toAdd.length === 0 && this.toRemove.length === 1) {
return removeStringSingular
}
// Plural
if (this.toAdd.length > 1 && this.toRemove.length === 0) {
return addStringPlural
}
if (this.toAdd.length === 0 && this.toRemove.length > 1) {
return removeStringPlural
}
// Mixed
if (this.toAdd.length > 1 && this.toRemove.length === 1) {
return `${addStringPlural}<br>${removeStringSingular}`
}
if (this.toAdd.length === 1 && this.toRemove.length > 1) {
return `${addStringSingular}<br>${removeStringPlural}`
}
// Both plural
return `${addStringPlural}<br>${removeStringPlural}`
},
},
beforeMount() {
Expand Down Expand Up @@ -136,38 +221,69 @@ export default defineComponent({
},
isChecked(tag: TagWithId): boolean {
return this.tagList[tag.displayName]
&& this.tagList[tag.displayName] === this.nodes.length
return this.tagList[tag.displayName] === this.nodes.length
},
isIndeterminate(tag: TagWithId): boolean {
return this.tagList[tag.displayName] !== 0
return this.tagList[tag.displayName]
&& this.tagList[tag.displayName] !== 0
&& this.tagList[tag.displayName] !== this.nodes.length
},
onCheckUpdate(tag: TagWithId, checked: boolean) {
logger.debug('onCheckUpdate', { tag, checked })
if (checked) {
this.toAdd.push(tag)
this.toRemove = this.toRemove.filter(search => search.id !== tag.id)
this.tagList[tag.displayName] = this.nodes.length
} else {
this.toRemove.push(tag)
this.toAdd = this.toAdd.filter(search => search.id !== tag.id)
this.tagList[tag.displayName] = 0
}
},
onSubmit() {
logger.debug('onSubmit')
this.$emit('close', null)
},
onCancel() {
this.opened = false
showInfo(t('systemtags', 'File tags modification canceled'))
this.$emit('close', null)
},
},
})
</script>

<style scoped lang="scss">
// Common sticky properties
.systemtags-picker__create,
.systemtags-picker__note {
position: sticky;
z-index: 9;
background-color: var(--color-main-background);
}
.systemtags-picker__create {
display: flex;
align-items: center;
.input-field {
margin: 0;
margin-inline-end: 10px;
}
top: 0;
gap: 8px;
padding-block-end: 8px;
align-items: flex-end;
button {
flex-shrink: 0;
}
}
.systemtags-picker__note {
bottom: 0;
padding-block: 8px;
& > div {
margin: 0 !important;
}
}
</style>

0 comments on commit ee3e7cb

Please sign in to comment.