FEAT: backup/restore v2 & disclaimer v1
This commit is contained in:
@@ -19,7 +19,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<section>
|
<section>
|
||||||
<h2 class="text-3xl text-center">
|
<h2 class="text-3xl text-center">
|
||||||
Pre-configured applications :
|
Pre-configured applications
|
||||||
</h2>
|
</h2>
|
||||||
<ul class="flex justify-center p-4 m-4 max-w-full flex-wrap">
|
<ul class="flex justify-center p-4 m-4 max-w-full flex-wrap">
|
||||||
<li v-for="app in apps" class="m-4">
|
<li v-for="app in apps" class="m-4">
|
||||||
|
@@ -4,25 +4,24 @@
|
|||||||
import Gitea from 'Svg/apps/gitea.vue'
|
import Gitea from 'Svg/apps/gitea.vue'
|
||||||
import Folder from 'Svg/folder.vue'
|
import Folder from 'Svg/folder.vue'
|
||||||
import Storj from 'Svg/storj.vue'
|
import Storj from 'Svg/storj.vue'
|
||||||
import Rewind from 'Svg/rewind.vue'
|
|
||||||
import Terminal from 'Component/terminal.vue'
|
import Terminal from 'Component/terminal.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {Penpot, Deluge, Gitea, Rewind, Storj, Folder},
|
components: {Penpot, Deluge, Gitea, Storj, Folder},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
terminalContent: '',
|
terminalContent: '',
|
||||||
penpotClass: [],
|
penpotClass: [],
|
||||||
delugeClass: [],
|
delugeClass: [],
|
||||||
folderClass: [],
|
folderClass: [],
|
||||||
storjClass: ['hidden'],
|
storjClass: [],
|
||||||
progressBarClass: '',
|
progressBarClass: [],
|
||||||
progressClass: 'w-0',
|
progressClass: '',
|
||||||
startApps: 'w-full',
|
startApps: '',
|
||||||
endApps: 'hidden',
|
endApps: '',
|
||||||
upClass: ['animate-upApp', 'mx-2', 'md:mx-12'],
|
upClass: ['animate-upApp', 'mx-2', 'md:mx-12'],
|
||||||
downClass: ['opacity-0', 'w-0', 'p-0'],
|
downClass: [],
|
||||||
pauseClass: ['filter', 'grayscale'],
|
pauseClass: [],
|
||||||
compressingClass: ['mx-0', 'rounded-none'],
|
compressingClass: [],
|
||||||
isDemonstrationEnded: false,
|
isDemonstrationEnded: false,
|
||||||
}),
|
}),
|
||||||
methods: {
|
methods: {
|
||||||
@@ -35,10 +34,20 @@
|
|||||||
this.folderClass = this.storjClass = this.downClass
|
this.folderClass = this.storjClass = this.downClass
|
||||||
this.penpotClass = this.delugeClass = this.giteaClass = this.upClass
|
this.penpotClass = this.delugeClass = this.giteaClass = this.upClass
|
||||||
|
|
||||||
|
this.storjClass = ['hidden']
|
||||||
|
this.progressBarClass = ['opacity-0']
|
||||||
|
this.progressClass = 'w-0'
|
||||||
|
this.startApps = 'w-full'
|
||||||
|
this.endApps = 'hidden'
|
||||||
|
this.upClass = ['animate-upApp', 'mx-2', 'md:mx-12']
|
||||||
|
this.downClass = ['opacity-0', 'w-0', 'p-0', 'h-0']
|
||||||
|
this.pauseClass = ['filter', 'grayscale']
|
||||||
|
this.compressingClass = ['mx-0', 'rounded-none']
|
||||||
|
|
||||||
let i = 0
|
let i = 0
|
||||||
|
|
||||||
this.timer = setInterval(async () => {
|
this.timer = setInterval(async () => {
|
||||||
// up
|
// pegaz backup
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
let cmd = '$ pegaz backup\n'
|
let cmd = '$ pegaz backup\n'
|
||||||
for (let y in cmd) {
|
for (let y in cmd) {
|
||||||
@@ -47,14 +56,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i == 1) {
|
if (i == 1) {
|
||||||
this.progressClass = 'w-1/4'
|
|
||||||
this.penpotClass = [...this.upClass, ...this.pauseClass]
|
this.penpotClass = [...this.upClass, ...this.pauseClass]
|
||||||
this.delugeClass = [...this.upClass, ...this.pauseClass]
|
this.delugeClass = [...this.upClass, ...this.pauseClass]
|
||||||
this.giteaClass = [...this.upClass, ...this.pauseClass]
|
this.giteaClass = [...this.upClass, ...this.pauseClass]
|
||||||
}
|
}
|
||||||
if (i == 2) this.progressClass = 'w-2/4'
|
if (i == 2) {
|
||||||
if (i == 3) {
|
|
||||||
this.progressClass = 'w-3/4'
|
|
||||||
this.penpotClass = [...this.compressingClass, ...this.pauseClass]
|
this.penpotClass = [...this.compressingClass, ...this.pauseClass]
|
||||||
this.delugeClass = [...this.compressingClass, ...this.pauseClass]
|
this.delugeClass = [...this.compressingClass, ...this.pauseClass]
|
||||||
this.giteaClass = [...this.compressingClass, ...this.pauseClass]
|
this.giteaClass = [...this.compressingClass, ...this.pauseClass]
|
||||||
@@ -62,22 +68,69 @@
|
|||||||
this.delugeClass.push('rounded-r-xl', 'rounded-l-none')
|
this.delugeClass.push('rounded-r-xl', 'rounded-l-none')
|
||||||
this.startApps = 'w-16'
|
this.startApps = 'w-16'
|
||||||
}
|
}
|
||||||
if (i == 4) {
|
if (i == 3) {
|
||||||
|
this.progressBarClass = 'opacity-100'
|
||||||
|
this.progressClass = 'w-full'
|
||||||
|
}
|
||||||
|
if (i == 5) {
|
||||||
|
this.progressBarClass = 'opacity-0'
|
||||||
this.folderClass = this.upClass
|
this.folderClass = this.upClass
|
||||||
this.startApps = ['hidden']
|
this.startApps = ['hidden']
|
||||||
this.endApps = ''
|
this.endApps = ''
|
||||||
this.progressClass = 'w-full'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == 5) this.progressBarClass = 'opacity-0'
|
|
||||||
|
|
||||||
if (i == 1) this.terminalContent += 'Pausing apps ... done\n'
|
if (i == 1) this.terminalContent += 'Pausing apps ... done\n'
|
||||||
if (i == 2) this.terminalContent += '[*] apps backup\n'
|
if (i == 2) this.terminalContent += '[*] compressing files\n'
|
||||||
if (i == 3) this.terminalContent += '[*] compressing files\n'
|
if (i == 4) this.terminalContent += 'Unpausing apps ... done\n'
|
||||||
if (i == 4) this.terminalContent += '[√] apps backup done\n'
|
if (i == 5) this.terminalContent += '[√] apps backup done\n'
|
||||||
|
|
||||||
if (i == 30) clearInterval(this.timer)
|
// pegaz restore
|
||||||
|
|
||||||
|
// this.progressClass = 'w-0'
|
||||||
|
// this.startApps = 'w-full'
|
||||||
|
|
||||||
|
if (i == 7) this.terminalContent = ''
|
||||||
|
if (i == 7) this.progressClass = 'w-0'
|
||||||
|
|
||||||
|
if (i == 8) {
|
||||||
|
let cmd = '$ pegaz restore\n'
|
||||||
|
for (let y in cmd) {
|
||||||
|
this.terminalContent += cmd[y]
|
||||||
|
await this.delay(20)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == 10) {
|
||||||
|
this.progressBarClass = 'opacity-100'
|
||||||
|
this.progressClass = 'w-full'
|
||||||
|
}
|
||||||
|
if (i == 11) {
|
||||||
|
this.folderClass = this.downClass
|
||||||
|
this.progressBarClass = 'opacity-0'
|
||||||
|
this.startApps = 'w-full'
|
||||||
|
}
|
||||||
|
if (i == 11) {
|
||||||
|
this.penpotClass = [...this.upClass, ...this.pauseClass]
|
||||||
|
this.delugeClass = [...this.upClass, ...this.pauseClass]
|
||||||
|
this.giteaClass = [...this.upClass, ...this.pauseClass]
|
||||||
|
}
|
||||||
|
if (i == 13) {
|
||||||
|
this.penpotClass = [...this.upClass]
|
||||||
|
this.delugeClass = [...this.upClass]
|
||||||
|
this.giteaClass = [...this.upClass]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 9) this.terminalContent += 'Stoping apps ... done\n'
|
||||||
|
if (i == 10) this.terminalContent += '[*] uncompressing files\n'
|
||||||
|
if (i == 12) this.terminalContent += '[*] starting apps ...done\n'
|
||||||
|
if (i == 13) this.terminalContent += '[√] apps restore done\n'
|
||||||
|
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
|
if (i == 15) this.isDemonstrationEnded = true
|
||||||
|
if (i == 15) this.progressClass = 'w-0'
|
||||||
|
if (i == 15) this.terminalContent = ''
|
||||||
|
// if (i == 15) clearInterval(this.timer)
|
||||||
|
if (i == 15) i = 0
|
||||||
}, 1000)
|
}, 1000)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -88,12 +141,12 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<h2 class="text-3xl text-center mb-10">
|
<h2 class="title">
|
||||||
Backup & restore :
|
Backup & restore
|
||||||
</h2>
|
</h2>
|
||||||
<section class="pegaz-section">
|
<section class="pegaz-section">
|
||||||
<Terminal :terminalContent="terminalContent" />
|
<Terminal :terminalContent="terminalContent" />
|
||||||
<div class="flex flex-col items-center w-1/2 h-full rounded-b-xl transition-all">
|
<div class="flex flex-col items-center w-1/2 h-20 relative rounded-b-xl transition-all">
|
||||||
<div class="flex transition-all justify-center duration-1000" :class="startApps">
|
<div class="flex transition-all justify-center duration-1000" :class="startApps">
|
||||||
<Penpot :class="penpotClass" class="app app--backup" />
|
<Penpot :class="penpotClass" class="app app--backup" />
|
||||||
<Gitea :class="giteaClass" class="app app--backup hidden md:block" />
|
<Gitea :class="giteaClass" class="app app--backup hidden md:block" />
|
||||||
@@ -108,27 +161,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<Storj class="hidden" :class="storjClass" />
|
<Storj class="hidden" :class="storjClass" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-center w-full" :class="progressBarClass">
|
<div class="flex mt-10 w-14 absolute" :class="progressBarClass">
|
||||||
<div class="relative flex jus mt-12 w-44 rounded-full">
|
<span class="h-2 w-full absolute bg-black rounded-full opacity-10"></span>
|
||||||
<span class="h-1 w-full absolute bg-black opacity-10"></span>
|
<span class="h-2 absolute rounded-full bg-green-400 transition-all duration-1000" :class="progressClass"></span>
|
||||||
<span class="h-1 absolute bg-green-400 transition-all duration-1000" :class="progressClass"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<transition
|
|
||||||
enter-active-class="duration-300 ease-out"
|
|
||||||
enter-from-class="transform opacity-0"
|
|
||||||
enter-to-class="opacity-100"
|
|
||||||
leave-active-class="duration-200 ease-in"
|
|
||||||
leave-from-class="opacity-100"
|
|
||||||
leave-to-class="transform opacity-0"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
@click="demonstration"
|
|
||||||
v-if="isDemonstrationEnded"
|
|
||||||
class="bg-indigo-600 hover:bg-indigo-500 focus:outline-none focus:ring-4 hover:ring-indigo-200 focus:ring-indigo-300 focus:ring-opacity-100 transition-all rounded-full p-8 lg:p-20 md:p-12 absolute cursor-pointer focus:p-18 shadow-2xl z-50">
|
|
||||||
<Rewind class="text-white" />
|
|
||||||
</div>
|
|
||||||
</transition>
|
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
@@ -2,11 +2,10 @@
|
|||||||
import Nextcloud from 'Svg/apps/nextcloud.vue'
|
import Nextcloud from 'Svg/apps/nextcloud.vue'
|
||||||
import Jellyfin from 'Svg/apps/jellyfin.vue'
|
import Jellyfin from 'Svg/apps/jellyfin.vue'
|
||||||
import Backbutton from 'Svg/backbutton.vue'
|
import Backbutton from 'Svg/backbutton.vue'
|
||||||
import Rewind from 'Svg/rewind.vue'
|
|
||||||
import Terminal from 'Component/terminal.vue'
|
import Terminal from 'Component/terminal.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {Nextcloud, Jellyfin, Backbutton, Rewind},
|
components: {Nextcloud, Jellyfin, Backbutton},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
terminalContent: '',
|
terminalContent: '',
|
||||||
subDomain: '',
|
subDomain: '',
|
||||||
@@ -49,7 +48,7 @@
|
|||||||
// open
|
// open
|
||||||
if (i == 5) this.nextcloudClass.push('animate-openApp')
|
if (i == 5) this.nextcloudClass.push('animate-openApp')
|
||||||
if (i == 6) this.nextcloudClass = openClass
|
if (i == 6) this.nextcloudClass = openClass
|
||||||
if (i == 6) this.subDomain = 'nextcloud.'
|
if (i == 6) this.subDomain = 'cloud.'
|
||||||
if (i == 6) this.subdomainClass = ['']
|
if (i == 6) this.subdomainClass = ['']
|
||||||
if (i == 6) this.subdomainClass = ['animate-click']
|
if (i == 6) this.subdomainClass = ['animate-click']
|
||||||
//close
|
//close
|
||||||
@@ -96,8 +95,12 @@
|
|||||||
if (i == 26) this.nextcloudClass = downClass
|
if (i == 26) this.nextcloudClass = downClass
|
||||||
if (i == 27) this.isDemonstrationEnded = true
|
if (i == 27) this.isDemonstrationEnded = true
|
||||||
|
|
||||||
if (i == 30) clearInterval(this.timer)
|
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
|
// if (i == 30) clearInterval(this.timer)
|
||||||
|
if (i == 30) this.terminalContent = ''
|
||||||
|
if (i == 30) this.jellyfinClass = downClass
|
||||||
|
if (i == 30) i = 0
|
||||||
}, 1000)
|
}, 1000)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -114,8 +117,8 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<section class="pegaz-section">
|
<section class="pegaz-section">
|
||||||
<Terminal :terminalContent="terminalContent" :class="{'blur-sm': isDemonstrationEnded}" />
|
<Terminal :terminalContent="terminalContent" />
|
||||||
<div class="bg-slate-400 flex flex-col items-center rounded-2xl w-2/4 md:min-w-fit h-80 md:-ml-8 md:z-0" :class="{'blur-sm': isDemonstrationEnded}">
|
<div class="bg-slate-400 flex flex-col items-center relative rounded-2xl w-full md:w-2/4 m-0 md:min-w-fit h-80 max-h-80 md:-ml-8 md:z-0">
|
||||||
<div class="bg-white flex items-center rounded-2xl pr-4 pl-2 py-1 m-4 w-4/5">
|
<div class="bg-white flex items-center rounded-2xl pr-4 pl-2 py-1 m-4 w-4/5">
|
||||||
<Backbutton class="mr-3 p-1 bg-slate-300 rounded-full" :class="backbuttonClass" />
|
<Backbutton class="mr-3 p-1 bg-slate-300 rounded-full" :class="backbuttonClass" />
|
||||||
<span class="text-gray-400">
|
<span class="text-gray-400">
|
||||||
@@ -130,20 +133,5 @@
|
|||||||
<Jellyfin class="app" :class="jellyfinClass" title="jellyfin.domain.com" />
|
<Jellyfin class="app" :class="jellyfinClass" title="jellyfin.domain.com" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<transition
|
|
||||||
enter-active-class="duration-300 ease-out"
|
|
||||||
enter-from-class="transform opacity-0"
|
|
||||||
enter-to-class="opacity-100"
|
|
||||||
leave-active-class="duration-200 ease-in"
|
|
||||||
leave-from-class="opacity-100"
|
|
||||||
leave-to-class="transform opacity-0"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
@click="demonstration"
|
|
||||||
v-if="isDemonstrationEnded"
|
|
||||||
class="bg-indigo-600 hover:bg-indigo-500 focus:outline-none focus:ring-4 hover:ring-indigo-200 focus:ring-indigo-300 focus:ring-opacity-100 transition-all rounded-full p-8 lg:p-20 md:p-12 absolute cursor-pointer focus:p-18 shadow-2xl z-50">
|
|
||||||
<Rewind class="text-white" />
|
|
||||||
</div>
|
|
||||||
</transition>
|
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
19
src/components/disclaimer.vue
Normal file
19
src/components/disclaimer.vue
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<template>
|
||||||
|
<section class="container mx-auto my-20">
|
||||||
|
<h2 class="title">
|
||||||
|
Features
|
||||||
|
</h2>
|
||||||
|
<p class="text-xl md:text-center">
|
||||||
|
Pegaz is a simple web-service launcher.
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
In extending docker-compose functionnality, pegaz let you control multiple docker-compose.yml configurations.
|
||||||
|
</p>
|
||||||
|
<ul class="text-xl md:text-2xl p-14">
|
||||||
|
<li>🔒 ssl certification</li>
|
||||||
|
<li>🎉 sub-domain & multi-domain directly in docker-compose file</li>
|
||||||
|
<li>📝 pre & post install script</li>
|
||||||
|
<li>📦 backup / restore volumes</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</template>
|
@@ -4,7 +4,7 @@
|
|||||||
terminalContent: {
|
terminalContent: {
|
||||||
required: true,
|
required: true,
|
||||||
type: String,
|
type: String,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex h-4/5">
|
<div class="flex h-4/5">
|
||||||
<code class="w-full text-white font-mono text-xs md:text-base p-4 pt-0 mr-0 overflow-scroll whitespace-pre">
|
<code class="w-full text-white font-mono text-xs md:text-base p-4 pt-0 mr-0 overflow-scroll whitespace-pre">
|
||||||
{{ terminalContent }}<span class="w-2 h-4 bg-white inline-block animate-blink relative" style="margin-bottom: -2px;" ref="terminal" />
|
{{ terminalContent }}<span class="w-2 h-4 bg-white inline-block relative" style="margin-bottom: -2px;" ref="terminal" />
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -15,8 +15,9 @@
|
|||||||
</header>
|
</header>
|
||||||
<main class="-mt-20">
|
<main class="-mt-20">
|
||||||
<Demo />
|
<Demo />
|
||||||
<AppList />
|
<Disclaimer />
|
||||||
<BackupRestore />
|
<BackupRestore />
|
||||||
|
<AppList />
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -33,15 +34,14 @@ import HeroButtons from 'Component/hero-buttons.vue'
|
|||||||
import Demo from 'Component/demo.vue'
|
import Demo from 'Component/demo.vue'
|
||||||
import AppList from 'Component/applications-list.vue'
|
import AppList from 'Component/applications-list.vue'
|
||||||
import BackupRestore from 'Component/backup-restore.vue'
|
import BackupRestore from 'Component/backup-restore.vue'
|
||||||
|
import Disclaimer from 'Component/disclaimer.vue'
|
||||||
|
|
||||||
useMeta({
|
useMeta({
|
||||||
title: 'Deploy stack',
|
title: 'Deploy stack',
|
||||||
})
|
})
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const usersStore = useUsersStore()
|
const usersStore = useUsersStore()
|
||||||
|
|
||||||
const newName = ref('')
|
const newName = ref('')
|
||||||
|
|
||||||
function saveName() {
|
function saveName() {
|
||||||
@@ -57,9 +57,12 @@ function saveName() {
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
.pegaz-section {
|
.pegaz-section {
|
||||||
@apply flex flex-col md:flex-row items-center justify-center mb-28;
|
@apply flex flex-col md:flex-row items-center justify-center mb-28
|
||||||
|
}
|
||||||
|
.title {
|
||||||
|
@apply text-3xl text-center mb-10
|
||||||
}
|
}
|
||||||
.app {
|
.app {
|
||||||
@apply bg-black bg-opacity-10 w-20 h-20 p-4 rounded-xl flex-wrap cursor-pointer inline-block transition-all;
|
@apply bg-black bg-opacity-10 w-20 h-20 p-4 rounded-xl flex-wrap cursor-pointer inline-block transition-all
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Reference in New Issue
Block a user