Browse Source

[Feature][UI Next][V1.0.0-Alpha] UI support timezone setting (#8833)

Devosend 3 years ago
parent
commit
5aeb753ae8

+ 6 - 0
dolphinscheduler-ui-next/src/layouts/content/components/navbar/index.tsx

@@ -20,6 +20,7 @@ import styles from './index.module.scss'
 import { NMenu } from 'naive-ui'
 import Logo from '../logo'
 import Locales from '../locales'
+import Timezone from '../timezone'
 import User from '../user'
 import Theme from '../theme'
 import { useMenuClick } from './use-menuClick'
@@ -36,6 +37,10 @@ const Navbar = defineComponent({
       type: Array as PropType<any>,
       default: []
     },
+    timezoneOptions: {
+      type: Array as PropType<any>,
+      default: []
+    },
     userDropdownOptions: {
       type: Array as PropType<any>,
       default: []
@@ -62,6 +67,7 @@ const Navbar = defineComponent({
         <div class={styles.settings}>
           <Theme />
           <Locales localesOptions={this.localesOptions} />
+          <Timezone timezoneOptions={this.timezoneOptions} />
           <User userDropdownOptions={this.userDropdownOptions} />
         </div>
       </div>

+ 20 - 0
dolphinscheduler-ui-next/src/layouts/content/components/timezone/index.module.scss

@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+ .icon {
+  margin: 0 12px;
+}

+ 64 - 0
dolphinscheduler-ui-next/src/layouts/content/components/timezone/index.tsx

@@ -0,0 +1,64 @@
+/*
+ * 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, PropType } from 'vue'
+import { NIcon, NButton, NPopselect } from 'naive-ui'
+import styles from './index.module.scss'
+import { DownOutlined } from '@vicons/antd'
+import { useDropDown } from './use-dropdown'
+import { useTimezoneStore } from '@/store/timezone/timezone'
+
+const Timezone = defineComponent({
+  name: 'Timezone',
+  props: {
+    timezoneOptions: {
+      type: Array as PropType<any>,
+      default: []
+    }
+  },
+  setup(props) {
+    const timezoneStore = useTimezoneStore()
+    const chooseVal = ref(
+      props.timezoneOptions.filter(
+        (item: { value: string }) => item.value === timezoneStore.getTimezone
+      )[0].label
+    )
+
+    const { handleSelect } = useDropDown(chooseVal)
+
+    return { handleSelect, chooseVal }
+  },
+  render() {
+    return (
+      <NPopselect
+        options={this.timezoneOptions}
+        trigger='click'
+        scrollable
+        onUpdateValue={this.handleSelect}
+      >
+        <NButton text>
+          {this.chooseVal}
+          <NIcon class={styles.icon}>
+            <DownOutlined />
+          </NIcon>
+        </NButton>
+      </NPopselect>
+    )
+  }
+})
+
+export default Timezone

+ 52 - 0
dolphinscheduler-ui-next/src/layouts/content/components/timezone/use-dropdown.ts

@@ -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.
+ */
+
+import { useI18n } from 'vue-i18n'
+import { updateUser } from '@/service/modules/users'
+import { useTimezoneStore } from '@/store/timezone/timezone'
+import { useUserStore } from '@/store/user/user'
+import type { UserInfoRes } from '@/service/modules/users/types'
+
+export function useDropDown(chooseVal: any) {
+  const { t } = useI18n()
+
+  const userStore = useUserStore()
+  const timezoneStore = useTimezoneStore()
+
+  const userInfo = userStore.userInfo as UserInfoRes
+
+  const handleSelect = (value: string) => {
+    updateUser({
+      userPassword: '',
+      id: userInfo.id,
+      userName: '',
+      tenantId: userInfo.tenantId,
+      email: '',
+      phone: userInfo.phone,
+      state: userInfo.state,
+      timeZone: value
+    }).then(() => {
+      chooseVal.value = value
+      timezoneStore.setTimezone(value as string)
+      window.$message.success(t('profile.timezone_success'))
+    })
+  }
+
+  return {
+    handleSelect
+  }
+}

+ 1 - 0
dolphinscheduler-ui-next/src/layouts/content/index.tsx

@@ -107,6 +107,7 @@ const Content = defineComponent({
             onHandleMenuClick={this.getSideMenuOptions}
             headerMenuOptions={this.headerMenuOptions}
             localesOptions={this.localesOptions}
+            timezoneOptions={this.timezoneOptions}
             userDropdownOptions={this.userDropdownOptions}
           />
         </NLayoutHeader>

+ 5 - 0
dolphinscheduler-ui-next/src/layouts/content/use-dataList.ts

@@ -50,6 +50,7 @@ import {
 } from '@vicons/antd'
 import { useMenuStore } from '@/store/menu/menu'
 import { useUserStore } from '@/store/user/user'
+import { timezoneList } from '@/utils/timezone'
 import type { UserInfoRes } from '@/service/modules/users/types'
 
 export function useDataList() {
@@ -72,9 +73,13 @@ export function useDataList() {
     }
   ]
 
+  const timezoneOptions = () =>
+    timezoneList.map((item) => ({ label: item, value: item }))
+
   const state = reactive({
     isShowSide: false,
     localesOptions,
+    timezoneOptions: timezoneOptions(),
     userDropdownOptions: [],
     menuOptions: [],
     headerMenuOptions: [],

+ 2 - 1
dolphinscheduler-ui-next/src/locales/modules/en_US.ts

@@ -136,7 +136,8 @@ const profile = {
   phone_tips: 'Please enter your phone',
   state_tips: 'Please choose your state',
   enable: 'Enable',
-  disable: 'Disable'
+  disable: 'Disable',
+  timezone_success: 'Time zone updated successful'
 }
 
 const monitor = {

+ 2 - 1
dolphinscheduler-ui-next/src/locales/modules/zh_CN.ts

@@ -135,7 +135,8 @@ const profile = {
   phone_tips: '请输入手机号',
   state_tips: '请选择状态',
   enable: '启用',
-  disable: '禁用'
+  disable: '禁用',
+  timezone_success: '时区更新成功'
 }
 
 const monitor = {

+ 1 - 0
dolphinscheduler-ui-next/src/service/modules/users/types.ts

@@ -35,6 +35,7 @@ interface UserReq {
   phone?: string
   queue?: string
   state?: number
+  timeZone?: string
 }
 
 interface IdReq {

+ 37 - 0
dolphinscheduler-ui-next/src/store/timezone/timezone.ts

@@ -0,0 +1,37 @@
+/*
+ * 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 { timezoneStore, Timezone } from './types'
+
+export const useTimezoneStore = defineStore({
+  id: 'timezone',
+  state: (): timezoneStore => ({
+    timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
+  }),
+  persist: true,
+  getters: {
+    getTimezone(): Timezone {
+      return this.timezone
+    }
+  },
+  actions: {
+    setTimezone(timezone: Timezone): void {
+      this.timezone = timezone
+    }
+  }
+})

+ 26 - 0
dolphinscheduler-ui-next/src/store/timezone/types.ts

@@ -0,0 +1,26 @@
+/*
+ * 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 { timezoneList } from '@/utils/timezone'
+
+type Timezone = typeof timezoneList[number]
+
+interface timezoneStore {
+  timezone: Timezone
+}
+
+export { timezoneStore, Timezone }

+ 7 - 0
dolphinscheduler-ui-next/src/views/login/use-login.ts

@@ -24,11 +24,13 @@ import type { SessionIdRes } from '@/service/modules/login/types'
 import type { UserInfoRes } from '@/service/modules/users/types'
 import { useMenuStore } from '@/store/menu/menu'
 import cookies from 'js-cookie'
+import { useTimezoneStore } from '@/store/timezone/timezone'
 
 export function useLogin(state: any) {
   const router: Router = useRouter()
   const userStore = useUserStore()
   const menuStore = useMenuStore()
+  const timezoneStore = useTimezoneStore()
 
   const handleLogin = () => {
     state.loginFormRef.validate(async (valid: any) => {
@@ -40,6 +42,11 @@ export function useLogin(state: any) {
         const userInfoRes: UserInfoRes = await getUserInfo()
         await userStore.setUserInfo(userInfoRes)
 
+        const timezone = userInfoRes.timeZone
+          ? userInfoRes.timeZone
+          : Intl.DateTimeFormat().resolvedOptions().timeZone
+        await timezoneStore.setTimezone(timezone)
+
         const key = menuStore.getMenuKey
 
         router.push({ path: key || 'home' })