UNPKG

@nextcloud/vue

Version:
280 lines (279 loc) 8.05 kB
import NcEllipsisedOption from "../Components/NcEllipsisedOption.mjs"; import { N as NcSelect } from "./NcSelect-DRRPiPZG.mjs"; import axios from "@nextcloud/axios"; import { generateRemoteUrl } from "@nextcloud/router"; import { r as register, h as t0, a as t } from "./_l10n-JYjUKekn.mjs"; import { n as normalizeComponent } from "./_plugin-vue2_normalizer-DU4iP6Vu.mjs"; const xmlToJson = (xml) => { let obj = {}; if (xml.nodeType === 1) { if (xml.attributes.length > 0) { obj["@attributes"] = {}; for (let j = 0; j < xml.attributes.length; j++) { const attribute = xml.attributes.item(j); obj["@attributes"][attribute.nodeName] = attribute.nodeValue; } } } else if (xml.nodeType === 3) { obj = xml.nodeValue; } if (xml.hasChildNodes()) { for (let i = 0; i < xml.childNodes.length; i++) { const item = xml.childNodes.item(i); const nodeName = item.nodeName; if (typeof obj[nodeName] === "undefined") { obj[nodeName] = xmlToJson(item); } else { if (typeof obj[nodeName].push === "undefined") { const old = obj[nodeName]; obj[nodeName] = []; obj[nodeName].push(old); } obj[nodeName].push(xmlToJson(item)); } } } return obj; }; const parseXml = (xml) => { let dom = null; try { dom = new DOMParser().parseFromString(xml, "text/xml"); } catch (e) { console.error("Failed to parse xml document", e); } return dom; }; const xmlToTagList = (xml) => { const json = xmlToJson(parseXml(xml)); const list = json["d:multistatus"]["d:response"]; const result = []; for (const index in list) { const tag = list[index]["d:propstat"]; if (tag["d:status"]["#text"] !== "HTTP/1.1 200 OK") { continue; } result.push({ id: parseInt(tag["d:prop"]["oc:id"]["#text"]), displayName: tag["d:prop"]["oc:display-name"]["#text"], canAssign: tag["d:prop"]["oc:can-assign"]["#text"] === "true", userAssignable: tag["d:prop"]["oc:user-assignable"]["#text"] === "true", userVisible: tag["d:prop"]["oc:user-visible"]["#text"] === "true" }); } return result; }; const searchTags = async function() { if (window.NextcloudVueDocs) { return Promise.resolve(xmlToTagList(window.NextcloudVueDocs.tags)); } const result = await axios({ method: "PROPFIND", url: generateRemoteUrl("dav") + "/systemtags/", data: '<?xml version="1.0"?>\n <d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns">\n <d:prop>\n <oc:id />\n <oc:display-name />\n <oc:user-visible />\n <oc:user-assignable />\n <oc:can-assign />\n </d:prop>\n </d:propfind>' }); return xmlToTagList(result.data); }; register(t0); const _sfc_main = { name: "NcSelectTags", components: { NcEllipsisedOption, NcSelect }, props: { // Add NcSelect prop defaults and populate $props ...NcSelect.props, /** * Enable automatic fetching of tags * * If `false`, available tags must be passed using the `options` prop */ fetchTags: { type: Boolean, default: true }, /** * Callback to generate the label text * * @see https://vue-select.org/api/props.html#getoptionlabel */ getOptionLabel: { type: Function, default: (option) => { const { displayName, userVisible, userAssignable } = option; if (userVisible === false) { return t("{tag} (invisible)", { tag: displayName }); } if (userAssignable === false) { return t("{tag} (restricted)", { tag: displayName }); } return displayName; } }, /** * Sets the maximum number of tags to display in the dropdown list * * Because of compatibility reasons only 5 tag entries are shown by * default */ limit: { type: Number, default: 5 }, /** * Allow selection of multiple options * * This prop automatically sets the internal `closeOnSelect` prop to * its boolean opposite * * @see https://vue-select.org/api/props.html#multiple */ multiple: { type: Boolean, default: true }, /** * Callback to filter available options */ optionsFilter: { type: Function, default: null }, /** * Enable passing of `value` prop and emitted `input` events as-is * i.e. for usage with `v-model` * * If `true`, custom internal `value` and `input` handling is disabled */ passthru: { type: Boolean, default: false }, /** * Placeholder text * * @see https://vue-select.org/api/props.html#placeholder */ placeholder: { type: String, default: t("Select a tag") }, /** * Currently selected value */ value: { type: [Number, Array, Object], default: null }, /** * Any available prop * * @see https://vue-select.org/api/props.html */ // Not an actual prop but needed to show in vue-styleguidist docs // eslint-disable-next-line " ": {} }, emits: [ "input", /** * All events from https://vue-select.org/api/events.html */ // Not an actual event but needed to show in vue-styleguidist docs " " ], data() { return { search: "", availableTags: [] }; }, computed: { availableOptions() { if (this.optionsFilter) { return this.tags.filter(this.optionsFilter); } return this.tags; }, localValue() { if (this.tags.length === 0) { return []; } if (this.multiple) { return this.value.filter((tag) => tag !== "").map((id) => this.tags.find((tag2) => tag2.id === id)); } else { return this.tags.find((tag) => tag.id === this.value); } }, propsToForward() { const { // Props handled by this component fetchTags, optionsFilter, passthru, // Props to forward ...propsToForward } = this.$props; return propsToForward; }, tags() { if (!this.fetchTags) { return this.options; } return this.availableTags; } }, async created() { if (!this.fetchTags) { return; } try { const result = await searchTags(); this.availableTags = result; } catch (error) { console.error("Loading systemtags failed", error); } }, methods: { handleInput(value) { if (this.multiple) { this.$emit("input", value.map((element) => element.id)); } else { if (value === null) { this.$emit("input", null); } else { this.$emit("input", value.id); } } } } }; var _sfc_render = function render() { var _vm = this, _c = _vm._self._c; return _c("NcSelect", _vm._g(_vm._b({ attrs: { "options": _vm.availableOptions, "close-on-select": !_vm.multiple, "value": _vm.passthru ? _vm.value : _vm.localValue }, on: { "search": (searchString) => _vm.search = searchString }, scopedSlots: _vm._u([{ key: "option", fn: function(option) { return [_c("NcEllipsisedOption", { attrs: { "name": _vm.getOptionLabel(option), "search": _vm.search } })]; } }, { key: "selected-option", fn: function(selectedOption) { return [_c("NcEllipsisedOption", { attrs: { "name": _vm.getOptionLabel(selectedOption), "search": _vm.search } })]; } }, _vm._l(_vm.$scopedSlots, function(_, name) { return { key: name, fn: function(data) { return [_vm._t(name, null, null, data)]; } }; })], null, true) }, "NcSelect", _vm.propsToForward, false), { ..._vm.$listeners, input: _vm.passthru ? _vm.$listeners.input : _vm.handleInput })); }; var _sfc_staticRenderFns = []; var __component__ = /* @__PURE__ */ normalizeComponent( _sfc_main, _sfc_render, _sfc_staticRenderFns, false, null, null ); const NcSelectTags = __component__.exports; export { NcSelectTags as N };