feat(NcCollectionList): merge nextcloud-vue-collections into nextcloud/vue
Signed-off-by: Maksim Sukharev <antreesy.web@gmail.com>
This commit is contained in:
Родитель
196685c121
Коммит
0637422d32
|
@ -0,0 +1,345 @@
|
|||
<!--
|
||||
- SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
|
||||
- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-->
|
||||
|
||||
<template>
|
||||
<ul v-if="collections && type && id" id="collection-list" class="collection-list">
|
||||
<li @click="showSelect">
|
||||
<div class="avatar">
|
||||
<span class="icon-projects" />
|
||||
</div>
|
||||
<div id="collection-select-container">
|
||||
<NcSelect ref="select"
|
||||
v-model="value"
|
||||
:aria-label-combobox="t('core', 'Add to a project')"
|
||||
:options="options"
|
||||
:placeholder="placeholder"
|
||||
label="title"
|
||||
:limit="5"
|
||||
@close="isSelectOpen = false"
|
||||
@open="isSelectOpen = true"
|
||||
@option:selected="select"
|
||||
@search="search">
|
||||
<template #selected-option="option">
|
||||
<span class="option__desc">
|
||||
<span class="option__title">{{ option.title }}</span>
|
||||
</span>
|
||||
</template>
|
||||
<template #option="option">
|
||||
<span class="option__wrapper">
|
||||
<span v-if="option.class" :class="option.class" class="avatar" />
|
||||
<NcAvatar v-else-if="option.method !== 2" allow-placeholder :display-name="option.title" />
|
||||
<span class="option__title">{{ option.title }}</span>
|
||||
</span>
|
||||
</template>
|
||||
<p class="hint">
|
||||
{{ t('core', 'Connect items to a project to make them easier to find') }}
|
||||
</p>
|
||||
</NcSelect>
|
||||
</div>
|
||||
</li>
|
||||
<transition name="fade">
|
||||
<li v-if="error" class="error">
|
||||
{{ error }}
|
||||
</li>
|
||||
</transition>
|
||||
<NcCollectionListItem v-for="collection in collections" :key="collection.id" :collection="collection" />
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import debounce from 'debounce'
|
||||
import { t } from '@nextcloud/l10n'
|
||||
|
||||
import NcAvatar from '../NcAvatar/index.js'
|
||||
import NcSelect from '../NcSelect/index.js'
|
||||
import NcCollectionListItem from './NcCollectionListItem.vue'
|
||||
|
||||
import { state, actions } from './collectionstore.js'
|
||||
|
||||
const METHOD_CREATE_COLLECTION = 0
|
||||
const METHOD_ADD_TO_COLLECTION = 1
|
||||
|
||||
const _debouncedSearch = debounce(
|
||||
function(query, loading) {
|
||||
if (query !== '') {
|
||||
loading(true)
|
||||
actions.search(query).then((collections) => {
|
||||
this.searchCollections = collections
|
||||
}).catch(e => {
|
||||
console.error('Failed to search for collections', e)
|
||||
}).finally(() => {
|
||||
loading(false)
|
||||
})
|
||||
}
|
||||
}, 500)
|
||||
|
||||
export default {
|
||||
name: 'NcCollectionList',
|
||||
|
||||
components: {
|
||||
NcCollectionListItem,
|
||||
NcAvatar,
|
||||
NcSelect,
|
||||
},
|
||||
|
||||
props: {
|
||||
/**
|
||||
* Resource type identifier
|
||||
*/
|
||||
type: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
/**
|
||||
* Unique id of the resource
|
||||
*/
|
||||
id: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
/**
|
||||
* Name of the resource
|
||||
*/
|
||||
name: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
|
||||
isActive: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
|
||||
setup() {
|
||||
return {
|
||||
state,
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
selectIsOpen: false,
|
||||
generatingCodes: false,
|
||||
codes: undefined,
|
||||
value: null,
|
||||
model: {},
|
||||
searchCollections: [],
|
||||
error: null,
|
||||
isSelectOpen: false,
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
collections() {
|
||||
return this.state.collections.filter((collection) => {
|
||||
return typeof collection.resources.find((resource) => resource && resource.id === '' + this.id && resource.type === this.type) !== 'undefined'
|
||||
})
|
||||
},
|
||||
|
||||
placeholder() {
|
||||
return this.isSelectOpen ? t('core', 'Type to search for existing projects') : t('core', 'Add to a project')
|
||||
},
|
||||
|
||||
options() {
|
||||
const options = []
|
||||
window.OCP.Collaboration.getTypes().sort().forEach((type) => {
|
||||
options.push({
|
||||
method: METHOD_CREATE_COLLECTION,
|
||||
type,
|
||||
title: window.OCP.Collaboration.getLabel(type),
|
||||
class: window.OCP.Collaboration.getIcon(type),
|
||||
action: () => window.OCP.Collaboration.trigger(type),
|
||||
})
|
||||
})
|
||||
for (const index in this.searchCollections) {
|
||||
if (this.collections.findIndex((collection) => collection.id === this.searchCollections[index].id) === -1) {
|
||||
options.push({
|
||||
method: METHOD_ADD_TO_COLLECTION,
|
||||
title: this.searchCollections[index].name,
|
||||
collectionId: this.searchCollections[index].id,
|
||||
})
|
||||
}
|
||||
}
|
||||
return options
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
type() {
|
||||
if (this.isActive) {
|
||||
actions.fetchCollectionsByResource({
|
||||
resourceType: this.type,
|
||||
resourceId: this.id,
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
id() {
|
||||
if (this.isActive) {
|
||||
actions.fetchCollectionsByResource({
|
||||
resourceType: this.type,
|
||||
resourceId: this.id,
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
isActive(isActive) {
|
||||
if (isActive) {
|
||||
actions.fetchCollectionsByResource({
|
||||
resourceType: this.type,
|
||||
resourceId: this.id,
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
actions.fetchCollectionsByResource({
|
||||
resourceType: this.type,
|
||||
resourceId: this.id,
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
t,
|
||||
|
||||
select(selectedOption, id) {
|
||||
if (selectedOption.method === METHOD_CREATE_COLLECTION) {
|
||||
selectedOption.action().then((id) => {
|
||||
actions.createCollection({
|
||||
baseResourceType: this.type,
|
||||
baseResourceId: this.id,
|
||||
resourceType: selectedOption.type,
|
||||
resourceId: id,
|
||||
name: this.name,
|
||||
}).catch((e) => {
|
||||
this.setError(t('core', 'Failed to create a project'), e)
|
||||
})
|
||||
}).catch((e) => {
|
||||
console.error('No resource selected', e)
|
||||
})
|
||||
}
|
||||
|
||||
if (selectedOption.method === METHOD_ADD_TO_COLLECTION) {
|
||||
actions.addResourceToCollection({
|
||||
collectionId: selectedOption.collectionId, resourceType: this.type, resourceId: this.id,
|
||||
}).catch((e) => {
|
||||
this.setError(t('core', 'Failed to add the item to the project'), e)
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
search(query, loading) {
|
||||
_debouncedSearch.bind(this)(query, loading)
|
||||
},
|
||||
|
||||
showSelect() {
|
||||
this.selectIsOpen = true
|
||||
this.$refs.select.$el.focus()
|
||||
},
|
||||
|
||||
hideSelect() {
|
||||
this.selectIsOpen = false
|
||||
},
|
||||
|
||||
isVueComponent(object) {
|
||||
return object._isVue
|
||||
},
|
||||
|
||||
setError(error, e) {
|
||||
console.error(error, e)
|
||||
this.error = error
|
||||
setTimeout(() => {
|
||||
this.error = null
|
||||
}, 5000)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.collection-list * {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.collection-list > li {
|
||||
display: flex;
|
||||
align-items: start;
|
||||
gap: 12px;
|
||||
|
||||
& > .avatar {
|
||||
margin-top: auto;
|
||||
}
|
||||
}
|
||||
|
||||
#collection-select-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.v-select {
|
||||
// NcAvatar in the dropdown
|
||||
span.avatar {
|
||||
display: block;
|
||||
padding: 16px;
|
||||
opacity: .7;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p.hint {
|
||||
z-index: 1;
|
||||
// fix alignment
|
||||
margin-top: -16px;
|
||||
padding: 8px 8px;
|
||||
color: var(--color-text-maxcontrast);
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
div.avatar {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin: 0;
|
||||
padding: 8px;
|
||||
background-color: var(--color-background-dark);
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
/** TODO provide white icon in core */
|
||||
.icon-projects {
|
||||
display: block;
|
||||
padding: 8px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.option__wrapper {
|
||||
display: flex;
|
||||
|
||||
.avatar {
|
||||
display: block;
|
||||
background-color: var(--color-background-darker) !important;
|
||||
}
|
||||
|
||||
.option__title {
|
||||
padding: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.fade-enter-active, .fade-leave-active {
|
||||
transition: opacity .5s;
|
||||
}
|
||||
|
||||
.fade-enter, .fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,313 @@
|
|||
<!--
|
||||
- SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
|
||||
- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-->
|
||||
|
||||
<template>
|
||||
<li class="collection-list-item">
|
||||
<NcAvatar :display-name="collection.name" allow-placeholder class="collection-avatar" />
|
||||
<span v-if="newName === null"
|
||||
class="collection-item-name"
|
||||
title=""
|
||||
@click="showDetails">{{ collection.name }}</span>
|
||||
<form v-else :class="{'shouldshake': error.rename }" @submit.prevent="renameCollection">
|
||||
<input v-model="newName"
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
autocapitalize="off">
|
||||
<input type="submit" value="" class="icon-confirm">
|
||||
</form>
|
||||
<div v-if="!detailsOpen && newName === null" class="linked-icons">
|
||||
<a v-for="resource in limitedResources(collection)"
|
||||
:key="resource.type + '|' + resource.id"
|
||||
:title="resource.name"
|
||||
:href="resource.link"
|
||||
:class="typeClass(resource)"><img :src="iconUrl(resource)"></a>
|
||||
</div>
|
||||
|
||||
<span v-if="newName === null" class="sharingOptionsGroup">
|
||||
<NcActions>
|
||||
<NcActionButton icon="icon-info"
|
||||
@click.prevent="toggleDetails">
|
||||
{{ detailsOpen ? t('core', 'Hide details') : t('core', 'Show details') }}
|
||||
</NcActionButton>
|
||||
<NcActionButton icon="icon-rename"
|
||||
@click.prevent="openRename">
|
||||
{{ t('core', 'Rename project') }}
|
||||
</NcActionButton>
|
||||
</NcActions>
|
||||
</span>
|
||||
|
||||
<transition name="fade">
|
||||
<div v-if="error.rename" class="error">
|
||||
{{ error.rename }}
|
||||
</div>
|
||||
</transition>
|
||||
<transition name="fade">
|
||||
<ul v-if="detailsOpen" class="resource-list-details">
|
||||
<li v-for="resource in collection.resources"
|
||||
:key="resource.type + '|' + resource.id"
|
||||
:class="typeClass(resource)">
|
||||
<a :href="resource.link"><img :src="iconUrl(resource)"><span class="resource-name">{{ resource.name || '' }}</span></a>
|
||||
<span class="icon-close" @click="removeResource(collection, resource)" />
|
||||
</li>
|
||||
</ul>
|
||||
</transition>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { set } from 'vue'
|
||||
import { t } from '@nextcloud/l10n'
|
||||
|
||||
import NcActions from '../NcActions/index.js'
|
||||
import NcActionButton from '../NcActionButton/index.js'
|
||||
import NcAvatar from '../NcAvatar/index.js'
|
||||
|
||||
import { actions } from './collectionstore.js'
|
||||
|
||||
export default {
|
||||
name: 'NcCollectionListItem',
|
||||
|
||||
components: {
|
||||
NcAvatar,
|
||||
NcActions,
|
||||
NcActionButton,
|
||||
},
|
||||
|
||||
props: {
|
||||
collection: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
detailsOpen: false,
|
||||
newName: null,
|
||||
error: {},
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
getIcon() {
|
||||
return (resource) => [resource.iconClass]
|
||||
},
|
||||
|
||||
typeClass() {
|
||||
return (resource) => 'resource-type-' + resource.type
|
||||
},
|
||||
|
||||
limitedResources() {
|
||||
return (collection) => collection.resources ? collection.resources.slice(0, 2) : []
|
||||
},
|
||||
|
||||
iconUrl() {
|
||||
return (resource) => {
|
||||
if (resource.mimetype) {
|
||||
return OC.MimeType.getIconUrl(resource.mimetype)
|
||||
}
|
||||
if (resource.iconUrl) {
|
||||
return resource.iconUrl
|
||||
}
|
||||
return ''
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
t,
|
||||
|
||||
toggleDetails() {
|
||||
this.detailsOpen = !this.detailsOpen
|
||||
},
|
||||
|
||||
showDetails() {
|
||||
this.detailsOpen = true
|
||||
},
|
||||
|
||||
hideDetails() {
|
||||
this.detailsOpen = false
|
||||
},
|
||||
|
||||
removeResource(collection, resource) {
|
||||
actions.removeResource({
|
||||
collectionId: collection.id, resourceType: resource.type, resourceId: resource.id,
|
||||
})
|
||||
},
|
||||
|
||||
openRename() {
|
||||
this.newName = this.collection.name
|
||||
},
|
||||
|
||||
renameCollection() {
|
||||
if (this.newName === '') {
|
||||
this.newName = null
|
||||
return
|
||||
}
|
||||
actions.renameCollection({
|
||||
collectionId: this.collection.id,
|
||||
name: this.newName,
|
||||
}).then((collection) => {
|
||||
this.newName = null
|
||||
}).catch((e) => {
|
||||
this.$set(this.error, 'rename', t('core', 'Failed to rename the project'))
|
||||
console.error(e)
|
||||
setTimeout(() => {
|
||||
set(this.error, 'rename', null)
|
||||
}, 3000)
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.fade-enter-active, .fade-leave-active {
|
||||
transition: opacity .3s ease;
|
||||
}
|
||||
|
||||
.fade-enter, .fade-leave-to
|
||||
/* .fade-leave-active below version 2.1.8 */
|
||||
{
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.linked-icons {
|
||||
display: flex;
|
||||
|
||||
img {
|
||||
padding: 12px;
|
||||
height: 44px;
|
||||
display: block;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
opacity: 0.7;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.popovermenu {
|
||||
display: none;
|
||||
|
||||
&.open {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
li.collection-list-item {
|
||||
flex-wrap: wrap;
|
||||
height: auto;
|
||||
cursor: pointer;
|
||||
margin-bottom: 0 !important;
|
||||
|
||||
.collection-avatar {
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
form, .collection-item-name {
|
||||
flex-basis: 10%;
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.collection-item-name {
|
||||
padding: 12px 9px;
|
||||
}
|
||||
|
||||
input {
|
||||
margin-top: 4px;
|
||||
border-color: var(--color-border-maxcontrast);
|
||||
|
||||
&[type=text] {
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.error {
|
||||
flex-basis: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.resource-list-details {
|
||||
flex-basis: 100%;
|
||||
width: 100%;
|
||||
|
||||
li {
|
||||
display: flex;
|
||||
margin-left: 44px;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-background-dark);
|
||||
}
|
||||
|
||||
a {
|
||||
flex-grow: 1;
|
||||
padding: 3px;
|
||||
max-width: calc(100% - 30px);
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
span.resource-name {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
vertical-align: top;
|
||||
white-space: nowrap;
|
||||
flex-grow: 1;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.icon-close {
|
||||
opacity: .7;
|
||||
|
||||
&:hover, &:focus {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.shouldshake {
|
||||
animation: shake 0.6s 1 linear;
|
||||
}
|
||||
|
||||
@keyframes shake {
|
||||
0% {
|
||||
transform: translate(15px);
|
||||
}
|
||||
20% {
|
||||
transform: translate(-15px);
|
||||
}
|
||||
40% {
|
||||
transform: translate(7px);
|
||||
}
|
||||
60% {
|
||||
transform: translate(-7px);
|
||||
}
|
||||
80% {
|
||||
transform: translate(3px);
|
||||
}
|
||||
100% {
|
||||
transform: translate(0px);
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import axios from '@nextcloud/axios'
|
||||
import { generateOcsUrl } from '@nextcloud/router'
|
||||
|
||||
class CollectionService {
|
||||
|
||||
constructor() {
|
||||
this.http = axios
|
||||
}
|
||||
|
||||
listCollection(collectionId) {
|
||||
return this.http.get(generateOcsUrl('collaboration/resources/collections/{collectionId}', { collectionId }))
|
||||
}
|
||||
|
||||
renameCollection(collectionId, collectionName) {
|
||||
return this.http.put(generateOcsUrl('collaboration/resources/collections/{collectionId}', { collectionId }), {
|
||||
collectionName,
|
||||
}).then(result => {
|
||||
return result.data.ocs.data
|
||||
})
|
||||
}
|
||||
|
||||
getCollectionsByResource(resourceType, resourceId) {
|
||||
return this.http.get(generateOcsUrl('collaboration/resources/{resourceType}/{resourceId}', { resourceType, resourceId }))
|
||||
.then(result => {
|
||||
return result.data.ocs.data
|
||||
})
|
||||
}
|
||||
|
||||
createCollection(resourceType, resourceId, name) {
|
||||
return this.http.post(generateOcsUrl('collaboration/resources/{resourceType}/{resourceId}', { resourceType, resourceId }), {
|
||||
name,
|
||||
})
|
||||
.then((response) => {
|
||||
return response.data.ocs.data
|
||||
})
|
||||
}
|
||||
|
||||
addResource(collectionId, resourceType, resourceId) {
|
||||
resourceId = '' + resourceId
|
||||
return this.http.post(generateOcsUrl('collaboration/resources/collections/{collectionId}', { collectionId }), {
|
||||
resourceType,
|
||||
resourceId,
|
||||
}).then((response) => {
|
||||
return response.data.ocs.data
|
||||
})
|
||||
}
|
||||
|
||||
removeResource(collectionId, resourceType, resourceId) {
|
||||
return this.http.delete(generateOcsUrl('collaboration/resources/collections/{collectionId}', { collectionId }), { params: { resourceType, resourceId } })
|
||||
.then((response) => {
|
||||
return response.data.ocs.data
|
||||
})
|
||||
}
|
||||
|
||||
search(query) {
|
||||
return this.http.get(generateOcsUrl('collaboration/resources/collections/search/{query}', { query }))
|
||||
.then((response) => {
|
||||
return response.data.ocs.data
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const service = new CollectionService()
|
||||
|
||||
export default service
|
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { reactive, set } from 'vue'
|
||||
import service from './collectionservice.js'
|
||||
|
||||
const state = reactive({
|
||||
collections: [],
|
||||
})
|
||||
|
||||
const mutations = {
|
||||
addCollections(collections) {
|
||||
set(state, 'collections', collections)
|
||||
},
|
||||
addCollection(collection) {
|
||||
state.collections.push(collection)
|
||||
},
|
||||
removeCollection(collectionId) {
|
||||
set(state, 'collections', state.collections.filter(item => item.id !== collectionId))
|
||||
},
|
||||
updateCollection(collection) {
|
||||
const index = state.collections.findIndex((_item) => _item.id === collection.id)
|
||||
if (index !== -1) {
|
||||
set(state.collections, index, collection)
|
||||
} else {
|
||||
state.collections.push(collection)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
const actions = {
|
||||
fetchCollectionsByResource({ resourceType, resourceId }) {
|
||||
return service.getCollectionsByResource(resourceType, resourceId).then((collections) => {
|
||||
mutations.addCollections(collections)
|
||||
return collections
|
||||
})
|
||||
},
|
||||
createCollection({ baseResourceType, baseResourceId, resourceType, resourceId, name }) {
|
||||
return service.createCollection(baseResourceType, baseResourceId, name).then((collection) => {
|
||||
mutations.addCollection(collection)
|
||||
actions.addResourceToCollection({
|
||||
collectionId: collection.id,
|
||||
resourceType,
|
||||
resourceId,
|
||||
})
|
||||
})
|
||||
},
|
||||
renameCollection({ collectionId, name }) {
|
||||
return service.renameCollection(collectionId, name).then((collection) => {
|
||||
mutations.updateCollection(collection)
|
||||
return collection
|
||||
})
|
||||
},
|
||||
addResourceToCollection({ collectionId, resourceType, resourceId }) {
|
||||
return service.addResource(collectionId, resourceType, resourceId).then((collection) => {
|
||||
mutations.updateCollection(collection)
|
||||
return collection
|
||||
})
|
||||
},
|
||||
removeResource({ collectionId, resourceType, resourceId }) {
|
||||
return service.removeResource(collectionId, resourceType, resourceId).then((collection) => {
|
||||
if (collection.resources.length > 0) {
|
||||
mutations.updateCollection(collection)
|
||||
} else {
|
||||
mutations.removeCollection(collection)
|
||||
}
|
||||
})
|
||||
},
|
||||
search(query) {
|
||||
return service.search(query)
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
const store = {
|
||||
actions,
|
||||
state,
|
||||
}
|
||||
export default store
|
||||
export { actions, state }
|
|
@ -0,0 +1,6 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
export { default as NcCollectionListItem } from './NcCollectionListItem.vue'
|
||||
export { default } from './NcCollectionList.vue'
|
|
@ -36,6 +36,7 @@ export { default as NcBreadcrumb } from './NcBreadcrumb/index.js'
|
|||
export { default as NcBreadcrumbs } from './NcBreadcrumbs/index.js'
|
||||
export { default as NcButton } from './NcButton/index.js'
|
||||
export { default as NcCheckboxRadioSwitch } from './NcCheckboxRadioSwitch/index.js'
|
||||
export { default as NcCollectionList, NcCollectionListItem } from './NcCollectionList/index.js'
|
||||
export { default as NcColorPicker } from './NcColorPicker/index.js'
|
||||
export { default as NcContent } from './NcContent/index.js'
|
||||
export { default as NcCounterBubble } from './NcCounterBubble/index.js'
|
||||
|
|
Загрузка…
Ссылка в новой задаче