diff --git a/.idea/totpal.iml b/.idea/totpal.iml
index c617868..02d2170 100644
--- a/.idea/totpal.iml
+++ b/.idea/totpal.iml
@@ -7,7 +7,7 @@
-
+
diff --git a/js_conversion.py b/js_conversion.py
index c932542..be42098 100644
--- a/js_conversion.py
+++ b/js_conversion.py
@@ -18,15 +18,15 @@ def get_set_attr(name, attr) -> str:
if RelationshipDefinition in attr.__class__.__mro__:
return f"""
get_{name}() {{
- return this.json.{name}
+ return this._get_relation('{name}')
}}
link_{name}(ref) {{
- return this._link_property('{name}', ref)
+ return this._link_relation('{name}', ref)
}}
unlink_{name}(ref) {{
- return this._unlink_property('{name}', ref)
+ return this._unlink_relation('{name}', ref)
}}
"""
else:
diff --git a/server/abstract_api.py b/server/abstract_api.py
index e411e7a..077be5d 100644
--- a/server/abstract_api.py
+++ b/server/abstract_api.py
@@ -153,7 +153,8 @@ def handle_object_api_request_id(cls: Type[StructuredNode], uid: str):
obj = cls.nodes.get_or_none(uid=uid)
if not obj:
raise ApiError.not_found(cls, uid)
-
+ obj.delete()
+ return '', 204
def handle_object_api_request_for_relation(cls: Type[StructuredNode], uid, relation, reluid):
obj = cls.nodes.get_or_none(uid=uid)
diff --git a/server/models/models.py b/server/models/models.py
index b14bf0d..171a05f 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 07c43fd..58cfef4 100644
--- a/static/api.js
+++ b/static/api.js
@@ -1,5 +1,5 @@
class StructuredNode {
- constructor(json) {
+ constructor(json = {}) {
if (this.constructor === StructuredNode) {
throw new TypeError('Cannot instantiate object of abstract type StructuredNode!')
}
@@ -10,13 +10,65 @@ class StructuredNode {
this.hooks = []
this.deleted = false
this.__name__ = this.constructor.name.toLowerCase()
+ // holds a list of all relations that are already loaded
+
+ this._update_json()
+ }
+
+ _update_json(json) {
+ let old_json = this.json;
+ this.__loaded__ = [];
+ if (json) {
+ this.json = json
+ } else {
+ old_json = {}
+ }
+
+ Object.values(this.definition.rels).forEach(rel => {
+ // if we did not recieve an update for this relation, don't touch it!
+ // we might have gotten an update without relational information
+ if (this.json[rel.field] === undefined) {
+ return
+ }
+
+ this.__loaded__.push(rel.field)
+ const type = StructuredNode.classes[rel.target].klass;
+
+ if (rel.cardinality.endsWith('OrMore')) {
+ this.json[rel.field] = this.json[rel.field].map(x => new type(x))
+ } else {
+ if (this.json[rel.field] === null) {
+ return
+ }
+ this.json[rel.field] = new type(this.json[rel.field])
+ }
+ })
+
+ Object.values(this.definition.props).forEach(prop => {
+ // no update for this prop? don't put anything in.
+ if (this.json[prop.field] === undefined || this.json[prop.field] === null)
+ return
+
+ this.json[prop.field] = PropertyConversion.deserialize(prop.type, this.json[prop.field])
+ })
+
+ // keep fields from old_json which are not defined in the new json
+ Object.keys(old_json).forEach(key => {
+ if (this.json[key] === undefined) {
+ this.json = old_json[key];
+ // keep loaded state
+ if (this.definition.rels[key]) {
+ this.__loaded__.push(key)
+ }
+ }
+ })
}
check(name, new_value) {
return true
}
- _link_property(name, elm) {
+ _link_relation(name, elm) {
const relation = this.definition.rels[name]
if (!relation) {
@@ -34,7 +86,7 @@ class StructuredNode {
// make results available immediately
if (relation.cardinality.endsWith('OrMore')) {
- if (!this.json[name].contains(elm)) {
+ if (!this.json[name].filter(e => e.json.uid === elm.json.uid)) {
this.json[name].push(elm)
}
} else {
@@ -42,30 +94,38 @@ class StructuredNode {
}
return Api.post(`/${this.__name__}/${this.json.uid}/${name}/${elm.json.uid}`).then(json => {
- this.json = json
+ this._update_json(json)
this.update('link')
return this
})
}
}
- _unlink_property(name, type, elm) {
+ _unlink_relation(name, type, elm) {
return Api.delete(`/${this.__name__}/${this.json.uid}/${name}/${elm.json.uid}`).then(json => {
- this.json = json
+ this._update_json(json)
this.update('link')
return this
})
}
- _set(name, new_val) {
- if (this.check(name, new_val)) {
- const def = this.definition.props[name]
+ _get_relation(name) {
+ if (this.__loaded__.indexOf(name) > -1) {
+ return Promise.resolve(this.json[name])
+ } else {
+ return this.refresh().then(elm => elm.json[name])
+ }
+ }
- if (!def) {
- throw new Error("No attribute " + name + " found!")
- }
+ _set(name, new_val) {
+ const def = this.definition.props[name]
+ if (!def)
+ throw new Error("No attribute " + name + " found!")
+ if (this.check(def, new_val)) {
+ this.json[name] = new_val
+ this.changes[name] = PropertyConversion.serialize(def.type, new_val)
}
}
@@ -76,14 +136,15 @@ class StructuredNode {
if (this.json.uid) {
return Api.put(`/${this.__name__}/${this.json.uid}`, this.changes).then(json => {
- this.json = json
+ this._update_json(json)
this.changes = {}
this.update('save')
return this
})
} else {
return Api.post('/' + this.__name__, this.json).then(json => {
- this.json = json
+ debugger;
+ this._update_json(json)
this.changes = {}
this.update('created')
return this
@@ -104,7 +165,7 @@ class StructuredNode {
refresh() {
return Api.get(`/${this.__name__}/${this.json.uid}`).then(json => {
- this.json = json
+ this._update_json(json)
this.update('refresh')
return this
})
diff --git a/static/models.js b/static/models.js
index 3d20b2c..4b03fb5 100644
--- a/static/models.js
+++ b/static/models.js
@@ -20,28 +20,28 @@ class Person extends StructuredNode {
get_father() {
- return this.json.father
+ return this._get_relation('father')
}
link_father(ref) {
- return this._link_property('father', ref)
+ return this._link_relation('father', ref)
}
unlink_father(ref) {
- return this._unlink_property('father', ref)
+ return this._unlink_relation('father', ref)
}
get_mother() {
- return this.json.mother
+ return this._get_relation('mother')
}
link_mother(ref) {
- return this._link_property('mother', ref)
+ return this._link_relation('mother', ref)
}
unlink_mother(ref) {
- return this._unlink_property('mother', ref)
+ return this._unlink_relation('mother', ref)
}
@@ -82,15 +82,15 @@ class Person extends StructuredNode {
get_places() {
- return this.json.places
+ return this._get_relation('places')
}
link_places(ref) {
- return this._link_property('places', ref)
+ return this._link_relation('places', ref)
}
unlink_places(ref) {
- return this._unlink_property('places', ref)
+ return this._unlink_relation('places', ref)
}
}
@@ -116,28 +116,28 @@ class Event extends StructuredNode {
get_participants() {
- return this.json.participants
+ return this._get_relation('participants')
}
link_participants(ref) {
- return this._link_property('participants', ref)
+ return this._link_relation('participants', ref)
}
unlink_participants(ref) {
- return this._unlink_property('participants', ref)
+ return this._unlink_relation('participants', ref)
}
get_places() {
- return this.json.places
+ return this._get_relation('places')
}
link_places(ref) {
- return this._link_property('places', ref)
+ return this._link_relation('places', ref)
}
unlink_places(ref) {
- return this._unlink_property('places', ref)
+ return this._unlink_relation('places', ref)
}
@@ -160,15 +160,15 @@ class Event extends StructuredNode {
get_related_events() {
- return this.json.related_events
+ return this._get_relation('related_events')
}
link_related_events(ref) {
- return this._link_property('related_events', ref)
+ return this._link_relation('related_events', ref)
}
unlink_related_events(ref) {
- return this._unlink_property('related_events', ref)
+ return this._unlink_relation('related_events', ref)
}
}
@@ -203,15 +203,15 @@ class Place extends StructuredNode {
get_visitors() {
- return this.json.visitors
+ return this._get_relation('visitors')
}
link_visitors(ref) {
- return this._link_property('visitors', ref)
+ return this._link_relation('visitors', ref)
}
unlink_visitors(ref) {
- return this._unlink_property('visitors', ref)
+ return this._unlink_relation('visitors', ref)
}
}
@@ -237,28 +237,28 @@ class Image extends StructuredNode {
get_pictured() {
- return this.json.pictured
+ return this._get_relation('pictured')
}
link_pictured(ref) {
- return this._link_property('pictured', ref)
+ return this._link_relation('pictured', ref)
}
unlink_pictured(ref) {
- return this._unlink_property('pictured', ref)
+ return this._unlink_relation('pictured', ref)
}
get_place() {
- return this.json.place
+ return this._get_relation('place')
}
link_place(ref) {
- return this._link_property('place', ref)
+ return this._link_relation('place', ref)
}
unlink_place(ref) {
- return this._unlink_property('place', ref)
+ return this._unlink_relation('place', ref)
}
diff --git a/templates/base.html b/templates/base.html
index 942f059..de54ac8 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -1,7 +1,7 @@
-
+