Changes for page Helpers

Last modified by Benjamin Fischer on 2025/06/17 11:57

From version 1.1
edited by Benjamin Fischer
on 2025/05/15 13:30
Change comment: There is no comment for this version
To version 1.15
edited by Benjamin Fischer
on 2025/05/15 16:48
Change comment: There is no comment for this version

Summary

Details

XWiki.JavaScriptExtension[0]
Caching policy
... ... @@ -1,0 +1,1 @@
1 +default
Code
... ... @@ -1,0 +1,96 @@
1 +const livetableRowHook = {};
2 +
3 +((() => {
4 + const tagCols = {};
5 +
6 + document.observe('xwiki:livetable:loading', () => {
7 + for (const tab of document.querySelectorAll(".xwiki-livetable")) {
8 + const tableId = tab.id;
9 + if (!tableId) continue;
10 +
11 + // coulmn data sources
12 + const conf = JSON.parse(tab.dataset.settings);
13 +
14 + tagCols[tableId] = (conf.columnDescriptors.tags ?? { aux: [] }).aux ?? [["Tags", true]];
15 + tagCols[tableId].forEach(([name], i) => {
16 + const cn = `tags-${i}`;
17 + conf.columns.splice(conf.columns.indexOf("tags"), 1, cn);
18 + conf.columnDescriptors[cn] = {
19 + displayName: name,
20 + headerClass: "tagsCol",
21 + html: true,
22 + sortable: false,
23 + };
24 + });
25 + tab.dataset.settings = JSON.stringify(conf);
26 +
27 + // column headers
28 + tab.querySelectorAll(".xwiki-livetable-display-header .tagsCol").forEach(
29 + (v, i) => v.textContent = tagCols[tableId][i][0]
30 + );
31 +
32 + // filter fields
33 + tab.querySelectorAll(".xwiki-livetable-display-header-filter input[type=text]").forEach(
34 + v => (v.placeholder = "Filter ...");
35 + );
36 +
37 + // column tooltips
38 + tab.querySelectorAll(".xwiki-livetable-display-header-text").forEach(
39 + el => {
40 + const t = el.textContent.trim();
41 + const c = conf.columnDescriptors[t]?.tooltip;
42 + if (c) {
43 + el.title = t;
44 + el.dataset.content = c;
45 + el.dataset.toggle = "popover";
46 + el.dataset.placement = "top";
47 + }
48 + }
49 + )
50 +
51 + // handle clicks for tags
52 + tab.getElementsByClassName("xwiki-livetable-display-body")[0].addEventListener("click", ev => {
53 + if (ev.button) return; // only left click
54 + if (ev.target.nodeName !== "SPAN") return;
55 + if (!ev.target.classList.contains("ltTag")) return;
56 + const tag = ev.target.textContent;
57 + ev.preventDefault();
58 + const lt = tab.__liveTable;
59 + const st = lt.tagCloud.selectedTags;
60 + if (tag in st) delete st[tag];
61 + else st[tag] = {};
62 + lt.tags = Object.keys(st);
63 + lt.clearCache();
64 + lt.showRows(1, lt.limit);
65 + });
66 +
67 + }
68 + });
69 +
70 + document.observe("xwiki:livetable:receivedEntries", ({ memo: { data, tableId } }) => {
71 + const rf = livetableRowHook[tableId];
72 + for (const row of data.rows) {
73 + if (rf) rf(row);
74 +
75 + // tags
76 + const tags = new Set(row.tags_value.slice(1, -1).split(", "));
77 + tagCols[tableId]?.forEach(([name, ...want], i) =>
78 + row[`tags-${i}`] = (
79 + want[0] === true
80 + ? Array.from(tags)
81 + : want.filter(tag => tags.delete(tag))
82 + ).sort().map(tag => `<span class="ltTag" style="cursor:pointer;white-space:nowrap;">${tag}</span>`).join(", ")
83 + );
84 + }
85 + });
86 +
87 + livetableRowHook.jobs = row => {
88 + const a = new Element("a", { href: row.link });
89 + a.innerHTML = `<b class="wikiexternallink">${row.doc_title}</b>`;
90 + row.doc_title = a.outerHTML;
91 +
92 + row.doc_date = row.doc_date.split(" ")[0];
93 + };
94 +
95 +})());
96 +
Name
... ... @@ -1,0 +1,1 @@
1 +Global Helpers
Parse content
... ... @@ -1,0 +1,1 @@
1 +No
Use this extension
... ... @@ -1,0 +1,1 @@
1 +always