@nextcloud/vue
Version:
Nextcloud vue components
557 lines (556 loc) • 18.8 kB
JavaScript
import '../assets/NcRelatedResourcesPanel-DYB-wrU0.css';
import axios from "@nextcloud/axios";
import { generateOcsUrl } from "@nextcloud/router";
import { r as register, z as t38, a as t, A as t41, B as t9 } from "./_l10n-DrTiip5c.mjs";
import { N as NcButton } from "./NcButton-Dc8V4Urj.mjs";
import { g as getRoute } from "./autolink-U5pBzLgI.mjs";
import { resolveComponent, createElementBlock, openBlock, createVNode, withCtx, createTextVNode, toDisplayString, createElementVNode, mergeProps, createCommentVNode, Fragment, renderList, createBlock } from "vue";
import { _ as _export_sfc } from "./_plugin-vue_export-helper-1tPrXgE0.mjs";
import { getCapabilities } from "@nextcloud/capabilities";
import { C as ChevronDown } from "./ChevronDown-FiGpp0KT.mjs";
import { C as ChevronUp } from "./ChevronUp-DPXFp1ss.mjs";
import { N as NcIconSvgWrapper } from "./NcIconSvgWrapper-BvLanNaW.mjs";
import { l as logger } from "./logger-D3RVzcfQ.mjs";
register(t38);
const _sfc_main$4 = {
name: "NcResource",
components: {
NcButton
},
/* eslint vue/require-prop-comment: warn -- TODO: Add a proper doc block about what this props do */
props: {
icon: {
type: String,
required: true
},
name: {
type: String,
required: true
},
url: {
type: String,
required: true
}
},
data() {
return {
labelTranslated: t('Open link to "{resourceName}"', { resourceName: this.name })
};
},
computed: {
route() {
return getRoute(this.$router, this.url);
}
},
methods: {
t
}
};
const _hoisted_1$4 = { class: "resource" };
const _hoisted_2$4 = { class: "resource__icon" };
const _hoisted_3$3 = ["src"];
function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
const _component_NcButton = resolveComponent("NcButton");
return openBlock(), createElementBlock("li", _hoisted_1$4, [
createVNode(_component_NcButton, {
class: "resource__button",
"aria-label": $data.labelTranslated,
to: $options.route,
href: $options.route ? null : $props.url,
variant: "tertiary"
}, {
icon: withCtx(() => [
createElementVNode("div", _hoisted_2$4, [
createElementVNode("img", { src: $props.icon }, null, 8, _hoisted_3$3)
])
]),
default: withCtx(() => [
createTextVNode(" " + toDisplayString($props.name), 1)
]),
_: 1
}, 8, ["aria-label", "to", "href"])
]);
}
const NcResource = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render$4], ["__scopeId", "data-v-8db55138"]]);
const _sfc_main$3 = {
name: "AccountGroupIcon",
emits: ["click"],
props: {
title: {
type: String
},
fillColor: {
type: String,
default: "currentColor"
},
size: {
type: Number,
default: 24
}
}
};
const _hoisted_1$3 = ["aria-hidden", "aria-label"];
const _hoisted_2$3 = ["fill", "width", "height"];
const _hoisted_3$2 = { d: "M12,5.5A3.5,3.5 0 0,1 15.5,9A3.5,3.5 0 0,1 12,12.5A3.5,3.5 0 0,1 8.5,9A3.5,3.5 0 0,1 12,5.5M5,8C5.56,8 6.08,8.15 6.53,8.42C6.38,9.85 6.8,11.27 7.66,12.38C7.16,13.34 6.16,14 5,14A3,3 0 0,1 2,11A3,3 0 0,1 5,8M19,8A3,3 0 0,1 22,11A3,3 0 0,1 19,14C17.84,14 16.84,13.34 16.34,12.38C17.2,11.27 17.62,9.85 17.47,8.42C17.92,8.15 18.44,8 19,8M5.5,18.25C5.5,16.18 8.41,14.5 12,14.5C15.59,14.5 18.5,16.18 18.5,18.25V20H5.5V18.25M0,20V18.5C0,17.11 1.89,15.94 4.45,15.6C3.86,16.28 3.5,17.22 3.5,18.25V20H0M24,20H20.5V18.25C20.5,17.22 20.14,16.28 19.55,15.6C22.11,15.94 24,17.11 24,18.5V20Z" };
const _hoisted_4$2 = { key: 0 };
function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
return openBlock(), createElementBlock("span", mergeProps(_ctx.$attrs, {
"aria-hidden": $props.title ? null : "true",
"aria-label": $props.title,
class: "material-design-icon account-group-icon",
role: "img",
onClick: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("click", $event))
}), [
(openBlock(), createElementBlock("svg", {
fill: $props.fillColor,
class: "material-design-icon__svg",
width: $props.size,
height: $props.size,
viewBox: "0 0 24 24"
}, [
createElementVNode("path", _hoisted_3$2, [
$props.title ? (openBlock(), createElementBlock("title", _hoisted_4$2, toDisplayString($props.title), 1)) : createCommentVNode("", true)
])
], 8, _hoisted_2$3))
], 16, _hoisted_1$3);
}
const AccountGroup = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$3]]);
const _sfc_main$2 = {
name: "OpenInNewIcon",
emits: ["click"],
props: {
title: {
type: String
},
fillColor: {
type: String,
default: "currentColor"
},
size: {
type: Number,
default: 24
}
}
};
const _hoisted_1$2 = ["aria-hidden", "aria-label"];
const _hoisted_2$2 = ["fill", "width", "height"];
const _hoisted_3$1 = { d: "M14,3V5H17.59L7.76,14.83L9.17,16.24L19,6.41V10H21V3M19,19H5V5H12V3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V12H19V19Z" };
const _hoisted_4$1 = { key: 0 };
function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
return openBlock(), createElementBlock("span", mergeProps(_ctx.$attrs, {
"aria-hidden": $props.title ? null : "true",
"aria-label": $props.title,
class: "material-design-icon open-in-new-icon",
role: "img",
onClick: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("click", $event))
}), [
(openBlock(), createElementBlock("svg", {
fill: $props.fillColor,
class: "material-design-icon__svg",
width: $props.size,
height: $props.size,
viewBox: "0 0 24 24"
}, [
createElementVNode("path", _hoisted_3$1, [
$props.title ? (openBlock(), createElementBlock("title", _hoisted_4$1, toDisplayString($props.title), 1)) : createCommentVNode("", true)
])
], 8, _hoisted_2$2))
], 16, _hoisted_1$2);
}
const OpenInNew = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render$2]]);
register(t41);
const teamResourceProviders = getCapabilities()?.circles?.teamResourceProviders ?? [];
const _sfc_main$1 = {
name: "NcTeamResources",
components: {
AccountGroup,
ChevronDown,
ChevronUp,
OpenInNew,
NcButton,
NcIconSvgWrapper
},
/* eslint vue/require-prop-comment: warn -- TODO: Add a proper doc block about what this props do */
props: {
providerId: {
type: String,
default: null
},
itemId: {
type: [String, Number],
default: null
}
},
data() {
return {
appEnabled: OC?.appswebroots?.circles !== void 0 && (OC.config.version.split(".")[0] ?? 0) >= 29,
loading: false,
teamResources: null,
teamOpen: []
};
},
computed: {
isVisible() {
return !this.loading && this.teamResources?.length > 0;
},
teamProviders() {
return (teamId) => {
const team = this.teamResources.find((t2) => t2.teamId === teamId);
return team.resources?.reduce((acc, resource) => {
if (resource.provider.id === this.providerId && resource.id === String(this.itemId)) {
return acc;
}
if (!acc[resource.provider.id]) {
acc[resource.provider.id] = resource.provider;
acc[resource.provider.id].resources = [];
}
if (resource.provider.id === this.providerId && resource.id === String(this.itemId)) {
return acc;
}
acc[resource.provider.id].resources.push(resource);
return acc;
}, {});
};
},
open() {
return (teamId) => {
return this.teamOpen.indexOf(teamId) !== -1;
};
}
},
watch: {
providerId() {
this.fetchTeamResources();
},
itemId() {
this.fetchTeamResources();
}
},
created() {
this.fetchTeamResources();
},
methods: {
t,
async fetchTeamResources() {
if (!teamResourceProviders.includes(this.providerId)) {
return;
}
try {
this.loading = true;
const response = await axios.get(generateOcsUrl(`/teams/resources/${this.providerId}/${this.itemId}`));
this.teamResources = response.data.ocs.data.teams;
this.teamOpen = [this.teamResources[0]?.teamId];
} catch (error) {
this.teamResources = null;
logger.error("[NcTeamResources] Failed to fetch resources", { error });
} finally {
this.loading = false;
}
},
toggleOpen(teamId, open) {
if (open) {
this.teamOpen.push(teamId);
} else {
this.teamOpen.splice(this.teamOpen.indexOf(teamId), 1);
}
}
}
};
const _hoisted_1$1 = {
key: 0,
class: "team-resources"
};
const _hoisted_2$1 = { class: "team-resources__header" };
const _hoisted_3 = ["open", "onToggle"];
const _hoisted_4 = { class: "related-team__header" };
const _hoisted_5 = { class: "related-team__name" };
const _hoisted_6 = { key: 0 };
const _hoisted_7 = ["href"];
const _hoisted_8 = {
key: 0,
class: "resource__icon"
};
const _hoisted_9 = {
key: 2,
class: "resource__icon"
};
const _hoisted_10 = ["src"];
const _hoisted_11 = { class: "resource__name" };
function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
const _component_AccountGroup = resolveComponent("AccountGroup");
const _component_OpenInNew = resolveComponent("OpenInNew");
const _component_NcButton = resolveComponent("NcButton");
const _component_ChevronUp = resolveComponent("ChevronUp");
const _component_ChevronDown = resolveComponent("ChevronDown");
const _component_NcIconSvgWrapper = resolveComponent("NcIconSvgWrapper");
return $data.appEnabled && $options.isVisible ? (openBlock(), createElementBlock("div", _hoisted_1$1, [
createElementVNode("h5", _hoisted_2$1, toDisplayString($options.t("Related team resources")), 1),
(openBlock(true), createElementBlock(Fragment, null, renderList($data.teamResources, (team) => {
return openBlock(), createElementBlock("details", {
key: team.teamId,
name: "Team resources",
class: "related-team",
open: $options.open(team.teamId),
onToggle: (event) => $options.toggleOpen(team.teamId, event.target.open)
}, [
createElementVNode("summary", _hoisted_4, [
createElementVNode("h5", _hoisted_5, [
createVNode(_component_AccountGroup, { size: 20 }),
createTextVNode(" " + toDisplayString(team.displayName), 1)
]),
createVNode(_component_NcButton, {
"aria-label": $options.t("View team"),
href: team.link,
title: $options.t("View team"),
variant: "tertiary"
}, {
icon: withCtx(() => [
createVNode(_component_OpenInNew, { size: 20 })
]),
_: 2
}, 1032, ["aria-label", "href", "title"]),
$options.open(team.teamId) ? (openBlock(), createBlock(_component_ChevronUp, {
key: 0,
size: 20
})) : (openBlock(), createBlock(_component_ChevronDown, {
key: 1,
size: 20
}))
]),
createElementVNode("div", null, [
(openBlock(true), createElementBlock(Fragment, null, renderList($options.teamProviders(team.teamId), (provider) => {
return openBlock(), createElementBlock("div", {
key: provider.id,
class: "related-team-provider"
}, [
provider.resources.length > 0 ? (openBlock(), createElementBlock("h6", _hoisted_6, toDisplayString(provider.name), 1)) : createCommentVNode("", true),
createElementVNode("ul", null, [
(openBlock(true), createElementBlock(Fragment, null, renderList(provider.resources, (resource) => {
return openBlock(), createElementBlock("li", {
key: resource.url,
class: "related-team-resource"
}, [
createElementVNode("a", {
href: resource.url,
class: "related-team-resource__link"
}, [
resource.iconEmoji ? (openBlock(), createElementBlock("span", _hoisted_8, toDisplayString(resource.iconEmoji), 1)) : resource.iconSvg ? (openBlock(), createBlock(_component_NcIconSvgWrapper, {
key: 1,
class: "resource__icon",
svg: resource.iconSvg,
size: 20
}, null, 8, ["svg"])) : resource.iconURL ? (openBlock(), createElementBlock("span", _hoisted_9, [
createElementVNode("img", {
src: resource.iconURL,
alt: ""
}, null, 8, _hoisted_10)
])) : createCommentVNode("", true),
createElementVNode("span", _hoisted_11, toDisplayString(resource.label), 1)
], 8, _hoisted_7)
]);
}), 128))
])
]);
}), 128))
])
], 40, _hoisted_3);
}), 128))
])) : createCommentVNode("", true);
}
const NcTeamResources = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render$1], ["__scopeId", "data-v-a0203ee5"]]);
register(t9);
const _sfc_main = {
name: "NcRelatedResourcesPanel",
components: {
NcResource,
NcTeamResources
},
/* eslint vue/require-prop-comment: warn -- TODO: Add a proper doc block about what this props do */
props: {
/**
* The provider id implemented with `\OCA\RelatedResources\IRelatedResourceProvider::getProviderId()`
*/
providerId: {
type: String,
default: null
},
/**
* The item id which uniquely identities the e.g. Calendar event, Deck board, file, Talk room, etc.
*/
itemId: {
type: [String, Number],
default: null
},
/**
* Limits to specific resource type. i.e. any provider id implemented with `\OCA\RelatedResources\IRelatedResourceProvider::getProviderId()`
*/
resourceType: {
type: String,
default: ""
},
/**
* Set the maximum number of resources to load
*/
limit: {
type: Number,
default: 0
},
/**
* Only used by the files sidebar
*
* File info is passed when registered with `OCA.Sharing.ShareTabSections.registerSection()`
*/
fileInfo: {
type: Object,
default: null
},
/**
* Make the header name dynamic
*/
header: {
type: String,
default: t("Related resources")
},
description: {
type: String,
default: t("Anything shared with the same group of people will show up here")
},
/**
* If this element is used on a primary element set to true for primary styling.
*/
primary: {
type: Boolean,
default: false
}
},
emits: [
"hasError",
"hasResources"
],
data() {
return {
appEnabled: OC?.appswebroots?.related_resources !== void 0,
loading: false,
error: null,
resources: []
};
},
computed: {
isVisible() {
if (this.loading) {
return false;
}
return this.error ?? this.resources.length > 0;
},
subline() {
if (this.error) {
return t("Error getting related resources. Please contact your system administrator if you have any questions.");
}
return this.description;
},
hasResourceInfo() {
if (this.providerId !== null && this.itemId !== null) {
return true;
}
if (this.fileInfo !== null) {
return true;
}
return false;
},
isFiles() {
return this.fileInfo?.id !== void 0;
},
url() {
let providerId = null;
let itemId = null;
if (this.isFiles) {
providerId = "files";
itemId = this.fileInfo.id;
} else {
providerId = this.providerId;
itemId = this.itemId;
}
return generateOcsUrl("/apps/related_resources/related/{providerId}?itemId={itemId}&resourceType={resourceType}&limit={limit}&format=json", {
providerId,
itemId,
resourceType: this.resourceType,
limit: this.limit
});
}
},
watch: {
providerId() {
this.fetchRelatedResources();
},
itemId() {
this.fetchRelatedResources();
},
fileInfo() {
this.fetchRelatedResources();
},
error(error) {
this.$emit("hasError", Boolean(error));
},
resources(resources) {
this.$emit("hasResources", resources.length > 0);
}
},
created() {
this.fetchRelatedResources();
},
methods: {
t,
async fetchRelatedResources() {
if (!this.appEnabled || !this.hasResourceInfo) {
return;
}
this.loading = true;
this.error = null;
this.resources = [];
try {
const response = await axios.get(this.url);
this.resources = response.data.ocs?.data;
} catch (error) {
this.error = error;
logger.error("[NcRelatedResourcesPanel] Failed to fetch resources", { error });
} finally {
this.loading = false;
}
}
}
};
const _hoisted_1 = {
key: 0,
class: "related-resources"
};
const _hoisted_2 = { class: "related-resources__header" };
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_NcTeamResources = resolveComponent("NcTeamResources");
const _component_NcResource = resolveComponent("NcResource");
return openBlock(), createElementBlock("div", null, [
createVNode(_component_NcTeamResources, {
"provider-id": $props.providerId,
"item-id": $props.itemId
}, null, 8, ["provider-id", "item-id"]),
$data.appEnabled && $options.isVisible ? (openBlock(), createElementBlock("div", _hoisted_1, [
createElementVNode("div", _hoisted_2, [
createElementVNode("h5", null, toDisplayString($props.header), 1),
createElementVNode("p", null, toDisplayString($options.subline), 1)
]),
(openBlock(true), createElementBlock(Fragment, null, renderList($data.resources, (resource) => {
return openBlock(), createBlock(_component_NcResource, {
key: resource.itemId,
class: "related-resources__entry",
icon: resource.icon,
name: resource.title,
url: resource.url
}, null, 8, ["icon", "name", "url"]);
}), 128))
])) : createCommentVNode("", true)
]);
}
const NcRelatedResourcesPanel = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-551fe92c"]]);
export {
NcRelatedResourcesPanel as N
};
//# sourceMappingURL=NcRelatedResourcesPanel-BVGAmIja.mjs.map