Adds ability to edit pageInfo through the UI

This commit is contained in:
Alicia Sykes 2021-10-23 13:07:30 +01:00
parent a48024e59c
commit 8147f40e9c
10 changed files with 214 additions and 9 deletions

View File

@ -193,6 +193,7 @@
"edit-mode-name": "Edit Mode",
"edit-mode-subtitle": "You are in Edit Mode",
"edit-mode-description": "This means you can make modifications to your config, and preview the results, but until you save, none of your changes will be preserved.",
"save-stage-btn": "Save",
"export": {
"export-title": "Export Config",
"copy-clipboard-btn": "Copy to Clipboard",

View File

@ -1,8 +1,11 @@
<template>
<button
@click="click ? click() : () => null"
:disabled="disabled"
:class="disallow ? 'disallowed': ''"
:type="type || 'button'"
:disabled="disabled"
v-tooltip="hoverText"
:title="tooltip"
>
<slot></slot>
<slot name="text"></slot>
@ -15,10 +18,21 @@
export default {
name: 'Button',
props: {
text: String,
click: Function,
disabled: Boolean,
disallow: Boolean,
text: String, // The text to be displayed in the button
click: Function, // Function to call when clicked
disabled: Boolean, // If true, button cannot be clicked
disallow: Boolean, // Show not-allowed cursor when true
type: String, // The html button type attribute
tooltip: String, // Text to be displayed on hover
},
computed: {
/* If tooltip prop specified, then return config for v-tooltip */
hoverText() {
const content = this.tooltip;
const trigger = 'hover focus';
const delay = { show: 350, hide: 100 };
return (content) ? { content, trigger, delay } : undefined;
},
},
};
</script>

View File

@ -12,8 +12,11 @@
<div class="edit-banner-section empty-space"></div>
<!-- Save Buttons -->
<div class="edit-banner-section save-buttons-container">
<p class="section-sub-title">Config Saving Options</p>
<p class="section-sub-title">
{{ $t('interactive-editor.config-save-methods-subheading') }}
</p>
<Button
:click="openExportConfigMenu"
v-tooltip="tooltip($t('interactive-editor.export-config-tooltip'))"
>
{{ $t('interactive-editor.export-config-btn') }}
@ -41,8 +44,11 @@
</div>
<!-- Open Modal Buttons -->
<div class="edit-banner-section edit-site-config-buttons">
<p class="section-sub-title">Edit Site Data</p>
<p class="section-sub-title">
{{ $t('interactive-editor.edit-site-data-subheading') }}
</p>
<Button
:click="openEditPageInfo"
v-tooltip="tooltip($t('interactive-editor.edit-page-info-tooltip'))"
>
{{ $t('interactive-editor.edit-page-info-btn') }}
@ -55,12 +61,16 @@
<AppConfigIcon />
</Button>
</div>
<!-- Modals for editing appConfig + pageInfo -->
<EditPageInfo />
</div>
</template>
<script>
import Button from '@/components/FormElements/Button';
import StoreKeys from '@/utils/StoreMutations';
import { modalNames } from '@/utils/defaults';
import EditPageInfo from '@/components/InteractiveEditor/EditPageInfo';
import SaveLocallyIcon from '@/assets/interface-icons/interactive-editor-save-locally.svg';
import SaveToDiskIcon from '@/assets/interface-icons/interactive-editor-save-disk.svg';
@ -73,6 +83,7 @@ export default {
name: 'EditModeSaveMenu',
components: {
Button,
EditPageInfo,
SaveLocallyIcon,
SaveToDiskIcon,
ExportIcon,
@ -88,6 +99,14 @@ export default {
tooltip(content) {
return { content, trigger: 'hover focus', delay: 250 };
},
openExportConfigMenu() {
this.$modal.show(modalNames.EXPORT_CONFIG_MENU);
this.$store.commit(StoreKeys.SET_MODAL_OPEN, true);
},
openEditPageInfo() {
this.$modal.show(modalNames.EDIT_PAGE_INFO);
this.$store.commit(StoreKeys.SET_MODAL_OPEN, true);
},
},
};
</script>
@ -159,5 +178,16 @@ div.edit-mode-bottom-banner {
flex-direction: column;
}
}
/* Set colors for buttons */
.edit-banner-section button {
color: var(--interactive-editor-color);
border-color: var(--interactive-editor-color);
background: var(--interactive-editor-background);
&:hover {
color: var(--interactive-editor-background);
border-color: var(--interactive-editor-color);
background: var(--interactive-editor-color);
}
}
}
</style>

View File

@ -0,0 +1,96 @@
<template>
<modal
:name="modalName"
:resizable="true"
width="50%"
height="80%"
classes="dashy-modal edit-page-info"
@closed="modalClosed"
>
<div class="edit-page-info-inner">
<h3>{{ $t('interactive-editor.edit-page-info-btn') }}</h3>
<FormSchema
:schema="schema"
v-model="formData"
@submit.prevent="saveToState"
class="page-info-form"
name="pageInfoForm"
>
<Button type="submit">
{{ $t('interactive-editor.save-stage-btn') }}
<SaveIcon />
</button>
</FormSchema>
</div>
</modal>
</template>
<script>
import FormSchema from '@formschema/native';
import DashySchema from '@/utils/ConfigSchema';
import StoreKeys from '@/utils/StoreMutations';
import { modalNames } from '@/utils/defaults';
import Button from '@/components/FormElements/Button';
import SaveIcon from '@/assets/interface-icons/save-config.svg';
export default {
name: 'EditPageInfo',
data() {
return {
formData: {},
schema: DashySchema.properties.pageInfo,
modalName: modalNames.EDIT_PAGE_INFO,
};
},
props: {},
components: {
FormSchema,
Button,
SaveIcon,
},
mounted() {
this.formData = this.pageInfo;
},
computed: {
pageInfo() {
return this.$store.getters.pageInfo;
},
},
methods: {
/* When form submitteed, update VueX store with new pageInfo, and close modal */
saveToState() {
this.$store.commit(StoreKeys.UPDATE_PAGE_INFO, this.formData);
this.$modal.hide(this.modalName);
this.$store.commit(StoreKeys.SET_MODAL_OPEN, false);
this.$store.commit(StoreKeys.SET_EDIT_MODE, true);
},
/* Called when modal manually closed, updates state to allow searching again */
modalClosed() {
this.$store.commit(StoreKeys.SET_MODAL_OPEN, false);
},
},
};
</script>
<style lang="scss">
@import '@/styles/style-helpers.scss';
@import '@/styles/media-queries.scss';
.edit-page-info-inner {
padding: 1rem;
background: var(--interactive-editor-background);
color: var(--interactive-editor-color);
height: 100%;
overflow-y: auto;
@extend .scroll-bar;
h3 {
font-size: 1.4rem;
margin: 0.5rem;
}
.page-info-form {
@extend .schema-form;
margin-bottom: 2.5rem;
}
}
</style>

View File

@ -15,6 +15,7 @@ const {
SET_LANGUAGE,
UPDATE_ITEM,
SET_EDIT_MODE,
UPDATE_PAGE_INFO,
} = Keys;
const store = new Vuex.Store({
@ -77,6 +78,11 @@ const store = new Vuex.Store({
});
state.config = newConfig;
},
[UPDATE_PAGE_INFO](state, newPageInfo) {
const newConfig = state.config;
newConfig.pageInfo = newPageInfo;
state.config = newConfig;
},
},
actions: {
/* Called when app first loaded. Reads config and sets state */

View File

@ -637,7 +637,7 @@ html[data-theme='material-dark'] {
--config-settings-background: #131a1f;
--config-settings-color: #41e2ed;
--interactive-editor-background: #131a1f;
--interactive-editor-background: #242a2f;
--interactive-editor-background-darker: #131a1f;
--interactive-editor-color: #41e2ed;

View File

@ -1,3 +1,4 @@
@import '@/styles/media-queries.scss';
/* Fancy scrollbar */
.scroll-bar {
@ -58,6 +59,52 @@
}
}
/* Form elements in the auto-schema form */
.schema-form {
fieldset {
border: none;
display: flex;
flex-direction: column;
> div {
border-bottom: 1px dashed var(--primary);
margin: 0.5rem 0;
label {
font-size: 1rem;
text-decoration: underline;
}
}
div[data-fs-wrapper] {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
flex-direction: row-reverse;
justify-content: space-between;
padding: 0.5rem 0;
@include tablet-down {
flex-direction: column-reverse;
}
span {
font-style: italic;
margin-right: 0.5rem;
}
input {
min-width: 15rem;
padding: 0.5rem 0.75rem;
margin: 0.5rem auto;
font-size: 1rem;
box-sizing: border-box;
color: var(--primary);
background: var(--background);;
border: 1px solid var(--primary);
border-radius: var(--curve-factor);
&:focus {
box-shadow: 1px 1px 6px var(--config-settings-color);
outline: none;
}
}
}
}
}
/* Single-style helpers */
.bold { font-weight: bold; }

View File

@ -9,16 +9,19 @@
"type": "object",
"properties": {
"title": {
"title": "Title",
"type": "string",
"description": "Title and heading for the app"
},
"description": {
"title": "Description",
"type": "string",
"description": "Sub-title, displayed in header"
},
"navLinks": {
"type": "array",
"maxItems": 6,
"title": "Navigation Links",
"description": "Quick access links, displayed in header",
"items": {
"type": "object",
@ -38,9 +41,12 @@
}
},
"footerText": {
"title": "Footer Text",
"description": "Content to display within the global page footer",
"type": "string"
},
"logo": {
"title": "App Logo",
"type": "string",
"description": "Path to an optional image asset, to be displayed in the header",
"pattern": "^(http|/)",

View File

@ -4,8 +4,9 @@ const KEY_NAMES = [
'UPDATE_CONFIG',
'SET_MODAL_OPEN',
'SET_LANGUAGE',
'UPDATE_ITEM',
'SET_EDIT_MODE',
'UPDATE_ITEM',
'UPDATE_PAGE_INFO',
];
// Convert array of key names into an object, and export

View File

@ -123,6 +123,10 @@ module.exports = {
ABOUT_APP: 'ABOUT_APP',
LANG_SWITCHER: 'LANG_SWITCHER',
EDIT_ITEM: 'EDIT_ITEM',
EDIT_SECTION: 'EDIT_SECTION',
EDIT_PAGE_INFO: 'EDIT_PAGE_INFO',
EDIT_APP_CONFIG: 'EDIT_APP_CONFIG',
EXPORT_CONFIG_MENU: 'EXPORT_CONFIG_MENU',
},
/* Key names for the top-level objects in conf.yml */
topLevelConfKeys: {