diff --git a/src/config.json b/src/config.json index 511510749233da02e7452d8e86f14f17544617da..0c6dc1dfe4b5839abe92f447489133637279cd4f 100644 --- a/src/config.json +++ b/src/config.json @@ -90,8 +90,6 @@ "user.firstname", "email" ], - "searchKeys": [ - "email" - ] + "searchKeys": [] } } diff --git a/src/events/viewEvent.js b/src/events/viewEvent.js index 2398b4721098cf941bbbaf091bf7de503c5bb5f8..7e9e7d4c7f523058958ce4e9a0780cdcf9eb5db2 100644 --- a/src/events/viewEvent.js +++ b/src/events/viewEvent.js @@ -19,57 +19,41 @@ import { ResourceHandler } from '../auth'; const viewLayout = [ { - '.eventViewContainer': { - display: 'grid', - 'grid-template-columns': '40% 55%', - 'grid-gap': '50px', - }, - '.propertyTitle': { - color: 'rgba(0, 0, 0, 0.54)', - }, - '.propertyText': { - color: 'rgba(0, 0, 0, 0.87)', - }, - '.propertyLangIndicator': { - width: '30px', - height: '20px', - float: 'left', - 'background-color': 'rgb(031,045,084)', - 'border-radius': '10px', - 'text-align': 'center', - 'line-height': '20px', - color: 'rgb(255,255,255)', - 'margin-right': '10px', - 'font-size' : '11px', - }, - '.eventInfoCard': { - padding: '10px', - 'font-size': '15sp', - }, - '.eventViewLeft': { - 'grid-column': 1, - }, - '.eventViewRight': { - 'grid-column': 2, - }, - '.eventViewRight h4': { - 'margin-top': '0px', - } - }, - { '.eventViewContainer': { - display: 'grid', - 'grid-template-columns': '40% 60%', - 'grid-gap': '50px', + display: 'grid', + 'grid-template-columns': '40% 55%', + 'grid-gap': '50px', + }, + '.propertyTitle': { + color: 'rgba(0, 0, 0, 0.54)', + }, + '.propertyText': { + color: 'rgba(0, 0, 0, 0.87)', + }, + '.propertyLangIndicator': { + width: '30px', + height: '20px', + float: 'left', + 'background-color': 'rgb(031,045,084)', + 'border-radius': '10px', + 'text-align': 'center', + 'line-height': '20px', + color: 'rgb(255,255,255)', + 'margin-right': '10px', + 'font-size' : '11px', + }, + '.eventInfoCard': { + padding: '10px', + 'font-size': '15sp', }, '.eventViewLeft': { - 'grid-column': 1, + 'grid-column': 1, }, '.eventViewRight': { - 'grid-column': 2, + 'grid-column': 2, }, '.eventViewRight h4': { - 'margin-top': '2px', + 'margin-top': '0px', }, }, ]; @@ -77,6 +61,8 @@ styler.add('eventView', viewLayout); class PropertyInfo { view({ attrs: { title, de, en } }) { + //const text = ''; + if(de && en) { return m('div', m('p.propertyTitle', {style: { 'margin-top': '10px', 'margin-bottom': '3px' } }, [title]), @@ -111,10 +97,18 @@ class PropertyInfo { class ParticipantsTable { constructor({ attrs: { where } }) { - this.ctrl = new DatalistController('eventsignups', { - embedded: { user: 1 }, - where, - }, signupConfig.tableKeys); + this.ctrl = new DatalistController( + 'eventsignups', { + embedded: { user: 1 }, + where, + }, + [ + 'email', + 'user.firstname', + 'user.lastname', + ], + false, + ); } getItemData(data) { @@ -394,4 +388,4 @@ export default class viewEvent extends ItemView { ]) } -} \ No newline at end of file +} diff --git a/src/listcontroller.js b/src/listcontroller.js index bc759b307e92a02d5522e68b65014274b5bb75de..1d871958e6b962ce77e83a49e3d59d2bfb16c5f2 100644 --- a/src/listcontroller.js +++ b/src/listcontroller.js @@ -2,10 +2,16 @@ import Stream from 'mithril/stream'; import { ResourceHandler } from './auth'; export default class DatalistController { - constructor(resource, query = {}, searchKeys = false) { - this.handler = new ResourceHandler(resource, searchKeys); + constructor(resource, query = {}, searchKeys = false, onlineSearch = true) { + this.onlineSearch = onlineSearch; + if (onlineSearch) { + this.handler = new ResourceHandler(resource, searchKeys); + } else { + this.handler = new ResourceHandler(resource, false); + this.clientSearchKeys = searchKeys ||Â []; + } this.query = query || {}; - this.items = []; + this.search = null; // state pointer that is counted up every time the table is refreshed so // we can tell infinite scroll that the data-version has changed. this.stateCounter = Stream(0); @@ -27,25 +33,66 @@ export default class DatalistController { getPageData(pageNum) { // for some reason this is called before the object is instantiated. // check this and return nothing - const query = {}; - Object.keys(this.query).forEach((key) => { query[key] = this.query[key]; }); + const query = Object.assign({}, this.query); query.max_results = 10; query.page = pageNum; return new Promise((resolve, reject) => { this.handler.get(query).then((data) => { - resolve(data._items); + // If onlineSearch is false, we filter the page-results at the client + // because the API would not understand the search pattern, e.g. for + // embedded keys like user.firstname + if (!this.onlineSearch && this.clientSearchKeys.length > 0 && this.search) { + const response = []; + // We go through all response items and will add them to response if + // they match the query. + data._items.forEach((item) => { + // Try every search Key seperately, such that any match with any + // key is sufficient + this.clientSearchKeys.some((key) => { + if (key.match(/.*\..*/)) { + // traverse the key, this is a key pointing to a sub-object + let intermediateObject = Object.assign({}, item); + key.split('.').forEach((subKey) => { + intermediateObject = intermediateObject[subKey]; + }); + if (intermediateObject.includes(this.search)) { + response.push(item); + // return true to end the search of this object, it is already + // matched + return true; + } + } else if (item[key] && item[key].includes(this.search)) { + response.push(item); + // return true to end the search of this object, it is already + // matched + return true; + } + return false; + }); + }); + resolve(response); + } else { + resolve(data._items); + } }); }); } setSearch(search) { - this.query.search = search; - this.refresh(); + if (this.onlineSearch) { + this.search = search; + this.query.search = search; + this.refresh(); + } else if (this.clientSearchKeys.length > 0) { + this.search = search; + this.refresh(); + } } setQuery(query) { this.query = query; + this.query.search = this.search; this.refresh(); } }