ASW-9 feat: GUI页面布局开发

This commit is contained in:
zyh
2024-07-16 14:06:02 +08:00
parent 28b7256483
commit 7bb62881e8
32 changed files with 793 additions and 141 deletions

View File

@@ -1,10 +0,0 @@
* {
margin: 0;
padding: 0;
list-style: none;
}
#app{
width: 100vw;
height: 100vh;
}

View File

@@ -5,7 +5,7 @@
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>AppSketch</title>
<link rel="stylesheet" href="./index.css"/>
<link rel="stylesheet" href="./index.scss"/>
</head>
<body>
<div id="app"></div>

17
index.scss Normal file
View File

@@ -0,0 +1,17 @@
* {
margin: 0;
padding: 0;
list-style: none;
box-sizing: border-box;
}
body{
color: var(--text);
}
#app{
width: 100vw;
height: 100vh;
background-color: var(--background);
}

1
package-lock.json generated
View File

@@ -8,6 +8,7 @@
"name": "app-sketch",
"version": "0.0.0",
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"@vueuse/core": "^10.11.0",
"axios": "^1.7.2",
"codemirror": "^5.65.16",

View File

@@ -9,6 +9,7 @@
"preview": "vite preview"
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"@vueuse/core": "^10.11.0",
"axios": "^1.7.2",
"codemirror": "^5.65.16",

View File

@@ -0,0 +1,3 @@
const avatarUrl = "data:image/png;base64,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"
export default avatarUrl

View File

@@ -0,0 +1,38 @@
<template>
<div id="layout">
<layout-header></layout-header>
<div id="layout-container">
<left-menu></left-menu>
<div class="pageContent">
<router-view></router-view>
</div>
</div>
</div>
</template>
<script setup>
import layoutHeader from '@/components/layout/layoutHeader.vue';
import leftMenu from '@/components/layout/leftMenu.vue';
</script>
<style lang="scss" scoped>
#layout {
width: 100%;
height: 100%;
#layout-container {
height: calc(100vh - 70px);
position: relative;
.pageContent {
padding: 18px 45px 32px 107px;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
gap: 18px 0;
overflow-x: hidden;
overflow-y: auto;
position: relative;
}
}
}
</style>

View File

@@ -0,0 +1,333 @@
<template>
<div id="layout-header">
<!-- left -->
<div class="header-left">
<div class="header-logo">
<el-icon :size="45">
<Loading />
</el-icon>
<p>
<span>Appsketch</span>
<span>Works</span>
</p>
</div>
<el-dropdown class="workspace-dropdown" placement="bottom-start">
<div class="workspace-dropdown-button">
Community
<el-icon class="el-icon--right"><arrow-down /></el-icon>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>Community</el-dropdown-item>
<el-dropdown-item>
<el-icon class="primary-color" :size="16">
<CirclePlus />
</el-icon>
<span>Add a Private Workspace</span>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<!-- search -->
<div id="header-search">
<el-input v-model="keyword" size="large" placeholder="Search">
<template #prefix>
<el-icon><Search /></el-icon>
</template>
</el-input>
</div>
</div>
<!-- right -->
<div class="header-right">
<el-switch
class="theme-switch"
:width="56"
size="large"
v-model="isLight"
inline-prompt
:active-icon="Sunny"
:inactive-icon="Moon"
@change="themeChange"
>
</el-switch>
<el-dropdown
class="avatar-dropdown"
placement="bottom-end"
popper-class="avatar-popper"
>
<div class="avatar-dropdown-img">
<img :src="avatarUrl" alt="" />
<el-icon class="el-icon--right"><arrow-down /></el-icon>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>
<div>
<p class="profile-text">Profile</p>
<p class="profile-info">123456789@gmail.com</p>
</div>
</el-dropdown-item>
<el-dropdown-item>
<el-icon :size="16">
<CircleClose />
</el-icon>
<span class="profile-text">Sign Out</span>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<el-dropdown
class="headerMore-dropdown"
trigger="click"
placement="bottom-end"
popper-class="headerMore-popper"
>
<button class="headerMore-dropdown-button">
<el-icon><Grid /></el-icon>
</button>
<template #dropdown>
<el-dropdown-menu>
<ul class="headerMore-list">
<li class="headerMore-item active">
<el-icon><Setting /></el-icon>
<span>PCAPs</span>
</li>
<li class="headerMore-item">
<el-icon><Setting /></el-icon>
<span>About</span>
</li>
<li class="headerMore-item">
<el-icon><Setting /></el-icon>
<span>company</span>
</li>
<li class="headerMore-item">
<el-icon><Setting /></el-icon>
<span>FAQ</span>
</li>
<li class="headerMore-item">
<el-icon><Setting /></el-icon>
<span>Docs</span>
</li>
<li class="headerMore-item">
<el-icon><Setting /></el-icon>
<span>Resources</span>
</li>
<li class="headerMore-item">
<el-icon><Setting /></el-icon>
<span>Contact</span>
</li>
<li class="headerMore-item">
<el-icon><Setting /></el-icon>
<span>Pricing</span>
</li>
</ul>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</template>
<script setup>
import avatarUrl from './avatar.js';
import { Sunny, Moon } from '@element-plus/icons-vue';
import { toRefs, ref } from 'vue';
import { useMainStore } from '@/store/index';
import { useTheme } from '@/hooks/useTheme';
const props = defineProps({
test: {
type: String,
},
});
const mainStore = useMainStore();
const keyword = ref('');
const { themeSet } = useTheme();
const isLight = ref(mainStore.theme === 'light');
const themeChange = (val) => {
themeSet(val ? 'light' : 'dark');
};
</script>
<style lang="scss" scoped>
#layout-header {
width: 100%;
height: 70px;
background-color: var(--background_secondary);
padding: 14px 32px;
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);
display: flex;
align-items: center;
justify-content: space-between;
.header-left {
align-items: center;
display: flex;
.header-logo {
display: flex;
align-items: center;
gap: 15px;
.el-icon {
color: var(--primary);
}
p {
span {
font-size: 22px;
font-weight: 500;
}
span:last-of-type {
margin-left: 10px;
color: var(--primary);
}
}
}
.workspace-dropdown {
margin-left: 20px;
.workspace-dropdown-button {
outline: none;
cursor: pointer;
display: inline-flex;
justify-content: center;
align-items: center;
gap: 10px;
background: #e0eaff;
border: 1px solid var(--primary);
border-radius: 4px;
color: var(--primary);
height: 27px;
padding: 0 8px;
}
}
#header-search {
margin-left: 60px;
.el-input {
width: 320px;
}
}
}
.header-right {
display: flex;
align-items: center;
gap: 20px;
:deep(.theme-switch) {
.el-icon {
font-size: 20px !important;
color: #fac302 !important;
}
.el-switch__core {
border: none;
background: #636363;
}
.el-icon {
margin-left: 4px;
}
&.is-checked {
.el-switch__core {
background: #e8e8e8;
}
.el-icon {
margin-left: 0px;
}
}
}
.avatar-dropdown {
.avatar-dropdown-img {
outline: none;
cursor: default;
align-items: center;
display: flex;
gap: 0 5px;
img {
width: 36px;
height: 36px;
}
}
}
.headerMore-dropdown {
.headerMore-dropdown-button {
background: transparent;
border: none;
border-radius: 4px;
box-shadow: none;
cursor: pointer;
outline: none;
color: var(--text);
font-size: 22px;
width: 28px;
height: 28px;
display: flex;
justify-content: center;
align-items: center;
&:hover {
color: var(--primary);
}
&[aria-expanded='true'] {
background: #f0f0f0;
color: var(--primary);
}
}
}
}
}
</style>
<style lang="scss">
.avatar-popper {
.profile-text, .el-icon {
color: var(--text);
}
.profile-info{
color: var(--text_secondary);
}
.el-dropdown-menu__item {
padding: 10px 16px;
&:last-of-type {
border-top: 1px solid #ceced2;
}
}
}
.headerMore-popper {
.el-dropdown-menu {
padding: 0;
.headerMore-list {
padding: 8px;
display: flex;
gap: 0 8px;
justify-content: center;
max-width: 224px;
flex-wrap: wrap;
.headerMore-item {
width: 64px;
height: 64px;
align-items: center;
border-radius: 4px;
color: var(--text);
display: flex;
flex-direction: column;
gap: 4px 0;
justify-content: center;
transition: all 0.2s ease-in;
cursor: pointer;
.el-icon {
font-size: 20px;
}
span {
font-size: 14px;
}
&:hover {
color: var(--primary);
}
&.active {
background: #f0f0f0;
color: var(--primary);
}
}
}
}
}
</style>

View File

@@ -0,0 +1,160 @@
<template>
<div id="leftMenu">
<ul class="leftMenu-list">
<li
class="leftMenu-item"
:class="{
active: `${currentRoute}` == item.route,
}"
v-for="item in menuList"
:key="item.route"
@click="jummp(item.route)"
>
<div class="leftMenu-icon">
<el-icon><Notebook /></el-icon>
</div>
<div class="leftMenu-text">{{ item.name }}</div>
</li>
</ul>
</div>
</template>
<script setup>
import { useRouter } from 'vue-router';
import { toRefs, ref, watch } from 'vue';
import { useI18n } from "vue-i18n"
const props = defineProps({
test: {
type: String,
},
});
const { t } = useI18n()
const router = useRouter();
const currentRoute = ref('');
watch(
() => router.currentRoute.value,
(value) => {
currentRoute.value = value.path;
},
{ immediate: true }
);
const jummp = (path) => {
router.push({
path: path,
});
};
const menuList = ref([
{
name: 'Workbooks',
route: '/workbooks',
},
{
name: 'Applications',
route: '/applications',
},
{
name: 'Signatures',
route: '/signatures',
},
{
name: 'Pcaps',
route: '/pcaps',
},
{
name: 'Packages',
route: '/packages',
},
{
name: 'Jobs',
route: '/jobs',
},
{
name: 'Playbooks',
route: '/playbooks',
},
{
name: 'Runners',
route: '/runners',
},
]);
</script>
<style lang="scss" scoped>
#leftMenu {
z-index: 10;
position: absolute;
left: 0;
top: 0;
width: 64px;
height: calc(100vh - 70px);
padding: 24px 0;
transition: width 0.2s ease-in;
background-color: var(--background_secondary);
&:hover {
width: 240px;
.leftMenu-list .leftMenu-item .leftMenu-text {
display: block;
width: 100%;
}
}
.leftMenu-list {
display: flex;
flex-direction: column;
gap: 12px 0;
width: 100%;
.leftMenu-item {
width: 100%;
height: 56px;
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
&:hover {
.leftMenu-icon {
color: var(--primary);
}
.leftMenu-text {
color: var(--primary);
}
}
&.active {
background-color: var(--primary_inactive);
.leftMenu-icon {
color: var(--primary);
}
.leftMenu-text {
color: var(--primary);
}
}
.leftMenu-icon {
flex-shrink: 0;
width: 64px;
height: 56px;
display: flex;
justify-content: center;
align-items: center;
font-size: 32px;
color: var(--text_secondary);
}
.leftMenu-text {
display: none;
width: 0;
transition: width 0.2s ease-in;
padding: 0 5px;
font-size: 18px;
font-weight: 600;
max-height: 56px;
overflow: hidden;
white-space: nowrap;
color: var(--text_secondary);
}
}
}
}
</style>

View File

@@ -6,5 +6,6 @@ export default {
edit: 'Edit',
save: 'Save',
cancel: 'Cancel',
}
}
notFound: 'Not found',
},
};

View File

@@ -6,5 +6,6 @@ export default {
edit: '编辑',
save: '保存',
cancel: '取消',
notFound: '找不到',
}
}

View File

@@ -1,17 +1,21 @@
import { createApp } from 'vue'
import App from './App.vue'
import './styles/index.scss'
import './styles/element/index.scss'
import './styles/index.scss'
import router from "./router"
import { createPinia } from 'pinia'
import ElementPlus from 'element-plus'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import i18n from '@/i18n/index'
const app = createApp(App)
app.use(router)
app.use(createPinia())
app.use(ElementPlus)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
app.use(i18n)
app.mount('#app')

View File

@@ -7,11 +7,48 @@ const router = createRouter({
routes: [
{
path: '/',
redirect: '/home',
component: () => import('@/components/layout/index.vue'),
redirect: '/workbooks',
children: [
{
path: '/workbooks',
component: () => import('@/views/workbooks.vue'),
},
{
path: '/applications',
component: () => import('@/views/applications.vue'),
},
{
path: '/signatures',
component: () => import('@/views/signatures.vue'),
},
{
path: '/pcaps',
component: () => import('@/views/pcaps.vue'),
},
{
path: '/packages',
component: () => import('@/views/packages.vue'),
},
{
path: '/jobs',
component: () => import('@/views/jobs.vue'),
},
{
path: '/playbooks',
component: () => import('@/views/playbooks.vue'),
},
{
path: '/runners',
component: () => import('@/views/runners.vue'),
},
],
},
//404页面捕获
{
path: '/home',
component: () => import('../views/home.vue'),
path: '/:pathMatch(.*)*',
name: 'NotFound',
component: () => import('@/views/404.vue')
},
],
});

4
src/styles/common.scss Normal file
View File

@@ -0,0 +1,4 @@
.primary-color{
color: var(--primary) !important;
}

View File

@@ -5,4 +5,7 @@
padding-bottom: 1px;
}
}
.diff-commandbar{
display: none;
}
}

View File

@@ -1,7 +1,7 @@
@forward 'element-plus/theme-chalk/src/dark/var.scss' with (
$colors: (
'primary': (
'base': #00ccff,
'base': #185bdc,
),
),
);

View File

@@ -1,7 +1,7 @@
@forward 'element-plus/theme-chalk/src/common/var.scss' with (
$colors: (
'primary': (
'base': pink,
'base': #185bdc,
),
),
);

View File

@@ -1,3 +1,4 @@
/* 加载主题变量 */
@import './theme/index.scss';
@import './components/index.scss';
@import './components/index.scss';
@import './common.scss';

View File

@@ -1,9 +1,48 @@
html.dark{
/* 1.字色 */
// 标题字色
--color-text-primary: #D8D8D8;
// 普通字色
--color-text-regular: #BEBEBE;
// 次要字色
--color-text-secondary: #999999;
--primary: #467be1;
--primary_inactive: #283164;
--primary_inactive_hover: #535fa3;
--success: #52db57;
--success_secondary: #cff9d3;
--error: #db5264;
--background: #262836;
--background_secondary: #1e1e29;
--text: #f5f5f5;
--text_secondary: #bcbcbc;
--border: #f7f7f7;
--pcap_input_background: #1e1e29;
--table_border: #505050;
--table_header: #292933;
--folder_background_active: #19294b;
--filter_background: #283164;
--filter_hover: #364289;
--table_row_hover: #283164;
--chart_box_background: #1e1e29;
--table_small_header: #1e1e2d;
--table_small_row: #12121d;
--table_small_border: #272727;
--drag_chart_hover: #30303b;
--timebar_background: #1d223f;
--menu_background: #20212a;
--log_tabs: #505050;
--local_chip: #434343;
--info_background: #535fa3;
--error_background: #db5264;
--error_icon: #ffecec;
--error_secondary: #fae3e3;
}
// 覆盖elmentui主题色
:root{
--el-text-color-primary : var(--text);
--el-text-color-regular : var(--text);
--el-text-color-secondary : var(--text);
.el-input {
--el-input-icon-color: var(--text);
}
.el-dropdown__popper{
--el-dropdown-menuItem-hover-fill: var(--primary_inactive);
}
}

View File

@@ -1,9 +1,48 @@
:root{
/* 1.字色 */
// 标题字色
--color-text-primary: #333333;
// 普通字色
--color-text-regular: #666666;
// 标题字色
--color-text-secondary: #999999;
}
:root {
--primary: #185bdc;
--primary_inactive: #e0eaff;
--primary_inactive_hover: #cddbf8;
--success: #2ca538;
--success_secondary: #cff9d3;
--error: #980f0f;
--background: #f8fbff;
--background_secondary: #fff;
--text: #0e1236;
--text_secondary: #98a0bc;
--border: #ceced2;
--pcap_input_background: #e0eaff;
--table_border: #f7f7f7;
--table_header: #fafafa;
--folder_background_active: #e0eaff;
--filter_background: #e0eaff;
--filter_hover: #cadcff;
--table_row_hover: #f6f9ff;
--chart_box_background: #f2f7ff;
--table_small_header: #e5eeff;
--table_small_row: #f5f9ff;
--table_small_border: #ececec;
--drag_chart_hover: #f1f6ff;
--timebar_background: #f9faff;
--menu_background: #fff;
--log_tabs: #ebeaea;
--local_chip: #ededed;
--info_background: #ecf0ff;
--error_background: #ffecec;
--error_icon: #980f0f;
--error_secondary: #fae3e3;
}
// 覆盖elmentui主题色
:root {
--el-text-color-primary: var(--text);
--el-text-color-regular: var(--text);
--el-text-color-secondary: var(--text);
.el-input {
--el-input-icon-color: var(--text);
}
.el-dropdown__popper {
--el-dropdown-menuItem-hover-fill: var(--primary_inactive);
}
}

View File

@@ -1 +0,0 @@
$aaa:green

28
src/views/404.vue Normal file
View File

@@ -0,0 +1,28 @@
<template>
<div id="notFound">
<h1>404</h1>
<p>{{$t('overall.notFound')}}</p>
</div>
</template>
<script setup></script>
<style lang="scss" scoped>
#notFound {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
h1 {
font-size: 72px;
color: var(--text);
margin-bottom: 20px;
}
p {
font-size: 46px;
color: var(--text_secondary);
}
}
</style>

View File

@@ -0,0 +1,7 @@
<template>
<div id="applications">applications</div>
</template>
<script setup></script>
<style lang="scss" scoped></style>

View File

@@ -1,104 +0,0 @@
<template>
<el-switch v-model="isDark" @change="themeChange"/>
<el-button type="primary">{{ isDark ? 'Dark' : 'Light' }}</el-button>
<p>自定义字体主题</p>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="date" label="Date" />
<el-table-column prop="name" label="Name" />
<el-table-column prop="address" label="Address" />
</el-table>
<el-date-picker
v-model="date"
type="datetime"
/>
<el-select
v-model="value"
placeholder="Select"
size="large"
style="width: 240px"
@change="language"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<p>{{$t('overall.add') }}</p>
<p>{{$t('overall.edit') }}</p>
<p>{{$t('overall.save') }}</p>
<jsonEditor></jsonEditor>
<jsonDiff></jsonDiff>
</template>
<script setup>
import jsonEditor from '@/components/jsonEditor.vue'
import jsonDiff from '@/components/jsonDiff.vue'
import { ref, } from 'vue'
import { useI18n } from "vue-i18n"
import { useMainStore } from '@/store/index'
import { useTheme } from '@/hooks/useTheme'
const { t, locale } = useI18n()
const value = ref(locale.value)
const options = [
{
value: 'en',
label: 'English',
},
{
value: 'zh',
label: '中文',
},
]
const mainStore = useMainStore()
const language = (val)=>{
locale.value = val
mainStore.language = val
localStorage.setItem('asg-language', val)
}
const { themeSet } = useTheme()
const isDark = ref(mainStore.theme === 'dark' )
const themeChange = (val)=>{
themeSet(val? 'dark' : 'light')
}
const date = ref('')
const tableData = [
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
]
</script>
<style lang="scss" scoped>
p {
color: var(--color-text-primary);
}
</style>

7
src/views/jobs.vue Normal file
View File

@@ -0,0 +1,7 @@
<template>
<div id="jobs">jobs</div>
</template>
<script setup></script>
<style lang="scss" scoped></style>

7
src/views/packages.vue Normal file
View File

@@ -0,0 +1,7 @@
<template>
<div id="packages">packages</div>
</template>
<script setup></script>
<style lang="scss" scoped></style>

7
src/views/pcaps.vue Normal file
View File

@@ -0,0 +1,7 @@
<template>
<div id="pcaps">pcaps</div>
</template>
<script setup></script>
<style lang="scss" scoped></style>

7
src/views/playbooks.vue Normal file
View File

@@ -0,0 +1,7 @@
<template>
<div id="playbooks">playbooks</div>
</template>
<script setup></script>
<style lang="scss" scoped></style>

7
src/views/runners.vue Normal file
View File

@@ -0,0 +1,7 @@
<template>
<div id="runners">runners</div>
</template>
<script setup></script>
<style lang="scss" scoped></style>

7
src/views/signatures.vue Normal file
View File

@@ -0,0 +1,7 @@
<template>
<div id="signatures">signatures</div>
</template>
<script setup></script>
<style lang="scss" scoped></style>

7
src/views/workbooks.vue Normal file
View File

@@ -0,0 +1,7 @@
<template>
<div id="workbooks">workbooks</div>
</template>
<script setup></script>
<style lang="scss" scoped></style>

View File

@@ -9,6 +9,7 @@ export default defineConfig({
alias: {
//别名配置
"@": path.resolve(__dirname, "./src"),
'~/': `${path.resolve(__dirname, 'src')}/`,
},
},
//本地运行配置,以及反向代理配置