@xwiki/cristal-dsvuetify 0.14.0 → 0.15.0
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/CHANGELOG.md +16 -0
- package/dist/{index-C4ioHAez.js → index-BAakw3UY.js} +5925 -5865
- package/dist/index-BAakw3UY.js.map +1 -0
- package/dist/index.es.js +7 -5
- package/dist/index.umd.js +11 -9
- package/dist/index.umd.js.map +1 -1
- package/dist/translations-k4crOAds.js +24 -0
- package/dist/{translations-BNEIsfPR.js.map → translations-k4crOAds.js.map} +1 -1
- package/dist/vue/form/x-navigation-tree-select.vue.d.ts +12 -0
- package/dist/vue/x-navigation-tree.vue.d.ts +2 -8
- package/dist/{x-alert-CTAhsN6L.js → x-alert-CRdF8zFB.js} +4 -4
- package/dist/x-alert-CRdF8zFB.js.map +1 -0
- package/dist/{x-btn-BsiSIiiO.js → x-btn-DwTcXGgx.js} +2 -2
- package/dist/{x-btn-BsiSIiiO.js.map → x-btn-DwTcXGgx.js.map} +1 -1
- package/dist/{x-checkbox-CJ3_IJ-Y.js → x-checkbox-Fro597Ax.js} +2 -2
- package/dist/{x-checkbox-CJ3_IJ-Y.js.map → x-checkbox-Fro597Ax.js.map} +1 -1
- package/dist/x-dialog-DCEnccuq.js +48 -0
- package/dist/x-dialog-DCEnccuq.js.map +1 -0
- package/dist/{x-file-input-CMM5DWJc.js → x-file-input-CvH0AC3G.js} +13 -11
- package/dist/{x-file-input-CMM5DWJc.js.map → x-file-input-CvH0AC3G.js.map} +1 -1
- package/dist/x-form-DCHdDC6W.js +25 -0
- package/dist/x-form-DCHdDC6W.js.map +1 -0
- package/dist/x-navigation-tree-D_fUW-gW.js +520 -0
- package/dist/x-navigation-tree-D_fUW-gW.js.map +1 -0
- package/dist/x-navigation-tree-select-DaiYF3ux.js +95 -0
- package/dist/x-navigation-tree-select-DaiYF3ux.js.map +1 -0
- package/dist/x-text-field-2Sv6HUGW.js +43 -0
- package/dist/{x-text-field-BxSiyeFc.js.map → x-text-field-2Sv6HUGW.js.map} +1 -1
- package/langs/translation-de.json +3 -1
- package/langs/translation-en.json +3 -1
- package/langs/translation-fr.json +3 -1
- package/package.json +13 -11
- package/src/components/vuetifyDesignSystemLoader.ts +7 -1
- package/src/translations.ts +4 -0
- package/src/vue/css/style.css +1 -1
- package/src/vue/form/x-form.vue +8 -4
- package/src/vue/form/x-navigation-tree-select.vue +120 -0
- package/src/vue/form/x-text-field.vue +3 -0
- package/src/vue/x-navigation-tree.vue +17 -27
- package/dist/index-C4ioHAez.js.map +0 -1
- package/dist/translations-BNEIsfPR.js +0 -10
- package/dist/x-alert-CTAhsN6L.js.map +0 -1
- package/dist/x-dialog-C4gz0mOu.js +0 -48
- package/dist/x-dialog-C4gz0mOu.js.map +0 -1
- package/dist/x-form-BLg386BG.js +0 -32
- package/dist/x-form-BLg386BG.js.map +0 -1
- package/dist/x-navigation-tree-BW05Yivz.js +0 -502
- package/dist/x-navigation-tree-BW05Yivz.js.map +0 -1
- package/dist/x-text-field-BxSiyeFc.js +0 -38
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { defineComponent as C, mergeModels as X, inject as k, useModel as w, ref as v, onMounted as N, resolveComponent as i, openBlock as B, createElementBlock as D, Fragment as H, createVNode as t, unref as o, withCtx as a, createTextVNode as h, toDisplayString as _ } from "vue";
|
|
2
|
+
import { t as M } from "./translations-k4crOAds.js";
|
|
3
|
+
import T from "./x-breadcrumb-C2iUd4Sf.js";
|
|
4
|
+
import { SpaceReference as S } from "@xwiki/cristal-model-api";
|
|
5
|
+
import { useI18n as F } from "vue-i18n";
|
|
6
|
+
import { a as I } from "./index-BAakw3UY.js";
|
|
7
|
+
import { _ as j } from "./_plugin-vue_export-helper-CHgC5LLL.js";
|
|
8
|
+
const z = /* @__PURE__ */ C({
|
|
9
|
+
__name: "x-navigation-tree-select",
|
|
10
|
+
props: /* @__PURE__ */ X({
|
|
11
|
+
label: {},
|
|
12
|
+
help: {},
|
|
13
|
+
currentPageReference: {},
|
|
14
|
+
modelValue: {}
|
|
15
|
+
}, {
|
|
16
|
+
modelValue: {},
|
|
17
|
+
modelModifiers: {}
|
|
18
|
+
}),
|
|
19
|
+
emits: ["update:modelValue"],
|
|
20
|
+
setup(m) {
|
|
21
|
+
const d = k("cristal"), f = d.getContainer().get("PageHierarchyResolverProvider").get(), y = d.getContainer().get("ModelReferenceHandlerProvider").get(), { t: c } = F({
|
|
22
|
+
messages: M
|
|
23
|
+
}), s = m, p = w(m, "modelValue"), u = v(!1), n = v([]);
|
|
24
|
+
let l;
|
|
25
|
+
N(async () => {
|
|
26
|
+
l = s.currentPageReference, p.value = s.currentPageReference.space, n.value = await f.getPageHierarchy(
|
|
27
|
+
s.currentPageReference.space
|
|
28
|
+
);
|
|
29
|
+
});
|
|
30
|
+
async function b(e) {
|
|
31
|
+
l = y.createDocumentReference(
|
|
32
|
+
e.location.names[e.location.names.length - 1],
|
|
33
|
+
new S(e.location.wiki, ...e.location.names.slice(0, -1))
|
|
34
|
+
), p.value = e.location, n.value = await f.getPageHierarchy(l);
|
|
35
|
+
}
|
|
36
|
+
return (e, r) => {
|
|
37
|
+
const P = i("x-btn"), V = i("XNavigationTree"), R = i("XBtn"), x = i("XDialog");
|
|
38
|
+
return B(), D(H, null, [
|
|
39
|
+
t(o(I), {
|
|
40
|
+
label: e.label,
|
|
41
|
+
hint: e.help,
|
|
42
|
+
"persistent-hint": e.help !== void 0,
|
|
43
|
+
active: n.value.length > 0,
|
|
44
|
+
readonly: ""
|
|
45
|
+
}, {
|
|
46
|
+
default: a(() => [
|
|
47
|
+
t(T, { items: n.value }, null, 8, ["items"])
|
|
48
|
+
]),
|
|
49
|
+
_: 1
|
|
50
|
+
}, 8, ["label", "hint", "persistent-hint", "active"]),
|
|
51
|
+
t(x, {
|
|
52
|
+
modelValue: u.value,
|
|
53
|
+
"onUpdate:modelValue": r[1] || (r[1] = (g) => u.value = g),
|
|
54
|
+
width: "auto",
|
|
55
|
+
title: o(c)("vuetify.tree.select.location.label")
|
|
56
|
+
}, {
|
|
57
|
+
activator: a(() => [
|
|
58
|
+
t(P, {
|
|
59
|
+
id: "change-page-location-button",
|
|
60
|
+
size: "small",
|
|
61
|
+
color: "secondary"
|
|
62
|
+
}, {
|
|
63
|
+
default: a(() => [
|
|
64
|
+
h(_(o(c)("vuetify.tree.select.location.label")), 1)
|
|
65
|
+
]),
|
|
66
|
+
_: 1
|
|
67
|
+
})
|
|
68
|
+
]),
|
|
69
|
+
default: a(() => [
|
|
70
|
+
t(V, {
|
|
71
|
+
"current-page-reference": o(l),
|
|
72
|
+
"click-action": b
|
|
73
|
+
}, null, 8, ["current-page-reference"])
|
|
74
|
+
]),
|
|
75
|
+
footer: a(() => [
|
|
76
|
+
t(R, {
|
|
77
|
+
variant: "primary",
|
|
78
|
+
onClick: r[0] || (r[0] = (g) => u.value = !1)
|
|
79
|
+
}, {
|
|
80
|
+
default: a(() => [
|
|
81
|
+
h(_(o(c)("vuetify.tree.select.location.select")), 1)
|
|
82
|
+
]),
|
|
83
|
+
_: 1
|
|
84
|
+
})
|
|
85
|
+
]),
|
|
86
|
+
_: 1
|
|
87
|
+
}, 8, ["modelValue", "title"])
|
|
88
|
+
], 64);
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
}), J = /* @__PURE__ */ j(z, [["__scopeId", "data-v-059de402"]]);
|
|
92
|
+
export {
|
|
93
|
+
J as default
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=x-navigation-tree-select-DaiYF3ux.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"x-navigation-tree-select-DaiYF3ux.js","sources":["../src/vue/form/x-navigation-tree-select.vue"],"sourcesContent":["<!--\nSee the LICENSE file distributed with this work for additional\ninformation regarding copyright ownership.\n\nThis is free software; you can redistribute it and/or modify it\nunder the terms of the GNU Lesser General Public License as\npublished by the Free Software Foundation; either version 2.1 of\nthe License, or (at your option) any later version.\n\nThis software is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\nLesser General Public License for more details.\n\nYou should have received a copy of the GNU Lesser General Public\nLicense along with this software; if not, write to the Free\nSoftware Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\n02110-1301 USA, or see the FSF site: http://www.fsf.org.\n-->\n<script setup lang=\"ts\">\nimport messages from \"../../translations\";\nimport XBreadcrumb from \"../x-breadcrumb.vue\";\nimport { SpaceReference } from \"@xwiki/cristal-model-api\";\nimport { inject, onMounted, ref } from \"vue\";\nimport { useI18n } from \"vue-i18n\";\nimport { VTextField } from \"vuetify/components/VTextField\";\nimport type { CristalApp } from \"@xwiki/cristal-api\";\nimport type { NavigationTreeSelectProps } from \"@xwiki/cristal-dsapi\";\nimport type {\n PageHierarchyItem,\n PageHierarchyResolver,\n PageHierarchyResolverProvider,\n} from \"@xwiki/cristal-hierarchy-api\";\nimport type { DocumentReference } from \"@xwiki/cristal-model-api\";\nimport type {\n ModelReferenceHandler,\n ModelReferenceHandlerProvider,\n} from \"@xwiki/cristal-model-reference-api\";\nimport type { NavigationTreeNode } from \"@xwiki/cristal-navigation-tree-api\";\nimport type { Ref } from \"vue\";\n\nconst cristal: CristalApp = inject<CristalApp>(\"cristal\")!;\nconst hierarchyResolver: PageHierarchyResolver = cristal\n .getContainer()\n .get<PageHierarchyResolverProvider>(\"PageHierarchyResolverProvider\")\n .get()!;\nconst referenceHandler: ModelReferenceHandler = cristal\n .getContainer()\n .get<ModelReferenceHandlerProvider>(\"ModelReferenceHandlerProvider\")\n .get()!;\n\nconst { t } = useI18n({\n messages,\n});\nconst props = defineProps<NavigationTreeSelectProps>();\nconst model = defineModel<SpaceReference>();\n\nconst openedLocationDialog: Ref<boolean> = ref(false);\nconst hierarchy: Ref<Array<PageHierarchyItem>> = ref([]);\nlet selectedPage: DocumentReference | undefined;\n\nonMounted(async () => {\n selectedPage = props.currentPageReference;\n model.value = props.currentPageReference!.space;\n hierarchy.value = await hierarchyResolver.getPageHierarchy(\n props.currentPageReference!.space!,\n );\n});\n\nasync function treeNodeClickAction(node: NavigationTreeNode) {\n selectedPage = referenceHandler.createDocumentReference(\n node.location.names[node.location.names.length - 1],\n new SpaceReference(node.location.wiki, ...node.location.names.slice(0, -1)),\n );\n model.value = node.location;\n hierarchy.value = await hierarchyResolver.getPageHierarchy(selectedPage);\n}\n</script>\n\n<template>\n <v-text-field\n :label=\"label\"\n :hint=\"help\"\n :persistent-hint=\"help !== undefined\"\n :active=\"hierarchy.length > 0\"\n readonly\n >\n <template #default>\n <XBreadcrumb :items=\"hierarchy\"></XBreadcrumb>\n </template>\n </v-text-field>\n <XDialog\n v-model=\"openedLocationDialog\"\n width=\"auto\"\n :title=\"t('vuetify.tree.select.location.label')\"\n >\n <template #activator>\n <x-btn id=\"change-page-location-button\" size=\"small\" color=\"secondary\">\n {{ t(\"vuetify.tree.select.location.label\") }}\n </x-btn>\n </template>\n <template #default>\n <XNavigationTree\n :current-page-reference=\"selectedPage\"\n :click-action=\"treeNodeClickAction\"\n ></XNavigationTree>\n </template>\n <template #footer>\n <XBtn variant=\"primary\" @click=\"openedLocationDialog = false\">\n {{ t(\"vuetify.tree.select.location.select\") }}\n </XBtn>\n </template>\n </XDialog>\n</template>\n\n<style scoped>\n.v-treeview {\n overflow: auto;\n}\n</style>\n"],"names":["cristal","inject","hierarchyResolver","referenceHandler","t","useI18n","messages","props","__props","model","_useModel","openedLocationDialog","ref","hierarchy","selectedPage","onMounted","treeNodeClickAction","node","SpaceReference"],"mappings":";;;;;;;;;;;;;;;;;;;;AAyCM,UAAAA,IAAsBC,EAAmB,SAAS,GAClDC,IAA2CF,EAC9C,aAAA,EACA,IAAmC,+BAA+B,EAClE,IAAI,GACDG,IAA0CH,EAC7C,aAAA,EACA,IAAmC,+BAA+B,EAClE,IAAI,GAED,EAAE,GAAAI,EAAE,IAAIC,EAAQ;AAAA,MACpBC,UAAAA;AAAAA,IAAA,CACD,GACKC,IAAQC,GACRC,IAAQC,iBAA4B,GAEpCC,IAAqCC,EAAI,EAAK,GAC9CC,IAA2CD,EAAI,EAAE;AACnD,QAAAE;AAEJ,IAAAC,EAAU,YAAY;AACpB,MAAAD,IAAeP,EAAM,sBACfE,EAAA,QAAQF,EAAM,qBAAsB,OAChCM,EAAA,QAAQ,MAAMX,EAAkB;AAAA,QACxCK,EAAM,qBAAsB;AAAA,MAC9B;AAAA,IAAA,CACD;AAED,mBAAeS,EAAoBC,GAA0B;AAC3D,MAAAH,IAAeX,EAAiB;AAAA,QAC9Bc,EAAK,SAAS,MAAMA,EAAK,SAAS,MAAM,SAAS,CAAC;AAAA,QAClD,IAAIC,EAAeD,EAAK,SAAS,MAAM,GAAGA,EAAK,SAAS,MAAM,MAAM,GAAG,EAAE,CAAC;AAAA,MAC5E,GACAR,EAAM,QAAQQ,EAAK,UACnBJ,EAAU,QAAQ,MAAMX,EAAkB,iBAAiBY,CAAY;AAAA,IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { defineComponent as s, mergeModels as m, useModel as d, computed as i, openBlock as p, createBlock as f, unref as y } from "vue";
|
|
2
|
+
import { t as c } from "./translations-k4crOAds.js";
|
|
3
|
+
import { useI18n as V } from "vue-i18n";
|
|
4
|
+
import { a as h } from "./index-BAakw3UY.js";
|
|
5
|
+
const g = /* @__PURE__ */ s({
|
|
6
|
+
__name: "x-text-field",
|
|
7
|
+
props: /* @__PURE__ */ m({
|
|
8
|
+
name: {},
|
|
9
|
+
label: {},
|
|
10
|
+
required: { type: Boolean },
|
|
11
|
+
autofocus: { type: Boolean },
|
|
12
|
+
modelValue: {},
|
|
13
|
+
help: {},
|
|
14
|
+
readonly: { type: Boolean }
|
|
15
|
+
}, {
|
|
16
|
+
modelValue: {},
|
|
17
|
+
modelModifiers: {}
|
|
18
|
+
}),
|
|
19
|
+
emits: ["update:modelValue"],
|
|
20
|
+
setup(l) {
|
|
21
|
+
const { t: n } = V({
|
|
22
|
+
messages: c
|
|
23
|
+
}), a = l, t = d(l, "modelValue"), u = i(() => {
|
|
24
|
+
const e = [];
|
|
25
|
+
return a.required && e.push((o) => o ? !0 : n("vuetify.text.input.mandatory")), e;
|
|
26
|
+
});
|
|
27
|
+
return (e, o) => (p(), f(y(h), {
|
|
28
|
+
modelValue: t.value,
|
|
29
|
+
"onUpdate:modelValue": o[0] || (o[0] = (r) => t.value = r),
|
|
30
|
+
label: e.label,
|
|
31
|
+
name: e.name,
|
|
32
|
+
autofocus: e.autofocus,
|
|
33
|
+
hint: e.help,
|
|
34
|
+
"persistent-hint": e.help !== void 0,
|
|
35
|
+
rules: u.value,
|
|
36
|
+
readonly: e.readonly
|
|
37
|
+
}, null, 8, ["modelValue", "label", "name", "autofocus", "hint", "persistent-hint", "rules", "readonly"]));
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
export {
|
|
41
|
+
g as default
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=x-text-field-2Sv6HUGW.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"x-text-field-
|
|
1
|
+
{"version":3,"file":"x-text-field-2Sv6HUGW.js","sources":["../src/vue/form/x-text-field.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport messages from \"../../translations\";\nimport { computed } from \"vue\";\nimport { useI18n } from \"vue-i18n\";\nimport { VTextField } from \"vuetify/components/VTextField\";\nimport type { TextFieldProps } from \"@xwiki/cristal-dsapi\";\n\nconst { t } = useI18n({\n messages,\n});\nconst props = defineProps<TextFieldProps>();\nconst input = defineModel<string>();\n\nconst rules = computed(() => {\n const rulesList = [];\n if (props.required) {\n rulesList.push((value: unknown) => {\n if (value) {\n return true;\n } else {\n return t(\"vuetify.text.input.mandatory\");\n }\n });\n }\n return rulesList;\n});\n</script>\n\n<template>\n <v-text-field\n v-model=\"input\"\n :label=\"label\"\n :name=\"name\"\n :autofocus=\"autofocus\"\n :hint=\"help\"\n :persistent-hint=\"help !== undefined\"\n :rules=\"rules\"\n :readonly=\"readonly\"\n ></v-text-field>\n</template>\n\n<style scoped></style>\n"],"names":["t","useI18n","messages","props","__props","input","_useModel","rules","computed","rulesList","value"],"mappings":";;;;;;;;;;;;;;;;;;;;AAOM,UAAA,EAAE,GAAAA,EAAE,IAAIC,EAAQ;AAAA,MACpBC,UAAAA;AAAAA,IAAA,CACD,GACKC,IAAQC,GACRC,IAAQC,EAAmBF,GAAA,YAAC,GAE5BG,IAAQC,EAAS,MAAM;AAC3B,YAAMC,IAAY,CAAC;AACnB,aAAIN,EAAM,YACEM,EAAA,KAAK,CAACC,MACVA,IACK,KAEAV,EAAE,8BAA8B,CAE1C,GAEIS;AAAA,IAAA,CACR;;;;;;;;;;;;;;"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"vuetify.file.input.mandatory": "Pflichtfeld",
|
|
3
|
-
"vuetify.text.input.mandatory": "Pflichtfeld"
|
|
3
|
+
"vuetify.text.input.mandatory": "Pflichtfeld",
|
|
4
|
+
"vuetify.tree.select.location.label": "Speicherort der Seite ändern",
|
|
5
|
+
"vuetify.tree.select.location.select": "Auswählen"
|
|
4
6
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"vuetify.file.input.mandatory": "Mandatory field",
|
|
3
|
-
"vuetify.text.input.mandatory": "Mandatory field"
|
|
3
|
+
"vuetify.text.input.mandatory": "Mandatory field",
|
|
4
|
+
"vuetify.tree.select.location.label": "Change Page Location",
|
|
5
|
+
"vuetify.tree.select.location.select": "Select"
|
|
4
6
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"vuetify.file.input.mandatory": "Champ obligatoire",
|
|
3
|
-
"vuetify.text.input.mandatory": "Champ obligatoire"
|
|
3
|
+
"vuetify.text.input.mandatory": "Champ obligatoire",
|
|
4
|
+
"vuetify.tree.select.location.label": "Changer l'emplacement de la page",
|
|
5
|
+
"vuetify.tree.select.location.select": "Sélectionner"
|
|
4
6
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xwiki/cristal-dsvuetify",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"license": "LGPL 2.1",
|
|
5
5
|
"author": "XWiki Org Community <contact@xwiki.org>",
|
|
6
6
|
"homepage": "https://cristal.xwiki.org/",
|
|
@@ -22,14 +22,16 @@
|
|
|
22
22
|
},
|
|
23
23
|
"main": "./dist/index.es.js",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"inversify": "6.2.
|
|
25
|
+
"inversify": "6.2.2",
|
|
26
26
|
"vue": "3.5.13",
|
|
27
|
-
"vue-i18n": "11.0
|
|
28
|
-
"vuetify": "3.7.
|
|
29
|
-
"@xwiki/cristal-api": "0.
|
|
30
|
-
"@xwiki/cristal-
|
|
31
|
-
"@xwiki/cristal-document-api": "0.
|
|
32
|
-
"@xwiki/cristal-
|
|
27
|
+
"vue-i18n": "11.1.0",
|
|
28
|
+
"vuetify": "3.7.11",
|
|
29
|
+
"@xwiki/cristal-model-api": "0.15.0",
|
|
30
|
+
"@xwiki/cristal-api": "0.15.0",
|
|
31
|
+
"@xwiki/cristal-document-api": "0.15.0",
|
|
32
|
+
"@xwiki/cristal-model-reference-api": "0.15.0",
|
|
33
|
+
"@xwiki/cristal-navigation-tree-api": "0.15.0",
|
|
34
|
+
"@xwiki/cristal-hierarchy-api": "0.15.0"
|
|
33
35
|
},
|
|
34
36
|
"peerDependencies": {
|
|
35
37
|
"reflect-metadata": "0.2.2"
|
|
@@ -38,10 +40,10 @@
|
|
|
38
40
|
"@vue/test-utils": "2.4.6",
|
|
39
41
|
"reflect-metadata": "0.2.2",
|
|
40
42
|
"typescript": "5.7.3",
|
|
41
|
-
"vite": "6.0
|
|
43
|
+
"vite": "6.1.0",
|
|
42
44
|
"vue-tsc": "2.2.0",
|
|
43
|
-
"@xwiki/cristal-
|
|
44
|
-
"@xwiki/cristal-
|
|
45
|
+
"@xwiki/cristal-dsapi": "0.15.0",
|
|
46
|
+
"@xwiki/cristal-dev-config": "0.15.0"
|
|
45
47
|
},
|
|
46
48
|
"scripts": {
|
|
47
49
|
"build": "pnpm compile",
|
|
@@ -26,7 +26,7 @@ import * as components from "vuetify/components";
|
|
|
26
26
|
import { VCol, VContainer, VRow, VTextField } from "vuetify/components";
|
|
27
27
|
|
|
28
28
|
import * as directives from "vuetify/directives";
|
|
29
|
-
import { mdi } from "vuetify/iconsets/mdi";
|
|
29
|
+
import { aliases, mdi } from "vuetify/iconsets/mdi-svg";
|
|
30
30
|
import { blue, blueGrey } from "vuetify/util/colors";
|
|
31
31
|
import type { DesignSystemLoader } from "@xwiki/cristal-api";
|
|
32
32
|
import type { App } from "vue";
|
|
@@ -56,6 +56,7 @@ export class VuetifyDesignSystemLoader implements DesignSystemLoader {
|
|
|
56
56
|
directives,
|
|
57
57
|
icons: {
|
|
58
58
|
defaultSet: "mdi",
|
|
59
|
+
aliases,
|
|
59
60
|
sets: {
|
|
60
61
|
mdi,
|
|
61
62
|
},
|
|
@@ -146,5 +147,10 @@ export class VuetifyDesignSystemLoader implements DesignSystemLoader {
|
|
|
146
147
|
"XCheckbox",
|
|
147
148
|
() => import("../vue/form/x-checkbox.vue"),
|
|
148
149
|
);
|
|
150
|
+
registerAsyncComponent(
|
|
151
|
+
app,
|
|
152
|
+
"XNavigationTreeSelect",
|
|
153
|
+
() => import("../vue/form/x-navigation-tree-select.vue"),
|
|
154
|
+
);
|
|
149
155
|
}
|
|
150
156
|
}
|
package/src/translations.ts
CHANGED
|
@@ -18,9 +18,13 @@
|
|
|
18
18
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
+
import de from "../langs/translation-de.json";
|
|
21
22
|
import en from "../langs/translation-en.json";
|
|
23
|
+
import fr from "../langs/translation-fr.json";
|
|
22
24
|
|
|
23
25
|
const translations: Record<string, Record<string, string>> = {
|
|
24
26
|
en,
|
|
27
|
+
fr,
|
|
28
|
+
de,
|
|
25
29
|
};
|
|
26
30
|
export default translations;
|
package/src/vue/css/style.css
CHANGED
package/src/vue/form/x-form.vue
CHANGED
|
@@ -8,10 +8,14 @@ function submit() {
|
|
|
8
8
|
|
|
9
9
|
<template>
|
|
10
10
|
<v-form @submit.prevent="submit">
|
|
11
|
-
<
|
|
12
|
-
<slot></slot>
|
|
13
|
-
</v-container>
|
|
11
|
+
<slot></slot>
|
|
14
12
|
</v-form>
|
|
15
13
|
</template>
|
|
16
14
|
|
|
17
|
-
<style scoped
|
|
15
|
+
<style scoped>
|
|
16
|
+
.v-form {
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
gap: var(--cr-spacing-x-small);
|
|
20
|
+
}
|
|
21
|
+
</style>
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
See the LICENSE file distributed with this work for additional
|
|
3
|
+
information regarding copyright ownership.
|
|
4
|
+
|
|
5
|
+
This is free software; you can redistribute it and/or modify it
|
|
6
|
+
under the terms of the GNU Lesser General Public License as
|
|
7
|
+
published by the Free Software Foundation; either version 2.1 of
|
|
8
|
+
the License, or (at your option) any later version.
|
|
9
|
+
|
|
10
|
+
This software is distributed in the hope that it will be useful,
|
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
13
|
+
Lesser General Public License for more details.
|
|
14
|
+
|
|
15
|
+
You should have received a copy of the GNU Lesser General Public
|
|
16
|
+
License along with this software; if not, write to the Free
|
|
17
|
+
Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
|
18
|
+
02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
|
19
|
+
-->
|
|
20
|
+
<script setup lang="ts">
|
|
21
|
+
import messages from "../../translations";
|
|
22
|
+
import XBreadcrumb from "../x-breadcrumb.vue";
|
|
23
|
+
import { SpaceReference } from "@xwiki/cristal-model-api";
|
|
24
|
+
import { inject, onMounted, ref } from "vue";
|
|
25
|
+
import { useI18n } from "vue-i18n";
|
|
26
|
+
import { VTextField } from "vuetify/components/VTextField";
|
|
27
|
+
import type { CristalApp } from "@xwiki/cristal-api";
|
|
28
|
+
import type { NavigationTreeSelectProps } from "@xwiki/cristal-dsapi";
|
|
29
|
+
import type {
|
|
30
|
+
PageHierarchyItem,
|
|
31
|
+
PageHierarchyResolver,
|
|
32
|
+
PageHierarchyResolverProvider,
|
|
33
|
+
} from "@xwiki/cristal-hierarchy-api";
|
|
34
|
+
import type { DocumentReference } from "@xwiki/cristal-model-api";
|
|
35
|
+
import type {
|
|
36
|
+
ModelReferenceHandler,
|
|
37
|
+
ModelReferenceHandlerProvider,
|
|
38
|
+
} from "@xwiki/cristal-model-reference-api";
|
|
39
|
+
import type { NavigationTreeNode } from "@xwiki/cristal-navigation-tree-api";
|
|
40
|
+
import type { Ref } from "vue";
|
|
41
|
+
|
|
42
|
+
const cristal: CristalApp = inject<CristalApp>("cristal")!;
|
|
43
|
+
const hierarchyResolver: PageHierarchyResolver = cristal
|
|
44
|
+
.getContainer()
|
|
45
|
+
.get<PageHierarchyResolverProvider>("PageHierarchyResolverProvider")
|
|
46
|
+
.get()!;
|
|
47
|
+
const referenceHandler: ModelReferenceHandler = cristal
|
|
48
|
+
.getContainer()
|
|
49
|
+
.get<ModelReferenceHandlerProvider>("ModelReferenceHandlerProvider")
|
|
50
|
+
.get()!;
|
|
51
|
+
|
|
52
|
+
const { t } = useI18n({
|
|
53
|
+
messages,
|
|
54
|
+
});
|
|
55
|
+
const props = defineProps<NavigationTreeSelectProps>();
|
|
56
|
+
const model = defineModel<SpaceReference>();
|
|
57
|
+
|
|
58
|
+
const openedLocationDialog: Ref<boolean> = ref(false);
|
|
59
|
+
const hierarchy: Ref<Array<PageHierarchyItem>> = ref([]);
|
|
60
|
+
let selectedPage: DocumentReference | undefined;
|
|
61
|
+
|
|
62
|
+
onMounted(async () => {
|
|
63
|
+
selectedPage = props.currentPageReference;
|
|
64
|
+
model.value = props.currentPageReference!.space;
|
|
65
|
+
hierarchy.value = await hierarchyResolver.getPageHierarchy(
|
|
66
|
+
props.currentPageReference!.space!,
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
async function treeNodeClickAction(node: NavigationTreeNode) {
|
|
71
|
+
selectedPage = referenceHandler.createDocumentReference(
|
|
72
|
+
node.location.names[node.location.names.length - 1],
|
|
73
|
+
new SpaceReference(node.location.wiki, ...node.location.names.slice(0, -1)),
|
|
74
|
+
);
|
|
75
|
+
model.value = node.location;
|
|
76
|
+
hierarchy.value = await hierarchyResolver.getPageHierarchy(selectedPage);
|
|
77
|
+
}
|
|
78
|
+
</script>
|
|
79
|
+
|
|
80
|
+
<template>
|
|
81
|
+
<v-text-field
|
|
82
|
+
:label="label"
|
|
83
|
+
:hint="help"
|
|
84
|
+
:persistent-hint="help !== undefined"
|
|
85
|
+
:active="hierarchy.length > 0"
|
|
86
|
+
readonly
|
|
87
|
+
>
|
|
88
|
+
<template #default>
|
|
89
|
+
<XBreadcrumb :items="hierarchy"></XBreadcrumb>
|
|
90
|
+
</template>
|
|
91
|
+
</v-text-field>
|
|
92
|
+
<XDialog
|
|
93
|
+
v-model="openedLocationDialog"
|
|
94
|
+
width="auto"
|
|
95
|
+
:title="t('vuetify.tree.select.location.label')"
|
|
96
|
+
>
|
|
97
|
+
<template #activator>
|
|
98
|
+
<x-btn id="change-page-location-button" size="small" color="secondary">
|
|
99
|
+
{{ t("vuetify.tree.select.location.label") }}
|
|
100
|
+
</x-btn>
|
|
101
|
+
</template>
|
|
102
|
+
<template #default>
|
|
103
|
+
<XNavigationTree
|
|
104
|
+
:current-page-reference="selectedPage"
|
|
105
|
+
:click-action="treeNodeClickAction"
|
|
106
|
+
></XNavigationTree>
|
|
107
|
+
</template>
|
|
108
|
+
<template #footer>
|
|
109
|
+
<XBtn variant="primary" @click="openedLocationDialog = false">
|
|
110
|
+
{{ t("vuetify.tree.select.location.select") }}
|
|
111
|
+
</XBtn>
|
|
112
|
+
</template>
|
|
113
|
+
</XDialog>
|
|
114
|
+
</template>
|
|
115
|
+
|
|
116
|
+
<style scoped>
|
|
117
|
+
.v-treeview {
|
|
118
|
+
overflow: auto;
|
|
119
|
+
}
|
|
120
|
+
</style>
|
|
@@ -31,11 +31,14 @@ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
|
|
31
31
|
*/
|
|
32
32
|
import { inject, onBeforeMount, ref, watch } from "vue";
|
|
33
33
|
import { VTreeview } from "vuetify/labs/VTreeview";
|
|
34
|
-
import type { CristalApp
|
|
34
|
+
import type { CristalApp } from "@xwiki/cristal-api";
|
|
35
35
|
import type { DocumentService } from "@xwiki/cristal-document-api";
|
|
36
|
-
import type {
|
|
36
|
+
import type { NavigationTreeProps } from "@xwiki/cristal-dsapi";
|
|
37
|
+
import type {
|
|
38
|
+
DocumentReference,
|
|
39
|
+
SpaceReference,
|
|
40
|
+
} from "@xwiki/cristal-model-api";
|
|
37
41
|
import type {
|
|
38
|
-
NavigationTreeNode,
|
|
39
42
|
NavigationTreeSource,
|
|
40
43
|
NavigationTreeSourceProvider,
|
|
41
44
|
} from "@xwiki/cristal-navigation-tree-api";
|
|
@@ -49,8 +52,6 @@ type TreeItem = {
|
|
|
49
52
|
_location: SpaceReference;
|
|
50
53
|
};
|
|
51
54
|
|
|
52
|
-
type OnClickAction = (node: NavigationTreeNode) => void;
|
|
53
|
-
|
|
54
55
|
const cristal: CristalApp = inject<CristalApp>("cristal")!;
|
|
55
56
|
const documentService: DocumentService = cristal
|
|
56
57
|
.getContainer()
|
|
@@ -66,10 +67,7 @@ const activatedNodes: Ref<Array<string>> = ref(new Array<string>());
|
|
|
66
67
|
const expandedNodes: Ref<Array<string>> = ref(new Array<string>());
|
|
67
68
|
var isExpanding: boolean = false;
|
|
68
69
|
|
|
69
|
-
const props = defineProps<
|
|
70
|
-
clickAction?: OnClickAction;
|
|
71
|
-
currentPage?: PageData;
|
|
72
|
-
}>();
|
|
70
|
+
const props = defineProps<NavigationTreeProps>();
|
|
73
71
|
|
|
74
72
|
onBeforeMount(async () => {
|
|
75
73
|
for (const node of await treeSource.getChildNodes("")) {
|
|
@@ -87,14 +85,16 @@ onBeforeMount(async () => {
|
|
|
87
85
|
documentService.registerDocumentChangeListener("update", onDocumentUpdate);
|
|
88
86
|
});
|
|
89
87
|
|
|
90
|
-
watch(() => props.
|
|
88
|
+
watch(() => props.currentPageReference, expandTree);
|
|
91
89
|
|
|
92
90
|
// TODO: reduce the number of statements in the following method and reactivate the disabled eslint rule.
|
|
93
91
|
// eslint-disable-next-line max-statements
|
|
94
92
|
async function expandTree() {
|
|
95
|
-
if (props.
|
|
93
|
+
if (props.currentPageReference && !isExpanding) {
|
|
96
94
|
isExpanding = true;
|
|
97
|
-
const newExpandedNodes = treeSource.getParentNodesId(
|
|
95
|
+
const newExpandedNodes = treeSource.getParentNodesId(
|
|
96
|
+
props.currentPageReference,
|
|
97
|
+
);
|
|
98
98
|
let i;
|
|
99
99
|
let currentNodes = rootNodes.value;
|
|
100
100
|
for (i = 0; i < newExpandedNodes.length - 1; i++) {
|
|
@@ -163,7 +163,7 @@ function clearSelection() {
|
|
|
163
163
|
|
|
164
164
|
// TODO: reduce the number of statements in the following method and reactivate the disabled eslint rule.
|
|
165
165
|
// eslint-disable-next-line max-statements
|
|
166
|
-
async function onDocumentDelete(page:
|
|
166
|
+
async function onDocumentDelete(page: DocumentReference) {
|
|
167
167
|
const parents = treeSource.getParentNodesId(page);
|
|
168
168
|
let currentItem: TreeItem | undefined = undefined;
|
|
169
169
|
let currentItemChildren: TreeItem[] | undefined = rootNodes.value;
|
|
@@ -192,7 +192,7 @@ async function onDocumentDelete(page: PageData) {
|
|
|
192
192
|
|
|
193
193
|
// TODO: reduce the number of statements in the following method and reactivate the disabled eslint rule.
|
|
194
194
|
// eslint-disable-next-line max-statements
|
|
195
|
-
async function onDocumentUpdate(page:
|
|
195
|
+
async function onDocumentUpdate(page: DocumentReference) {
|
|
196
196
|
const parents = treeSource.getParentNodesId(page);
|
|
197
197
|
let currentParent: string | undefined = undefined;
|
|
198
198
|
let currentItems: TreeItem[] | undefined = rootNodes.value;
|
|
@@ -238,7 +238,9 @@ async function onDocumentUpdate(page: PageData) {
|
|
|
238
238
|
const newItems = await treeSource.getChildNodes(
|
|
239
239
|
currentParent ? currentParent : "",
|
|
240
240
|
);
|
|
241
|
-
const currentPageParents = treeSource.getParentNodesId(
|
|
241
|
+
const currentPageParents = treeSource.getParentNodesId(
|
|
242
|
+
props.currentPageReference,
|
|
243
|
+
);
|
|
242
244
|
newItemsLoop: for (const newItem of newItems) {
|
|
243
245
|
for (const i of currentItems!.keys()) {
|
|
244
246
|
if (newItem.id == currentItems![i].id) {
|
|
@@ -312,16 +314,4 @@ async function onDocumentUpdate(page: PageData) {
|
|
|
312
314
|
:deep(.v-list-item--link) {
|
|
313
315
|
cursor: default;
|
|
314
316
|
}
|
|
315
|
-
/*TODO: This section needs to be removed when the oficial fix is released on Vuetify
|
|
316
|
-
https://github.com/vuetifyjs/vuetify/issues/20421#event-16001533054
|
|
317
|
-
START FIX
|
|
318
|
-
*/
|
|
319
|
-
:deep(.v-treeview-item:not(.v-list-group__header)) {
|
|
320
|
-
padding-inline-start: calc(39px + 6px) !important;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
:deep(.v-treeview-item .v-list-item__spacer) {
|
|
324
|
-
width: 4px !important;
|
|
325
|
-
}
|
|
326
|
-
/*END FIX*/
|
|
327
317
|
</style>
|