Browse Source

[Fix-7525][Feature][UI Next] Provide a common layout for the module of dolphinscheduler-ui-next. (#7526)

* add layout

* add layout

* add layout

* add routes

* add routes

* modify layout

* modify layout

* modify layout

* modify layout

* improve a few issues with code specification
3.0.0/version-upgrade
calvin 3 years ago committed by GitHub
parent
commit
49662c7865
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      dolphinscheduler-ui-next/package.json
  2. 5
      dolphinscheduler-ui-next/src/App.tsx
  3. 99
      dolphinscheduler-ui-next/src/assets/images/nav-logo.svg
  4. 52
      dolphinscheduler-ui-next/src/layouts/basic/components/header/index.module.scss
  5. 106
      dolphinscheduler-ui-next/src/layouts/basic/components/header/index.tsx
  6. 36
      dolphinscheduler-ui-next/src/layouts/basic/components/logo/index.module.scss
  7. 38
      dolphinscheduler-ui-next/src/layouts/basic/components/logo/index.tsx
  8. 19
      dolphinscheduler-ui-next/src/layouts/basic/components/sider/index.module.scss
  9. 79
      dolphinscheduler-ui-next/src/layouts/basic/components/sider/index.tsx
  10. 54
      dolphinscheduler-ui-next/src/layouts/basic/index.module.scss
  11. 234
      dolphinscheduler-ui-next/src/layouts/basic/index.tsx
  12. 12
      dolphinscheduler-ui-next/src/layouts/content/Content.tsx
  13. 24
      dolphinscheduler-ui-next/src/router/index.ts
  14. 181
      dolphinscheduler-ui-next/src/router/routes.ts
  15. 46
      dolphinscheduler-ui-next/src/store/route/route.ts
  16. 25
      dolphinscheduler-ui-next/src/store/route/types.ts

9
dolphinscheduler-ui-next/package.json

@ -28,6 +28,15 @@
"@types/qs": "^6.9.7", "@types/qs": "^6.9.7",
"@typescript-eslint/eslint-plugin": "^5.6.0", "@typescript-eslint/eslint-plugin": "^5.6.0",
"@typescript-eslint/parser": "^5.6.0", "@typescript-eslint/parser": "^5.6.0",
"@vicons/antd": "^0.11.0",
"@vicons/carbon": "^0.11.0",
"@vicons/fa": "^0.11.0",
"@vicons/fluent": "^0.11.0",
"@vicons/ionicons4": "^0.11.0",
"@vicons/ionicons5": "^0.11.0",
"@vicons/material": "^0.11.0",
"@vicons/tabler": "^0.11.0",
"@vicons/utils": "^0.1.4",
"@vitejs/plugin-vue": "^1.10.2", "@vitejs/plugin-vue": "^1.10.2",
"@vitejs/plugin-vue-jsx": "^1.3.1", "@vitejs/plugin-vue-jsx": "^1.3.1",
"dart-sass": "^1.25.0", "dart-sass": "^1.25.0",

5
dolphinscheduler-ui-next/src/App.tsx

@ -17,17 +17,18 @@
import { defineComponent, computed } from 'vue' import { defineComponent, computed } from 'vue'
import { NConfigProvider, darkTheme, GlobalThemeOverrides } from 'naive-ui' import { NConfigProvider, darkTheme, GlobalThemeOverrides } from 'naive-ui'
import { useAsyncRouteStore } from '@/store/route/route'
import { useThemeStore } from '@/store/theme/theme' import { useThemeStore } from '@/store/theme/theme'
import themeList from '@/themes' import themeList from '@/themes'
const App = defineComponent({ const App = defineComponent({
name: 'App', name: 'App',
setup() { setup() {
const asyncRouteStore = useAsyncRouteStore()
const themeStore = useThemeStore() const themeStore = useThemeStore()
const currentTheme = computed(() => const currentTheme = computed(() =>
themeStore.darkTheme ? darkTheme : undefined themeStore.darkTheme ? darkTheme : undefined
) )
return { return {
currentTheme, currentTheme,
} }
@ -42,7 +43,7 @@ const App = defineComponent({
<NConfigProvider <NConfigProvider
theme={this.currentTheme} theme={this.currentTheme}
themeOverrides={themeOverrides} themeOverrides={themeOverrides}
style={{ width: '100%', height: '100vh' }} style={{ width: '100%', height: '100vh', overflow: 'hidden' }}
> >
<router-view /> <router-view />
</NConfigProvider> </NConfigProvider>

99
dolphinscheduler-ui-next/src/assets/images/nav-logo.svg

@ -0,0 +1,99 @@
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<!--<?xml version="1.0" encoding="utf-8"?>-->
<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 180 46" style="enable-background:new 0 0 180 46;" xml:space="preserve">
<style type="text/css">
.st0{fill:#85CDF0;}
.st1{fill:#0097E0;}
.st2{fill:#FFFFFF;}
</style>
<g>
<path class="st0" d="M29.9,25.6H14.5c-2.1,0-3.8,1.8-3.8,3.9c0,0.8,0.2,1.6,0.7,2.2c0.3-0.1,0.6-0.2,0.9-0.3l0,0l0,0
c1-0.4,2.1-1.2,2.8-1.8c0.2-0.1,0.3-0.2,0.4-0.3c0.1-0.1,0.2-0.2,0.4-0.3c0.6-0.5,1.4-1.1,2.6-1.3c0.2,0,0.4,0,0.7,0
c1,0,1.9,0.3,2.5,0.9c0.2-0.1,0.4-0.2,0.5-0.3c0.3-0.1,0.5-0.3,0.7-0.4s0.5-0.2,0.8-0.2c0.6,0,1.2,0.3,1.5,0.9
c0.2,0.4,0.4,1.1-0.2,2.2c-0.1,0.2-0.3,0.4-0.4,0.7c-0.3,0.6-0.7,1.2-1.3,2h6.6c2.1,0,3.8-1.8,3.8-3.9C33.7,27.4,32,25.6,29.9,25.6
z"/>
<path class="st1" d="M5.7,20.3h1c0.6,0,1-0.4,1-1s-0.4-1-1-1h-1c-2.1,0-3.7-1.7-3.7-3.9c0-2.1,1.6-3.8,3.6-3.9v2.1l2.8-2.9l-2.8-3
v1.7c-3,0.2-5.6,2.8-5.6,6C0,17.7,2.5,20.3,5.7,20.3z"/>
<path class="st1" d="M38.4,18.6h-1c-0.6,0-1,0.4-1,1s0.4,1,1,1h1c2.1,0,3.7,1.7,3.7,3.9c0,2.1-1.6,3.8-3.6,3.9v-2.1L35.7,29l2.8,3
v-1.7c3-0.1,5.5-2.6,5.5-5.9C44.1,21.1,41.6,18.6,38.4,18.6z"/>
<path class="st0" d="M29.9,15.3H14.5c-2.1,0-3.8,1.8-3.8,3.9s1.7,3.9,3.8,3.9h15.4c2.1,0,3.8-1.8,3.8-3.9S32,15.3,29.9,15.3z"/>
<path class="st0" d="M29.9,5.1H14.5c-2.1,0-3.8,1.8-3.8,3.9l0,0c0,2.2,1.7,3.9,3.8,3.9h15.4c2.1,0,3.8-1.8,3.8-3.9l0,0
C33.7,6.8,32,5.1,29.9,5.1z"/>
<path class="st1" d="M19.5,39c0.2,1.3-0.4,1-0.9,0.6c-0.3-0.2-1.2-0.7-1.7-1c0.8-0.4,1.5-0.9,2-1.3C19.2,37.8,19.4,38.4,19.5,39z
M18.4,31c-0.1,0-0.2,0.1-0.2,0.2s0.1,0.2,0.2,0.2s0.2-0.1,0.2-0.2S18.5,31,18.4,31z M24.2,30.3c-0.8,1.3-1.8,3.3-4.6,5.9
c-0.6,0.6-1.9,1.5-3.2,2.1c-0.4,0.2-1,0.4-1.6,0.6c0.4-0.6,0.6-1.2,0.7-1.8h-0.3c-0.7,2.3-2.4,4.3-4.5,5c-1.3,0.4-1-0.3-0.8-0.9
c0.2-0.4,0.7-2.4,0.9-3.4l-0.4-0.1c0,0,0,0.2-0.1,0.4s-0.1,0.5-0.2,0.8c-1.2-0.4-2.4-1-3.3-2.1c-1.3-1.6-1.9-3.1-2.2-5.9
c-0.1-0.7-0.8-1.4-1.6-2.3c-1-1.1-1-2.7-0.4-2.9c0.4-0.1,2.5,0.9,3.2,1.4c0.8-0.6,2-1.6,2.4-1.3C8.5,26,8.6,27,7.9,28.5
c-1.5,3.1,0.6,4,1.1,4.1c0.9,0.2,2.3,0.3,3.7-0.3c1.3-0.5,2.9-1.8,3.4-2.2c0.7-0.5,1.4-1.2,2.5-1.4c1.3-0.2,2.3,0.2,2.8,1.1
c0.6-0.2,1.4-0.8,2-1C23.9,28.5,25,28.9,24.2,30.3z M18.8,31.4c0-0.3-0.2-0.6-0.5-0.6s-0.5,0.3-0.5,0.6S18,32,18.3,32
C18.6,31.9,18.8,31.7,18.8,31.4z"/>
<g>
<path class="st2" d="M49,17.6h4.8c1.6,0,2.9,0.6,3.8,1.8c0.8,1.1,1.2,2.5,1.2,4.2c0,1.3-0.2,2.5-0.7,3.6c-0.8,1.9-2.3,2.8-4.3,2.8
H49V17.6z M53.5,28.6c0.5,0,1-0.1,1.3-0.2c0.6-0.2,1.1-0.6,1.5-1.3c0.3-0.5,0.5-1.1,0.7-1.9c0.1-0.5,0.1-0.9,0.1-1.3
c0-1.5-0.3-2.7-0.9-3.6c-0.6-0.8-1.5-1.3-2.8-1.3h-2.8v9.5L53.5,28.6L53.5,28.6z"/>
<path class="st2" d="M67.3,21.9c0.8,0.8,1.2,1.9,1.2,3.4s-0.3,2.7-1,3.6c-0.7,1-1.7,1.4-3.2,1.4c-1.2,0-2.2-0.4-2.9-1.3
c-0.7-0.8-1.1-2-1.1-3.4c0-1.5,0.4-2.7,1.1-3.6c0.7-0.9,1.7-1.4,3-1.4C65.5,20.7,66.5,21.1,67.3,21.9z M66.3,27.9
c0.4-0.8,0.5-1.6,0.5-2.5c0-0.8-0.1-1.5-0.4-2.1c-0.4-0.8-1.1-1.2-2.1-1.2c-0.9,0-1.5,0.4-1.9,1.1s-0.6,1.6-0.6,2.6
s0.2,1.8,0.6,2.4c0.4,0.6,1,1,1.9,1C65.3,29.1,66,28.7,66.3,27.9z"/>
<path class="st2" d="M70.3,17.6h1.5V30h-1.5V17.6z"/>
<path class="st2" d="M73.8,21h1.4v1.2c0.3-0.4,0.6-0.7,1-1c0.5-0.3,1.1-0.5,1.8-0.5c1,0,1.8,0.4,2.5,1.2c0.7,0.8,1,1.9,1,3.4
c0,2-0.5,3.4-1.5,4.2c-0.6,0.5-1.4,0.8-2.2,0.8c-0.7,0-1.2-0.1-1.7-0.4c-0.3-0.2-0.6-0.5-0.9-0.9v4.6h-1.5L73.8,21L73.8,21z
M79.4,28.1c0.5-0.6,0.7-1.5,0.7-2.7c0-0.7-0.1-1.3-0.3-1.9c-0.4-1-1.1-1.5-2.1-1.5s-1.7,0.5-2.1,1.6c-0.2,0.6-0.3,1.3-0.3,2.1
c0,0.7,0.1,1.3,0.3,1.8c0.4,0.9,1.1,1.4,2.1,1.4C78.4,29,78.9,28.7,79.4,28.1z"/>
<path class="st2" d="M83.3,17.6h1.5v4.6c0.3-0.5,0.7-0.8,0.9-1c0.5-0.3,1.1-0.5,1.8-0.5c1.3,0,2.1,0.5,2.6,1.4
c0.2,0.5,0.4,1.2,0.4,2.1V30H89v-5.7c0-0.7-0.1-1.2-0.2-1.5c-0.3-0.5-0.8-0.7-1.5-0.7c-0.6,0-1.2,0.2-1.7,0.7
c-0.5,0.4-0.7,1.3-0.7,2.5V30h-1.5V17.6H83.3z"/>
<path class="st2" d="M92.6,17.6h1.5v1.7h-1.5V17.6z M92.6,21h1.5v9h-1.5V21z"/>
<path class="st2" d="M96.4,21h1.4v1.3c0.4-0.5,0.9-0.9,1.3-1.1c0.5-0.2,1-0.3,1.5-0.3c1.2,0,2.1,0.4,2.5,1.3
c0.2,0.5,0.4,1.2,0.4,2.1V30H102v-5.7c0-0.6-0.1-1-0.2-1.3c-0.3-0.6-0.7-0.8-1.4-0.8c-0.3,0-0.6,0-0.9,0.1
c-0.4,0.1-0.8,0.4-1.1,0.7c-0.2,0.3-0.4,0.6-0.5,0.9s-0.1,0.8-0.1,1.4V30h-1.5L96.4,21L96.4,21z"/>
<path class="st2" d="M107,26c0,0.7,0.2,1.3,0.5,1.7c0.5,0.8,1.4,1.2,2.8,1.2c0.6,0,1.1-0.1,1.6-0.3c0.9-0.3,1.4-1,1.4-1.9
c0-0.7-0.2-1.2-0.6-1.4c-0.4-0.3-1-0.5-1.9-0.7l-1.6-0.4c-1-0.2-1.8-0.5-2.2-0.8c-0.7-0.5-1.1-1.3-1.1-2.3c0-1.1,0.4-2,1.1-2.7
s1.8-1.1,3.1-1.1c1.2,0,2.3,0.3,3.1,0.9c0.9,0.6,1.3,1.6,1.3,3H113c-0.1-0.7-0.2-1.2-0.5-1.5c-0.5-0.6-1.3-1-2.4-1
c-0.9,0-1.6,0.2-2,0.6s-0.6,0.9-0.6,1.5s0.2,1.1,0.7,1.3c0.3,0.2,1,0.4,2.1,0.7l1.6,0.4c0.8,0.2,1.4,0.5,1.8,0.8
c0.7,0.6,1.1,1.4,1.1,2.5c0,1.4-0.5,2.4-1.4,2.9c-0.9,0.6-2,0.9-3.3,0.9c-1.5,0-2.6-0.4-3.4-1.2c-0.8-0.8-1.2-1.8-1.2-3.2h1.5V26z
"/>
<path class="st2" d="M122.7,21.5c0.6,0.5,1,1.3,1.1,2.6h-1.4c-0.1-0.6-0.3-1-0.6-1.4c-0.3-0.4-0.8-0.6-1.5-0.6
c-0.9,0-1.6,0.5-2,1.4c-0.3,0.6-0.4,1.4-0.4,2.3s0.2,1.7,0.6,2.3c0.4,0.6,1,0.9,1.8,0.9c0.6,0,1.1-0.2,1.5-0.6s0.6-0.9,0.7-1.6
h1.4c-0.2,1.2-0.6,2.1-1.2,2.6c-0.7,0.6-1.5,0.8-2.5,0.8c-1.1,0-2.1-0.4-2.7-1.3c-0.7-0.9-1-1.9-1-3.2c0-1.6,0.4-2.8,1.1-3.7
c0.7-0.9,1.7-1.3,2.9-1.3C121.3,20.7,122.1,21,122.7,21.5z"/>
<path class="st2" d="M125.3,17.6h1.5v4.6c0.3-0.5,0.7-0.8,0.9-1c0.5-0.3,1.1-0.5,1.8-0.5c1.3,0,2.1,0.5,2.6,1.4
c0.2,0.5,0.4,1.2,0.4,2.1V30H131v-5.7c0-0.7-0.1-1.2-0.2-1.5c-0.3-0.5-0.8-0.7-1.5-0.7c-0.6,0-1.2,0.2-1.7,0.7
c-0.5,0.4-0.7,1.3-0.7,2.5V30h-1.5V17.6H125.3z"/>
<path class="st2" d="M140,21.2c0.6,0.3,1,0.7,1.3,1.2s0.5,1,0.6,1.6c0.1,0.4,0.1,1.1,0.1,2h-6.4c0,0.9,0.2,1.7,0.6,2.2
c0.4,0.6,1,0.8,1.8,0.8s1.4-0.3,1.8-0.8c0.3-0.3,0.4-0.7,0.5-1.1h1.5c0,0.3-0.2,0.7-0.4,1.1s-0.5,0.7-0.7,1
c-0.4,0.5-1,0.8-1.7,0.9c-0.4,0.1-0.8,0.1-1.2,0.1c-1.1,0-2-0.4-2.8-1.2c-0.8-0.8-1.1-2-1.1-3.4c0-1.5,0.4-2.6,1.1-3.5
c0.8-0.9,1.8-1.4,3-1.4C138.9,20.8,139.5,20.9,140,21.2z M140.6,24.8c-0.1-0.7-0.2-1.2-0.4-1.6c-0.4-0.7-1.1-1.1-2-1.1
c-0.7,0-1.2,0.3-1.7,0.8s-0.7,1.1-0.7,1.9C135.8,24.8,140.6,24.8,140.6,24.8z"/>
<path class="st2" d="M148.8,21.3c0.3,0.2,0.6,0.5,0.9,0.9v-4.6h1.4V30h-1.3v-1.3c-0.3,0.6-0.7,1-1.2,1.2s-1,0.4-1.6,0.4
c-1,0-1.8-0.4-2.5-1.3c-0.7-0.8-1.1-2-1.1-3.4c0-1.3,0.3-2.5,1-3.4c0.7-1,1.6-1.4,2.8-1.4C147.8,20.8,148.3,21,148.8,21.3z
M145.5,28.1c0.4,0.7,1,1,1.9,1c0.7,0,1.2-0.3,1.7-0.9c0.4-0.6,0.7-1.5,0.7-2.6s-0.2-2-0.7-2.5s-1-0.8-1.7-0.8s-1.3,0.3-1.8,0.9
s-0.7,1.4-0.7,2.6C144.9,26.6,145.1,27.4,145.5,28.1z"/>
<path class="st2" d="M154.8,21v6c0,0.5,0.1,0.8,0.2,1.1c0.3,0.5,0.7,0.8,1.4,0.8c1,0,1.7-0.5,2-1.4c0.2-0.5,0.3-1.2,0.3-2.1V21
h1.5v9h-1.4v-1.3c-0.2,0.3-0.4,0.6-0.7,0.9c-0.6,0.5-1.2,0.7-2,0.7c-1.2,0-2.1-0.4-2.5-1.3c-0.2-0.5-0.4-1.1-0.4-1.8V21H154.8z"/>
<path class="st2" d="M162.7,17.6h1.5V30h-1.5V17.6z"/>
<path class="st2" d="M171.8,21.2c0.6,0.3,1,0.7,1.3,1.2s0.5,1,0.6,1.6c0.1,0.4,0.1,1.1,0.1,2h-6.4c0,0.9,0.2,1.7,0.6,2.2
c0.4,0.6,1,0.8,1.8,0.8s1.4-0.3,1.8-0.8c0.3-0.3,0.4-0.7,0.5-1.1h1.5c0,0.3-0.2,0.7-0.4,1.1s-0.5,0.7-0.7,1
c-0.4,0.5-1,0.8-1.7,0.9c-0.4,0.1-0.8,0.1-1.2,0.1c-1.1,0-2-0.4-2.8-1.2c-0.8-0.8-1.1-2-1.1-3.4c0-1.5,0.4-2.6,1.1-3.5
c0.8-0.9,1.8-1.4,3-1.4C170.6,20.8,171.2,20.9,171.8,21.2z M172.3,24.8c-0.1-0.7-0.2-1.2-0.4-1.6c-0.4-0.7-1.1-1.1-2-1.1
c-0.7,0-1.2,0.3-1.7,0.8s-0.7,1.1-0.7,1.9C167.5,24.8,172.3,24.8,172.3,24.8z"/>
<path class="st2" d="M175.7,21h1.4v1.6c0.1-0.3,0.4-0.7,0.8-1.1c0.4-0.4,1-0.7,1.5-0.7h0.1c0.1,0,0.2,0,0.3,0v1.6
c-0.1,0-0.2,0-0.2,0c-0.1,0-0.2,0-0.2,0c-0.7,0-1.3,0.2-1.7,0.7s-0.6,1.1-0.6,1.7V30h-1.5L175.7,21L175.7,21z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.3 KiB

52
dolphinscheduler-ui-next/src/layouts/basic/components/header/index.module.scss

@ -0,0 +1,52 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.header-model {
display: flex;
justify-content: space-between;
align-items: center;
height: 60px;
box-shadow: rgba(0, 0, 0, 0.3) 0px 3px 5px;
position: relative;
width: 100%;
padding: 0px;
margin: 0px;
.nav {
display: flex;
justify-content: space-between;
align-items: center;
width: inherit;
.menu {
margin-left: 0px;
text-align: center;
font-size: 15px;
color: rgb(255, 255, 255);
}
.profile {
width: 135px;
display: flex;
justify-content: space-between;
margin-right: 20px;
text-align: center;
.icon {
margin-right: 5px;
display: inline-flex;
align-items: center;
}
}
}
}

106
dolphinscheduler-ui-next/src/layouts/basic/components/header/index.tsx

@ -0,0 +1,106 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { defineComponent, ref } from "vue";
import styles from "./index.module.scss";
import { NDropdown, NIcon, NLayoutHeader, NMenu } from "naive-ui";
import { Logo } from "@/layouts/basic/components/logo";
import { IosArrowDown } from "@vicons/ionicons4";
import { UserAlt } from "@vicons/fa";
const Header = defineComponent({
name: "Header",
props: {
inverted: {
type: Boolean,
default: true,
},
menuOptions: {
type: Array,
default: [],
},
languageOptions: {
type: Array,
default: [],
},
profileOptions: {
type: Array,
default: [],
},
currentMenu: {
type: Object,
},
defaultMenuKey: {
type: String,
},
},
setup(props, context) {
const currentMenuRef = ref({});
const handleMenuClick = (key, data) => {
currentMenuRef.value = data;
context.emit("menuClick", data);
};
return { handleMenuClick };
},
render() {
return (
<NLayoutHeader
class={styles["header-model"]}
inverted={this.inverted}
bordered
>
<Logo />
<div class={styles.nav}>
<NMenu
mode="horizontal"
onUpdate:value={this.handleMenuClick}
defaultValue={this.defaultMenuKey}
class={styles.menu}
inverted={this.inverted}
options={this.menuOptions}
/>
<div class={styles.profile}>
<NDropdown inverted={this.inverted} options={this.languageOptions}>
<span>
<NIcon class={styles.icon}>
<IosArrowDown />
</NIcon>
</span>
</NDropdown>
<NDropdown inverted={this.inverted} options={this.profileOptions}>
<span>
<NIcon class={styles.icon}>
<UserAlt />
</NIcon>
admin
<NIcon class={styles.icon}>
<IosArrowDown />
</NIcon>
</span>
</NDropdown>
</div>
</div>
</NLayoutHeader>
);
},
});
export { Header };

36
dolphinscheduler-ui-next/src/layouts/basic/components/logo/index.module.scss

@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.logo {
display: flex;
align-items: center;
justify-content: center;
height: 64px;
line-height: 64px;
overflow: hidden;
white-space: nowrap;
width: 280px;
img {
width: auto;
height: 46px;
}
.title {
margin-bottom: 0;
}
}

38
dolphinscheduler-ui-next/src/layouts/basic/components/logo/index.tsx

@ -0,0 +1,38 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { defineComponent, ref } from "vue";
import styles from "./index.module.scss";
const Logo = defineComponent({
name: "Logo",
setup() {
const invertedRef = ref(true);
return { invertedRef };
},
render() {
return (
<div class={styles.logo}>
<img src="../../../src/assets/images/nav-logo.svg" alt="" />
</div>
);
},
});
export { Logo };

19
dolphinscheduler-ui-next/src/layouts/basic/components/sider/index.module.scss

@ -0,0 +1,19 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.sider-model {
}

79
dolphinscheduler-ui-next/src/layouts/basic/components/sider/index.tsx

@ -0,0 +1,79 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { defineComponent, ref } from "vue";
import { NLayoutSider, NMenu } from "naive-ui";
const Sider = defineComponent({
name: "Sider",
props: {
visible: {
type: Boolean,
default: true,
},
inverted: {
type: Boolean,
default: true,
},
menuOptions: {
type: Array,
default: [],
},
currentMenu: {
type: Object,
},
defaultMenuKey: {
type: String,
},
},
setup(props) {
const currentMenuRef = ref({});
const handleMenuClick = (key, data) => {
currentMenuRef.value = data;
};
return { handleMenuClick };
},
render() {
if (this.visible) {
return (
<NLayoutSider
width={240}
collapseMode={"width"}
collapsedWidth={64}
inverted={this.inverted}
nativeScrollbar={false}
show-trigger
bordered
>
<NMenu
onUpdate:value={this.handleMenuClick}
inverted={this.inverted}
collapsedWidth={64}
collapsedIconSize={22}
options={this.menuOptions}
/>
</NLayoutSider>
);
} else {
return "";
}
},
});
export { Sider };

54
dolphinscheduler-ui-next/src/layouts/basic/index.module.scss

@ -0,0 +1,54 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.container {
.header-model {
display: flex;
justify-content: space-between;
align-items: center;
height: 60px;
box-shadow: rgba(0, 0, 0, 0.3) 0px 3px 5px;
position: relative;
width: 100%;
padding: 0px;
margin: 0px;
.nav {
display: flex;
justify-content: space-between;
align-items: center;
width: inherit;
.menu {
margin-left: 0px;
text-align: center;
font-size: 15px;
color: rgb(255, 255, 255);
}
.profile {
width: 135px;
display: flex;
justify-content: space-between;
margin-right: 20px;
text-align: center;
.icon {
margin-right: 5px;
display: inline-flex;
align-items: center;
}
}
}
}
}

234
dolphinscheduler-ui-next/src/layouts/basic/index.tsx

@ -0,0 +1,234 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { h, defineComponent, ref } from "vue";
import styles from "./index.module.scss";
import { useI18n } from "vue-i18n";
import {
PersonCircleOutline,
LogOutOutline,
FileTrayFullOutline,
Server,
SettingsOutline,
} from "@vicons/ionicons5";
import {
HomeOutlined,
FolderOutlined,
SafetyCertificateOutlined,
UserOutlined,
} from "@vicons/antd";
import { Database, Notes, Users } from "@vicons/tabler";
import { MonitorFilled, AcUnitOutlined } from "@vicons/material";
import { Flow } from "@vicons/carbon";
import { Header } from "./components/header";
import { Sider } from "./components/sider";
import { NLayout, NLayoutContent, NIcon } from "naive-ui";
function renderIcon(icon) {
return () => h(NIcon, null, { default: () => h(icon) });
}
const switchLanguageOptions = [
{
label: "English",
key: "en",
},
{
label: "中文",
key: "zh",
},
];
const profileOptions = [
{
label: "用户信息",
key: "profile",
icon: renderIcon(PersonCircleOutline),
},
{
label: "退出登录",
key: "logout",
icon: renderIcon(LogOutOutline),
},
];
const menuOptions = [
{
label: "首页",
key: "home",
icon: renderIcon(HomeOutlined),
},
{
label: "项目管理",
key: "project",
icon: renderIcon(Notes),
children: [
{
label: "项目",
key: "projects-list",
icon: renderIcon(Notes),
},
{
label: "工作流监控",
key: "projects-index",
icon: renderIcon(Flow),
},
],
},
{
label: "资源中心",
key: "resources",
icon: renderIcon(FolderOutlined),
children: [
{
label: "文件管理",
key: "file",
icon: renderIcon(FileTrayFullOutline),
},
{
label: "创建资源",
key: "resource-file-create",
icon: renderIcon(AcUnitOutlined),
},
],
},
{
label: "数据源中心",
key: "datasource",
icon: renderIcon(Database),
children: [
{
label: "数据源中心",
key: "datasource-list",
icon: renderIcon(Database),
},
],
},
{
label: "监控中心",
key: "monitor",
icon: renderIcon(MonitorFilled),
children: [
{
key: "servers-master",
title: "服务管理-Master",
icon: renderIcon(Server),
},
{
key: "servers-worker",
title: "服务管理-Worker",
icon: renderIcon(SettingsOutline),
},
],
},
{
label: "安全中心",
key: "security",
icon: renderIcon(SafetyCertificateOutlined),
children: [
{
key: "tenement-manage",
label: "租户管理",
icon: renderIcon(UserOutlined),
},
{
key: "users-manage",
label: "用户管理",
icon: renderIcon(Users),
},
],
},
];
const basic = defineComponent({
name: "basic",
setup() {
const invertedRef = ref(true);
const hasSiderRef = ref(false);
const defaultMenuKeyRef = ref("home");
const currentMenuRef = ref({});
const topMenuOptionsRef = ref([]);
const sideMenuOptionsRef = ref([]);
const handleTopMenuClick = (data) => {
currentMenuRef.value = data;
generateMenus();
};
const handleSideMenuClick = (key, data) => {
console.log(data);
};
const generateMenus = () => {
topMenuOptionsRef.value = [];
sideMenuOptionsRef.value = [];
hasSiderRef.value = false;
menuOptions.forEach((option) => {
topMenuOptionsRef.value.push({
label: option.label,
key: option.key,
icon: option.icon,
});
if (
currentMenuRef.value.key === option.key ||
defaultMenuKeyRef.value === option.key
) {
if (option.hasOwnProperty("children") && option.children) {
sideMenuOptionsRef.value = option.children;
hasSiderRef.value = true;
}
}
});
};
generateMenus();
return {
topMenuOptionsRef,
sideMenuOptionsRef,
invertedRef,
hasSiderRef,
defaultMenuKeyRef,
handleTopMenuClick,
handleSideMenuClick,
};
},
render() {
return (
<NLayout class={styles.container}>
<Header
languageOptions={switchLanguageOptions}
profileOptions={profileOptions}
menuOptions={this.topMenuOptionsRef}
inverted={this.invertedRef}
defaultMenuKey={this.defaultMenuKeyRef}
onMenuClick={this.handleTopMenuClick}
/>
<NLayout hasSider>
<Sider
visible={this.hasSiderRef}
inverted={this.invertedRef}
menuOptions={this.sideMenuOptionsRef}
/>
<NLayoutContent>
<router-view />
</NLayoutContent>
</NLayout>
</NLayout>
);
},
});
export default basic;

12
dolphinscheduler-ui-next/src/layouts/content/Content.tsx

@ -15,11 +15,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { defineComponent } from 'vue' import { defineComponent } from "vue";
import { NLayout, NLayoutContent } from 'naive-ui' import { NLayout, NLayoutContent } from "naive-ui";
const Content = defineComponent({ const Content = defineComponent({
name: 'Content', name: "Content",
render() { render() {
return ( return (
<NLayout> <NLayout>
@ -27,8 +27,8 @@ const Content = defineComponent({
<router-view /> <router-view />
</NLayoutContent> </NLayoutContent>
</NLayout> </NLayout>
) );
}, },
}) });
export default Content export default Content;

24
dolphinscheduler-ui-next/src/router/index.ts

@ -20,17 +20,17 @@ import {
createWebHistory, createWebHistory,
NavigationGuardNext, NavigationGuardNext,
RouteLocationNormalized, RouteLocationNormalized,
} from 'vue-router' } from "vue-router";
import routes from './routes' import routes from "./routes";
// NProgress // NProgress
import NProgress from 'nprogress' import NProgress from "nprogress";
import 'nprogress/nprogress.css' import "nprogress/nprogress.css";
const router = createRouter({ const router = createRouter({
history: createWebHistory(), history: createWebHistory(),
routes, routes,
}) });
/** /**
* Routing to intercept * Routing to intercept
@ -41,14 +41,14 @@ router.beforeEach(
from: RouteLocationNormalized, from: RouteLocationNormalized,
next: NavigationGuardNext next: NavigationGuardNext
) => { ) => {
NProgress.start() NProgress.start();
next() next();
NProgress.done() NProgress.done();
} }
) );
router.afterEach(() => { router.afterEach(() => {
NProgress.done() NProgress.done();
}) });
export default router export default router;

181
dolphinscheduler-ui-next/src/router/routes.ts

@ -15,44 +15,189 @@
* limitations under the License. * limitations under the License.
*/ */
import type { RouteRecordRaw } from 'vue-router' import type { RouteRecordRaw } from "vue-router";
import type { Component } from 'vue' import type { Component } from "vue";
import utils from '@/utils' import utils from "@/utils";
import { useI18n } from "vue-i18n";
// All TSX files under the views folder automatically generate mapping relationship // All TSX files under the views folder automatically generate mapping relationship
const modules = import.meta.glob('/src/views/**/**.tsx') const modules = import.meta.glob("/src/views/**/**.tsx");
const components: { [key: string]: Component } = utils.mapping(modules) const components: { [key: string]: Component } = utils.mapping(modules);
/** /**
* Basic page * Basic page
*/ */
const basePage: RouteRecordRaw[] = [ const basePage: RouteRecordRaw[] = [
{ {
path: '/', path: "/",
redirect: { name: 'home' }, redirect: { name: "home" },
component: () => import('@/layouts/content/Content'), meta: { title: "首页" },
component: () => import("@/layouts/basic"),
children: [ children: [
{ {
path: '/home', path: "/home",
name: 'home', name: "home",
component: components['home'], component: components["home"],
meta: {
title: "首页",
},
},
],
},
];
const projectsPage = [
{
path: "/projects",
name: "projects",
redirect: { name: "projects-list" },
meta: { title: "项目管理" },
component: () => import("@/layouts/basic"),
children: [
{
path: "/projects/list",
name: "projects-list",
component: components["home"],
meta: {
title: "项目",
},
},
{
path: "/projects/:projectCode/index",
name: "projects-index",
component: components["home"],
meta: {
title: "工作流监控",
},
},
],
},
];
const resourcesPage = [
{
path: "/resource",
name: "resource",
redirect: { name: "file" },
meta: { title: "资源中心" },
component: () => import("@/layouts/basic"),
children: [
{
path: "/resource/file",
name: "file",
component: components["home"],
meta: {
title: "文件管理",
},
},
{
path: "/resource/file/create",
name: "resource-file-create",
component: components["home"],
meta: {
title: "创建资源",
},
},
],
},
];
const datasourcePage = [
{
path: "/datasource",
name: "datasource",
redirect: { name: "datasource-list" },
meta: { title: "数据源中心" },
component: () => import("@/layouts/basic"),
children: [
{
path: "/datasource/list",
name: "datasource-list",
component: components["home"],
meta: {
title: "数据源中心",
},
},
],
},
];
const monitorPage = [
{
path: "/monitor",
name: "monitor",
meta: { title: "monitor" },
redirect: { name: "servers-master" },
component: () => import("@/layouts/basic"),
children: [
{
path: "/monitor/servers/master",
name: "servers-master",
component: components["home"],
meta: {
title: "服务管理-Master",
},
},
{
path: "/monitor/servers/worker",
name: "servers-worker",
component: components["home"],
meta: {
title: "服务管理-Worker",
},
},
],
},
];
const securityPage: RouteRecordRaw[] = [
{
path: "/security",
name: "security",
meta: { title: "安全中心" },
redirect: { name: "tenement-manage" },
component: () => import("@/layouts/basicLayout"),
children: [
{
path: "/security/tenant",
name: "tenement-manage",
component: components["home"],
meta: {
title: "租户管理",
},
},
{
path: "/security/users",
name: "users-manage",
component: components["home"],
meta: {
title: "用户管理",
},
}, },
], ],
}, },
] ];
/** /**
* Login page * Login page
*/ */
const loginPage: RouteRecordRaw[] = [ const loginPage: RouteRecordRaw[] = [
{ {
path: '/login', path: "/login",
name: 'login', name: "login",
component: components['login'], component: components["login"],
}, },
] ];
const routes: RouteRecordRaw[] = [...basePage, ...loginPage] const routes: RouteRecordRaw[] = [
...basePage,
...loginPage,
...projectsPage,
...resourcesPage,
...datasourcePage,
...monitorPage,
...securityPage,
];
// 重新组织后导出 // 重新组织后导出
export default routes export default routes;

46
dolphinscheduler-ui-next/src/store/route/route.ts

@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { toRaw } from "vue";
import { defineStore } from "pinia";
import RouteState from "./types";
import { RouteRecordRaw } from "vue-router";
export const useAsyncRouteStore = defineStore({
id: "route",
state: (): RouteState => ({
menus: [],
routers: [],
addRouters: [],
}),
getters: {
getMenus(): RouteRecordRaw[] {
return this.menus;
},
getRouters(): RouteRecordRaw[] {
return toRaw(this.addRouters);
},
},
actions: {
setMenus(menus) {
this.menus = menus;
},
async generateRouters(routes) {
console.log(routes);
},
},
});

25
dolphinscheduler-ui-next/src/store/route/types.ts

@ -0,0 +1,25 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { RouteRecordRaw } from "vue-router";
interface RouteState {
menus: RouteRecordRaw[];
routers: any[];
addRouters: any[];
}
export default RouteState;
Loading…
Cancel
Save