Implements frontend work for Rebuild App functionality

This commit is contained in:
Alicia Sykes 2021-06-20 16:51:23 +01:00
parent b0d5b63703
commit e75b0c780f
6 changed files with 222 additions and 3 deletions

View File

@ -0,0 +1 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="hammer" class="svg-inline--fa fa-hammer fa-w-18" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M571.31 193.94l-22.63-22.63c-6.25-6.25-16.38-6.25-22.63 0l-11.31 11.31-28.9-28.9c5.63-21.31.36-44.9-16.35-61.61l-45.25-45.25c-62.48-62.48-163.79-62.48-226.28 0l90.51 45.25v18.75c0 16.97 6.74 33.25 18.75 45.25l49.14 49.14c16.71 16.71 40.3 21.98 61.61 16.35l28.9 28.9-11.31 11.31c-6.25 6.25-6.25 16.38 0 22.63l22.63 22.63c6.25 6.25 16.38 6.25 22.63 0l90.51-90.51c6.23-6.24 6.23-16.37-.02-22.62zm-286.72-15.2c-3.7-3.7-6.84-7.79-9.85-11.95L19.64 404.96c-25.57 23.88-26.26 64.19-1.53 88.93s65.05 24.05 88.93-1.53l238.13-255.07c-3.96-2.91-7.9-5.87-11.44-9.41l-49.14-49.14z"></path></svg>

After

Width:  |  Height:  |  Size: 798 B

View File

@ -0,0 +1 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="sync" class="svg-inline--fa fa-sync fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M440.65 12.57l4 82.77A247.16 247.16 0 0 0 255.83 8C134.73 8 33.91 94.92 12.29 209.82A12 12 0 0 0 24.09 224h49.05a12 12 0 0 0 11.67-9.26 175.91 175.91 0 0 1 317-56.94l-101.46-4.86a12 12 0 0 0-12.57 12v47.41a12 12 0 0 0 12 12H500a12 12 0 0 0 12-12V12a12 12 0 0 0-12-12h-47.37a12 12 0 0 0-11.98 12.57zM255.83 432a175.61 175.61 0 0 1-146-77.8l101.8 4.87a12 12 0 0 0 12.57-12v-47.4a12 12 0 0 0-12-12H12a12 12 0 0 0-12 12V500a12 12 0 0 0 12 12h47.35a12 12 0 0 0 12-12.6l-4.15-82.57A247.17 247.17 0 0 0 255.83 504c121.11 0 221.93-86.92 243.55-201.82a12 12 0 0 0-11.8-14.18h-49.05a12 12 0 0 0-11.67 9.26A175.86 175.86 0 0 1 255.83 432z"></path></svg>

After

Width:  |  Height:  |  Size: 855 B

View File

@ -0,0 +1,33 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="100px" height="100px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
<defs>
<clipPath id="ldio-owbkoh4un5-cp">
<rect x="20" y="0" width="60" height="100"></rect>
</clipPath>
</defs>
<path
fill="none"
stroke="var(--primary, #00af87)"
stroke-width="6"
stroke-linecap="round"
stroke-linejoin="round"
stroke-miterlimit="10"
clip-path="url(#ldio-owbkoh4un5-cp)"
d="M90,76.7V28.3c0-2.7-2.2-5-5-5h-3.4c-2.7,0-5,2.2-5,5v43.4c0,2.7-2.2,5-5,5h-3.4c-2.7,0-5-2.2-5-5V28.3c0-2.7-2.2-5-5-5H55 c-2.7,0-5,2.2-5,5v43.4c0,2.7-2.2,5-5,5h-3.4c-2.7,0-5-2.2-5-5V28.3c0-2.7-2.2-5-5-5h-3.4c-2.7,0-5,2.2-5,5v43.4c0,2.7-2.2,5-5,5H15 c-2.7,0-5-2.2-5-5V23.3"
>
<animateTransform
attributeName="transform"
type="translate"
repeatCount="indefinite"
dur="1.4925373134328357s"
values="-20 0;7 0"
keyTimes="0;1"
></animateTransform>
<animate
attributeName="stroke-dasharray"
repeatCount="indefinite"
dur="1.4925373134328357s"
values="0 72 125 232;0 197 125 233"
keyTimes="0;1"></animate>
</path>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -11,7 +11,7 @@
</a> </a>
<button class="config-button center" @click="goToEdit()"> <button class="config-button center" @click="goToEdit()">
<EditIcon class="button-icon"/> <EditIcon class="button-icon"/>
Edit Sections Edit Config
</button> </button>
<button class="config-button center" @click="goToMetaEdit()"> <button class="config-button center" @click="goToMetaEdit()">
<MetaDataIcon class="button-icon"/> <MetaDataIcon class="button-icon"/>
@ -25,6 +25,10 @@
<CloudIcon class="button-icon"/> <CloudIcon class="button-icon"/>
{{backupId ? 'Edit Cloud Sync' : 'Enable Cloud Sync'}} {{backupId ? 'Edit Cloud Sync' : 'Enable Cloud Sync'}}
</button> </button>
<button class="config-button center" @click="openRebuildAppModal()">
<RebuildIcon class="button-icon"/>
Rebuild Application
</button>
<button class="config-button center" @click="resetLocalSettings()"> <button class="config-button center" @click="resetLocalSettings()">
<DeleteIcon class="button-icon"/> <DeleteIcon class="button-icon"/>
Reset Local Settings Reset Local Settings
@ -40,8 +44,10 @@
</span> </span>
</div> </div>
</div> </div>
<!-- Rebuild App Modal -->
<RebuildApp />
</TabItem> </TabItem>
<TabItem name="Backup Config" class="code-container"> <TabItem name="View Config" class="code-container">
<pre id="conf-yaml">{{this.jsonParser(this.config)}}</pre> <pre id="conf-yaml">{{this.jsonParser(this.config)}}</pre>
<div class="yaml-action-buttons"> <div class="yaml-action-buttons">
<h2>Actions</h2> <h2>Actions</h2>
@ -50,7 +56,7 @@
<a class="yaml-button reset" @click="resetLocalSettings()">Reset Config</a> <a class="yaml-button reset" @click="resetLocalSettings()">Reset Config</a>
</div> </div>
</TabItem> </TabItem>
<TabItem name="Edit Sections"> <TabItem name="Edit Config">
<JsonEditor :config="config" /> <JsonEditor :config="config" />
</TabItem> </TabItem>
<TabItem name="Edit Site Meta"> <TabItem name="Edit Site Meta">
@ -73,12 +79,15 @@ import { localStorageKeys, modalNames } from '@/utils/defaults';
import EditSiteMeta from '@/components/Configuration/EditSiteMeta'; import EditSiteMeta from '@/components/Configuration/EditSiteMeta';
import JsonEditor from '@/components/Configuration/JsonEditor'; import JsonEditor from '@/components/Configuration/JsonEditor';
import CustomCssEditor from '@/components/Configuration/CustomCss'; import CustomCssEditor from '@/components/Configuration/CustomCss';
import RebuildApp from '@/components/Configuration/RebuildApp';
import DownloadIcon from '@/assets/interface-icons/config-download-file.svg'; import DownloadIcon from '@/assets/interface-icons/config-download-file.svg';
import DeleteIcon from '@/assets/interface-icons/config-delete-local.svg'; import DeleteIcon from '@/assets/interface-icons/config-delete-local.svg';
import EditIcon from '@/assets/interface-icons/config-edit-json.svg'; import EditIcon from '@/assets/interface-icons/config-edit-json.svg';
import MetaDataIcon from '@/assets/interface-icons/config-meta-data.svg'; import MetaDataIcon from '@/assets/interface-icons/config-meta-data.svg';
import CustomCssIcon from '@/assets/interface-icons/config-custom-css.svg'; import CustomCssIcon from '@/assets/interface-icons/config-custom-css.svg';
import CloudIcon from '@/assets/interface-icons/cloud-backup-restore.svg'; import CloudIcon from '@/assets/interface-icons/cloud-backup-restore.svg';
import RebuildIcon from '@/assets/interface-icons/application-rebuild.svg';
export default { export default {
name: 'ConfigContainer', name: 'ConfigContainer',
@ -100,12 +109,14 @@ export default {
EditSiteMeta, EditSiteMeta,
JsonEditor, JsonEditor,
CustomCssEditor, CustomCssEditor,
RebuildApp,
DownloadIcon, DownloadIcon,
DeleteIcon, DeleteIcon,
EditIcon, EditIcon,
CloudIcon, CloudIcon,
MetaDataIcon, MetaDataIcon,
CustomCssIcon, CustomCssIcon,
RebuildIcon,
}, },
methods: { methods: {
/* Seletcs the edit tab of the tab view */ /* Seletcs the edit tab of the tab view */
@ -121,6 +132,9 @@ export default {
const itemToSelect = this.$refs.tabView.navItems[4]; const itemToSelect = this.$refs.tabView.navItems[4];
this.$refs.tabView.activeTabItem({ tabItem: itemToSelect, byUser: true }); this.$refs.tabView.activeTabItem({ tabItem: itemToSelect, byUser: true });
}, },
openRebuildAppModal() {
this.$modal.show(modalNames.REBUILD_APP);
},
openCloudSync() { openCloudSync() {
this.$modal.show(modalNames.CLOUD_BACKUP); this.$modal.show(modalNames.CLOUD_BACKUP);
}, },

View File

@ -0,0 +1,169 @@
<template>
<modal :name="modalName" :resizable="true" width="50%" height="60%" classes="dashy-modal">
<div class="rebuild-app-container">
<!-- Title, intro and start button -->
<h3 class="rebuild-app-title">Rebuild Application</h3>
<p>
A rebuild is required for changes written to the conf.yml file to take effect.
This should happen automatically, but if it hasn't, you can manually trigger it here.<br>
This is not required for modifications stored locally.
</p>
<Button :click="startBuild" :disabled="loading">
<template v-slot:text>{{ loading ? 'Building...' : 'Start Build' }}</template>
<template v-slot:icon><RebuildIcon /></template>
</Button>
<!-- Loading animation and text (shown while build is happening) -->
<div v-if="loading" class="loader-info">
<LoadingAnimation class="loader" />
<p class="loading-message">This may take a few minutes...</p>
</div>
<!-- Build response, and next actions (shown after build is done) -->
<div class="rebuild-response" v-if="success !== undefined">
<p v-if="success" class="response-status success"> Build completed succesfully</p>
<p v-else class="response-status failure"> Build operation failed</p>
<pre class="output"><code>{{ output || error }}</code></pre>
<p class="rebuild-message">{{ message }}</p>
<p v-if="success" class="rebuild-message">
A page reload is now required for changes to take effect
</p>
<Button :click="refreshPage" v-if="success">
<template v-slot:text>Reload Page</template>
<template v-slot:icon><ReloadIcon /></template>
</Button>
</div>
</div>
</modal>
</template>
<script>
import axios from 'axios';
import Button from '@/components/FormElements/Button';
import { modalNames } from '@/utils/defaults';
import RebuildIcon from '@/assets/interface-icons/application-rebuild.svg';
import ReloadIcon from '@/assets/interface-icons/application-reload.svg';
import LoadingAnimation from '@/assets/interface-icons/loader.svg';
export default {
name: 'RebuildApp',
components: {
Button,
RebuildIcon,
ReloadIcon,
LoadingAnimation,
},
data: () => ({
modalName: modalNames.REBUILD_APP,
loading: false,
success: undefined,
error: '',
output: '',
message: '',
}),
methods: {
startBuild() {
const baseUrl = process.env.VUE_APP_DOMAIN || window.location.origin;
const endpoint = `${baseUrl}/config-manager/rebuild`;
this.loading = true;
axios.get(endpoint)
.then((response) => {
this.finished(response.data || false);
})
.catch((error) => {
this.finished({ success: false, error });
});
},
finished(responseData) {
this.loading = false;
if (responseData) {
const {
success, output, error, message,
} = responseData;
this.success = success;
this.output = output;
this.message = message;
this.error = error;
}
this.$toasted.show(
(this.success ? '✅ Build Completed Succesfully' : '❌ Build Failed'),
{ className: `toast-${this.success ? 'success' : 'error'}` },
);
},
refreshPage() {
location.reload(); // eslint-disable-line no-restricted-globals
},
},
};
</script>
<style scoped lang="scss">
.rebuild-app-container {
display: flex;
flex-direction: column;
height: 100%;
padding: 1rem;
color: var(--config-settings-color);
background: var(--config-settings-background);
overflow: auto;
button {
background: var(--config-settings-background);
color: var(--config-settings-color);
}
h3.rebuild-app-title {
text-align: center;
font-size: 2rem;
margin: 1rem;
}
div.loader-info {
margin: 0.2rem auto;
text-align: center;
svg.loader {
width: 100px;
}
p.loading-message {
margin: 0;
font-size: 0.8rem;
opacity: var(--dimming-factor);
animation: 3s fadeIn;
animation-fill-mode: forwards;
opacity: 0;
@keyframes fadeIn {
90% { opacity: 0; }
95% { opacity: 0.8; }
100% { opacity: 1; }
}
}
}
div.rebuild-response {
width: 80%;
margin: 0 auto 4rem auto;
text-align: center;
p.response-status {
font-size: 1rem;
text-align: left;
&.success {
color: var(--success);
}
&.failure {
color: var(--danger);
}
}
pre.output {
padding: 1rem;
font-size: 0.75rem;
border-radius: var(--curve-factor-small);
text-align: left;
color: var(--white);
background: var(--black);
white-space: pre-wrap;
}
p.rebuild-message {
font-size: 1rem;
text-align: left;
margin: 0.8rem 0;
color: var(--config-settings-color);
}
}
}
</style>

View File

@ -62,6 +62,7 @@ module.exports = {
modalNames: { modalNames: {
CONF_EDITOR: 'CONF_EDITOR', CONF_EDITOR: 'CONF_EDITOR',
CLOUD_BACKUP: 'CLOUD_BACKUP', CLOUD_BACKUP: 'CLOUD_BACKUP',
REBUILD_APP: 'REBUILD_APP',
}, },
topLevelConfKeys: { topLevelConfKeys: {
PAGE_INFO: 'pageInfo', PAGE_INFO: 'pageInfo',