diff --git a/js_conversion.py b/js_conversion.py index 956f83e..c932542 100644 --- a/js_conversion.py +++ b/js_conversion.py @@ -36,10 +36,7 @@ def get_set_attr(name, attr) -> str: }} """ + f""" set_{name}(new_val) {{ - if (this.check('{name}', new_val)) {{ - this.json.{name} = new_val - this.changes.{name} = new_val - }} + this._set('{name}', new_val) }} """ if name != 'uid' else '' diff --git a/server/models/models.py b/server/models/models.py index 171a05f..b14bf0d 100644 --- a/server/models/models.py +++ b/server/models/models.py @@ -1,5 +1,5 @@ from neomodel import StructuredNode, StringProperty, RelationshipTo, RelationshipFrom, \ - UniqueIdProperty, DateProperty, StructuredRel, RelationshipManager + UniqueIdProperty, DateProperty, StructuredRel, RelationshipManager, from neomodel.cardinality import ZeroOrOne, ZeroOrMore, One, OneOrMore diff --git a/static/api.js b/static/api.js index 3e46f40..07c43fd 100644 --- a/static/api.js +++ b/static/api.js @@ -12,7 +12,7 @@ class StructuredNode { this.__name__ = this.constructor.name.toLowerCase() } - check(name, type, new_value) { + check(name, new_value) { return true } @@ -57,12 +57,16 @@ class StructuredNode { }) } - static by_id(uid) { - return Api.get('/' + this.name.toLowerCase() + '/' + uid).then(x => new this(x)) - } + _set(name, new_val) { + if (this.check(name, new_val)) { + const def = this.definition.props[name] - static find(attributes, settings) { + if (!def) { + throw new Error("No attribute " + name + " found!") + } + + } } save() { @@ -98,6 +102,14 @@ class StructuredNode { }) } + refresh() { + return Api.get(`/${this.__name__}/${this.json.uid}`).then(json => { + this.json = json + this.update('refresh') + return this + }) + } + exists() { return !this.deleted && !!this.json.uid } @@ -122,6 +134,25 @@ class StructuredNode { StructuredNode.classes[klass.name] = {klass, props, rels} } + static by_id(uid) { + return Api.get('/' + this.name.toLowerCase() + '/' + uid) + .then(x => new this(x)) + } + + static filter(attributes = {}, settings = {}) { + Object.keys(settings).forEach(key => { + attributes['$' + key] = settings[key] + }) + + return Api.get(`/${this.name.toLowerCase()}?` + Api.queryParams(attributes)) + .then(json => json.map(x => new this(x))) + } + + static find(attributes) { + return this.filter(attributes, {$limit: 1}) + .then(r => r.length === 0 ? null : r[0]) + } + } StructuredNode.classes = {} @@ -177,6 +208,13 @@ class Api { // 'Authorization': 'Bearer ' + Api.token } } + + static queryParams(...dicts) { + return dicts.map(dict => + Object.keys(dict).map(key => + encodeURIComponent(key)+'='+encodeURIComponent(dict[key])).join('&') + ).join('&') + } } class ApiError { @@ -197,4 +235,28 @@ class ApiError { }) } } -} \ No newline at end of file +} + + +class PropertyConversion { + static serialize(type, value) { + if (PropertyConversion.to[type]) { + return PropertyConversion.to[type](value) + } + return value + } + + static deserialize(type, value) { + if (PropertyConversion.to[type]) { + return PropertyConversion.from[type](value) + } + return value + } +} + +PropertyConversion.from = { + DateProperty: (val) => new Date(val), +} +PropertyConversion.to = { + DateProperty: (val) => ('' + val).slice(0,-11), +} diff --git a/static/models.js b/static/models.js index 7b1731a..3d20b2c 100644 --- a/static/models.js +++ b/static/models.js @@ -15,10 +15,7 @@ class Person extends StructuredNode { } set_name(new_val) { - if (this.check('name', new_val)) { - this.json.name = new_val - this.changes.name = new_val - } + this._set('name', new_val) } @@ -53,10 +50,7 @@ class Person extends StructuredNode { } set_birthdate(new_val) { - if (this.check('birthdate', new_val)) { - this.json.birthdate = new_val - this.changes.birthdate = new_val - } + this._set('birthdate', new_val) } @@ -65,10 +59,7 @@ class Person extends StructuredNode { } set_deceased(new_val) { - if (this.check('deceased', new_val)) { - this.json.deceased = new_val - this.changes.deceased = new_val - } + this._set('deceased', new_val) } @@ -77,10 +68,7 @@ class Person extends StructuredNode { } set_description(new_val) { - if (this.check('description', new_val)) { - this.json.description = new_val - this.changes.description = new_val - } + this._set('description', new_val) } @@ -89,10 +77,7 @@ class Person extends StructuredNode { } set_picture(new_val) { - if (this.check('picture', new_val)) { - this.json.picture = new_val - this.changes.picture = new_val - } + this._set('picture', new_val) } @@ -126,10 +111,7 @@ class Event extends StructuredNode { } set_name(new_val) { - if (this.check('name', new_val)) { - this.json.name = new_val - this.changes.name = new_val - } + this._set('name', new_val) } @@ -164,10 +146,7 @@ class Event extends StructuredNode { } set_date(new_val) { - if (this.check('date', new_val)) { - this.json.date = new_val - this.changes.date = new_val - } + this._set('date', new_val) } @@ -176,10 +155,7 @@ class Event extends StructuredNode { } set_end_date(new_val) { - if (this.check('end_date', new_val)) { - this.json.end_date = new_val - this.changes.end_date = new_val - } + this._set('end_date', new_val) } @@ -213,10 +189,7 @@ class Place extends StructuredNode { } set_name(new_val) { - if (this.check('name', new_val)) { - this.json.name = new_val - this.changes.name = new_val - } + this._set('name', new_val) } @@ -225,10 +198,7 @@ class Place extends StructuredNode { } set_description(new_val) { - if (this.check('description', new_val)) { - this.json.description = new_val - this.changes.description = new_val - } + this._set('description', new_val) } @@ -262,10 +232,7 @@ class Image extends StructuredNode { } set_description(new_val) { - if (this.check('description', new_val)) { - this.json.description = new_val - this.changes.description = new_val - } + this._set('description', new_val) } @@ -300,10 +267,7 @@ class Image extends StructuredNode { } set_date(new_val) { - if (this.check('date', new_val)) { - this.json.date = new_val - this.changes.date = new_val - } + this._set('date', new_val) } } diff --git a/static/site.js b/static/site.js index e69de29..bacf467 100644 --- a/static/site.js +++ b/static/site.js @@ -0,0 +1,62 @@ +class View { + constructor(tag = 'div') { + this.root = document.createElement(tag) + } + + $(sel) { + return this.root.querySelector(sel) + } + + $$(sel) { + return this.root.querySelectorAll(sel) + } + + on(elm, evt, cb) { + if (typeof elm === 'string') { + elm = this.$(elm) + } + + elm.addEventListener(evt, cb) + } +} + +class DefaultView extends View{ + constructor(object) { + super('div') + this.object = object; + this.fields = {} + this.subviews = {} + } + + render() { + Object.keys(this.object.json).forEach( + key => this.root.appendChild(this.getNode(key)) + ) + } + + getNode(name, value=null) { + if (this.fields[name]) { + return this.fields[name] + } + value = value === null ? this.object.json[name] : value + + if (value instanceof StructuredNode) { + this.subviews[name] = new DefaultView(value) + this.fields[name] = this.subviews[name].root + } else if (value instanceof Array) { + const elm = document.createElement('ul') + value.forEach((elm, i) => { + const li = document.createElement('li') + li.appendChild(this.getNode(name+'['+i+']',elm)) + elm.appendChild(li) + }) + this.fields[name] = elm + } else { + const elm = document.createElement('p') + elm.innerHTML = `${name}: ${value}` + this.fields[name] = elm + } + + return this.fields[name] + } +} \ No newline at end of file