@nextcloud/vue
Version:
Nextcloud vue components
595 lines (594 loc) • 21.3 kB
JavaScript
import '../assets/NcCollectionList-C7OiUQQ-.css';
import debounce from "debounce";
import { resolveComponent, createElementBlock, openBlock, createVNode, createCommentVNode, toDisplayString, withModifiers, normalizeClass, withDirectives, createElementVNode, vModelText, Fragment, renderList, createBlock, resolveDynamicComponent, withCtx, createTextVNode, Transition, ref } from "vue";
import { r as register, s as t28, a as t, u as t6 } from "./_l10n-DrTiip5c.mjs";
import { N as NcActionButton } from "./NcActionButton-pKOSrlGE.mjs";
import { N as NcActions } from "./NcActions-DWmvh7-Y.mjs";
import { N as NcAvatar } from "./NcAvatar-DmUGApWA.mjs";
import { g as getRoute } from "./autolink-U5pBzLgI.mjs";
import { _ as _export_sfc } from "./_plugin-vue_export-helper-1tPrXgE0.mjs";
import { l as logger } from "./logger-D3RVzcfQ.mjs";
import { N as NcSelect } from "./NcSelect-Czzsi3P_.mjs";
import axios from "@nextcloud/axios";
import { generateOcsUrl } from "@nextcloud/router";
register(t28);
const _sfc_main$1 = {
name: "NcCollectionListItem",
components: {
NcAvatar,
NcActions,
NcActionButton
},
props: {
/**
* The collection
*/
collection: {
type: Object,
default: null
},
/**
* Current error if any
*/
error: {
type: String,
default: void 0
}
},
emits: [
"removeResource",
"renameCollection"
],
data() {
return {
detailsOpen: false,
newName: null
};
},
computed: {
getIcon() {
return (resource) => [resource.iconClass];
},
typeClass() {
return (resource) => "resource-type-" + resource.type;
},
resources() {
return this.collection.resources?.filter((resource) => !Array.isArray(resource)) ?? [];
},
getComponent() {
return (resource) => {
const route = getRoute(this.$router, resource.link);
return route ? { component: "router-link", to: route, href: void 0 } : { component: "a", to: void 0, href: resource.link };
};
},
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;
},
removeResource(collection, resource) {
this.$emit("removeResource", {
collectionId: collection.id,
resourceType: resource.type,
resourceId: resource.id
});
},
openRename() {
this.newName = this.collection.name;
},
renameCollection() {
if (this.newName) {
this.$emit("renameCollection", {
collectionId: this.collection.id,
name: this.newName
});
}
this.newName = null;
}
}
};
const _hoisted_1$1 = { class: "collection-list-item" };
const _hoisted_2$1 = {
key: 2,
class: "linked-icons"
};
const _hoisted_3$1 = ["src", "alt"];
const _hoisted_4$1 = {
key: 3,
class: "sharingOptionsGroup"
};
const _hoisted_5$1 = {
key: 0,
class: "error"
};
const _hoisted_6$1 = {
key: 0,
class: "resource-list-details"
};
const _hoisted_7$1 = ["src", "alt"];
const _hoisted_8$1 = { class: "resource-name" };
const _hoisted_9 = ["onClick"];
function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
const _component_NcAvatar = resolveComponent("NcAvatar");
const _component_NcActionButton = resolveComponent("NcActionButton");
const _component_NcActions = resolveComponent("NcActions");
return openBlock(), createElementBlock("li", _hoisted_1$1, [
createVNode(_component_NcAvatar, {
"display-name": $props.collection.name,
"allow-placeholder": "",
class: "collection-avatar"
}, null, 8, ["display-name"]),
$data.newName === null ? (openBlock(), createElementBlock("span", {
key: 0,
class: "collection-item-name",
title: "",
onClick: _cache[0] || (_cache[0] = (...args) => $options.showDetails && $options.showDetails(...args))
}, toDisplayString($props.collection.name), 1)) : (openBlock(), createElementBlock("form", {
key: 1,
class: normalizeClass({ "should-shake": $props.error }),
onSubmit: _cache[2] || (_cache[2] = withModifiers((...args) => $options.renameCollection && $options.renameCollection(...args), ["prevent"]))
}, [
withDirectives(createElementVNode("input", {
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => $data.newName = $event),
type: "text",
autocomplete: "off",
autocapitalize: "off"
}, null, 512), [
[vModelText, $data.newName]
]),
_cache[3] || (_cache[3] = createElementVNode("input", {
type: "submit",
value: "",
class: "icon-confirm"
}, null, -1))
], 34)),
!$data.detailsOpen && $data.newName === null ? (openBlock(), createElementBlock("div", _hoisted_2$1, [
(openBlock(true), createElementBlock(Fragment, null, renderList($options.resources.slice(0, 2), (resource) => {
return openBlock(), createBlock(resolveDynamicComponent($options.getComponent(resource).component), {
key: resource.type + "|" + resource.id,
title: resource.name,
to: $options.getComponent(resource).to,
href: $options.getComponent(resource).href,
class: normalizeClass($options.typeClass(resource))
}, {
default: withCtx(() => [
createElementVNode("img", {
src: $options.iconUrl(resource),
alt: resource.name
}, null, 8, _hoisted_3$1)
]),
_: 2
}, 1032, ["title", "to", "href", "class"]);
}), 128))
])) : createCommentVNode("", true),
$data.newName === null ? (openBlock(), createElementBlock("span", _hoisted_4$1, [
createVNode(_component_NcActions, null, {
default: withCtx(() => [
createVNode(_component_NcActionButton, {
icon: "icon-info",
onClick: withModifiers($options.toggleDetails, ["prevent"])
}, {
default: withCtx(() => [
createTextVNode(toDisplayString($data.detailsOpen ? $options.t("Hide details") : $options.t("Show details")), 1)
]),
_: 1
}, 8, ["onClick"]),
createVNode(_component_NcActionButton, {
icon: "icon-rename",
onClick: withModifiers($options.openRename, ["prevent"])
}, {
default: withCtx(() => [
createTextVNode(toDisplayString($options.t("Rename project")), 1)
]),
_: 1
}, 8, ["onClick"])
]),
_: 1
})
])) : createCommentVNode("", true),
createVNode(Transition, { name: "fade" }, {
default: withCtx(() => [
$props.error ? (openBlock(), createElementBlock("div", _hoisted_5$1, toDisplayString($props.error), 1)) : createCommentVNode("", true)
]),
_: 1
}),
createVNode(Transition, { name: "fade" }, {
default: withCtx(() => [
$data.detailsOpen ? (openBlock(), createElementBlock("ul", _hoisted_6$1, [
(openBlock(true), createElementBlock(Fragment, null, renderList($options.resources, (resource) => {
return openBlock(), createElementBlock("li", {
key: resource.type + "|" + resource.id,
class: normalizeClass($options.typeClass(resource))
}, [
(openBlock(), createBlock(resolveDynamicComponent($options.getComponent(resource).component), {
to: $options.getComponent(resource).to,
href: $options.getComponent(resource).href
}, {
default: withCtx(() => [
createElementVNode("img", {
src: $options.iconUrl(resource),
alt: resource.name
}, null, 8, _hoisted_7$1),
createElementVNode("span", _hoisted_8$1, toDisplayString(resource.name || ""), 1)
]),
_: 2
}, 1032, ["to", "href"])),
createElementVNode("span", {
class: "icon-close",
onClick: ($event) => $options.removeResource($props.collection, resource)
}, null, 8, _hoisted_9)
], 2);
}), 128))
])) : createCommentVNode("", true)
]),
_: 1
})
]);
}
const NcCollectionListItem = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render$1], ["__scopeId", "data-v-52d18b4a"]]);
register(t6);
function extractOcsData(response) {
return response.data.ocs.data;
}
function renameCollectionService(collectionId, collectionName) {
return axios.put(generateOcsUrl("collaboration/resources/collections/{collectionId}", { collectionId }), { collectionName }).then(extractOcsData);
}
function getCollectionsByResourceService(resourceType, resourceId) {
return axios.get(generateOcsUrl("collaboration/resources/{resourceType}/{resourceId}", { resourceType, resourceId })).then(extractOcsData);
}
function createCollectionService(resourceType, resourceId, name) {
return axios.post(generateOcsUrl("collaboration/resources/{resourceType}/{resourceId}", { resourceType, resourceId }), { name }).then(extractOcsData);
}
function addResourceService(collectionId, resourceType, resourceId) {
return axios.post(generateOcsUrl("collaboration/resources/collections/{collectionId}", { collectionId }), { resourceType, resourceId }).then(extractOcsData);
}
function removeResourceService(collectionId, resourceType, resourceId) {
return axios.delete(generateOcsUrl("collaboration/resources/collections/{collectionId}", { collectionId }), { params: { resourceType, resourceId } }).then(extractOcsData);
}
function searchService(query) {
return axios.get(generateOcsUrl("collaboration/resources/collections/search/{query}", { query })).then(extractOcsData);
}
function useCollections() {
const storedCollections = ref([]);
const addCollections = (collections) => {
storedCollections.value = collections;
};
const addCollection = (collection) => {
storedCollections.value.push(collection);
};
const removeCollection = (collectionId) => {
storedCollections.value = storedCollections.value.filter((item) => item.id !== collectionId);
};
const updateCollection = (collection) => {
const index = storedCollections.value.findIndex((item) => item.id === collection.id);
if (index !== -1) {
storedCollections.value[index] = collection;
} else {
addCollection(collection);
}
};
const fetchCollectionsByResource = async ({ resourceType, resourceId }) => {
const collections = await getCollectionsByResourceService(resourceType, resourceId);
addCollections(collections);
};
const createCollection = async ({ baseResourceType, baseResourceId, resourceType, resourceId, name }) => {
const collection = await createCollectionService(baseResourceType, baseResourceId, name);
addCollection(collection);
await addResourceToCollection({
collectionId: collection.id,
resourceType,
resourceId
});
};
const renameCollection = async ({ collectionId, name }) => {
const collection = await renameCollectionService(collectionId, name);
updateCollection(collection);
};
async function addResourceToCollection({ collectionId, resourceType, resourceId }) {
const collection = await addResourceService(collectionId, resourceType, String(resourceId));
updateCollection(collection);
}
const removeResourceFromCollection = async ({ collectionId, resourceType, resourceId }) => {
const collection = await removeResourceService(collectionId, resourceType, String(resourceId));
if (collection.resources.length > 0) {
updateCollection(collection);
} else {
removeCollection(collectionId);
}
};
return {
storedCollections,
fetchCollectionsByResource,
createCollection,
renameCollection,
addResourceToCollection,
removeResourceFromCollection
};
}
const METHOD_CREATE_COLLECTION = 0;
const METHOD_ADD_TO_COLLECTION = 1;
const _sfc_main = {
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: ""
},
/**
* Whether the component is active (to start fetch resources)
*/
isActive: {
type: Boolean,
default: true
}
},
setup() {
const {
storedCollections,
fetchCollectionsByResource,
createCollection,
addResourceToCollection,
removeResourceFromCollection,
renameCollection
} = useCollections();
const searchCollections = ref([]);
const search = debounce(function(query, loading) {
if (query !== "") {
loading(true);
searchService(query).then((collections) => {
searchCollections.value = collections;
}).catch((error) => {
logger.error("Failed to search for collections", { error });
}).finally(() => {
loading(false);
});
}
}, 500);
return {
storedCollections,
fetchCollectionsByResource,
createCollection,
addResourceToCollection,
removeResourceFromCollection,
renameCollection,
searchCollections,
search
};
},
data() {
return {
selectIsOpen: false,
generatingCodes: false,
codes: void 0,
value: null,
model: {},
collectionsError: {},
error: null,
isSelectOpen: false
};
},
computed: {
collections() {
return this.storedCollections.filter((collection) => collection.resources.some((resource) => resource && resource.id === String(this.id) && resource.type === this.type));
},
placeholder() {
return this.isSelectOpen ? t("Type to search for existing projects") : t("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.find((collection) => collection.id === this.searchCollections[index].id)) {
options.push({
method: METHOD_ADD_TO_COLLECTION,
title: this.searchCollections[index].name,
collectionId: this.searchCollections[index].id
});
}
}
return options;
},
resourceIdentifier() {
return {
resourceType: this.type,
resourceId: this.id,
isActive: this.isActive
};
}
},
watch: {
resourceIdentifier: {
deep: true,
immediate: true,
handler(resourceIdentifier) {
if (!resourceIdentifier.isActive || !resourceIdentifier.resourceId || !resourceIdentifier.resourceType) {
return;
}
this.fetchCollectionsByResource(resourceIdentifier);
}
}
},
methods: {
t,
select(selectedOption) {
if (selectedOption.method === METHOD_CREATE_COLLECTION) {
selectedOption.action().then((resourceId) => {
this.createCollection({
baseResourceType: this.type,
baseResourceId: this.id,
resourceType: selectedOption.type,
resourceId,
name: this.name
}).catch((e) => {
this.setError(t("Failed to create a project"), e);
});
}).catch((e) => {
logger.error("[NcCollectionList] No resource selected", e);
});
}
if (selectedOption.method === METHOD_ADD_TO_COLLECTION) {
this.addResourceToCollection({
collectionId: selectedOption.collectionId,
resourceType: this.type,
resourceId: this.id
}).catch((e) => {
this.setError(t("Failed to add the item to the project"), e);
});
}
this.value = null;
},
showSelect() {
this.selectIsOpen = true;
this.$refs.select.$el.focus();
},
setError(error, e) {
logger.error(error, { error: e });
this.error = error;
setTimeout(() => {
this.error = null;
}, 5e3);
},
renameCollectionFromItem({ collectionId, name }) {
this.renameCollection({ collectionId, name }).catch((e) => {
logger.error(t("Failed to rename the project"), { error: e });
this.collectionsError[collectionId] = t("Failed to rename the project");
setTimeout(() => {
this.collectionsError[collectionId] = null;
}, 5e3);
});
}
}
};
const _hoisted_1 = {
key: 0,
id: "collection-list",
class: "collection-list"
};
const _hoisted_2 = { id: "collection-select-container" };
const _hoisted_3 = { class: "option__desc" };
const _hoisted_4 = { class: "option__title" };
const _hoisted_5 = { class: "option__wrapper" };
const _hoisted_6 = { class: "option__title" };
const _hoisted_7 = { class: "hint" };
const _hoisted_8 = {
key: 0,
class: "error"
};
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_NcAvatar = resolveComponent("NcAvatar");
const _component_NcSelect = resolveComponent("NcSelect");
const _component_NcCollectionListItem = resolveComponent("NcCollectionListItem");
return $options.collections && $props.type && $props.id ? (openBlock(), createElementBlock("ul", _hoisted_1, [
createElementVNode("li", {
onClick: _cache[3] || (_cache[3] = (...args) => $options.showSelect && $options.showSelect(...args))
}, [
_cache[4] || (_cache[4] = createElementVNode("div", { class: "avatar" }, [
createElementVNode("span", { class: "icon-projects" })
], -1)),
createElementVNode("div", _hoisted_2, [
createVNode(_component_NcSelect, {
ref: "select",
modelValue: $data.value,
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $data.value = $event),
"aria-label-combobox": $options.t("Add to a project"),
options: $options.options,
placeholder: $options.placeholder,
label: "title",
limit: 5,
onClose: _cache[1] || (_cache[1] = ($event) => $data.isSelectOpen = false),
onOpen: _cache[2] || (_cache[2] = ($event) => $data.isSelectOpen = true),
"onOption:selected": $options.select,
onSearch: $setup.search
}, {
"selected-option": withCtx((option) => [
createElementVNode("span", _hoisted_3, [
createElementVNode("span", _hoisted_4, toDisplayString(option.title), 1)
])
]),
option: withCtx((option) => [
createElementVNode("span", _hoisted_5, [
option.class ? (openBlock(), createElementBlock("span", {
key: 0,
class: normalizeClass([option.class, "avatar"])
}, null, 2)) : option.method !== 2 ? (openBlock(), createBlock(_component_NcAvatar, {
key: 1,
"allow-placeholder": "",
"display-name": option.title
}, null, 8, ["display-name"])) : createCommentVNode("", true),
createElementVNode("span", _hoisted_6, toDisplayString(option.title), 1)
])
]),
default: withCtx(() => [
createElementVNode("p", _hoisted_7, toDisplayString($options.t("Connect items to a project to make them easier to find")), 1)
]),
_: 1
}, 8, ["modelValue", "aria-label-combobox", "options", "placeholder", "onOption:selected", "onSearch"])
])
]),
createVNode(Transition, { name: "fade" }, {
default: withCtx(() => [
$data.error ? (openBlock(), createElementBlock("li", _hoisted_8, toDisplayString($data.error), 1)) : createCommentVNode("", true)
]),
_: 1
}),
(openBlock(true), createElementBlock(Fragment, null, renderList($options.collections, (collection) => {
return openBlock(), createBlock(_component_NcCollectionListItem, {
key: collection.id,
collection,
error: $data.collectionsError[collection.id],
onRenameCollection: $options.renameCollectionFromItem,
onRemoveResource: $setup.removeResourceFromCollection
}, null, 8, ["collection", "error", "onRenameCollection", "onRemoveResource"]);
}), 128))
])) : createCommentVNode("", true);
}
const NcCollectionList = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-047356d6"]]);
export {
NcCollectionList as N
};
//# sourceMappingURL=NcCollectionList-C-Zxsdgw.mjs.map