Skip to content

Commit c1c2601

Browse files
committed
[academic_query] add working edit mode and use short descriptions for attributes
SQUASHED: AUTO-COMMIT-src-components-widgets-academic-query.js,AUTO-COMMIT-src-components-widgets-academic-subquery.js,
1 parent e666d4f commit c1c2601

File tree

2 files changed

+120
-58
lines changed

2 files changed

+120
-58
lines changed

src/components/widgets/academic-query.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,11 @@ export default class AcademicQuery extends Morph {
5959
}
6060

6161
async updateView() {
62+
if(!this.subquery) { return }
6263
var pane = this.get("#pane")
6364
var queryView = <academic-subquery></academic-subquery>;
64-
if(this.subquery) {
65-
queryView = this.subquery;
66-
} else {
67-
lively.notify("Could not load query.");
68-
}
65+
queryView = this.subquery;
66+
6967
var input = <input id="queryInput" value={this.textContent} style="width: 300px"></input>;
7068
var updateButton = <button click={() => this.setQuery(input.value)}>update</button>;
7169
var searchButton = <button click={() => lively.openBrowser("academic://expr:" + this.textContent + "?count=100")}>search</button>;

src/components/widgets/academic-subquery.js

Lines changed: 117 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@ import Morph from 'src/components/widgets/lively-morph.js';
22
import ohm from "https://unpkg.com/[email protected]/dist/ohm.js";
33
import {Author, Paper, MicrosoftAcademicEntities} from "src/client/literature.js";
44

5+
/*MD
6+
# Blabla
7+
Strg + Alt + P
8+
oder Alt + P MD*/
9+
10+
/*MD <edit://src/components/widgets/academic-subquery.html>
11+
oder browse://
12+
#TODO MD*/
513
var g = ohm.grammar(
614
`Academic {
715
Exp =
@@ -131,8 +139,73 @@ export default class AcademicSubquery extends Morph {
131139
super();
132140
}
133141

142+
/*MD ## Init MD*/
134143
async initialize() {
135-
this.updateView()
144+
// load the schema of a paper
145+
this.schema = await MicrosoftAcademicEntities.generateSchema("paper");
146+
// to use the descriptions in the UI, we need to shorten some
147+
var createShortDescriptions = attr => {
148+
switch(attr.name) {
149+
case "AW":
150+
attr.shortDesc = "Unique words in abstract";
151+
break;
152+
case "BT":
153+
attr.shortDesc = "BibTex document type";
154+
break;
155+
case "CitCon":
156+
attr.shortDesc = "Citation contexts";
157+
break;
158+
case "D":
159+
attr.shortDesc = "Date";
160+
break;
161+
case "DOI":
162+
attr.shortDesc = "Digital Object Identifier";
163+
break;
164+
case "E":
165+
attr.shortDesc = "Extended metadata";
166+
break;
167+
case "FamId":
168+
attr.shortDesc = "Family Group ID";
169+
break;
170+
case "LP":
171+
attr.shortDesc = "Last Page";
172+
break;
173+
case "Pt":
174+
attr.shortDesc = "Publication type";
175+
break;
176+
case "RId":
177+
attr.shortDesc = "Referenced Paper IDs";
178+
break;
179+
case "VFN":
180+
attr.shortDesc = "Journal or Conf. name (full)";
181+
break;
182+
case "VSN":
183+
attr.shortDesc = "Journal or Conf. name (short)";
184+
break;
185+
case "W":
186+
attr.shortDesc = "Unique words in title";
187+
break;
188+
default:
189+
attr.shortDesc = attr.description;
190+
}
191+
return attr;
192+
}
193+
this.schemaFiltered = this.schema
194+
.filter(attr => attr.operations != "None")
195+
.map(attr => createShortDescriptions(attr));
196+
// map words for operations to symbols for the query
197+
this.mapOperationToSymbol = op => {switch(op) {
198+
case "Equals":
199+
return ["==", "="];
200+
case "StartsWith":
201+
return ["="];
202+
case "IsBetween":
203+
return [">", ">=", "<", "<=", "="];
204+
default:
205+
return op;
206+
}};
207+
208+
this.updateView();
136209

137210
observer = new MutationObserver((mutations) => {
138211
clearTimeout(timeout);
@@ -151,17 +224,13 @@ export default class AcademicSubquery extends Morph {
151224
})
152225
}, 300);
153226
});
154-
155227
const config = {
156228
attributes: true,
157229
childList: true,
158230
subtree: true,
159231
attributeOldValue: true,
160232
characterDataOldValue: true,
161233
};
162-
163-
// TODO: Why are we switching focus after editing
164-
// once we start observing?
165234
observer.observe(this.get('#pane'), config);
166235

167236
// TODO: falls ich das umbaue, sodass eine subquery einfach als
@@ -174,13 +243,6 @@ export default class AcademicSubquery extends Morph {
174243
this.addEventListener('drop', (evt) => this.onDrop(evt))
175244
*/
176245
this.style.draggable = 'true';
177-
// "drag",
178-
// "dragend",
179-
// "dragenter",
180-
// "dragleave",
181-
// "dragover",
182-
// "dragstart",
183-
// "drop",
184246
}
185247

186248
onDragStart(event) {
@@ -253,7 +315,7 @@ export default class AcademicSubquery extends Morph {
253315
this.ui.addEventListener('dragleave', this.onDragLeave)
254316
this.ui.addEventListener('drop', this.onDrop)
255317
}
256-
this.ui.queryElement = this; // oufff
318+
this.ui.queryElement = this; // for drag and drop
257319
/*if (!this.isComplex) {
258320
this.addEventListener('dragstart', this.onDragStart)
259321
this.addEventListener('dragend', this.onDragEnd)
@@ -290,7 +352,6 @@ export default class AcademicSubquery extends Morph {
290352
}
291353

292354
async viewToQuery() {
293-
// TODO!
294355
var query = this.textContent;
295356

296357
if (this.isComplex) {
@@ -303,71 +364,74 @@ export default class AcademicSubquery extends Morph {
303364
}
304365
} else {
305366
var innerSpan = this.get('#inner');
306-
if (innerSpan) {
367+
if (!innerSpan) { return query }
368+
var attr, comp, val;
369+
if (this.editing) { // edit mode
370+
var attrElement = innerSpan.querySelector('#attribute');
371+
attr = attrElement.options[attrElement.selectedIndex].value // or .text;
372+
var compElement = innerSpan.querySelector('#comparator');
373+
comp = compElement.options[compElement.selectedIndex].value // or .text;
374+
val = innerSpan.querySelector('#value').value;
375+
} else { // read mode
307376
//lively.notify("INNERSPAN", innerSpan)
308-
var [attr, comp, val] = innerSpan
309-
.querySelectorAll("span[name='queryPart']")
310-
.map(e => e.textContent);
377+
[attr, comp, val] = innerSpan
378+
.querySelectorAll("span[name='queryPart']")
379+
.map(e => e.textContent);
311380
if (val)
312381
val = val.slice(0, val.length - 1); // remove last whitespace
313-
314-
// TODO check if attribute has string value
315-
var stringAttributes = {
316-
"A": "Author",
317-
"AA.AuN": "Author Name",
318-
}
319-
if (attr.slice(0, attr.length - 1) in stringAttributes) {
320-
val = "'" + val + "'"
321-
}
322-
//query = attr + comp + "'" + val + "'";
323-
if (innerSpan.getAttribute("type") == "composite")
324-
query = "Composite(" + attr + comp + val + ")";
325-
else
326-
query = attr + comp + val;
327382
}
383+
384+
385+
386+
// TODO check if attribute has string value
387+
var stringAttributes = {
388+
"A": "Author",
389+
"AA.AuN": "Author Name",
390+
}
391+
if (attr.slice(0, attr.length - 1) in stringAttributes) {
392+
val = "'" + val + "'"
393+
}
394+
// TODO: check if current attribute is composite (has .)
395+
//query = attr + comp + "'" + val + "'";
396+
if (innerSpan.getAttribute("type") == "composite")
397+
query = "Composite(" + attr + comp + val + ")";
398+
else
399+
query = attr + comp + val;
400+
401+
402+
403+
328404
}
329-
405+
lively.notify("QUERY from view", query)
330406
return query
331407
}
332408

333409
async toggleEditing() {
410+
await this.setQuery(await this.viewToQuery()); // update query from changes
334411
this.editing = !this.editing;
335-
lively.notify("EDIT", this.editing)
336-
this.ui = await this.queryToView();
412+
this.ui = await this.queryToView(); // update ui to read-mode
337413
this.updateView();
338414
}
339415

340416
// builds the UI in edit mode
341417
async buildEditable(ast) {
342418
var inner = <span id="inner"></span>;
343419
var query = <span name="sub" draggable='false'></span>;
344-
var schema = await MicrosoftAcademicEntities.generateSchema("paper"); // TODO: in der Klasse speichern?
345420

346421
// attribute
347422
var attribute = <select name='attribute' id='attribute'></select>;
348-
var selectedAttribute; // TODO: Klassenvariable?
349-
schema.filter(attr => attr.operations != "None").forEach(option => {
423+
//var selectedAttribute; // TODO: Klassenvariable?
424+
this.schemaFiltered.forEach(option => {
350425
var selected = (option.name == ast.attribute);
351-
if (selected) { selectedAttribute = option; }
352-
attribute.options.add(new Option(option.name, option.name, selected, selected))
426+
if (selected) { this.selectedAttribute = option; }
427+
attribute.options.add(new Option(option.shortDesc, option.name, selected, selected))
353428
})
354429
query.appendChild(attribute);
355430

356431
// comparator
357-
var mapOperationToSymbol = op => {switch(op) {
358-
case "Equals":
359-
return ["==", "="];
360-
case "StartsWith":
361-
return ["="];
362-
case "IsBetween":
363-
return [">", ">=", "<", "<=", "="];
364-
default:
365-
return op;
366-
} // TODO: in der Klasse speichern?
367-
};
368432
var comparator = <select name='comparator' id='comparator'></select>;
369-
selectedAttribute.operations.split(", ")
370-
.map(operation => mapOperationToSymbol(operation)) // map words to arrays of symbols
433+
this.selectedAttribute.operations.split(", ")
434+
.map(operation => this.mapOperationToSymbol(operation)) // map words to arrays of symbols
371435
.flat()
372436
.filter((item, pos, self) => self.indexOf(item) == pos) // deduplicate
373437
.forEach(option => {

0 commit comments

Comments
 (0)