@ -0,0 +1,4 @@
|
||||
> 1%
|
||||
last 2 versions
|
||||
not dead
|
||||
not ie 11
|
@ -0,0 +1,5 @@
|
||||
[*.{js,jsx,ts,tsx,vue}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
@ -0,0 +1,82 @@
|
||||
{
|
||||
"globals": {
|
||||
"Component": true,
|
||||
"ComponentPublicInstance": true,
|
||||
"ComputedRef": true,
|
||||
"DirectiveBinding": true,
|
||||
"EffectScope": true,
|
||||
"ExtractDefaultPropTypes": true,
|
||||
"ExtractPropTypes": true,
|
||||
"ExtractPublicPropTypes": true,
|
||||
"InjectionKey": true,
|
||||
"MaybeRef": true,
|
||||
"MaybeRefOrGetter": true,
|
||||
"PropType": true,
|
||||
"Ref": true,
|
||||
"Slot": true,
|
||||
"Slots": true,
|
||||
"VNode": true,
|
||||
"WritableComputedRef": true,
|
||||
"computed": true,
|
||||
"createApp": true,
|
||||
"customRef": true,
|
||||
"defineAsyncComponent": true,
|
||||
"defineComponent": true,
|
||||
"defineStore": true,
|
||||
"effectScope": true,
|
||||
"getCurrentInstance": true,
|
||||
"getCurrentScope": true,
|
||||
"h": true,
|
||||
"inject": true,
|
||||
"isProxy": true,
|
||||
"isReactive": true,
|
||||
"isReadonly": true,
|
||||
"isRef": true,
|
||||
"markRaw": true,
|
||||
"nextTick": true,
|
||||
"onActivated": true,
|
||||
"onBeforeMount": true,
|
||||
"onBeforeRouteLeave": true,
|
||||
"onBeforeRouteUpdate": true,
|
||||
"onBeforeUnmount": true,
|
||||
"onBeforeUpdate": true,
|
||||
"onDeactivated": true,
|
||||
"onErrorCaptured": true,
|
||||
"onMounted": true,
|
||||
"onRenderTracked": true,
|
||||
"onRenderTriggered": true,
|
||||
"onScopeDispose": true,
|
||||
"onServerPrefetch": true,
|
||||
"onUnmounted": true,
|
||||
"onUpdated": true,
|
||||
"onWatcherCleanup": true,
|
||||
"provide": true,
|
||||
"reactive": true,
|
||||
"readonly": true,
|
||||
"ref": true,
|
||||
"resolveComponent": true,
|
||||
"shallowReactive": true,
|
||||
"shallowReadonly": true,
|
||||
"shallowRef": true,
|
||||
"storeToRefs": true,
|
||||
"toRaw": true,
|
||||
"toRef": true,
|
||||
"toRefs": true,
|
||||
"toValue": true,
|
||||
"triggerRef": true,
|
||||
"unref": true,
|
||||
"useAttrs": true,
|
||||
"useCssModule": true,
|
||||
"useCssVars": true,
|
||||
"useId": true,
|
||||
"useModel": true,
|
||||
"useRoute": true,
|
||||
"useRouter": true,
|
||||
"useSlots": true,
|
||||
"useTemplateRef": true,
|
||||
"watch": true,
|
||||
"watchEffect": true,
|
||||
"watchPostEffect": true,
|
||||
"watchSyncEffect": true
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
@ -0,0 +1,147 @@
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
// @ts-nocheck
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
// Generated by unplugin-auto-import
|
||||
// biome-ignore lint: disable
|
||||
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 defineStore: typeof import('pinia')['defineStore']
|
||||
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 onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave']
|
||||
const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate']
|
||||
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 onWatcherCleanup: typeof import('vue')['onWatcherCleanup']
|
||||
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 shallowReactive: typeof import('vue')['shallowReactive']
|
||||
const shallowReadonly: typeof import('vue')['shallowReadonly']
|
||||
const shallowRef: typeof import('vue')['shallowRef']
|
||||
const storeToRefs: typeof import('pinia')['storeToRefs']
|
||||
const toRaw: typeof import('vue')['toRaw']
|
||||
const toRef: typeof import('vue')['toRef']
|
||||
const toRefs: typeof import('vue')['toRefs']
|
||||
const toValue: typeof import('vue')['toValue']
|
||||
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 useId: typeof import('vue')['useId']
|
||||
const useModel: typeof import('vue')['useModel']
|
||||
const useRoute: typeof import('vue-router')['useRoute']
|
||||
const useRouter: typeof import('vue-router')['useRouter']
|
||||
const useSlots: typeof import('vue')['useSlots']
|
||||
const useTemplateRef: typeof import('vue')['useTemplateRef']
|
||||
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 type re-export
|
||||
declare global {
|
||||
// @ts-ignore
|
||||
export type { Component, Slot, Slots, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
|
||||
import('vue')
|
||||
}
|
||||
|
||||
// for vue template auto import
|
||||
import { UnwrapRef } from 'vue'
|
||||
declare module 'vue' {
|
||||
interface GlobalComponents {}
|
||||
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 defineStore: UnwrapRef<typeof import('pinia')['defineStore']>
|
||||
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 onBeforeRouteLeave: UnwrapRef<typeof import('vue-router')['onBeforeRouteLeave']>
|
||||
readonly onBeforeRouteUpdate: UnwrapRef<typeof import('vue-router')['onBeforeRouteUpdate']>
|
||||
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 onWatcherCleanup: UnwrapRef<typeof import('vue')['onWatcherCleanup']>
|
||||
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 shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
|
||||
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
|
||||
readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
|
||||
readonly storeToRefs: UnwrapRef<typeof import('pinia')['storeToRefs']>
|
||||
readonly toRaw: UnwrapRef<typeof import('vue')['toRaw']>
|
||||
readonly toRef: UnwrapRef<typeof import('vue')['toRef']>
|
||||
readonly toRefs: UnwrapRef<typeof import('vue')['toRefs']>
|
||||
readonly toValue: UnwrapRef<typeof import('vue')['toValue']>
|
||||
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 useId: UnwrapRef<typeof import('vue')['useId']>
|
||||
readonly useModel: UnwrapRef<typeof import('vue')['useModel']>
|
||||
readonly useRoute: UnwrapRef<typeof import('vue-router')['useRoute']>
|
||||
readonly useRouter: UnwrapRef<typeof import('vue-router')['useRouter']>
|
||||
readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
|
||||
readonly useTemplateRef: UnwrapRef<typeof import('vue')['useTemplateRef']>
|
||||
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']>
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
// Generated by unplugin-vue-components
|
||||
// Read more: https://github.com/vuejs/core/pull/3399
|
||||
// biome-ignore lint: disable
|
||||
export {}
|
||||
|
||||
/* prettier-ignore */
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
AppFooter: typeof import('./src/components/AppFooter.vue')['default']
|
||||
DrawerComponent: typeof import('./src/components/common/DrawerComponent.vue')['default']
|
||||
HelloWorld: typeof import('./src/components/HelloWorld.vue')['default']
|
||||
LayoutComponent: typeof import('./src/components/common/LayoutComponent.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
import vuetify from 'eslint-config-vuetify'
|
||||
|
||||
export default vuetify()
|
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Welcome to Vuetify 3</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,20 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"target": "es5",
|
||||
"module": "esnext",
|
||||
"baseUrl": "./",
|
||||
"moduleResolution": "bundler",
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
},
|
||||
"lib": [
|
||||
"esnext",
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"scripthost"
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "autoflow-web-console",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"lint": "eslint . --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource/roboto": "5.2.5",
|
||||
"@mdi/font": "7.4.47",
|
||||
"prettier": "^3.5.3",
|
||||
"vue": "^3.5.13",
|
||||
"vuetify": "^3.8.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^5.2.3",
|
||||
"eslint": "^9.23.0",
|
||||
"eslint-config-vuetify": "^4.0.0",
|
||||
"globals": "^16.0.0",
|
||||
"pinia": "^3.0.1",
|
||||
"sass-embedded": "^1.86.3",
|
||||
"unplugin-auto-import": "^19.1.1",
|
||||
"unplugin-fonts": "^1.3.1",
|
||||
"unplugin-vue-components": "^28.4.1",
|
||||
"unplugin-vue-router": "^0.12.0",
|
||||
"vite": "^6.2.2",
|
||||
"vite-plugin-vue-layouts-next": "^0.0.8",
|
||||
"vite-plugin-vuetify": "^2.1.1",
|
||||
"vue-router": "^4.5.0"
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 15 KiB |
@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<v-app>
|
||||
<router-view />
|
||||
</v-app>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
//
|
||||
</script>
|
After Width: | Height: | Size: 581 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 526 B |
After Width: | Height: | Size: 624 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 12 KiB |
@ -0,0 +1,82 @@
|
||||
<template>
|
||||
<v-footer
|
||||
app
|
||||
height="40"
|
||||
>
|
||||
<a
|
||||
v-for="item in items"
|
||||
:key="item.title"
|
||||
class="d-inline-block mx-2 social-link"
|
||||
:href="item.href"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
:title="item.title"
|
||||
>
|
||||
<v-icon
|
||||
:icon="item.icon"
|
||||
:size="item.icon === '$vuetify' ? 24 : 16"
|
||||
/>
|
||||
</a>
|
||||
|
||||
<div
|
||||
class="text-caption text-disabled"
|
||||
style="position: absolute; right: 16px;"
|
||||
>
|
||||
© 2016-{{ (new Date()).getFullYear() }} <span class="d-none d-sm-inline-block">Vuetify, LLC</span>
|
||||
—
|
||||
<a
|
||||
class="text-decoration-none on-surface"
|
||||
href="https://vuetifyjs.com/about/licensing/"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
MIT License
|
||||
</a>
|
||||
</div>
|
||||
</v-footer>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const items = [
|
||||
{
|
||||
title: 'Vuetify Documentation',
|
||||
icon: `$vuetify`,
|
||||
href: 'https://vuetifyjs.com/',
|
||||
},
|
||||
{
|
||||
title: 'Vuetify Support',
|
||||
icon: 'mdi-shield-star-outline',
|
||||
href: 'https://support.vuetifyjs.com/',
|
||||
},
|
||||
{
|
||||
title: 'Vuetify X',
|
||||
icon: ['M2.04875 3.00002L9.77052 13.3248L1.99998 21.7192H3.74882L10.5519 14.3697L16.0486 21.7192H22L13.8437 10.8137L21.0765 3.00002H19.3277L13.0624 9.76874L8.0001 3.00002H2.04875ZM4.62054 4.28821H7.35461L19.4278 20.4308H16.6937L4.62054 4.28821Z'],
|
||||
href: 'https://x.com/vuetifyjs',
|
||||
},
|
||||
{
|
||||
title: 'Vuetify GitHub',
|
||||
icon: `mdi-github`,
|
||||
href: 'https://github.com/vuetifyjs/vuetify',
|
||||
},
|
||||
{
|
||||
title: 'Vuetify Discord',
|
||||
icon: ['M22,24L16.75,19L17.38,21H4.5A2.5,2.5 0 0,1 2,18.5V3.5A2.5,2.5 0 0,1 4.5,1H19.5A2.5,2.5 0 0,1 22,3.5V24M12,6.8C9.32,6.8 7.44,7.95 7.44,7.95C8.47,7.03 10.27,6.5 10.27,6.5L10.1,6.33C8.41,6.36 6.88,7.53 6.88,7.53C5.16,11.12 5.27,14.22 5.27,14.22C6.67,16.03 8.75,15.9 8.75,15.9L9.46,15C8.21,14.73 7.42,13.62 7.42,13.62C7.42,13.62 9.3,14.9 12,14.9C14.7,14.9 16.58,13.62 16.58,13.62C16.58,13.62 15.79,14.73 14.54,15L15.25,15.9C15.25,15.9 17.33,16.03 18.73,14.22C18.73,14.22 18.84,11.12 17.12,7.53C17.12,7.53 15.59,6.36 13.9,6.33L13.73,6.5C13.73,6.5 15.53,7.03 16.56,7.95C16.56,7.95 14.68,6.8 12,6.8M9.93,10.59C10.58,10.59 11.11,11.16 11.1,11.86C11.1,12.55 10.58,13.13 9.93,13.13C9.29,13.13 8.77,12.55 8.77,11.86C8.77,11.16 9.28,10.59 9.93,10.59M14.1,10.59C14.75,10.59 15.27,11.16 15.27,11.86C15.27,12.55 14.75,13.13 14.1,13.13C13.46,13.13 12.94,12.55 12.94,11.86C12.94,11.16 13.45,10.59 14.1,10.59Z'],
|
||||
href: 'https://community.vuetifyjs.com/',
|
||||
},
|
||||
{
|
||||
title: 'Vuetify Reddit',
|
||||
icon: `mdi-reddit`,
|
||||
href: 'https://reddit.com/r/vuetifyjs',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<style scoped lang="sass">
|
||||
.social-link :deep(.v-icon)
|
||||
color: rgba(var(--v-theme-on-background), var(--v-disabled-opacity))
|
||||
text-decoration: none
|
||||
transition: .2s ease-in-out
|
||||
|
||||
&:hover
|
||||
color: rgba(25, 118, 210, 1)
|
||||
</style>
|
@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<v-container class="fill-height" max-width="900">
|
||||
<div>
|
||||
<v-img
|
||||
class="mb-4"
|
||||
height="150"
|
||||
src="@/assets/logo.png"
|
||||
/>
|
||||
|
||||
<div class="mb-8 text-center">
|
||||
<div class="text-body-2 font-weight-light mb-n1">Welcome to</div>
|
||||
<h1 class="text-h2 font-weight-bold">Vuetify</h1>
|
||||
</div>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12">
|
||||
<v-card
|
||||
class="py-4"
|
||||
color="surface-variant"
|
||||
image="https://cdn.vuetifyjs.com/docs/images/one/create/feature.png"
|
||||
prepend-icon="mdi-rocket-launch-outline"
|
||||
rounded="lg"
|
||||
variant="tonal"
|
||||
>
|
||||
<template #image>
|
||||
<v-img position="top right" />
|
||||
</template>
|
||||
|
||||
<template #title>
|
||||
<h2 class="text-h5 font-weight-bold">
|
||||
Get started
|
||||
</h2>
|
||||
</template>
|
||||
|
||||
<template #subtitle>
|
||||
<div class="text-subtitle-1">
|
||||
Change this page by updating <v-kbd>{{ `<HelloWorld />` }}</v-kbd> in <v-kbd>components/HelloWorld.vue</v-kbd>.
|
||||
</div>
|
||||
</template>
|
||||
</v-card>
|
||||
</v-col>
|
||||
|
||||
<v-col v-for="link in links" :key="link.href" cols="6">
|
||||
<v-card
|
||||
append-icon="mdi-open-in-new"
|
||||
class="py-4"
|
||||
color="surface-variant"
|
||||
:href="link.href"
|
||||
:prepend-icon="link.icon"
|
||||
rel="noopener noreferrer"
|
||||
rounded="lg"
|
||||
:subtitle="link.subtitle"
|
||||
target="_blank"
|
||||
:title="link.title"
|
||||
variant="tonal"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const links = [
|
||||
{
|
||||
href: 'https://vuetifyjs.com/',
|
||||
icon: 'mdi-text-box-outline',
|
||||
subtitle: 'Learn about all things Vuetify in our documentation.',
|
||||
title: 'Documentation',
|
||||
},
|
||||
{
|
||||
href: 'https://vuetifyjs.com/introduction/why-vuetify/#feature-guides',
|
||||
icon: 'mdi-star-circle-outline',
|
||||
subtitle: 'Explore available framework Features.',
|
||||
title: 'Features',
|
||||
},
|
||||
{
|
||||
href: 'https://vuetifyjs.com/components/all',
|
||||
icon: 'mdi-widgets-outline',
|
||||
subtitle: 'Discover components in the API Explorer.',
|
||||
title: 'Components',
|
||||
},
|
||||
{
|
||||
href: 'https://discord.vuetifyjs.com',
|
||||
icon: 'mdi-account-group-outline',
|
||||
subtitle: 'Connect with Vuetify developers.',
|
||||
title: 'Community',
|
||||
},
|
||||
]
|
||||
</script>
|
@ -0,0 +1,35 @@
|
||||
# Components
|
||||
|
||||
Vue template files in this folder are automatically imported.
|
||||
|
||||
## 🚀 Usage
|
||||
|
||||
Importing is handled by [unplugin-vue-components](https://github.com/unplugin/unplugin-vue-components). This plugin automatically imports `.vue` files created in the `src/components` directory, and registers them as global components. This means that you can use any component in your application without having to manually import it.
|
||||
|
||||
The following example assumes a component located at `src/components/MyComponent.vue`:
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<MyComponent />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
//
|
||||
</script>
|
||||
```
|
||||
|
||||
When your template is rendered, the component's import will automatically be inlined, which renders to this:
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<MyComponent />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import MyComponent from '@/components/MyComponent.vue'
|
||||
</script>
|
||||
```
|
@ -0,0 +1,139 @@
|
||||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { useRouter } from "vue-router";
|
||||
import { menuUtils } from "@/utils/menuUtils";
|
||||
import { storage } from "@/utils/storage";
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const isShowAuth = ref(false);
|
||||
|
||||
const isLinkActive = (link) => {
|
||||
return route.path.includes(link);
|
||||
};
|
||||
|
||||
const goMain = () => {
|
||||
router.push("/home");
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
isShowAuth.value = true;
|
||||
//storage.getAuth().auth === "ADMIN";
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-card flat class="mx-auto">
|
||||
<v-card
|
||||
:ripple="false"
|
||||
flat
|
||||
class="bg-shades-transparent font-weight-bold d-flex w-100 justify-center text-h5 pa-4 pb-16"
|
||||
@click="goMain"
|
||||
>
|
||||
<div>
|
||||
<v-img :src="logo" width="auto" height="32" />
|
||||
</div>
|
||||
</v-card>
|
||||
<v-list nav class="pa-5">
|
||||
<template
|
||||
v-for="({ title, value, icon, path, depth }, i) in menuUtils.menuItem"
|
||||
:key="`group_id_${i}`"
|
||||
>
|
||||
<template v-if="depth && depth.length > 0">
|
||||
<v-list-group :key="`group_id_${i}`">
|
||||
<template #activator="{ props }">
|
||||
<v-list-item
|
||||
rounded
|
||||
v-bind="props"
|
||||
:title="title"
|
||||
:prepend-icon="icon"
|
||||
class="pa-2 rounded-lg"
|
||||
>
|
||||
</v-list-item>
|
||||
</template>
|
||||
<v-list-item
|
||||
v-for="({ title: t, path: p }, j) in depth"
|
||||
:key="`id_${j}`"
|
||||
rounded
|
||||
:title="t"
|
||||
:value="t"
|
||||
:to="p"
|
||||
:active-color="isLinkActive(p) ? 'primary' : null"
|
||||
:active="isLinkActive(p)"
|
||||
class="pa-2 rounded-lg"
|
||||
></v-list-item>
|
||||
</v-list-group>
|
||||
</template>
|
||||
<template v-else>
|
||||
<v-list-item
|
||||
rounded
|
||||
:title="title"
|
||||
:value="value"
|
||||
:to="path"
|
||||
:prepend-icon="icon"
|
||||
:active="isLinkActive(path)"
|
||||
style="padding-inline-start: 10px"
|
||||
:active-color="isLinkActive(path) ? 'primary' : null"
|
||||
density="compact"
|
||||
class="pa-2 rounded-lg"
|
||||
></v-list-item>
|
||||
</template>
|
||||
</template>
|
||||
<template v-if="isShowAuth">
|
||||
<template
|
||||
v-for="(
|
||||
{ title, value, icon, path, depth }, i
|
||||
) in menuUtils.adminMenuItem"
|
||||
:key="`group_id_6`"
|
||||
>
|
||||
<template v-if="depth && depth.length > 0">
|
||||
<v-list-group :key="`group_id_${i}`">
|
||||
<template #activator="{ props }">
|
||||
<v-list-item
|
||||
rounded
|
||||
v-bind="props"
|
||||
:title="title"
|
||||
:prepend-icon="icon"
|
||||
class="pa-2 rounded-lg"
|
||||
>
|
||||
</v-list-item>
|
||||
</template>
|
||||
<v-list-item
|
||||
v-for="({ title: t, path: p }, j) in depth"
|
||||
:key="`id_${j}`"
|
||||
rounded
|
||||
:title="t"
|
||||
:value="t"
|
||||
:to="p"
|
||||
:active-color="isLinkActive(p) ? 'primary' : null"
|
||||
:active="isLinkActive(p)"
|
||||
class="pa-2 rounded-lg"
|
||||
></v-list-item>
|
||||
</v-list-group>
|
||||
</template>
|
||||
<template v-else>
|
||||
<v-list-item
|
||||
rounded
|
||||
:title="title"
|
||||
:value="value"
|
||||
:to="path"
|
||||
:prepend-icon="icon"
|
||||
:active="isLinkActive(path)"
|
||||
style="padding-inline-start: 10px"
|
||||
:active-color="isLinkActive(path) ? 'primary' : null"
|
||||
density="compact"
|
||||
class="pa-2 rounded-lg"
|
||||
></v-list-item>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
</v-list>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<style scoped lang="sass">
|
||||
|
||||
</style>
|
@ -0,0 +1,154 @@
|
||||
<script setup>
|
||||
import {useRoute, useRouter} from "vue-router";
|
||||
import {storage} from "@/utils/storage.js";
|
||||
import DrawerComponent from "@/components/common/DrawerComponent.vue";
|
||||
import {watchEffect} from "vue";
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const menu = ref([]);
|
||||
|
||||
const menuItems = [
|
||||
{
|
||||
title: "Select Project",
|
||||
},
|
||||
{
|
||||
title: "Change Password",
|
||||
click: () => {
|
||||
showPasswordModal.value = true;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Logout",
|
||||
icon: "mdi-logout",
|
||||
click: () => {
|
||||
logOut();
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const userMenuItems = [
|
||||
{
|
||||
title: "Select Project",
|
||||
},
|
||||
{
|
||||
title: "Change Password",
|
||||
},
|
||||
{
|
||||
title: "Logout",
|
||||
icon: "mdi-logout",
|
||||
click: () => {
|
||||
logOut();
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const drawer = ref(null);
|
||||
const pageTitle = computed(() => {
|
||||
return route.meta.title;
|
||||
});
|
||||
|
||||
const pagePath = computed(() => {
|
||||
return route.path;
|
||||
});
|
||||
|
||||
const logOut = () => {
|
||||
storage.clearAuth();
|
||||
router.push("/signin");
|
||||
};
|
||||
|
||||
const goHome = () => {
|
||||
router.push("/main");
|
||||
};
|
||||
|
||||
const showPasswordModal = ref(false);
|
||||
const selectedUserData = ref({});
|
||||
|
||||
watchEffect(() => {
|
||||
// const auth = storage.getAuth().auth;
|
||||
// if (auth === "ADMIN") {
|
||||
menu.value = menuItems;
|
||||
// } else {
|
||||
// menu.value = userMenuItems;
|
||||
// }
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-app>
|
||||
<v-navigation-drawer v-model="drawer" border="0" hide-overlay permanent>
|
||||
<DrawerComponent />
|
||||
</v-navigation-drawer>
|
||||
|
||||
<v-app-bar class="bg-shades-transparent" flat>
|
||||
<div class="px-8 text-h6 text-secondary font-weight-medium">
|
||||
Autoflow Web Console
|
||||
</div>
|
||||
<v-spacer></v-spacer>
|
||||
<v-menu location="bottom end">
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-tooltip location="bottom" text="dashboard">
|
||||
<template #activator="{ props }">
|
||||
<v-btn
|
||||
icon
|
||||
color="secondary"
|
||||
class="mr-3"
|
||||
v-bind="props"
|
||||
>
|
||||
<v-icon>mdi-settings</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
<v-tooltip location="bottom" text="dashboard">
|
||||
<template #activator="{ props }">
|
||||
<v-btn
|
||||
icon
|
||||
color="secondary"
|
||||
class="mr-3"
|
||||
@click="goHome"
|
||||
v-bind="props"
|
||||
>
|
||||
<v-icon>mdi-home</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
<div style="min-width: 180px" class="d-flex flex-column align-end">
|
||||
<div class="font-weight-black">ADMIN_001</div>
|
||||
<div class="text-subtitle-2">No Project Selected</div>
|
||||
</div>
|
||||
<v-btn icon color="secondary" v-bind="props" class="mr-3">
|
||||
<v-icon>mdi-arrow-down-drop-circle-outline</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-list>
|
||||
<v-list-item
|
||||
v-for="(item, index) in menu"
|
||||
:key="index"
|
||||
:value="index"
|
||||
@click="item.click"
|
||||
:prepend-icon="item.icon"
|
||||
>
|
||||
<v-list-item-title>{{ item.title }}</v-list-item-title>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</v-app-bar>
|
||||
|
||||
<v-main>
|
||||
<v-container
|
||||
fluid
|
||||
class="pa-16 background d-flex justify-center"
|
||||
style="width: 100%"
|
||||
>
|
||||
<slot></slot>
|
||||
</v-container>
|
||||
</v-main>
|
||||
|
||||
</v-app>
|
||||
</template>
|
||||
|
||||
<style scoped lang="sass">
|
||||
|
||||
</style>
|
@ -0,0 +1,5 @@
|
||||
# Layouts
|
||||
|
||||
Layouts are reusable components that wrap around pages. They are used to provide a consistent look and feel across multiple pages.
|
||||
|
||||
Full documentation for this feature can be found in the Official [vite-plugin-vue-layouts-next](https://github.com/loicduong/vite-plugin-vue-layouts-next) repository.
|
@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<LayoutComponent>
|
||||
<router-view />
|
||||
</LayoutComponent>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import LayoutComponent from '@/components/common/LayoutComponent.vue';
|
||||
</script>
|
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* main.js
|
||||
*
|
||||
* Bootstraps Vuetify and other plugins then mounts the App`
|
||||
*/
|
||||
|
||||
// Plugins
|
||||
import { registerPlugins } from '@/plugins'
|
||||
|
||||
// Components
|
||||
import App from './App.vue'
|
||||
|
||||
// Composables
|
||||
import { createApp } from 'vue'
|
||||
|
||||
// Styles
|
||||
import 'unfonts.css'
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
registerPlugins(app)
|
||||
|
||||
app.mount('#app')
|
@ -0,0 +1,11 @@
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>main</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="sass">
|
||||
|
||||
</style>
|
@ -0,0 +1,11 @@
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>main</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="sass">
|
||||
|
||||
</style>
|
@ -0,0 +1,11 @@
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>main</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="sass">
|
||||
|
||||
</style>
|
@ -0,0 +1,11 @@
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>main</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="sass">
|
||||
|
||||
</style>
|
@ -0,0 +1,11 @@
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>main</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="sass">
|
||||
|
||||
</style>
|
@ -0,0 +1,159 @@
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { storage } from "@/utils/storage";
|
||||
import logo from "@/assets/wordmark.png";
|
||||
|
||||
import logo2 from "@/assets/workflow.png";
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const data = ref({
|
||||
form: false,
|
||||
userId: "",
|
||||
userPw: "",
|
||||
loading: false,
|
||||
snackbar: false,
|
||||
snackbarText: "",
|
||||
snackbarColor: "",
|
||||
});
|
||||
|
||||
const resetForm = () => {
|
||||
data.value.userId = "";
|
||||
data.value.userPw = "";
|
||||
data.value.loading = false;
|
||||
};
|
||||
|
||||
const signIn = () => {
|
||||
// if (!data.value.form) return;
|
||||
// data.value.loading = true;
|
||||
// setTimeout(() => (data.value.loading = false), 2000);
|
||||
|
||||
// const params = {
|
||||
// userId: data.value.userId,
|
||||
// password: data.value.userPw,
|
||||
// };
|
||||
//
|
||||
// UserManagerService.signIn(params).then((d) => {
|
||||
// if (d.data.success === true) {
|
||||
// storage.setAuth(d.data.data);
|
||||
router.push("/main");
|
||||
// } else {
|
||||
// resetForm();
|
||||
// data.value.snackbar = true;
|
||||
// }
|
||||
// });
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-container :fluid="true" class="pa-0">
|
||||
<v-sheet
|
||||
class="background-image w-100 h-screen d-flex align-center justify-center flex-column"
|
||||
>
|
||||
<v-card flat class="bg-transparent d-flex align-center flex-column">
|
||||
<v-card
|
||||
class="mx-auto pa-10 mb-4 login-box rounded-lg d-flex flex-column"
|
||||
style="min-width: 450px !important;"
|
||||
density="comfortable"
|
||||
>
|
||||
<div class="mb-4 w-100 d-flex justify-center">
|
||||
<div
|
||||
class="bg-transparent rounded-circle pa-2"
|
||||
style="border: 1.5px solid #f7f7f8"
|
||||
>
|
||||
<v-icon>mdi-shield-key-outline</v-icon>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="text-h5 pb-2 text-center font-weight-bold">
|
||||
Autoflow Web Console
|
||||
</div>
|
||||
|
||||
<v-form v-model="data.form" @submit.prevent="signIn" class="mt-3">
|
||||
<v-text-field
|
||||
v-model="data.userId"
|
||||
:readonly="data.loading"
|
||||
class="mb-2"
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
placeholder="아이디를 입력해주세요."
|
||||
></v-text-field>
|
||||
|
||||
<v-text-field
|
||||
v-model="data.userPw"
|
||||
:readonly="data.loading"
|
||||
type="password"
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
class="mb-2"
|
||||
placeholder="비밀번호를 입력해주세요."
|
||||
></v-text-field>
|
||||
|
||||
<v-btn
|
||||
:disabled="!data.form"
|
||||
:loading="data.loading"
|
||||
block
|
||||
color="primary"
|
||||
size="large"
|
||||
type="submit"
|
||||
variant="flat"
|
||||
>
|
||||
login
|
||||
</v-btn>
|
||||
</v-form>
|
||||
</v-card>
|
||||
</v-card>
|
||||
|
||||
<v-sheet
|
||||
class="position-absolute w-100 bg-transparent pa-4"
|
||||
style="bottom: 0; left: 0"
|
||||
>
|
||||
<v-sheet class="bg-shades-transparent d-flex align-end"
|
||||
>Copyright © 2025 Autoflow Web Console
|
||||
</v-sheet>
|
||||
</v-sheet>
|
||||
<v-sheet
|
||||
class="position-absolute w-100 bg-transparent pa-4"
|
||||
style="bottom: 0; right: 0"
|
||||
>
|
||||
<v-sheet class="bg-shades-transparent d-flex justify-end">
|
||||
<img :src="logo" style="width: 5%" />
|
||||
</v-sheet>
|
||||
</v-sheet>
|
||||
</v-sheet>
|
||||
</v-container>
|
||||
|
||||
<v-snackbar
|
||||
v-model="data.snackbar"
|
||||
timeout="2000"
|
||||
location="button"
|
||||
:color="data.snackbarColor"
|
||||
>
|
||||
{{ data.snackbarText }}
|
||||
<template #actions>
|
||||
<v-btn variant="text" @click="data.snackbar = false"> 닫기 </v-btn>
|
||||
</template>
|
||||
</v-snackbar>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.login-box {
|
||||
background-color: rgba(18, 18, 18, 0.4); /* 흰색 배경에 30% 불투명도 */
|
||||
backdrop-filter: blur(10px); /* 배경 블러 효과 */
|
||||
}
|
||||
|
||||
.background-image {
|
||||
background-image: linear-gradient(
|
||||
90deg,
|
||||
rgba(19, 18, 18, 0.5),
|
||||
rgba(19, 18, 18, 0.3),
|
||||
rgba(19, 18, 18, 0.3),
|
||||
rgba(19, 18, 18, 0.5)
|
||||
),url("@/assets/4117551.jpg"); /* 배경 이미지 경로 */
|
||||
background-size: cover; /* 이미지가 화면을 꽉 채우도록 설정 */
|
||||
background-position: center; /* 이미지 중앙 정렬 */
|
||||
background-repeat: no-repeat; /* 이미지 반복 방지 */
|
||||
min-height: 100vh; /* 화면 전체 높이 설정 */
|
||||
}
|
||||
</style>
|
@ -0,0 +1,11 @@
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>main</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="sass">
|
||||
|
||||
</style>
|
@ -0,0 +1,5 @@
|
||||
# Pages
|
||||
|
||||
Vue components created in this folder will automatically be converted to navigatable routes.
|
||||
|
||||
Full documentation for this feature can be found in the Official [unplugin-vue-router](https://github.com/posva/unplugin-vue-router) repository.
|
@ -0,0 +1,11 @@
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>main</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="sass">
|
||||
|
||||
</style>
|
@ -0,0 +1,11 @@
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>main</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="sass">
|
||||
|
||||
</style>
|
@ -0,0 +1,11 @@
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>main</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="sass">
|
||||
|
||||
</style>
|
@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<HelloWorld />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
//
|
||||
</script>
|
@ -0,0 +1,3 @@
|
||||
# Plugins
|
||||
|
||||
Plugins are a way to extend the functionality of your Vue application. Use this folder for registering plugins that you want to use globally.
|
@ -0,0 +1,17 @@
|
||||
/**
|
||||
* plugins/index.js
|
||||
*
|
||||
* Automatically included in `./src/main.js`
|
||||
*/
|
||||
|
||||
// Plugins
|
||||
import vuetify from './vuetify'
|
||||
import pinia from '@/stores'
|
||||
import router from '@/router'
|
||||
|
||||
export function registerPlugins (app) {
|
||||
app
|
||||
.use(vuetify)
|
||||
.use(router)
|
||||
.use(pinia)
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
/**
|
||||
* plugins/vuetify.js
|
||||
*
|
||||
* Framework documentation: https://vuetifyjs.com`
|
||||
*/
|
||||
|
||||
// Styles
|
||||
import '@mdi/font/css/materialdesignicons.css'
|
||||
import 'vuetify/styles'
|
||||
|
||||
// Composables
|
||||
import { createVuetify } from 'vuetify'
|
||||
|
||||
// https://vuetifyjs.com/en/introduction/why-vuetify/#feature-guides
|
||||
export default createVuetify({
|
||||
theme: {
|
||||
defaultTheme: 'dark',
|
||||
},
|
||||
})
|
@ -0,0 +1,146 @@
|
||||
import { createRouter, createWebHistory } from "vue-router";
|
||||
import { storage } from "@/utils/storage";
|
||||
|
||||
|
||||
const rootPath = import.meta.env.VITE_ROOT_PATH;
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: `/`,
|
||||
component: () => import('@/layouts/default.vue'),
|
||||
redirect: { name: "signin" },
|
||||
children: [
|
||||
{
|
||||
name: "main",
|
||||
path: `/main`,
|
||||
meta: {
|
||||
title: "",
|
||||
requiresAuth: false,
|
||||
},
|
||||
component: () => import('@/pages/MainView.vue'),
|
||||
},
|
||||
{
|
||||
name: "home",
|
||||
path: `/home`,
|
||||
meta: {
|
||||
title: "Home",
|
||||
requiresAuth: false,
|
||||
},
|
||||
component: () => import("@/pages/HomeView.vue"),
|
||||
},
|
||||
{
|
||||
name: "workflows",
|
||||
path: `/workflows`,
|
||||
meta: {
|
||||
title: "Workflows",
|
||||
requiresAuth: false,
|
||||
},
|
||||
component: () => import("@/pages/WorkflowView.vue"),
|
||||
},
|
||||
{
|
||||
name: "workflow-step-config",
|
||||
path: `/workflow-step-config`,
|
||||
meta: {
|
||||
title: "Workflow Step Config",
|
||||
requiresAuth: false,
|
||||
},
|
||||
component: () => import("@/pages/WorkflowStepConfigView.vue"),
|
||||
},
|
||||
{
|
||||
name: "run",
|
||||
path: `/run`,
|
||||
meta: {
|
||||
title: "Run",
|
||||
requiresAuth: false,
|
||||
},
|
||||
redirect: { name: "experiment" },
|
||||
children: [
|
||||
{
|
||||
name: "experiment",
|
||||
path: `/run/experiment`,
|
||||
meta: {
|
||||
title: "Experiment",
|
||||
requiresAuth: false,
|
||||
},
|
||||
component: () => import("@/pages/ExperimentView.vue"),
|
||||
},
|
||||
{
|
||||
name: "Excutions",
|
||||
path: `/run/excutions`,
|
||||
meta: {
|
||||
title: "Excutions",
|
||||
requiresAuth: false,
|
||||
},
|
||||
component: () => import("@/pages/ExcutionsView.vue"),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "deployment",
|
||||
path: `/deployment`,
|
||||
meta: {
|
||||
title: "Deployment",
|
||||
requiresAuth: false,
|
||||
},
|
||||
component: () => import("@/pages/DeploymentView.vue"),
|
||||
},
|
||||
{
|
||||
name: "training-script",
|
||||
path: `/training-script`,
|
||||
meta: {
|
||||
title: "Training Script",
|
||||
requiresAuth: true,
|
||||
},
|
||||
component: () => import("@/pages/TrainingScriptView.vue"),
|
||||
},
|
||||
{
|
||||
name: "datasets",
|
||||
path: `/datasets`,
|
||||
meta: {
|
||||
title: "Datasets",
|
||||
requiresAuth: true,
|
||||
},
|
||||
component: () => import("@/pages/DatasetView.vue"),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "signin",
|
||||
path: `/signin`,
|
||||
meta: {
|
||||
title: "로그인",
|
||||
requiresAuth: false,
|
||||
},
|
||||
component: () => import('@/pages/LoginView.vue'),
|
||||
},
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.VITE_ROOT_PATH),
|
||||
routes,
|
||||
});
|
||||
|
||||
// router.beforeEach((to) => {
|
||||
// if (!storage.getAuth() && to.name !== "signin") {
|
||||
// return { name: "signin" };
|
||||
// } else if (storage.getAuth() && to.name === "signin") {
|
||||
// return { name: "main" };
|
||||
// }
|
||||
//
|
||||
// // 권한 검사
|
||||
// if (to.meta.requiresAuth) {
|
||||
// if (storage.getAuth().auth !== "ADMIN") {
|
||||
// // const store = commonStore();
|
||||
// // store.setSnackbarMsg({
|
||||
// // text: "접근 권한이 없습니다.",
|
||||
// // result: 500,
|
||||
// // color: "error",
|
||||
// // });
|
||||
// return { name: "main" };
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return true; // 허용된 경우 라우트 진행
|
||||
// });
|
||||
|
||||
export default router;
|
@ -0,0 +1,5 @@
|
||||
# Store
|
||||
|
||||
Pinia stores are used to store reactive state and expose actions to mutate it.
|
||||
|
||||
Full documentation for this feature can be found in the Official [Pinia](https://pinia.esm.dev/) repository.
|
@ -0,0 +1,8 @@
|
||||
// Utilities
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useAppStore = defineStore('app', {
|
||||
state: () => ({
|
||||
//
|
||||
}),
|
||||
})
|
@ -0,0 +1,4 @@
|
||||
// Utilities
|
||||
import { createPinia } from 'pinia'
|
||||
|
||||
export default createPinia()
|
@ -0,0 +1,3 @@
|
||||
# Styles
|
||||
|
||||
This directory is for configuring the styles of the application.
|
@ -0,0 +1,10 @@
|
||||
/**
|
||||
* src/styles/settings.scss
|
||||
*
|
||||
* Configures SASS variables and Vuetify overwrites
|
||||
*/
|
||||
|
||||
// https://vuetifyjs.com/features/sass-variables/`
|
||||
// @use 'vuetify/settings' with (
|
||||
// $color-pack: false
|
||||
// );
|
@ -0,0 +1,52 @@
|
||||
export const menuUtils = {
|
||||
menuItem: [
|
||||
{
|
||||
title: "Home",
|
||||
path: "/home",
|
||||
value: "home",
|
||||
icon: "mdi-monitor-multiple",
|
||||
},
|
||||
{
|
||||
title: "Workflows",
|
||||
path: "/workflows",
|
||||
value: "workflows",
|
||||
icon: "mdi-code-braces",
|
||||
},
|
||||
{
|
||||
title: "Workflow Step Config",
|
||||
path: "/workflow-step-config",
|
||||
value: "workflow-step-config",
|
||||
icon: "mdi-hammer-wrench",
|
||||
},
|
||||
{
|
||||
title: "Run",
|
||||
path: "/run",
|
||||
value: "run",
|
||||
icon: "mdi-format-list-bulleted-square",
|
||||
depth: [
|
||||
{ title: "Experiment", path: "/run/experiment" },
|
||||
{ title: "Excutions", path: "/run/excutions" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Deployment",
|
||||
path: "/deployment",
|
||||
value: "deployment",
|
||||
icon: "mdi-folder-search",
|
||||
},
|
||||
],
|
||||
adminMenuItem: [
|
||||
{
|
||||
title: "Training Script",
|
||||
path: "/training-script",
|
||||
value: "training-script",
|
||||
icon: "mdi-account",
|
||||
},
|
||||
{
|
||||
title: "Datasets",
|
||||
path: "/datasets",
|
||||
value: "datasets",
|
||||
icon: "mdi-account",
|
||||
},
|
||||
],
|
||||
};
|
@ -0,0 +1,46 @@
|
||||
export const storage = {
|
||||
get: (key) => {
|
||||
return localStorage.getItem(key);
|
||||
},
|
||||
set: (key, value) => {
|
||||
localStorage.setItem(key, value);
|
||||
},
|
||||
getToken: () => {
|
||||
const authString = localStorage.getItem("autoflow-auth");
|
||||
if (authString !== null) {
|
||||
const auth = JSON.parse(authString);
|
||||
return auth.token;
|
||||
}
|
||||
return "";
|
||||
},
|
||||
getUserId: () => {
|
||||
const authString = localStorage.getItem("autoflow-auth");
|
||||
if (authString !== null) {
|
||||
const auth = JSON.parse(authString);
|
||||
return auth.userId;
|
||||
}
|
||||
return "";
|
||||
},
|
||||
getId: () =>{
|
||||
const authString = localStorage.getItem("autoflow-auth");
|
||||
if (authString !== null) {
|
||||
const auth = JSON.parse(authString);
|
||||
return auth.id;
|
||||
}
|
||||
return "";
|
||||
},
|
||||
|
||||
getAuth: () => {
|
||||
const authString = localStorage.getItem("autoflow-auth");
|
||||
if (authString !== null) {
|
||||
return JSON.parse(authString);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
setAuth: (value) => {
|
||||
localStorage.setItem("autoflow-auth", JSON.stringify(value));
|
||||
},
|
||||
clearAuth: () => {
|
||||
localStorage.removeItem("autoflow-auth");
|
||||
},
|
||||
};
|
@ -0,0 +1,33 @@
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
// @ts-nocheck
|
||||
// Generated by unplugin-vue-router. ‼️ DO NOT MODIFY THIS FILE ‼️
|
||||
// It's recommended to commit this file.
|
||||
// Make sure to add this file to your tsconfig.json file as an "includes" or "files" entry.
|
||||
|
||||
declare module 'vue-router/auto-routes' {
|
||||
import type {
|
||||
RouteRecordInfo,
|
||||
ParamValue,
|
||||
ParamValueOneOrMore,
|
||||
ParamValueZeroOrMore,
|
||||
ParamValueZeroOrOne,
|
||||
} from 'vue-router'
|
||||
|
||||
/**
|
||||
* Route name map generated by unplugin-vue-router
|
||||
*/
|
||||
export interface RouteNamedMap {
|
||||
'/': RouteRecordInfo<'/', '/', Record<never, never>, Record<never, never>>,
|
||||
'/DatasetView': RouteRecordInfo<'/DatasetView', '/DatasetView', Record<never, never>, Record<never, never>>,
|
||||
'/DeploymentView': RouteRecordInfo<'/DeploymentView', '/DeploymentView', Record<never, never>, Record<never, never>>,
|
||||
'/ExcutionsView': RouteRecordInfo<'/ExcutionsView', '/ExcutionsView', Record<never, never>, Record<never, never>>,
|
||||
'/ExperimentView': RouteRecordInfo<'/ExperimentView', '/ExperimentView', Record<never, never>, Record<never, never>>,
|
||||
'/HomeView': RouteRecordInfo<'/HomeView', '/HomeView', Record<never, never>, Record<never, never>>,
|
||||
'/LoginView': RouteRecordInfo<'/LoginView', '/LoginView', Record<never, never>, Record<never, never>>,
|
||||
'/MainView': RouteRecordInfo<'/MainView', '/MainView', Record<never, never>, Record<never, never>>,
|
||||
'/TrainingScriptView': RouteRecordInfo<'/TrainingScriptView', '/TrainingScriptView', Record<never, never>, Record<never, never>>,
|
||||
'/WorkflowStepConfigView': RouteRecordInfo<'/WorkflowStepConfigView', '/WorkflowStepConfigView', Record<never, never>, Record<never, never>>,
|
||||
'/WorkflowView': RouteRecordInfo<'/WorkflowView', '/WorkflowView', Record<never, never>, Record<never, never>>,
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
// Plugins
|
||||
import AutoImport from 'unplugin-auto-import/vite'
|
||||
import Components from 'unplugin-vue-components/vite'
|
||||
import Fonts from 'unplugin-fonts/vite'
|
||||
import Layouts from 'vite-plugin-vue-layouts-next'
|
||||
import Vue from '@vitejs/plugin-vue'
|
||||
import VueRouter from 'unplugin-vue-router/vite'
|
||||
import { VueRouterAutoImports } from 'unplugin-vue-router'
|
||||
import Vuetify, { transformAssetUrls } from 'vite-plugin-vuetify'
|
||||
|
||||
// Utilities
|
||||
import { defineConfig } from 'vite'
|
||||
import { fileURLToPath, URL } from 'node:url'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
VueRouter(),
|
||||
Layouts(),
|
||||
Vue({
|
||||
template: { transformAssetUrls },
|
||||
}),
|
||||
// https://github.com/vuetifyjs/vuetify-loader/tree/master/packages/vite-plugin#readme
|
||||
Vuetify({
|
||||
autoImport: true,
|
||||
styles: {
|
||||
configFile: 'src/styles/settings.scss',
|
||||
},
|
||||
}),
|
||||
Components(),
|
||||
Fonts({
|
||||
google: {
|
||||
families: [{
|
||||
name: 'Roboto',
|
||||
styles: 'wght@100;300;400;500;700;900',
|
||||
}],
|
||||
},
|
||||
}),
|
||||
AutoImport({
|
||||
imports: [
|
||||
'vue',
|
||||
VueRouterAutoImports,
|
||||
{
|
||||
pinia: ['defineStore', 'storeToRefs'],
|
||||
},
|
||||
],
|
||||
eslintrc: {
|
||||
enabled: true,
|
||||
},
|
||||
vueTemplate: true,
|
||||
}),
|
||||
],
|
||||
optimizeDeps: {
|
||||
exclude: [
|
||||
'vuetify',
|
||||
'vue-router',
|
||||
'unplugin-vue-router/runtime',
|
||||
'unplugin-vue-router/data-loaders',
|
||||
'unplugin-vue-router/data-loaders/basic',
|
||||
],
|
||||
},
|
||||
define: { 'process.env': {} },
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('src', import.meta.url)),
|
||||
},
|
||||
extensions: [
|
||||
'.js',
|
||||
'.json',
|
||||
'.jsx',
|
||||
'.mjs',
|
||||
'.ts',
|
||||
'.tsx',
|
||||
'.vue',
|
||||
],
|
||||
},
|
||||
server: {
|
||||
port: 3000,
|
||||
},
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
sass: {
|
||||
api: 'modern-compiler',
|
||||
},
|
||||
scss: {
|
||||
api: 'modern-compiler',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|