Browse Source

[Feat][UI] Set up UI setting component in profile page (#11226)

* Set up UI setting component in profile page

* Add UI setting page to the route, remove UI setting section from the profile

* Add log auto refresh timer store

* Add logTimer to pinia store and cookies

* Read logTimer from pinia store, and delay getLogs by passing the logTimer to setInterval in refreshLogs function

* Add log timer to getLogs

* Fine tune view log, add auto refresh based on time interval set in UI setting

* Add useI18n to ui setting

* Set up UI setting component in profile page

* Add UI setting page to the route, remove UI setting section from the profile

* Add log auto refresh timer store

* Add logTimer to pinia store and cookies

* Read logTimer from pinia store, and delay getLogs by passing the logTimer to setInterval in refreshLogs function

* Add log timer to getLogs

* Fine tune view log, add auto refresh based on time interval set in UI setting

* Add useI18n to ui setting

* [Feat][UI] Add UI setting page in the project.

* [Feat][UI] Add UI setting page in the project.

* Remove logTimer in cookies

* Clear timer id, set VITE_APP_DEV_WEB_URL back to default

* Clear time id in dag

* [Feat][UI] Add license header.

* [Feat][UI] Remove console.

* [Fix][UI] Fix log timer types.

Co-authored-by: songjianet <1778651752@qq.com>
3.2.0-release
lynn-illumio 2 years ago committed by GitHub
parent
commit
234f2e8a40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      dolphinscheduler-ui/pnpm-lock.yaml
  2. 1
      dolphinscheduler-ui/src/layouts/content/components/timezone/index.tsx
  3. 10
      dolphinscheduler-ui/src/layouts/content/use-dataList.ts
  4. 4
      dolphinscheduler-ui/src/locales/en_US/index.ts
  5. 3
      dolphinscheduler-ui/src/locales/en_US/menu.ts
  6. 23
      dolphinscheduler-ui/src/locales/en_US/ui_setting.ts
  7. 4
      dolphinscheduler-ui/src/locales/zh_CN/index.ts
  8. 1
      dolphinscheduler-ui/src/locales/zh_CN/menu.ts
  9. 23
      dolphinscheduler-ui/src/locales/zh_CN/ui_setting.ts
  10. 43
      dolphinscheduler-ui/src/router/modules/ui-setting.ts
  11. 5
      dolphinscheduler-ui/src/router/routes.ts
  12. 38
      dolphinscheduler-ui/src/store/logTimer/logTimer.ts
  13. 21
      dolphinscheduler-ui/src/store/logTimer/types.ts
  14. 5
      dolphinscheduler-ui/src/views/profile/use-form.ts
  15. 29
      dolphinscheduler-ui/src/views/projects/task/instance/batch-task.tsx
  16. 3
      dolphinscheduler-ui/src/views/projects/task/instance/index.tsx
  17. 22
      dolphinscheduler-ui/src/views/projects/task/instance/stream-task.tsx
  18. 32
      dolphinscheduler-ui/src/views/projects/workflow/components/dag/index.tsx
  19. 91
      dolphinscheduler-ui/src/views/ui-setting/index.tsx

2
dolphinscheduler-ui/pnpm-lock.yaml

@ -15,7 +15,7 @@
# limitations under the License.
#
lockfileVersion: 5.3
lockfileVersion: 5.4
specifiers:
'@antv/layout': 0.1.31

1
dolphinscheduler-ui/src/layouts/content/components/timezone/index.tsx

@ -33,6 +33,7 @@ const Timezone = defineComponent({
}
},
setup(props) {
// console.log(prosp.timezoneOptions);
const { t } = useI18n()
const reload: any = inject('reload')
const timezoneStore = useTimezoneStore()

10
dolphinscheduler-ui/src/layouts/content/use-dataList.ts

@ -314,7 +314,15 @@ export function useDataList() {
icon: renderIcon(SafetyOutlined)
}
]
}
},
// add UI setting to the banner
{
label: () =>
h(NEllipsis, null, { default: () => t('menu.ui_setting') }),
key: 'ui-setting',
icon: renderIcon(SettingOutlined),
children: []
},
]
}

4
dolphinscheduler-ui/src/locales/en_US/index.ts

@ -30,6 +30,7 @@ import resource from '@/locales/en_US/resource'
import security from '@/locales/en_US/security'
import theme from '@/locales/en_US/theme'
import user_dropdown from '@/locales/en_US/user-dropdown'
import ui_setting from '@/locales/en_US/ui_setting'
export default {
login,
@ -46,5 +47,6 @@ export default {
security,
datasource,
data_quality,
crontab
crontab,
ui_setting
}

3
dolphinscheduler-ui/src/locales/en_US/menu.ts

@ -56,5 +56,6 @@ export default {
task_group_queue: 'Task Group Queue',
data_quality: 'Data Quality',
task_result: 'Task Result',
rule: 'Rule management'
rule: 'Rule management',
ui_setting: 'Setting',
}

23
dolphinscheduler-ui/src/locales/en_US/ui_setting.ts

@ -0,0 +1,23 @@
/*
* 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.
*/
export default {
log: {
refresh_time: 'Log Auto Refresh Time',
}
}

4
dolphinscheduler-ui/src/locales/zh_CN/index.ts

@ -30,6 +30,7 @@ import resource from '@/locales/zh_CN/resource'
import security from '@/locales/zh_CN/security'
import theme from '@/locales/zh_CN/theme'
import user_dropdown from '@/locales/zh_CN/user-dropdown'
import ui_setting from '@/locales/zh_CN/ui_setting'
export default {
login,
@ -46,5 +47,6 @@ export default {
security,
datasource,
data_quality,
crontab
crontab,
ui_setting
}

1
dolphinscheduler-ui/src/locales/zh_CN/menu.ts

@ -22,6 +22,7 @@ export default {
datasource: '数据源中心',
monitor: '监控中心',
security: '安全中心',
ui_setting: '界面设置',
project_overview: '项目概览',
workflow_relation: '工作流关系',
workflow: '工作流',

23
dolphinscheduler-ui/src/locales/zh_CN/ui_setting.ts

@ -0,0 +1,23 @@
/*
* 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.
*/
export default {
log: {
refresh_time: '自动刷新时间',
}
}

43
dolphinscheduler-ui/src/router/modules/ui-setting.ts

@ -0,0 +1,43 @@
/*
* 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 type { Component } from 'vue'
import utils from '@/utils'
// All TSX files under the views folder automatically generate mapping relationship
const modules = import.meta.glob('/src/views/**/**.tsx')
const components: { [key: string]: Component } = utils.mapping(modules)
export default {
path: '/ui-setting',
name: 'ui-setting',
meta: { title: '设置' },
component: () => import('@/layouts/content'),
children: [
{
path: '',
name: 'ui-setting',
component: components['ui-setting'],
meta: {
title: '设置',
activeMenu: 'ui-setting',
showSide: false,
auth: []
}
}
]
}

5
dolphinscheduler-ui/src/router/routes.ts

@ -24,6 +24,8 @@ import datasourcePage from './modules/datasource'
import monitorPage from './modules/monitor'
import securityPage from './modules/security'
import dataQualityPage from './modules/data-quality'
// todo: why is it throwing cannot find module and its corresponding type, but the render is working?
import uiSettingPage from './modules/ui-setting'
// All TSX files under the views folder automatically generate mapping relationship
const modules = import.meta.glob('/src/views/**/**.tsx')
@ -74,7 +76,8 @@ const basePage: RouteRecordRaw[] = [
datasourcePage,
monitorPage,
securityPage,
dataQualityPage
dataQualityPage,
uiSettingPage
]
/**

38
dolphinscheduler-ui/src/store/logTimer/logTimer.ts

@ -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 { defineStore } from 'pinia'
import { LogTimerStore } from './types'
export const useLogTimerStore = defineStore({
id: 'logTimer',
state: (): LogTimerStore => ({
logTimer: 0,
}),
persist: true,
getters: {
getLogTimer(): number {
return this.logTimer
}
},
actions: {
setLogTimer(timer: number): void {
this.logTimer = timer
}
}
})

21
dolphinscheduler-ui/src/store/logTimer/types.ts

@ -0,0 +1,21 @@
/*
* 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.
*/
interface LogTimerStore {
logTimer: number
}
export { LogTimerStore }

5
dolphinscheduler-ui/src/views/profile/use-form.ts

@ -23,6 +23,7 @@ import type { FormRules } from 'naive-ui'
import type { UserInfoRes } from '@/service/modules/users/types'
export function useForm() {
// todo: is "t": some kind of function to internationalize text?
const { t, locale } = useI18n()
const userInfo = useUserStore().userInfo as UserInfoRes
@ -31,7 +32,7 @@ export function useForm() {
profileForm: {
username: userInfo.userName,
email: userInfo.email,
phone: userInfo.phone
phone: userInfo.phone,
},
saving: false,
rules: {
@ -62,7 +63,7 @@ export function useForm() {
state.profileForm = {
username: userInfo.userName,
email: userInfo.email,
phone: userInfo.phone
phone: userInfo.phone,
}
})

29
dolphinscheduler-ui/src/views/projects/task/instance/batch-task.tsx

@ -38,12 +38,15 @@ import { useI18n } from 'vue-i18n'
import { useAsyncState } from '@vueuse/core'
import { queryLog } from '@/service/modules/log'
import { stateType } from '@/common/common'
import { useLogTimerStore } from '@/store/logTimer/logTimer'
import Card from '@/components/card'
import LogModal from '@/components/log-modal'
const BatchTaskInstance = defineComponent({
name: 'task-instance',
setup() {
const logTimerStore = useLogTimerStore()
const logTimer = logTimerStore.getLogTimer
const { t, variables, getTableData, createColumns } = useTable()
const requestTableData = () => {
@ -74,20 +77,34 @@ const BatchTaskInstance = defineComponent({
variables.showModalRef = false
}
const getLogs = (row: any) => {
var getLogsID: number
const getLogs = (row: any, logTimer: number) => {
const { state } = useAsyncState(
queryLog({
taskInstanceId: Number(row.id),
limit: variables.limit,
skipLineNum: variables.skipLineNum
}).then((res: any) => {
if (res?.message) {
variables.logRef += res.message
variables.logRef += res.message || ''
if (res && res.message !== '') {
variables.limit += 1000
variables.skipLineNum += res.lineNum
getLogs(row)
getLogs(row, logTimer)
} else {
variables.logLoadingRef = false
if (logTimer !== 0) {
if (typeof getLogsID === 'number') {
clearTimeout(getLogsID)
}
getLogsID = setTimeout(() => {
variables.logRef = ''
variables.limit = 1000
variables.skipLineNum = 0
variables.logLoadingRef = true
getLogs(row, logTimer)
}, logTimer * 1000)
}
}
}),
{}
@ -100,7 +117,7 @@ const BatchTaskInstance = defineComponent({
variables.logRef = ''
variables.limit = 1000
variables.skipLineNum = 0
getLogs(row)
getLogs(row, logTimer)
}
const trim = getCurrentInstance()?.appContext.config.globalProperties.trim
@ -118,7 +135,7 @@ const BatchTaskInstance = defineComponent({
() => variables.showModalRef,
() => {
if (variables.showModalRef) {
getLogs(variables.row)
getLogs(variables.row, logTimer)
} else {
variables.row = {}
variables.logRef = ''

3
dolphinscheduler-ui/src/views/projects/task/instance/index.tsx

@ -21,6 +21,7 @@ import { NTabPane, NTabs } from 'naive-ui'
import BatchTaskInstance from './batch-task'
import StreamTaskInstance from './stream-task'
const TaskDefinition = defineComponent({
name: 'task-instance',
setup() {
@ -38,4 +39,4 @@ const TaskDefinition = defineComponent({
}
})
export default TaskDefinition
export default TaskDefinition

22
dolphinscheduler-ui/src/views/projects/task/instance/stream-task.tsx

@ -39,6 +39,7 @@ import { useI18n } from 'vue-i18n'
import { useAsyncState } from '@vueuse/core'
import { queryLog } from '@/service/modules/log'
import { streamStateType } from '@/common/common'
import { useLogTimerStore } from '@/store/logTimer/logTimer'
import Card from '@/components/card'
import LogModal from '@/components/log-modal'
@ -46,6 +47,8 @@ const BatchTaskInstance = defineComponent({
name: 'task-instance',
setup() {
let setIntervalP: number
const logTimerStore = useLogTimerStore()
const logTimer = logTimerStore.getLogTimer
const { t, variables, getTableData, createColumns } = useTable()
const onUpdatePageSize = () => {
@ -62,20 +65,27 @@ const BatchTaskInstance = defineComponent({
variables.showModalRef = false
}
const getLogs = (row: any) => {
const getLogs = (row: any, logTimer: number) => {
const { state } = useAsyncState(
queryLog({
taskInstanceId: Number(row.id),
limit: variables.limit,
skipLineNum: variables.skipLineNum
}).then((res: any) => {
if (res?.message) {
variables.logRef += res.message
variables.logRef += res.message || ''
if (res && res.message !== '') {
variables.limit += 1000
variables.skipLineNum += res.lineNum
getLogs(row)
getLogs(row, logTimer)
} else {
variables.logLoadingRef = false
setTimeout(() => {
variables.logRef = ''
variables.limit = 1000
variables.skipLineNum = 0
variables.logLoadingRef = true
getLogs(row, logTimer)
}, logTimer * 1000)
}
}),
{}
@ -88,7 +98,7 @@ const BatchTaskInstance = defineComponent({
variables.logRef = ''
variables.limit = 1000
variables.skipLineNum = 0
getLogs(row)
getLogs(row, logTimer)
}
const trim = getCurrentInstance()?.appContext.config.globalProperties.trim
@ -113,7 +123,7 @@ const BatchTaskInstance = defineComponent({
() => variables.showModalRef,
() => {
if (variables.showModalRef) {
getLogs(variables.row)
getLogs(variables.row, logTimer)
} else {
variables.row = {}
variables.logRef = ''

32
dolphinscheduler-ui/src/views/projects/workflow/components/dag/index.tsx

@ -54,6 +54,7 @@ import './x6-style.scss'
import { queryLog } from '@/service/modules/log'
import { useAsyncState } from '@vueuse/core'
import utils from '@/utils'
import { useLogTimerStore } from '@/store/logTimer/logTimer'
const props = {
// If this prop is passed, it means from definition detail
@ -84,6 +85,9 @@ export default defineComponent({
const route = useRoute()
const theme = useThemeStore()
const logTimerStore = useLogTimerStore()
const logTimer = logTimerStore.getLogTimer
// Whether the graph can be operated
provide('readonly', toRef(props, 'readonly'))
@ -233,23 +237,37 @@ export default defineComponent({
const handleViewLog = (taskId: number, taskType: string) => {
taskModalVisible.value = false
viewLog(taskId, taskType)
getLogs()
getLogs(logTimer)
}
const getLogs = () => {
var getLogsID: number
const getLogs = (logTimer: number) => {
const { state } = useAsyncState(
queryLog({
taskInstanceId: nodeVariables.logTaskId,
limit: nodeVariables.limit,
skipLineNum: nodeVariables.skipLineNum
}).then((res: any) => {
if (res.message) {
nodeVariables.logRef += res.message
nodeVariables.logRef += res.message || ''
if (res && res.message !== '') {
nodeVariables.limit += 1000
nodeVariables.skipLineNum += res.lineNum
getLogs()
getLogs(logTimer)
} else {
nodeVariables.logLoadingRef = false
if (logTimer !== 0) {
if (typeof getLogsID === 'number') {
clearTimeout(getLogsID)
}
getLogsID = setTimeout(() => {
nodeVariables.limit += 1000
nodeVariables.skipLineNum += 1000
getLogs(logTimer)
}, logTimer * 1000)
}
}
}),
{}
@ -258,11 +276,11 @@ export default defineComponent({
return state
}
const refreshLogs = () => {
const refreshLogs = (logTimer: number) => {
nodeVariables.logRef = ''
nodeVariables.limit = 1000
nodeVariables.skipLineNum = 0
getLogs()
getLogs(logTimer)
}
const downloadLogs = () => {

91
dolphinscheduler-ui/src/views/ui-setting/index.tsx

@ -0,0 +1,91 @@
/*
* 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 { useI18n } from 'vue-i18n'
import { NForm, NFormItem, NSelect } from "naive-ui";
import { defineComponent } from "vue";
import { useLogTimerStore } from '@/store/logTimer/logTimer'
// Update LogTimer store when select value is updated
const handleUpdateValue = (logTimer: number) => {
const logTimerStore = useLogTimerStore()
logTimerStore.setLogTimer(logTimer)
}
const setting = defineComponent({
name: 'ui-setting',
setup() {
const logTimerStore = useLogTimerStore()
const defaultLogTimer = logTimerStore.getLogTimer;
const logTimerMap = {
0: "Off",
10: '10 Seconds',
30: '30 Seconds',
60: '1 Minute',
300: '5 Minutes',
1800: '30 Minutes'
} as any
const logTimerOptions = [
{
label: "Off",
value: 0,
},
{
label: "10 Seconds",
value: 10,
},
{
label: "30 Seconds",
value: 30,
},
{
label: "1 Minute",
value: 60,
},
{
label: "5 Minutes",
value: 300,
},
{
label: "30 Minutes",
value: 1800,
},
]
return {defaultLogTimer, logTimerMap, logTimerOptions}
},
render() {
const { t } = useI18n()
return (
<>
<NForm>
<NFormItem label={t('ui_setting.log.refresh_time')}>
<NSelect
default-value={this.logTimerMap[this.defaultLogTimer]}
options={this.logTimerOptions}
onUpdateValue={handleUpdateValue}
/>
</NFormItem>
</NForm>
</>
)
}
})
export default setting
Loading…
Cancel
Save