@conduction/nextcloud-vue 2.56.0-beta.48 → 2.56.0-beta.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +46 -28
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js +17 -10
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
- package/dist/esm/components/CnBrandBar/CnBrandBar.vue2.js.map +1 -1
- package/dist/esm/components/CnBrandBar/CnBrandBar.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +56 -16
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDeviceFramesWidget/CnDeviceFramesWidget.vue.js +9 -0
- package/dist/esm/components/CnDeviceFramesWidget/CnDeviceFramesWidget.vue.js.map +1 -0
- package/dist/esm/components/CnDeviceFramesWidget/CnDeviceFramesWidget.vue2.js +240 -0
- package/dist/esm/components/CnDeviceFramesWidget/CnDeviceFramesWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnDeviceFramesWidget/CnDeviceFramesWidget.vue3.js +65 -0
- package/dist/esm/components/CnDeviceFramesWidget/CnDeviceFramesWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnDeviceFramesWidget/index.js +30 -0
- package/dist/esm/components/CnDeviceFramesWidget/index.js.map +1 -0
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue.js +1 -1
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js +17 -1
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js +30 -31
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnHeaderSearchLabel/CnHeaderSearchLabel.vue.js +6 -0
- package/dist/esm/components/CnHeaderSearchLabel/CnHeaderSearchLabel.vue.js.map +1 -0
- package/dist/esm/components/CnHeaderSearchLabel/CnHeaderSearchLabel.vue2.js +90 -0
- package/dist/esm/components/CnHeaderSearchLabel/CnHeaderSearchLabel.vue2.js.map +1 -0
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +48 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js +20 -2
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue.js +1 -1
- package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue2.js +230 -25
- package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue2.js.map +1 -1
- package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue3.js +447 -221
- package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue3.js.map +1 -1
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/l10n/en.json.js +18 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +18 -1
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/library-style.js +1 -1
- package/dist/esm/nextcloud-vue.css +356 -114
- package/dist/esm/utils/libraryWidgetKeys.js +1 -0
- package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
- package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +6964 -5943
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +356 -114
- package/l10n/en.json +18 -1
- package/l10n/nl.json +18 -1
- package/package.json +1 -1
- package/src/components/CnAppRoot/CnAppRoot.vue +20 -0
- package/src/components/CnBrandBar/CnBrandBar.vue +5 -4
- package/src/components/CnDetailPage/CnDetailPage.vue +55 -15
- package/src/components/CnDeviceFramesWidget/CnDeviceFramesWidget.vue +360 -0
- package/src/components/CnDeviceFramesWidget/index.js +29 -0
- package/src/components/CnFactsWidget/CnFactsWidget.vue +46 -2
- package/src/components/CnHeaderSearchLabel/CnHeaderSearchLabel.vue +107 -0
- package/src/components/CnRecordListWidget/CnRecordListWidget.vue +81 -1
- package/src/components/CnRegisterMapping/CnRegisterMapping.md +10 -0
- package/src/components/CnRegisterMapping/CnRegisterMapping.vue +511 -28
- package/src/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
- package/src/components/index.js +1 -0
- package/src/index.js +1 -0
- package/src/schemas/app-manifest-v2.schema.json +6 -1
- package/src/utils/libraryWidgetKeys.js +1 -0
- package/src/utils/validateManifestV2.compiled.js +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CnBrandBar.vue2.js","sources":["../../../../src/components/CnBrandBar/CnBrandBar.vue"],"sourcesContent":["<!--\n CnBrandBar — the brand block in Nextcloud's own header (screens-brand-block-top-bar).\n\n Draws the 237px brand
|
|
1
|
+
{"version":3,"file":"CnBrandBar.vue2.js","sources":["../../../../src/components/CnBrandBar/CnBrandBar.vue"],"sourcesContent":["<!--\n CnBrandBar — the brand block in Nextcloud's own header (screens-brand-block-top-bar).\n\n Draws the brand block (a 237px brand link with the emblem, organisation and\n app name, then a 1px divider 12px on) at the START of `#header`, before the app menu, under the\n board look. CnAppRoot mounts it when a brand is declared and `#header` exists.\n\n `#header` is Nextcloud's and offers no extension point for apps, so this is\n the one place the library reaches into it, and it does so defensively:\n - it adds ONE node of its own (a host element) as the first child of the\n header, and teleports the block into it; it never moves, edits or removes\n a node Nextcloud drew;\n - it re-inserts its own host when Nextcloud re-renders the header (a\n MutationObserver on the header and its parent), never a second one;\n - with no `#header` it renders nothing and emits `unavailable`, so\n CnAppRoot lets the navigation draw the block instead.\n\n Sizes come from the board: `dossiq/DqKop`.\n-->\n<template>\n\t<Teleport v-if=\"host\" :to=\"host\">\n\t\t<div class=\"cn-brand-bar\" data-testid=\"cn-brand-bar\">\n\t\t\t<div class=\"cn-brand-bar__brand\" data-testid=\"cn-brand-bar-brand\">\n\t\t\t\t<!-- Decorative beside a name: the name already says whose app this is. -->\n\t\t\t\t<img\n\t\t\t\t\tv-if=\"typeof brand.emblem === 'string' && brand.emblem !== ''\"\n\t\t\t\t\tclass=\"cn-brand-bar__emblem\"\n\t\t\t\t\tdata-testid=\"cn-brand-bar-emblem\"\n\t\t\t\t\t:src=\"brand.emblem\"\n\t\t\t\t\t:alt=\"brand.name ? '' : brand.alt\">\n\t\t\t\t<span\n\t\t\t\t\tv-else-if=\"brand.emblem === true\"\n\t\t\t\t\tclass=\"cn-brand-bar__emblem cn-brand-bar__emblem--theme\"\n\t\t\t\t\tdata-testid=\"cn-brand-bar-emblem\"\n\t\t\t\t\taria-hidden=\"true\" />\n\t\t\t\t<img\n\t\t\t\t\tv-else-if=\"brand.logo\"\n\t\t\t\t\tclass=\"cn-brand-bar__emblem\"\n\t\t\t\t\t:src=\"brand.logo\"\n\t\t\t\t\t:alt=\"brand.name ? '' : brand.alt\">\n\t\t\t\t<span v-if=\"brand.name || brand.caption\" class=\"cn-brand-bar__text\">\n\t\t\t\t\t<span v-if=\"brand.caption\" class=\"cn-brand-bar__caption\">{{ brand.caption }}</span>\n\t\t\t\t\t<strong v-if=\"brand.name\" class=\"cn-brand-bar__name\">{{ brand.name }}</strong>\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t\t<span class=\"cn-brand-bar__divider\" aria-hidden=\"true\" />\n\t\t</div>\n\t</Teleport>\n</template>\n\n<script>\nimport { markRaw } from 'vue'\n\nconst HOST_CLASS = 'cn-brand-bar-host'\n\n/**\n * The brand block in Nextcloud's header.\n *\n * @event unavailable Emitted when there is no `#header` to put the block in (or it disappears), so the host lets the navigation draw it.\n *\n * @spec openspec/changes/screens-brand-block-top-bar/specs/layout-components/spec.md#requirement-the-board-look-draws-the-brand-block-in-the-nextcloud-header\n */\nexport default {\n\tname: 'CnBrandBar',\n\n\tprops: {\n\t\t/**\n\t\t * The resolved brand: `{ logo, emblem, name, caption, alt }`. `emblem`\n\t\t * is a URL, or `true` for the theme's `--nldesign-emblem-url`.\n\t\t *\n\t\t * @type {{logo?: string, emblem?: (string|boolean), name?: string, caption?: string, alt?: string}}\n\t\t */\n\t\tbrand: {\n\t\t\ttype: Object,\n\t\t\trequired: true,\n\t\t},\n\t},\n\n\temits: ['unavailable'],\n\n\tdata() {\n\t\treturn { host: null, observer: null }\n\t},\n\n\tmounted() {\n\t\tthis.attach()\n\t},\n\n\tbeforeUnmount() {\n\t\tthis.detach()\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Insert the host as the first child of `#header` and watch the header.\n\t\t * Emits `unavailable` when there is no header.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tattach() {\n\t\t\tconst header = document.getElementById('header')\n\t\t\tif (!header) {\n\t\t\t\t/**\n\t\t\t\t * @event unavailable Emitted when there is no `#header` to put the block in.\n\t\t\t\t */\n\t\t\t\tthis.$emit('unavailable')\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.host = markRaw(document.createElement('div'))\n\t\t\tthis.host.className = HOST_CLASS\n\t\t\theader.insertBefore(this.host, header.firstChild)\n\t\t\tif (typeof MutationObserver === 'function') {\n\t\t\t\tthis.observer = new MutationObserver(() => this.reattach())\n\t\t\t\tthis.observer.observe(header, { childList: true })\n\t\t\t\tif (header.parentNode) {\n\t\t\t\t\tthis.observer.observe(header.parentNode, { childList: true })\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Put the same host back when Nextcloud re-rendered the header and took\n\t\t * it out. Never creates a second host; when the header is gone for good\n\t\t * it hands the block back to the navigation.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\treattach() {\n\t\t\tif (!this.host) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst header = document.getElementById('header')\n\t\t\tif (!header) {\n\t\t\t\tthis.$emit('unavailable')\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.host.parentNode !== header) {\n\t\t\t\theader.insertBefore(this.host, header.firstChild)\n\t\t\t\tthis.observer?.observe(header, { childList: true })\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Stop watching and remove only the host this component added.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tdetach() {\n\t\t\tthis.observer?.disconnect()\n\t\t\tthis.observer = null\n\t\t\tthis.host?.remove()\n\t\t\tthis.host = null\n\t\t},\n\t},\n}\n</script>\n\n<style>\n/* The host is one flex item at the start of Nextcloud's header. */\n.cn-brand-bar-host {\n\tflex: none;\n\tdisplay: flex;\n\talign-items: center;\n\theight: 100%;\n\tmargin-inline-end: 12px;\n}\n\n.cn-brand-bar {\n\tbox-sizing: border-box;\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 12px;\n}\n\n/* The brand link is 237px; the divider follows it, 12px on. */\n.cn-brand-bar__brand {\n\tflex: none;\n\twidth: var(--cn-board-brand-width, 237px);\n\tbox-sizing: border-box;\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tmin-width: 0;\n\tmin-height: 48px;\n\tmax-height: 100%;\n\tpadding: 0 6px;\n\tborder-radius: 8px;\n\tcolor: var(--color-background-plain-text, var(--color-main-text));\n}\n\n.cn-brand-bar__emblem {\n\tflex: none;\n\theight: var(--cn-nav-emblem-size, 34px);\n\twidth: auto;\n\tobject-fit: contain;\n}\n\n.cn-brand-bar__emblem--theme {\n\tdisplay: inline-block;\n\twidth: var(--cn-nav-emblem-size, 34px);\n\tbackground: var(--nldesign-emblem-url) center / contain no-repeat;\n}\n\n.cn-brand-bar__text {\n\tdisplay: flex;\n\tflex-direction: column;\n\tline-height: 1.15;\n\tmin-width: 0;\n}\n\n.cn-brand-bar__caption {\n\tfont-size: 13px;\n\twhite-space: nowrap;\n\topacity: 0.8;\n}\n\n.cn-brand-bar__name {\n\tfont-size: 18px;\n\tfont-weight: 700;\n\twhite-space: nowrap;\n}\n\n.cn-brand-bar__divider {\n\tflex: none;\n\twidth: 1px;\n\theight: 28px;\n\tbackground: currentColor;\n\topacity: 0.25;\n\tcolor: var(--color-background-plain-text, var(--color-main-text));\n}\n</style>\n"],"names":[],"mappings":";;AAqDA,MAAM,aAAa,oBAAkB;;AAErC;AACC;AACA;;AAEA;AACA;;AAED,aAAe;AACd,CAAA,IAAI,EAAE,YAAY;;AAElB,CAAA,KAAK,EAAE;AACN;;;AAGC;AACA;;AAED,EAAA,KAAK,EAAE;GACN,IAAI,EAAE,MAAM;GACZ,QAAQ,EAAE,IAAI;GACd;EACD;;AAED,CAAA,KAAK,EAAE,CAAC,aAAa,CAAC;;AAEtB,CAAA,IAAI,GAAG;AACN,EAAA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAK,EAAA;EACpC;;AAED,CAAA,OAAO,GAAG;EACT,IAAI,CAAC,MAAM,GAAC;EACZ;;AAED,CAAA,aAAa,GAAG;EACf,IAAI,CAAC,MAAM,GAAC;EACZ;;AAED,CAAA,OAAO,EAAE;AACR;;AAEC;AACA;;;AAGD,EAAA,MAAM,GAAG;AACR,GAAA,MAAM,SAAS,QAAQ,CAAC,cAAc,CAAC,QAAQ,EAAA;GAC/C,IAAI,CAAC,MAAM,EAAE;AACZ;AACC;;IAED,IAAI,CAAC,KAAK,CAAC,aAAa,EAAA;IACxB,MAAK;AACN,IAAA;GACA,IAAI,CAAC,OAAO,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,EAAA;GACjD,IAAI,CAAC,IAAI,CAAC,SAAU,GAAE,WAAS;GAC/B,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,UAAU,EAAA;AAChD,GAAA,IAAI,OAAO,gBAAiB,KAAI,UAAU,EAAE;IAC3C,IAAI,CAAC,WAAW,IAAI,gBAAgB,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,EAAA;AAC1D,IAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAA;AACjD,IAAA,IAAI,MAAM,CAAC,UAAU,EAAE;KACtB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAG,EAAG,EAAA;AAC7D,KAAA;AACD,IAAA;GACA;;AAED;;;AAGC;AACA;;;EAGD,QAAQ,GAAG;AACV,GAAA,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;IACf,MAAK;AACN,IAAA;AACA,GAAA,MAAM,SAAS,QAAQ,CAAC,cAAc,CAAC,QAAQ,EAAA;GAC/C,IAAI,CAAC,MAAM,EAAE;IACZ,IAAI,CAAC,KAAK,CAAC,aAAa,EAAA;IACxB,MAAK;AACN,IAAA;AACA,GAAA,IAAI,IAAI,CAAC,IAAI,CAAC,eAAe,MAAM,EAAE;IACpC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,UAAU,EAAA;IAChD,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAA;AACnD,IAAA;GACA;;AAED;;AAEC;;;AAGD,EAAA,MAAM,GAAG;GACR,IAAI,CAAC,QAAQ,EAAE,UAAU,GAAC;AAC1B,GAAA,IAAI,CAAC,QAAO,GAAI,KAAG;AACnB,GAAA,IAAI,CAAC,IAAI,EAAE,MAAM,GAAC;GAClB,IAAI,CAAC,IAAK,GAAE,KAAG;GACf;EACD;AACF;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CnBrandBar.vue3.js","sources":["../../../../src/components/CnBrandBar/CnBrandBar.vue?vue&type=template&id=
|
|
1
|
+
{"version":3,"file":"CnBrandBar.vue3.js","sources":["../../../../src/components/CnBrandBar/CnBrandBar.vue?vue&type=template&id=639a1bad&lang.js"],"sourcesContent":["<!--\n CnBrandBar — the brand block in Nextcloud's own header (screens-brand-block-top-bar).\n\n Draws the brand block (a 237px brand link with the emblem, organisation and\n app name, then a 1px divider 12px on) at the START of `#header`, before the app menu, under the\n board look. CnAppRoot mounts it when a brand is declared and `#header` exists.\n\n `#header` is Nextcloud's and offers no extension point for apps, so this is\n the one place the library reaches into it, and it does so defensively:\n - it adds ONE node of its own (a host element) as the first child of the\n header, and teleports the block into it; it never moves, edits or removes\n a node Nextcloud drew;\n - it re-inserts its own host when Nextcloud re-renders the header (a\n MutationObserver on the header and its parent), never a second one;\n - with no `#header` it renders nothing and emits `unavailable`, so\n CnAppRoot lets the navigation draw the block instead.\n\n Sizes come from the board: `dossiq/DqKop`.\n-->\n<template>\n\t<Teleport v-if=\"host\" :to=\"host\">\n\t\t<div class=\"cn-brand-bar\" data-testid=\"cn-brand-bar\">\n\t\t\t<div class=\"cn-brand-bar__brand\" data-testid=\"cn-brand-bar-brand\">\n\t\t\t\t<!-- Decorative beside a name: the name already says whose app this is. -->\n\t\t\t\t<img\n\t\t\t\t\tv-if=\"typeof brand.emblem === 'string' && brand.emblem !== ''\"\n\t\t\t\t\tclass=\"cn-brand-bar__emblem\"\n\t\t\t\t\tdata-testid=\"cn-brand-bar-emblem\"\n\t\t\t\t\t:src=\"brand.emblem\"\n\t\t\t\t\t:alt=\"brand.name ? '' : brand.alt\">\n\t\t\t\t<span\n\t\t\t\t\tv-else-if=\"brand.emblem === true\"\n\t\t\t\t\tclass=\"cn-brand-bar__emblem cn-brand-bar__emblem--theme\"\n\t\t\t\t\tdata-testid=\"cn-brand-bar-emblem\"\n\t\t\t\t\taria-hidden=\"true\" />\n\t\t\t\t<img\n\t\t\t\t\tv-else-if=\"brand.logo\"\n\t\t\t\t\tclass=\"cn-brand-bar__emblem\"\n\t\t\t\t\t:src=\"brand.logo\"\n\t\t\t\t\t:alt=\"brand.name ? '' : brand.alt\">\n\t\t\t\t<span v-if=\"brand.name || brand.caption\" class=\"cn-brand-bar__text\">\n\t\t\t\t\t<span v-if=\"brand.caption\" class=\"cn-brand-bar__caption\">{{ brand.caption }}</span>\n\t\t\t\t\t<strong v-if=\"brand.name\" class=\"cn-brand-bar__name\">{{ brand.name }}</strong>\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t\t<span class=\"cn-brand-bar__divider\" aria-hidden=\"true\" />\n\t\t</div>\n\t</Teleport>\n</template>\n\n<script>\nimport { markRaw } from 'vue'\n\nconst HOST_CLASS = 'cn-brand-bar-host'\n\n/**\n * The brand block in Nextcloud's header.\n *\n * @event unavailable Emitted when there is no `#header` to put the block in (or it disappears), so the host lets the navigation draw it.\n *\n * @spec openspec/changes/screens-brand-block-top-bar/specs/layout-components/spec.md#requirement-the-board-look-draws-the-brand-block-in-the-nextcloud-header\n */\nexport default {\n\tname: 'CnBrandBar',\n\n\tprops: {\n\t\t/**\n\t\t * The resolved brand: `{ logo, emblem, name, caption, alt }`. `emblem`\n\t\t * is a URL, or `true` for the theme's `--nldesign-emblem-url`.\n\t\t *\n\t\t * @type {{logo?: string, emblem?: (string|boolean), name?: string, caption?: string, alt?: string}}\n\t\t */\n\t\tbrand: {\n\t\t\ttype: Object,\n\t\t\trequired: true,\n\t\t},\n\t},\n\n\temits: ['unavailable'],\n\n\tdata() {\n\t\treturn { host: null, observer: null }\n\t},\n\n\tmounted() {\n\t\tthis.attach()\n\t},\n\n\tbeforeUnmount() {\n\t\tthis.detach()\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Insert the host as the first child of `#header` and watch the header.\n\t\t * Emits `unavailable` when there is no header.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tattach() {\n\t\t\tconst header = document.getElementById('header')\n\t\t\tif (!header) {\n\t\t\t\t/**\n\t\t\t\t * @event unavailable Emitted when there is no `#header` to put the block in.\n\t\t\t\t */\n\t\t\t\tthis.$emit('unavailable')\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.host = markRaw(document.createElement('div'))\n\t\t\tthis.host.className = HOST_CLASS\n\t\t\theader.insertBefore(this.host, header.firstChild)\n\t\t\tif (typeof MutationObserver === 'function') {\n\t\t\t\tthis.observer = new MutationObserver(() => this.reattach())\n\t\t\t\tthis.observer.observe(header, { childList: true })\n\t\t\t\tif (header.parentNode) {\n\t\t\t\t\tthis.observer.observe(header.parentNode, { childList: true })\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Put the same host back when Nextcloud re-rendered the header and took\n\t\t * it out. Never creates a second host; when the header is gone for good\n\t\t * it hands the block back to the navigation.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\treattach() {\n\t\t\tif (!this.host) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst header = document.getElementById('header')\n\t\t\tif (!header) {\n\t\t\t\tthis.$emit('unavailable')\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.host.parentNode !== header) {\n\t\t\t\theader.insertBefore(this.host, header.firstChild)\n\t\t\t\tthis.observer?.observe(header, { childList: true })\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Stop watching and remove only the host this component added.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tdetach() {\n\t\t\tthis.observer?.disconnect()\n\t\t\tthis.observer = null\n\t\t\tthis.host?.remove()\n\t\t\tthis.host = null\n\t\t},\n\t},\n}\n</script>\n\n<style>\n/* The host is one flex item at the start of Nextcloud's header. */\n.cn-brand-bar-host {\n\tflex: none;\n\tdisplay: flex;\n\talign-items: center;\n\theight: 100%;\n\tmargin-inline-end: 12px;\n}\n\n.cn-brand-bar {\n\tbox-sizing: border-box;\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 12px;\n}\n\n/* The brand link is 237px; the divider follows it, 12px on. */\n.cn-brand-bar__brand {\n\tflex: none;\n\twidth: var(--cn-board-brand-width, 237px);\n\tbox-sizing: border-box;\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tmin-width: 0;\n\tmin-height: 48px;\n\tmax-height: 100%;\n\tpadding: 0 6px;\n\tborder-radius: 8px;\n\tcolor: var(--color-background-plain-text, var(--color-main-text));\n}\n\n.cn-brand-bar__emblem {\n\tflex: none;\n\theight: var(--cn-nav-emblem-size, 34px);\n\twidth: auto;\n\tobject-fit: contain;\n}\n\n.cn-brand-bar__emblem--theme {\n\tdisplay: inline-block;\n\twidth: var(--cn-nav-emblem-size, 34px);\n\tbackground: var(--nldesign-emblem-url) center / contain no-repeat;\n}\n\n.cn-brand-bar__text {\n\tdisplay: flex;\n\tflex-direction: column;\n\tline-height: 1.15;\n\tmin-width: 0;\n}\n\n.cn-brand-bar__caption {\n\tfont-size: 13px;\n\twhite-space: nowrap;\n\topacity: 0.8;\n}\n\n.cn-brand-bar__name {\n\tfont-size: 18px;\n\tfont-weight: 700;\n\twhite-space: nowrap;\n}\n\n.cn-brand-bar__divider {\n\tflex: none;\n\twidth: 1px;\n\theight: 28px;\n\tbackground: currentColor;\n\topacity: 0.25;\n\tcolor: var(--color-background-plain-text, var(--color-main-text));\n}\n</style>\n"],"names":["_createBlock","_createElementVNode","_createElementBlock"],"mappings":";;;AAwCO,EAAA,KAAK,EAAC,cAAc;AAAC,EAAA,aAAW,EAAC,cAAc;;;AAC9C,EAAA,KAAK,EAAC,qBAAqB;AAAC,EAAA,aAAW,EAAC,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;UAFnD,KAAK,CAAA,IAAA;oBAAjBA;;AAAmB,QAAA,EAAC,EAAI,KAAG,CAAA,IAAA;;AAC5B,QAAAC,kBAAA,QAAA;AACC,UAAAA,kBAAA,QAAA;AAGG,YAAA,CAAA,OAAA,MAAA,CAAA,KAAA,CAAA,MAAA,KAAA,QAAA,IAAA,MAAA,CAAA,KAAA,CAAA,MAAA,KAAA,EAAA;8BADJC;;AAEC,kBAAA,KAAK,EAAC,sBAAsB;AAC5B,kBAAA,aAAE,EAAA,qBAAA;kBACD,GAAG,EAAE,MAAA,CAAA,KAAA,CAAA,MAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -885,7 +885,7 @@ var script = {
|
|
|
885
885
|
default: false,
|
|
886
886
|
},
|
|
887
887
|
|
|
888
|
-
/** Label for the header Edit button. Defaults to a translated "Edit". */
|
|
888
|
+
/** Label for the header Edit button, run through the host translate. Defaults to a translated "Edit". */
|
|
889
889
|
editLabel: {
|
|
890
890
|
type: String,
|
|
891
891
|
default: '',
|
|
@@ -2200,14 +2200,40 @@ var script = {
|
|
|
2200
2200
|
|
|
2201
2201
|
/**
|
|
2202
2202
|
* The side column's widget definitions. A string names a widget
|
|
2203
|
-
* declared in `widgets`; an object is a definition of its own.
|
|
2203
|
+
* declared in `widgets`; an object is a definition of its own. A
|
|
2204
|
+
* definition whose `visibleWhen` does not hold for the record (or the
|
|
2205
|
+
* records `visibilityContext` names) is left out, exactly as in the
|
|
2206
|
+
* body grid; edit mode shows them all.
|
|
2204
2207
|
*
|
|
2205
2208
|
* @return {Array<object>} The definitions that resolve, each with an `id`.
|
|
2206
2209
|
* @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-side-column
|
|
2210
|
+
* @spec openspec/changes/detail-side-visible-when/specs/detail-page/spec.md#requirement-a-side-column-widget-shows-only-while-its-visiblewhen-holds
|
|
2207
2211
|
*/
|
|
2208
2212
|
sideColumnWidgets() {
|
|
2213
|
+
const resolved = this.declaredSideWidgets.filter((widget) => this.sideWidgetVisible(widget));
|
|
2214
|
+
if (!this.isBoard) {
|
|
2215
|
+
return resolved
|
|
2216
|
+
}
|
|
2217
|
+
// The board look: the notice first, the History card last.
|
|
2218
|
+
const rank = (widget) => (widget.type === 'banner' ? 0 : isActivityWidget(widget) ? 2 : 1);
|
|
2219
|
+
return resolved
|
|
2220
|
+
.map((widget, index) => ({ widget, index }))
|
|
2221
|
+
.sort((a, b) => (rank(a.widget) - rank(b.widget)) || (a.index - b.index))
|
|
2222
|
+
.map(({ widget }) => widget)
|
|
2223
|
+
},
|
|
2224
|
+
|
|
2225
|
+
/**
|
|
2226
|
+
* The side column's entries resolved to definitions, before any
|
|
2227
|
+
* `visibleWhen` is read: a string names a widget declared in
|
|
2228
|
+
* `widgets`, an object is a definition of its own (given an id when it
|
|
2229
|
+
* has none).
|
|
2230
|
+
*
|
|
2231
|
+
* @return {Array<object>}
|
|
2232
|
+
* @spec openspec/changes/detail-side-visible-when/specs/detail-page/spec.md#requirement-a-side-column-widget-shows-only-while-its-visiblewhen-holds
|
|
2233
|
+
*/
|
|
2234
|
+
declaredSideWidgets() {
|
|
2209
2235
|
const declared = Array.isArray(this.widgets) ? this.widgets : [];
|
|
2210
|
-
|
|
2236
|
+
return (Array.isArray(this.sideColumn) ? this.sideColumn : [])
|
|
2211
2237
|
.map((entry, index) => {
|
|
2212
2238
|
if (typeof entry === 'string') {
|
|
2213
2239
|
return declared.find((widget) => widget && widget.id === entry) || null
|
|
@@ -2217,16 +2243,7 @@ var script = {
|
|
|
2217
2243
|
}
|
|
2218
2244
|
return entry.id ? entry : { ...entry, id: `cn-side-${index}` }
|
|
2219
2245
|
})
|
|
2220
|
-
.filter(Boolean)
|
|
2221
|
-
if (!this.isBoard) {
|
|
2222
|
-
return resolved
|
|
2223
|
-
}
|
|
2224
|
-
// The board look: the notice first, the History card last.
|
|
2225
|
-
const rank = (widget) => (widget.type === 'banner' ? 0 : isActivityWidget(widget) ? 2 : 1);
|
|
2226
|
-
return resolved
|
|
2227
|
-
.map((widget, index) => ({ widget, index }))
|
|
2228
|
-
.sort((a, b) => (rank(a.widget) - rank(b.widget)) || (a.index - b.index))
|
|
2229
|
-
.map(({ widget }) => widget)
|
|
2246
|
+
.filter(Boolean)
|
|
2230
2247
|
},
|
|
2231
2248
|
|
|
2232
2249
|
/**
|
|
@@ -2547,12 +2564,14 @@ var script = {
|
|
|
2547
2564
|
},
|
|
2548
2565
|
|
|
2549
2566
|
/**
|
|
2550
|
-
* Label for the header Edit button
|
|
2567
|
+
* Label for the header Edit button: the manifest's `editLabel` through
|
|
2568
|
+
* the host translate, else the library's translated "Edit".
|
|
2551
2569
|
*
|
|
2552
2570
|
* @return {string}
|
|
2571
|
+
* @spec openspec/changes/detail-edit-label-translate/specs/detail-page/spec.md#requirement-the-edit-button-label-follows-the-reader-s-language
|
|
2553
2572
|
*/
|
|
2554
2573
|
editActionLabel() {
|
|
2555
|
-
return this.editLabel
|
|
2574
|
+
return this.editLabel ? this.effectiveTranslate(this.editLabel) : translate('nextcloud-vue', 'Edit')
|
|
2556
2575
|
},
|
|
2557
2576
|
|
|
2558
2577
|
/**
|
|
@@ -2806,7 +2825,7 @@ var script = {
|
|
|
2806
2825
|
if (!this.widgetVisibilityData || this.visibilityRowsPending) {
|
|
2807
2826
|
return ''
|
|
2808
2827
|
}
|
|
2809
|
-
const defs = [...(this.bodyGridWidgets || []), ...((this.activeView && this.activeView.widgets) || [])];
|
|
2828
|
+
const defs = [...(this.bodyGridWidgets || []), ...((this.activeView && this.activeView.widgets) || []), ...this.declaredSideWidgets];
|
|
2810
2829
|
const remote = defs.filter((def) => def && def.visibleWhen && typeof def.visibleWhen === 'object'
|
|
2811
2830
|
&& !isLocallyDecidableVisibleWhen(def.visibleWhen));
|
|
2812
2831
|
if (remote.length === 0) {
|
|
@@ -4681,6 +4700,27 @@ var script = {
|
|
|
4681
4700
|
return compactLayoutRows(drawable)
|
|
4682
4701
|
},
|
|
4683
4702
|
|
|
4703
|
+
/**
|
|
4704
|
+
* Whether a side column widget shows: always in edit mode or without a
|
|
4705
|
+
* `visibleWhen`, else while it holds for the record and the records
|
|
4706
|
+
* `visibilityContext` names, read by the same `detailWidgetVisible` the
|
|
4707
|
+
* body grid uses (local field conditions, `@context.<name>.*`, and the
|
|
4708
|
+
* answers of endpoint and source conditions).
|
|
4709
|
+
*
|
|
4710
|
+
* @param {object} widget A side column widget definition.
|
|
4711
|
+
* @return {boolean}
|
|
4712
|
+
* @spec openspec/changes/detail-side-visible-when/specs/detail-page/spec.md#requirement-a-side-column-widget-shows-only-while-its-visiblewhen-holds
|
|
4713
|
+
*/
|
|
4714
|
+
sideWidgetVisible(widget) {
|
|
4715
|
+
if (this.editingBody || widget.visibleWhen === undefined || widget.visibleWhen === null) {
|
|
4716
|
+
return true
|
|
4717
|
+
}
|
|
4718
|
+
return detailWidgetVisible(widget, this.widgetVisibilityData, {
|
|
4719
|
+
pending: this.visibilityRowsPending,
|
|
4720
|
+
answers: this.widgetConditionAnswers,
|
|
4721
|
+
})
|
|
4722
|
+
},
|
|
4723
|
+
|
|
4684
4724
|
/**
|
|
4685
4725
|
* Whether a layout item has anything to draw, so a grid cell is worth
|
|
4686
4726
|
* spending on it.
|