cleanup , header & logo
This commit is contained in:
@@ -1,85 +0,0 @@
|
||||
<style>
|
||||
.data-explorer .results {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 480px;
|
||||
background: var(--eicui-base-color-grey);
|
||||
resize:vertical;
|
||||
}
|
||||
.data-explorer .results .detail {
|
||||
position: absolute;
|
||||
left: var(--eicui-base-spacing-2xs);
|
||||
top: var(--eicui-base-spacing-2xs);
|
||||
}
|
||||
.data-explorer .results .detail article {
|
||||
resize: horizontal;
|
||||
min-width: 240px;
|
||||
}
|
||||
.data-explorer .results .detail article footer:empty:before {
|
||||
content: "(no entity relation)";
|
||||
text-align: center;
|
||||
font-size: smaller;
|
||||
color: var(--eicui-base-color-grey);
|
||||
}
|
||||
.data-explorer .results .detail article > section {
|
||||
padding: 0;
|
||||
max-height: 320px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.data-explorer .results .detail article > footer { grid-auto-flow: row; }
|
||||
.data-explorer .results .detail article > section [eicdatagrid] { font-size: small; }
|
||||
.data-explorer .results svg .entity {
|
||||
cursor:pointer;
|
||||
transition: all 0.7s;
|
||||
}
|
||||
.data-explorer .results svg .entity .icon {
|
||||
font-family: 'glyphs';
|
||||
font-size: 24px;
|
||||
}
|
||||
.data-explorer .results svg .entity .bg {
|
||||
fill: var(--app-color-white);
|
||||
transition: all 0.7s;
|
||||
}
|
||||
.data-explorer .results svg .entity text {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
text-align: center;
|
||||
fill: var(--app-color-black);
|
||||
stroke-width: 0.1;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
transition: all 0.7s;
|
||||
}
|
||||
.data-explorer .results svg .entity .title { font-size: 14px; font-weight: bold; }
|
||||
.data-explorer .results svg .entity .type { font-size: 11px; }
|
||||
.data-explorer .results svg .relation {
|
||||
fill: none;
|
||||
stroke: var(--app-color-white);
|
||||
stroke-width: 3px;
|
||||
transition: all 0.7s;
|
||||
}
|
||||
.data-explorer .results svg .entity.selected .bg { fill: var(--app-color-primary); }
|
||||
.data-explorer .results svg .entity.selected text {
|
||||
fill: var(--app-color-white);
|
||||
}
|
||||
.data-explorer .results svg .related { stroke: var(--app-color-accent); }
|
||||
.data-explorer .results svg .entity.related .bg { fill: var(--app-color-accent); }
|
||||
.data-explorer .results svg .entity.related text { stroke: var(--app-color-black); fill: var(--app-color-black); }
|
||||
</style>
|
||||
<article eiccard class="data-explorer">
|
||||
<header>
|
||||
<h1>MarkLogic™ Data Storage Explorer</h1>
|
||||
<h2></h2>
|
||||
</header>
|
||||
<section>
|
||||
<div class="filters">
|
||||
<input eicinput type="search" name="q" placeholder="full text search" />
|
||||
<select eicselect name="attributes" editable placeholder="add some filters..."></select>
|
||||
|
||||
</div>
|
||||
<div class="results">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"></svg>
|
||||
<div class="detail" placeholder="select an entity"></div>
|
||||
</div>
|
||||
</section>
|
||||
</article>
|
||||
@@ -1,406 +0,0 @@
|
||||
/**
|
||||
* n00014p5
|
||||
*/
|
||||
class DataExplorerView extends EICDomContent {
|
||||
|
||||
options = {
|
||||
entity: {
|
||||
width: 140,
|
||||
height: 70,
|
||||
gap: 20,
|
||||
dragging: false,
|
||||
current: null
|
||||
},
|
||||
map: {
|
||||
position: { x: 0, y: 0 },
|
||||
size: { width: 0, height: 0 },
|
||||
dragging: false,
|
||||
},
|
||||
scale: {
|
||||
current: 1.0,
|
||||
factor: 0.085,
|
||||
min: 0.5,
|
||||
max: 4
|
||||
},
|
||||
guides: true
|
||||
}
|
||||
|
||||
filtersList = [];
|
||||
|
||||
DOMContentLoaded(options) {
|
||||
for(let model in options.models) this[model] = options.models[model];
|
||||
|
||||
this.components = ui.eicfy(this.el);
|
||||
|
||||
this.q = this.components.find(c => c.el.name == 'q');
|
||||
this.q.onQuery = this.onQuery.bind(this);
|
||||
|
||||
this.attributes = this.components.find(c => c.el.name == 'attributes');
|
||||
this.attributes.activeEditor = DataExplorerFilter;
|
||||
this.attributes.onEditorOpened = this.fillFilters.bind(this);
|
||||
this.attributes.el.addEventListener( 'change' , this.onQuery.bind(this));
|
||||
|
||||
this.results = this.find('.results');
|
||||
this.viewboxPosition = {x: 0, y: 0};
|
||||
|
||||
this.map = this.find('.results svg');
|
||||
this.map.addEventListener('wheel', this.onMapScroll.bind(this));
|
||||
this.map.addEventListener('mousedown', this.onMapDragStart.bind(this));
|
||||
this.map.addEventListener('mousemove', this.onMapDragMove.bind(this));
|
||||
this.mouseUpHandler = this.onMapDragStop.bind(this);
|
||||
this.entityUpHandler = this.onEntityDragStop.bind(this);
|
||||
// observe map viewport resizing
|
||||
new ResizeObserver(this.onMapResize.bind(this)).observe(this.find('.results '))
|
||||
|
||||
this.ml.filters().then(payload => { this.filtersList = payload; })
|
||||
}
|
||||
|
||||
clearMap() {
|
||||
this.map.innerHTML = '';
|
||||
this.entities = [];
|
||||
}
|
||||
|
||||
clearDetail() { this.find('.detail').innerHTML = ''; }
|
||||
|
||||
fillFilters(editor) {
|
||||
let select = editor.el.querySelector('select');
|
||||
|
||||
for(let field of this.filtersList) {
|
||||
let option = ui.create(`<option value="${field.name}">${field.name}</option>`)
|
||||
select.append(option)
|
||||
}
|
||||
}
|
||||
|
||||
fillMap(data) {
|
||||
this.clearMap();
|
||||
this.clearDetail();
|
||||
|
||||
this.viewboxSize = {
|
||||
x: this.find('.results').clientWidth,
|
||||
y: this.find('.results').clientHeight
|
||||
};
|
||||
|
||||
this.viewboxStartPosition = {x: 0, y: 0};
|
||||
this.options.map.dragging = false;
|
||||
|
||||
for(let entity of data.entities) this.addEntity(entity);
|
||||
for(let relation of data.relations) this.addRelation(relation);
|
||||
|
||||
this.reorderMap();
|
||||
}
|
||||
|
||||
addEntity(entity) {
|
||||
const width = this.options.entity.width;
|
||||
const height = this.options.entity.height;
|
||||
const gap = this.options.entity.gap;
|
||||
|
||||
let template = this.ml.getType(entity._entity_type);
|
||||
let index = this.entities.length;
|
||||
let content = ui.create(
|
||||
`<svg class="entity" x="${gap + (width + gap) * index}" y="30" width="${width}" text-anchor="middle" data-id="${entity.id}">
|
||||
<rect class="bg" width="${width}" height="${height}" x="2" y="5" rx="10"></rect>
|
||||
<text class="icon" x="${width / 2}" y="32">${template.icon}</text>
|
||||
<text class="title" x="${width / 2}" y="50">${entity._entity_label}</text>
|
||||
<text class="type" x="${width / 2}" y="65">${template.label}</text>
|
||||
</svg>`
|
||||
);
|
||||
content.addEventListener('click', this.onEntitySelect.bind(this));
|
||||
content.addEventListener('mousedown', this.onEntityDragStart.bind(this));
|
||||
content.addEventListener('mousemove', this.onEntityMove.bind(this));
|
||||
this.entities.push({ el: content, data: entity, lines: [] });
|
||||
this.map.append(content);
|
||||
}
|
||||
|
||||
addRelation(relation) {
|
||||
let o1 = this.entities.find(item => item.data.id == relation.source);
|
||||
let o2 = this.entities.find(item => item.data.id == relation.target);
|
||||
|
||||
if(!o1 || !o2) return;
|
||||
|
||||
let line = ui.create(
|
||||
`<svg><line class="relation"
|
||||
x1="${o1.el.getAttribute('x')}" y1="${o1.el.getAttribute('y')}"
|
||||
x2="${o2.el.getAttribute('x')}" y2="${o2.el.getAttribute('y')}"
|
||||
data-source="${o1.data.id}" data-target="${o2.data.id}" /></svg>`
|
||||
).querySelector('line');
|
||||
this.map.prepend(line);
|
||||
|
||||
o1.lines.push(line)
|
||||
o2.lines.push(line)
|
||||
}
|
||||
|
||||
reorderMap() {
|
||||
let a = (Math.PI * 2) / this.entities.length;
|
||||
let r = (this.options.entity.width) * Math.log(this.entities.length);
|
||||
let i = 0;
|
||||
let center = { x: this.viewboxSize.x / 2, y: this.viewboxSize.y / 2 }
|
||||
|
||||
for(let entity of this.entities) {
|
||||
let pos = {
|
||||
x: center.x + (Math.cos(a * i - Math.PI * .5) * r) - (this.options.entity.width / 2),
|
||||
y: center.y + (Math.sin(a * i - Math.PI * .5) * r) - (this.options.entity.height / 2)
|
||||
}
|
||||
entity.el.setAttribute('x', pos.x)
|
||||
entity.el.setAttribute('y', pos.y)
|
||||
|
||||
for(let line of entity.lines) {
|
||||
if(line.getAttribute("data-source") == entity.data.id) {
|
||||
line.setAttribute("x1", pos.x + (this.options.entity.width / 2));
|
||||
line.setAttribute("y1", pos.y + (this.options.entity.height / 2));
|
||||
} else {
|
||||
line.setAttribute("x2", pos.x + (this.options.entity.width / 2));
|
||||
line.setAttribute("y2", pos.y + (this.options.entity.height / 2));
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if(this.entities.length > 0 && this.options.guides) {
|
||||
let guide = ui.create(`<svg><circle stroke="#888" fill="none" stroke-width="1" stroke-dasharray="5,5" cx="${center.x}" cy="${center.y}" r="${r}" /></svg>`)
|
||||
this.map.prepend(guide.querySelector('circle'));
|
||||
}
|
||||
}
|
||||
|
||||
setEntityDetail(entity) {
|
||||
let template = this.ml.getType(entity._entity_type);
|
||||
|
||||
let el = ui.create(`<article eiccard primary>
|
||||
<header><h1>${entity._entity_label}</h1><h2 small>${template.label}</h2></header>
|
||||
<section>
|
||||
<div eicdatagrid footer="hidden"></div>
|
||||
</section>
|
||||
<footer></footer>
|
||||
</article>`);
|
||||
|
||||
let footer = el.querySelector('footer');
|
||||
|
||||
let props = new DataGrid(el.querySelector('[eicdatagrid]'), {
|
||||
headers: [
|
||||
{label: 'property', filter:'text'},
|
||||
{label: 'value', filter:'text'},
|
||||
],
|
||||
height: '270px'
|
||||
});
|
||||
|
||||
this.setEntityProp(props, entity, 'id', null, entity._entity_type)
|
||||
|
||||
|
||||
for(let prop in entity.data) {
|
||||
//if(['_entity_type', '_entity_label'].indexOf(prop) == -1) {
|
||||
this.setEntityProp(props, entity.data, prop, null, entity._entity_type)
|
||||
//}
|
||||
}
|
||||
|
||||
let lines = this.entities.find(item => item.data.id == entity.id).lines;
|
||||
|
||||
if(lines.length > 0) {
|
||||
footer.append(ui.create(`<div xsmall>Relates locally to:</small>`))
|
||||
let ul = ui.create(`<ul bulleted small></ul>`)
|
||||
footer.append(ul);
|
||||
|
||||
for(let line of lines) {
|
||||
let other = this.entities.find(item => (item.data.id == line.getAttribute('data-target') && line.getAttribute('data-source') == entity.id) || (item.data.id == line.getAttribute('data-source') && line.getAttribute('data-target') == entity.id))
|
||||
let template = this.ml.getType(other.data._entity_type);
|
||||
let li = ui.create(`<li data-id="${other.data.id}"><a href="#">${other.data._entity_label} (${template.label})</a></li>`);
|
||||
li.addEventListener('click', this.onEntitySelect.bind(this))
|
||||
ul.append(li)
|
||||
}
|
||||
}
|
||||
|
||||
this.clearDetail();
|
||||
this.find('.detail').append(el);
|
||||
}
|
||||
|
||||
setEntityProp(table, parent, prop, prefix, type) {
|
||||
if(typeof parent[prop] !== 'object') {
|
||||
let allowSearch = ['id', 'email', 'euLogin', 'pic'].indexOf(prop) != -1;
|
||||
let value = allowSearch ?
|
||||
`<a data-query="${type}:${prop}:${parent[prop]}" href="#">${parent[prop]}</a>` :
|
||||
parent[prop];
|
||||
|
||||
let row = table.addRow('', [ (prefix ? prefix + '.': '') + prop, value ]);
|
||||
|
||||
if(allowSearch) {
|
||||
row.querySelector('.cell:nth-child(3) a').addEventListener('click', this.onQueryEntity.bind(this))
|
||||
}
|
||||
} else {
|
||||
for(let subprop in parent[prop])
|
||||
this.setEntityProp(table,parent[prop], subprop, (prefix ? prefix + '.': '') + prop, type)
|
||||
}
|
||||
}
|
||||
|
||||
onQuery(event) {
|
||||
|
||||
if(this.q.value.trim() == '' && this.attributes.value.length == 0) return;
|
||||
|
||||
let query = { freeText: this.q.value }
|
||||
|
||||
this.attributes.value.map(val => {
|
||||
let parts = val.split('=');
|
||||
if(parts.length > 1) query[parts[0]] = parts[1];
|
||||
})
|
||||
|
||||
this.ml.search(query).then( this.fillMap.bind(this));
|
||||
}
|
||||
|
||||
onQueryEntity(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
this.q.value = event.currentTarget.dataset.query;
|
||||
this.onQuery(event);
|
||||
}
|
||||
|
||||
onEntityDragStart(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
this.options.entity.current = event.currentTarget
|
||||
|
||||
this.mouseStartPosition = { x: event.pageX, y: event.pageY }
|
||||
this.entityStartPosition = { x: Number.parseFloat(this.options.entity.current.getAttribute("x")), y: Number.parseFloat(this.options.entity.current.getAttribute("y")) }
|
||||
|
||||
window.addEventListener("mouseup", this.entityUpHandler);
|
||||
|
||||
this.options.entity.dragging = true;
|
||||
}
|
||||
|
||||
onEntityMove(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
this.mousePosition = { x: event.offsetX, y: event.offsetY };
|
||||
|
||||
if(this.options.entity.dragging) {
|
||||
this.options.entity.current.setAttribute("x", this.entityStartPosition.x - (this.mouseStartPosition.x - event.pageX) * this.options.scale.current)
|
||||
this.options.entity.current.setAttribute("y", this.entityStartPosition.y - (this.mouseStartPosition.y - event.pageY) * this.options.scale.current)
|
||||
|
||||
let entity = this.entities.find(item => item.data.id == (this.options.entity.current.getAttribute("data-id")))
|
||||
let pos = { x: Number.parseFloat(this.options.entity.current.getAttribute("x")), y: Number.parseFloat(this.options.entity.current.getAttribute("y")) }
|
||||
|
||||
for(let line of entity.lines) {
|
||||
if(line.getAttribute("data-source") == entity.data.id) {
|
||||
line.setAttribute("x1", pos.x + (this.options.entity.width / 2));
|
||||
line.setAttribute("y1", pos.y + (this.options.entity.height / 2));
|
||||
} else {
|
||||
line.setAttribute("x2", pos.x + (this.options.entity.width / 2));
|
||||
line.setAttribute("y2", pos.y + (this.options.entity.height / 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onEntityDragStop(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
window.removeEventListener("mouseup", this.entityUpHandler);
|
||||
this.options.entity.dragging = false;
|
||||
}
|
||||
|
||||
onEntitySelect(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
let selected = this.entities.find(item => item.el.dataset.id == event.currentTarget.dataset.id);
|
||||
this.entities.forEach(item => {
|
||||
item.el.classList.remove('selected');
|
||||
item.el.classList.remove('related');
|
||||
item.lines.forEach(line => line.classList.remove('related'))
|
||||
});
|
||||
selected.el.classList.add('selected');
|
||||
selected.lines.forEach(line => {
|
||||
line.classList.add('related');
|
||||
let other = this.entities.find(item => (item.data.id == line.getAttribute('data-target') && line.getAttribute('data-source') == selected.data.id) || (item.data.id == line.getAttribute('data-source') && line.getAttribute('data-target') == selected.data.id));
|
||||
other.el.classList.add('related');
|
||||
});
|
||||
|
||||
this.setEntityDetail(selected.data);
|
||||
}
|
||||
|
||||
onMapScroll(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
let scale = 1. + (event.deltaY < 0 ? - this.options.scale.factor : this.options.scale.factor);
|
||||
|
||||
if((this.options.scale.current * scale < this.options.scale.max) && (this.options.scale.current * scale > this.options.scale.min))
|
||||
{
|
||||
let pos = {
|
||||
x: (this.mousePosition.x * this.options.scale.current) + this.viewboxPosition.x,
|
||||
y: (this.mousePosition.y * this.options.scale.current) + this.viewboxPosition.y
|
||||
}
|
||||
|
||||
this.viewboxPosition.x = (this.viewboxPosition.x - pos.x) * scale + pos.x;
|
||||
this.viewboxPosition.y = (this.viewboxPosition.y - pos.y) * scale + pos.y;
|
||||
this.options.scale.current *= scale;
|
||||
|
||||
this.setViewbox();
|
||||
}
|
||||
}
|
||||
|
||||
onMapDragStart(event) {
|
||||
this.mouseStartPosition = { x: event.pageX, y: event.pageY }
|
||||
this.viewboxStartPosition = { x: this.viewboxPosition.x, y: this.viewboxPosition.y }
|
||||
this.options.map.dragging = true;
|
||||
|
||||
window.addEventListener("mouseup", this.mouseUpHandler);
|
||||
}
|
||||
|
||||
onMapDragMove(event) {
|
||||
this.mousePosition = { x: event.offsetX, y: event.offsetY };
|
||||
|
||||
if(this.options.map.dragging) {
|
||||
this.viewboxPosition.x = this.viewboxStartPosition.x + (this.mouseStartPosition.x - event.pageX) * this.options.scale.current;
|
||||
this.viewboxPosition.y = this.viewboxStartPosition.y + (this.mouseStartPosition.y - event.pageY) * this.options.scale.current;
|
||||
this.setViewbox();
|
||||
}
|
||||
}
|
||||
|
||||
onMapDragStop(event) {
|
||||
window.removeEventListener("mouseup", this.mouseUpHandler);
|
||||
this.options.map.dragging = false;
|
||||
}
|
||||
|
||||
onMapResize(event) {
|
||||
this.viewboxSize = {
|
||||
x: this.find('.results').clientWidth,
|
||||
y: this.find('.results').clientHeight
|
||||
};
|
||||
|
||||
this.setViewbox();
|
||||
}
|
||||
|
||||
setViewbox() { this.map.setAttribute("viewBox", this.viewboxPosition.x + " " + this.viewboxPosition.y + " " + (this.viewboxSize.x * this.options.scale.current) + " " + (this.viewboxSize.y * this.options.scale.current)); }
|
||||
}
|
||||
|
||||
class DataExplorerFilter extends SelectEditor {
|
||||
|
||||
_template = `<div class="eicui-select-editor cols-2">
|
||||
<select eicselect placeholder="select a field"></select><input eicinput data-type="ignore" placeholder="set a value" />
|
||||
</div>`;
|
||||
|
||||
open() {
|
||||
super.open();
|
||||
this.input = this.components.find(c => c.el.nodeName == 'INPUT')
|
||||
this.select = this.components.find(c => c.el.nodeName == 'SELECT')
|
||||
this.select.clear();
|
||||
}
|
||||
|
||||
initEvents() {
|
||||
this.el.querySelector('input').addEventListener('keypress', this.onKeyPressed.bind(this));
|
||||
this.el.querySelector('select').addEventListener('change', this.onFieldChange.bind(this) );
|
||||
}
|
||||
|
||||
onFieldChange(event) {
|
||||
this.input.disabled = this.select.value.length == 0;
|
||||
}
|
||||
|
||||
get valid() { return super.valid && this.el.querySelector('select').value != ''; }
|
||||
|
||||
get value() { return {value: this.el.querySelector('select').value + "=" + this.el.querySelector('input').value, label: this.el.querySelector('select').value + ' is "' + this.el.querySelector('input').value + '"' } }
|
||||
|
||||
}
|
||||
|
||||
app.registerClass('DataExplorerView', DataExplorerView);
|
||||
@@ -1,82 +0,0 @@
|
||||
<style>
|
||||
.admin-access-control > header {
|
||||
background: url(/app/assets/images/cards/eic_purple_banner.png);
|
||||
background-position: top;
|
||||
background-size: contain !important;
|
||||
background-repeat: no-repeat;
|
||||
background-color: #5336a3;
|
||||
border-bottom: 4px solid white !important;
|
||||
}
|
||||
.admin-access-control .platform-status { min-width:25vw; }
|
||||
.admin-access-control .platform-monitor {
|
||||
display: grid;
|
||||
justify-items: center;
|
||||
grid-gap: var(--eicui-base-spacing-m);
|
||||
}
|
||||
.admin-access-control .platform-monitor .grants { text-align: center; line-height:150% }
|
||||
.admin-access-control .active-users-grid .row { grid-template-columns: 1fr 2fr 3fr 2fr 110px; }
|
||||
.admin-access-control .active-users-grid .actions > div {
|
||||
display: inline-grid;
|
||||
grid-gap: var(--eicui-base-spacing-2xs);
|
||||
grid-auto-flow: column;
|
||||
}
|
||||
.admin-access-control .active-users-grid .dataset .cell:nth-child(2) { text-align: center; }
|
||||
.admin-access-control .active-users-grid .dataset .cell:nth-child(5) { text-align: center; }
|
||||
.admin-access-control .active-users-grid .dataset .cell:nth-child(6) { text-align: right; }
|
||||
</style>
|
||||
<article eiccard media class="admin-access-control">
|
||||
<header>
|
||||
<h1>Users Access Management</h1>
|
||||
<h2>EIC Platform Administration</h2>
|
||||
</header>
|
||||
<section>
|
||||
<div class="cols-2 left">
|
||||
<div>
|
||||
<article warning eiccard class="platform-status">
|
||||
<section class="platform-monitor">Unknown state</section>
|
||||
<footer>
|
||||
<div class="cols-2">
|
||||
<button small primary eicbutton class="start" data-trigger="onStartPlatform"><span>Free access</span></button>
|
||||
<button small danger eicbutton class="stop" data-trigger="onStopPlatform"><span>Restrict access</span></button>
|
||||
</div>
|
||||
</footer>
|
||||
</article>
|
||||
<article eiccard class="banned-users">
|
||||
<header>
|
||||
<h1>Banned users</h1>
|
||||
</header>
|
||||
<section>
|
||||
<div eicdatagrid class="banned-users-grid" xsmall></div>
|
||||
</section>
|
||||
<footer>
|
||||
<div class="cols-1 right"><button eicbutton primary small disabled><span>Add</span></button></div>
|
||||
</footer>
|
||||
</article>
|
||||
|
||||
</div>
|
||||
<div>
|
||||
<article eiccard class="ws-users">
|
||||
<header>
|
||||
<div class="cols-2 right">
|
||||
<h1>Active user sessions</h1>
|
||||
<!--<button primary small eicbutton data-trigger="refreshUsers"><span>Refresh</span></button>-->
|
||||
</div>
|
||||
</header>
|
||||
<section>
|
||||
<div eicdatagrid class="active-users-grid" xsmall></div>
|
||||
</section>
|
||||
<footer>
|
||||
<div class="actions cols-2">
|
||||
<div></div>
|
||||
<div class="cols-2">
|
||||
<button eicbutton class="kick-all" danger small data-trigger="onUsersKick"><span>Kick all</span></button>
|
||||
<button eicbutton class="message-all" primary small data-trigger="onUsersMessage"><span>Message all</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</article>
|
||||
|
||||
@@ -1,391 +0,0 @@
|
||||
class AdminAccessControlView extends EICDomContent {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
Object.assign(this, app.helpers.basicDialogs)
|
||||
}
|
||||
|
||||
refreshRate = 1000;
|
||||
|
||||
DOMContentLoaded(options) {
|
||||
for(let model in options.models) this[model] = options.models[model];
|
||||
|
||||
this.components = ui.eicfy(this.el);
|
||||
|
||||
this.buttonStart = this.components.find(component => component.el.classList.contains('start'));
|
||||
this.buttonStop = this.components.find(component => component.el.classList.contains('stop'));
|
||||
|
||||
this.gridUsers = new DataGrid(this.find('.active-users-grid'), {
|
||||
headers: [
|
||||
{ label: 'Online', type:'markup', filter: 'list', sortable: true},
|
||||
{ label: 'EU Login', type:'markup', filter: 'text', sortable: true},
|
||||
{ label: 'Full name', type:'markup', filter: 'text', sortable: true},
|
||||
{ label: 'Last req.', type:'markup', filter: false, sortable: true},
|
||||
],
|
||||
height: '60vh'
|
||||
});
|
||||
|
||||
this.gridBannedUsers = new DataGrid(this.find('.banned-users-grid'), {
|
||||
headers: [ { label: 'EU Login', type:'markup', filter: 'text'} ],
|
||||
height: '40vh'
|
||||
});
|
||||
|
||||
this.initEvents();
|
||||
this.startAutoRefreshUser()
|
||||
this.startAutoRefreshPlatform()
|
||||
}
|
||||
|
||||
initEvents() {
|
||||
let triggers = this.components.filter(c => ![ '', undefined ].includes( c.el.dataset.trigger) );
|
||||
for(let element of triggers) {
|
||||
if(typeof this[element.el.dataset.trigger] === 'function') {
|
||||
element.click = this[element.el.dataset.trigger].bind(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DOMContentRemoved(){
|
||||
this.stopAutoRefreshUser()
|
||||
this.stopAutoRefreshPlatform()
|
||||
}
|
||||
|
||||
DOMContentFocused(){
|
||||
this.startAutoRefreshUser()
|
||||
this.startAutoRefreshPlatform()
|
||||
}
|
||||
|
||||
DOMContentBlured(){
|
||||
this.stopAutoRefreshUser()
|
||||
this.stopAutoRefreshPlatform()
|
||||
}
|
||||
|
||||
startAutoRefreshPlatform(){
|
||||
if(this.refreshPlatformTo) return
|
||||
this.refreshPlatformTo = null
|
||||
this.refreshPlatformActive = true
|
||||
this.refreshPlatform()
|
||||
}
|
||||
|
||||
stopAutoRefreshPlatform(){
|
||||
if(this.refreshPlatformTo){
|
||||
clearTimeout(this.refreshPlatformTo)
|
||||
this.refreshPlatformTo = null
|
||||
}
|
||||
this.refreshPlatformActive = false
|
||||
}
|
||||
|
||||
refreshPlatform(){
|
||||
if(this.refreshPlatformTo){
|
||||
clearTimeout(this.refreshPlatformTo)
|
||||
this.refreshPlatformTo = null
|
||||
}
|
||||
this.platform.getPlatformStatus().then(this.fillPlatformState.bind(this))
|
||||
if(this.refreshPlatformActive) this.refreshPlatformTo = setTimeout(this.refreshPlatform.bind(this),this.refreshRate)
|
||||
}
|
||||
|
||||
startAutoRefreshUser(){
|
||||
if(this.refreshUserTo) return
|
||||
this.refreshUserTo = null
|
||||
this.refreshUserActive = true
|
||||
this.refreshUsers()
|
||||
}
|
||||
|
||||
stopAutoRefreshUser(){
|
||||
if(this.refreshUserTo){
|
||||
clearTimeout(this.refreshUserTo)
|
||||
this.refreshUserTo = null
|
||||
}
|
||||
this.refreshUserActive = false
|
||||
}
|
||||
|
||||
refreshUsers(event){
|
||||
|
||||
if(this.refreshUserTo){
|
||||
clearTimeout(this.refreshUserTo)
|
||||
this.refreshUserTo = null
|
||||
}
|
||||
this.platform.getUsers().then(this.fillUsers.bind(this))
|
||||
if(this.refreshUserActive) this.refreshUserTo = setTimeout(this.refreshUsers.bind(this), this.refreshRate)
|
||||
}
|
||||
|
||||
fillUsers(list) {
|
||||
if(!list) return
|
||||
// seriously ?
|
||||
const noKickRoles = ['EIC_Admin', 'EIC_Dev'] // just for display, anti-foot-shoot exists BE side
|
||||
|
||||
this.gridUsers.loading = false;
|
||||
this.gridUsers.clear()
|
||||
for(let item of list) {
|
||||
let lastAjax = 3600-item.sessionExpire
|
||||
lastAjax = lastAjax<60 ? `${lastAjax} sec` : `${Math.floor(lastAjax/60)} min ${lastAjax%60} sec`
|
||||
let row = this.gridUsers.addRow(item.uid, [
|
||||
`<span style="font-size:0">${item.busConnected ? 'Yes': 'No'}</span><span ${item.busConnected ? 'success': 'danger'} small class="icon-big-bullet"></span>`,
|
||||
item.uid,
|
||||
`<span title="${item.given_name + ' ' + item.family_name}">${item.given_name + ' ' + item.family_name}</span>`,
|
||||
`<span style="font-size:0">${item.sessionExpire}</span><span>${lastAjax}</span>`
|
||||
]);
|
||||
let buttonBar = ui.create(`<div></div>`)
|
||||
let btnMsg = ui.create(`<button eicbutton class="icon-coaching message" data-uid="${item.uid}" rounded primary xsmall title="send message"></button>`)
|
||||
btnMsg.addEventListener('click',this.onUserMessage.bind(this))
|
||||
buttonBar.appendChild(btnMsg);
|
||||
|
||||
let intersect = noKickRoles.filter(value => item.userRoles.includes(value));
|
||||
if(intersect.length==0){
|
||||
let btnKick = ui.create(`<button eicbutton class="icon-logoff kick" data-uid="${item.uid}" rounded warning xsmall title="Terminate session"></button>`)
|
||||
btnKick.addEventListener('click',this.onUserKick.bind(this))
|
||||
buttonBar.appendChild(btnKick);
|
||||
|
||||
let btnBan = ui.create(`<button eicbutton class="icon-locked ban" data-uid="${item.uid}" rounded danger xsmall title="Ban from the platform"></button>`)
|
||||
btnBan.addEventListener('click',this.onUserBan.bind(this))
|
||||
buttonBar.appendChild(btnBan);
|
||||
}
|
||||
|
||||
row.querySelector('.cell.actions').appendChild(buttonBar);
|
||||
}
|
||||
}
|
||||
|
||||
fillPlatformState(data) {
|
||||
let article = new Card(this.find('.platform-status'));
|
||||
let alert = this.find('.platform-status > section');
|
||||
|
||||
if(data) {
|
||||
this.fillBannedUsers(data.blockedUUIDs)
|
||||
if(data.platformRestrictions) {
|
||||
article.severity = 'danger';
|
||||
alert.innerHTML = `<span danger xlarge class="icon-locked"></span>
|
||||
<span danger><b>access restricted</b></span>
|
||||
<span success><b>granted access:</b></span>
|
||||
<div class="grants">
|
||||
${data.platformRestrictions.allowedRoles.map(item=>('<span info xsmall eicchip title="Group ' + item + ' allowed"><label>'+item+'</label></span>')).join('')}
|
||||
${data.platformRestrictions.allowedUUIDs.map(item=>('<span primary xsmall eicchip title="User ' + item + ' allowed">'+item+'</span>')).join('')}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
ui.eicfy(alert);
|
||||
//buttonsstop stays visible to allow changing allowed roles & uuids
|
||||
this.buttonStop.disabled = false;
|
||||
this.buttonStart.disabled = false;
|
||||
|
||||
} else {
|
||||
article.severity = 'success'
|
||||
alert.innerHTML = `<span success xlarge class="icon-unlocked"></span>
|
||||
<span success><b>no restrictions</b></span>`
|
||||
|
||||
this.buttonStop.disabled = false;
|
||||
this.buttonStart.disabled = true;
|
||||
}
|
||||
} else {
|
||||
article.severity = 'warning'
|
||||
alert.innerHTML = `<span warning xlarge class="icon-bug"></span>
|
||||
<span warning><b>status report unavailable</b></span>`
|
||||
this.buttonStart.disabled = true;
|
||||
this.buttonStop.disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
fillDaemonsState(list){
|
||||
for(let daemon of Object.keys(list)){
|
||||
let led = this.find(`.status-${daemon}`)
|
||||
let tmstp = this.find(`.time-${daemon}`)
|
||||
if(led){
|
||||
led.innerHTML = `<span ${list[daemon] ? 'success': 'danger'} small class="icon-big-bullet"></span>`
|
||||
if(list[daemon]){
|
||||
tmstp.innerHTML = `${list[daemon] ? list[daemon].substr(11,8) : ''}`
|
||||
ui.show(tmstp, 'inline-flex')
|
||||
} else {
|
||||
ui.hide(tmstp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fillBannedUsers(list) {
|
||||
if(!list) return
|
||||
this.gridBannedUsers.clear()
|
||||
for(let uid of list) {
|
||||
let row = this.gridBannedUsers.addRow(uid, [
|
||||
uid,
|
||||
]);
|
||||
let buttonBar = ui.create(`<div></div>`)
|
||||
let btnUnban = ui.create(`<button eicbutton class="icon-unlocked unban" data-uid="${uid}" rounded primary xsmall title="Un-ban"></button>`)
|
||||
btnUnban.addEventListener('click',this.onUserUnban.bind(this))
|
||||
buttonBar.appendChild(btnUnban);
|
||||
row.querySelector('.cell.actions').appendChild(buttonBar);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async onStopPlatform(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
let uid = event.currentTarget.dataset.uid;
|
||||
let result = await this.openDialog(
|
||||
await this.loadContent(
|
||||
'system/admin/platform-control/dialogs/PlatformDownDialog',
|
||||
{ title: `Restricting platform access` },
|
||||
{ platform: this.platform }
|
||||
)
|
||||
);
|
||||
|
||||
if(result) {
|
||||
this.platform.stopPlatform(result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async onStartPlatform(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
let result = await this.confirmDialog({
|
||||
title: 'Releasing platform restrictions',
|
||||
message: `<p>You are about to remove restrictions on the EIC platform.</p>
|
||||
<p>All users will be able to connect again.</p>`,
|
||||
okLabel: 'Free access',
|
||||
severity: 'primary',
|
||||
})
|
||||
|
||||
if(result) {
|
||||
this.platform.startPlatform(result);
|
||||
}
|
||||
}
|
||||
|
||||
onUsersUpdate(event) { this.fillUsers(event.data.users); }
|
||||
|
||||
/**
|
||||
* Growls a message to a user through bus
|
||||
*/
|
||||
async onUserMessage(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
let uid = event.currentTarget.dataset.uid;
|
||||
let result = await this.openDialog(
|
||||
await this.loadContent(
|
||||
'system/admin/platform-control/dialogs/PlatformUserMessageDialog',
|
||||
{ title: `Warn user ${uid}` },
|
||||
{ }
|
||||
)
|
||||
);
|
||||
|
||||
if(result) {
|
||||
this.platform.growlOne(uid, result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Growls a message to all users through bus
|
||||
*/
|
||||
async onUsersMessage(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
let result = await this.openDialog(
|
||||
await this.loadContent(
|
||||
'system/admin/platform-control/dialogs/PlatformUserMessageDialog',
|
||||
{ title: `Warn user` },
|
||||
{ }
|
||||
)
|
||||
);
|
||||
|
||||
if(result) {
|
||||
this.platform.growlGlobal(result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Kicks a user though bus
|
||||
*/
|
||||
async onUserKick(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
let uid = event.currentTarget.dataset.uid;
|
||||
let result = await this.confirmDialog({
|
||||
title: 'Kick user',
|
||||
message: `<p>You are about to kick user <b>${uid}</b> from the platform.</p>
|
||||
<p>All of his current activities will be terminated.</p>`,
|
||||
okLabel: 'Kick',
|
||||
severity: 'danger',
|
||||
okPromise: () => { return(this.platform.kick(uid)) }
|
||||
})
|
||||
|
||||
if(result) {
|
||||
ui.growl.append(`User ${uid} has been kicked !`, 'success', 10000)
|
||||
if(!this.refreshUserActive) this.refreshUsers()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Kicks all users though bus
|
||||
*/
|
||||
async onUsersKick(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
let result = await this.confirmDialog({
|
||||
title: 'Kick all users',
|
||||
message: `<p>You are about to kick <b>ALL</b> users from the platform.</p>
|
||||
<p>All of their current activities will be terminated.</p>`,
|
||||
okLabel: 'Kick',
|
||||
severity: 'danger',
|
||||
okPromise: () => { return(this.platform.kickAll()) }
|
||||
})
|
||||
|
||||
if(result) {
|
||||
ui.growl.append(`All users (except Admins & Devs) have been kicked !`, 'success', 10000)
|
||||
if(!this.refreshUserActive) this.refreshUsers()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Bans a user from the platform though bus
|
||||
*/
|
||||
async onUserBan(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
let uid = event.currentTarget.dataset.uid;
|
||||
let result = await this.confirmDialog({
|
||||
title: 'Ban user',
|
||||
message: `<p>You are about to <b>ban</b> user <b>${uid}</b> from the platform.</p>
|
||||
<p>All of his current activities will be terminated
|
||||
and he won't be able to login again.</p>`,
|
||||
okLabel: 'Ban',
|
||||
severity: 'danger',
|
||||
okPromise: () => { return(this.platform.ban(uid)) }
|
||||
})
|
||||
|
||||
if(result) {
|
||||
ui.growl.append(`User ${uid} has been banned !`, 'success', 10000)
|
||||
if(!this.refreshPlatformActive) this.refreshPlatform()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bans a user from the platform though bus
|
||||
*/
|
||||
async onUserUnban(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
let uid = event.currentTarget.dataset.uid;
|
||||
let result = await this.confirmDialog({
|
||||
title: 'Unban user',
|
||||
message: `<p>You are about to allow <b>${uid}</b> back on the platform.</p>`,
|
||||
okLabel: 'Unban',
|
||||
severity: 'success',
|
||||
okPromise: () => { return(this.platform.unban(uid)) }
|
||||
})
|
||||
|
||||
if(result) {
|
||||
ui.growl.append(`User ${uid} has been unbanned !`, 'success', 10000)
|
||||
if(!this.refreshPlatformActive) this.refreshPlatform()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
app.registerClass('AdminAccessControlView', AdminAccessControlView);
|
||||
@@ -1,10 +0,0 @@
|
||||
<style>
|
||||
.config-snipet{
|
||||
background-color: #000;
|
||||
padding: 5px;
|
||||
width: 100vh;
|
||||
}
|
||||
</style>
|
||||
<div class="system-message-form">
|
||||
<pre class="config-snipet"><code class="view-config language-json"></code></pre>
|
||||
</div>
|
||||
@@ -1,27 +0,0 @@
|
||||
class PlatformConfigViewDialog extends EICDialogContent {
|
||||
|
||||
actions = [
|
||||
{
|
||||
label: 'ok',
|
||||
onclick: this.confirm.bind(this),
|
||||
severity: 'primary',
|
||||
role: 'confirm'
|
||||
}
|
||||
]
|
||||
|
||||
DOMContentLoaded(options) {
|
||||
ui.eicfy(this.el);
|
||||
this.codeBox = this.find('.view-config')
|
||||
let snipet = hljs.highlight(JSON.stringify(options.config, null, 4), { 'language':'json'} );
|
||||
this.codeBox.innerHTML = snipet.value
|
||||
}
|
||||
|
||||
confirm(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
this.commit();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
app.registerClass('PlatformConfigViewDialog', PlatformConfigViewDialog);
|
||||
@@ -1,18 +0,0 @@
|
||||
<style>
|
||||
.system-message-form .allowed-users{ /* room for the popup-input */
|
||||
min-height: calc(8*var(--base-font-size));
|
||||
}
|
||||
</style>
|
||||
<div class="system-message-form">
|
||||
<p danger>You are about to restrict the EIC platform access.</p>
|
||||
<p>All users will be disconnected and unable to login anymore.</p>
|
||||
<p>Only specific roles and users selected below will still have access.</p>
|
||||
<div>
|
||||
<label>Allowed roles:</label>
|
||||
<select eicselect name="allowedRoles" multiple></select>
|
||||
</div>
|
||||
<div class="allowed-users">
|
||||
<label>Allowed EU-logins:</label>
|
||||
<select eicselect name="allowedUUIDs" editable data-type="array" class="" placeholder="Type EUlogin-ID and press enter" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,72 +0,0 @@
|
||||
class PlatformDownDialog extends EICDialogContent {
|
||||
|
||||
actions = [
|
||||
{
|
||||
label: 'cancel',
|
||||
onclick: this.cancel.bind(this),
|
||||
severity: 'secondary',
|
||||
role: 'cancel'
|
||||
},
|
||||
{
|
||||
label: 'Restrict access',
|
||||
onclick: this.confirm.bind(this),
|
||||
severity: 'danger',
|
||||
role: 'confirm'
|
||||
}
|
||||
]
|
||||
|
||||
DOMContentLoaded(options) {
|
||||
let components = ui.eicfy(this.el)
|
||||
|
||||
this.RolesSelect = components.find(component => component.el.name == 'allowedRoles')
|
||||
this.UUIDsSelect = components.find(component => component.el.name == 'allowedUUIDs')
|
||||
|
||||
options.platform.getPlatformStatus().then(this.fillSelects.bind(this))
|
||||
|
||||
this.form = new Form(this.el);
|
||||
}
|
||||
|
||||
fillSelects(data){
|
||||
let allowedRoles = []
|
||||
let allowedUUIDs = []
|
||||
if(data.platformRestrictions && Array.isArray(data.platformRestrictions.allowedRoles)) {
|
||||
allowedRoles = data.platformRestrictions.allowedRoles
|
||||
}
|
||||
if(data.platformRestrictions && Array.isArray(data.platformRestrictions.allowedUUIDs)) {
|
||||
allowedUUIDs = data.platformRestrictions.allowedUUIDs
|
||||
}
|
||||
|
||||
if(allowedRoles.indexOf('EIC_Dev')<0) allowedRoles.push('EIC_Dev') // Voluntarily hard-coded, other securities also BE-side
|
||||
|
||||
// Would be cool, but css issues & currently can't avoid getting the group item in the values.
|
||||
// let roleOptions = app.meta.toOptionsRecurse(app.meta.getCollection('user-roles'), allowedRoles, true)
|
||||
// this.RolesSelect.el.innerHTML = roleOptions ;
|
||||
|
||||
let RolesChildren = app.meta.getCollection('user-roles').reduce((acc, item)=>{ acc = [...acc, ...item.children]; return(acc)},[])
|
||||
let rolesOptions = app.meta.toOptions(RolesChildren, allowedRoles)
|
||||
rolesOptions.forEach(item => this.RolesSelect.el.append(item))
|
||||
//having several options selected (in a multiple) doesn't work when appending, but works on setting the value as an Array
|
||||
this.RolesSelect.value = allowedRoles
|
||||
this.UUIDsSelect.value = allowedUUIDs
|
||||
}
|
||||
|
||||
cancel(event){
|
||||
event.stopPropagation()
|
||||
event.preventDefault()
|
||||
this.RolesSelect.closeCatalog()
|
||||
super.cancel(event)
|
||||
}
|
||||
|
||||
confirm(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
this.RolesSelect.closeCatalog()
|
||||
this.actions.forEach(item=> {item.button.loading=true; item.button.disabled=true} )
|
||||
if(this.form.validate()) {
|
||||
this.commit(this.form.value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
app.registerClass('PlatformDownDialog', PlatformDownDialog);
|
||||
@@ -1,32 +0,0 @@
|
||||
<div class="system-message-form">
|
||||
<label>Please provide the message you want to send:</label>
|
||||
|
||||
<div>
|
||||
<label>Predefined messages:</label>
|
||||
<select eicselect name="predefined"></select>
|
||||
</div>
|
||||
|
||||
<div class="cols-2">
|
||||
<div>
|
||||
<label>severity:</label>
|
||||
<select eicselect name="growlSeverity">
|
||||
<option value="secondary">secondary</option>
|
||||
<option value="primary">primary</option>
|
||||
<option value="danger">danger</option>
|
||||
<option value="success">success</option>
|
||||
<option value="warning">warning</option>
|
||||
<option value="info">info</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label>duration:</label>
|
||||
<input eicinput type="number" name="growlTime" value="5" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>message:</label>
|
||||
<textarea eictextarea name="growlMessage" data-path="" class="required" rows="6"></textarea>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -1,58 +0,0 @@
|
||||
class PlatformUserMessageDialog extends EICDialogContent {
|
||||
|
||||
actions = [
|
||||
{
|
||||
label: 'cancel',
|
||||
onclick: this.cancel.bind(this),
|
||||
severity: 'secondary',
|
||||
role: 'cancel'
|
||||
},
|
||||
{
|
||||
label: 'send',
|
||||
onclick: this.confirm.bind(this),
|
||||
severity: 'primary',
|
||||
role: 'confirm'
|
||||
}
|
||||
]
|
||||
|
||||
DOMContentLoaded(options) {
|
||||
let components = ui.eicfy(this.el);
|
||||
this.messagesSelect = components.find(component => component.el.name == 'predefined')
|
||||
this.growlSeverity = components.find(component => component.el.name == 'growlSeverity')
|
||||
this.growlTime = components.find(component => component.el.name == 'growlTime')
|
||||
this.growlMessage = components.find(component => component.el.name == 'growlMessage')
|
||||
|
||||
let messagesSelectOptions = app.meta.toOptions(app.meta.getCollection('user-messages'),[],true)
|
||||
messagesSelectOptions.forEach(item => this.messagesSelect.el.append(item))
|
||||
this.messagesSelect.change(this.onMessageChange.bind(this));
|
||||
this.form = new Form(this.el);
|
||||
}
|
||||
|
||||
confirm(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
this.actions.forEach(item=> {item.button.loading=true; item.button.disabled=true} )
|
||||
if(this.form.validate()) {
|
||||
this.commit(this.form.value);
|
||||
} else {
|
||||
this.actions.forEach(item=> {item.button.loading=false; item.button.disabled=false} )
|
||||
}
|
||||
}
|
||||
|
||||
onMessageChange(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
if(this.messagesSelect.value) {
|
||||
let msgData = app.meta.getCollection('user-messages').find(item=>item.id==this.messagesSelect.value)
|
||||
this.growlSeverity.value = msgData.severity
|
||||
this.growlTime.value = msgData.duration
|
||||
this.growlMessage.value = msgData.message.join('\n')
|
||||
} else {
|
||||
this.growlSeverity.value = 'secondary'
|
||||
this.growlTime.value = 5
|
||||
this.growlMessage.value = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
app.registerClass('PlatformUserMessageDialog', PlatformUserMessageDialog);
|
||||
@@ -1,80 +0,0 @@
|
||||
<style>
|
||||
.chalkboard > header { background: url('/app/assets/images/cards/chalkboard.jpg'); }
|
||||
.chalkboard .toolbox {
|
||||
text-align: center;
|
||||
}
|
||||
.chalkboard .board .dummy {
|
||||
display: block;
|
||||
height: 0;
|
||||
}
|
||||
.chalkboard canvas {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
cursor:default;
|
||||
}
|
||||
.chalkboard canvas.drawing {
|
||||
cursor:crosshair;
|
||||
}
|
||||
.chalkboard .toolbox .color-sample {
|
||||
display: inline-grid;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 1px solid black !important;
|
||||
margin: 1px !important;
|
||||
}
|
||||
.chalkboard .toolbox .pen-sample {
|
||||
display: inline-grid;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
border: 1px solid black !important;
|
||||
margin: 1px !important;
|
||||
}
|
||||
.chalkboard .toolbox span.selected {
|
||||
border-color: var(--eicui-base-color-accessible-focus) !important;
|
||||
box-shadow: inset 0 0 0 1px var(--eicui-base-color-accessible-focus),inset 0 0 0 2px var(--eicui-base-color-grey-5);
|
||||
transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out;
|
||||
}
|
||||
.chalkboard .board .users {
|
||||
width: fit-content;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
<article eiccard media class="chalkboard">
|
||||
<header>
|
||||
<h1>Magic Chalkboard</h1>
|
||||
<h2>Collaborative artworks</h2>
|
||||
</header>
|
||||
<section>
|
||||
<div class="cols-2 left top">
|
||||
<div class="toolbox">
|
||||
<input eicinput type="hidden" name="color" value="white" />
|
||||
<input eicinput type="hidden" name="width" value="2" />
|
||||
|
||||
<div class="colors">
|
||||
<span class="color-sample selected" data-id="white" data-value="rgba(255,255,255,1)" style="background:rgba(255,255,255,1)"></span>
|
||||
<span class="color-sample" data-id="blue" data-value="rgba(0, 42, 255, 1)" style="background:rgba(0, 42, 255, 1)"></span>
|
||||
<span class="color-sample" data-id="red" data-value="rgba(255, 0, 0, 1)" style="background:rgba(255, 0, 0, 1)"></span>
|
||||
<span class="color-sample" data-id="yellow" data-value="rgba(255, 247, 6, 1)" style="background:rgba(255, 247, 6, 1)"></span>
|
||||
<span class="color-sample" data-id="green" data-value="rgba(54, 255, 8, 1)" style="background:rgba(54, 255, 8, 1)"></span>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="pens">
|
||||
<span class="pen-sample icon-big-bullet selected" xxsmall data-value="2"></span>
|
||||
<span class="pen-sample icon-big-bullet" xsmall data-value="4"></span>
|
||||
<span class="pen-sample icon-big-bullet" small data-value="6"></span>
|
||||
</div>
|
||||
<hr/>
|
||||
<button class="clear-board" eicbutton icon="icon-bin" xsmall danger></button>
|
||||
<button class="dl-board" eicbutton icon="icon-download" xsmall info></button>
|
||||
</div>
|
||||
<div class="board">
|
||||
<span class="dummy">*</span>
|
||||
<canvas></canvas>
|
||||
<div class="users"></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</article>
|
||||
@@ -1,318 +0,0 @@
|
||||
/**
|
||||
* Magic Chalkboard demo app
|
||||
*
|
||||
* A simple app to share an editable canvas between bus users.
|
||||
* Demonstrates :
|
||||
* - subscription to a custom channel
|
||||
* - burst event send/receive of custom event types
|
||||
* - lightspeed response time of events broadcasting
|
||||
* - accuracy and reliability of event queuing
|
||||
* - implementation of app design with bus connected/disconnected.
|
||||
*
|
||||
* @author Michael Fallise
|
||||
* @version 1.0
|
||||
*/
|
||||
class ChalkboardView extends EICDomContent {
|
||||
|
||||
options = {
|
||||
background: 'rgba(0,0,0,1)',
|
||||
busChannel: 'collaborative:chalkboard'
|
||||
}
|
||||
|
||||
DOMContentLoaded() {
|
||||
|
||||
let components = ui.eicfy(this.el);
|
||||
|
||||
this.useBus = false;
|
||||
this.busUsers = [];
|
||||
|
||||
this.toolbox = new Form(this.find('.toolbox'));
|
||||
|
||||
let colors = this.findAll('.color-sample');
|
||||
for(let color of colors) color.addEventListener('click', this.onColorChange.bind(this));
|
||||
|
||||
let pens = this.findAll('.pen-sample');
|
||||
for(let pen of pens) pen.addEventListener('click', this.onPenChange.bind(this));
|
||||
|
||||
let dl = components.find(item => item.el.classList.contains('dl-board'));
|
||||
dl.addEventListener('click', this.onBoardDownload.bind(this));
|
||||
|
||||
let clear = components.find(item => item.el.classList.contains('clear-board'));
|
||||
clear.addEventListener('click', this.onBoardClear.bind(this));
|
||||
|
||||
this.board = this.find('canvas');
|
||||
this.board.style.background = this.options.background;
|
||||
this.ctx = this.board.getContext("2d");
|
||||
this.ctx.lineCap = 'round';
|
||||
|
||||
this.drawing = this.eraser = false;
|
||||
this.mouseCurrent = { x: 0, y: 0 };
|
||||
this.mousePrev = { x: 0, y: 0 };
|
||||
|
||||
// referencing computed event handlers
|
||||
this.mouseDownHandler = this.onChalkStart.bind(this);
|
||||
this.mouseMoveHandler = this.onChalkMove.bind(this);
|
||||
this.mouseUpHandler = this.onChalkEnd.bind(this);
|
||||
this.busDrawHandler = this.onBusDraw.bind(this);
|
||||
this.busClearHandler = this.onBusClear.bind(this);
|
||||
this.busPingHandler = this.onBusPing.bind(this);
|
||||
this.busJoinHandler = this.onBusJoin.bind(this);
|
||||
this.busLeaveHandler = this.onBusLeave.bind(this);
|
||||
|
||||
this.setBrush();
|
||||
this.setBoardSize();
|
||||
this.clear();
|
||||
this.initListeners();
|
||||
}
|
||||
|
||||
DOMContentRemoved() { this.closeListeners(); }
|
||||
|
||||
DOMContentResized() {
|
||||
let data = this.board.toDataURL('image/png');
|
||||
this.setBoardSize();
|
||||
let img = new Image;
|
||||
let self = this
|
||||
img.onload = function() { self.ctx.drawImage(img, 0, 0); };
|
||||
img.src = data;
|
||||
|
||||
}
|
||||
|
||||
setBoardSize() {
|
||||
let rect = this.board.getBoundingClientRect()
|
||||
this.board.width = rect.width;
|
||||
this.board.height = rect.height;
|
||||
}
|
||||
|
||||
/* Nike to Mike : As planned, made higher-level addBusListener & removeBusListener
|
||||
* Changes : Includes channel filtering (important to avoid chan injections by script-kiddies)
|
||||
*
|
||||
* You can replace old-style :
|
||||
* app.events.addEvent('MessageBus.XXX', handler, scope)
|
||||
* app.events.removeEvent('MessageBus.XXX', handler, scope)
|
||||
* => handler receives pure JS event, and probably uses e.detail.payload
|
||||
*
|
||||
* by new-style:
|
||||
* app.MessageBus.addBusListener('XXX', [this.busChannel], handler, scope)
|
||||
* app.MessageBus.removeBusListener('XXX', handler, scope)
|
||||
* => handler receives (realChan, payload, sender)
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
initListeners() {
|
||||
this.board.addEventListener('mousedown', this.mouseDownHandler);
|
||||
this.board.addEventListener('mousemove', this.mouseMoveHandler);
|
||||
this.board.addEventListener('mouseup', this.mouseUpHandler);
|
||||
// disabling context menu on canvas in order to use right button for eraser
|
||||
this.board.oncontextmenu = function() { return false;}
|
||||
|
||||
if(app.MessageBus.connected) {
|
||||
console.log("USING BUS")
|
||||
app.MessageBus.subscribe([this.options.busChannel])
|
||||
.then( payload => {
|
||||
app.MessageBus.addBusListener('board_draw', ['collaborative:chalkboard'], this.busDrawHandler, 'chalkboard');
|
||||
app.MessageBus.addBusListener('board_clear', ['collaborative:chalkboard'], this.busClearHandler, 'chalkboard');
|
||||
app.MessageBus.addBusListener('board_ping', ['collaborative:chalkboard'], this.busPingHandler, 'chalkboard');
|
||||
app.MessageBus.addBusListener('board_join', ['collaborative:chalkboard'], this.busJoinHandler, 'chalkboard');
|
||||
app.MessageBus.addBusListener('board_leave', ['collaborative:chalkboard'], this.busLeaveHandler, 'chalkboard');
|
||||
this.useBus = true;
|
||||
this.pingUsers();
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
closeListeners() {
|
||||
if(this.useBus) {
|
||||
app.MessageBus.removeBusListener('board_draw', this.busDrawHandler, 'chalkboard');
|
||||
app.MessageBus.removeBusListener('board_clear', this.busClearHandler, 'chalkboard');
|
||||
app.MessageBus.removeBusListener('board_join', this.busJoinHandler, 'chalkboard');
|
||||
app.MessageBus.removeBusListener('board_ping', this.busPingHandler, 'chalkboard');
|
||||
app.MessageBus.removeBusListener('board_leave', this.busLeaveHandler, 'chalkboard');
|
||||
this.leaveApp();
|
||||
this.useBus = false;
|
||||
}
|
||||
}
|
||||
|
||||
setBrush() { this.brush = this.toolbox.value; }
|
||||
|
||||
draw(brush, from, to) {
|
||||
this.ctx.fillStyle = brush.color;
|
||||
this.ctx.strokeStyle = brush.color;
|
||||
this.ctx.lineWidth = brush.width;
|
||||
this.ctx.beginPath();
|
||||
this.ctx.moveTo(from.x, from.y);
|
||||
this.ctx.lineTo(to.x, to.y);
|
||||
this.ctx.stroke();
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.ctx.fillStyle = this.options.background;
|
||||
this.ctx.fillRect(0, 0, this.board.width, this.board.height);
|
||||
this.ctx.fillStyle = this.brush.color;
|
||||
}
|
||||
|
||||
onChalkStart(event) {
|
||||
this.drawing = true;
|
||||
this.eraser = event.button == 2,
|
||||
|
||||
this.mousePrev.x = this.mouseCurrent.x;
|
||||
this.mousePrev.y = this.mouseCurrent.y;
|
||||
|
||||
this.setBrush();
|
||||
}
|
||||
|
||||
onChalkMove(event) {
|
||||
|
||||
let rect = event.target.getBoundingClientRect();
|
||||
|
||||
this.mouseCurrent.x = event.pageX - rect.left;
|
||||
this.mouseCurrent.y = event.pageY - rect.top;
|
||||
|
||||
if(this.drawing) {
|
||||
|
||||
this.board.classList.add('drawing');
|
||||
|
||||
let brush = this.eraser ? { color: this.options.background, width: 20 }: this.brush;
|
||||
|
||||
if(this.useBus) {
|
||||
app.MessageBus.sendEvent(this.options.busChannel,'board_draw', {
|
||||
uid: app.User.identity.uuid,
|
||||
brush: brush,
|
||||
from: this.mousePrev,
|
||||
to: this.mouseCurrent,
|
||||
});
|
||||
} else {
|
||||
this.draw(brush, this.mousePrev, this.mouseCurrent);
|
||||
}
|
||||
|
||||
this.mousePrev.x = this.mouseCurrent.x;
|
||||
this.mousePrev.y = this.mouseCurrent.y;
|
||||
}
|
||||
}
|
||||
|
||||
onChalkEnd(event) {
|
||||
this.drawing = this.eraser = false;
|
||||
this.board.classList.remove('drawing');
|
||||
}
|
||||
|
||||
onColorChange(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
this.find('.color-sample.selected').classList.remove('selected');
|
||||
|
||||
let color = event.currentTarget;
|
||||
color.classList.add('selected');
|
||||
this.find('input[name="color"]').value = color.dataset.value;
|
||||
}
|
||||
|
||||
onPenChange(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
this.find('.pen-sample.selected').classList.remove('selected');
|
||||
|
||||
let pen = event.currentTarget;
|
||||
pen.classList.add('selected');
|
||||
this.find('input[name="width"]').value = pen.dataset.value;
|
||||
}
|
||||
|
||||
onBusPing(event) {
|
||||
let payload = {
|
||||
uid: app.User.identity.uuid,
|
||||
name: app.User.identity.firstname + ' ' + app.User.identity.lastname
|
||||
}
|
||||
|
||||
app.MessageBus.sendEvent(this.options.busChannel,'board_join', payload);
|
||||
}
|
||||
|
||||
joinApp() {
|
||||
let payload = {
|
||||
uid: app.User.identity.uuid,
|
||||
name: app.User.identity.firstname + ' ' + app.User.identity.lastname
|
||||
}
|
||||
|
||||
app.MessageBus.sendEvent(this.options.busChannel,'board_join', payload);
|
||||
}
|
||||
|
||||
leaveApp() { app.MessageBus.sendEvent(this.options.busChannel,'board_leave'); }
|
||||
|
||||
pingUsers() {
|
||||
this.busUsers = [];
|
||||
|
||||
let container = this.find('.users');
|
||||
container.innerHTML = '';
|
||||
|
||||
app.MessageBus.sendEvent(this.options.busChannel,'board_ping');
|
||||
}
|
||||
|
||||
refreshUsers() {
|
||||
let container = this.find('.users');
|
||||
console.log('', this.busUsers)
|
||||
for(let user of this.busUsers) {
|
||||
if(!user.tag) {
|
||||
let tag = new Chip(null, {
|
||||
label: user.name,
|
||||
icon: 'icon-edit',
|
||||
size: 'small',
|
||||
severity: 'secondary'
|
||||
});
|
||||
container.append(tag.el)
|
||||
user.tag = tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onBusDraw(chan, payload, sender) {
|
||||
|
||||
/*
|
||||
for(let item of this.busUsers) {
|
||||
item.tag.severity = 'secondary';
|
||||
}
|
||||
|
||||
let user = this.busUsers.find(item => item.uid == payload.uid);
|
||||
user.tag.severity = 'primary';
|
||||
*/
|
||||
this.draw(payload.brush, payload.from, payload.to);
|
||||
}
|
||||
|
||||
onBusClear(chan, payload, sender) { this.clear(); }
|
||||
|
||||
onBusJoin(chan, payload, sender) {
|
||||
let user = payload;
|
||||
let index = this.busUsers.findIndex(item => item.uid == user.uid);
|
||||
console.log('index', index, this.busUsers)
|
||||
console.log('user', user)
|
||||
if(index == -1) {
|
||||
this.busUsers.push(user);
|
||||
this.refreshUsers();
|
||||
}
|
||||
}
|
||||
|
||||
onBusLeave(chan, payload, sender) { this.pingUsers(); }
|
||||
|
||||
onBoardDownload(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
let data = this.board.toDataURL('image/png');
|
||||
|
||||
let link = document.createElement('a');
|
||||
link.download = 'chalkboard.png';
|
||||
link.href = data;
|
||||
link.click();
|
||||
}
|
||||
|
||||
onBoardClear(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
if(this.useBus) {
|
||||
app.MessageBus.sendEvent(this.options.busChannel,'board_clear', {});
|
||||
} else {
|
||||
this.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
app.registerClass('ChalkboardView',ChalkboardView);
|
||||
@@ -1,73 +0,0 @@
|
||||
<style>
|
||||
|
||||
|
||||
.component-lab [eicstatechart] {
|
||||
height: 320px;
|
||||
}
|
||||
|
||||
.component-lab { }
|
||||
.component-lab textarea {
|
||||
height: 240px;
|
||||
font-family: monospace;
|
||||
}
|
||||
.component-lab { }
|
||||
</style>
|
||||
<article eiccard class="component-lab">
|
||||
<header>
|
||||
<h1>Components Forge</h1>
|
||||
<h2>Current: Relation Map</h2>
|
||||
</header>
|
||||
<section>
|
||||
<div eicstatechart class="relation-map"></div>
|
||||
<div class="cols-2">
|
||||
<div>
|
||||
<label xsmall>config</label>
|
||||
<textarea eictextarea name="config">
|
||||
{
|
||||
"orientation": "linear",
|
||||
"resizable": true,
|
||||
"allowDrag": true,
|
||||
"entity": {
|
||||
"width": 180,
|
||||
"height": 80,
|
||||
"gap": 40
|
||||
}
|
||||
}
|
||||
</textarea>
|
||||
</div>
|
||||
<div>
|
||||
<label xsmall>data</label>
|
||||
<textarea eictextarea name="data">
|
||||
{
|
||||
"entities": [
|
||||
{
|
||||
"title": "Entity 1",
|
||||
"severity": "info"
|
||||
},
|
||||
{
|
||||
"title": "Entity 2",
|
||||
"subtitle": "has an id value of 2",
|
||||
"data": {
|
||||
"id": 2,
|
||||
"test": "some value"
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "Entity 3",
|
||||
"subtitle": "has an id value of 3",
|
||||
"badge": 42,
|
||||
"data": {
|
||||
"id": 3,
|
||||
"test": "some value"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cols-1 right">
|
||||
<button eicbutton xsmall primary class="button-update">update</button>
|
||||
</div>
|
||||
</section>
|
||||
</article>
|
||||
@@ -1,37 +0,0 @@
|
||||
class ComponentLabView extends EICDomContent {
|
||||
|
||||
|
||||
|
||||
DOMContentLoaded() {
|
||||
this.components = ui.eicfy(this.el);
|
||||
|
||||
this.tConfig = this.components.find(c => c.el.name == 'config');
|
||||
this.tData = this.components.find(c => c.el.name == 'data');
|
||||
this.btReset = this.components.find(c => c.el.classList.contains('button-update'));
|
||||
|
||||
this.reset(JSON.parse(this.tConfig.value), JSON.parse(this.tData.value));
|
||||
|
||||
this.btReset.addEventListener('click', this.onReset.bind(this));
|
||||
}
|
||||
|
||||
onReset(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
this.reset(JSON.parse(this.tConfig.value), JSON.parse(this.tData.value));
|
||||
}
|
||||
|
||||
reset(config, data) {
|
||||
this.map = new StateChart(this.find('.relation-map'), config)
|
||||
|
||||
this.map.data = data;
|
||||
this.map.click = this.testBadge.bind(this)
|
||||
}
|
||||
|
||||
testBadge(entity) {
|
||||
entity.badge = 23
|
||||
}
|
||||
}
|
||||
|
||||
app.registerClass('ComponentLabView',ComponentLabView);
|
||||
|
||||
@@ -1,212 +0,0 @@
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Fugaz+One&display=swap');
|
||||
:root {
|
||||
--smp-global-background: #dcd4bc;
|
||||
--smp-global-color: #503333;
|
||||
}
|
||||
.sampler-app > header { background: url('/app/assets/images/cards/lab-sampler.jpg'); }
|
||||
.sampler-app section {
|
||||
border: none;
|
||||
background: var(--smp-global-background);
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.sampler-app .speaker {
|
||||
color: black;
|
||||
height: 340px;
|
||||
min-width: 340px;
|
||||
width: 340px;
|
||||
border: 7px solid rgb(0 0 0 / 5%);
|
||||
padding: 20px;
|
||||
display: grid;
|
||||
margin: 0 40px 0 0;
|
||||
border-radius: 18px;
|
||||
}
|
||||
[device="tablet"] .sampler-app .speaker,
|
||||
[device="mobile"] .sampler-app .speaker {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.sampler-app .speaker .hole {
|
||||
background-color: black;
|
||||
border-radius: 50%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
}
|
||||
|
||||
.sampler-app .speaker .stripes {
|
||||
color: black;
|
||||
background-image: linear-gradient(0deg, var(--smp-global-background) 60%, black 1%, black 10%, #0000003b 25%);
|
||||
background-size: 1px 23px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
}
|
||||
.sampler-app .pads {
|
||||
display: flex;
|
||||
grid-gap: var(--eicui-base-spacing-l);
|
||||
flex-flow: wrap;
|
||||
}
|
||||
.sampler-app .pads .pad {
|
||||
display: grid;
|
||||
grid-template-rows: auto min-content;
|
||||
grid-template-columns: min-content auto;
|
||||
grid-gap: 4px;
|
||||
flex: 1;
|
||||
min-width: 100px;
|
||||
max-width: 140px;
|
||||
}
|
||||
.sampler-app .pads .pad kbd {
|
||||
align-self: flex-end;
|
||||
justify-self: center;
|
||||
color: white;
|
||||
background: var(--smp-global-color);
|
||||
padding: 6px 11px;
|
||||
border-radius: 5px;
|
||||
font-size: 0.95rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.sampler-app .pads .pad button {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 2px solid black;
|
||||
grid-column: 1 / 3;
|
||||
border-radius: 6px;
|
||||
padding: 0;
|
||||
box-shadow: 1px 4px 4px #0000007d;
|
||||
min-height: 40px;
|
||||
}
|
||||
.sampler-app .pads .pad button.assigned:hover span {
|
||||
border-color: orange !important;
|
||||
}
|
||||
.sampler-app .pads .pad button span {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #404040;
|
||||
border: 8px solid #59402c;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.sampler-app .pads .pad button.assigned span { border: 3px solid #b77c4c; }
|
||||
.sampler-app .pads .pad button.playing span { border: 3px solid #93f795; }
|
||||
.sampler-app .pads .pad label {
|
||||
color: #ffffffc4;
|
||||
background: var(--smp-global-color);
|
||||
padding: 8px 3px 8px 10px;
|
||||
margin: 3px 0 0 0;
|
||||
text-transform: uppercase;
|
||||
font-family: 'Fugaz One', cursive;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 0.75rem;
|
||||
align-content: center;
|
||||
}
|
||||
.sampler-app footer {
|
||||
background-color: rgba(0, 0, 0, 0.168);
|
||||
grid-area: footer;
|
||||
border-top: 4px solid #ffffff61;
|
||||
}
|
||||
</style>
|
||||
<article eiccard media class="sampler-app">
|
||||
<header>
|
||||
<h1>CARMELOMATIC<sup>®</sup></h1>
|
||||
<h2>SAMPLER 3000</h2>
|
||||
</header>
|
||||
<section>
|
||||
|
||||
<div class="speaker">
|
||||
<div class="hole"></div>
|
||||
<div class="stripes"></div>
|
||||
</div>
|
||||
<!---->
|
||||
<div class="pads">
|
||||
<div class="pad">
|
||||
<button accesskey="e"><span></span></button>
|
||||
<kbd>e</kbd><label for="button"></label>
|
||||
</div>
|
||||
<div class="pad">
|
||||
<button accesskey="r"><span></span></button>
|
||||
<kbd>r</kbd><label for="button"></label>
|
||||
</div>
|
||||
<div class="pad">
|
||||
<button accesskey="t"><span></span></button>
|
||||
<kbd>t</kbd><label for="button"></label>
|
||||
</div>
|
||||
<div class="pad">
|
||||
<button accesskey="y"><span></span></button>
|
||||
<kbd>y</kbd><label for="button"></label>
|
||||
</div>
|
||||
<div class="pad">
|
||||
<button accesskey="d"><span></span></button>
|
||||
<kbd>d</kbd><label for="button"></label>
|
||||
</div>
|
||||
<div class="pad">
|
||||
<button accesskey="f"><span></span></button>
|
||||
<kbd>f</kbd><label for="button"></label>
|
||||
</div>
|
||||
<div class="pad">
|
||||
<button accesskey="g"><span></span></button>
|
||||
<kbd>g</kbd><label for="button"></label>
|
||||
</div>
|
||||
<div class="pad">
|
||||
<button accesskey="h"><span></span></button>
|
||||
<kbd>h</kbd><label for="button"></label>
|
||||
</div>
|
||||
<div class="pad">
|
||||
<button accesskey="c"><span></span></button>
|
||||
<kbd>c</kbd><label for="button"></label>
|
||||
</div>
|
||||
<div class="pad">
|
||||
<button accesskey="v"><span></span></button>
|
||||
<kbd>v</kbd><label for="button"></label>
|
||||
</div>
|
||||
<div class="pad">
|
||||
<button accesskey="b"><span></span></button>
|
||||
<kbd>b</kbd><label for="button"></label>
|
||||
</div>
|
||||
<div class="pad">
|
||||
<button accesskey="n"><span></span></button>
|
||||
<kbd>n</kbd><label for="button"></label>
|
||||
</div>
|
||||
<div class="pad">
|
||||
<button accesskey="u"><span></span></button>
|
||||
<kbd>u</kbd><label for="button"></label>
|
||||
</div>
|
||||
<div class="pad">
|
||||
<button accesskey="i"><span></span></button>
|
||||
<kbd>i</kbd><label for="button"></label>
|
||||
</div>
|
||||
<div class="pad">
|
||||
<button accesskey="o"><span></span></button>
|
||||
<kbd>o</kbd><label for="button"></label>
|
||||
</div>
|
||||
<div class="pad">
|
||||
<button accesskey="p"><span></span></button>
|
||||
<kbd>p</kbd><label for="button"></label>
|
||||
</div>
|
||||
<div class="pad">
|
||||
<button accesskey="j"><span></span></button>
|
||||
<kbd>j</kbd><label for="button"></label>
|
||||
</div>
|
||||
<div class="pad">
|
||||
<button accesskey="k"><span></span></button>
|
||||
<kbd>k</kbd><label for="button"></label>
|
||||
</div>
|
||||
<div class="pad">
|
||||
<button accesskey="l"><span></span></button>
|
||||
<kbd>l</kbd><label for="button"></label>
|
||||
</div>
|
||||
<div class="pad">
|
||||
<button accesskey="m"><span></span></button>
|
||||
<kbd>m</kbd><label for="button"></label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
</article>
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
class SamplerView extends EICDomContent {
|
||||
// all mpeg preloading not in dependency anymore,
|
||||
// but here, when you're really about to use then
|
||||
|
||||
sounds = [
|
||||
{"name": "98.mp3","path": "/app/assets/sfx/sampler/", 'label': '98'},
|
||||
{"name": "quenouilles.mp3","path": "/app/assets/sfx/sampler/", 'label': 'As-tu vu?'},
|
||||
{"name": "celebrate.mp3","path": "/app/assets/sfx/sampler/", 'label': 'party'},
|
||||
{"name": "paillettes.mp3","path": "/app/assets/sfx/sampler/", 'label': 'paillettes'},
|
||||
{"name": "manu.mp3","path": "/app/assets/sfx/sampler/", 'label': 'Manu'},
|
||||
{"name": "projet.mp3","path": "/app/assets/sfx/sampler/", 'label': 'Projet'},
|
||||
{"name": "judgenot.mp3","path": "/app/assets/sfx/sampler/", 'label': 'Judge not!'},
|
||||
{"name": "metaphore.mp3","path": "/app/assets/sfx/sampler/", 'label': 'Metaphore'},
|
||||
{"name": "gamin.mp3","path": "/app/assets/sfx/sampler/", 'label': 'Gamin!'},
|
||||
{"name": "jcvd.mp3","path": "/app/assets/sfx/sampler/", 'label': '1+1=11'},
|
||||
{"name": "balladur.mp3","path": "/app/assets/sfx/sampler/", 'label': 'Arretez!'},
|
||||
{"name": "guingamp.mp3","path": "/app/assets/sfx/sampler/", 'label': 'En avant !'},
|
||||
{"name": "phrases.mp3","path": "/app/assets/sfx/sampler/", 'label': 'Phrases...'},
|
||||
{"name": "bourpif.mp3","path": "/app/assets/sfx/sampler/", 'label': 'Raoul'},
|
||||
{"name": "fairplay.mp3","path": "/app/assets/sfx/sampler/", 'label': 'Fairplay'},
|
||||
{"name": "neanderthal.mp3","path": "/app/assets/sfx/sampler/", 'label': 'Neanderthal'},
|
||||
{"name": "hassancehef.mp3","path": "/app/assets/sfx/sampler/", 'label': 'C\'est possible !'}
|
||||
];
|
||||
|
||||
mixer = null;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
DOMContentLoaded() {
|
||||
this.pads = this.findAll('.pad');
|
||||
this.init();
|
||||
this.preloadSounds(this.sounds);
|
||||
}
|
||||
|
||||
DOMContentRemoved() { window.removeEventListener('keyup',this.keyHandler); }
|
||||
|
||||
init() {
|
||||
for(let i = 0; i < this.sounds.length; i++) {
|
||||
let data = this.sounds[i];
|
||||
this.pads[i].name = data.name;
|
||||
this.pads[i].querySelector('label').innerText = data.label;
|
||||
let button = this.pads[i].querySelector('button');
|
||||
button.addEventListener('click', this.play.bind(this, data.name));
|
||||
}
|
||||
this.keyHandler = this.onKeyPressed.bind(this);
|
||||
window.addEventListener('keyup', this.keyHandler);
|
||||
}
|
||||
|
||||
preloadSounds(sndList){
|
||||
for(let snd of sndList){
|
||||
app.Assets.loadSound({
|
||||
'id': snd.name,
|
||||
'name': snd.name,
|
||||
'path': snd.path
|
||||
}).then(audioEl => {
|
||||
audioEl.addEventListener("play", this.playBoy.bind(this));
|
||||
audioEl.addEventListener("pause", this.pauseBoy.bind(this));
|
||||
let pad, idx;
|
||||
for([idx, pad] of this.pads.entries()){
|
||||
if(pad.name==audioEl.getAttribute('aid')) {
|
||||
pad.querySelector('button').classList.add('assigned');
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
playBoy(event){
|
||||
let aid = event.target.getAttribute('aid');
|
||||
let pad, idx;
|
||||
for([idx, pad] of this.pads.entries()){
|
||||
if(pad.name==aid) {
|
||||
pad.querySelector('button').classList.remove('assigned')
|
||||
pad.querySelector('button').classList.add('playing');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pauseBoy(event){
|
||||
let aid = event.target.getAttribute('aid');
|
||||
let pad, idx;
|
||||
for([idx, pad] of this.pads.entries()){
|
||||
if(pad.name==aid) {
|
||||
pad.querySelector('button').classList.remove('playing')
|
||||
pad.querySelector('button').classList.add('assigned');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
play(audioid, event) {
|
||||
event.stopPropagation();
|
||||
|
||||
if(this.mixer) {
|
||||
this.mixer.pause();
|
||||
this.mixer.currentTime = 0;
|
||||
}
|
||||
this.mixer = app.Assets.Store.sfx[audioid];
|
||||
this.mixer.play();
|
||||
}
|
||||
|
||||
stop() {}
|
||||
|
||||
onKeyPressed(event) {
|
||||
let btn = document.querySelector('button[accessKey="'+event.key.toLowerCase()+'"]');
|
||||
if(btn) btn.click();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
app.registerClass('SamplerView',SamplerView);
|
||||
@@ -1,46 +0,0 @@
|
||||
<article eiccard>
|
||||
<header>
|
||||
<h1>Form test</h1>
|
||||
</header>
|
||||
<section class="form">
|
||||
<input type="hidden" data-path="pathAnd" name="name" value="done" />
|
||||
<input type="hidden" name="nameOnly" value="done" />
|
||||
<input type="hidden" data-path="pathonly" value="done" />
|
||||
<input type="hidden" data-path="ignoredField" class="ignore" value="Mutafuka! your snooping to much" />
|
||||
<input type="hidden" data-path="basearray[0]" value="a" />
|
||||
<input type="hidden" data-path="basearray[1]" value="b" />
|
||||
<input type="hidden" data-path="arrayOfObjects[0].value" data-type="number" value="100" />
|
||||
<input type="hidden" data-path="arrayOfObjects[0].label" value="aa" />
|
||||
<input type="hidden" data-path="arrayOfObjects[1].value" data-type="number" value="200.45" />
|
||||
<input type="hidden" data-path="arrayOfObjects[1].label" value="bb" />
|
||||
<input type="hidden" data-path="arrayOfObjects[2].value" data-type="number" value="300" />
|
||||
<input type="hidden" data-path="arrayOfObjects[2].label" value="cc" />
|
||||
<input type="hidden" data-path="boolean" data-type="boolean" value="true" />
|
||||
|
||||
<textarea data-path="justification.description" eictextarea maxlen="200"
|
||||
hint="No more than 200 characters please."
|
||||
placeholder="Please type some words..."></textarea>
|
||||
|
||||
<label>pick some values</label>
|
||||
<select eicselect multiple data-path="justification.programme" placeholder="Please select a programme...">
|
||||
<option value=""></option>
|
||||
<option value="1">PRG1</option>
|
||||
<option value="2">PRG2</option>
|
||||
<option value="3">PRG3</option>
|
||||
</select>
|
||||
|
||||
<input eiccheckbox type="checkbox" data-path="justification.independentExpert" label="You confirm that you have relied on independent external experts to perform the project review" value="yes" />
|
||||
<input eiccheckbox type="checkbox" class="ignore" data-path="justification.compliance" label="You confirm that you have complied with all the conditions and requirements set out for Fast Track scheme" />
|
||||
|
||||
</section>
|
||||
<section primary>
|
||||
<label>JSON output</label>
|
||||
<textarea eictextarea class="output"></textarea>
|
||||
</section>
|
||||
<footer>
|
||||
<div class="cols-2 right">
|
||||
<div></div>
|
||||
<button eicbutton primary class="generate">output form</button>
|
||||
</div>
|
||||
</footer>
|
||||
</article>
|
||||
@@ -1,15 +0,0 @@
|
||||
class TestView extends EICDomContent {
|
||||
|
||||
constructor() { super(); }
|
||||
|
||||
DOMContentLoaded() {
|
||||
ui.eicfy(this.el)
|
||||
|
||||
let form = new Form(this.find('.form'));
|
||||
let output = this.find('.output')
|
||||
this.find('.generate').addEventListener('click', event => { output.value = JSON.stringify(form.value) });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
app.registerClass('TestView',TestView);
|
||||
@@ -1,716 +0,0 @@
|
||||
<style type="text/css">
|
||||
.eicui-components > header {
|
||||
background: url('/app/assets/images/cards/eicui-banner.jpg');
|
||||
}
|
||||
.eicui-components button.show-code{
|
||||
width: min-content;
|
||||
float: right;
|
||||
}
|
||||
[eicdialog]>article { margin: auto; }
|
||||
|
||||
.eicui-components code {
|
||||
white-space: pre-wrap
|
||||
}
|
||||
.eicui-components ul.features { font-size:.8em; }
|
||||
</style>
|
||||
<article eiccard media class="eicui-components">
|
||||
<header>
|
||||
<h1>EICUI Components</h1>
|
||||
<h2></h2>
|
||||
</header>
|
||||
<section>
|
||||
<p>
|
||||
The EICUI component library is a complete portage of the EUI component library.
|
||||
Despite the fact that it sticks to the design and behaviour of the original components, there are some major technical differences:
|
||||
</p>
|
||||
<ul bulleted>
|
||||
<li>The library is written in vanilla JS. So, it can virtually be embedded in any environment or framework, not limited only to AngularJS</li>
|
||||
<li>The library code is much lighter than the original EUI (about 15 times lighter)</li>
|
||||
<li>Components can be declared either through tags (for basic components) or by code (class instanciation)</li>
|
||||
<li>Some misleading or useless components options have been discarded.</li>
|
||||
<li>The icon library has been reduced and aligned to the EIC interface needs.</li>
|
||||
</ul>
|
||||
<h4>Main principles</h4>
|
||||
</section>
|
||||
<section>
|
||||
<h3>Basic components</h3>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>Alert messages</h1>
|
||||
<h2></h2>
|
||||
</header>
|
||||
<section>
|
||||
<button eicbutton rounded basic primary small icon="icon-writing" class="show-code" data-codeclass="alertsexample"></button>
|
||||
<br>
|
||||
<h6>Default</h6>
|
||||
<div class="alertsexample" data-codetitle="Alert messages" eicalert>Sample text</div>
|
||||
<h6>Closable</h6>
|
||||
<div class="alertsexample" data-codetitle="Alert messages (closable)" eicalert closable>Sample text</div>
|
||||
<h6>Severities</h6>
|
||||
<div class="alertsexample" data-codetitle="Alert messages (info)" eicalert info>"info" message (default)</div>
|
||||
<div class="alertsexample" data-codetitle="Alert messages (success)" eicalert success>"success" message</div>
|
||||
<div class="alertsexample" data-codetitle="Alert messages (secondary)" eicalert secondary>"secondary" message</div>
|
||||
<div class="alertsexample" data-codetitle="Alert messages (warning)" eicalert warning>"warning" message</div>
|
||||
<div class="alertsexample" data-codetitle="Alert messages (danger)" eicalert danger>"danger" message</div>
|
||||
<h6>Muted</h6>
|
||||
<div class="alertsexample" data-codetitle="Alert messages (info - muted)" eicalert info muted>"info" message (default)</div>
|
||||
<div class="alertsexample" data-codetitle="Alert messages (success - muted)" eicalert success muted>"success" message</div>
|
||||
<div class="alertsexample" data-codetitle="Alert messages (secondary - muted)" eicalert secondary muted>"secondary" message</div>
|
||||
<div class="alertsexample" data-codetitle="Alert messages (warning - muted)" eicalert warning muted>"warning" message</div>
|
||||
<div class="alertsexample" data-codetitle="Alert messages (danger - muted)" eicalert danger muted>"danger" message</div>
|
||||
</section>
|
||||
</article>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>Badges</h1>
|
||||
<h2>
|
||||
<span eicchip xsmall info><label>severity</label></span>
|
||||
<span eicchip xsmall info><label>size</label></span>
|
||||
</h2>
|
||||
</header>
|
||||
<section>
|
||||
<h6>Default usage</h6>
|
||||
<p>Use one of the available icon-* class to display the desired icon :</p>
|
||||
<span eicbadge>9</span>
|
||||
<span eicbadge>hello</span>
|
||||
<h6>Color variants</h6>
|
||||
<p>Using one of the attribute option : <code>primary</code> | <code>secondary</code> | <code>info</code> | <code>success</code> | <code>warning</code> | <code>danger</code> | <code>accent</code></p>
|
||||
<pre> <span <strong>eicbadge</strong>>value</span> </pre>
|
||||
<span eicbadge primary>9</span>
|
||||
<span eicbadge secondary>9</span>
|
||||
<span eicbadge info>9</span>
|
||||
<span eicbadge success>9</span>
|
||||
<span eicbadge warning>9</span>
|
||||
<span eicbadge danger>9</span>
|
||||
<span eicbadge accent>9</span>
|
||||
<h6>Sizing</h6>
|
||||
<span eicbadge xxsmall>9</span>
|
||||
<span eicbadge xsmall>9</span>
|
||||
<span eicbadge small>9</span>
|
||||
<span eicbadge medium>9</span>
|
||||
<span eicbadge large>9</span>
|
||||
<span eicbadge xlarge>9</span>
|
||||
<span eicbadge xxlarge>9</span>
|
||||
<span eicbadge xxxlarge>9</span>
|
||||
<span eicbadge xxxxlarge>9</span>
|
||||
</section>
|
||||
</article>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>Buttons</h1>
|
||||
<h2>
|
||||
<span eicchip xsmall info><label>severity</label></span>
|
||||
<span eicchip xsmall info><label>size</label></span>
|
||||
<span eicchip xsmall info><label>badge</label></span>
|
||||
</h2>
|
||||
</header>
|
||||
<section>
|
||||
<button eicbutton rounded basic primary small icon="icon-writing" class="show-code" data-codeclass="buttons"></button>
|
||||
|
||||
<h6>Default button</h6>
|
||||
<button eicbutton class="buttons" data-codetitle="button">Base button</button>
|
||||
<h6>Color semantics</h6>
|
||||
<p>Using one of the attribute option : <code>primary</code> | <code>secondary</code> | <code>info</code> | <code>success</code> | <code>warning</code> | <code>danger</code> | <code>accent</code></p>
|
||||
<button eicbutton class="buttons" data-codetitle="button">Base button</button>
|
||||
<button eicbutton primary class="buttons" data-codetitle="button">Primary button</button>
|
||||
<button eicbutton secondary class="buttons" data-codetitle="button">Secondary button</button>
|
||||
<button eicbutton info class="buttons" data-codetitle="button">Info button</button>
|
||||
<button eicbutton success class="buttons" data-codetitle="button">Success button</button>
|
||||
<button eicbutton warning class="buttons" data-codetitle="button">Warning button</button>
|
||||
<button eicbutton danger class="buttons" data-codetitle="button">Dangerous button</button>
|
||||
<button eicbutton accent class="buttons" data-codetitle="button">Accent button</button>
|
||||
<h6>Rounded buttons</h6>
|
||||
<p>Using the attribute option : <code>rounded</code></p>
|
||||
<button eicbutton rounded class="buttons" data-codetitle="button">Base button</button>
|
||||
<button eicbutton rounded primary class="buttons" data-codetitle="button">Primary button</button>
|
||||
<button eicbutton rounded secondary class="buttons" data-codetitle="button">Secondary button</button>
|
||||
<button eicbutton rounded danger class="buttons" data-codetitle="button">Dangerous button</button>
|
||||
<button eicbutton rounded warning class="buttons" data-codetitle="button">Dangerous button</button>
|
||||
<button eicbutton rounded info class="buttons" data-codetitle="button">Dangerous button</button>
|
||||
<h6>Disabled buttons</h6>
|
||||
<p>Disable a button by adding a <code>disabled</code> attribute </p>
|
||||
<button eicbutton disabled class="buttons" data-codetitle="button">Base button</button>
|
||||
<button eicbutton disabled small danger rounded class="buttons" data-codetitle="button">Base button</button>
|
||||
<button eicbutton disabled rounded large class="buttons" data-codetitle="button">Base button</button>
|
||||
<h6>Sizes</h6>
|
||||
<p>Adapt specific sizes by using the attribute option : <code>small</code> | <code>large</code></p>
|
||||
<button eicbutton xsmall class="buttons" data-codetitle="button">XSmall button</button>
|
||||
<button eicbutton small class="buttons" data-codetitle="button">Small button</button>
|
||||
<button eicbutton class="buttons" data-codetitle="button">Medium (default) button</button>
|
||||
<button eicbutton large class="buttons" data-codetitle="button">Large button</button>
|
||||
<h6>With badge</h6>
|
||||
<p>Add abadge using attribute : <code>badge="value"</code></p>
|
||||
<button eicbutton badge="99" class="buttons" data-codetitle="button">Badged button</button>
|
||||
<button eicbutton badge="!" class="buttons" data-codetitle="button">Badged button</button>
|
||||
<h6>Loader state</h6>
|
||||
<p>Set button under a loading state using attribute : <code>loading="true"</code></p>
|
||||
<p>Please note that buttons under loading state are also automaticaly disabled</p>
|
||||
<button eicbutton loading="true" primary class="buttons" data-codetitle="button">I'm waiting for something</button>
|
||||
<button eicbutton loading="true" primary icon="icon-search" class="buttons" data-codetitle="button"></button>
|
||||
</section>
|
||||
</article>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>CHiPs (tadataladaaaa)</h1>
|
||||
<h2>
|
||||
<span eicchip xsmall info><label>severity</label></span>
|
||||
<span eicchip xsmall info><label>size</label></span>
|
||||
</h2>
|
||||
</header>
|
||||
<section>
|
||||
<button eicbutton rounded basic primary small icon="icon-writing" class="show-code" data-codeclass="chips"></button>
|
||||
<h6>Default</h6>
|
||||
<div class="chips" data-codetitle="CHiPs basic patrol">
|
||||
<span eicchip><label>I'm Poncherello</label></span>
|
||||
<span eicchip><label>I'm Baker (the other guy)</label></span>
|
||||
</div>
|
||||
<h6>Color semantics</h6>
|
||||
<p>Using one of the attribute option : <code>primary</code> | <code>secondary</code> | <code>info</code> | <code>success</code> | <code>warning</code> | <code>danger</code> | <code>accent</code></p>
|
||||
<div class="chips" data-codetitle="CHiPs patrol with colors">
|
||||
<span eicchip primary><label>Primary</label></span>
|
||||
<span eicchip secondary><label>Secondary</label></span>
|
||||
<span eicchip info><label>Info</label></span>
|
||||
<span eicchip warning><label>Warning</label></span>
|
||||
<span eicchip danger><label>Danger</label></span>
|
||||
<span eicchip success><label>Success</label></span>
|
||||
<span eicchip accent><label>Accent</label></span>
|
||||
</div>
|
||||
<h6>Destroyable</h6>
|
||||
<p>Using the attribute option : <code>destroyable</code></p>
|
||||
<div class="chips" data-codetitle="CHiPs destroy patrol (only for bad guys of course)">
|
||||
<span eicchip destroyable><label>Zombie</label></span>
|
||||
<span eicchip destroyable><label>Mosquito</label></span>
|
||||
</div>
|
||||
<h6>With icon</h6>
|
||||
<p>Using the attribute option : <code>icon="..."</code>. See available icons in the styleguide</p>
|
||||
<div class="chips" data-codetitle="CHiPs patrol with icon">
|
||||
<span eicchip danger icon="icon-user"><label>Zombie</label></span>
|
||||
<span eicchip warning destroyable icon="icon-warning"><label>Mosquito</label></span>
|
||||
</div>
|
||||
<h6>Sizes</h6>
|
||||
<div class="chips" data-codetitle="CHiPs patrol where size matters">
|
||||
<span eicchip xxsmall><label>xxsmall</label></span>
|
||||
<span eicchip xsmall><label>xsmall</label></span>
|
||||
<span eicchip small><label>small</label></span>
|
||||
<span eicchip><label>medium (default)</label></span>
|
||||
<span eicchip large><label>large</label></span>
|
||||
<span eicchip xlarge><label>xlarge</label></span>
|
||||
<span eicchip xxlarge><label>xxlarge</label></span>
|
||||
</div>
|
||||
<h6>Sizes with icons</h6>
|
||||
<div class="chips" data-codetitle="CHiPs patrol with sizes and icons">
|
||||
<span eicchip xxsmall icon="icon-user" destroyable><label>xxsmall</label></span>
|
||||
<span eicchip xsmall icon="icon-user" destroyable><label>xsmall</label></span>
|
||||
<span eicchip small icon="icon-user" destroyable><label>small</label></span>
|
||||
<span eicchip icon="icon-user" destroyable><label>medium (default)</label></span>
|
||||
<span eicchip large icon="icon-user" destroyable><label>large chip</label></span>
|
||||
<span eicchip xlarge icon="icon-user" destroyable><label>xlarge chip</label></span>
|
||||
<span eicchip xxlarge icon="icon-user" destroyable><label>xxlarge chip</label></span>
|
||||
</div>
|
||||
<h6>Outline variant</h6>
|
||||
<p>Using the attribute option : <code>outline</code></p>
|
||||
<div class="chips" data-codetitle="CHiPs patrol with attribute options">
|
||||
<span eicchip outline primary><label>Primary</label></span>
|
||||
<span eicchip outline secondary><label>Secondary</label></span>
|
||||
<span eicchip outline info><label>Info</label></span>
|
||||
<span eicchip outline warning><label>Warning</label></span>
|
||||
<span eicchip outline danger><label>Danger</label></span>
|
||||
<span eicchip outline success><label>Success</label></span>
|
||||
<span eicchip outline accent><label>Accent</label></span>
|
||||
</div>
|
||||
</section>
|
||||
</article>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>Drop-down Menus</h1>
|
||||
<h2></h2>
|
||||
</header>
|
||||
<section>
|
||||
<p>to be described</p>
|
||||
</section>
|
||||
</article>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>Growler</h1>
|
||||
<h2></h2>
|
||||
</header>
|
||||
<section>
|
||||
<button eicbutton rounded basic primary small icon="icon-writing" class="show-code" data-codeclass="growlerexample"></button>
|
||||
<br>
|
||||
<button eicbutton info class="growl-test growlerexample" data-codetitle="info growler" data-message="Roarr!" data-severity="info">Click me</button>
|
||||
<button eicbutton warning class="growl-test growlerexample" data-codetitle="warning growler" data-message="You've been warned" data-severity="warning">Click me for a warning</button>
|
||||
<button eicbutton danger class="growl-test growlerexample" data-codetitle="danger growler" data-message="Something went wrong" data-severity="danger">Click me for something bad</button>
|
||||
</section>
|
||||
</article>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>Icons</h1>
|
||||
<h2>
|
||||
<span eicchip xsmall info><label>severity</label></span>
|
||||
<span eicchip xsmall outline><label>size</label></span>
|
||||
</h2>
|
||||
</header>
|
||||
<section>
|
||||
<button eicbutton rounded basic primary small icon="icon-writing" class="show-code" data-codeclass="icons"></button>
|
||||
<h6>Default usage</h6>
|
||||
<p>Use one of the available icon-* class to display the desired icon :</p>
|
||||
<h6>Color variants</h6>
|
||||
<p>Using one of the attribute option : <code>primary</code> | <code>secondary</code> | <code>info</code> | <code>success</code> | <code>warning</code> | <code>danger</code> | <code>accent</code></p>
|
||||
<pre> <span class="<strong>icon-coaching</strong>"></span> </pre>
|
||||
<span class="icon-coaching icons" primary></span>
|
||||
<span class="icon-coaching icons" secondary></span>
|
||||
<span class="icon-coaching icons" success></span>
|
||||
<span class="icon-coaching icons" warning></span>
|
||||
<span class="icon-coaching icons"danger></span>
|
||||
<span class="icon-coaching icons" accent></span>
|
||||
<span class="icon-coaching icons" info></span>
|
||||
<h6>Sizing</h6>
|
||||
<span class="icon-coaching icons" xxsmall></span>
|
||||
<span class="icon-coaching icons" xsmall></span>
|
||||
<span class="icon-coaching icons" small></span>
|
||||
<span class="icon-coaching icons" medium></span>
|
||||
<span class="icon-coaching icons" large></span>
|
||||
<span class="icon-coaching icons" xlarge></span>
|
||||
<span class="icon-coaching icons" xxlarge></span>
|
||||
<span class="icon-coaching icons" xxxlarge></span>
|
||||
<span class="icon-coaching icons" xxxxlarge></span>
|
||||
|
||||
</section>
|
||||
</article>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>Menus</h1>
|
||||
<h2></h2>
|
||||
</header>
|
||||
<section>
|
||||
<p>to be described</p>
|
||||
</section>
|
||||
</article>
|
||||
</section>
|
||||
<section>
|
||||
<h3>Container components</h3>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>Cards</h1>
|
||||
<h2>
|
||||
<span eicchip xsmall info><label>severity</label></span>
|
||||
<span eicchip xsmall info><label>badge</label></span>
|
||||
</h2>
|
||||
</header>
|
||||
<section>
|
||||
<button eicbutton rounded basic primary small icon="icon-writing" class="show-code" data-codeclass="cards"></button>
|
||||
<p>The card component is used to group various pieces of content into a container which can be used throughout your website.</p>
|
||||
<h6>Default</h6>
|
||||
<p>Basically a card component is a DOM structure using this blueprint:</p>
|
||||
<article eiccard class="cards" data-codetitle="Default card"><section>Some content</section></article>
|
||||
<h6>Severities</h6>
|
||||
<p>cards support standard severity attributes : <code>primary</code> | <code>secondary</code> | <code>info</code> | <code>success</code> | <code>warning</code> | <code>danger</code> | <code>accent</code></p>
|
||||
<article eiccard primary class="cards" data-codetitle="Primary card"><section>Some primary content</section></article>
|
||||
<article eiccard secondary class="cards" data-codetitle="Secondary card"><section>Some secondary content</section></article>
|
||||
<article eiccard danger class="cards" data-codetitle="Danger card"><section>Some dangerous content</section></article>
|
||||
<article eiccard warning class="cards" data-codetitle="Warning card"><section>Some warning content</section></article>
|
||||
<article eiccard info class="cards" data-codetitle="Info card"><section>Some info content</section></article>
|
||||
<article eiccard success class="cards" data-codetitle="Success card"><section>Some success content</section></article>
|
||||
<article eiccard accent class="cards" data-codetitle="Accent card"><section>Some accent content</section></article>
|
||||
<h6>Header and footer</h6>
|
||||
<article eiccard primary class="cards" data-codetitle="Header and footer card">
|
||||
<header>
|
||||
<h1>This is title</h1>
|
||||
<h2>This is subtitle</h2>
|
||||
</header>
|
||||
<section>Some primary content</section>
|
||||
<footer>this is footer</footer>
|
||||
</article>
|
||||
<p>Each part of this structure is optional, meaning you only keep from the strucure what is actually use. Just remove the unnecessary parts.</p>
|
||||
<h6>Collapsable content</h6>
|
||||
<p>You may choose to allow your card content to be collapsed (hidden) at user will. Simply add a <code>collapsable</code> attribute to your card (the main article tag).</p>
|
||||
<article eiccard danger collapsable class="cards" data-codetitle="Collapsable card">
|
||||
<header>
|
||||
<h1>I'm expanded</h1>
|
||||
<h2>...but not for long</h2>
|
||||
</header>
|
||||
<section>Some dangerous content</section>
|
||||
</article>
|
||||
<p>To control the initial state of the card, by deault the card will appear expand. If you want it to appear collapsed, add a <code>collapsed</code> attribute to the card too.</p>
|
||||
<article eiccard success collapsable collapsed class="cards" data-codetitle="Collapsed card">
|
||||
<header>
|
||||
<h1>Uncollapse me</h1>
|
||||
</header>
|
||||
<section>Some dangerous content withoutt subtitle</section>
|
||||
</article>
|
||||
</section>
|
||||
</article>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>Dialogs</h1>
|
||||
<h2></h2>
|
||||
</header>
|
||||
<section>
|
||||
<p>to be described</p>
|
||||
<h6>Basic usage</h6>
|
||||
<button eicbutton rounded basic primary small icon="icon-writing" class="show-code" data-codeclass="dialogexample"></button>
|
||||
<button eicbutton info small class="dialog-test dialogexample" data-codetitle="Opening a dialog">open a dialog</button>
|
||||
<h6>Using view content</h6>
|
||||
<p>to be described</p>
|
||||
<h6>Custom actions</h6>
|
||||
<p>to be described</p>
|
||||
</section>
|
||||
</article>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>Tabs</h1>
|
||||
<h2></h2>
|
||||
</header>
|
||||
<section>
|
||||
<p>to be described</p>
|
||||
<button eicbutton rounded basic primary small icon="icon-writing" class="show-code" data-codeclass="tabdefault"></button>
|
||||
<h6>Default</h6>
|
||||
<div class="tabdefault" data-codetitle="Tabs default">
|
||||
<menu eictab class="sample1" xxlarge>
|
||||
<li>Tab 1</li>
|
||||
<li>Tab 2</li>
|
||||
<li>Tab 3</li>
|
||||
</menu>
|
||||
<article eiccard class="tab-content sample1" xxlarge danger>
|
||||
<header>
|
||||
<h1>Tab 1 insight</h1>
|
||||
<h2>This is the 1st tab</h2>
|
||||
</header>
|
||||
<section>Tab 1 content</section>
|
||||
</article>
|
||||
<article eiccard class="tab-content sample1" xxlarge warning>
|
||||
<section>Tab 2 content</section>
|
||||
</article>
|
||||
<article eiccard class="tab-content sample1" xxlarge success>
|
||||
<section>Tab 3 content</section>
|
||||
</article>
|
||||
</div>
|
||||
<button eicbutton rounded basic primary small icon="icon-writing" class="show-code" data-codeclass="tabvertical"></button>
|
||||
<h6>Vertical</h6>
|
||||
<div class="tabvertical" data-codetitle="Tabs vertical">
|
||||
<div class="cols-2 left">
|
||||
<menu eictab vertical class="sample2" xsmall>
|
||||
<li>Tab 1</li>
|
||||
<li>Tab 2</li>
|
||||
<li>Tab 3</li>
|
||||
</menu>
|
||||
<article eiccard class="tab-content sample2">
|
||||
<header>
|
||||
<h1>Tab 1 insight</h1>
|
||||
<h2>This is the 1st tab</h2>
|
||||
</header>
|
||||
<section>Tab 1 content</section>
|
||||
</article>
|
||||
<article eiccard class="tab-content sample2">
|
||||
<section>Tab 2 content</section>
|
||||
</article>
|
||||
<article eiccard class="tab-content sample2">
|
||||
<section>Tab 3 content</section>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</article>
|
||||
</section>
|
||||
<section>
|
||||
<h3>Form components</h3>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>Inputs</h1>
|
||||
<h2>
|
||||
<span eicchip xsmall info><label>severity</label></span>
|
||||
<span eicchip xsmall danger><label>badge</label></span>
|
||||
<span eicchip xsmall info><label>form</label></span>
|
||||
</h2>
|
||||
</header>
|
||||
<section>
|
||||
<button eicbutton rounded basic primary small icon="icon-writing" class="show-code" data-codeclass="inputs"></button>
|
||||
<h6>Default</h6>
|
||||
<input eicinput value="This is some text..." class="inputs" data-codetitle="Input default"/>
|
||||
<label>Secondary (default)</label>
|
||||
<input eicinput secondary value="This is some text..." class="inputs" data-codetitle="Input secondary (default)"/>
|
||||
<label>Primary</label>
|
||||
<input eicinput primary value="This is some text..." class="inputs" data-codetitle="Input primary"/>
|
||||
<label>Danger / invalid</label>
|
||||
<input eicinput danger value="This is some text..." class="inputs" data-codetitle="Input danger/invalid"/>
|
||||
<label>Success</label>
|
||||
<input eicinput success value="This is some text..." class="inputs" data-codetitle="Input success"/>
|
||||
<label>Warning</label>
|
||||
<input eicinput warning value="This is some text..." class="inputs" data-codetitle="Input warning"/>
|
||||
<label>Info</label>
|
||||
<input eicinput info value="This is some text..." class="inputs" data-codetitle="Input info"/>
|
||||
<label>Accent</label>
|
||||
<input eicinput accent value="This is some non editable text..." class="inputs" data-codetitle="Input accent"/>
|
||||
<h6>Search input</h6>
|
||||
<input eicinput type="search" value="" class="inputs" data-codetitle="Query string Input"/>
|
||||
<h6>Number input</h6>
|
||||
<input eicinput type="number" value="" class="inputs" data-codetitle="Input for number"/>
|
||||
<h6>Date input</h6>
|
||||
<input eicinput type="date" value="" class="inputs" data-codetitle="Input for date"/>
|
||||
<h6>Date and time input</h6>
|
||||
<input eicinput type="datetime" value="" class="inputs" data-codetitle="Input for date & time"/>
|
||||
<h6>Accent</h6>
|
||||
<input eicinput accent value="This is some non editable text..." class="inputs" data-codetitle="Input accent"/>
|
||||
<h6>Multiple</h6>
|
||||
<p>(DEPRECATED)</p>
|
||||
<p>see Select[editable] for a replacer</p>
|
||||
<h6>Toggler</h6>
|
||||
<div class="cols-4">
|
||||
<input eicinput type="toggler" small data-path="toggy1" trueValue="wai" falseValue="queneni" labelright="Light" class="inputs" data-codetitle="Input toggler"/>
|
||||
<input eicinput type="toggler" medium warning data-path="toggy2" trueValue="wai" falseValue="queneni" labelleft="Dishwasher" class="inputs" data-codetitle="Input toggler"/>
|
||||
<input eicinput type="toggler" large danger data-path="toggy3" trueValue="wai" falseValue="queneni" labelright="Toaster" value="wai" class="inputs" data-codetitle="Input toggler"/>
|
||||
<input eicinput type="toggler" xlarge primary size="large" data-path="toggy4" trueValue="hifi" falseValue="tv" labelleft="TV" labelright="Hifi" class="inputs" data-codetitle="Input toggler"/>
|
||||
</div>
|
||||
</section>
|
||||
</article>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>Textareas</h1>
|
||||
<h2>
|
||||
<span eicchip xsmall info><label>severity</label></span>
|
||||
<span eicchip xsmall info><label>badge</label></span>
|
||||
<span eicchip xsmall info><label>form</label></span>
|
||||
</h2>
|
||||
</header>
|
||||
<section>
|
||||
<button eicbutton rounded basic primary small icon="icon-writing" class="show-code" data-codeclass="textareas"></button>
|
||||
<h6>Default</h6>
|
||||
<textarea eictextarea class="textareas" data-codetitle="Textarea default">This is some text...</textarea>
|
||||
<h6>Hint</h6>
|
||||
<p>Using the attribute option : <code>hint="..."</code></p>
|
||||
<textarea eictextarea hint="Please don't be gross." class="textareas" data-codetitle="Textarea with hint">This is some text...</textarea>
|
||||
<h6>With badge</h6>
|
||||
<p>You may check for size limitation, either by character length, word amount or byte length (according to the current text encoding)</p>
|
||||
<p>Characters limit: add attribute <code>maxlen="..."</code></p>
|
||||
<textarea eictextarea maxlen="200" hint="No more than 200 chars" placeholder="What's on your mind..." class="textareas" data-codetitle="Textarea with maxlen"></textarea>
|
||||
<p>Words limit: add attribute <code>maxwords="..."</code></p>
|
||||
<textarea eictextarea maxwords="20" hint="No more than 20 words" placeholder="What's on your mind..."class="textareas" data-codetitle="Textarea with maxwords"></textarea>
|
||||
<p>Bytes limit: add attribute <code>maxbytes="..."</code></p>
|
||||
<textarea eictextarea maxbytes="2048" hint="No more than 2048 bytes" placeholder="What's on your mind..." class="textareas" data-codetitle="Textarea with maxbytes"></textarea>
|
||||
</section>
|
||||
</article>
|
||||
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>Selects</h1>
|
||||
<h2></h2>
|
||||
</header>
|
||||
<section>
|
||||
<p>to be described</p>
|
||||
<button eicbutton rounded basic primary small icon="icon-writing" class="show-code" data-codeclass="selects"></button>
|
||||
<h6>Default</h6>
|
||||
<select eicselect class="selects" data-codetitle="Select default">
|
||||
<option></option>
|
||||
<option value="Pizza">Pizza</option>
|
||||
<option value="Burger">Burger</option>
|
||||
<option value="Kebab">Kebab</option>
|
||||
</select>
|
||||
<h6>Multi-selection</h6>
|
||||
<select eicselect multi class="selects" data-codetitle="Select with multi-selection">
|
||||
<option></option>
|
||||
<option value="Pizza">Pizza</option>
|
||||
<option value="Burger">Burger</option>
|
||||
<option value="Kebab">Kebab</option>
|
||||
</select>
|
||||
<h6>With lookup</h6>
|
||||
<select eicselect multi lookup class="selects" data-codetitle="Select with lookup">
|
||||
<option></option>
|
||||
<option value="Pizza">Pizza</option>
|
||||
<option value="Burger">Burger</option>
|
||||
<option value="Kebab">Kebab</option>
|
||||
</select>
|
||||
|
||||
<h6>Multi-level selection</h6>
|
||||
<select eicselect multi lookup class="selects" data-codetitle="Select with multi-level selection">
|
||||
<option></option>
|
||||
<option value="Pizzas" data-ref="pizza">Pizza</option>
|
||||
<option value="Burger" data-ref="burger">Burger</option>
|
||||
<option value="Kebab" data-ref="Kebab">Kebab</option>
|
||||
<optgroup data-parent="burger" >
|
||||
<option value="simple">Simple</option>
|
||||
<option value="bacon">Bacon</option>
|
||||
</optgroup>
|
||||
<optgroup data-parent="pizza" >
|
||||
<option value="margarita">Margarita</option>
|
||||
<option value="4cheese">4 Cheese</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
<div eicalert warning>
|
||||
KNOWN BUG:
|
||||
When selection popup is opened and user interacts with anoter element of the page wich leads to the removal of the select component from the DOM (i.e. closing a dialog containing the Select component),
|
||||
the selection popup will stay opened. any interaction (click) outside the selection popup will hide it.</div>
|
||||
</section>
|
||||
</article>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>Checkboxes</h1>
|
||||
<h2></h2>
|
||||
</header>
|
||||
<section>
|
||||
<p>to be described</p>
|
||||
</section>
|
||||
</article>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>Forms</h1>
|
||||
<h2>
|
||||
<span eicchip xsmall info><label>form</label></span>
|
||||
</h2>
|
||||
</header>
|
||||
<section>
|
||||
<p>
|
||||
The Form component, only availbale as an instanciable class is not a visual component. Associated with a DOM element, the Form will identify all inputs, textareas and selects defined in this DOM element and provide helper methods to manage this set of fields.
|
||||
Each field detected will be analyzed to identify:
|
||||
</p>
|
||||
<ul bulleted>
|
||||
<li>validation rules</li>
|
||||
<li>name and path described in the field. allowing exports to JSON format</li>
|
||||
</ul>
|
||||
<button eicbutton rounded basic primary small icon="icon-writing" class="show-code" data-codeclass="forms"></button>
|
||||
<h6>Simple form</h6>
|
||||
<form class="forms" data-codetitle="Simple form">
|
||||
<textarea eictextarea>This is some text...</textarea>
|
||||
</form>
|
||||
<h6>Form validation</h6>
|
||||
<p>to be descibed</p>
|
||||
<h6>JSON export</h6>
|
||||
<p>to be descibed</p>
|
||||
</section>
|
||||
</article>
|
||||
|
||||
</section>
|
||||
<section>
|
||||
<h2>Advanced components</h2>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>DataGrid</h1>
|
||||
<h2></h2>
|
||||
</header>
|
||||
<section>
|
||||
<button eicbutton rounded basic primary small icon="icon-writing" class="show-code" data-codeclass="gridexample"></button>
|
||||
<div eicdatagrid class="gridexample" data-codetitle="DataGrid"></div>
|
||||
</section>
|
||||
</article>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>WorkflowMap</h1>
|
||||
<h2></h2>
|
||||
</header>
|
||||
<section>
|
||||
<div eicflowmap></div>
|
||||
</section>
|
||||
</article>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>BarChart</h1>
|
||||
<h2></h2>
|
||||
</header>
|
||||
<section>
|
||||
<button eicbutton rounded basic primary small icon="icon-writing" class="show-code" data-codeclass="barchart"></button>
|
||||
<div eicbarchart></div>
|
||||
</section>
|
||||
</article>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>LineChart</h1>
|
||||
<h2></h2>
|
||||
</header>
|
||||
<section>
|
||||
<div class="">
|
||||
<button eicbutton rounded basic primary small icon="icon-writing" class="show-code" data-codeclass="linechart"></button>
|
||||
<div eiclinechart></div>
|
||||
<div>
|
||||
<span eicchip success small>Sidney</span>
|
||||
<span eicchip primary small>New York</span>
|
||||
<span eicchip danger small>Notre-Dame-de-Livoye</span>
|
||||
</div>
|
||||
<div eicalert info>
|
||||
<p>Note: Due to the fact that this component uses paths and path coordinates cannot be declared as relative (using percentage for instance), if you need a fluid resizing of the component, you need to call the redraw() method when resizing your container (typically using the DOMContentResized() method of your view).<br/>
|
||||
example:</p>
|
||||
<code>
|
||||
class myview extends DOMContent {
|
||||
|
||||
...
|
||||
|
||||
DOMContentResized() {
|
||||
super.DOMContentResized();
|
||||
this.mylinechart.redraw();
|
||||
}
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</article>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>PieTreeChart</h1>
|
||||
<h2></h2>
|
||||
</header>
|
||||
<section>
|
||||
<div class="">
|
||||
<button eicbutton rounded basic primary small icon="icon-writing" class="show-code" data-codeclass="pietreechart"></button>
|
||||
<div class="cols-5">
|
||||
<div>
|
||||
<div pietreechart1></div>
|
||||
<ul class="features">
|
||||
<li>100% compatible pieChart</li>
|
||||
<li>Same animation (refocus window)</li>
|
||||
<li>default CCW sort</li>
|
||||
<li>(here with <i>angularGap</i> = 0)</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<div pietreechart2></div>
|
||||
<ul class="features">
|
||||
<li><i>innerRadius</i> = 0 for old-style full pie</li>
|
||||
<li>Here <i>angularGap</i> = 5 to spread slices</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<div pietreechart3></div>
|
||||
<ul class="features">
|
||||
<li>Two levels</li>
|
||||
<li><i>angularGap</i> and <i>layerGap</i></li>
|
||||
<li>Children custom <i>severity</i></li>
|
||||
<li>De-centered whith custom <i>center</i></li>
|
||||
<li>Custom, clock-wise <i>sort</i></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<div pietreechart4></div>
|
||||
<ul class="features">
|
||||
<li>Children inherited <i>severity</i>...</li>
|
||||
<li>with increased <i></i>brightness</i></li>
|
||||
<li><i>click</i>-able</li>
|
||||
<li>Slices <i>datasets</i></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<div pietreechart5></div>
|
||||
<ul class="features">
|
||||
<li>3 levels</li>
|
||||
<li>Children inherited <i>severity</i>...</li>
|
||||
<li>with decreased <i></i>brightness</i></li>
|
||||
<li>Slice titles (hover)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</article>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>FileUpload</h1>
|
||||
<h2></h2>
|
||||
</header>
|
||||
<section>
|
||||
<button eicbutton rounded basic primary small icon="icon-writing" class="show-code" data-codeclass="fileuploadexample"></button>
|
||||
<h4>Normal server:</h4>
|
||||
<div eicfileupload class="filupld fileuploadexample" data-codetitle="Upload to normal server"></div>
|
||||
<h4>AWS infra (getting signed URL):</h4>
|
||||
<div eicfileupload class="filupld2 fileuploadexample" data-codetitle="Upload to AWS S3 bucket"></div>
|
||||
</section>
|
||||
</article>
|
||||
</section>
|
||||
</article>
|
||||
@@ -1,282 +0,0 @@
|
||||
class EICUIView extends EICDomContent {
|
||||
|
||||
DOMContentLoaded() {
|
||||
|
||||
/* tabdefault : show_code_start */
|
||||
let tab = new Tab();
|
||||
tab.addTabs(this.findAll('MENU[eictab].sample1 li'), this.findAll('.tab-content.sample1'));
|
||||
tab.disableByIndex(1);
|
||||
/* tabdefault : show_code_end */
|
||||
|
||||
/* tabvertical : show_code_start */
|
||||
tab = new Tab();
|
||||
tab.addTabs(this.findAll('MENU[eictab].sample2 li'), this.findAll('.tab-content.sample2'));
|
||||
tab.disableByIndex(2);
|
||||
/* tabvertical : show_code_end */
|
||||
|
||||
/* growlerexample : show_code_start */
|
||||
let growlButtons = this.findAll('button.growl-test');
|
||||
for(let i = 0; i < growlButtons.length; i++) {
|
||||
let button = growlButtons[i];
|
||||
|
||||
button.addEventListener('click', function(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
let button = event.currentTarget;
|
||||
ui.growl.append(button.dataset.message, button.dataset.severity);
|
||||
});
|
||||
}
|
||||
/* growlerexample : show_code_end */
|
||||
|
||||
/* dialogexample : show_code_start */
|
||||
let dialogButton = this.find('button.dialog-test');
|
||||
|
||||
dialogButton.addEventListener('click', function(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
this.openDialog(('Do you see this dialog?'))
|
||||
.then(function(result) {
|
||||
if(result)
|
||||
ui.growl.append('You approved the dialog', 'success');
|
||||
else
|
||||
ui.growl.append('You dismissed the dialog', 'warning');
|
||||
})
|
||||
|
||||
.catch(function() {
|
||||
ui.growl.append('You canceled the dialog', 'warning');
|
||||
})
|
||||
/**/
|
||||
}.bind(this));
|
||||
/* dialogexample : show_code_end */
|
||||
|
||||
let components = ui.eicfy(this.el);
|
||||
let togglers = components.filter(el => el.el.getAttribute('type')=='toggler')
|
||||
for(let toggy of togglers) toggy.onToggle = (val, obj) => console.log('toggler:',val, obj)
|
||||
|
||||
let grid = new DataGrid(this.find('[eicdatagrid]'), {
|
||||
headers: [
|
||||
{label: 'name', filter: 'text', sortable:true},
|
||||
{label: 'ingredients', filter: 'list', sortable:true},
|
||||
{label: 'price', type: 'currency', sortable:true},
|
||||
],
|
||||
height: '150px'
|
||||
});
|
||||
grid.addRow('1', [ 'Margarita', new Array('tomato', 'mozza'), 8.50 ]);
|
||||
grid.addRow('2', [ 'Chorizo', new Array('tomato', 'mozza', 'chorizo'), 10.50 ]);
|
||||
grid.addRow('3', [ 'Regina', new Array('tomato', 'mozza', 'ham', 'schrooms'), 10.50 ]);
|
||||
grid.addRow('4', [ 'Hawaï', new Array('tomato', 'mozza', 'ham', 'Pineapple'), 11.50 ]);
|
||||
grid.addRow('5', [ 'Garlic', new Array('tomato', 'mozza', 'garlic'), 10.00 ]);
|
||||
grid.addRow('6', [ 'Napoli', new Array('tomato', 'mozza', 'ham', 'Olive'), 13.00 ]);
|
||||
/* gridexample : show_code_end */
|
||||
|
||||
/* barchart : show_code_start */
|
||||
|
||||
new BarChart(this.find('[eicbarchart]'), {
|
||||
title: 'Bars sample',
|
||||
height: 200,
|
||||
data: [
|
||||
{value: 10, label:'', severity: 'danger'},
|
||||
{value: 20, label:'', severity: 'warning'},
|
||||
{value: 30, label:'', severity: 'primary'},
|
||||
{value: 50, label:'', severity: 'success'},
|
||||
]
|
||||
});
|
||||
/* barchart : show_code_end */
|
||||
|
||||
/* linechart : show_code_start */
|
||||
this.linechart = new LineChart(this.find('[eiclinechart]'), {
|
||||
title: 'Weather Forecast',
|
||||
height: 180,
|
||||
data: [
|
||||
{
|
||||
severity: 'primary',
|
||||
unit: '°C',
|
||||
data: [ 0, 5, 12, 24, 17]
|
||||
},
|
||||
{
|
||||
severity: 'danger',
|
||||
unit: '°C',
|
||||
data: [ 2, 3, 14, 22, 13]
|
||||
},
|
||||
{
|
||||
severity: 'success',
|
||||
unit: '°C',
|
||||
data: [ 19, 11, 9, 10, 12]
|
||||
}
|
||||
],
|
||||
labels: [
|
||||
'27 jun', '28 jun', '29 jun', '30 jun', '1 jul'
|
||||
]
|
||||
});
|
||||
/* linechart : show_code_end */
|
||||
|
||||
/* pietreechart : show_code_start */
|
||||
new PieTreeChart(this.find('[pietreechart1]'), {
|
||||
title: '',
|
||||
height: 200,
|
||||
data: [
|
||||
{ severity: 'danger', value: 25 },
|
||||
{ severity: 'success', value: 30 },
|
||||
{ severity: 'secondary', value: 15 },
|
||||
{ severity: 'primary', value: 22 },
|
||||
{ severity: 'warning', value: 8 },
|
||||
],
|
||||
angularGap:0,
|
||||
})
|
||||
new PieTreeChart(this.find('[pietreechart2]'), {
|
||||
title: '',
|
||||
height: 200,
|
||||
data: [
|
||||
{ severity: 'danger', value: 25 },
|
||||
{ severity: 'success', value: 30 },
|
||||
{ severity: 'secondary', value: 15 },
|
||||
{ severity: 'primary', value: 22 },
|
||||
{ severity: 'warning', value: 8 },
|
||||
],
|
||||
angularGap:5,
|
||||
innerRadius:0,
|
||||
outerRadius:50
|
||||
})
|
||||
new PieTreeChart(this.find('[pietreechart3]'), {
|
||||
title: '',
|
||||
height: 200,
|
||||
center:['70%','30%'],
|
||||
sort: ((a,b) => a.value < b.value ? 1 : -1),
|
||||
data: [
|
||||
{ severity: 'danger', value: 25, children: [
|
||||
{ severity: 'secondary', value: 10 },
|
||||
{ severity: 'primary', value: 20 },
|
||||
{ severity: 'success', value: 30 },
|
||||
{ severity: 'warning', value: 40 },
|
||||
]
|
||||
},
|
||||
{ severity: 'success', value: 30 },
|
||||
{ severity: 'secondary', value: 15 },
|
||||
{ severity: 'primary', value: 22 },
|
||||
{ severity: 'warning', value: 8 },
|
||||
],
|
||||
innerRadius:5,
|
||||
outerRadius:50
|
||||
})
|
||||
new PieTreeChart(this.find('[pietreechart4]'), {
|
||||
title: '',
|
||||
height: 200,
|
||||
data: [
|
||||
{ severity: 'danger', value: 25, dataset:{ id:'aa', val:25 }, children: [
|
||||
{ severity: 'inherit', brightness:'120%', value: 10, dataset:{ id:'aa.1', val:10 } },
|
||||
{ severity: 'inherit', brightness:'120%', value: 20, dataset:{ id:'aa.2', val:20 } },
|
||||
{ severity: 'inherit', brightness:'120%', value: 30, dataset:{ id:'aa.3', val:30 } },
|
||||
{ severity: 'inherit', brightness:'120%', value: 40, dataset:{ id:'aa.4', val:40 } },
|
||||
]
|
||||
},
|
||||
{ severity: 'success', value: 30, dataset:{ id:'bb', val:30 } },
|
||||
{ severity: 'secondary', value: 15, dataset:{ id:'cc', val:15 }, children: [
|
||||
{ severity: 'inherit', brightness:'120%', value: 50, dataset:{ id:'cc.1', val:50 } },
|
||||
{ severity: 'inherit', brightness:'120%', value: 20, dataset:{ id:'cc.2', val:20 } },
|
||||
{ severity: 'inherit', brightness:'120%', value: 30, dataset:{ id:'cc.3', val:30 } },
|
||||
]
|
||||
},
|
||||
{ severity: 'primary', value: 22, dataset:{ id:'dd', val:22 } },
|
||||
{ severity: 'warning', value: 8, dataset:{ id:'ee', val:8 } },
|
||||
],
|
||||
innerRadius:5,
|
||||
outerRadius:50,
|
||||
click: (e=>console.log('Clicked:',e.target.dataset ))
|
||||
})
|
||||
new PieTreeChart(this.find('[pietreechart5]'), {
|
||||
title: '',
|
||||
height: 200,
|
||||
data: [
|
||||
{ severity: 'danger', value: 25, title:'Red root area', children: [
|
||||
{ severity: 'inherit', brightness:'80%', value: 10, title:'Red direct child 1 area' },
|
||||
{ severity: 'inherit', brightness:'80%', value: 20, title:'Red direct child 2 area' },
|
||||
{ severity: 'inherit', brightness:'80%', value: 30, title:'Red direct child 3 area' },
|
||||
{ severity: 'inherit', brightness:'80%', value: 40, title:'Red direct child 4 area' },
|
||||
]
|
||||
},
|
||||
{ severity: 'success', value: 30, title:'Green root area', children: [
|
||||
{ severity: 'inherit', brightness:'80%', value: 2, title:'Green direct child 1 area' },
|
||||
{ severity: 'inherit', brightness:'80%', value: 4, title:'Green direct child 2 area' },
|
||||
{ severity: 'inherit', brightness:'80%', value: 6, title:'Green direct child 3 area' },
|
||||
]
|
||||
},
|
||||
{ severity: 'secondary', value: 15, title:'Grey root area', children: [
|
||||
{ severity: 'inherit', brightness:'80%', value: 50, title:'Grey direct child 1 area', children: [
|
||||
{ severity: 'inherit', brightness:'60%', value: 10, title:'Grey grand-child 1 area' },
|
||||
{ severity: 'inherit', brightness:'60%', value: 10, title:'Grey grand-child 2 area' },
|
||||
{ severity: 'inherit', brightness:'60%', value: 5 , title:'Grey grand-child 3 area' },
|
||||
] },
|
||||
{ severity: 'inherit', brightness:'80%', value: 20, title:'Grey direct child 2 area' },
|
||||
{ severity: 'inherit', brightness:'80%', value: 30, title:'Grey direct child 3 area' },
|
||||
]
|
||||
},
|
||||
{ severity: 'primary', value: 22, title:'Blue root area' },
|
||||
{ severity: 'warning', value: 8, title:'Orange root area' },
|
||||
],
|
||||
innerRadius:5,
|
||||
outerRadius:50
|
||||
})
|
||||
|
||||
/* pietreechart : show_code_end */
|
||||
|
||||
/* fileuploadexample : show_code_start */
|
||||
|
||||
// Normal server :
|
||||
this.fileUpload = new FileUpload(this.find('.filupld'), {
|
||||
uploadUrl: 'https://myserver.com/upload?file=',
|
||||
uploadMethod: 'POST',
|
||||
allowedExtensions: ['pdf'],
|
||||
allowDrop: true,
|
||||
maxFiles: 3,
|
||||
minFiles: 1,
|
||||
dndLabel : 'Drop your pitch PDFs here !'
|
||||
});
|
||||
/* fileuploadexample : show_code_end */
|
||||
|
||||
|
||||
// To AWS S3 bucket (pre-requesting a signed URL)
|
||||
/* Nike: Dependency async issue in this page,
|
||||
* but this AWS thing is meant to be deprecated anyway (cooloff period end: 31/11/2024) */
|
||||
// this.awsfileUpload = new AwsFileUpload(this.find('.filupld2'), {
|
||||
// getSignedUrlUrl : 'https://api.dev.eismea.eu/vod/source?file=',
|
||||
// getSignedUrlMethod : 'PUT',
|
||||
// apiKey: 'xxxyyyyzzzz',
|
||||
// uploadUrl: '',
|
||||
// uploadMethod: 'PUT',
|
||||
// allowedExtensions: ['mp4'],
|
||||
// allowedMimes: ['video/mp4'],
|
||||
// allowDrop: true,
|
||||
// maxFiles: 1,
|
||||
// minFiles: 1,
|
||||
// dndLabel : 'Drop your presentation video (mp4) here !'
|
||||
// });
|
||||
|
||||
let codeButtons = components.filter(el => el.el.classList.contains('show-code'))
|
||||
for(let codeButton of codeButtons) {
|
||||
codeButton.click = this.showCode.bind(this, codeButton)
|
||||
}
|
||||
}
|
||||
|
||||
async showCode(buttonObj, event) {
|
||||
event.preventDefault(); event.stopPropagation();
|
||||
let styleguideTemplate = app.Assets.Store.html[`/app/views/${this._className}.html`];
|
||||
let styleguideCode = this.DOMContentLoaded.toString();
|
||||
let result = await this.openDialog(await this.loadContent('system/tools/dialogs/codeTemplateDialog',
|
||||
{ title: `Code explorer` },
|
||||
{ styleguideView : this,
|
||||
styleguideTemplate : styleguideTemplate,
|
||||
styleguideCode: styleguideCode,
|
||||
codeclass: buttonObj.el.dataset.codeclass,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
DOMContentResized() {
|
||||
super.DOMContentResized();
|
||||
this.linechart.redraw();
|
||||
}
|
||||
}
|
||||
|
||||
app.registerClass('EICUIView', EICUIView)
|
||||
@@ -1,310 +0,0 @@
|
||||
<style type="text/css">
|
||||
.icon-list {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.icon-list li {
|
||||
list-style: none;
|
||||
display: grid;
|
||||
justify-items: center;
|
||||
margin: 10px;
|
||||
font-family: var(--eicui-base-font-family);
|
||||
width: 100px;
|
||||
}
|
||||
.icon-list li i {
|
||||
padding: 10px 10px;
|
||||
margin: 3px;
|
||||
border: 1px solid gray;
|
||||
width: 30px;
|
||||
display: flex;
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
background: var(--eicui-base-color-grey-15);
|
||||
font-size: var(--eicui-base-font-size-2xl);
|
||||
}
|
||||
.icon-list li label { font-size: var(--eicui-base-font-size-xs); }
|
||||
.styleguide > header { background: url('/app/assets/images/cards/styleguide.jpg'); }
|
||||
.grid-hilite span {
|
||||
display: block;
|
||||
min-height: 30px;
|
||||
border: 1px solid var(--eicui-base-color-primary-100);
|
||||
}
|
||||
</style>
|
||||
<article eiccard media class="styleguide">
|
||||
<header>
|
||||
<h1>Style guide</h1>
|
||||
</header>
|
||||
<section>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>Typography</h1>
|
||||
<h2>Utility classes available for text formatting</h2>
|
||||
<nav></nav>
|
||||
</header>
|
||||
<section>
|
||||
<h3>Font definition</h3>
|
||||
<a href="https://myeic.dev.eismea.eu/files/dg7LP7Tl3Tam8kO0onbrccQ" target="_blank">test1</a>
|
||||
<a href="/files/dg7LP7Tl3Tam8kO0onbrccQ" target="_blank">test2</a>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="eui-u-width-20">preview</th>
|
||||
<th>Name</th>
|
||||
<th>Value</th>
|
||||
<th>Utility class</th>
|
||||
<th>CSS variable</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<p class="eui-u-font-2xs">Sample text</p>
|
||||
</td>
|
||||
<td>2xs</td>
|
||||
<td>0.625rem</td>
|
||||
<td>eui-u-font-2xs</td>
|
||||
<td>--eicui-base-font-2xs</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p class="eui-u-font-xs">Sample text</p>
|
||||
</td>
|
||||
<td>xs</td>
|
||||
<td>0.75rem</td>
|
||||
<td>eui-u-font-xs</td>
|
||||
<td>--eicui-base-font-xs</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p class="eui-u-font-s">Sample text</p>
|
||||
</td>
|
||||
<td>s</td>
|
||||
<td>0.875rem</td>
|
||||
<td>eui-u-font-s</td>
|
||||
<td>--eicui-base-font-s</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p class="eui-u-font-m">Sample text</p>
|
||||
</td>
|
||||
<td>m</td>
|
||||
<td>1rem</td>
|
||||
<td>eui-u-font-m</td>
|
||||
<td>--eicui-base-font-m</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p class="eui-u-font-l">Sample text</p>
|
||||
</td>
|
||||
<td>l</td>
|
||||
<td>1.125rem</td>
|
||||
<td>eui-u-font-l</td>
|
||||
<td>--eicui-base-font-l</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p class="eui-u-font-xl">Sample text</p>
|
||||
</td>
|
||||
<td>xl</td>
|
||||
<td>1.25rem</td>
|
||||
<td>eui-u-font-xl</td>
|
||||
<td>--eicui-base-font-xl</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p class="eui-u-font-2xl">Sample text</p>
|
||||
</td>
|
||||
<td>2xl</td>
|
||||
<td>1.5rem</td>
|
||||
<td>eui-u-font-2xl</td>
|
||||
<td>--eicui-base-font-2xl</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p class="eui-u-font-3xl">Sample text</p>
|
||||
</td>
|
||||
<td>3xl</td>
|
||||
<td>1.75rem</td>
|
||||
<td>eui-u-font-3xl</td>
|
||||
<td>--eicui-base-font-3xl</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p class="eui-u-font-4xl">Sample text</p>
|
||||
</td>
|
||||
<td>4xl</td>
|
||||
<td>2rem</td>
|
||||
<td>eui-u-font-4xl</td>
|
||||
<td>--eicui-base-font-4xl</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p class="eui-u-font-5xl">Sample text</p>
|
||||
</td>
|
||||
<td>5xl</td>
|
||||
<td>2.25rem</td>
|
||||
<td>eui-u-font-5xl</td>
|
||||
<td>--eicui-base-font-5xl</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p class="eui-u-font-6xl">Sample text</p>
|
||||
</td>
|
||||
<td>6xl</td>
|
||||
<td>2.675rem</td>
|
||||
<td>eui-u-font-6xl</td>
|
||||
<td>--eicui-base-font-6xl</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
</article>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>Grid system</h1>
|
||||
<h2></h2>
|
||||
</header>
|
||||
<section>
|
||||
<p>You can organize your contents in columns. The amount of columns to be used is defined through a class entry in the contents container.</p>
|
||||
<p>Note that when using this grid system, the app will track interface resizing an adapt the column in order to keep a fluid display.</p>
|
||||
<div class="grid-hilite">
|
||||
<h6>2 columns (<code>class="cols-2"</code>)</h6>
|
||||
<div class="cols-2">
|
||||
<span></span>
|
||||
<span></span>
|
||||
</div>
|
||||
<h6>3 columns (<code>class="cols-3"</code>)</h6>
|
||||
<div class="cols-3">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</div>
|
||||
<h6>4 columns (<code>class="cols-4"</code>)</h6>
|
||||
<div class="cols-4">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</div>
|
||||
<h6>5 columns (<code>class="cols-5"</code>)</h6>
|
||||
<div class="cols-5">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</div>
|
||||
<h6>6 columns (<code>class="cols-6"</code>)</h6>
|
||||
<div class="cols-6">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</div>
|
||||
<h6>8 columns (<code>class="cols-8"</code>)</h6>
|
||||
<div class="cols-8">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</article>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>Color system</h1>
|
||||
<h2>Normalized color coding</h2>
|
||||
</header>
|
||||
<section>
|
||||
<h6>Severity</h6>
|
||||
<p>EUI provides a reduced set of colors providing a semantic information to the user.</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Meaning</th>
|
||||
<th>Color</th>
|
||||
<th>Attribute*</th>
|
||||
<th>css variable name</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Primary</td>
|
||||
<td><button eicbutton primary></button></td>
|
||||
<td>primary</td>
|
||||
<td>--eicui-base-color-primary-100</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Secondary</td>
|
||||
<td><button eicbutton ></button></td>
|
||||
<td>(used as default)</td>
|
||||
<td>--eicui-base-color-secondary-100</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Success</td>
|
||||
<td><button eicbutton success></button></td>
|
||||
<td>success</td>
|
||||
<td>--eicui-base-color-success-100</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Warning</td>
|
||||
<td><button eicbutton warning></button></td>
|
||||
<td>warning</td>
|
||||
<td>--eicui-base-color-warning-100</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Danger/failure</td>
|
||||
<td><button eicbutton danger></button></td>
|
||||
<td>danger</td>
|
||||
<td>--eicui-base-color-danger-100</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Info</td>
|
||||
<td><button eicbutton info></button></td>
|
||||
<td>info</td>
|
||||
<td>--eicui-base-color-info-100</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Accent</td>
|
||||
<td><button eicbutton accent></button></td>
|
||||
<td>accent</td>
|
||||
<td>--eicui-base-color-accent-100</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>* See components tagged with <span eicchip xsmall info>severity</span>, indicating they support severity color system</p>
|
||||
</section>
|
||||
</article>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>Headings</h1>
|
||||
<h2>Styles available for title formatting</h2>
|
||||
</header>
|
||||
<section>
|
||||
<h1>This is heading 1</h1>
|
||||
<h2>This is heading 2</h2>
|
||||
<h3>This is heading 3</h3>
|
||||
<h4>This is heading 4</h4>
|
||||
<h5>This is heading 5</h5>
|
||||
<h6>This is heading 6</h6>
|
||||
</section>
|
||||
</article>
|
||||
<article eiccard collapsable collapsed>
|
||||
<header>
|
||||
<h1>Icons</h1>
|
||||
<h2>Set of UI icons</h2>
|
||||
</header>
|
||||
<section>
|
||||
<ul class="icon-list"></ul>
|
||||
</section>
|
||||
</article>
|
||||
</section>
|
||||
</article>
|
||||
@@ -1,46 +0,0 @@
|
||||
class styleguideView extends EICDomContent {
|
||||
|
||||
DOMContentLoaded() {
|
||||
|
||||
// building icon list
|
||||
let iconList = this.find('ul.icon-list');
|
||||
let sheet = null;
|
||||
|
||||
for(let i = 0; document.styleSheets.length; i++) {
|
||||
let rule = document.styleSheets[i];
|
||||
if(rule) {
|
||||
let rules
|
||||
try { rules = rule.cssRules }
|
||||
catch(err) { rules = [] }
|
||||
for(let r = 0; r < rules.length; r++) {
|
||||
let islocal = rule.href && ( (new URL(rule.href)).host == document.location.host);
|
||||
if( (rules.item(r).styleSheet) && islocal) {
|
||||
sheet = rules.item(r).styleSheet;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(sheet) {
|
||||
let classes = [];
|
||||
for(let i = 0; i < sheet.rules.length; i++) {
|
||||
let rule = sheet.rules.item(i);
|
||||
if(rule.selectorText && rule.selectorText.indexOf('.icon-') == 0) {
|
||||
classes.push(rule.selectorText.replace('.', '').replace('::before', ''))
|
||||
}
|
||||
}
|
||||
|
||||
classes.sort();
|
||||
for(let i = 0; i < classes.length; i++) {
|
||||
let cls = classes[i];
|
||||
iconList.appendChild(ui.create(`<li><i medium class="${cls}"></i><label>${cls.replace('icon-', '')}</label></li>`))
|
||||
}
|
||||
}
|
||||
|
||||
ui.eicfy(this.el);
|
||||
}
|
||||
}
|
||||
|
||||
app.registerClass('styleguideView', styleguideView)
|
||||
Reference in New Issue
Block a user