Move presets into their own panel

This commit is contained in:
MattIPv4 2020-05-05 15:49:42 +01:00
parent e7e9cbcfa2
commit 795edd2255
5 changed files with 129 additions and 62 deletions

View File

@ -82,6 +82,38 @@ $highlight: #f2c94c;
margin-top: 0; margin-top: 0;
padding: 1.5rem 0 2rem; padding: 1.5rem 0 2rem;
&.presets {
text-align: left;
.header-group,
.buttons-group {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.header-group {
h3 {
margin: 0;
}
.button {
&.is-tiny {
font-size: 20px;
}
}
}
.message,
.buttons-group {
margin: 1rem 0 0;
}
.buttons-group {
align-items: center;
}
}
.container { .container {
padding: 0 1.5rem; padding: 0 1.5rem;
} }
@ -91,28 +123,21 @@ $highlight: #f2c94c;
padding: 0 1rem; padding: 0 1rem;
} }
} }
}
.buttons-group { .navigation-buttons {
align-items: center; align-items: center;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: flex-end;
} margin: 1.5rem 1.5rem 0;
.navigation-buttons { .button {
align-items: center; margin-left: .5rem;
display: flex;
flex-direction: row;
justify-content: flex-end;
margin: 1.5rem 1.5rem 0;
.button { i + span,
margin-left: .5rem; span + i {
margin: 0 0 0 .5rem;
i + span, }
span + i {
margin: 0 0 0 .5rem;
} }
} }
} }

View File

@ -15,47 +15,60 @@ limitations under the License.
--> -->
<template> <template>
<div class="panel"> <div>
<div class="tabs"> <div class="panel presets">
<ul> <Presets :data="$props.data.presets"></Presets>
<li v-for="tab in tabs" :class="tabClass(tab.key)">
<a @click="active = tab.key">{{ tab.display }}{{ changes(tab.key) }}</a>
</li>
</ul>
</div> </div>
<component :is="tab" <div class="panel">
v-for="tab in tabs" <div class="tabs">
:key="tab.key" <ul>
:data="$props.data[tab.key]" <li v-for="tab in tabs" :class="tabClass(tab.key)">
:style="{ display: active === tab.key ? 'block' : 'none' }" <a @click="active = tab.key">{{ tab.display }}{{ changes(tab.key) }}</a>
class="container" </li>
></component> </ul>
</div>
<div class="navigation-buttons"> <component :is="tab"
<a v-if="previousTab !== false" class="button is-mini" @click="active = previousTab"> v-for="tab in tabs"
<i class="fas fa-long-arrow-alt-left"></i> <span>Back</span> :key="tab.key"
</a> :data="$props.data[tab.key]"
<a v-if="nextTab !== false" class="button is-primary is-mini" @click="active = nextTab"> :style="{ display: active === tab.key ? 'block' : 'none' }"
<span>Next</span> <i class="fas fa-long-arrow-alt-right"></i> class="container"
</a> ></component>
<div class="navigation-buttons">
<a v-if="previousTab !== false" class="button is-mini" @click="active = previousTab">
<i class="fas fa-long-arrow-alt-left"></i> <span>Back</span>
</a>
<a v-if="nextTab !== false" class="button is-primary is-mini" @click="active = nextTab">
<span>Next</span> <i class="fas fa-long-arrow-alt-right"></i>
</a>
</div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import isChanged from '../util/is_changed'; import isChanged from '../util/is_changed';
import Presets from './domain_sections/presets';
import * as Sections from './domain_sections'; import * as Sections from './domain_sections';
const tabs = Object.values(Sections); const tabs = Object.values(Sections);
const delegated = tabs.reduce((prev, tab) => { const delegated = {
prev[tab.key] = tab.delegated; presets: Presets.delegated,
return prev; ...tabs.reduce((prev, tab) => {
}, {}); prev[tab.key] = tab.delegated;
return prev;
}, {}),
};
export default { export default {
name: 'Domain', name: 'Domain',
delegated, // Data the parent will present here delegated,
components: {
Presets,
}, // Data the parent will present here
props: { props: {
data: Object, // Data delegated back to us from parent data: Object, // Data delegated back to us from parent
}, },
@ -63,6 +76,7 @@ limitations under the License.
return { return {
active: tabs[0].key, active: tabs[0].key,
tabs, tabs,
hasUserInteraction: false,
}; };
}, },
computed: { computed: {
@ -81,7 +95,6 @@ limitations under the License.
}, },
methods: { methods: {
changesCount(tab) { changesCount(tab) {
if (tab === 'presets') return 0; // Ignore changes from presets
return Object.keys(this.$props.data[tab]) return Object.keys(this.$props.data[tab])
.filter(key => isChanged(this.$props.data[tab][key], tab, key)).length; .filter(key => isChanged(this.$props.data[tab][key], tab, key)).length;
}, },

View File

@ -1,4 +1,3 @@
export { default as Presets } from './presets';
export { default as Server } from './server'; export { default as Server } from './server';
export { default as HTTPS } from './https'; export { default as HTTPS } from './https';
export { default as PHP } from './php'; export { default as PHP } from './php';

View File

@ -1,13 +1,34 @@
<template> <template>
<div> <div class="container">
<div class="buttons-group"> <div class="header-group">
<a v-for="(preset, key) in $props.data" <h3>Presets</h3>
:class="`button${preset.computed ? ' is-primary' : ''}`" <template v-if="$parent.$data.hasUserInteraction">
@click="setPreset(key)" <a v-if="expanded" class="button is-tiny" @click="expanded = false">
> <i class="fas fa-angle-up"></i>
{{ preset.display }} </a>
</a> <a v-else class="button is-tiny" @click="expanded = true">
<i class="fas fa-angle-down"></i>
</a>
</template>
</div> </div>
<template v-if="!$parent.$data.hasUserInteraction || expanded">
<div v-if="$parent.$data.hasUserInteraction" class="message is-warning">
<div class="message-body">
It looks like you've customised the configuration for this domain.
Choosing a new preset may reset or change some of the settings that you've customised.
</div>
</div>
<div class="buttons-group">
<a v-for="(preset, key) in $props.data"
:class="`button${preset.computed ? ' is-primary' : ''}`"
@click="setPreset(key)"
>
{{ preset.display }}
</a>
</div>
</template>
</div> </div>
</template> </template>
@ -114,19 +135,20 @@
}; };
export default { export default {
name: 'DomainPresets', // Component name name: 'DomainPresets', // Component name
display: 'Presets', // Display name for tab display: 'Presets', // Display name for tab
key: 'presets', // Key for data in parent key: 'presets', // Key for data in parent
delegated: delegatedFromDefaults(defaults), // Data the parent will present here delegated: delegatedFromDefaults(defaults), // Data the parent will present here
props: { props: {
data: Object, // Data delegated back to us from parent data: Object, // Data delegated back to us from parent
}, },
data () { data () {
return { return {
i18n, i18n,
expanded: false,
}; };
}, },
computed: computedFromDefaults(defaults), // Getters & setters for the delegated data computed: computedFromDefaults(defaults, 'presets', false), // Getters & setters for the delegated data
watch: { watch: {
// When any data changes, check if it still matches a preset // When any data changes, check if it still matches a preset
'$parent.$props.data': { '$parent.$props.data': {

View File

@ -1,12 +1,20 @@
import isChanged from './is_changed'; import isChanged from './is_changed';
export default (defaults, cat) => { export default (defaults, cat, isInteraction = true) => {
return Object.keys(defaults).reduce((prev, key) => { return Object.keys(defaults).reduce((prev, key) => {
prev[key] = { prev[key] = {
get() { get() {
return this.$props.data[key].value; return this.$props.data[key].value;
}, },
set (value) { set (value) {
// Save user interaction if value changed
if (isInteraction
&& this.$parent
&& 'hasUserInteraction' in this.$parent.$data
&& !this.$parent.$data.hasUserInteraction
&& this.$props.data[key].value !== value)
this.$parent.$data.hasUserInteraction = true;
this.$props.data[key].value = value; this.$props.data[key].value = value;
this.$props.data[key].computed = value; this.$props.data[key].computed = value;
}, },