- Improved map page grid layout (2 and 3 column based layout), closed #935
This commit is contained in:
34
img/svg/grid_layout.svg
Normal file
34
img/svg/grid_layout.svg
Normal file
@@ -0,0 +1,34 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%">
|
||||
<defs>
|
||||
<g id="pf-svg-grid-3" fill="currentColor">
|
||||
<title>3 columns</title>
|
||||
<rect width="65" height="22" fill="#212c30" />
|
||||
<rect width="40" height="35" y="25" />
|
||||
<rect width="22" height="60" x="68" />
|
||||
<rect width="22" height="35" x="43" y="25" />
|
||||
</g>
|
||||
<g id="pf-svg-grid-2" fill="currentColor">
|
||||
<title>2 columns</title>
|
||||
<rect width="90" height="22" fill="#212c30" />
|
||||
<rect width="55" height="35" y="25" />
|
||||
<rect width="32" height="16" y="25" x="58" />
|
||||
<rect width="32" height="16" y="44" x="58" />
|
||||
</g>
|
||||
</defs>
|
||||
|
||||
<symbol id="pf-svg-grid-3-right" viewBox="0 0 90 60" width="100%" height="100%">
|
||||
<use href="#pf-svg-grid-3" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="pf-svg-grid-3-left" viewBox="0 0 90 60" width="100%" height="100%">
|
||||
<use href="#pf-svg-grid-3-right" transform="translate(90,0) scale(-1,1)" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="pf-svg-grid-2-right" viewBox="0 0 90 60" width="100%" height="100%">
|
||||
<use href="#pf-svg-grid-2" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="pf-svg-grid-2-left" viewBox="0 0 90 60" width="100%" height="100%">
|
||||
<use href="#pf-svg-grid-2-right" transform="translate(90,0) scale(-1,1)" />
|
||||
</symbol>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
31
js/app/lib/svg.js
Normal file
31
js/app/lib/svg.js
Normal file
@@ -0,0 +1,31 @@
|
||||
define([], () => {
|
||||
'use strict';
|
||||
|
||||
class SVG {
|
||||
|
||||
static updateSymbolSvg(svgEl, href){
|
||||
let useEl = svgEl.getElementsByTagNameNS(this.namespaces.svg, 'use')[0];
|
||||
if(useEl){
|
||||
useEl.setAttribute('href', href);
|
||||
}
|
||||
}
|
||||
|
||||
static newSymbolSvg(href){
|
||||
let svgEl = this.newEl();
|
||||
let useEl = this.newEl('use');
|
||||
useEl.setAttribute('href', href);
|
||||
svgEl.appendChild(useEl);
|
||||
return svgEl;
|
||||
}
|
||||
|
||||
static newEl(nodeName = 'svg', namespaceURI = this.namespaces.svg){
|
||||
return document.createElementNS(namespaceURI, nodeName);
|
||||
}
|
||||
}
|
||||
|
||||
SVG.namespaces = {
|
||||
'svg': 'http://www.w3.org/2000/svg'
|
||||
};
|
||||
|
||||
return SVG;
|
||||
});
|
||||
@@ -5,6 +5,7 @@ define([
|
||||
'app/map/map',
|
||||
'app/map/util',
|
||||
'app/lib/eventHandler',
|
||||
'app/lib/svg',
|
||||
'sortable',
|
||||
'module/base',
|
||||
'module/system_info',
|
||||
@@ -23,6 +24,7 @@ define([
|
||||
Map,
|
||||
MapUtil,
|
||||
EventHandler,
|
||||
Svg,
|
||||
Sortable,
|
||||
BaseModule,
|
||||
SystemInfoModule,
|
||||
@@ -61,9 +63,13 @@ define([
|
||||
editableHeadlineClass: 'pf-editable-headline',
|
||||
editableToggleClass: 'pf-editable-toggle',
|
||||
editableToggleItemClass: 'pf-editable-toggle-item',
|
||||
editableToggleSvgClass: 'pf-editable-toggle-svg',
|
||||
editableToggleBtnClass: 'pf-editable-toggle-btn',
|
||||
|
||||
mapTabContentLayoutOptions: ['left', 'right'],
|
||||
defaultMapTabContentLayout: 'right',
|
||||
mapTabContentLayoutColumnOptions: ['grid-2', 'grid-3'],
|
||||
mapTabContentLayoutOrientationOptions: ['left', 'right'],
|
||||
defaultMapTabContentCols: 'grid-3',
|
||||
defaultMapTabContentOrientation: 'right',
|
||||
};
|
||||
|
||||
let mapTabChangeBlocked = false; // flag for preventing map tab switch
|
||||
@@ -1533,7 +1539,12 @@ define([
|
||||
}
|
||||
|
||||
let setMapTabLayout = (tabEl, layoutNew) => {
|
||||
config.mapTabContentLayoutOptions.forEach(layout => tabEl.classList.toggle(layout, layout === layoutNew));
|
||||
config.mapTabContentLayoutColumnOptions.forEach(columns => tabEl.classList.toggle(columns, columns === layoutNew.columns));
|
||||
config.mapTabContentLayoutOrientationOptions.forEach(orientation => tabEl.classList.toggle(orientation, orientation === layoutNew.orientation));
|
||||
};
|
||||
|
||||
let getLayoutSvgLink = (layoutCols = config.defaultMapTabContentCols, orientation = config.defaultMapTabContentOrientation) => {
|
||||
return `#pf-svg-${layoutCols}-${orientation}`;
|
||||
};
|
||||
|
||||
Promise.all([
|
||||
@@ -1542,8 +1553,11 @@ define([
|
||||
]).then(payload => {
|
||||
let modules = payload[0];
|
||||
let localDataMap = payload[1];
|
||||
let layoutCurrent = Util.getObjVal(localDataMap, 'layout') || config.defaultMapTabContentLayout;
|
||||
let disabledValues = Util.getObjVal(localDataMap, 'modulesDisabled');
|
||||
let layoutCurrent = Object.assign({}, {
|
||||
columns: config.defaultMapTabContentCols,
|
||||
orientation: config.defaultMapTabContentOrientation
|
||||
}, Util.getObjVal(localDataMap, 'layout'));
|
||||
|
||||
// update mapModule with current layout class
|
||||
setMapTabLayout(tabEl, layoutCurrent);
|
||||
@@ -1601,40 +1615,98 @@ define([
|
||||
// add "layout" toggle to popover -----------------------------------------------------------------
|
||||
let anchorEl = editable.container.$form[0].querySelector(`.${config.editableSettingsClass}`);
|
||||
|
||||
let gridEl = Object.assign(document.createElement('div'), {
|
||||
className: config.editableToggleClass
|
||||
let toggleGroupEl = Object.assign(document.createElement('div'), {
|
||||
className: [config.editableToggleClass].join(' ')
|
||||
});
|
||||
|
||||
let gridItemEls = config.mapTabContentLayoutOptions.map(layout => {
|
||||
let gridItemEl = Object.assign(document.createElement('div'), {
|
||||
className: config.editableToggleItemClass + (layout === layoutCurrent ? ' active' : '')
|
||||
let gridItemEls = config.mapTabContentLayoutColumnOptions.map((layoutCols, i) => {
|
||||
let isActive = layoutCols === layoutCurrent.columns;
|
||||
let orientation = isActive ? layoutCurrent.orientation : undefined;
|
||||
|
||||
let svgEl = Svg.newSymbolSvg(getLayoutSvgLink(layoutCols, orientation));
|
||||
svgEl.classList.add('btn', 'btn-default', config.editableToggleSvgClass);
|
||||
svgEl.dataset.value = layoutCols;
|
||||
if(isActive){
|
||||
svgEl.classList.add('active');
|
||||
}
|
||||
|
||||
// left/right layout button
|
||||
let btnEl = Object.assign(document.createElement('div'), {
|
||||
className: ['btn', 'btn-xs', 'btn-default', config.editableToggleBtnClass].join(' ')
|
||||
});
|
||||
gridItemEl.style.setProperty('--bg-image', `url("${Util.imgRoot()}/icons/grid_${layout}.png")`);
|
||||
gridItemEl.dataset.value = layout;
|
||||
return gridItemEl;
|
||||
btnEl.append(Object.assign(document.createElement('i'), {
|
||||
className: ['fas', 'fa-rotate-90', 'fa-retweet'].join(' ')
|
||||
}));
|
||||
btnEl.dataset.value = 'left';
|
||||
if(!isActive){
|
||||
btnEl.classList.add('disabled');
|
||||
}
|
||||
if(orientation === btnEl.dataset.value){
|
||||
btnEl.classList.add('active');
|
||||
}
|
||||
|
||||
// btn group
|
||||
let btnGroupEl = Object.assign(document.createElement('div'), {
|
||||
className: ['btn-group', config.editableToggleItemClass].join(' ')
|
||||
});
|
||||
btnGroupEl.append(...(i % 2) ? [svgEl, btnEl] : [btnEl, svgEl]);
|
||||
|
||||
return btnGroupEl;
|
||||
});
|
||||
gridItemEls.splice(1, 0, Object.assign(document.createElement('i'), {
|
||||
className: ['fas', 'fa-lg', 'fa-exchange-alt'].join(' ')
|
||||
}));
|
||||
gridEl.append(...gridItemEls);
|
||||
anchorEl.insertAdjacentElement('beforebegin', gridEl);
|
||||
|
||||
toggleGroupEl.append(...gridItemEls);
|
||||
anchorEl.insertAdjacentElement('beforebegin', toggleGroupEl);
|
||||
|
||||
// click event for layout switch -> change layout -> store new layout setting
|
||||
EventHandler.addEventListener(gridEl, 'click.toggleSelect', e => {
|
||||
if(e.target.classList.contains(config.editableToggleItemClass)){
|
||||
let layoutNew = e.target.dataset.value;
|
||||
if(layoutNew !== layoutCurrent){
|
||||
gridItemEls.forEach(gridItemEl => gridItemEl.classList.toggle('active'));
|
||||
let activeMapId = Util.getObjVal(editable, 'options.pk');
|
||||
|
||||
Util.getLocalStore('map').setItem(`${activeMapId}.layout`, layoutNew).then(layoutNew => {
|
||||
setMapTabLayout(tabEl, layoutNew);
|
||||
// for next "toggle" detection
|
||||
layoutCurrent = layoutNew;
|
||||
editable.option('pfLayoutCurrent', layoutNew);
|
||||
});
|
||||
}
|
||||
EventHandler.addEventListener(toggleGroupEl, 'click.toggleSelect', e => {
|
||||
e.stopPropagation();
|
||||
// check if "click" bubbles up to .btn and button is not disabled
|
||||
let btnEl = e.target.closest(`.btn`);
|
||||
if(!btnEl || btnEl.classList.contains('disabled')){
|
||||
return;
|
||||
}
|
||||
|
||||
[...e.currentTarget.getElementsByClassName(config.editableToggleItemClass)].forEach(btnGroupEl => {
|
||||
let svgEl = btnGroupEl.querySelector(`.${config.editableToggleSvgClass}`);
|
||||
let btnEl = btnGroupEl.querySelector(`.${config.editableToggleBtnClass}`);
|
||||
|
||||
if(btnGroupEl === e.target.closest(`.${config.editableToggleItemClass}`)){
|
||||
if(svgEl === e.target.closest(`.${config.editableToggleSvgClass}`)){
|
||||
// click on SVG
|
||||
svgEl.classList.toggle('active', true);
|
||||
btnEl.classList.toggle('disabled', false);
|
||||
}
|
||||
|
||||
if(btnEl === e.target.closest(`.${config.editableToggleBtnClass}`)){
|
||||
// click on left/right btn
|
||||
btnEl.classList.toggle('active');
|
||||
// toggle SVG left/right
|
||||
Svg.updateSymbolSvg(svgEl, getLayoutSvgLink(
|
||||
svgEl.dataset.value,
|
||||
btnEl.classList.contains('active') ? btnEl.dataset.value : undefined
|
||||
));
|
||||
}
|
||||
|
||||
// store new values
|
||||
if(svgEl.classList.contains('active')){
|
||||
let activeMapId = Util.getObjVal(editable, 'options.pk');
|
||||
Util.getLocalStore('map').setItem(`${activeMapId}.layout`, {
|
||||
'columns': svgEl.dataset.value,
|
||||
'orientation': btnEl.classList.contains('active') ? btnEl.dataset.value : config.defaultMapTabContentOrientation
|
||||
}).then(layoutNew => {
|
||||
setMapTabLayout(tabEl, layoutNew);
|
||||
// for next "toggle" detection
|
||||
layoutCurrent = layoutNew;
|
||||
editable.option('pfLayoutCurrent', layoutNew);
|
||||
});
|
||||
}
|
||||
}else{
|
||||
Svg.updateSymbolSvg(svgEl, getLayoutSvgLink(svgEl.dataset.value));
|
||||
svgEl.classList.toggle('active', false);
|
||||
btnEl.classList.toggle('active', false);
|
||||
btnEl.classList.toggle('disabled', true);
|
||||
}
|
||||
});
|
||||
}, {passive: false});
|
||||
|
||||
// add "headlines" to Modules checklist -------------------------------------------------------
|
||||
|
||||
@@ -445,6 +445,7 @@ define([
|
||||
let executor = resolve => {
|
||||
let svgPaths = [
|
||||
'svg/logo_inline.svg',
|
||||
'svg/grid_layout.svg',
|
||||
'svg/swords.svg'
|
||||
].map(path => `text!${Util.imgRoot()}${path}!strip`);
|
||||
|
||||
|
||||
@@ -51,8 +51,7 @@ define([
|
||||
// close all modals
|
||||
$('.modal').modal('hide');
|
||||
|
||||
requirejs(['text!templates/dialog/notification.html', 'mustache'], function(template, Mustache){
|
||||
|
||||
requirejs(['text!templates/dialog/notification.html', 'mustache'], (template, Mustache) => {
|
||||
let data = {
|
||||
id: config.notificationDialogId,
|
||||
content: dialogData.content
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
34
public/img/v2.0.1/svg/grid_layout.svg
Normal file
34
public/img/v2.0.1/svg/grid_layout.svg
Normal file
@@ -0,0 +1,34 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%">
|
||||
<defs>
|
||||
<g id="pf-svg-grid-3" fill="currentColor">
|
||||
<title>3 columns</title>
|
||||
<rect width="65" height="22" fill="#212c30" />
|
||||
<rect width="40" height="35" y="25" />
|
||||
<rect width="22" height="60" x="68" />
|
||||
<rect width="22" height="35" x="43" y="25" />
|
||||
</g>
|
||||
<g id="pf-svg-grid-2" fill="currentColor">
|
||||
<title>2 columns</title>
|
||||
<rect width="90" height="22" fill="#212c30" />
|
||||
<rect width="55" height="35" y="25" />
|
||||
<rect width="32" height="16" y="25" x="58" />
|
||||
<rect width="32" height="16" y="44" x="58" />
|
||||
</g>
|
||||
</defs>
|
||||
|
||||
<symbol id="pf-svg-grid-3-right" viewBox="0 0 90 60" width="100%" height="100%">
|
||||
<use href="#pf-svg-grid-3" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="pf-svg-grid-3-left" viewBox="0 0 90 60" width="100%" height="100%">
|
||||
<use href="#pf-svg-grid-3-right" transform="translate(90,0) scale(-1,1)" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="pf-svg-grid-2-right" viewBox="0 0 90 60" width="100%" height="100%">
|
||||
<use href="#pf-svg-grid-2" />
|
||||
</symbol>
|
||||
|
||||
<symbol id="pf-svg-grid-2-left" viewBox="0 0 90 60" width="100%" height="100%">
|
||||
<use href="#pf-svg-grid-2-right" transform="translate(90,0) scale(-1,1)" />
|
||||
</symbol>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
31
public/js/v2.0.1/app/lib/svg.js
Normal file
31
public/js/v2.0.1/app/lib/svg.js
Normal file
@@ -0,0 +1,31 @@
|
||||
define([], () => {
|
||||
'use strict';
|
||||
|
||||
class SVG {
|
||||
|
||||
static updateSymbolSvg(svgEl, href){
|
||||
let useEl = svgEl.getElementsByTagNameNS(this.namespaces.svg, 'use')[0];
|
||||
if(useEl){
|
||||
useEl.setAttribute('href', href);
|
||||
}
|
||||
}
|
||||
|
||||
static newSymbolSvg(href){
|
||||
let svgEl = this.newEl();
|
||||
let useEl = this.newEl('use');
|
||||
useEl.setAttribute('href', href);
|
||||
svgEl.appendChild(useEl);
|
||||
return svgEl;
|
||||
}
|
||||
|
||||
static newEl(nodeName = 'svg', namespaceURI = this.namespaces.svg){
|
||||
return document.createElementNS(namespaceURI, nodeName);
|
||||
}
|
||||
}
|
||||
|
||||
SVG.namespaces = {
|
||||
'svg': 'http://www.w3.org/2000/svg'
|
||||
};
|
||||
|
||||
return SVG;
|
||||
});
|
||||
@@ -5,6 +5,7 @@ define([
|
||||
'app/map/map',
|
||||
'app/map/util',
|
||||
'app/lib/eventHandler',
|
||||
'app/lib/svg',
|
||||
'sortable',
|
||||
'module/base',
|
||||
'module/system_info',
|
||||
@@ -23,6 +24,7 @@ define([
|
||||
Map,
|
||||
MapUtil,
|
||||
EventHandler,
|
||||
Svg,
|
||||
Sortable,
|
||||
BaseModule,
|
||||
SystemInfoModule,
|
||||
@@ -61,9 +63,13 @@ define([
|
||||
editableHeadlineClass: 'pf-editable-headline',
|
||||
editableToggleClass: 'pf-editable-toggle',
|
||||
editableToggleItemClass: 'pf-editable-toggle-item',
|
||||
editableToggleSvgClass: 'pf-editable-toggle-svg',
|
||||
editableToggleBtnClass: 'pf-editable-toggle-btn',
|
||||
|
||||
mapTabContentLayoutOptions: ['left', 'right'],
|
||||
defaultMapTabContentLayout: 'right',
|
||||
mapTabContentLayoutColumnOptions: ['grid-2', 'grid-3'],
|
||||
mapTabContentLayoutOrientationOptions: ['left', 'right'],
|
||||
defaultMapTabContentCols: 'grid-3',
|
||||
defaultMapTabContentOrientation: 'right',
|
||||
};
|
||||
|
||||
let mapTabChangeBlocked = false; // flag for preventing map tab switch
|
||||
@@ -1533,7 +1539,12 @@ define([
|
||||
}
|
||||
|
||||
let setMapTabLayout = (tabEl, layoutNew) => {
|
||||
config.mapTabContentLayoutOptions.forEach(layout => tabEl.classList.toggle(layout, layout === layoutNew));
|
||||
config.mapTabContentLayoutColumnOptions.forEach(columns => tabEl.classList.toggle(columns, columns === layoutNew.columns));
|
||||
config.mapTabContentLayoutOrientationOptions.forEach(orientation => tabEl.classList.toggle(orientation, orientation === layoutNew.orientation));
|
||||
};
|
||||
|
||||
let getLayoutSvgLink = (layoutCols = config.defaultMapTabContentCols, orientation = config.defaultMapTabContentOrientation) => {
|
||||
return `#pf-svg-${layoutCols}-${orientation}`;
|
||||
};
|
||||
|
||||
Promise.all([
|
||||
@@ -1542,8 +1553,11 @@ define([
|
||||
]).then(payload => {
|
||||
let modules = payload[0];
|
||||
let localDataMap = payload[1];
|
||||
let layoutCurrent = Util.getObjVal(localDataMap, 'layout') || config.defaultMapTabContentLayout;
|
||||
let disabledValues = Util.getObjVal(localDataMap, 'modulesDisabled');
|
||||
let layoutCurrent = Object.assign({}, {
|
||||
columns: config.defaultMapTabContentCols,
|
||||
orientation: config.defaultMapTabContentOrientation
|
||||
}, Util.getObjVal(localDataMap, 'layout'));
|
||||
|
||||
// update mapModule with current layout class
|
||||
setMapTabLayout(tabEl, layoutCurrent);
|
||||
@@ -1601,40 +1615,98 @@ define([
|
||||
// add "layout" toggle to popover -----------------------------------------------------------------
|
||||
let anchorEl = editable.container.$form[0].querySelector(`.${config.editableSettingsClass}`);
|
||||
|
||||
let gridEl = Object.assign(document.createElement('div'), {
|
||||
className: config.editableToggleClass
|
||||
let toggleGroupEl = Object.assign(document.createElement('div'), {
|
||||
className: [config.editableToggleClass].join(' ')
|
||||
});
|
||||
|
||||
let gridItemEls = config.mapTabContentLayoutOptions.map(layout => {
|
||||
let gridItemEl = Object.assign(document.createElement('div'), {
|
||||
className: config.editableToggleItemClass + (layout === layoutCurrent ? ' active' : '')
|
||||
let gridItemEls = config.mapTabContentLayoutColumnOptions.map((layoutCols, i) => {
|
||||
let isActive = layoutCols === layoutCurrent.columns;
|
||||
let orientation = isActive ? layoutCurrent.orientation : undefined;
|
||||
|
||||
let svgEl = Svg.newSymbolSvg(getLayoutSvgLink(layoutCols, orientation));
|
||||
svgEl.classList.add('btn', 'btn-default', config.editableToggleSvgClass);
|
||||
svgEl.dataset.value = layoutCols;
|
||||
if(isActive){
|
||||
svgEl.classList.add('active');
|
||||
}
|
||||
|
||||
// left/right layout button
|
||||
let btnEl = Object.assign(document.createElement('div'), {
|
||||
className: ['btn', 'btn-xs', 'btn-default', config.editableToggleBtnClass].join(' ')
|
||||
});
|
||||
gridItemEl.style.setProperty('--bg-image', `url("${Util.imgRoot()}/icons/grid_${layout}.png")`);
|
||||
gridItemEl.dataset.value = layout;
|
||||
return gridItemEl;
|
||||
btnEl.append(Object.assign(document.createElement('i'), {
|
||||
className: ['fas', 'fa-rotate-90', 'fa-retweet'].join(' ')
|
||||
}));
|
||||
btnEl.dataset.value = 'left';
|
||||
if(!isActive){
|
||||
btnEl.classList.add('disabled');
|
||||
}
|
||||
if(orientation === btnEl.dataset.value){
|
||||
btnEl.classList.add('active');
|
||||
}
|
||||
|
||||
// btn group
|
||||
let btnGroupEl = Object.assign(document.createElement('div'), {
|
||||
className: ['btn-group', config.editableToggleItemClass].join(' ')
|
||||
});
|
||||
btnGroupEl.append(...(i % 2) ? [svgEl, btnEl] : [btnEl, svgEl]);
|
||||
|
||||
return btnGroupEl;
|
||||
});
|
||||
gridItemEls.splice(1, 0, Object.assign(document.createElement('i'), {
|
||||
className: ['fas', 'fa-lg', 'fa-exchange-alt'].join(' ')
|
||||
}));
|
||||
gridEl.append(...gridItemEls);
|
||||
anchorEl.insertAdjacentElement('beforebegin', gridEl);
|
||||
|
||||
toggleGroupEl.append(...gridItemEls);
|
||||
anchorEl.insertAdjacentElement('beforebegin', toggleGroupEl);
|
||||
|
||||
// click event for layout switch -> change layout -> store new layout setting
|
||||
EventHandler.addEventListener(gridEl, 'click.toggleSelect', e => {
|
||||
if(e.target.classList.contains(config.editableToggleItemClass)){
|
||||
let layoutNew = e.target.dataset.value;
|
||||
if(layoutNew !== layoutCurrent){
|
||||
gridItemEls.forEach(gridItemEl => gridItemEl.classList.toggle('active'));
|
||||
let activeMapId = Util.getObjVal(editable, 'options.pk');
|
||||
|
||||
Util.getLocalStore('map').setItem(`${activeMapId}.layout`, layoutNew).then(layoutNew => {
|
||||
setMapTabLayout(tabEl, layoutNew);
|
||||
// for next "toggle" detection
|
||||
layoutCurrent = layoutNew;
|
||||
editable.option('pfLayoutCurrent', layoutNew);
|
||||
});
|
||||
}
|
||||
EventHandler.addEventListener(toggleGroupEl, 'click.toggleSelect', e => {
|
||||
e.stopPropagation();
|
||||
// check if "click" bubbles up to .btn and button is not disabled
|
||||
let btnEl = e.target.closest(`.btn`);
|
||||
if(!btnEl || btnEl.classList.contains('disabled')){
|
||||
return;
|
||||
}
|
||||
|
||||
[...e.currentTarget.getElementsByClassName(config.editableToggleItemClass)].forEach(btnGroupEl => {
|
||||
let svgEl = btnGroupEl.querySelector(`.${config.editableToggleSvgClass}`);
|
||||
let btnEl = btnGroupEl.querySelector(`.${config.editableToggleBtnClass}`);
|
||||
|
||||
if(btnGroupEl === e.target.closest(`.${config.editableToggleItemClass}`)){
|
||||
if(svgEl === e.target.closest(`.${config.editableToggleSvgClass}`)){
|
||||
// click on SVG
|
||||
svgEl.classList.toggle('active', true);
|
||||
btnEl.classList.toggle('disabled', false);
|
||||
}
|
||||
|
||||
if(btnEl === e.target.closest(`.${config.editableToggleBtnClass}`)){
|
||||
// click on left/right btn
|
||||
btnEl.classList.toggle('active');
|
||||
// toggle SVG left/right
|
||||
Svg.updateSymbolSvg(svgEl, getLayoutSvgLink(
|
||||
svgEl.dataset.value,
|
||||
btnEl.classList.contains('active') ? btnEl.dataset.value : undefined
|
||||
));
|
||||
}
|
||||
|
||||
// store new values
|
||||
if(svgEl.classList.contains('active')){
|
||||
let activeMapId = Util.getObjVal(editable, 'options.pk');
|
||||
Util.getLocalStore('map').setItem(`${activeMapId}.layout`, {
|
||||
'columns': svgEl.dataset.value,
|
||||
'orientation': btnEl.classList.contains('active') ? btnEl.dataset.value : config.defaultMapTabContentOrientation
|
||||
}).then(layoutNew => {
|
||||
setMapTabLayout(tabEl, layoutNew);
|
||||
// for next "toggle" detection
|
||||
layoutCurrent = layoutNew;
|
||||
editable.option('pfLayoutCurrent', layoutNew);
|
||||
});
|
||||
}
|
||||
}else{
|
||||
Svg.updateSymbolSvg(svgEl, getLayoutSvgLink(svgEl.dataset.value));
|
||||
svgEl.classList.toggle('active', false);
|
||||
btnEl.classList.toggle('active', false);
|
||||
btnEl.classList.toggle('disabled', true);
|
||||
}
|
||||
});
|
||||
}, {passive: false});
|
||||
|
||||
// add "headlines" to Modules checklist -------------------------------------------------------
|
||||
|
||||
@@ -445,6 +445,7 @@ define([
|
||||
let executor = resolve => {
|
||||
let svgPaths = [
|
||||
'svg/logo_inline.svg',
|
||||
'svg/grid_layout.svg',
|
||||
'svg/swords.svg'
|
||||
].map(path => `text!${Util.imgRoot()}${path}!strip`);
|
||||
|
||||
|
||||
@@ -51,8 +51,7 @@ define([
|
||||
// close all modals
|
||||
$('.modal').modal('hide');
|
||||
|
||||
requirejs(['text!templates/dialog/notification.html', 'mustache'], function(template, Mustache){
|
||||
|
||||
requirejs(['text!templates/dialog/notification.html', 'mustache'], (template, Mustache) => {
|
||||
let data = {
|
||||
id: config.notificationDialogId,
|
||||
content: dialogData.content
|
||||
|
||||
@@ -1028,7 +1028,7 @@ input[type="email"]{
|
||||
.btn {
|
||||
font-family: $font-family-bold;
|
||||
will-change: background-color, border-color;
|
||||
border-radius: 2px;
|
||||
border-radius: $btn-border-radius-base;
|
||||
//@include transition( all 0.06s linear );
|
||||
@include transition( color 0.18s ease-in-out, background-color 0.18s ease-in-out, border-color 0.18s ease-in-out, box-shadow 0.18s ease-in-out );
|
||||
//@include box-shadow(0 1px 3px 0 rgba(red($black), green($black), blue($black), 0.12), 0 1px 2px 0 rgba(red($black), green($black), blue($black), 0.24));
|
||||
|
||||
@@ -166,6 +166,7 @@ $table-border-color: $gray-dark;
|
||||
//## For each of Bootstrap's buttons, define text, background and border color.
|
||||
|
||||
$btn-font-weight: normal;
|
||||
$btn-border-radius-base: 2px;
|
||||
|
||||
$btn-default-color: $gray-lightest;
|
||||
$btn-default-bg: $gray-light;
|
||||
|
||||
@@ -180,12 +180,10 @@
|
||||
border-radius: 0;
|
||||
}
|
||||
&:first-child:not(:last-child) {
|
||||
border-top-right-radius: $border-radius-base;
|
||||
border-bottom-left-radius: $border-radius-base;
|
||||
border-bottom-right-radius: $border-radius-base;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
&:last-child:not(:first-child) {
|
||||
border-bottom-left-radius: $border-radius-base;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
|
||||
border: 1px solid transparent;
|
||||
white-space: nowrap;
|
||||
@include button-size($padding-base-vertical, $padding-base-horizontal, $font-size-base, $line-height-base, $border-radius-base);
|
||||
@include button-size($padding-base-vertical, $padding-base-horizontal, $font-size-base, $line-height-base, $btn-border-radius-base);
|
||||
@include user-select(none);
|
||||
|
||||
&,
|
||||
|
||||
@@ -385,30 +385,52 @@ html{
|
||||
display: flex;
|
||||
margin-bottom: 5px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.pf-editable-toggle-item {
|
||||
@extend %pf-bg-image-wrapper;
|
||||
width: 98px;
|
||||
height: 68px;
|
||||
background-color: lighten($gray-light, 10%);
|
||||
padding: 3px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid $gray-dark;
|
||||
cursor: pointer;
|
||||
@include transition(background-color 0.08s ease-out);
|
||||
will-change: background-color;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
&.active {
|
||||
background-color: $teal;
|
||||
&:nth-child(odd) {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $teal-lighter;
|
||||
> .btn {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&.pf-editable-toggle-btn {
|
||||
font-size: 13px;
|
||||
|
||||
&:not(.disabled) {
|
||||
color: $gray-darker;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: $gray-dark; // overwrite default
|
||||
background-color: $btn-primary-bg;
|
||||
border-color: $btn-primary-border;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
color: $gray-dark;
|
||||
pointer-events: all; // required for cursor: not-allowed change (bootstrap bug) https://stackoverflow.com/a/50349274/4329969
|
||||
}
|
||||
|
||||
&.active, &:active {
|
||||
+ .btn.active, + .btn:active {
|
||||
clip-path: inset(-15px -15px -15px 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ .fas {
|
||||
margin: 0 10px;
|
||||
> .pf-editable-toggle-svg {
|
||||
width: 98px;
|
||||
height: 68px;
|
||||
color: $gray-dark; // SVG color
|
||||
padding: 3px;
|
||||
margin: 0 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,11 +43,43 @@ $mapModuleGridRowMinHeight: 38px;
|
||||
z-index: 100; // slightly over map tabs
|
||||
}
|
||||
|
||||
// global 'layout' class (left|right) affect child grid layout for .pf-map-tab-content elements
|
||||
// global layout 'column' class (grid-2|grid-3) affect child grid layout for .pf-map-tab-content elements
|
||||
// -> default: 'grid-3'
|
||||
&.grid-3 {
|
||||
.pf-map-tab-content {
|
||||
@media screen and (min-width: $screen-lg){
|
||||
grid-template:
|
||||
"map map map area2" minmax(0, max-content)
|
||||
"area1 area1 area3 area2" minmax(0, max-content)
|
||||
"area1 area1 area3 area2" minmax(0, 1fr) /
|
||||
1fr 1fr minmax($colMinWidth, 1fr) minmax($colMinWidth, 1fr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// global layout 'orientation' class (left|right) affect child grid layout for .pf-map-tab-content elements
|
||||
// -> default: 'right'
|
||||
&.left {
|
||||
// swap grid tab element
|
||||
@media screen and (min-width: $screen-lg){
|
||||
.pf-map-tab-content {
|
||||
@media screen and (min-width: $screen-sm){
|
||||
grid-template-areas:
|
||||
"map map"
|
||||
"area1 area1"
|
||||
"area3 area2";
|
||||
}
|
||||
|
||||
@media screen and (min-width: $screen-md){
|
||||
grid-template-areas:
|
||||
"map map map"
|
||||
"area2 area1 area1"
|
||||
"area3 area1 area1";
|
||||
grid-template-columns: minmax($colMinWidth, 1fr) 1fr 1fr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.left.grid-3 {
|
||||
@media screen and (min-width: $screen-lg){ // swap grid tab element
|
||||
grid-template-areas:
|
||||
". tabs1 tabs1 tabs1"
|
||||
"wrapper wrapper wrapper wrapper";
|
||||
@@ -55,8 +87,7 @@ $mapModuleGridRowMinHeight: 38px;
|
||||
}
|
||||
|
||||
.pf-map-tab-content {
|
||||
// swap grid area columns
|
||||
@media screen and (min-width: $screen-lg){
|
||||
@media screen and (min-width: $screen-lg){ // swap grid area columns
|
||||
grid-template-areas:
|
||||
"area2 map map map"
|
||||
"area2 area1 area1 area3"
|
||||
@@ -176,14 +207,8 @@ $mapModuleGridRowMinHeight: 38px;
|
||||
1fr 1fr minmax($colMinWidth, 1fr);
|
||||
}
|
||||
|
||||
|
||||
@media screen and (min-width: $screen-lg){
|
||||
grid-template:
|
||||
"map map map area2" minmax(0, max-content)
|
||||
"area1 area1 area3 area2" minmax(0, max-content)
|
||||
"area1 area1 area3 area2" minmax(0, 1fr) /
|
||||
1fr 1fr minmax($colMinWidth, 1fr) minmax($colMinWidth, 1fr);
|
||||
}
|
||||
// $screen-lg has 3rd column and depends on .grid-3 contextual class
|
||||
// @media screen and (min-width: $screen-lg){}
|
||||
|
||||
&.active {
|
||||
display: grid; // overwrites default display: block; of .tab-content
|
||||
|
||||
14
sass/layout/_shadow.scss
Normal file
14
sass/layout/_shadow.scss
Normal file
@@ -0,0 +1,14 @@
|
||||
.pf-shadow {
|
||||
position: relative;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: -1;
|
||||
box-shadow: 0px 0px 10px 5px #000;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user