summaryrefslogtreecommitdiffstats
path: root/install
diff options
context:
space:
mode:
authorPetr Vobornik <pvoborni@redhat.com>2013-11-25 13:56:27 +0100
committerPetr Vobornik <pvoborni@redhat.com>2014-04-15 12:41:53 +0200
commit642345fd53faabd9183bef1a7667bdb7956d27f7 (patch)
tree1ac9d5fdf22424a3bf99db5eb505747b28caa92c /install
parentdec7f98aa995b369f022813093ac88d0062e5089 (diff)
downloadfreeipa-642345fd53faabd9183bef1a7667bdb7956d27f7.tar.gz
freeipa-642345fd53faabd9183bef1a7667bdb7956d27f7.tar.xz
freeipa-642345fd53faabd9183bef1a7667bdb7956d27f7.zip
webui: standalone facet
`facet.Facet` is a new base class for facets. It doesn't have any dependencies on entities so it's usable for general purpose facets, e.g., future API browser, load facet or login facet. https://fedorahosted.org/freeipa/ticket/3903 Reviewed-By: Adam Misnyovszki <amisnyov@redhat.com>
Diffstat (limited to 'install')
-rw-r--r--install/ui/doc/categories.json1
-rw-r--r--install/ui/ipa.css10
-rw-r--r--install/ui/jsl.conf1
-rw-r--r--install/ui/src/freeipa/_base/construct.js12
-rw-r--r--install/ui/src/freeipa/facet.js4
-rw-r--r--install/ui/src/freeipa/facets/Facet.js329
6 files changed, 355 insertions, 2 deletions
diff --git a/install/ui/doc/categories.json b/install/ui/doc/categories.json
index e8ae56b79..d1e2d61e4 100644
--- a/install/ui/doc/categories.json
+++ b/install/ui/doc/categories.json
@@ -36,6 +36,7 @@
"name": "Facets",
"classes": [
"facet.facet",
+ "facets.Facet",
"*_facet"
]
},
diff --git a/install/ui/ipa.css b/install/ui/ipa.css
index a65505695..ca8ccaffc 100644
--- a/install/ui/ipa.css
+++ b/install/ui/ipa.css
@@ -198,12 +198,20 @@ textarea[readonly] {
/* ---- Facet ---- */
.facet {
+ position: relative;
+ display: none;
+}
+
+#simple-container .content {
+ height: 100%;
+}
+
+#container .facet {
position: absolute;
top: 110px;
left: 10px;
right: 10px;
bottom: 0;
- display: none;
}
.active-facet {
diff --git a/install/ui/jsl.conf b/install/ui/jsl.conf
index 62343cb1c..4bc1fdecb 100644
--- a/install/ui/jsl.conf
+++ b/install/ui/jsl.conf
@@ -136,6 +136,7 @@
+process src/freeipa/_base/*.js
+process src/freeipa/dialogs/*.js
+process src/freeipa/navigation/*.js
++process src/freeipa/facets/*.js
+process src/freeipa/widgets/*.js
+process src/*.js
+process ./*.js \ No newline at end of file
diff --git a/install/ui/src/freeipa/_base/construct.js b/install/ui/src/freeipa/_base/construct.js
index ce675e588..6db2134b8 100644
--- a/install/ui/src/freeipa/_base/construct.js
+++ b/install/ui/src/freeipa/_base/construct.js
@@ -107,6 +107,18 @@ define(['dojo/_base/declare',
return lang._mixin(r, src, construct.clone);
},
+ /**
+ * Run object's init function after instantiation if it has one
+ * @param {Object} obj
+ * @param {Object} spec
+ */
+ init_post_op: function(obj, spec) {
+ if (obj && typeof obj.init === 'function') {
+ obj.init(spec);
+ }
+ return obj;
+ },
+
no_cs_for_type_error: function(type) {
return {
error: 'No construction specification for given type',
diff --git a/install/ui/src/freeipa/facet.js b/install/ui/src/freeipa/facet.js
index f235ddc8f..5fc59ea3b 100644
--- a/install/ui/src/freeipa/facet.js
+++ b/install/ui/src/freeipa/facet.js
@@ -29,6 +29,7 @@ define([
'dojo/Stateful',
'dojo/Evented',
'./_base/Singleton_registry',
+ './_base/construct',
'./builder',
'./ipa',
'./jquery',
@@ -42,7 +43,7 @@ define([
'./field',
'./widget'
], function(declare, lang, construct, on, Stateful, Evented,
- Singleton_registry, builder, IPA, $,
+ Singleton_registry, construct_utils, builder, IPA, $,
navigation, phases, reg, rpc, su, text) {
/**
@@ -3493,6 +3494,7 @@ var FacetState = exp.FacetState = declare([Stateful, Evented], {
var registry = new Singleton_registry();
reg.set('facet', registry);
builder.set('facet', registry.builder);
+registry.builder.post_ops.push(construct_utils.init_post_op);
/**
* Action builder with registry
diff --git a/install/ui/src/freeipa/facets/Facet.js b/install/ui/src/freeipa/facets/Facet.js
new file mode 100644
index 000000000..8b55cec12
--- /dev/null
+++ b/install/ui/src/freeipa/facets/Facet.js
@@ -0,0 +1,329 @@
+/* Authors:
+ * Petr Vobornik <pvoborni@redhat.com>
+ *
+ * Copyright (C) 2013 Red Hat
+ * see file 'COPYING' for use and warranty information
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+define(['dojo/_base/declare',
+ 'dojo/_base/lang',
+ 'dojo/Evented',
+ 'dojo/dom-construct',
+ 'dojo/dom-class',
+ 'dojo/on',
+ '../builder',
+ '../facet',
+ '../ipa', // for util functions
+ '../jquery',
+ '../text',
+ '../widgets/ContainerMixin'
+ ],
+ function(declare, lang, Evented, construct, dom_class,
+ on, builder, mod_facet, IPA, $, text, ContainerMixin) {
+
+ /**
+ * Base class of Facet
+ *
+ * A future replacement/base class for `facet.facet`
+ *
+ * @class facets.Facet
+ * @mixins widgets.ContainerMixin
+ */
+ var Facet = declare([Evented, ContainerMixin], {
+
+ /**
+ * Name of preferred facet container
+ *
+ * Leave unset to use default container.
+ * @property {string}
+ */
+ preferred_container: null,
+
+ /**
+ * Facet name
+ * @property {string}
+ */
+ name: null,
+
+ /**
+ * Facet label
+ * @property {string}
+ */
+ label: null,
+
+ /**
+ * Facet title
+ * @property {string}
+ */
+ title: null,
+
+ /**
+ * Facet element's CSS class
+ * @property {string}
+ */
+ 'class': null,
+
+ /**
+ * Class which tells that the facet should be visible
+ * @property {string}
+ */
+ active_class: 'active',
+
+ /**
+ * dom_node of container
+ * Suppose to contain dom_node of this and other facets.
+ * @property {jQuery}
+ */
+ container_node: null,
+
+ /**
+ * dom_node which contains all content of this Facet.
+ * @property {HTMLElement}
+ * @readonly
+ */
+ dom_node: null,
+
+ /**
+ * DOM node which serves as container for child widgets
+ * @property {HTMLElement}
+ */
+ children_node: null,
+
+ /**
+ * Redirection target information.
+ *
+ * Can be facet and/or entity name.
+ * @property {Object}
+ * @param {string} entity entity name
+ * @param {string} facet facet name
+ */
+ redirect_info: null,
+
+ /**
+ * Public state
+ * @property {facet.FacetState}
+ * @protected
+ */
+ state: null,
+
+ /**
+ * Checks if two objects has the same properties with equal values.
+ *
+ * @param {Object} a
+ * @param {Object} b
+ * @return {boolean} `a` and `b` are value-equal
+ * @protected
+ */
+ state_diff: function(a, b) {
+ var diff = false;
+ var checked = {};
+
+ var check_diff = function(a, b, skip) {
+
+ var same = true;
+ skip = skip || {};
+
+ for (var key in a) {
+ if (a.hasOwnProperty(key) && !(key in skip)) {
+ var va = a[key];
+ var vb = b[key];
+ if (lang.isArray(va)) {
+ if (IPA.array_diff(va,vb)) {
+ same = false;
+ skip[a] = true;
+ break;
+ }
+ } else {
+ if (va != vb) {
+ same = false;
+ skip[a] = true;
+ break;
+ }
+ }
+ }
+ }
+ return !same;
+ };
+
+ diff = check_diff(a,b, checked);
+ diff = diff || check_diff(b,a, checked);
+ return diff;
+ },
+
+ /**
+ * Reset facet state to supplied
+ *
+ * @param {Object} state state to set
+ */
+ reset_state: function(state) {
+ this.state.reset(state);
+ },
+
+ /**
+ * Get copy of current state
+ *
+ * @return {Object} state
+ */
+ get_state: function() {
+ return this.state.clone();
+ },
+
+ /**
+ * Merges state into current and notifies it.
+ *
+ * @param {Object} state object to merge into current state
+ */
+ set_state: function(state) {
+ this.state.set(state);
+ },
+
+ /**
+ * Handle state set
+ * @param {Object} old_state
+ * @param {Object} state
+ * @protected
+ */
+ on_state_set: function(old_state, state) {
+ this.on_state_change(state);
+ },
+
+ /**
+ * Handle state change
+ * @param {Object} state
+ * @protected
+ */
+ on_state_change: function(state) {
+
+ this._notify_state_change(state);
+ },
+
+ /**
+ * Fires `facet-state-change` event with given state as event parameter.
+ *
+ * @fires facet-state-change
+ * @protected
+ * @param {Object} state
+ */
+ _notify_state_change: function(state) {
+ this.emit('facet-state-change', {
+ facet: this,
+ state: state
+ });
+ },
+
+ /**
+ * Create facet's HTML representation
+ * NOTE: may be renamed to render
+ */
+ create: function() {
+
+ if (this.dom_node) {
+ construct.empty(this.dom_node);
+ } else {
+ this.dom_node = construct.create('div', {
+ 'class': 'facet',
+ name: this.name,
+ 'data-name': this.name
+ });
+ }
+ if (this.container_node) {
+ construct.place(this.dom_node, this.container_node);
+ }
+ this.children_node = this.dom_node;
+ return this.dom_node;
+ },
+
+ /**
+ * Render child widgets
+ */
+ render_children: function() {
+ var widgets = this.get_widgets();
+
+ for (var i=0;i<widgets.length; i++) {
+ var widget = widgets[i];
+ var modern = typeof widget.render === 'function';
+
+ if (modern) {
+ widget.container_node = this.children_node;
+ widget.render();
+ } else {
+ var container = $('<div/>').appendTo(this.children_node);
+ widget.create(container);
+ }
+ }
+ },
+
+ /**
+ * Show facet
+ *
+ * - mark itself as active facet
+ */
+ show: function() {
+
+ if (!this.dom_node) {
+ this.create();
+ this.render_children();
+ }
+
+ dom_class.add(this.dom_node, 'active-facet');
+ this.emit('show', { source: this });
+ },
+
+ /**
+ * Un-mark itself as active facet
+ */
+ hide: function() {
+ dom_class.remove(this.dom_node, 'active-facet');
+ this.emit('hide', { source: this });
+ },
+
+ /**
+ * Initializes facet
+ *
+ * Facet builder should run this method after instantiation.
+ * @param {Object} spec
+ */
+ init: function(spec) {
+
+ this.add_widgets(spec.widgets || []);
+ },
+
+ can_leave: function() {
+ return true;
+ },
+
+ show_leave_dialog: function(callback) {
+ window.console.warning('Unimplemented');
+ },
+
+ /** Constructor */
+ constructor: function(spec) {
+
+ this.preferred_container = spec.preferred_container;
+ this.name = spec.name;
+ this.label = text.get(spec.label);
+ this.title = text.get(spec.title || spec.label);
+ this['class'] = spec['class'];
+ this.container_node = spec.container_node;
+ this.dom_node = spec.dom_node;
+ this.redirect_info = spec.redirect_info;
+ this.state = new mod_facet.FacetState();
+ on(this.state, 'set', lang.hitch(this, this.on_state_set));
+ }
+ });
+
+ return Facet;
+}); \ No newline at end of file