Failed to execute template. Cause: [Access denied when checking [script] access to [xwiki:Collaboratory.UX.HbpSkin.WebHome] for user [xwiki:XWiki.Admin]]. Click on this message for details.

Context Search - HBP Wiki

IAM21 instance, do not create collab nor modify a team, your changes will be lost


Wiki source code of Context Search

Version 26.70 by bougault on 2022/11/17 10:15

Hide last authors
bougault 1.1 1 {{html clean="false"}}
bougault 26.64 2 <!--
bougault 26.65 3 !!! POC. Code would must be reviewed / optimized and packaged for use in production !!!
bougault 26.64 4 -->
bougault 26.45 5 <script type="module">
bougault 26.70 6 import {LitElement, html} from 'https://cdn.jsdelivr.net/gh/lit/dist@2/core/lit-core.min.js';
7 window.addEventListener('DOMContentLoaded', function() {
8
bougault 26.46 9 class UnifiedSearch extends LitElement {
bougault 26.65 10 /*
bougault 26.47 11 static properties = {
bougault 26.49 12 searchText: { type: String },
bougault 26.50 13 favoritesFilter: { type: Boolean },
14 administratorFilter: { type: Boolean },
15 editorFilter: { type: Boolean },
16 viewerFilter: { type: Boolean },
17 publicFilter: { type: Boolean },
18 privateFilter: { type: Boolean },
bougault 26.47 19 }
bougault 26.65 20 */
bougault 26.49 21 constructor() {
22 super();
23 this.searchText = "";
bougault 26.68 24 this.administrator = false;
25 this.editor = false;
26 this.viewer = false;
27 this.rolesFilter = [];
bougault 26.69 28 this.filterUrl = new URL(`${document.location.origin}/rest/v1/collabs?search=&offset=0&orderField=title&order=asc&favorite=true&roles=`);
bougault 26.49 29 }
bougault 26.68 30 toggleRoleFilter(roleName) {
31 if(this.rolesFilter.indexOf(roleName) == -1) {
32 this.rolesFilter.push(roleName);
33 } else {
34 this.rolesFilter.filter(role => role !== roleName);
35 }
bougault 26.69 36 this[roleName] = !this[roleName];
37 this.filterUrl.searchParams.set('roles', this.rolesFilter.join("+"));
bougault 26.68 38 }
bougault 26.47 39 setSearchText(e) {
40 this.searchText = e.target.value;
41 }
42 handleSearch() {
43 console.log(this.searchText);
44 }
bougault 26.64 45 buildFilter() {
46 //https://wiki-dev.ebrains.eu/rest/v1/collabs?search=&offset=0&orderField=title&order=asc&favorite=true&roles=
47 }
bougault 26.46 48 render() {
bougault 26.49 49 return html`
50 <div>
51 <div>
52 <input @change="${this.setSearchText}" type="text" placeholder="Search..." />
53 <button @click="${this.handleSearch}">Search</button>
54 </div>
bougault 26.61 55 <div>
bougault 26.68 56 <label><input type="checkbox" @change="${() => this.toggleRoleFilter('administrator')}" .checked="${this.administratorFilter}"/> Administrator</label>
57 <label><input type="checkbox" @change="${() => this.toggleRoleFilter('editor')}" .checked="${this.editorFilter}"/> Editor</label>
58 <label><input type="checkbox" @change="${() => this.toggleRoleFilter('viewer')}" .checked="${this.viewerFilter}"/> Viewer</label>
bougault 26.61 59 </div>
bougault 26.49 60 </div>
61 `
bougault 26.46 62 }
63 }
64 customElements.define('clb-unified-search', UnifiedSearch);
bougault 26.70 65
66 function handleXWikiSearch(space, callback) {
67 require(['jquery'], function($) {
68 var solrServiceURL = new XWiki.Document('SuggestSolrService', 'XWiki').getURL('get');
69 const contextSearchButton = document.getElementById("context-search-button");
70 const xwikiSpace = space ? `.${space}` : '';
71 contextSearchButton.addEventListener('click', function() {
72 $.post(solrServiceURL, {
73 outputSyntax: 'plain',
74 media: 'json',
75 query: [
76 'q="__INPUT__"~100',
77 'fq=type:DOCUMENT',
78 `fq=space:Collabs${xwikiSpace}.*`
79 ].join('\n'),
80 input: $('#context-search-text').val()
81 }).then(res => {
82 if(callback) {
83 callback(res).then(results => {
84 contextSearchResponse.innerText = JSON.stringify(results, null, 2);
85 })
86 } else {
87 contextSearchResponse.innerText = JSON.stringify(res, null, 2);
88 }
89 });
90 });
91 });
92 }
93 });
bougault 26.45 94 </script>
bougault 1.1 95
bougault 26.46 96 <clb-unified-search></clb-unified-search>
bougault 26.62 97 <!--
bougault 1.1 98 <select id="context-search-type">
99 <option value="all">All</option>
100 <option value="collabs">Collabs</option>
101 <option value="current-collab">Current Collab</option>
102 </select>
bougault 26.37 103 <input type="text" id="context-search-text" />
104 <button id="context-search-button" class="btn btn-primary">Search</button>
bougault 26.36 105 <div class="form-group">
bougault 26.37 106 <label>
107 <input type="checkbox" data-role-filter="administrator"> Administrator
108 </label>
109 <label>
110 <input type="checkbox" data-role-filter="editor"> Editor
111 </label>
bougault 26.36 112 </div>
bougault 1.1 113
bougault 26.37 114
bougault 2.2 115 <pre id="context-search-response"></pre>
116 <script>
117 window.addEventListener('DOMContentLoaded', function() {
bougault 26.30 118 const filters = {
119 search: '',
120 offset: 0,
121 orderField: 'title',
122 order: 'asc',
123 favorite: false,
124 roles: [] // to be joined as administrator+editor+viewer
125 };
126
127 function addRole(role) {
128 if(filters.roles.indexOf(role) == -1) {
129 filters.roles.push(role);
130 }
131 }
132
133 function removeRole(role) {
bougault 26.39 134 filters.roles = filters.roles.filter(r => r !== role)
bougault 26.30 135 }
136
bougault 26.34 137 const filterInputs = document.querySelectorAll('input[data-role-filter]');
bougault 26.40 138
bougault 26.32 139 filterInputs.forEach(function(filterIpt) {
bougault 26.35 140 filterIpt.addEventListener('click', function() {
bougault 26.30 141 const role = this.getAttribute('data-role-filter');
142 if(this.checked) {
143 addRole(role);
144 } else {
145 removeRole(role);
146 }
bougault 26.42 147 runFilteredRequest();
bougault 26.30 148 })
149 });
150
bougault 26.42 151 function runFilteredRequest() {
bougault 26.43 152 const urlParams = new URLSearchParams();
bougault 26.44 153 const tmpFilters = filters;
154 tmpFilters.roles = tmpFilters.roles.join("+");
155 for(filter in tmpFilters) {
156 urlParams.set(filter, tmpFilters[filter]);
bougault 26.41 157 }
bougault 26.43 158 console.log(urlParams);
bougault 26.41 159 }
bougault 26.30 160 // https://wiki-dev.ebrains.eu/rest/v1/collabs?search=&offset=0&orderField=title&order=asc&favorite=false&roles=administrator
bougault 2.2 161 const contextSearchType = document.getElementById("context-search-type");
162 const contextSearchText = document.getElementById("context-search-text");
163 const contextSearchResponse = document.getElementById("context-search-response");
164 const contextSearchButton = document.getElementById("context-search-button");
165 contextSearchButton.addEventListener('click', function() {
166 const context = contextSearchType.options[contextSearchType.selectedIndex].value;
bougault 2.3 167 const term = contextSearchText.value;
168 switch(context) {
169 case 'collabs':
170 document.location.href = `/bin/view/Collabs/#search=${term}`;
171 break;
172 case 'current-collab':
bougault 19.1 173 handleXWikiSearch('bougaultx');
bougault 2.3 174 break
175 default:
bougault 26.40 176 handleXWikiSearch('')
bougault 2.3 177 }
178
bougault 2.2 179 });
bougault 26.12 180 function handleXWikiSearch(space, callback) {
bougault 26.2 181 require(['jquery'], function($) {
182 var solrServiceURL = new XWiki.Document('SuggestSolrService', 'XWiki').getURL('get');
183 const contextSearchButton = document.getElementById("context-search-button");
184 const xwikiSpace = space ? `.${space}` : '';
185 contextSearchButton.addEventListener('click', function() {
186 $.post(solrServiceURL, {
187 outputSyntax: 'plain',
188 media: 'json',
189 query: [
190 'q="__INPUT__"~100',
191 'fq=type:DOCUMENT',
192 `fq=space:Collabs${xwikiSpace}.*`
193 ].join('\n'),
194 input: $('#context-search-text').val()
195 }).then(res => {
bougault 26.12 196 if(callback) {
197 callback(res).then(results => {
198 contextSearchResponse.innerText = JSON.stringify(results, null, 2);
199 })
200 } else {
201 contextSearchResponse.innerText = JSON.stringify(res, null, 2);
202 }
bougault 26.2 203 });
204 });
bougault 23.1 205 });
bougault 26.2 206 }
bougault 26.11 207 function applyAdministratorFilter(results) {
bougault 26.12 208 return new Promise((resolve, reject) => {
bougault 26.22 209 //fetch("/rest/v1/collabs?roles=administrator")
210 fetch("/rest/v1/collabs?search=&offset=0&orderField=title&order=asc&favorite=false&roles=administrator")
bougault 26.12 211 .then(res => res.json())
bougault 26.14 212 .then(collabs => {
213 const spaces = collabs.map(collab => `Collabs.${collab.name}`);
bougault 26.25 214 const filtered = results.filter(result => spaces.some(space => result.space.startsWith(space)));
bougault 26.18 215 resolve(filtered);
bougault 26.12 216 })
217
218 })
bougault 26.2 219 }
220 });
bougault 2.2 221 </script>
bougault 26.62 222 -->
bougault 1.1 223 {{/html}}