summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Levy <alon@pobox.com>2015-04-06 11:43:16 +0300
committerAlon Levy <alon@pobox.com>2015-04-06 11:43:16 +0300
commit3ae06034b88e7a9887a1c9fb2f5e623cd9469669 (patch)
treef4fcf31e491ded0f747538af683322bdad0730ba /src
parentcadfc79763a9c5c7473ca8ab764a0f9c56b125c1 (diff)
client: property tab cleanup; resolve #396
Diffstat (limited to 'src')
-rw-r--r--src/client/model/types.js4
-rw-r--r--src/client/rz_core.js6
-rw-r--r--src/client/view/graph_view.js14
-rw-r--r--src/client/view/internal.js14
-rw-r--r--src/client/view/item_info.js (renamed from src/client/view/node_info.js)101
-rw-r--r--src/client/view/link_info.js36
-rw-r--r--src/client/view/tab.js62
-rw-r--r--src/client/view/view.js12
8 files changed, 77 insertions, 172 deletions
diff --git a/src/client/model/types.js b/src/client/model/types.js
index a30777e7..76959a83 100644
--- a/src/client/model/types.js
+++ b/src/client/model/types.js
@@ -73,8 +73,8 @@ return (
{
nodetypes: nodetypes,
type_attributes: function (type) {
- util.assert(type[0] !== '_', 'invalid type name');
- return type_attributes[type_attributes.hasOwnProperty(type) ? type : '_defaults'].attributes;
+ util.assert(!type || type[0] !== '_', 'invalid type name');
+ return type_attributes[!type && type_attributes.hasOwnProperty(type) ? type : '_defaults'].attributes;
},
all_attributes: all_attributes,
attribute_titles: attribute_titles,
diff --git a/src/client/rz_core.js b/src/client/rz_core.js
index 4115e4bc..cee60a29 100644
--- a/src/client/rz_core.js
+++ b/src/client/rz_core.js
@@ -1,7 +1,7 @@
"use strict"
-define(['jquery', 'd3', 'consts', 'rz_bus', 'util', 'model/graph', 'model/core', 'view/helpers', 'view/view', 'rz_observer', 'view/selection', 'rz_mesh', 'model/diff', "view/graph_view", 'view/svg_input'],
-function($, d3, consts, rz_bus, util, model_graph, model_core, view_helpers, view, rz_observer, selection, rz_mesh, model_diff, graph_view, svg_input) {
+define(['jquery', 'd3', 'consts', 'rz_bus', 'util', 'model/graph', 'model/core', 'view/helpers', 'view/item_info', 'rz_observer', 'view/selection', 'rz_mesh', 'model/diff', "view/graph_view", 'view/svg_input'],
+function($, d3, consts, rz_bus, util, model_graph, model_core, view_helpers, item_info, rz_observer, selection, rz_mesh, model_diff, graph_view, svg_input) {
var addednodes = [],
vis,
@@ -41,7 +41,7 @@ function svg_click_handler(e) {
}
svgInput.hide();
selection.clear();
- view.hide();
+ item_info.hide();
update_view__graph(false);
}
diff --git a/src/client/view/graph_view.js b/src/client/view/graph_view.js
index 234ed976..3a3bb6a4 100644
--- a/src/client/view/graph_view.js
+++ b/src/client/view/graph_view.js
@@ -25,8 +25,8 @@
* which resulted in overly complex (read: undefined/buggy) code.
*/
-define(['d3', 'Bacon', 'consts', 'util', 'view/selection', 'view/helpers', 'model/diff', 'view/view', 'view/bubble', 'model/types', 'view/layouts'],
-function(d3 , Bacon, consts, util , selection , view_helpers, model_diff , view, view_bubble, model_types, view_layouts) {
+define(['d3', 'Bacon', 'consts', 'util', 'view/selection', 'view/helpers', 'model/diff', 'view/item_info', 'view/bubble', 'model/types', 'view/layouts'],
+function(d3 , Bacon, consts, util , selection , view_helpers, model_diff , item_info, view_bubble, model_types, view_layouts) {
"use strict"
@@ -287,7 +287,7 @@ function GraphView(spec) {
function showNodeInfo(node) {
util.assert(!temporary, "cannot showNodeInfo on a temporary graph");
- view.node_info.show(graph, node)
+ item_info.show(graph, node)
}
function dragstarted(d) {
@@ -510,13 +510,7 @@ function GraphView(spec) {
// after this events bubbles to the svg element
return;
}
- var that = this;
-
- view.link_info.on_delete(function () {
- view.link_info.hide();
- graph.links__delete([that.link.id]);
- });
- view.link_info.show(d);
+ item_info.show(graph, d, ['name']);
(d3.event.shiftKey? selection.invert_link : selection.select_link)(this.link);
});
diff --git a/src/client/view/internal.js b/src/client/view/internal.js
deleted file mode 100644
index 33e14e7a..00000000
--- a/src/client/view/internal.js
+++ /dev/null
@@ -1,14 +0,0 @@
-define(['view/tab'],
-function(tab) {
-
-var LINK_INFO_SELECTOR = '#link_info',
- NODE_INFO_SELECTOR = '#info',
- edit_tab = new tab.Tab({edge: LINK_INFO_SELECTOR, node: NODE_INFO_SELECTOR});
-
-return {
- LINK_INFO_SELECTOR: LINK_INFO_SELECTOR,
- NODE_INFO_SELECTOR: NODE_INFO_SELECTOR,
- edit_tab: edit_tab,
-};
-
-});
diff --git a/src/client/view/node_info.js b/src/client/view/item_info.js
index ef853a94..1f187ce0 100644
--- a/src/client/view/node_info.js
+++ b/src/client/view/item_info.js
@@ -1,15 +1,16 @@
-define(['jquery', 'jquery-ui', 'util', 'consts', 'view/helpers', 'view/internal', 'model/diff', 'model/types'],
-function($, _unused_jquery_ui, util, consts, view_helpers, internal, model_diff, model_types) {
+define(['jquery', 'jquery-ui', 'util', 'consts', 'view/helpers', 'model/diff', 'model/types'],
+function($, _unused_jquery_ui, util, consts, view_helpers, model_diff, model_types) {
-var d = null,
+var DEBOUNCE_TIME = 500; // milliseconds
+
+var item = null,
msg_node = $('.info-card-message'),
graph,
- node,
setup_done = false,
- info = $('.info'),
+ info = $('#info'),
info_container = $('.info-container'),
form_element = $('#editbox'),
- delete_button = $('#edit-node-dialog__delete'),
+ delete_button = $('#edit-dialog__delete'),
form = _.object(model_types.all_attributes.map(function (attr) {
var element = edit_element_for_attribute(attr);
@@ -61,9 +62,26 @@ function _get_form_data() {
return ret;
}
+function is_node(item)
+{
+ return item.__src === undefined;
+}
+
+function update_item(item, new_data)
+{
+ if (is_node(item)) {
+ graph.update_node(item, new_data);
+ } else {
+ graph.update_link(item, new_data);
+ }
+}
+
function commit()
{
- graph.update_node(node, _get_form_data());
+ if (item === null) {
+ return;
+ }
+ update_item(item, _get_form_data());
}
function textarea_resize(text, max)
@@ -80,12 +98,12 @@ function textarea_resize(text, max)
function setup_change_handlers()
{
disable_change_handlers();
- // auto save style handlers
+ // auto save after DEBOUNCE_TIME inactivity
var streams = _.map(_.values(form), function (element) {
return element.asEventStream('change input keyup');
});
var single = _.reduce(streams, function (stream_a, stream_b) { return stream_a.merge(stream_b); });
- change_handlers = [single.debounce(500).onValue(function () {
+ change_handlers = [single.debounce(DEBOUNCE_TIME).onValue(function () {
commit();
})];
}
@@ -96,9 +114,18 @@ function disable_change_handlers()
change_handlers = [];
}
+function delete_item()
+{
+ if (is_node(item)) {
+ graph.nodes__delete([item.id]);
+ } else {
+ graph.links__delete([item.id]);
+ }
+}
+
/**
* XXX
- * need to update fields if and only if there have been no new input events associated with them since commit.
+ * need to update fields iff there have been no new input events associated with them since commit.
* do not look at contents because that will exist in the past too.
*
* see Bacon.awaiting.
@@ -118,25 +145,31 @@ function setup_click_handlers()
}
});
delete_button.on('click', function (e) {
+ var msg = is_node(item) ? 'delete node?' : 'delete link?';
+
e.preventDefault();
hide();
- if (confirm('delete node?')) {
- graph.nodes__delete([node.id]);
+ if (confirm(msg)) {
+ delete_item(item);
}
});
- $('#edit-node-dialog__save').on('click', function (e) {
+ $('#edit-dialog__save').on('click', function (e) {
e.preventDefault();
hide();
commit();
});
- // re-open dialog on node updates while it is open
+
+ // warn user if the item has been changed while open
diffBusUnsubscribe = graph.diffBus.onValue(function (diff) {
- if (model_diff.is_topo_diff(diff) && _.contains(diff.node_id_set_rm, node.id)) {
- warning('!! node has been deleted !!');
+ var removed_set = is_node(item) ? diff.node_id_set_rm : diff.link_id_set_rm,
+ changed_set = is_node(item) ? diff.id_to_node_map : diff.id_to_link_map;
+
+ if (model_diff.is_topo_diff(diff) && _.contains(removed_set, item.id)) {
+ warning('!! item has been deleted !!');
return;
}
- if (model_diff.is_attr_diff(diff) || _.contains(_.keys(diff.id_to_node_map), node.id)) {
- warning('!! node has been changed !!');
+ if (model_diff.is_attr_diff(diff) || _.contains(_.keys(changed_set), item.id)) {
+ warning('!! item has been changed !!');
return;
}
});
@@ -163,37 +196,41 @@ function update_textarea(textarea, value)
textarea_resize(textarea[0], 150);
}
-function show(_graph, d) {
- var visible_attributes = model_types.type_attributes(d.type).slice(0),
- hidden_attributes = _.difference(model_types.all_attributes, visible_attributes),
+function show(_graph, new_item, visible_attributes)
+{
+ var visible_attributes,
+ hidden_attributes,
visible_elements,
hidden_elements,
max_height;
+ visible_attributes = visible_attributes || model_types.type_attributes(new_item.type).slice(0);
+ hidden_attributes = _.difference(model_types.all_attributes, visible_attributes),
visible_elements = visible_attributes.map(base_element_for_attribute);
hidden_elements = hidden_attributes.map(base_element_for_attribute);
warning(''); // reset warning
graph = _graph;
- node = d;
- util.assert(graph.find_node__by_id(d.id) != null);
+ item = new_item;
+ util.assert((is_node(item) ? graph.find_node__by_id : graph.find_link__by_id)(item.id) != null);
setup_click_handlers();
- internal.edit_tab.show('node');
-
_.each(hidden_elements, function (element) { element.hide(); });
_.each(visible_elements, function (element) { element.show(); });
info.attr('class', 'info');
- info.addClass('type-' + d.type); // Add a class to distinguish types for css
+ info.addClass('type-' + item.type); // Add a class to distinguish types for css
// hack - should be able to set max-height via css percentage, no?
max_height = $(document.body).innerHeight() - $('.info')[0].getBoundingClientRect().top * 2;
info_container[0].style['max-height'] = String(max_height) + 'px';
+ info_container.show();
+ console.log(visible_attributes);
+ console.log(hidden_attributes);
_.each(visible_attributes, function (attr) {
var element = edit_element_for_attribute(attr);
- value = d[attr];
+ value = item[attr];
switch (attr) {
case 'enddate':
@@ -210,11 +247,11 @@ function show(_graph, d) {
break;
case 'status':
if (_.contains(rz_config.role_set, 'admin')) {
- status.val(d.status);
+ status.val(item.status);
status.show();
status_display.hide();
} else {
- status_display.text(d.status);
+ status_display.text(item.status);
status.hide();
status_display.show();
}
@@ -224,18 +261,16 @@ function show(_graph, d) {
element.val(value);
}
});
-
}
function hide() {
- node_id = null;
- internal.edit_tab.hide();
+ item = null;
+ info_container.hide();
}
return {
show: show,
hide: hide,
- isOpenProperty: internal.edit_tab.isOpenProperty,
};
});
diff --git a/src/client/view/link_info.js b/src/client/view/link_info.js
deleted file mode 100644
index d711e200..00000000
--- a/src/client/view/link_info.js
+++ /dev/null
@@ -1,36 +0,0 @@
-"use strict"
-
-define(['view/internal'],
-function(internal) {
-
-var delete_button = internal.edit_tab.get('edge', '#deleteedge'),
- delete_callback = undefined;
-
-delete_button.on('click', function() {
- if (delete_callback) {
- delete_callback();
- }
-});
-
-function show(link)
-{
- internal.edit_tab.show('edge');
- internal.edit_tab.get('edge', '#edgetitle').html(link.name);
-}
-
-function hide()
-{
- internal.edit_tab.hide();
-}
-
-function on_delete(f)
-{
- delete_callback = f;
-}
-
-return {
- show: show,
- hide: hide,
- on_delete: on_delete,
-};
-});
diff --git a/src/client/view/tab.js b/src/client/view/tab.js
deleted file mode 100644
index 586e308a..00000000
--- a/src/client/view/tab.js
+++ /dev/null
@@ -1,62 +0,0 @@
-"use strict"
-
-define(['jquery', 'Bacon'],
-function($, Bacon) {
-
-function Tab(dict) {
- var k,
- selector = {},
- name = [],
- openessBus = new Bacon.Bus();
-
- for (k in dict) {
- if (dict.hasOwnProperty(k) == false) {
- continue;
- }
- selector[k] = dict[k];
- name.push(k);
- }
- this._selector = selector;
- this._name = name;
- this._openessBus = openessBus;
- this.isOpenProperty = openessBus.toProperty(false)
-}
-
-Tab.prototype.show = function(shown_name) {
- var i,
- name,
- element;
-
- for (i = 0 ; i < this._name.length ; ++i) {
- name = this._name[i];
- element = $(this._selector[name]);
- if (name === shown_name) {
- element.fadeIn(300);
- } else {
- element.hide();
- }
- }
- this._openessBus.push(true);
-}
-
-Tab.prototype.hide = function() {
- var i;
-
- for (i = 0 ; i < this._name.length ; ++i) {
- $(this._selector[this._name[i]]).fadeOut(300);
- }
- this._openessBus.push(false);
-}
-
-Tab.prototype.get = function(name, sel) {
- // selector concatenation
- var e = $(this._selector[name] + ' ' + sel);
-
- return e;
-}
-
-return {
- Tab: Tab
-};
-
-});
diff --git a/src/client/view/view.js b/src/client/view/view.js
deleted file mode 100644
index 575dc0a5..00000000
--- a/src/client/view/view.js
+++ /dev/null
@@ -1,12 +0,0 @@
-"use strict"
-
-define(['view/node_info', 'view/link_info', 'view/internal'],
-function(view_node_info, view_link_info, view_internal) {
-return {
- 'node_info': view_node_info,
- 'link_info': view_link_info,
- 'hide': function() {
- view_internal.edit_tab.hide();
- },
-};
-});