Global search development

* search input
* parse query with operators
This commit is contained in:
John R. Supplee 2021-01-10 21:52:25 +02:00
parent 4e8ee8eb86
commit 5913a4af1b
4 changed files with 272 additions and 0 deletions

View file

@ -0,0 +1,37 @@
template(name="globalSearchHeaderBar")
h1
i.fa.fa-search
| {{_ 'globalSearch-title'}}
template(name="globalSearchModalTitle")
h2
i.fa.fa-keyboard-o
| {{_ 'globalSearch-title'}}
template(name="globalSearch")
if isPageReady.get
.wrapper
form.js-search-query-form
input(type="text" name="searchQuery" placeholder="{{_ 'search-example'}}" autofocus dir="auto")
else
+spinner
template(name="globalSearchViewChangePopup")
ul.pop-over-list
li
with "globalSearchViewChange-choice-me"
a.js-due-cards-view-me
i.fa.fa-user.colorful
| {{_ 'globalSearchViewChange-choice-me'}}
if $eq Utils.globalSearchView "me"
i.fa.fa-check
li
with "globalSearchViewChange-choice-all"
a.js-due-cards-view-all
i.fa.fa-users.colorful
| {{_ 'globalSearchViewChange-choice-all'}}
span.sub-name
+viewer
| {{_ 'globalSearchViewChange-choice-all-description' }}
if $eq Utils.globalSearchView "all"
i.fa.fa-check

View file

@ -0,0 +1,148 @@
const subManager = new SubsManager();
BlazeComponent.extendComponent({
events() {
return [
{
'click .js-due-cards-view-change': Popup.open('globalSearchViewChange'),
},
];
},
}).register('globalSearchHeaderBar');
Template.globalSearch.helpers({
userId() {
return Meteor.userId();
},
});
BlazeComponent.extendComponent({
events() {
return [
{
'click .js-due-cards-view-me'() {
Utils.setDueCardsView('me');
Popup.close();
},
'click .js-due-cards-view-all'() {
Utils.setDueCardsView('all');
Popup.close();
},
},
];
},
}).register('globalSearchViewChangePopup');
BlazeComponent.extendComponent({
onCreated() {
this.isPageReady = new ReactiveVar(true);
this.query = new ReactiveVar('');
// this.autorun(() => {
// const handle = subManager.subscribe('globalSearch');
// Tracker.nonreactive(() => {
// Tracker.autorun(() => {
// this.isPageReady.set(handle.ready());
// });
// });
// });
Meteor.subscribe('setting');
},
events() {
return [
{
'submit .js-search-query-form'(evt) {
evt.preventDefault();
this.query.set(evt.target.searchQuery.value);
// eslint-disable-next-line no-console
console.log('query:', this.query.get());
let query = this.query.get();
const reUser = /^@(?<user>\w+)(\s+|$)/;
const reLabel = /^#(?<label>\w+)(\s+|$)/;
const reOperator1 = /^(?<operator>\w+):(?<value>\w+)(\s+|$)/;
const reOperator2 = /^(?<operator>\w+):(?<quote>["']*)(?<value>.*?)\k<quote>(\s+|$)/;
const reText = /^(?<text>[^:@#\s]+)(\s+|$)/;
const reQuotedText = /^(?<quote>["'])(?<text>\w+)\k<quote>(\s+|$)/;
const operatorMap = {
board: 'boards',
b: 'boards',
label: 'labels',
lable: 'labels',
user: 'users',
u: 'users',
swimlane: 'swimlanes',
swim: 'swimlanes',
s: 'swimlanes',
list: 'lists',
l: 'lists',
};
const selector = {
boards: [],
swimlanes: [],
lists: [],
users: [],
labels: [],
};
let text = '';
while (query) {
// eslint-disable-next-line no-console
console.log('query:', query);
let m = query.match(reUser);
if (m) {
query = query.replace(reUser, '');
selector.users.push(m.groups.user);
continue;
}
m = query.match(reLabel);
if (m) {
query = query.replace(reLabel, '');
selector.labels.push(m.groups.label);
continue;
}
m = query.match(reOperator1);
if (!m) {
m = query.match(reOperator2);
if (m) {
query = query.replace(reOperator2, '');
}
} else {
query = query.replace(reOperator1, '');
}
if (m) {
const op = m.groups.operator.toLowerCase();
if (op in operatorMap) {
selector[operatorMap[op]].push(m.groups.value);
}
continue;
}
m = query.match(reQuotedText);
if (!m) {
m = query.match(reText);
if (m) {
query = query.replace(reText, '');
}
} else {
query = query.replace(reQuotedText, '');
}
if (m) {
text += (text ? ' ' : '') + m.groups.text;
}
}
// eslint-disable-next-line no-console
console.log('selector:', selector);
// eslint-disable-next-line no-console
console.log('text:', text);
},
},
];
},
globalSearchList() {},
}).register('globalSearch');

View file

@ -0,0 +1,69 @@
.due-cards-board-wrapper
border-radius: 8px
//padding: 0.5rem
min-width: 400px
border-width: 8px
border-color: grey
border-style: solid
margin-bottom: 2rem
margin-right: auto
margin-left: auto
.due-cards-board-title
font-size: 1.4rem
font-weight: bold
padding: 0.5rem
background-color: grey
color: white
.due-cards-swimlane-title
font-size: 1.1rem
font-weight: bold
padding: 0.5rem
padding-bottom: 0.4rem
margin-top: 0
margin-bottom: 0.5rem
//border-top: black 1px solid
//border-bottom: black 1px solid
text-align: center
.swimlane-default-color
background-color: lightgrey
.due-cards-list-title
font-weight: bold
font-size: 1.1rem
//padding-bottom: 0
//margin-bottom: 0
text-align: center
margin-bottom: 0.7rem
.due-cards-list-wrapper
margin: 1rem
border-radius: 5px
padding: 1.5rem
padding-top: 0.75rem
display: inline-block
min-width: 250px
max-width: 350px
.due-cards-card-wrapper
margin-top: 0
margin-bottom: 10px
.due-cards-dueat-list-wrapper
max-width: 500px
margin-right: auto
margin-left: auto
.due-cards-field-name
font-weight: bold
.due-cards-context
display: inline-block
.due-cards-context-separator
font-weight: bold
.due-cards-context-list
margin-bottom: 0.7rem

View file

@ -149,6 +149,24 @@ FlowRouter.route('/due-cards', {
},
});
FlowRouter.route('/global-search', {
name: 'global-search',
action() {
Filter.reset();
// EscapeActions.executeAll();
EscapeActions.executeUpTo('popup-close');
Utils.manageCustomUI();
Utils.manageMatomo();
BlazeLayout.render('defaultLayout', {
headerBar: 'globalSearchHeaderBar',
content: 'globalSearch',
});
// }
},
});
FlowRouter.route('/import/:source', {
name: 'import',
triggersEnter: [AccountsTemplates.ensureSignedIn],