mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
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>
This commit is contained in:
@@ -36,6 +36,7 @@
|
||||
"name": "Facets",
|
||||
"classes": [
|
||||
"facet.facet",
|
||||
"facets.Facet",
|
||||
"*_facet"
|
||||
]
|
||||
},
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
|
||||
329
install/ui/src/freeipa/facets/Facet.js
Normal file
329
install/ui/src/freeipa/facets/Facet.js
Normal file
@@ -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;
|
||||
});
|
||||
Reference in New Issue
Block a user