Merge pull request #134 from samuelthomas2774/add-settings-schemes

Add settings schemes
This commit is contained in:
Alexei Stukov 2018-02-14 21:41:24 +02:00 committed by GitHub
commit b51e675291
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 246 additions and 54 deletions

View File

@ -173,6 +173,7 @@ export default class {
const configs = {
defaultConfig: readConfig.defaultConfig,
schemes: readConfig.configSchemes,
userConfig
}

View File

@ -51,6 +51,7 @@ export default class Plugin {
get main() { return this.__pluginInternals.main }
get defaultConfig() { return this.configs.defaultConfig }
get userConfig() { return this.configs.userConfig }
get configSchemes() { return this.configs.schemes }
get id() { return this.info.id || this.name.replace(/[^a-zA-Z0-9-]/g, '-').replace(/--/g, '-') }
get name() { return this.info.name }
get authors() { return this.info.authors }

View File

@ -51,6 +51,7 @@ export default class Theme {
get main() { return this.__themeInternals.main }
get defaultConfig() { return this.configs.defaultConfig }
get userConfig() { return this.configs.userConfig }
get configSchemes() { return this.configs.schemes }
get id() { return this.info.id || this.name.toLowerCase().replace(/[^a-zA-Z0-9-]/g, '-').replace(/\s+/g, '-') }
get name() { return this.info.name }
get authors() { return this.info.authors }

View File

@ -3,3 +3,4 @@
@import './plugins.scss';
@import './card.scss';
@import './tooltips.scss';
@import './settings-schemes.scss';

View File

@ -0,0 +1,56 @@
.bd-settings-schemes {
margin-bottom: 15px;
border-bottom: 1px solid rgba(114, 118, 126, 0.3);
.bd-settings-schemes-container {
margin-right: -15px;
}
}
.bd-settings-scheme {
display: inline-block;
width: calc(33.3% - 15px);
margin: 0 15px 15px 0;
cursor: pointer;
vertical-align: top;
.bd-settings-modal & {
width: calc(50% - 15px);
.bd-settings-scheme-icon {
height: 120px;
}
}
.bd-settings-scheme-icon {
box-sizing: border-box;
width: 100%;
height: 120px;
border: 2px solid $coldimwhite;
border-radius: 3px;
transition: border-color 0.2s ease;
margin-bottom: 15px;
background: center / cover no-repeat #2f3136;
}
.bd-settings-scheme-name {
font-weight: 500;
color: #f6f6f7;
}
.bd-settings-scheme-hint {
flex: 1 1 auto;
color: #72767d;
font-size: 14px;
font-weight: 500;
margin-top: 10px;
}
&.bd-active {
cursor: default;
.bd-settings-scheme-icon {
border-color: $colbdblue;
}
}
}

View File

@ -33,7 +33,7 @@
<ContentColumn slot="content">
<div v-for="set in settings" v-if="activeContent(set.id) || animatingContent(set.id)" :class="{active: activeContent(set.id), animating: animatingContent(set.id)}">
<SettingsWrapper :headertext="set.headertext">
<SettingsPanel :settings="set.settings" :change="(c, s, v) => changeSetting(set.id, c, s, v)" />
<SettingsPanel :settings="set.settings" :schemes="set.schemes" :change="(c, s, v) => changeSetting(set.id, c, s, v)" />
</SettingsWrapper>
</div>
<div v-if="activeContent('css') || animatingContent('css')" :class="{active: activeContent('css'), animating: animatingContent('css')}">

View File

@ -9,39 +9,93 @@
*/
<template>
<div>
<template v-for="category in settings">
<div v-if="category.category === 'default' || !category.type">
<Setting v-for="setting in category.settings" :key="setting.id" :setting="setting" :change="v => settingChange(category, setting, v)" />
<div class="bd-settings-panel">
<div class="bd-settings-schemes" v-if="schemes && schemes.length">
<div class="bd-settings-schemes-container">
<template v-for="scheme in schemes">
<div class="bd-settings-scheme" :class="{'bd-active': checkSchemeActive(scheme)}" @click="() => setActiveScheme(scheme)">
<div class="bd-settings-scheme-icon" :style="{'background-image': `url(&quot;${scheme.icon_url}&quot;)`}"></div>
<div class="bd-settings-scheme-name" v-if="scheme.name">{{ scheme.name }}</div>
<div class="bd-settings-scheme-hint" v-if="scheme.hint">{{ scheme.hint }}</div>
</div>
</template>
</div>
<div v-else-if="category.type === 'static'">
<div class="bd-form-header">
<span class="bd-form-header-text">{{ category.category_name }}</span>
</div>
<div class="bd-settings-categories">
<template v-for="category in settings">
<div class="bd-settings-category">
<div v-if="category.category === 'default' || !category.type">
<Setting v-for="setting in category.settings" :key="setting.id" :setting="setting" :change="v => settingChange(category, setting, v)" />
</div>
<div class="bd-settings-static" v-else-if="category.type === 'static'">
<div class="bd-form-header">
<span class="bd-form-header-text">{{ category.category_name }}</span>
</div>
<Setting v-for="setting in category.settings" :key="setting.id" :setting="setting" :change="v => settingChange(category, setting, v)" />
</div>
<Drawer v-else-if="category.type === 'drawer'" :label="category.category_name">
<Setting v-for="setting in category.settings" :key="setting.id" :setting="setting" :change="v => settingChange(category, setting, v)" />
</Drawer>
<div v-else>
<Setting v-for="setting in category.settings" :key="setting.id" :setting="setting" :change="v => settingChange(category, setting, v)" />
</div>
</div>
<Setting v-for="setting in category.settings" :key="setting.id" :setting="setting" :change="v => settingChange(category, setting, v)" />
</div>
<Drawer v-else-if="category.type === 'drawer'" :label="category.category_name">
<Setting v-for="setting in category.settings" :key="setting.id" :setting="setting" :change="v => settingChange(category, setting, v)" />
</Drawer>
<div v-else>
<Setting v-for="setting in category.settings" :key="setting.id" :setting="setting" :change="v => settingChange(category, setting, v)" />
</div>
</template>
</template>
</div>
</div>
</template>
<script>
// Imports
import { Utils } from 'common';
import Setting from './setting/Setting.vue';
import Drawer from '../common/Drawer.vue';
export default {
props: ['settings', 'change'],
props: ['settings', 'schemes', 'change'],
components: {
Setting,
Drawer
},
data() {
return {
active_scheme: 'scheme-1'
};
},
methods: {
checkSchemeActive(scheme) {
for (let schemeCategory of scheme.settings) {
const category = this.settings.find(c => c.category === schemeCategory.category);
if (!category) return false;
for (let schemeSetting of schemeCategory.settings) {
const setting = category.settings.find(s => s.id === schemeSetting.id);
if (!setting || !Utils.compare(setting.value, schemeSetting.value)) return false;
}
}
return true;
},
setActiveScheme(scheme) {
for (let schemeCategory of scheme.settings) {
const category = this.settings.find(c => c.category === schemeCategory.category);
if (!category) {
console.err(`Category ${schemeCategory.category} does not exist`);
continue;
}
for (let schemeSetting of schemeCategory.settings) {
const setting = category.settings.find(s => s.id === schemeSetting.id);
if (!setting) {
console.err(`Setting ${schemeCategory.category}/${schemeSetting.id} does not exist`);
continue;
}
this.change(category.category, setting.id, schemeSetting.value);
}
}
},
settingChange(category, setting, value) {
if (setting.disabled) return;
this.change(category.category, setting.id, value);

View File

@ -10,8 +10,8 @@
<template>
<div class="bd-settings-modal" :class="{'bd-edited': changed}">
<Modal :headerText="modal.headertext" :close="attemptToClose" :class="{'bd-modal-out': modal.closing}">
<SettingsPanel :settings="configCache" :change="settingChange" slot="body" class="bd-settings-modal-body" />
<Modal :headerText="modal.headertext" :close="modal.close" :class="{'bd-modal-out': modal.closing}">
<SettingsPanel :settings="configCache" :schemes="modal.schemes" :change="settingChange" slot="body" class="bd-settings-modal-body" />
<div slot="footer" class="bd-footer-alert" :class="{'bd-active': changed, 'bd-warn': warnclose}">
<div class="bd-footer-alert-text">Unsaved changes</div>
<div class="bd-button bd-reset-button bd-tp" :class="{'bd-disabled': saving}" @click="resetSettings">Reset</div>
@ -91,19 +91,15 @@
this.configCache = JSON.parse(JSON.stringify(this.modal.settings));
this.changed = false;
this.$forceUpdate();
},
attemptToClose(e) {
if (!this.changed) {
this.closing = true;
setTimeout(() => {
this.modal.close();
}, 200);
return;
}
},
created() {
this.modal.beforeClose = force => {
if (this.changed && !force) {
this.warnclose = true;
setTimeout(() => this.warnclose = false, 400);
throw {message: 'Settings have been changed'};
}
this.warnclose = true;
setTimeout(() => {
this.warnclose = false;
}, 400);
}
},
beforeMount() {

View File

@ -24,15 +24,27 @@ export default class {
created() { modal.vue = this; }
};
modal.closing = false;
modal.close = () => this.close(modal);
modal.close = force => this.close(modal, force);
this.stack.push(modal);
Events.emit('bd-refresh-modals');
return modal;
}
static close(modal) {
return new Promise((resolve, reject) => {
static close(modal, force) {
return new Promise(async (resolve, reject) => {
if (modal.beforeClose) {
try {
let beforeCloseResult = modal.beforeClose(force);
if (beforeCloseResult instanceof Promise)
beforeCloseResult = await beforeCloseResult;
if (beforeCloseResult && !force) return reject(beforeCloseResult);
} catch (err) {
if (!force) return reject(err);
}
}
modal.closing = true;
setTimeout(() => {
this._stack = this.stack.filter(m => m !== modal);
@ -62,7 +74,8 @@ export default class {
static showContentManagerErrors() {
// Get any errors from PluginManager and ThemeManager
this.error({
const errors = ([]).concat(PluginManager.errors).concat(ThemeManager.errors);
if (errors.length) return this.error({
header:
(PluginManager.errors.length && ThemeManager.errors.length ? '' :
(PluginManager.errors.length ? PluginManager.moduleName : ThemeManager.moduleName) + ' - ') +
@ -73,13 +86,13 @@ export default class {
module: (PluginManager.errors.length && ThemeManager.errors.length ? 'Content Manager' :
(PluginManager.errors.length ? PluginManager.moduleName : ThemeManager.moduleName)),
type: 'err',
content: ([]).concat(PluginManager.errors).concat(ThemeManager.errors)
content: errors
});
}
static settings(headertext, settings, settingsUpdated, settingUpdated, saveSettings) {
static settings(headertext, settings, schemes, settingsUpdated, settingUpdated, saveSettings) {
return this.add({
headertext, settings,
headertext, settings, schemes,
saveSettings: saveSettings ? saveSettings : newSettings => {
const updatedSettings = [];
@ -105,11 +118,11 @@ export default class {
static internalSettings(set_id) {
const set = Settings.getSet(set_id);
if (!set) return;
return this.settings(set.headertext, set.settings, null, null, newSettings => Settings.mergeSettings(set.id, newSettings));
return this.settings(set.headertext, set.settings, set.schemes, null, null, newSettings => Settings.mergeSettings(set.id, newSettings));
}
static contentSettings(content) {
return this.settings(content.name + ' Settings', content.config, null, null, content.saveSettings.bind(content));
return this.settings(content.name + ' Settings', content.config, content.configSchemes, null, null, content.saveSettings.bind(content));
}
static get stack() {

View File

@ -8,9 +8,9 @@
"icon": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iQ2FscXVlXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMjAwMCAyMDAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAyMDAwIDIwMDAiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxnPjxwYXRoIGZpbGw9IiMzRTgyRTUiIGQ9Ik0xNDAyLjIsNjMxLjdjLTkuNy0zNTMuNC0yODYuMi00OTYtNjQyLjYtNDk2SDY4LjR2NzE0LjFsNDQyLDM5OFY0OTAuN2gyNTdjMjc0LjUsMCwyNzQuNSwzNDQuOSwwLDM0NC45SDU5Ny42djMyOS41aDE2OS44YzI3NC41LDAsMjc0LjUsMzQ0LjgsMCwzNDQuOGgtNjk5djM1NC45aDY5MS4yYzM1Ni4zLDAsNjMyLjgtMTQyLjYsNjQyLjYtNDk2YzAtMTYyLjYtNDQuNS0yODQuMS0xMjIuOS0zNjguNkMxMzU3LjcsOTE1LjgsMTQwMi4yLDc5NC4zLDE0MDIuMiw2MzEuN3oiLz48cGF0aCBmaWxsPSIjRkZGRkZGIiBkPSJNMTI2Mi41LDEzNS4yTDEyNjIuNSwxMzUuMmwtNzYuOCwwYzI2LjYsMTMuMyw1MS43LDI4LjEsNzUsNDQuM2M3MC43LDQ5LjEsMTI2LjEsMTExLjUsMTY0LjYsMTg1LjNjMzkuOSw3Ni42LDYxLjUsMTY1LjYsNjQuMywyNjQuNmwwLDEuMnYxLjJjMCwxNDEuMSwwLDU5Ni4xLDAsNzM3LjF2MS4ybDAsMS4yYy0yLjcsOTktMjQuMywxODgtNjQuMywyNjQuNmMtMzguNSw3My44LTkzLjgsMTM2LjItMTY0LjYsMTg1LjNjLTIyLjYsMTUuNy00Ni45LDMwLjEtNzIuNiw0My4xaDcyLjVjMzQ2LjIsMS45LDY3MS0xNzEuMiw2NzEtNTY3LjlWNzE2LjdDMTkzMy41LDMxMi4yLDE2MDguNywxMzUuMiwxMjYyLjUsMTM1LjJ6Ii8+PC9nPjwvc3ZnPg=="
},
"main": "index.js",
"type": "plugin",
"type": "plugin",
"dependencies": {
"Nonexistent Module": "1.0"
},
"Nonexistent Module": "1.0"
},
"defaultConfig": []
}

View File

@ -6,6 +6,6 @@
"description": "Example Plugin 2 Description"
},
"main": "index.js",
"type": "plugin",
"type": "plugin",
"defaultConfig": []
}

View File

@ -16,4 +16,4 @@ module.exports = (Plugin, Api, Vendor) =>
}
}
}
};

View File

@ -48,17 +48,17 @@
"options": [
{
"id": "opt1",
"text": "small",
"text": "small",
"value": "8px"
},
{
"id": "opt2",
"text": "medium",
"text": "medium",
"value": "12px"
},
{
"id": "opt3",
"text": "high",
"text": "high",
"value": "16px"
},
{
@ -78,27 +78,27 @@
{
"id": "opt1",
"text": "red",
"value": "red"
"value": "red"
},
{
"id": "opt2",
"text": "green",
"value": "green"
"value": "green"
},
{
"id": "opt3",
"text": "blue",
"value": "blue"
"value": "blue"
},
{
"id": "opt4",
"text": "orange",
"value": "orange"
"value": "orange"
},
{
"id": "opt5",
"text": "white",
"value": "white"
"value": "white"
}
]
},
@ -125,5 +125,74 @@
}
]
}
],
"configSchemes": [
{
"id": "scheme-1",
"name": "Test scheme",
"hint": "Sets the span border opacity to 1%.",
"icon_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/0c/Cow_female_black_white.jpg/220px-Cow_female_black_white.jpg",
"settings": [
{
"category": "default",
"settings": [
{
"id": "spanOpacity",
"value": 1
}
]
}
]
},
{
"id": "scheme-2",
"name": "Another test scheme",
"hint": "Sets the primary colour to red and the span border opacity to 99%.",
"icon_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/0c/Cow_female_black_white.jpg/220px-Cow_female_black_white.jpg",
"settings": [
{
"category": "default",
"settings": [
{
"id": "divBg",
"type": "text",
"value": "red",
"text": "Primary colour",
"hint": "A colour setting type would be nice here",
"scss_raw": true
},
{
"id": "spanOpacity",
"value": 99
}
]
}
]
},
{
"id": "scheme-3",
"name": "Final test scheme",
"hint": "Sets the primary colour to transparent and the span border opacity to 50%.",
"icon_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/0c/Cow_female_black_white.jpg/220px-Cow_female_black_white.jpg",
"settings": [
{
"category": "default",
"settings": [
{
"id": "divBg",
"type": "text",
"value": "transparent",
"text": "Primary colour",
"hint": "A colour setting type would be nice here",
"scss_raw": true
},
{
"id": "spanOpacity",
"value": 50
}
]
}
]
}
]
}