feat: switch to sidebase/nuxt !

This commit is contained in:
valere
2023-03-09 19:40:02 +01:00
parent 63b895633b
commit bab74dd088
86 changed files with 18165 additions and 5562 deletions

View File

@@ -1,3 +0,0 @@
node_modules/
dist/
npm-debug.log

View File

@@ -1,13 +0,0 @@
module.exports = {
extends: [
'plugin:vue/vue3-essential',
'prettier',
// 'airbnb-base',
'plugin:import/typescript'
],
rules: {
// override/add rules settings here, such as:
'vue/no-unused-vars': 'error',
'vue/multi-word-component-names': 'off',
},
}

93
.gitignore vendored
View File

@@ -1,20 +1,83 @@
# build output
dist/
.output/
# dependencies
node_modules/
# logs
# Logs and databases #
######################
*.log
*.sql
*.sqlite
*.db
*.sqlite-journal
/logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# environment variables
.env
.env.production
# macOS-specific files
# OS generated files #
######################
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# helmsman generated tmp folder
.helmsman-tmp
# Coverage directory used by tools like istanbul
coverage
# Dependency directories
node_modules/
jspm_packages/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# Nuxt
*.log*
.nuxt
.nitro
.cache
.output
.env
dist
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless
# IDE / Editor
.idea
# Service worker
sw.*
# Vim swap files
*.swp
# Auto generate on postinstall step
auto-imports.d.ts
components.d.ts

View File

@@ -1,11 +0,0 @@
module.exports = {
semi: false,
tabWidth: 2,
useTabs: false,
printWidth: 80,
endOfLine: 'auto',
singleQuote: true,
trailingComma: 'es5',
bracketSpacing: true,
arrowParens: 'always',
}

View File

@@ -1,13 +1,39 @@
FROM node:18-alpine as develop-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
# see https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact
ARG NODE_VERSION=node:16.14.2
FROM develop-stage as build-stage
FROM $NODE_VERSION AS dependency-base
# create destination directory
RUN mkdir -p /app
WORKDIR /app
# copy the app, note .dockerignore
COPY package.json .
COPY package-lock.json .
RUN npm ci
FROM dependency-base AS production-base
# build will also take care of building
# if necessary
COPY . .
RUN npm run build
FROM nginx:1.15.7-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
FROM $NODE_VERSION AS production
COPY --from=production-base /app/.output /app/.output
# Service hostname
ENV NUXT_HOST=0.0.0.0
# Service version
ARG NUXT_APP_VERSION
ENV NUXT_APP_VERSION=${NUXT_APP_VERSION}
ENV DATABASE_URL=file:./db.sqlite
# Run in production mode
ENV NODE_ENV=production
# start the app
CMD [ "node", "/app/.output/server/index.mjs" ]

21
License
View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2021 Shamim Hossain
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,90 +1,7 @@
# TODO
0. anim pegaz create ??
1. presentation de l'arborecense - doc du code
2. command line guide - doc du CLI
3. configuration file ?
- [ ] anim pegaz create ??
- [ ] presentation de l'arborecense - doc du code
- [ ] command line guide - doc du CLI
- [ ] configuration file ?
# vue-3-stackter
![Cover Image](https://raw.githubusercontent.com/shamscorner/images/main/vite-vue-3-tailwind.png)
A Vue3 starter project setup with these following components,
- [Vite](https://vitejs.dev/)
- vue-meta-3.0.0-alpha.8
- Router
- [Pinia](https://pinia.vuejs.org/) (Vue 3 default)
- Eslint
- Prettier
- [Tailwind CSS](https://tailwindcss.com/)
- File based routing with [vite-plugin-pages](https://github.com/hannoeru/vite-plugin-pages). (Like [Nuxt file system routing](https://nuxtjs.org/docs/2.x/features/file-system-routing))
- Layout system with [vite-plugin-vue-layouts](https://github.com/JohnCampionJr/vite-plugin-vue-layouts). (Like [Nuxt layouts](https://nuxtjs.org/docs/2.x/directory-structure/layouts))
- Components auto importing with [`unplugin-vue-components`](https://github.com/antfu/unplugin-vue-components)
- `~/` alias for `/src`. So we don't have to write something like `../../../SomeModule` to import modules.
- and some custom setups.
[Check out Typescript version here](https://github.com/shamscorner/vitesse-stackter-clean-architect)
### Run this project:
```
yarn
yarn dev
```
### Change site name
In `App.vue` change the following,
```Javascript
const siteName = 'Vite App' // add your site name here
```
### Layouts
You can add layouts in your project if you want. You will find `default.vue` and `404.vue` layout examples in this project. For more details, check out [vite-plugin-vue-layouts](https://github.com/JohnCampionJr/vite-plugin-vue-layouts). (Like [Nuxt layouts](https://nuxtjs.org/docs/2.x/directory-structure/layouts) system).
### Pages
You can add pages to your project. You will find some example pages in the `pages` directory (`index.vue`, `about/[name].vue`, and `[...all].vue`). For more details, check out [vite-plugin-pages](https://github.com/hannoeru/vite-plugin-pages). (Like [Nuxt file system routing](https://nuxtjs.org/docs/2.x/features/file-system-routing)).
### Meta info
You can add meta information in your pages. Here is an example,
```Javascript
<script setup>
import { useMeta } from 'vue-meta'
useMeta({
title: 'Homepage',
})
...
</script>
```
## Recommended IDE Setup
[VSCode](https://code.visualstudio.com/) + [Vetur](https://marketplace.visualstudio.com/items?itemName=octref.vetur). Make sure to enable `vetur.experimental.templateInterpolationService` in settings!
### If Using `<script setup>`
[`<script setup>`](https://github.com/vuejs/rfcs/pull/227) is a feature that is currently in RFC stage. To get proper IDE support for the syntax, use [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar) instead of Vetur (and disable Vetur).
## Type Support For `.vue` Imports in TS
Since TypeScript cannot handle type information for `.vue` imports, they are shimmed to be a generic Vue component type by default. In most cases this is fine if you don't really care about component prop types outside of templates. However, if you wish to get actual prop types in `.vue` imports (for example to get props validation when using manual `h(...)` calls), you can use the following:
### If Using Volar
Run `Volar: Switch TS Plugin on/off` from VSCode command palette.
### If Using Vetur
1. Install and add `@vuedx/typescript-plugin-vue` to the [plugins section](https://www.typescriptlang.org/tsconfig#plugins) in `tsconfig.json`
2. Delete `src/shims-vue.d.ts` as it is no longer needed to provide module info to Typescript
3. Open `src/main.ts` in VSCode
4. Open the VSCode command palette
5. Search and run "Select TypeScript version" -> "Use workspace version"

30
app.vue Normal file
View File

@@ -0,0 +1,30 @@
<template>
<div>
<Head>
<Title>Pegaz.io - docker-compose cli superset</Title>
<Meta charset="UTF-8" />
<Meta name="viewport" content="width=device-width" />
<Link
rel="icon"
type="image/svg+xml"
href="https://raw.githubusercontent.com/valerebron/pegaz/master/docs/pegaz.svg"
/>
<Link rel="canonical" href="https://pegaz.io" />
<Meta property="og:title" content="pegaz, deploy stack on the go" />
<Meta
property="og:image"
content="https://raw.githubusercontent.com/valerebron/pegaz/master/docs/pegaz.svg"
/>
<Meta property="og:site_name" content="Pegaz.io" />
<Meta name="description" content="Extending docker-compose functionalities and control multiple docker-compose.yml configurations"/>
<Meta name="viewport" content="width=device-width, initial-scale=1.0" />
</Head>
<NuxtPage />
</div>
</template>
<style lang="postcss">
html {
@apply bg-slate-100;
}
</style>

116
auto-imports.d.ts vendored Normal file
View File

@@ -0,0 +1,116 @@
// Generated by 'unplugin-auto-import'
export {}
declare global {
const EffectScope: typeof import('vue')['EffectScope']
const computed: typeof import('vue')['computed']
const createApp: typeof import('vue')['createApp']
const customRef: typeof import('vue')['customRef']
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
const defineComponent: typeof import('vue')['defineComponent']
const effectScope: typeof import('vue')['effectScope']
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
const getCurrentScope: typeof import('vue')['getCurrentScope']
const h: typeof import('vue')['h']
const inject: typeof import('vue')['inject']
const isProxy: typeof import('vue')['isProxy']
const isReactive: typeof import('vue')['isReactive']
const isReadonly: typeof import('vue')['isReadonly']
const isRef: typeof import('vue')['isRef']
const markRaw: typeof import('vue')['markRaw']
const nextTick: typeof import('vue')['nextTick']
const onActivated: typeof import('vue')['onActivated']
const onBeforeMount: typeof import('vue')['onBeforeMount']
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
const onDeactivated: typeof import('vue')['onDeactivated']
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
const onMounted: typeof import('vue')['onMounted']
const onRenderTracked: typeof import('vue')['onRenderTracked']
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
const onScopeDispose: typeof import('vue')['onScopeDispose']
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
const onUnmounted: typeof import('vue')['onUnmounted']
const onUpdated: typeof import('vue')['onUpdated']
const provide: typeof import('vue')['provide']
const reactive: typeof import('vue')['reactive']
const readonly: typeof import('vue')['readonly']
const ref: typeof import('vue')['ref']
const resolveComponent: typeof import('vue')['resolveComponent']
const resolveDirective: typeof import('vue')['resolveDirective']
const shallowReactive: typeof import('vue')['shallowReactive']
const shallowReadonly: typeof import('vue')['shallowReadonly']
const shallowRef: typeof import('vue')['shallowRef']
const toRaw: typeof import('vue')['toRaw']
const toRef: typeof import('vue')['toRef']
const toRefs: typeof import('vue')['toRefs']
const triggerRef: typeof import('vue')['triggerRef']
const unref: typeof import('vue')['unref']
const useAttrs: typeof import('vue')['useAttrs']
const useCssModule: typeof import('vue')['useCssModule']
const useCssVars: typeof import('vue')['useCssVars']
const useHead: typeof import('@vueuse/head')['useHead']
const useSlots: typeof import('vue')['useSlots']
const watch: typeof import('vue')['watch']
const watchEffect: typeof import('vue')['watchEffect']
const watchPostEffect: typeof import('vue')['watchPostEffect']
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
}
// for vue template auto import
import { UnwrapRef } from 'vue'
declare module 'vue' {
interface ComponentCustomProperties {
readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
readonly computed: UnwrapRef<typeof import('vue')['computed']>
readonly createApp: UnwrapRef<typeof import('vue')['createApp']>
readonly customRef: UnwrapRef<typeof import('vue')['customRef']>
readonly defineAsyncComponent: UnwrapRef<typeof import('vue')['defineAsyncComponent']>
readonly defineComponent: UnwrapRef<typeof import('vue')['defineComponent']>
readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>
readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
readonly h: UnwrapRef<typeof import('vue')['h']>
readonly inject: UnwrapRef<typeof import('vue')['inject']>
readonly isProxy: UnwrapRef<typeof import('vue')['isProxy']>
readonly isReactive: UnwrapRef<typeof import('vue')['isReactive']>
readonly isReadonly: UnwrapRef<typeof import('vue')['isReadonly']>
readonly isRef: UnwrapRef<typeof import('vue')['isRef']>
readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']>
readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']>
readonly onActivated: UnwrapRef<typeof import('vue')['onActivated']>
readonly onBeforeMount: UnwrapRef<typeof import('vue')['onBeforeMount']>
readonly onBeforeUnmount: UnwrapRef<typeof import('vue')['onBeforeUnmount']>
readonly onBeforeUpdate: UnwrapRef<typeof import('vue')['onBeforeUpdate']>
readonly onDeactivated: UnwrapRef<typeof import('vue')['onDeactivated']>
readonly onErrorCaptured: UnwrapRef<typeof import('vue')['onErrorCaptured']>
readonly onMounted: UnwrapRef<typeof import('vue')['onMounted']>
readonly onRenderTracked: UnwrapRef<typeof import('vue')['onRenderTracked']>
readonly onRenderTriggered: UnwrapRef<typeof import('vue')['onRenderTriggered']>
readonly onScopeDispose: UnwrapRef<typeof import('vue')['onScopeDispose']>
readonly onServerPrefetch: UnwrapRef<typeof import('vue')['onServerPrefetch']>
readonly onUnmounted: UnwrapRef<typeof import('vue')['onUnmounted']>
readonly onUpdated: UnwrapRef<typeof import('vue')['onUpdated']>
readonly provide: UnwrapRef<typeof import('vue')['provide']>
readonly reactive: UnwrapRef<typeof import('vue')['reactive']>
readonly readonly: UnwrapRef<typeof import('vue')['readonly']>
readonly ref: UnwrapRef<typeof import('vue')['ref']>
readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>
readonly resolveDirective: UnwrapRef<typeof import('vue')['resolveDirective']>
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
readonly toRaw: UnwrapRef<typeof import('vue')['toRaw']>
readonly toRef: UnwrapRef<typeof import('vue')['toRef']>
readonly toRefs: UnwrapRef<typeof import('vue')['toRefs']>
readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']>
readonly unref: UnwrapRef<typeof import('vue')['unref']>
readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
readonly useHead: UnwrapRef<typeof import('@vueuse/head')['useHead']>
readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
readonly watch: UnwrapRef<typeof import('vue')['watch']>
readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>
readonly watchSyncEffect: UnwrapRef<typeof import('vue')['watchSyncEffect']>
}
}

7
components.d.ts vendored
View File

@@ -7,14 +7,7 @@ export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
ApplicationsList: typeof import('./src/components/applications-list.vue')['default']
BackupRestore: typeof import('./src/components/backup-restore.vue')['default']
Demo: typeof import('./src/components/demo.vue')['default']
Disclaimer: typeof import('./src/components/disclaimer.vue')['default']
HeroButtons: typeof import('./src/components/hero-buttons.vue')['default']
HeroTitle: typeof import('./src/components/hero-title.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
Terminal: typeof import('./src/components/terminal.vue')['default']
}
}

View File

@@ -0,0 +1,65 @@
<script>
export default {
data: () => ({
apps: [
{
name: 'Deluge',
component: resolveComponent('SvgDeluge')
},
{
name: 'Drone',
component: resolveComponent('SvgDrone')
},
{
name: 'Gitea',
component: resolveComponent('SvgGitea')
},
{
name: 'Hoppscotch',
component: resolveComponent('SvgHoppscotch')
},
{
name: 'Jellyfin',
component: resolveComponent('SvgJellyfin')
},
{
name: 'Nextcloud',
component: resolveComponent('SvgNextcloud')
},
{
name: 'Plausible',
component: resolveComponent('SvgPlausible')
},
{
name: 'Penpot',
component: resolveComponent('SvgPenpot')
},
{
name: 'Radio',
component: resolveComponent('SvgRadio')
}
]
})
}
</script>
<template>
<section>
<h2 class="title">
Pre-configured applications
</h2>
<ul class="flex justify-center p-4 m-4 max-w-full flex-wrap">
<li v-for="app in apps" :key="app" class="m-4">
<a
:href="
'https://github.com/valerebron/pegaz/tree/master/services/' +
app.name.toLowerCase()
"
:title="app.name"
>
<component :is="app.component" class="app" />
</a>
</li>
</ul>
</section>
</template>

View File

@@ -1,13 +1,5 @@
<script>
import Penpot from 'Svg/apps/penpot.vue'
import Deluge from 'Svg/apps/deluge.vue'
import Gitea from 'Svg/apps/gitea.vue'
import Folder from 'Svg/folder.vue'
import Storj from 'Svg/storj.vue'
import Terminal from 'Component/terminal.vue'
export default {
components: { Penpot, Deluge, Gitea, Storj, Folder },
data: () => ({
terminalContent: '',
penpotClass: [],
@@ -22,24 +14,27 @@ export default {
downClass: [],
pauseClass: [],
compressingClass: [],
isDemonstrationEnded: false,
isDemonstrationEnded: false
}),
created () {
this.demonstration()
},
methods: {
delay(time) {
return new Promise((resolve) => setTimeout(resolve, time))
delay (time) {
return new Promise(resolve => setTimeout(resolve, time))
},
demonstration() {
demonstration () {
this.isDemonstrationEnded = false
this.terminalContent = ''
this.folderClass = this.storjClass = this.downClass
this.penpotClass = this.delugeClass = this.giteaClass = this.upClass
this.penpotClass = this.delugeClass = this.giteaClass = [...this.upClass, 'rounded-xl']
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.upClass = ['animate-upApp', 'mx-2', 'md:mx-12', 'rounded-xl']
this.downClass = ['opacity-0', 'w-0', 'p-0', 'h-0']
this.pauseClass = ['filter', 'grayscale']
this.compressingClass = ['mx-0', 'rounded-none']
@@ -48,102 +43,97 @@ export default {
this.timer = setInterval(async () => {
// pegaz backup
if (i == 0) {
let cmd = '$ pegaz backup\n'
for (let y in cmd) {
if (i === 0) {
const cmd = '$ pegaz backup\n'
for (const y in cmd) {
this.terminalContent += cmd[y]
await this.delay(20)
}
}
if (i == 1) {
this.penpotClass = [...this.upClass, ...this.pauseClass]
this.delugeClass = [...this.upClass, ...this.pauseClass]
this.giteaClass = [...this.upClass, ...this.pauseClass]
if (i === 1) {
this.penpotClass = this.delugeClass = this.giteaClass = [...this.upClass, ...this.pauseClass]
}
if (i == 2) {
this.penpotClass = [...this.compressingClass, ...this.pauseClass]
this.delugeClass = [...this.compressingClass, ...this.pauseClass]
if (i === 2) {
this.penpotClass = [...this.compressingClass, ...this.pauseClass, 'rounded-l-xl', 'rounded-r-none']
this.delugeClass = [...this.compressingClass, ...this.pauseClass, 'rounded-r-xl', 'rounded-l-none']
this.giteaClass = [...this.compressingClass, ...this.pauseClass]
this.penpotClass.push('rounded-l-xl', 'rounded-r-none')
this.delugeClass.push('rounded-r-xl', 'rounded-l-none')
this.startApps = 'w-16'
}
if (i == 3) {
if (i === 3) {
this.progressBarClass = 'opacity-100'
this.progressClass = 'w-full'
}
if (i == 5) {
if (i === 5) {
this.progressBarClass = 'opacity-0'
this.folderClass = this.upClass
this.startApps = ['hidden']
this.endApps = ''
}
if (i == 1) this.terminalContent += 'Pausing apps ... done\n'
if (i == 2) this.terminalContent += '[*] compressing files\n'
if (i == 4) this.terminalContent += 'Unpausing apps ... done\n'
if (i == 5) this.terminalContent += '[√] apps backup done\n'
if (i === 1) { this.terminalContent += 'Pausing apps ... done\n' }
if (i === 2) { this.terminalContent += '[*] compressing files\n' }
if (i === 4) { this.terminalContent += 'Unpausing apps ... done\n' }
if (i === 5) { this.terminalContent += '[√] apps backup done\n' }
// pegaz restore
// this.progressClass = 'w-0'
// this.startApps = 'w-full'
if (i == 7) this.terminalContent = ''
if (i == 7) this.progressClass = 'w-0'
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) {
if (i === 8) {
const cmd = '$ pegaz restore\n'
for (const y in cmd) {
this.terminalContent += cmd[y]
await this.delay(20)
}
}
if (i == 10) {
if (i === 10) {
this.progressBarClass = 'opacity-100'
this.progressClass = 'w-full'
}
if (i == 11) {
if (i === 11) {
this.folderClass = this.downClass
this.progressBarClass = 'opacity-0'
this.startApps = 'w-full'
}
if (i == 11) {
if (i === 11) {
this.penpotClass = [...this.upClass, ...this.pauseClass]
this.delugeClass = [...this.upClass, ...this.pauseClass]
this.giteaClass = [...this.upClass, ...this.pauseClass]
}
if (i == 13) {
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'
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
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
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)
},
},
async created() {
this.demonstration()
},
}
}
}
</script>
<template>
<h2 class="title">Backup & restore</h2>
<h2 class="title">
Backup & restore
</h2>
<section class="pegaz-section">
<Terminal :terminalContent="terminalContent" />
<Terminal :terminal-content="terminalContent" />
<div
class="flex flex-col items-center w-1/2 h-20 relative rounded-b-xl transition-all"
>
@@ -151,25 +141,27 @@ export default {
class="flex transition-all justify-center duration-1000"
:class="startApps"
>
<Penpot :class="penpotClass" class="app app--backup" />
<Gitea :class="giteaClass" class="app app--backup hidden md:block" />
<Deluge :class="delugeClass" class="app app--backup" />
<SvgPenpot :class="penpotClass" class="app--backup" />
<SvgGitea :class="giteaClass" class="app--backup hidden md:block" />
<SvgDeluge :class="delugeClass" class="app--backup" />
</div>
<div :class="endApps">
<div class="app" :class="folderClass">
<Folder class="text-yellow-400" />
<div class="-mt-7 text-sm text-center">tar.gz</div>
<SvgFolder class="text-yellow-400" />
<div class="-mt-7 text-sm text-center">
tar.gz
</div>
</div>
<Storj class="hidden" :class="storjClass" />
<SvgStorj class="hidden" :class="storjClass" />
</div>
<div class="flex mt-10 w-14 absolute" :class="progressBarClass">
<span
class="h-2 w-full absolute bg-black rounded-full opacity-10"
></span>
/>
<span
class="h-2 absolute rounded-full bg-green-400 transition-all duration-1000"
:class="progressClass"
></span>
/>
</div>
</div>
</section>

176
components/demo.vue Normal file
View File

@@ -0,0 +1,176 @@
<script>
export default {
data: () => ({
terminalContent: '',
subDomain: '',
nextcloudClass: [],
jellyfinClass: [],
backbuttonClass: [],
subdomainClass: [],
isDemonstrationEnded: false,
isPageScrolled: false
}),
created () {
this.nextcloudClass = this.jellyfinClass = []
},
beforeMount () {
window.addEventListener('scroll', () => {
if (!this.isPageScrolled) { this.demonstration() }
this.isPageScrolled = true
})
},
beforeUnmount () {
window.removeEventListener('scroll', () => {
if (!this.isPageScrolled) { this.demonstration() }
this.isPageScrolled = true
})
},
methods: {
demonstration () {
const upClass = [
'w-20',
'h-20',
'p-4',
'opacity-100',
'animate-upApp',
'rounded-xl',
'bg-black',
'bg-opacity-10',
'transition-all'
]
const downClass = ['opacity-0', 'w-0', 'p-0']
const openClass = [
'w-full',
'h-full',
'p-20',
'rounded-b-xl',
'rounded-t-none',
'bg-gradient-to-r',
'from-violet-100',
'to-indigo-100',
'transition-all'
]
const closeClass = [
...upClass,
'm-2'
]
function delay (time) {
return new Promise(resolve => setTimeout(resolve, time))
}
this.isDemonstrationEnded = false
this.terminalContent = ''
this.nextcloudClass = this.jellyfinClass = downClass
let i = 0
this.timer = setInterval(async () => {
// nextcloud
// up
if (i === 0) {
const cmd = '$ pegaz up nextcloud\n'
for (const y in cmd) {
this.terminalContent += cmd[y]
await delay(20)
}
}
if (i === 1) { this.terminalContent += 'Creating nextcloud ... done\n' }
if (i === 2) { this.terminalContent += '[√] https://nextcloud.domain.com\n' }
if (i === 3) { this.nextcloudClass = upClass }
// open
if (i === 5) { this.nextcloudClass.push('animate-openApp') }
if (i === 6) { this.nextcloudClass = openClass }
if (i === 6) { this.subDomain = 'cloud.' }
if (i === 6) { this.subdomainClass = [''] }
if (i === 6) { this.subdomainClass = ['animate-click'] }
// close
if (i === 7) { this.terminalContent = '' }
if (i === 9) { this.backbuttonClass = ['animate-click'] }
if (i === 10) { this.nextcloudClass = closeClass }
if (i === 10) { this.subDomain = this.backbuttonClass = '' }
// jellyfin
// up
if (i === 11) {
const cmd = '$ pegaz up jellyfin\n'
for (const y in cmd) {
this.terminalContent += cmd[y]
await delay(20)
}
}
if (i === 12) { this.terminalContent += 'Creating jellyfin ... done\n' }
if (i === 13) { this.terminalContent += '[√] https://jellyfin.domain.com\n' }
if (i === 14) { this.jellyfinClass = closeClass }
// open
if (i === 16) { this.jellyfinClass.push('animate-openApp') }
if (i === 16) { this.nextcloudClass = downClass }
if (i === 17) { this.jellyfinClass = openClass }
if (i === 17) { this.subDomain = 'jellyfin.' }
if (i === 6) { this.subdomainClass = [''] }
if (i === 6) { this.subdomainClass = ['animate-click'] }
// close
if (i === 20) { this.backbuttonClass = ['animate-click'] }
if (i === 21) { this.jellyfinClass = this.nextcloudClass = closeClass }
if (i === 21) { this.subDomain = '' }
if (i === 21) { this.terminalContent = '' }
// nextcloud down
if (i === 23) {
const cmd = '$ pegaz down nextcloud\n'
for (const y in cmd) {
this.terminalContent += cmd[y]
await delay(20)
}
}
if (i === 24) { this.terminalContent += 'Stopping nextcloud ... done\n' }
if (i === 25) { this.terminalContent += '[√] Removing nextcloud ... done\n' }
if (i === 26) { this.nextcloudClass = downClass }
if (i === 27) { this.isDemonstrationEnded = true }
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)
}
}
}
</script>
<template>
<section class="pegaz-section">
<Terminal :terminal-content="terminalContent" />
<div
class="bg-slate-400 flex flex-col items-center relative rounded-2xl w-full m-0 md:min-w-fit max-w-2xl 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"
>
<SvgBackbutton
class="mr-3 p-1 bg-slate-300 rounded-full"
:class="backbuttonClass"
/>
<span class="text-gray-400"> https:// </span>
<span class="text-indigo-700 font-bold" :class="subdomainClass">
{{ subDomain }} </span>domain.com
</div>
<div
class="bg-white w-full h-full flex rounded-b-xl justify-center items-center"
>
<SvgNextcloud
class="app-demo"
:class="nextcloudClass"
title="nextcloud.domain.com"
/>
<SvgJellyfin
class="app-demo"
:class="jellyfinClass"
title="jellyfin.domain.com"
/>
</div>
</div>
</section>
</template>

View File

@@ -5,7 +5,9 @@
<b>multiple</b> docker-compose.yml <b>configurations</b>.
</p>
<div class="my-20">
<h2 class="title">Features</h2>
<h2 class="title">
Features
</h2>
<ul class="text-xl md:text-2xl p-6 [&>li]:leading-10 [&>li]:md:pb-6">
<li>🔒 ssl certification</li>
<li>🌐 sub-domain & multi-domain directly in docker-compose file</li>

View File

@@ -1,24 +1,14 @@
<script>
import ClipBoard from 'Svg/clipboard.vue'
export default {
components: { ClipBoard },
data: () => {
return {
isClicked: false,
}
},
methods: {
copyToClipBoard() {
navigator.clipboard
.writeText('curl -sL get.pegaz.io | sudo bash')
.then(() => {
this.isClicked = true
setTimeout(() => {
this.isClicked = false
}, 600)
})
},
},
<script setup lang="ts">
const isClicked = ref(false)
const copyToClipBoard = () => {
navigator.clipboard
.writeText('curl -sL get.pegaz.io | sudo bash')
.then(() => {
isClicked.value = true
setTimeout(() => {
isClicked.value = false
}, 600)
})
}
</script>
@@ -32,10 +22,10 @@ export default {
get started
</a>
<div
class="font-mono bg-neutral-900 text-neutral-50 text-base rounded-xl flex justify-between items-center pl-3 pr-4 py-4 sm:ml-4 border border-transparent text-base shadow-primary-700 relative"
class="font-mono bg-neutral-900 text-neutral-50 rounded-xl flex justify-between items-center pl-3 pr-4 py-4 sm:ml-4 border border-transparent text-base shadow-primary-700 relative"
>
<span class="select-all"> curl -sL get.pegaz.io | sudo bash </span>
<ClipBoard
<SvgClipboard
class="ml-3 cursor-pointer"
:class="{ 'animate-ping': isClicked }"
@click="copyToClipBoard"

View File

@@ -1,21 +1,21 @@
<script setup>
import Logo from 'Svg/logo.vue'
</script>
<template>
<section>
<div class="flex justify-center -ml-24 animate-slide">
<div class="py-4 mr-3 animate-fadeout opacity-0">
<div class="bg-gray-400 h-px w-16 my-3 block"></div>
<div class="bg-gray-400 h-px w-16 my-3 translate-x-3 block"></div>
<div class="bg-gray-400 h-px w-16 my-3 translate-x-1 block"></div>
<div class="bg-gray-400 h-px w-16 my-3 translate-x-6 block"></div>
<div class="bg-gray-400 h-px w-16 my-3 block" />
<div class="bg-gray-400 h-px w-16 my-3 translate-x-3 block" />
<div class="bg-gray-400 h-px w-16 my-3 translate-x-1 block" />
<div class="bg-gray-400 h-px w-16 my-3 translate-x-6 block" />
</div>
<Logo />
<SvgPegaz />
</div>
<div class="text-center py-4">
<h1 class="text-5xl font-bold leading-relaxed">Pegaz.io</h1>
<h2 class="text-3xl text-center">docker-compose cli superset</h2>
<h1 class="text-5xl font-bold leading-relaxed">
Pegaz.io
</h1>
<h2 class="text-3xl text-center">
docker-compose cli superset
</h2>
</div>
</section>
</template>

View File

@@ -1,10 +1,10 @@
<template>
<svg
id="screenshot-ebe7fc5d-5b94-11ed-963d-5f59412bd802"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="14.364"
xmlns="http://www.w3.org/2000/svg"
height="13.2"
id="screenshot-ebe7fc5d-5b94-11ed-963d-5f59412bd802"
viewBox="674.9 1469.9 14.364 13.2"
style="-webkit-print-color-adjust: exact"
fill="none"

View File

@@ -1,10 +1,10 @@
<template>
<svg
id="screenshot-39f85615-bf4c-80f1-8001-923fc255459e"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="17.2"
xmlns="http://www.w3.org/2000/svg"
height="17.2"
id="screenshot-39f85615-bf4c-80f1-8001-923fc255459e"
viewBox="572.9 1607.9 17.2 17.2"
style="-webkit-print-color-adjust: exact"
fill="none"

View File

@@ -1,10 +1,10 @@
<template>
<svg
id="screenshot-b97b5a92-5b4a-11ed-b852-87fca6c776a4"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="17.2"
xmlns="http://www.w3.org/2000/svg"
height="20.2"
id="screenshot-b97b5a92-5b4a-11ed-b852-87fca6c776a4"
viewBox="1033.9 280.9 17.2 20.2"
style="-webkit-print-color-adjust: exact"
fill="none"

View File

@@ -1,10 +1,10 @@
<template>
<svg
id="screenshot-8851a460-5b95-11ed-963d-5f59412bd802"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="19.2"
xmlns="http://www.w3.org/2000/svg"
height="17.2"
id="screenshot-8851a460-5b95-11ed-963d-5f59412bd802"
viewBox="186.9 1600.9 19.2 17.2"
style="-webkit-print-color-adjust: exact"
fill="none"

View File

@@ -1,10 +1,10 @@
<template>
<svg
id="screenshot-c9186fb0-5b95-11ed-963d-5f59412bd802"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="61"
xmlns="http://www.w3.org/2000/svg"
height="43"
id="screenshot-c9186fb0-5b95-11ed-963d-5f59412bd802"
viewBox="-0 -0 61 43"
style="-webkit-print-color-adjust: exact"
fill="none"

View File

@@ -1,8 +1,8 @@
<template>
<svg
id="screenshot-e1abaae4-8d9a-80ff-8001-956afa1f32eb"
width="44"
height="43"
id="screenshot-e1abaae4-8d9a-80ff-8001-956afa1f32eb"
viewBox="1281 -100 44 43"
style="-webkit-print-color-adjust: exact"
fill="none"
@@ -17,11 +17,11 @@
<g id="shape-e1abaae4-8d9a-80ff-8001-956afa1f32eb" style="fill: #000000">
<g id="fills-e1abaae4-8d9a-80ff-8001-956afa1f32eb" style="fill: #000000">
<path
id="path2"
fill-rule="evenodd"
rx="0"
ry="0"
d="M1303,-100C1290.845,-100,1281,-90.135,1281,-77.956C1281,-68.202,1287.297,-59.963,1296.043,-57.042C1297.143,-56.849,1297.555,-57.511,1297.555,-58.089C1297.555,-58.613,1297.528,-60.349,1297.528,-62.195C1292,-61.175,1290.57,-63.545,1290.13,-64.785C1289.883,-65.419,1288.81,-67.375,1287.875,-67.899C1287.105,-68.312,1286.005,-69.332,1287.847,-69.359C1289.58,-69.387,1290.817,-67.761,1291.23,-67.1C1293.21,-63.765,1296.373,-64.702,1297.637,-65.281C1297.83,-66.714,1298.407,-67.678,1299.04,-68.229C1294.145,-68.78,1289.03,-70.682,1289.03,-79.113C1289.03,-81.511,1289.883,-83.495,1291.285,-85.038C1291.065,-85.589,1290.295,-87.848,1291.505,-90.879C1291.505,-90.879,1293.347,-91.458,1297.555,-88.62C1299.315,-89.116,1301.185,-89.364,1303.055,-89.364C1304.925,-89.364,1306.795,-89.116,1308.555,-88.62C1312.762,-91.486,1314.605,-90.879,1314.605,-90.879C1315.815,-87.848,1315.045,-85.589,1314.825,-85.038C1316.228,-83.495,1317.08,-81.538,1317.08,-79.113C1317.08,-70.654,1311.938,-68.78,1307.043,-68.229C1307.84,-67.54,1308.528,-66.218,1308.528,-64.151C1308.528,-61.203,1308.5,-58.833,1308.5,-58.089C1308.5,-57.511,1308.913,-56.822,1310.012,-57.042C1318.968,-60.071,1324.998,-68.486,1325,-77.956C1325,-90.135,1315.155,-100,1303,-100ZZ"
id="path2"
style="fill: #000000"
/>
</g>

View File

@@ -0,0 +1,196 @@
<template>
<svg
id="svg190"
version="1.1"
width="393.39569"
height="393.39569"
viewBox="0 0 393.39569 393.39569"
sodipodi:docname="logo.svg"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
>
<defs
id="defs194"
>
<linearGradient
id="linearGradient13929"
inkscape:collect="always"
>
<stop
id="stop13925"
style="stop-color:#04865c;stop-opacity:1;"
offset="0"
/>
<stop
id="stop13927"
style="stop-color:#066245;stop-opacity:1;"
offset="1"
/>
</linearGradient>
<linearGradient
id="linearGradient13767"
inkscape:collect="always"
>
<stop
id="stop13763"
style="stop-color:#67ceaa;stop-opacity:1;"
offset="0"
/>
<stop
id="stop13765"
style="stop-color:#39b088;stop-opacity:0;"
offset="1"
/>
</linearGradient>
<linearGradient
id="linearGradient19707"
inkscape:collect="always"
>
<stop
id="stop19703"
style="stop-color:#067555;stop-opacity:1;"
offset="0"
/>
<stop
id="stop26611"
style="stop-color:#066548;stop-opacity:1;"
offset="0.5"
/>
<stop
id="stop19705"
style="stop-color:#06563b;stop-opacity:1;"
offset="1"
/>
</linearGradient>
<radialGradient
id="radialGradient19709"
inkscape:collect="always"
xlink:href="#linearGradient19707"
cx="258.2518"
cy="111.30856"
fx="258.2518"
fy="111.30856"
r="144.73241"
gradientTransform="matrix(1,0,0,0.26232525,0,82.109517)"
gradientUnits="userSpaceOnUse"
/>
<linearGradient
id="linearGradient13769"
inkscape:collect="always"
xlink:href="#linearGradient13767"
x1="227.9971"
y1="164.44801"
x2="199.6779"
y2="361.70694"
gradientUnits="userSpaceOnUse"
/>
<radialGradient
id="radialGradient13931"
inkscape:collect="always"
xlink:href="#linearGradient13929"
cx="230.15836"
cy="47.509117"
fx="230.15836"
fy="47.509117"
r="57.429787"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.6711718,0.06259482,-0.02693208,0.28877884,81.31173,70.298382)"
/>
</defs>
<g
id="g196"
inkscape:groupmode="layer"
inkscape:label="Image"
transform="translate(-22.985779,-1.2769928)"
>
<circle
id="path18800"
style="fill:#10b982;fill-opacity:1;stroke:none;stroke-width:1.47767"
cx="219.68362"
cy="197.97484"
r="196.69785"
/>
<circle
id="path564"
style="fill:url(#radialGradient13931);fill-opacity:1;stroke:none;stroke-width:1.9172;stroke-dasharray:none"
cx="229.63922"
cy="130.58992"
r="57.429787"
/>
<path
id="path1435"
style="display:inline;fill:url(#linearGradient13769);fill-opacity:1;stroke:none;stroke-width:23.0629;stroke-dasharray:none"
d="M 154.83569,140.29296 87.837483,323.35279 312.196,348.95574 292.17195,161.84683 Z"
sodipodi:nodetypes="ccccc"
/>
<ellipse
id="path510"
style="fill:url(#radialGradient19709);fill-opacity:1;stroke:none;stroke-width:3.08472;stroke-dasharray:none"
cx="258.2518"
cy="111.30856"
rx="144.73241"
ry="37.966965"
transform="matrix(0.98785347,0.15538828,-0.26474655,0.96431803,0,0)"
/>
<path
id="path510-5-3-5"
style="fill:#5cc9a4;fill-opacity:1;stroke-width:1.59418"
transform="matrix(0.98803718,0.15421583,-0.26666281,0.96378989,0,0)"
d="m 336.80361,138.97559 a 75.060692,19.552454 0 0 1 -75.06069,19.55245 75.060692,19.552454 0 0 1 -75.06069,-19.55245 75.060692,19.552454 0 0 1 75.06069,-19.55246 75.060692,19.552454 0 0 1 75.06069,19.55246 z"
/>
<ellipse
id="path510-5-3"
style="fill:#85e6bd;fill-opacity:1;stroke:none;stroke-width:1.39712;stroke-dasharray:none"
cx="261.77979"
cy="142.58211"
rx="66.810738"
ry="16.871904"
transform="matrix(0.98881768,0.14912947,-0.27528102,0.9613638,0,0)"
/>
<ellipse
id="path510-5"
style="fill:#5cc9a4;fill-opacity:1;stroke:none;stroke-width:1.04102;stroke-dasharray:none"
cx="261.53564"
cy="134.85057"
rx="48.843674"
ry="12.812929"
transform="matrix(0.98785347,0.15538828,-0.26474655,0.96431803,0,0)"
/>
<circle
id="path564-3"
style="fill:#c7e9dd;fill-opacity:1;stroke:none;stroke-width:0.324698;stroke-dasharray:none"
cx="227.53282"
cy="126.47501"
r="9.7263527"
/>
<circle
id="path564-3-6"
style="fill:#c7e9dd;fill-opacity:1;stroke:none;stroke-width:0.222375;stroke-dasharray:none"
cx="275.15833"
cy="137.97833"
r="6.6612716"
/>
<circle
id="path564-3-6-7"
style="fill:#c7e9dd;fill-opacity:1;stroke:none;stroke-width:0.222375;stroke-dasharray:none"
cx="179.57893"
cy="123.66492"
r="6.6612716"
/>
<path
id="path16760"
style="fill:#5cc9a4;fill-opacity:1;stroke:none"
d="m 144.8295,167.73835 2.96312,-6.07927 c 0,0 9.17615,9.8631 4.31124,9.21855 -4.86492,-0.64455 -4.86492,-0.64455 -4.86492,-0.64455 l -0.0627,0.32937 z"
/>
<path
id="path17989"
style="fill:#5cc9a4;fill-opacity:1;stroke:none"
d="m 295.86423,184.55616 -1.11687,9.82274 -3.40985,-1.3222 -0.43522,-8.31425 z"
/>
</g>
</svg>
</template>

View File

@@ -10,9 +10,9 @@
>
<defs>
<linearGradient
id="b"
gradientUnits="userSpaceOnUse"
y1="294.65"
id="b"
xlink:href="#a"
x1="37.362"
y2="279.148"

View File

@@ -1,10 +1,10 @@
<template>
<svg
id="screenshot-8851a463-5b95-11ed-963d-5f59412bd802"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="17"
xmlns="http://www.w3.org/2000/svg"
height="21.069"
id="screenshot-8851a463-5b95-11ed-963d-5f59412bd802"
viewBox="258 1606 17 21.069"
style="-webkit-print-color-adjust: exact"
fill="none"

View File

@@ -1,10 +1,10 @@
<template>
<svg
id="screenshot-ebe7fc64-5b94-11ed-963d-5f59412bd802"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="38.197"
xmlns="http://www.w3.org/2000/svg"
height="42.988"
id="screenshot-ebe7fc64-5b94-11ed-963d-5f59412bd802"
viewBox="678 1826 38.197 42.988"
style="-webkit-print-color-adjust: exact"
fill="none"

View File

@@ -3,9 +3,9 @@ export default {
props: {
terminalContent: {
required: true,
type: String,
},
},
type: String
}
}
}
</script>
@@ -14,19 +14,19 @@ export default {
class="bg-slate-900 flex-row rounded-xl w-4/5 md:w-96 max-w-full md:min-w-max h-56 md:z-10 -mb-8 md:-mb-0"
>
<div class="p-3 flex justify-between w-20">
<div class="bg-green-400 h-4 w-4 r-1 rounded-full"></div>
<div class="bg-yellow-300 h-4 w-4 r-1 rounded-full"></div>
<div class="bg-red-600 h-4 w-4 r-1 rounded-full"></div>
<div class="bg-green-400 h-4 w-4 r-1 rounded-full" />
<div class="bg-yellow-300 h-4 w-4 r-1 rounded-full" />
<div class="bg-red-600 h-4 w-4 r-1 rounded-full" />
</div>
<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"
>
{{ terminalContent
}}<span
{{ terminalContent }}
<span
ref="terminal"
class="w-2 h-4 bg-white inline-block relative"
style="margin-bottom: -2px"
ref="terminal"
/>
</code>
</div>

136
coverage/add.vue.html Normal file
View File

@@ -0,0 +1,136 @@
<!doctype html>
<html lang="en">
<head>
<title>Code coverage report for add.vue</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="prettify.css" />
<link rel="stylesheet" href="base.css" />
<link rel="shortcut icon" type="image/x-icon" href="favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type='text/css'>
.coverage-summary .sorter {
background-image: url(sort-arrow-sprite.png);
}
</style>
</head>
<body>
<div class='wrapper'>
<div class='pad1'>
<h1><a href="index.html">All files</a> add.vue</h1>
<div class='clearfix'>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Statements</span>
<span class='fraction'>0/17</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Branches</span>
<span class='fraction'>0/1</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Functions</span>
<span class='fraction'>0/1</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Lines</span>
<span class='fraction'>0/17</span>
</div>
</div>
<p class="quiet">
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
</p>
<template id="filterTemplate">
<div class="quiet">
Filter:
<input oninput="onInput()" type="search" id="fileSearch">
</div>
</template>
</div>
<div class='status-line low'></div>
<pre><table class="coverage">
<tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
<a name='L2'></a><a href='#L2'>2</a>
<a name='L3'></a><a href='#L3'>3</a>
<a name='L4'></a><a href='#L4'>4</a>
<a name='L5'></a><a href='#L5'>5</a>
<a name='L6'></a><a href='#L6'>6</a>
<a name='L7'></a><a href='#L7'>7</a>
<a name='L8'></a><a href='#L8'>8</a>
<a name='L9'></a><a href='#L9'>9</a>
<a name='L10'></a><a href='#L10'>10</a>
<a name='L11'></a><a href='#L11'>11</a>
<a name='L12'></a><a href='#L12'>12</a>
<a name='L13'></a><a href='#L13'>13</a>
<a name='L14'></a><a href='#L14'>14</a>
<a name='L15'></a><a href='#L15'>15</a>
<a name='L16'></a><a href='#L16'>16</a>
<a name='L17'></a><a href='#L17'>17</a>
<a name='L18'></a><a href='#L18'>18</a></td><td class="line-coverage quiet"><span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js"><span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" ><span class="branch-0 cbranch-no" title="branch not covered" >&lt;template&gt;</span></span></span>
<span class="cstat-no" title="statement not covered" > &lt;form @submit.prevent="addTodoAndClear()"&gt;</span>
<span class="cstat-no" title="statement not covered" > &lt;input v-model="newTodo" type="text" class="p-4 w-full" placeholder="write a new todo ..."&gt;</span>
<span class="cstat-no" title="statement not covered" > &lt;/form&gt;</span>
<span class="cstat-no" title="statement not covered" >&lt;/template&gt;</span>
<span class="cstat-no" title="statement not covered" ></span>
<span class="cstat-no" title="statement not covered" >&lt;script lang="ts" setup&gt;</span>
<span class="cstat-no" title="statement not covered" >import { useTodoStore } from '~~/stores/TodoStore'</span>
<span class="cstat-no" title="statement not covered" >const store = useTodoStore()</span>
<span class="cstat-no" title="statement not covered" >const newTodo = ref('')</span>
<span class="cstat-no" title="statement not covered" >const addTodoAndClear = () =&gt; {</span>
<span class="cstat-no" title="statement not covered" > if (newTodo.value.length !== 0) {</span>
<span class="cstat-no" title="statement not covered" > store.addTodo(newTodo.value)</span>
<span class="cstat-no" title="statement not covered" > newTodo.value = ''</span>
<span class="cstat-no" title="statement not covered" > }</span>
<span class="cstat-no" title="statement not covered" >}</span>
<span class="cstat-no" title="statement not covered" >&lt;/script&gt;</span>
&nbsp;</pre></td></tr></table></pre>
<div class='push'></div><!-- for sticky footer -->
</div><!-- /wrapper -->
<div class='footer quiet pad2 space-top1 center small'>
Code coverage generated by
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
at 2023-03-01T07:48:52.713Z
</div>
<script src="prettify.js"></script>
<script>
window.onload = function () {
prettyPrint();
};
</script>
<script src="sorter.js"></script>
<script src="block-navigation.js"></script>
</body>
</html>

224
coverage/base.css Normal file
View File

@@ -0,0 +1,224 @@
body, html {
margin:0; padding: 0;
height: 100%;
}
body {
font-family: Helvetica Neue, Helvetica, Arial;
font-size: 14px;
color:#333;
}
.small { font-size: 12px; }
*, *:after, *:before {
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
box-sizing:border-box;
}
h1 { font-size: 20px; margin: 0;}
h2 { font-size: 14px; }
pre {
font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace;
margin: 0;
padding: 0;
-moz-tab-size: 2;
-o-tab-size: 2;
tab-size: 2;
}
a { color:#0074D9; text-decoration:none; }
a:hover { text-decoration:underline; }
.strong { font-weight: bold; }
.space-top1 { padding: 10px 0 0 0; }
.pad2y { padding: 20px 0; }
.pad1y { padding: 10px 0; }
.pad2x { padding: 0 20px; }
.pad2 { padding: 20px; }
.pad1 { padding: 10px; }
.space-left2 { padding-left:55px; }
.space-right2 { padding-right:20px; }
.center { text-align:center; }
.clearfix { display:block; }
.clearfix:after {
content:'';
display:block;
height:0;
clear:both;
visibility:hidden;
}
.fl { float: left; }
@media only screen and (max-width:640px) {
.col3 { width:100%; max-width:100%; }
.hide-mobile { display:none!important; }
}
.quiet {
color: #7f7f7f;
color: rgba(0,0,0,0.5);
}
.quiet a { opacity: 0.7; }
.fraction {
font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
font-size: 10px;
color: #555;
background: #E8E8E8;
padding: 4px 5px;
border-radius: 3px;
vertical-align: middle;
}
div.path a:link, div.path a:visited { color: #333; }
table.coverage {
border-collapse: collapse;
margin: 10px 0 0 0;
padding: 0;
}
table.coverage td {
margin: 0;
padding: 0;
vertical-align: top;
}
table.coverage td.line-count {
text-align: right;
padding: 0 5px 0 20px;
}
table.coverage td.line-coverage {
text-align: right;
padding-right: 10px;
min-width:20px;
}
table.coverage td span.cline-any {
display: inline-block;
padding: 0 5px;
width: 100%;
}
.missing-if-branch {
display: inline-block;
margin-right: 5px;
border-radius: 3px;
position: relative;
padding: 0 4px;
background: #333;
color: yellow;
}
.skip-if-branch {
display: none;
margin-right: 10px;
position: relative;
padding: 0 4px;
background: #ccc;
color: white;
}
.missing-if-branch .typ, .skip-if-branch .typ {
color: inherit !important;
}
.coverage-summary {
border-collapse: collapse;
width: 100%;
}
.coverage-summary tr { border-bottom: 1px solid #bbb; }
.keyline-all { border: 1px solid #ddd; }
.coverage-summary td, .coverage-summary th { padding: 10px; }
.coverage-summary tbody { border: 1px solid #bbb; }
.coverage-summary td { border-right: 1px solid #bbb; }
.coverage-summary td:last-child { border-right: none; }
.coverage-summary th {
text-align: left;
font-weight: normal;
white-space: nowrap;
}
.coverage-summary th.file { border-right: none !important; }
.coverage-summary th.pct { }
.coverage-summary th.pic,
.coverage-summary th.abs,
.coverage-summary td.pct,
.coverage-summary td.abs { text-align: right; }
.coverage-summary td.file { white-space: nowrap; }
.coverage-summary td.pic { min-width: 120px !important; }
.coverage-summary tfoot td { }
.coverage-summary .sorter {
height: 10px;
width: 7px;
display: inline-block;
margin-left: 0.5em;
background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent;
}
.coverage-summary .sorted .sorter {
background-position: 0 -20px;
}
.coverage-summary .sorted-desc .sorter {
background-position: 0 -10px;
}
.status-line { height: 10px; }
/* yellow */
.cbranch-no { background: yellow !important; color: #111; }
/* dark red */
.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 }
.low .chart { border:1px solid #C21F39 }
.highlighted,
.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{
background: #C21F39 !important;
}
/* medium red */
.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE }
/* light red */
.low, .cline-no { background:#FCE1E5 }
/* light green */
.high, .cline-yes { background:rgb(230,245,208) }
/* medium green */
.cstat-yes { background:rgb(161,215,106) }
/* dark green */
.status-line.high, .high .cover-fill { background:rgb(77,146,33) }
.high .chart { border:1px solid rgb(77,146,33) }
/* dark yellow (gold) */
.status-line.medium, .medium .cover-fill { background: #f9cd0b; }
.medium .chart { border:1px solid #f9cd0b; }
/* light yellow */
.medium { background: #fff4c2; }
.cstat-skip { background: #ddd; color: #111; }
.fstat-skip { background: #ddd; color: #111 !important; }
.cbranch-skip { background: #ddd !important; color: #111; }
span.cline-neutral { background: #eaeaea; }
.coverage-summary td.empty {
opacity: .5;
padding-top: 4px;
padding-bottom: 4px;
line-height: 1;
color: #888;
}
.cover-fill, .cover-empty {
display:inline-block;
height: 12px;
}
.chart {
line-height: 0;
}
.cover-empty {
background: white;
}
.cover-full {
border-right: none !important;
}
pre.prettyprint {
border: none !important;
padding: 0 !important;
margin: 0 !important;
}
.com { color: #999 !important; }
.ignore-none { color: #999; font-weight: normal; }
.wrapper {
min-height: 100%;
height: auto !important;
height: 100%;
margin: 0 auto -48px;
}
.footer, .push {
height: 48px;
}

View File

@@ -0,0 +1,87 @@
/* eslint-disable */
var jumpToCode = (function init() {
// Classes of code we would like to highlight in the file view
var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no'];
// Elements to highlight in the file listing view
var fileListingElements = ['td.pct.low'];
// We don't want to select elements that are direct descendants of another match
var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > `
// Selecter that finds elements on the page to which we can jump
var selector =
fileListingElements.join(', ') +
', ' +
notSelector +
missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b`
// The NodeList of matching elements
var missingCoverageElements = document.querySelectorAll(selector);
var currentIndex;
function toggleClass(index) {
missingCoverageElements
.item(currentIndex)
.classList.remove('highlighted');
missingCoverageElements.item(index).classList.add('highlighted');
}
function makeCurrent(index) {
toggleClass(index);
currentIndex = index;
missingCoverageElements.item(index).scrollIntoView({
behavior: 'smooth',
block: 'center',
inline: 'center'
});
}
function goToPrevious() {
var nextIndex = 0;
if (typeof currentIndex !== 'number' || currentIndex === 0) {
nextIndex = missingCoverageElements.length - 1;
} else if (missingCoverageElements.length > 1) {
nextIndex = currentIndex - 1;
}
makeCurrent(nextIndex);
}
function goToNext() {
var nextIndex = 0;
if (
typeof currentIndex === 'number' &&
currentIndex < missingCoverageElements.length - 1
) {
nextIndex = currentIndex + 1;
}
makeCurrent(nextIndex);
}
return function jump(event) {
if (
document.getElementById('fileSearch') === document.activeElement &&
document.activeElement != null
) {
// if we're currently focused on the search input, we don't want to navigate
return;
}
switch (event.which) {
case 78: // n
case 74: // j
goToNext();
break;
case 66: // b
case 75: // k
case 80: // p
goToPrevious();
break;
}
};
})();
window.addEventListener('keydown', jumpToCode);

108
coverage/clover.xml Normal file
View File

@@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8"?>
<coverage generated="1677656932716" clover="3.2.0">
<project timestamp="1677656932717" name="All files">
<metrics statements="93" coveredstatements="0" conditionals="3" coveredconditionals="0" methods="3" coveredmethods="0" elements="99" coveredelements="0" complexity="0" loc="93" ncloc="93" packages="1" files="3" classes="3"/>
<file name="add.vue" path="/home/valere/sidebase/components/todo/add.vue">
<metrics statements="17" coveredstatements="0" conditionals="1" coveredconditionals="0" methods="1" coveredmethods="0"/>
<line num="1" count="0" type="cond" truecount="0" falsecount="1"/>
<line num="2" count="0" type="stmt"/>
<line num="3" count="0" type="stmt"/>
<line num="4" count="0" type="stmt"/>
<line num="5" count="0" type="stmt"/>
<line num="6" count="0" type="stmt"/>
<line num="7" count="0" type="stmt"/>
<line num="8" count="0" type="stmt"/>
<line num="9" count="0" type="stmt"/>
<line num="10" count="0" type="stmt"/>
<line num="11" count="0" type="stmt"/>
<line num="12" count="0" type="stmt"/>
<line num="13" count="0" type="stmt"/>
<line num="14" count="0" type="stmt"/>
<line num="15" count="0" type="stmt"/>
<line num="16" count="0" type="stmt"/>
<line num="17" count="0" type="stmt"/>
</file>
<file name="list.vue" path="/home/valere/sidebase/components/todo/list.vue">
<metrics statements="13" coveredstatements="0" conditionals="1" coveredconditionals="0" methods="1" coveredmethods="0"/>
<line num="1" count="0" type="cond" truecount="0" falsecount="1"/>
<line num="2" count="0" type="stmt"/>
<line num="3" count="0" type="stmt"/>
<line num="4" count="0" type="stmt"/>
<line num="5" count="0" type="stmt"/>
<line num="6" count="0" type="stmt"/>
<line num="7" count="0" type="stmt"/>
<line num="8" count="0" type="stmt"/>
<line num="9" count="0" type="stmt"/>
<line num="10" count="0" type="stmt"/>
<line num="11" count="0" type="stmt"/>
<line num="12" count="0" type="stmt"/>
<line num="13" count="0" type="stmt"/>
</file>
<file name="row.vue" path="/home/valere/sidebase/components/todo/row.vue">
<metrics statements="63" coveredstatements="0" conditionals="1" coveredconditionals="0" methods="1" coveredmethods="0"/>
<line num="1" count="0" type="cond" truecount="0" falsecount="1"/>
<line num="2" count="0" type="stmt"/>
<line num="3" count="0" type="stmt"/>
<line num="4" count="0" type="stmt"/>
<line num="5" count="0" type="stmt"/>
<line num="6" count="0" type="stmt"/>
<line num="7" count="0" type="stmt"/>
<line num="8" count="0" type="stmt"/>
<line num="9" count="0" type="stmt"/>
<line num="10" count="0" type="stmt"/>
<line num="11" count="0" type="stmt"/>
<line num="12" count="0" type="stmt"/>
<line num="13" count="0" type="stmt"/>
<line num="14" count="0" type="stmt"/>
<line num="15" count="0" type="stmt"/>
<line num="16" count="0" type="stmt"/>
<line num="17" count="0" type="stmt"/>
<line num="18" count="0" type="stmt"/>
<line num="19" count="0" type="stmt"/>
<line num="20" count="0" type="stmt"/>
<line num="21" count="0" type="stmt"/>
<line num="22" count="0" type="stmt"/>
<line num="23" count="0" type="stmt"/>
<line num="24" count="0" type="stmt"/>
<line num="25" count="0" type="stmt"/>
<line num="26" count="0" type="stmt"/>
<line num="27" count="0" type="stmt"/>
<line num="28" count="0" type="stmt"/>
<line num="29" count="0" type="stmt"/>
<line num="30" count="0" type="stmt"/>
<line num="31" count="0" type="stmt"/>
<line num="32" count="0" type="stmt"/>
<line num="33" count="0" type="stmt"/>
<line num="34" count="0" type="stmt"/>
<line num="35" count="0" type="stmt"/>
<line num="36" count="0" type="stmt"/>
<line num="37" count="0" type="stmt"/>
<line num="38" count="0" type="stmt"/>
<line num="39" count="0" type="stmt"/>
<line num="40" count="0" type="stmt"/>
<line num="41" count="0" type="stmt"/>
<line num="42" count="0" type="stmt"/>
<line num="43" count="0" type="stmt"/>
<line num="44" count="0" type="stmt"/>
<line num="45" count="0" type="stmt"/>
<line num="46" count="0" type="stmt"/>
<line num="47" count="0" type="stmt"/>
<line num="48" count="0" type="stmt"/>
<line num="49" count="0" type="stmt"/>
<line num="50" count="0" type="stmt"/>
<line num="51" count="0" type="stmt"/>
<line num="52" count="0" type="stmt"/>
<line num="53" count="0" type="stmt"/>
<line num="54" count="0" type="stmt"/>
<line num="55" count="0" type="stmt"/>
<line num="56" count="0" type="stmt"/>
<line num="57" count="0" type="stmt"/>
<line num="58" count="0" type="stmt"/>
<line num="59" count="0" type="stmt"/>
<line num="60" count="0" type="stmt"/>
<line num="61" count="0" type="stmt"/>
<line num="62" count="0" type="stmt"/>
<line num="63" count="0" type="stmt"/>
</file>
</project>
</coverage>

File diff suppressed because one or more lines are too long

BIN
coverage/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

146
coverage/index.html Normal file
View File

@@ -0,0 +1,146 @@
<!doctype html>
<html lang="en">
<head>
<title>Code coverage report for All files</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="prettify.css" />
<link rel="stylesheet" href="base.css" />
<link rel="shortcut icon" type="image/x-icon" href="favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type='text/css'>
.coverage-summary .sorter {
background-image: url(sort-arrow-sprite.png);
}
</style>
</head>
<body>
<div class='wrapper'>
<div class='pad1'>
<h1>All files</h1>
<div class='clearfix'>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Statements</span>
<span class='fraction'>0/93</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Branches</span>
<span class='fraction'>0/3</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Functions</span>
<span class='fraction'>0/3</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Lines</span>
<span class='fraction'>0/93</span>
</div>
</div>
<p class="quiet">
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
</p>
<template id="filterTemplate">
<div class="quiet">
Filter:
<input oninput="onInput()" type="search" id="fileSearch">
</div>
</template>
</div>
<div class='status-line low'></div>
<div class="pad1">
<table class="coverage-summary">
<thead>
<tr>
<th data-col="file" data-fmt="html" data-html="true" class="file">File</th>
<th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th>
<th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th>
<th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th>
<th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th>
<th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th>
<th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th>
</tr>
</thead>
<tbody><tr>
<td class="file low" data-value="add.vue"><a href="add.vue.html">add.vue</a></td>
<td data-value="0" class="pic low">
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="17" class="abs low">0/17</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="1" class="abs low">0/1</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="1" class="abs low">0/1</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="17" class="abs low">0/17</td>
</tr>
<tr>
<td class="file low" data-value="list.vue"><a href="list.vue.html">list.vue</a></td>
<td data-value="0" class="pic low">
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="13" class="abs low">0/13</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="1" class="abs low">0/1</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="1" class="abs low">0/1</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="13" class="abs low">0/13</td>
</tr>
<tr>
<td class="file low" data-value="row.vue"><a href="row.vue.html">row.vue</a></td>
<td data-value="0" class="pic low">
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="63" class="abs low">0/63</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="1" class="abs low">0/1</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="1" class="abs low">0/1</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="63" class="abs low">0/63</td>
</tr>
</tbody>
</table>
</div>
<div class='push'></div><!-- for sticky footer -->
</div><!-- /wrapper -->
<div class='footer quiet pad2 space-top1 center small'>
Code coverage generated by
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
at 2023-03-01T07:48:52.713Z
</div>
<script src="prettify.js"></script>
<script>
window.onload = function () {
prettyPrint();
};
</script>
<script src="sorter.js"></script>
<script src="block-navigation.js"></script>
</body>
</html>

124
coverage/list.vue.html Normal file
View File

@@ -0,0 +1,124 @@
<!doctype html>
<html lang="en">
<head>
<title>Code coverage report for list.vue</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="prettify.css" />
<link rel="stylesheet" href="base.css" />
<link rel="shortcut icon" type="image/x-icon" href="favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type='text/css'>
.coverage-summary .sorter {
background-image: url(sort-arrow-sprite.png);
}
</style>
</head>
<body>
<div class='wrapper'>
<div class='pad1'>
<h1><a href="index.html">All files</a> list.vue</h1>
<div class='clearfix'>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Statements</span>
<span class='fraction'>0/13</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Branches</span>
<span class='fraction'>0/1</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Functions</span>
<span class='fraction'>0/1</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Lines</span>
<span class='fraction'>0/13</span>
</div>
</div>
<p class="quiet">
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
</p>
<template id="filterTemplate">
<div class="quiet">
Filter:
<input oninput="onInput()" type="search" id="fileSearch">
</div>
</template>
</div>
<div class='status-line low'></div>
<pre><table class="coverage">
<tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
<a name='L2'></a><a href='#L2'>2</a>
<a name='L3'></a><a href='#L3'>3</a>
<a name='L4'></a><a href='#L4'>4</a>
<a name='L5'></a><a href='#L5'>5</a>
<a name='L6'></a><a href='#L6'>6</a>
<a name='L7'></a><a href='#L7'>7</a>
<a name='L8'></a><a href='#L8'>8</a>
<a name='L9'></a><a href='#L9'>9</a>
<a name='L10'></a><a href='#L10'>10</a>
<a name='L11'></a><a href='#L11'>11</a>
<a name='L12'></a><a href='#L12'>12</a>
<a name='L13'></a><a href='#L13'>13</a>
<a name='L14'></a><a href='#L14'>14</a></td><td class="line-coverage quiet"><span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js"><span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" ><span class="branch-0 cbranch-no" title="branch not covered" >&lt;template&gt;</span></span></span>
<span class="cstat-no" title="statement not covered" > &lt;section class="h-screen w-screen justify-center items-center flex"&gt;</span>
<span class="cstat-no" title="statement not covered" > &lt;ul class="bg-gray-100 flex-row border-2 w-10/12 md:w-5/6 lg:w-1/2"&gt;</span>
<span class="cstat-no" title="statement not covered" > &lt;TodoAdd /&gt;</span>
<span class="cstat-no" title="statement not covered" > &lt;TodoRow v-for="(todo, index) in store.getTodos" :key="index" :todo="todo" /&gt;</span>
<span class="cstat-no" title="statement not covered" > &lt;/ul&gt;</span>
<span class="cstat-no" title="statement not covered" > &lt;/section&gt;</span>
<span class="cstat-no" title="statement not covered" >&lt;/template&gt;</span>
<span class="cstat-no" title="statement not covered" ></span>
<span class="cstat-no" title="statement not covered" >&lt;script lang="ts" setup&gt;</span>
<span class="cstat-no" title="statement not covered" >import { useTodoStore } from '~~/stores/TodoStore'</span>
<span class="cstat-no" title="statement not covered" >const store = useTodoStore()</span>
<span class="cstat-no" title="statement not covered" >&lt;/script&gt;</span>
&nbsp;</pre></td></tr></table></pre>
<div class='push'></div><!-- for sticky footer -->
</div><!-- /wrapper -->
<div class='footer quiet pad2 space-top1 center small'>
Code coverage generated by
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
at 2023-03-01T07:48:52.713Z
</div>
<script src="prettify.js"></script>
<script>
window.onload = function () {
prettyPrint();
};
</script>
<script src="sorter.js"></script>
<script src="block-navigation.js"></script>
</body>
</html>

1
coverage/prettify.css Normal file
View File

@@ -0,0 +1 @@
.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}

2
coverage/prettify.js Normal file

File diff suppressed because one or more lines are too long

274
coverage/row.vue.html Normal file
View File

@@ -0,0 +1,274 @@
<!doctype html>
<html lang="en">
<head>
<title>Code coverage report for row.vue</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="prettify.css" />
<link rel="stylesheet" href="base.css" />
<link rel="shortcut icon" type="image/x-icon" href="favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type='text/css'>
.coverage-summary .sorter {
background-image: url(sort-arrow-sprite.png);
}
</style>
</head>
<body>
<div class='wrapper'>
<div class='pad1'>
<h1><a href="index.html">All files</a> row.vue</h1>
<div class='clearfix'>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Statements</span>
<span class='fraction'>0/63</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Branches</span>
<span class='fraction'>0/1</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Functions</span>
<span class='fraction'>0/1</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Lines</span>
<span class='fraction'>0/63</span>
</div>
</div>
<p class="quiet">
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
</p>
<template id="filterTemplate">
<div class="quiet">
Filter:
<input oninput="onInput()" type="search" id="fileSearch">
</div>
</template>
</div>
<div class='status-line low'></div>
<pre><table class="coverage">
<tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
<a name='L2'></a><a href='#L2'>2</a>
<a name='L3'></a><a href='#L3'>3</a>
<a name='L4'></a><a href='#L4'>4</a>
<a name='L5'></a><a href='#L5'>5</a>
<a name='L6'></a><a href='#L6'>6</a>
<a name='L7'></a><a href='#L7'>7</a>
<a name='L8'></a><a href='#L8'>8</a>
<a name='L9'></a><a href='#L9'>9</a>
<a name='L10'></a><a href='#L10'>10</a>
<a name='L11'></a><a href='#L11'>11</a>
<a name='L12'></a><a href='#L12'>12</a>
<a name='L13'></a><a href='#L13'>13</a>
<a name='L14'></a><a href='#L14'>14</a>
<a name='L15'></a><a href='#L15'>15</a>
<a name='L16'></a><a href='#L16'>16</a>
<a name='L17'></a><a href='#L17'>17</a>
<a name='L18'></a><a href='#L18'>18</a>
<a name='L19'></a><a href='#L19'>19</a>
<a name='L20'></a><a href='#L20'>20</a>
<a name='L21'></a><a href='#L21'>21</a>
<a name='L22'></a><a href='#L22'>22</a>
<a name='L23'></a><a href='#L23'>23</a>
<a name='L24'></a><a href='#L24'>24</a>
<a name='L25'></a><a href='#L25'>25</a>
<a name='L26'></a><a href='#L26'>26</a>
<a name='L27'></a><a href='#L27'>27</a>
<a name='L28'></a><a href='#L28'>28</a>
<a name='L29'></a><a href='#L29'>29</a>
<a name='L30'></a><a href='#L30'>30</a>
<a name='L31'></a><a href='#L31'>31</a>
<a name='L32'></a><a href='#L32'>32</a>
<a name='L33'></a><a href='#L33'>33</a>
<a name='L34'></a><a href='#L34'>34</a>
<a name='L35'></a><a href='#L35'>35</a>
<a name='L36'></a><a href='#L36'>36</a>
<a name='L37'></a><a href='#L37'>37</a>
<a name='L38'></a><a href='#L38'>38</a>
<a name='L39'></a><a href='#L39'>39</a>
<a name='L40'></a><a href='#L40'>40</a>
<a name='L41'></a><a href='#L41'>41</a>
<a name='L42'></a><a href='#L42'>42</a>
<a name='L43'></a><a href='#L43'>43</a>
<a name='L44'></a><a href='#L44'>44</a>
<a name='L45'></a><a href='#L45'>45</a>
<a name='L46'></a><a href='#L46'>46</a>
<a name='L47'></a><a href='#L47'>47</a>
<a name='L48'></a><a href='#L48'>48</a>
<a name='L49'></a><a href='#L49'>49</a>
<a name='L50'></a><a href='#L50'>50</a>
<a name='L51'></a><a href='#L51'>51</a>
<a name='L52'></a><a href='#L52'>52</a>
<a name='L53'></a><a href='#L53'>53</a>
<a name='L54'></a><a href='#L54'>54</a>
<a name='L55'></a><a href='#L55'>55</a>
<a name='L56'></a><a href='#L56'>56</a>
<a name='L57'></a><a href='#L57'>57</a>
<a name='L58'></a><a href='#L58'>58</a>
<a name='L59'></a><a href='#L59'>59</a>
<a name='L60'></a><a href='#L60'>60</a>
<a name='L61'></a><a href='#L61'>61</a>
<a name='L62'></a><a href='#L62'>62</a>
<a name='L63'></a><a href='#L63'>63</a>
<a name='L64'></a><a href='#L64'>64</a></td><td class="line-coverage quiet"><span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js"><span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" ><span class="branch-0 cbranch-no" title="branch not covered" >&lt;template v-if="isActive"&gt;</span></span></span>
<span class="cstat-no" title="statement not covered" > &lt;li class="hover:bg-green-100 px-8 py-4 flex justify-between"&gt;</span>
<span class="cstat-no" title="statement not covered" > &lt;NCheckbox</span>
<span class="cstat-no" title="statement not covered" > v-if="!editMode"</span>
<span class="cstat-no" title="statement not covered" > :checked="todo.isDone"</span>
<span class="cstat-no" title="statement not covered" > :label="todo.content"</span>
<span class="cstat-no" title="statement not covered" > size="large"</span>
<span class="cstat-no" title="statement not covered" > class="grow"</span>
<span class="cstat-no" title="statement not covered" > @update:checked="toggleDone(todo)"</span>
<span class="cstat-no" title="statement not covered" > /&gt;</span>
<span class="cstat-no" title="statement not covered" > &lt;input</span>
<span class="cstat-no" title="statement not covered" > v-if="editMode"</span>
<span class="cstat-no" title="statement not covered" > ref="editinput"</span>
<span class="cstat-no" title="statement not covered" > v-model="newContent"</span>
<span class="cstat-no" title="statement not covered" > class="grow px-2"</span>
<span class="cstat-no" title="statement not covered" > type="text"</span>
<span class="cstat-no" title="statement not covered" > @focusout="updateContent(todo)"</span>
<span class="cstat-no" title="statement not covered" > @keypress.enter="updateContent(todo)"</span>
<span class="cstat-no" title="statement not covered" > &gt;</span>
<span class="cstat-no" title="statement not covered" > &lt;div class="flex justify-around w-24"&gt;</span>
<span class="cstat-no" title="statement not covered" > &lt;NButton type="warning" @click="editTodo()"&gt;</span>
<span class="cstat-no" title="statement not covered" > 🖊️</span>
<span class="cstat-no" title="statement not covered" > &lt;/NButton&gt;</span>
<span class="cstat-no" title="statement not covered" > &lt;NButton type="error" @click="store.dropTodo(todo)"&gt;</span>
<span class="cstat-no" title="statement not covered" > 🗑</span>
<span class="cstat-no" title="statement not covered" > &lt;/NButton&gt;</span>
<span class="cstat-no" title="statement not covered" > &lt;/div&gt;</span>
<span class="cstat-no" title="statement not covered" > &lt;/li&gt;</span>
<span class="cstat-no" title="statement not covered" >&lt;/template&gt;</span>
<span class="cstat-no" title="statement not covered" ></span>
<span class="cstat-no" title="statement not covered" >&lt;script lang="ts" setup&gt;</span>
<span class="cstat-no" title="statement not covered" >import Todo from 'types/todo'</span>
<span class="cstat-no" title="statement not covered" >import { useTodoStore } from '~~/stores/TodoStore'</span>
<span class="cstat-no" title="statement not covered" >const store = useTodoStore()</span>
<span class="cstat-no" title="statement not covered" >interface Props {</span>
<span class="cstat-no" title="statement not covered" > todo: Todo</span>
<span class="cstat-no" title="statement not covered" >}</span>
<span class="cstat-no" title="statement not covered" >const props = defineProps&lt;Props&gt;()</span>
<span class="cstat-no" title="statement not covered" >const editMode = ref(false)</span>
<span class="cstat-no" title="statement not covered" >const newContent = ref(props.todo.content)</span>
<span class="cstat-no" title="statement not covered" >const editinput = ref&lt;HTMLInputElement&gt;()</span>
<span class="cstat-no" title="statement not covered" >const toggleDone = (todo: Todo) =&gt; {</span>
<span class="cstat-no" title="statement not covered" > todo.isDone = !todo.isDone</span>
<span class="cstat-no" title="statement not covered" > store.updateTodo(todo)</span>
<span class="cstat-no" title="statement not covered" >}</span>
<span class="cstat-no" title="statement not covered" >const editTodo = () =&gt; {</span>
<span class="cstat-no" title="statement not covered" > editMode.value = !editMode.value</span>
<span class="cstat-no" title="statement not covered" > nextTick(() =&gt; {</span>
<span class="cstat-no" title="statement not covered" > editinput.value?.focus()</span>
<span class="cstat-no" title="statement not covered" > })</span>
<span class="cstat-no" title="statement not covered" >}</span>
<span class="cstat-no" title="statement not covered" >const updateContent = (todo: Todo) =&gt; {</span>
<span class="cstat-no" title="statement not covered" > todo.content = newContent.value</span>
<span class="cstat-no" title="statement not covered" > store.updateTodo(todo)</span>
<span class="cstat-no" title="statement not covered" > editMode.value = !editMode</span>
<span class="cstat-no" title="statement not covered" >}</span>
<span class="cstat-no" title="statement not covered" >&lt;/script&gt;</span>
<span class="cstat-no" title="statement not covered" ></span>
<span class="cstat-no" title="statement not covered" >&lt;style&gt;</span>
<span class="cstat-no" title="statement not covered" >.n-checkbox--checked .n-checkbox__label {</span>
<span class="cstat-no" title="statement not covered" > @apply line-through opacity-50;</span>
<span class="cstat-no" title="statement not covered" >}</span>
<span class="cstat-no" title="statement not covered" >&lt;/style&gt;</span>
&nbsp;</pre></td></tr></table></pre>
<div class='push'></div><!-- for sticky footer -->
</div><!-- /wrapper -->
<div class='footer quiet pad2 space-top1 center small'>
Code coverage generated by
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
at 2023-03-01T07:48:52.713Z
</div>
<script src="prettify.js"></script>
<script>
window.onload = function () {
prettyPrint();
};
</script>
<script src="sorter.js"></script>
<script src="block-navigation.js"></script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

196
coverage/sorter.js Normal file
View File

@@ -0,0 +1,196 @@
/* eslint-disable */
var addSorting = (function() {
'use strict';
var cols,
currentSort = {
index: 0,
desc: false
};
// returns the summary table element
function getTable() {
return document.querySelector('.coverage-summary');
}
// returns the thead element of the summary table
function getTableHeader() {
return getTable().querySelector('thead tr');
}
// returns the tbody element of the summary table
function getTableBody() {
return getTable().querySelector('tbody');
}
// returns the th element for nth column
function getNthColumn(n) {
return getTableHeader().querySelectorAll('th')[n];
}
function onFilterInput() {
const searchValue = document.getElementById('fileSearch').value;
const rows = document.getElementsByTagName('tbody')[0].children;
for (let i = 0; i < rows.length; i++) {
const row = rows[i];
if (
row.textContent
.toLowerCase()
.includes(searchValue.toLowerCase())
) {
row.style.display = '';
} else {
row.style.display = 'none';
}
}
}
// loads the search box
function addSearchBox() {
var template = document.getElementById('filterTemplate');
var templateClone = template.content.cloneNode(true);
templateClone.getElementById('fileSearch').oninput = onFilterInput;
template.parentElement.appendChild(templateClone);
}
// loads all columns
function loadColumns() {
var colNodes = getTableHeader().querySelectorAll('th'),
colNode,
cols = [],
col,
i;
for (i = 0; i < colNodes.length; i += 1) {
colNode = colNodes[i];
col = {
key: colNode.getAttribute('data-col'),
sortable: !colNode.getAttribute('data-nosort'),
type: colNode.getAttribute('data-type') || 'string'
};
cols.push(col);
if (col.sortable) {
col.defaultDescSort = col.type === 'number';
colNode.innerHTML =
colNode.innerHTML + '<span class="sorter"></span>';
}
}
return cols;
}
// attaches a data attribute to every tr element with an object
// of data values keyed by column name
function loadRowData(tableRow) {
var tableCols = tableRow.querySelectorAll('td'),
colNode,
col,
data = {},
i,
val;
for (i = 0; i < tableCols.length; i += 1) {
colNode = tableCols[i];
col = cols[i];
val = colNode.getAttribute('data-value');
if (col.type === 'number') {
val = Number(val);
}
data[col.key] = val;
}
return data;
}
// loads all row data
function loadData() {
var rows = getTableBody().querySelectorAll('tr'),
i;
for (i = 0; i < rows.length; i += 1) {
rows[i].data = loadRowData(rows[i]);
}
}
// sorts the table using the data for the ith column
function sortByIndex(index, desc) {
var key = cols[index].key,
sorter = function(a, b) {
a = a.data[key];
b = b.data[key];
return a < b ? -1 : a > b ? 1 : 0;
},
finalSorter = sorter,
tableBody = document.querySelector('.coverage-summary tbody'),
rowNodes = tableBody.querySelectorAll('tr'),
rows = [],
i;
if (desc) {
finalSorter = function(a, b) {
return -1 * sorter(a, b);
};
}
for (i = 0; i < rowNodes.length; i += 1) {
rows.push(rowNodes[i]);
tableBody.removeChild(rowNodes[i]);
}
rows.sort(finalSorter);
for (i = 0; i < rows.length; i += 1) {
tableBody.appendChild(rows[i]);
}
}
// removes sort indicators for current column being sorted
function removeSortIndicators() {
var col = getNthColumn(currentSort.index),
cls = col.className;
cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, '');
col.className = cls;
}
// adds sort indicators for current column being sorted
function addSortIndicators() {
getNthColumn(currentSort.index).className += currentSort.desc
? ' sorted-desc'
: ' sorted';
}
// adds event listeners for all sorter widgets
function enableUI() {
var i,
el,
ithSorter = function ithSorter(i) {
var col = cols[i];
return function() {
var desc = col.defaultDescSort;
if (currentSort.index === i) {
desc = !currentSort.desc;
}
sortByIndex(i, desc);
removeSortIndicators();
currentSort.index = i;
currentSort.desc = desc;
addSortIndicators();
};
};
for (i = 0; i < cols.length; i += 1) {
if (cols[i].sortable) {
// add the click event handler on the th so users
// dont have to click on those tiny arrows
el = getNthColumn(i).querySelector('.sorter').parentElement;
if (el.addEventListener) {
el.addEventListener('click', ithSorter(i));
} else {
el.attachEvent('onclick', ithSorter(i));
}
}
}
}
// adds sorting functionality to the UI
return function() {
if (!getTable()) {
return;
}
cols = loadColumns();
loadData();
addSearchBox();
addSortIndicators();
enableUI();
};
})();
window.addEventListener('load', addSorting);

File diff suppressed because one or more lines are too long

6
dockerignore Normal file
View File

@@ -0,0 +1,6 @@
node_modules
npm-debug*
.nuxt
dist
tests
.output

6
env.d.ts vendored Normal file
View File

@@ -0,0 +1,6 @@
// for svgo
declare module '*.svg' {
import type { DefineComponent } from 'vue'
const component: DefineComponent
export default component
}

10
eslintignore Normal file
View File

@@ -0,0 +1,10 @@
dist
public
# ignore generate imports
auto-imports.d.ts
components.d.ts
dist
.output
node_modules

13
eslintrc Normal file
View File

@@ -0,0 +1,13 @@
{
"extends": ["@nuxtjs/eslint-config-typescript"],
"overrides": [
{
"files": [
"./server/**/*.ts"
],
"rules": {
"no-console": ["error", { "allow": ["info", "warn", "trace", "error"]}]
}
}
]
}

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -1,6 +0,0 @@
import { defineConfig } from 'histoire'
import { HstVue } from '@histoire/plugin-vue'
export default defineConfig({
plugins: [HstVue()],
})

View File

@@ -1,35 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<link
rel="icon"
type="image/svg+xml"
href="https://raw.githubusercontent.com/valerebron/pegaz/master/docs/pegaz.svg"
/>
<meta name="generator" content="{Astro.generator}" />
<meta
name="description"
content="pegaz, deploy stack on the go with docker-compose"
/>
<link rel="canonical" href="https://pegaz.io" />
<meta property="og:title" content="pegaz, deploy stack on the go" />
<meta
property="og:image"
content="https://raw.githubusercontent.com/valerebron/pegaz/master/docs/pegaz.svg"
/>
<meta property="og:site_name" content="Pegaz.io" />
<script
defer
data-domain="pegaz.io"
src="https://plausible.erudi.fr/js/plausible.js"
></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>pegaz.io</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

22
nuxt.config.ts Normal file
View File

@@ -0,0 +1,22 @@
export default defineNuxtConfig({
runtimeConfig: {
version: '0.0.1'
},
modules: ['@nuxtjs/tailwindcss', 'nuxt-svgo', '@huntersofbook/naive-ui-nuxt',
[
'@pinia/nuxt',
{
autoImports: [
// automatically imports `defineStore`
'defineStore', // import { defineStore } from 'pinia'
// automatically imports `defineStore` as `definePiniaStore`
['defineStore', 'definePiniaStore'] // import { defineStore as definePiniaStore } from 'pinia'
]
}
]
],
extends: ['@sidebase/core'],
typescript: {
shim: false
}
})

20467
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,46 +1,53 @@
{
"version": "3.0.1",
"license": "MIT",
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "vite preview",
"histoire": "histoire dev",
"test": "vitest",
"lint": "eslint --fix src/main.js",
"format": "prettier -w ."
"private": true,
"overrides": {
"vue": "latest"
},
"dependencies": {
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-vue": "^9.2.0",
"pinia": "^2.0.16",
"prettier": "^2.7.1",
"typescript": "^4.9.3",
"vue": "^3.2.41",
"vue-meta": "3.0.0-alpha.10",
"vue-router": "4.1.2"
"scripts": {
"dev": "nuxt dev",
"build": "nuxt build",
"start": "NODE_ENV=production node .output/server/index.mjs",
"lint": "eslint .",
"test": "TZ=UTC vitest --run",
"test:components": "TZ=UTC vitest --run components/",
"test:watch": "TZ=UTC vitest",
"test:ui": "TZ=UTC vitest --ui --open",
"postinstall": "nuxt prepare",
"generate": "nuxt generate",
"preview": "nuxt preview",
"typecheck": "nuxt typecheck"
},
"devDependencies": {
"@histoire/plugin-vue": "^0.11.7",
"@typescript-eslint/eslint-plugin": "^5.45.0",
"@faker-js/faker": "^7.6.0",
"@huntersofbook/naive-ui-nuxt": "^0.5.1",
"@nuxt/test-utils": "^3.0.0",
"@nuxtjs/eslint-config-typescript": "^12.0.0",
"@nuxtjs/tailwindcss": "^6.2.0",
"@testing-library/vue": "^6.6.1",
"@vitejs/plugin-vue": "^3.2.0",
"@vue/compiler-sfc": "^3.2.37",
"@vue/test-utils": "^2.2.4",
"autoprefixer": "^10.4.7",
"eslint": "^8.28.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.6.1",
"eslint-plugin-react": "^7.31.11",
"eslint-plugin-react-hooks": "^4.6.0",
"histoire": "^0.11.7",
"postcss": "^8.4.14",
"tailwindcss": "^3.1.6",
"unplugin-vue-components": "^0.21.1",
"vite": "^3.2.3",
"vite-plugin-eslint": "^1.8.1",
"vite-plugin-pages": "^0.27.1",
"vite-plugin-vue-layouts": "^0.7.0",
"vitest": "^0.25.3"
"@vitest/coverage-c8": "^0.26.0",
"@vitest/ui": "^0.26.1",
"dayjs": "^1.11.7",
"eslint": "^8.31.0",
"h3": "^1.0.2",
"jsdom": "^21.0.0",
"nuxt": "3.0.0",
"nuxt-svgo": "^1.1.0",
"playwright": "^1.29.2",
"prisma": "^4.8.1",
"typescript": "^4.9.4",
"unplugin-auto-import": "^0.12.1",
"unplugin-vue-components": "^0.22.12",
"uuid": "^9.0.0",
"vite-svg-loader": "^3.6.0",
"vitest": "^0.26.1",
"vue-tsc": "^1.0.16"
},
"dependencies": {
"@pinia/nuxt": "^0.4.6",
"@prisma/client": "^4.8.1",
"@sidebase/core": "^0.1.4",
"pinia": "^2.0.30",
"youtubei": "^1.1.2"
}
}

41
pages/index.vue Normal file
View File

@@ -0,0 +1,41 @@
<template>
<div class="mx-6">
<header class="h-screen flex flex-col justify-center">
<nav class="fixed right-0 top-0 p-2 z-50">
<a
title="Go to Pegaz GitHub repo"
href="https://github.com/valerebron/pegaz"
target="_blank"
>
<SvgGithub class="bg-white rounded-full shadow-lg hover:scale-105" />
</a>
</nav>
<HeroTitle client:visible />
<HeroButtons client:visible />
</header>
<main class="-mt-20">
<Demo />
<Disclaimer />
<BackupRestore />
<ApplicationsList />
</main>
</div>
</template>
<style>
.pegaz-section {
@apply flex flex-col md:flex-row items-center justify-center mb-28;
}
.title {
@apply text-3xl text-center mb-10 uppercase text-transparent bg-clip-text bg-gradient-to-r from-violet-900 to-blue-500;
}
.app {
@apply bg-black bg-opacity-10 w-20 h-20 p-4 flex-wrap cursor-pointer inline-block rounded-xl transition-all;
}
.app--demo {
@apply bg-black bg-opacity-10 w-20 h-20 p-4 flex-wrap cursor-pointer inline-block transition-all;
}
.app--backup {
@apply bg-black bg-opacity-10 w-20 h-20 p-4 flex-wrap cursor-pointer inline-block transition-all;
}
</style>

View File

@@ -1,6 +0,0 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

View File

@@ -1,25 +0,0 @@
<template>
<metainfo>
<template v-slot:title="{ content }">
{{ content ? `${content} | ${siteName}` : siteName }}
</template>
</metainfo>
<router-view />
</template>
<script setup>
import { useMeta } from 'vue-meta'
const siteName = 'Pegaz.io'
useMeta({
title: '',
htmlAttrs: { lang: 'en', amp: true },
})
</script>
<style lang="postcss">
html {
@apply bg-slate-100;
}
</style>

View File

@@ -1,63 +0,0 @@
<template>
<svg
xmlns:xlink="http://www.w3.org/1999/xlink"
width="160.997"
xmlns="http://www.w3.org/2000/svg"
height="98.997"
id="screenshot-ad9ebd90-5ab7-11ed-b140-a5c46caee909"
viewBox="766.502 -54.498 160.997 98.997"
style="-webkit-print-color-adjust: exact"
fill="none"
version="1.1"
>
<g id="shape-ad9ebd90-5ab7-11ed-b140-a5c46caee909">
<defs>
<linearGradient
gradientUnits="userSpaceOnUse"
y1="294.65009"
id="d3e7133f-3d52-8015-8001-96a125166333-linearGradient5892"
xlink:href="#d3e7133f-3d52-8015-8001-96a125166333-linearGradient5890"
x1="37.362221"
y2="279.14844"
x2="19.9897"
gradientTransform="matrix(1.027997,0,0,1.03956,747.572515,-73.646054) matrix(3.7795276,0,0,3.7795276,18.897638,-1009.3508)"
/>
<linearGradient
id="d3e7133f-3d52-8015-8001-96a125166333-linearGradient5890"
>
<stop
offset="0"
id="stop5886"
style="stop-color: rgb(50, 46, 235); stop-opacity: 1"
/>
<stop
offset="1"
id="stop5888"
style="stop-color: rgb(112, 47, 255); stop-opacity: 1"
/>
</linearGradient>
</defs>
<g id="fills-ad9ebd90-5ab7-11ed-b140-a5c46caee909">
<path
rx="0"
ry="0"
d="M886.653,-54C870.298,-53.532,863.114,-31.168,863.114,-31.168C858.24,-40.251,846.248,-41.148,842.636,-41.213L781.653,-41.215C781.653,-41.211,781.652,-41.206,781.651,-41.198L767.054,-41.237C767.027,-40.977,767.009,-40.716,767,-40.455C767.008,-32.786,774.928,-26.389,785.257,-25.709L818.135,-25.644L818.135,-25.648L833.035,-25.621C834.436,-25.598,835.56,-24.442,835.561,-23.024C835.561,-21.592,834.415,-20.43,832.999,-20.426L832.999,-20.423L818.135,-20.423L818.135,-20.446L786.108,-20.446C785.485,-20.446,785.845,-20.446,785.263,-20.446L785.263,-20.444C785.273,-12.775,793.23,-5.553,803.558,-4.873C803.558,-4.873,805.16,-4.869,805.233,-4.869C805.792,-4.865,807.303,-4.85,818.119,-4.85C818.132,-4.85,818.144,-4.847,818.157,-4.846C818.157,-4.846,820.128,-4.826,832.999,-4.826C834.415,-4.822,835.561,-3.659,835.561,-2.227C835.561,-0.881,834.545,0.213,833.248,0.345L820.191,0.345L818.135,0.345L803.542,0.345L803.542,0.362C803.549,7.085,809.667,13.462,818.135,15.393L820.191,15.902C825.606,15.937,831.021,15.906,836.436,15.963C819.147,15.971,847.872,15.965,850.989,15.965L854.33,16.185L863.873,25.003C881.087,35.074,895.985,36.562,895.985,36.562C895.985,36.562,908.222,52.531,926.285,37.672C927.885,36.356,926.299,34.566,926.299,34.566L878.636,-31.168ZM785.263,-20.444C776.71,-20.444,771.287,-20.445,770.819,-20.446L770.819,-20.444C770.377,-20.444,775.319,-20.444,785.263,-20.444ZZM893.486,-43.489C887.446,-41.215,885.133,-31.079,885.133,-31.079L889.053,-25.751Z"
style="
display: inline;
fill: url('#d3e7133f-3d52-8015-8001-96a125166333-linearGradient5892');
"
/>
</g>
<g id="strokes-ad9ebd90-5ab7-11ed-b140-a5c46caee909">
<g class="stroke-shape">
<path
rx="0"
ry="0"
d="M886.653,-54C870.298,-53.532,863.114,-31.168,863.114,-31.168C858.24,-40.251,846.248,-41.148,842.636,-41.213L781.653,-41.215C781.653,-41.211,781.652,-41.206,781.651,-41.198L767.054,-41.237C767.027,-40.977,767.009,-40.716,767,-40.455C767.008,-32.786,774.928,-26.389,785.257,-25.709L818.135,-25.644L818.135,-25.648L833.035,-25.621C834.436,-25.598,835.56,-24.442,835.561,-23.024C835.561,-21.592,834.415,-20.43,832.999,-20.426L832.999,-20.423L818.135,-20.423L818.135,-20.446L786.108,-20.446C785.485,-20.446,785.845,-20.446,785.263,-20.446L785.263,-20.444C785.273,-12.775,793.23,-5.553,803.558,-4.873C803.558,-4.873,805.16,-4.869,805.233,-4.869C805.792,-4.865,807.303,-4.85,818.119,-4.85C818.132,-4.85,818.144,-4.847,818.157,-4.846C818.157,-4.846,820.128,-4.826,832.999,-4.826C834.415,-4.822,835.561,-3.659,835.561,-2.227C835.561,-0.881,834.545,0.213,833.248,0.345L820.191,0.345L818.135,0.345L803.542,0.345L803.542,0.362C803.549,7.085,809.667,13.462,818.135,15.393L820.191,15.902C825.606,15.937,831.021,15.906,836.436,15.963C819.147,15.971,847.872,15.965,850.989,15.965L854.33,16.185L863.873,25.003C881.087,35.074,895.985,36.562,895.985,36.562C895.985,36.562,908.222,52.531,926.285,37.672C927.885,36.356,926.299,34.566,926.299,34.566L878.636,-31.168ZM785.263,-20.444C776.71,-20.444,771.287,-20.445,770.819,-20.446L770.819,-20.444C770.377,-20.444,775.319,-20.444,785.263,-20.444ZZM893.486,-43.489C887.446,-41.215,885.133,-31.079,885.133,-31.079L889.053,-25.751Z"
style="display: inline; fill: none; stroke-width: 0.996658"
/>
</g>
</g>
</g>
</svg>
</template>

View File

@@ -1,62 +0,0 @@
<script>
import CodeServer from 'Svg/apps/code.vue'
import Deluge from 'Svg/apps/deluge.vue'
import Drone from 'Svg/apps/drone.vue'
import Gitea from 'Svg/apps/gitea.vue'
import Jellyfin from 'Svg/apps/jellyfin.vue'
import Nextcloud from 'Svg/apps/nextcloud.vue'
import Penpot from 'Svg/apps/penpot.vue'
import Plausible from 'Svg/apps/plausible.vue'
import Rss from 'Svg/apps/rss.vue'
import Hoppscotch from 'Svg/apps/hoppscotch.vue'
import Radio from 'Svg/apps/radio.vue'
export default {
components: {
CodeServer,
Deluge,
Drone,
Gitea,
Jellyfin,
Nextcloud,
Penpot,
Plausible,
Rss,
Hoppscotch,
Radio,
},
data: () => ({
apps: [
'Deluge',
'Drone',
'Gitea',
'Jellyfin',
'Nextcloud',
'Penpot',
'Plausible',
'Rss',
'hoppscotch',
'radio',
],
}),
}
</script>
<template>
<section>
<h2 class="title">Pre-configured applications</h2>
<ul class="flex justify-center p-4 m-4 max-w-full flex-wrap">
<li v-for="app in apps" :key="app" class="m-4">
<a
:href="
'https://github.com/valerebron/pegaz/tree/master/services/' +
app.toLowerCase()
"
:title="app"
>
<component :is="app" class="app" />
</a>
</li>
</ul>
</section>
</template>

View File

@@ -1,174 +0,0 @@
<script>
import Nextcloud from 'Svg/apps/nextcloud.vue'
import Jellyfin from 'Svg/apps/jellyfin.vue'
import Backbutton from 'Svg/backbutton.vue'
import Terminal from 'Component/terminal.vue'
export default {
components: { Nextcloud, Jellyfin, Backbutton },
data: () => ({
terminalContent: '',
subDomain: '',
nextcloudClass: [],
jellyfinClass: [],
backbuttonClass: [],
subdomainClass: [],
isDemonstrationEnded: false,
}),
methods: {
demonstration() {
const upClass = [
'w-20',
'p-4',
'opacity-100',
'animate-upApp',
'rounded-xl',
]
const downClass = ['opacity-0', 'w-0', 'p-0']
const openClass = [
'w-full',
'h-full',
'p-20',
'rounded-b-xl',
'rounded-t-none',
'bg-gradient-to-r',
'from-violet-100',
'to-indigo-100',
]
const closeClass = [
'w-20',
'p-4',
'opacity-100',
'animate-upApp',
'rounded-xl',
'm-2',
]
function delay(time) {
return new Promise((resolve) => setTimeout(resolve, time))
}
this.isDemonstrationEnded = false
this.terminalContent = ''
this.nextcloudClass = this.jellyfinClass = downClass
let i = 0
this.timer = setInterval(async () => {
// nextcloud
// up
if (i == 0) {
let cmd = '$ pegaz up nextcloud\n'
for (let y in cmd) {
this.terminalContent += cmd[y]
await delay(20)
}
}
if (i == 1) this.terminalContent += 'Creating nextcloud ... done\n'
if (i == 2) this.terminalContent += '[√] https://nextcloud.domain.com\n'
if (i == 3) this.nextcloudClass = upClass
// open
if (i == 5) this.nextcloudClass.push('animate-openApp')
if (i == 6) this.nextcloudClass = openClass
if (i == 6) this.subDomain = 'cloud.'
if (i == 6) this.subdomainClass = ['']
if (i == 6) this.subdomainClass = ['animate-click']
//close
if (i == 7) this.terminalContent = ''
if (i == 9) this.backbuttonClass = ['animate-click']
if (i == 10) this.nextcloudClass = closeClass
if (i == 10) this.subDomain = this.backbuttonClass = ''
// jellyfin
// up
if (i == 11) {
let cmd = '$ pegaz up jellyfin\n'
for (let y in cmd) {
this.terminalContent += cmd[y]
await delay(20)
}
}
if (i == 12) this.terminalContent += 'Creating jellyfin ... done\n'
if (i == 13) this.terminalContent += '[√] https://jellyfin.domain.com\n'
if (i == 14) this.jellyfinClass = closeClass
// open
if (i == 16) this.jellyfinClass.push('animate-openApp')
if (i == 16) this.nextcloudClass = downClass
if (i == 17) this.jellyfinClass = openClass
if (i == 17) this.subDomain = 'jellyfin.'
if (i == 6) this.subdomainClass = ['']
if (i == 6) this.subdomainClass = ['animate-click']
//close
if (i == 20) this.backbuttonClass = ['animate-click']
if (i == 21) this.jellyfinClass = this.nextcloudClass = closeClass
if (i == 21) this.subDomain = ''
if (i == 21) this.terminalContent = ''
// nextcloud down
if (i == 23) {
let cmd = '$ pegaz down nextcloud\n'
for (let y in cmd) {
this.terminalContent += cmd[y]
await delay(20)
}
}
if (i == 24) this.terminalContent += 'Stopping nextcloud ... done\n'
if (i == 25) this.terminalContent += '[√] Removing nextcloud ... done\n'
if (i == 26) this.nextcloudClass = downClass
if (i == 27) this.isDemonstrationEnded = true
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)
},
},
async created() {
let isPageScrolled = false
this.nextcloudClass = this.jellyfinClass = []
document.onscroll = (event) => {
if (!isPageScrolled) this.demonstration()
isPageScrolled = true
}
},
}
</script>
<template>
<section class="pegaz-section">
<Terminal :terminalContent="terminalContent" />
<div
class="bg-slate-400 flex flex-col items-center relative rounded-2xl w-full m-0 md:min-w-fit max-w-2xl 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"
>
<Backbutton
class="mr-3 p-1 bg-slate-300 rounded-full"
:class="backbuttonClass"
/>
<span class="text-gray-400"> https:// </span>
<span class="text-indigo-700 font-bold" :class="subdomainClass">
{{ subDomain }} </span
>domain.com
</div>
<div
class="bg-white w-full h-full flex rounded-b-xl justify-center items-center"
>
<Nextcloud
class="app"
:class="nextcloudClass"
title="nextcloud.domain.com"
/>
<Jellyfin
class="app"
:class="jellyfinClass"
title="jellyfin.domain.com"
/>
</div>
</div>
</section>
</template>

View File

@@ -1,3 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View File

@@ -1,19 +0,0 @@
<template>
<main class="max-w-5xl p-5 mx-auto my-10 text-center">
<router-view />
<div>
<v-button @click="router.back()"> Go Back </v-button>
</div>
</main>
</template>
<script setup>
import { useRouter } from 'vue-router'
import { useMeta } from 'vue-meta'
useMeta({
title: '404 - Not found!',
})
const router = useRouter()
</script>

View File

@@ -1,3 +0,0 @@
<template>
<router-view />
</template>

View File

@@ -1,23 +0,0 @@
import { createApp } from 'vue';
import { createMetaManager } from 'vue-meta';
import { createRouter, createWebHistory } from 'vue-router';
import { createPinia } from 'pinia';
import { setupLayouts } from 'virtual:generated-layouts';
import generatedRoutes from 'virtual:generated-pages';
import App from './App.vue';
import './index.css';
const routes = setupLayouts(generatedRoutes);
const router = createRouter({
history: createWebHistory(),
routes,
});
const app = createApp(App)
.use(router)
.use(createPinia())
.use(createMetaManager());
router.isReady();
app.mount('#app');

View File

@@ -1,8 +0,0 @@
<template>
<div class="py-4 text-2xl text-center">Page Not found!</div>
</template>
<route lang="yaml">
meta:
layout: 404
</route>

View File

@@ -1,26 +0,0 @@
<template>
<div>
<h1 class="text-2xl font-bold">About {{ usersStore.name }}</h1>
<p class="my-8">
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Itaque
voluptatem consequuntur molestiae cumque recusandae eos non, consectetur,
repellat architecto illo nobis, voluptatum dolor! Reprehenderit, nam
veniam quibusdam ab nulla rem.
</p>
<router-link to="/">
<v-button>Back to home</v-button>
</router-link>
</div>
</template>
<script setup>
import { useMeta } from 'vue-meta'
import { useUsersStore } from 'Store/useUsersStore'
useMeta({
title: 'About Page',
})
const usersStore = useUsersStore()
</script>

View File

@@ -1,68 +0,0 @@
<template>
<div class="mx-6">
<header class="h-screen flex flex-col justify-center">
<nav class="fixed right-0 top-0 p-2 z-50">
<a
title="Go to Pegaz GitHub repo"
href="https://github.com/valerebron/pegaz"
target="_blank"
>
<Github class="bg-white rounded-full shadow-lg hover:scale-105" />
</a>
</nav>
<HeroTitle client:visible />
<HeroButtons client:visible />
</header>
<main class="-mt-20">
<Demo />
<Disclaimer />
<BackupRestore />
<AppList />
</main>
</div>
</template>
<script setup>
import { useMeta } from 'vue-meta'
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { useUsersStore } from 'Store/useUsersStore'
import Github from 'Svg/github.vue'
import HeroTitle from 'Component/hero-title.vue'
import HeroButtons from 'Component/hero-buttons.vue'
import Demo from 'Component/demo.vue'
import AppList from 'Component/applications-list.vue'
import BackupRestore from 'Component/backup-restore.vue'
import Disclaimer from 'Component/disclaimer.vue'
useMeta({
title: 'Deploy stack on the go'
})
const router = useRouter()
const usersStore = useUsersStore()
const newName = ref('')
function saveName() {
if (newName.value === '') {
return
}
usersStore.saveName(newName.value)
router.push(`/about/${newName.value}`)
newName.value = ''
}
</script>
<style>
.pegaz-section {
@apply flex flex-col md:flex-row items-center justify-center mb-28;
}
.title {
@apply text-3xl text-center mb-10 uppercase text-transparent bg-clip-text bg-gradient-to-r from-violet-900 to-blue-500;
}
.app {
@apply bg-black bg-opacity-10 w-20 h-20 p-4 rounded-xl flex-wrap cursor-pointer inline-block transition-all;
}
</style>

View File

@@ -1,22 +0,0 @@
import { defineStore, acceptHMRUpdate } from 'pinia'
export const useUsersStore = defineStore('users', {
state: () => {
return {
name: 'John Doe',
}
},
getters: {
nameUppercased: (state) => state.name.toUpperCase(),
},
actions: {
saveName(name) {
this.name = name
},
},
})
if (import.meta.hot)
import.meta.hot.accept(acceptHMRUpdate(useUsersStore, import.meta.hot))

View File

@@ -1,40 +1,38 @@
module.exports = {
content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
darkMode: 'class',
export default {
theme: {
extend: {
keyframes: {
blink: {
'0%': { opacity: '0' },
'100%': { opacity: '100' },
'100%': { opacity: '100' }
},
slide: {
'0%': { transform: 'translateX(-40px)' },
'100%': { transform: 'translateX(0px)' },
'100%': { transform: 'translateX(0px)' }
},
fadin: {
'0%': { opacity: '0' },
'100%': { opacity: '1' },
'100%': { opacity: '1' }
},
fadeout: {
'0%': { opacity: '1' },
'100%': { opacity: '0' },
'100%': { opacity: '0' }
},
upApp: {
'0%': { transform: 'scale(0)' },
'90%': { transform: 'scale(1.2)' },
'100%': { transform: 'sale(1)' },
'100%': { transform: 'sale(1)' }
},
openApp: {
'0%': { transform: 'scale(0.8)' },
'50%': { transform: 'scale(1.2)' },
'100%': { transform: 'sale(1)' },
'100%': { transform: 'sale(1)' }
},
click: {
'0%': { transform: 'scale(0.5)' },
'50%': { transform: 'scale(1.5)' },
'100%': { transform: 'sale(1)' },
},
'100%': { transform: 'sale(1)' }
}
},
animation: {
blink: 'blink .6s infinite',
@@ -42,12 +40,8 @@ module.exports = {
fadeout: 'fadeout .8s',
upApp: 'upApp .5s cubic-bezier(0, 0, 0.2, 1)',
openApp: 'openApp .3s cubic-bezier(0, 0, 0.2, 1)',
click: 'click .3s cubic-bezier(0, 0, 0.2, 1)',
},
},
},
variants: {
extend: {},
},
plugins: [],
click: 'click .3s cubic-bezier(0, 0, 0.2, 1)'
}
}
}
}

View File

@@ -1,7 +0,0 @@
import { test, assert, describe } from 'vitest'
describe('example test', () => {
test('assert', () => {
assert.equal(1, 1)
})
})

View File

@@ -1,13 +1,4 @@
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"experimentalDecorators": true,
"lib": ["dom", "esnext"]
},
"exclude": ["node_modules", "dist"]
// https://nuxt.com/docs/guide/concepts/typescript
"extends": "./.nuxt/tsconfig.json"
}

7
types/todo.d.ts vendored Normal file
View File

@@ -0,0 +1,7 @@
export default interface Todo {
id: string
content: string
isDone: boolean
createdAt: date
updatedAt: date
}

View File

@@ -1,25 +0,0 @@
import path from 'path'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import Pages from 'vite-plugin-pages'
import Components from 'unplugin-vue-components/vite'
import Layouts from 'vite-plugin-vue-layouts'
import eslintPlugin from 'vite-plugin-eslint'
export default defineConfig({
resolve: {
alias: {
'~': path.resolve(__dirname, 'src'),
Component: path.resolve(__dirname, 'src/components'),
Store: path.resolve(__dirname, 'src/stores'),
Svg: path.resolve(__dirname, 'src/assets/svg'),
},
},
plugins: [vue(), Pages(), Layouts(), Components(), eslintPlugin()],
build: {
target: 'esnext',
},
test: {
environment: 'happy-dom',
},
})

View File

@@ -1,8 +0,0 @@
import { defineConfig } from 'vitest/config'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
test: {
// ...
},
})

49
vitest.config.ts Normal file
View File

@@ -0,0 +1,49 @@
import path from 'path'
import { defineConfig } from 'vitest/config'
import vue from '@vitejs/plugin-vue'
import svgLoader from 'vite-svg-loader'
import Components from 'unplugin-vue-components/vite'
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers'
import AutoImport from 'unplugin-auto-import/vite'
const include = [/\.vue$/, /\.vue\?vue/, /\.stories\.ts$/, /\.[tj]s$/]
export default defineConfig({
resolve: {
alias: {
'~': path.resolve(__dirname)
}
},
plugins: [
vue(),
Components({
dirs: ['~/components'],
directoryAsNamespace: true,
resolvers: [NaiveUiResolver()],
include
}),
AutoImport({
include,
imports: ['vue', '@vueuse/head'],
dirs: ['~/composables'],
vueTemplate: true
}),
svgLoader()
],
test: {
globalSetup: ['./tests/setupSqliteDbEnv'],
globals: true,
environment: 'jsdom',
threads: false,
coverage: {
enabled: true,
// We want to catch all js/ts/... files, not only the ones imported in some tests
// see https://github.com/bcoe/c8#checking-for-full-source-coverage-using---all
all: true,
include: [
// Nuxt 3 framework folders and files sources from directory structure here: https://nuxt.com/docs/guide/directory-structure/nuxt
'components',
'composables'
]
}
}
})