This is an automated email from the ASF dual-hosted git repository.

zhongjiajie pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git


The following commit(s) were added to refs/heads/dev by this push:
     new 4514eae  [Feature][UI Next] Add task state statistics table. (#7760)
4514eae is described below

commit 4514eaeb8b8e209beb8c7e10109d2c5412323378
Author: songjianet <[email protected]>
AuthorDate: Fri Dec 31 17:54:51 2021 +0800

    [Feature][UI Next] Add task state statistics table. (#7760)
---
 .../src/components/chart/modules/Pie.tsx           |   7 --
 .../layouts/content/components/sidebar/index.tsx   |   5 +-
 .../src/layouts/content/index.tsx                  |   1 -
 .../src/service/modules/projects-analysis/types.ts |  12 +-
 .../src/views/home/definition-card.tsx             |  58 +++++++++
 dolphinscheduler-ui-next/src/views/home/index.tsx  |  78 +++++--------
 .../src/views/home/state-card.tsx                  |  83 +++++++++++++
 .../src/views/home/{use-task-state.ts => types.ts} |  13 +++
 .../src/views/home/use-process-definition.ts       |  21 ++--
 .../src/views/home/use-process-state.ts            |   2 +
 .../src/views/home/use-table.ts                    |   2 +-
 .../src/views/home/use-task-state.ts               |  31 +++++
 dolphinscheduler-ui-next/src/views/login/index.tsx | 130 +++++++++++----------
 13 files changed, 311 insertions(+), 132 deletions(-)

diff --git a/dolphinscheduler-ui-next/src/components/chart/modules/Pie.tsx 
b/dolphinscheduler-ui-next/src/components/chart/modules/Pie.tsx
index be982bb..aab5f96 100644
--- a/dolphinscheduler-ui-next/src/components/chart/modules/Pie.tsx
+++ b/dolphinscheduler-ui-next/src/components/chart/modules/Pie.tsx
@@ -55,13 +55,6 @@ const PieChart = defineComponent({
             show: false,
             position: 'center',
           },
-          emphasis: {
-            label: {
-              show: true,
-              fontSize: '40',
-              fontWeight: 'bold',
-            },
-          },
           labelLine: {
             show: false,
           },
diff --git 
a/dolphinscheduler-ui-next/src/layouts/content/components/sidebar/index.tsx 
b/dolphinscheduler-ui-next/src/layouts/content/components/sidebar/index.tsx
index 39c9cfa..c8927ec 100644
--- a/dolphinscheduler-ui-next/src/layouts/content/components/sidebar/index.tsx
+++ b/dolphinscheduler-ui-next/src/layouts/content/components/sidebar/index.tsx
@@ -22,7 +22,7 @@ import { useI18n } from 'vue-i18n'
 import { useLanguageStore } from '@/store/language/language'
 
 interface Props {
-  sideMenuOptions: Array<any>,
+  sideMenuOptions: Array<any>
   isShowSide: boolean
 }
 
@@ -45,7 +45,8 @@ const Sidebar = (props: Props) => {
   const refreshOptionsRef = ref()
 
   return (
-    <NLayoutSider style={{display: props.isShowSide ? 'block' : 'none'}}
+    <NLayoutSider
+      style={{ display: props.isShowSide ? 'block' : 'none' }}
       bordered
       nativeScrollbar={false}
       show-trigger='bar'
diff --git a/dolphinscheduler-ui-next/src/layouts/content/index.tsx 
b/dolphinscheduler-ui-next/src/layouts/content/index.tsx
index fddf0ac..4cef9e6 100644
--- a/dolphinscheduler-ui-next/src/layouts/content/index.tsx
+++ b/dolphinscheduler-ui-next/src/layouts/content/index.tsx
@@ -23,7 +23,6 @@ import { useDataList } from './use-dataList'
 import { useLanguageStore } from '@/store/language/language'
 
 const Content = () => {
-
   const { state, getHeaderMenuOptions } = useDataList()
 
   const headerMenuOptions = getHeaderMenuOptions(state.menuOptions)
diff --git 
a/dolphinscheduler-ui-next/src/service/modules/projects-analysis/types.ts 
b/dolphinscheduler-ui-next/src/service/modules/projects-analysis/types.ts
index 71333f9..8df5057 100644
--- a/dolphinscheduler-ui-next/src/service/modules/projects-analysis/types.ts
+++ b/dolphinscheduler-ui-next/src/service/modules/projects-analysis/types.ts
@@ -30,9 +30,19 @@ interface UserList {
   count: number
 }
 
+interface TaskCountDto {
+  count: number
+  taskStateType: string
+}
+
 interface ProcessDefinitionRes {
   count: number
   userList: UserList[]
 }
 
-export { CodeReq, StateReq, ProcessDefinitionRes }
+interface TaskStateRes {
+  totalCount: number
+  taskCountDtos: TaskCountDto[]
+}
+
+export { CodeReq, StateReq, ProcessDefinitionRes, TaskStateRes }
diff --git a/dolphinscheduler-ui-next/src/views/home/definition-card.tsx 
b/dolphinscheduler-ui-next/src/views/home/definition-card.tsx
new file mode 100644
index 0000000..e4f5f6d
--- /dev/null
+++ b/dolphinscheduler-ui-next/src/views/home/definition-card.tsx
@@ -0,0 +1,58 @@
+/*
+ * 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, PropType } from 'vue'
+import { useProcessDefinition } from './use-process-definition'
+import BarChart from '@/components/chart/modules/Bar'
+import Card from '@/components/card'
+
+const props = {
+  title: {
+    type: String as PropType<string>,
+  },
+}
+
+const DefinitionCard = defineComponent({
+  name: 'DefinitionCard',
+  props,
+  setup() {
+    const { getProcessDefinition } = useProcessDefinition()
+    const processDefinition = getProcessDefinition()
+
+    return { processDefinition }
+  },
+  render() {
+    const { title, processDefinition } = this
+
+    return (
+      <Card title={title}>
+        {{
+          default: () =>
+            processDefinition.xAxisData.length > 0 &&
+            processDefinition.seriesData.length > 0 && (
+              <BarChart
+                xAxisData={processDefinition.xAxisData}
+                seriesData={processDefinition.seriesData}
+              />
+            ),
+        }}
+      </Card>
+    )
+  },
+})
+
+export default DefinitionCard
diff --git a/dolphinscheduler-ui-next/src/views/home/index.tsx 
b/dolphinscheduler-ui-next/src/views/home/index.tsx
index 62d89d8..19313b3 100644
--- a/dolphinscheduler-ui-next/src/views/home/index.tsx
+++ b/dolphinscheduler-ui-next/src/views/home/index.tsx
@@ -15,75 +15,57 @@
  * limitations under the License.
  */
 
-import { defineComponent } from 'vue'
-import { NGrid, NGi, NDataTable } from 'naive-ui'
+import { defineComponent, Ref, onMounted, ref, watch } from 'vue'
+import { NGrid, NGi } from 'naive-ui'
+import { startOfToday, getTime } from 'date-fns'
 import { useI18n } from 'vue-i18n'
-import { useTable } from './use-table'
-import { useProcessDefinition } from './use-process-definition'
-import Card from '@/components/card'
-import PieChart from '@/components/chart/modules/Pie'
-import BarChart from '@/components/chart/modules/Bar'
+import { useTaskState } from './use-task-state'
+import StateCard from './state-card'
+import DefinitionCard from './definition-card'
 import styles from './index.module.scss'
-import type { ProcessDefinitionRes } from 
'@/service/modules/projects-analysis/types'
 
 export default defineComponent({
   name: 'home',
   setup() {
     const { t } = useI18n()
-    const { getProcessDefinition, formatProcessDefinition } =
-      useProcessDefinition()
-    const processDefinition = getProcessDefinition()
+    const dateRef = ref([getTime(startOfToday()), Date.now()])
+    const { getTaskState } = useTaskState()
+    let taskStateRef: Ref<any> = ref([])
 
-    return { t, processDefinition, formatProcessDefinition }
+    onMounted(() => {
+      taskStateRef.value = getTaskState(dateRef.value)
+    })
+
+    const handleTaskDate = (val: any) => {
+      taskStateRef.value = getTaskState(val)
+    }
+
+    return { t, dateRef, handleTaskDate, taskStateRef }
   },
   render() {
-    const { columnsRef } = useTable()
-    const { t, processDefinition, formatProcessDefinition } = this
-    const chartData =
-      Object.keys(processDefinition).length > 0 &&
-      formatProcessDefinition(processDefinition as ProcessDefinitionRes)
+    const { t, dateRef, handleTaskDate } = this
 
     return (
       <div>
         <NGrid x-gap={12} cols={2}>
           <NGi>
-            <Card title={t('home.task_state_statistics')}>
-              {{
-                default: () => (
-                  <div class={styles['card-table']}>
-                    <PieChart />
-                    <NDataTable columns={columnsRef} />
-                  </div>
-                ),
-              }}
-            </Card>
+            <StateCard
+              title={t('home.task_state_statistics')}
+              date={dateRef}
+              tableData={this.taskStateRef.value}
+              onUpdateDatePickerValue={handleTaskDate}
+            />
           </NGi>
           <NGi class={styles['card-table']}>
-            <Card title={t('home.process_state_statistics')}>
-              {{
-                default: () => (
-                  <div class={styles['card-table']}>
-                    <PieChart />
-                    <NDataTable columns={columnsRef} />
-                  </div>
-                ),
-              }}
-            </Card>
+            <StateCard
+              title={t('home.process_state_statistics')}
+              date={dateRef}
+            />
           </NGi>
         </NGrid>
         <NGrid cols={1} style='margin-top: 12px;'>
           <NGi>
-            <Card title={t('home.process_definition_statistics')}>
-              {{
-                default: () =>
-                  chartData && (
-                    <BarChart
-                      xAxisData={chartData.xAxisData}
-                      seriesData={chartData.seriesData}
-                    />
-                  ),
-              }}
-            </Card>
+            <DefinitionCard title={t('home.process_definition_statistics')} />
           </NGi>
         </NGrid>
       </div>
diff --git a/dolphinscheduler-ui-next/src/views/home/state-card.tsx 
b/dolphinscheduler-ui-next/src/views/home/state-card.tsx
new file mode 100644
index 0000000..432a5ec
--- /dev/null
+++ b/dolphinscheduler-ui-next/src/views/home/state-card.tsx
@@ -0,0 +1,83 @@
+/*
+ * 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, PropType } from 'vue'
+import { useTable } from './use-table'
+import styles from '@/views/home/index.module.scss'
+import PieChart from '@/components/chart/modules/Pie'
+import { NDataTable, NDatePicker } from 'naive-ui'
+import Card from '@/components/card'
+
+const props = {
+  title: {
+    type: String as PropType<string>,
+  },
+  date: {
+    type: Array as PropType<Array<any>>,
+  },
+  tableData: {
+    type: [Array, Boolean] as PropType<Array<any> | false>,
+  },
+}
+
+const StateCard = defineComponent({
+  name: 'StateCard',
+  props,
+  emits: ['updateDatePickerValue'],
+  setup(props, ctx) {
+    const onUpdateDatePickerValue = (val: any) => {
+      ctx.emit('updateDatePickerValue', val)
+    }
+
+    return { onUpdateDatePickerValue }
+  },
+  render() {
+    const { title, date, tableData, onUpdateDatePickerValue } = this
+    const { columnsRef } = useTable()
+
+    return (
+      <Card title={title}>
+        {{
+          default: () => (
+            <div class={styles['card-table']}>
+              <PieChart />
+              {tableData && (
+                <NDataTable
+                  columns={columnsRef}
+                  data={tableData}
+                  striped
+                  size={'small'}
+                />
+              )}
+            </div>
+          ),
+          'header-extra': () => (
+            <NDatePicker
+              default-value={date}
+              onUpdateValue={onUpdateDatePickerValue}
+              size='small'
+              type='datetimerange'
+              clearable
+            />
+          ),
+        }}
+      </Card>
+    )
+  },
+})
+
+export default StateCard
diff --git a/dolphinscheduler-ui-next/src/views/home/use-task-state.ts 
b/dolphinscheduler-ui-next/src/views/home/types.ts
similarity index 79%
copy from dolphinscheduler-ui-next/src/views/home/use-task-state.ts
copy to dolphinscheduler-ui-next/src/views/home/types.ts
index 3e7c6c2..83b6cc5 100644
--- a/dolphinscheduler-ui-next/src/views/home/use-task-state.ts
+++ b/dolphinscheduler-ui-next/src/views/home/types.ts
@@ -14,3 +14,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
+interface ChartData {
+  xAxisData: Array<string>
+  seriesData: Array<number>
+}
+
+interface TaskStateTableData {
+  id: number
+  number: number
+  state: string
+}
+
+export { ChartData, TaskStateTableData }
diff --git a/dolphinscheduler-ui-next/src/views/home/use-process-definition.ts 
b/dolphinscheduler-ui-next/src/views/home/use-process-definition.ts
index cc97464..cfb04a4 100644
--- a/dolphinscheduler-ui-next/src/views/home/use-process-definition.ts
+++ b/dolphinscheduler-ui-next/src/views/home/use-process-definition.ts
@@ -18,22 +18,23 @@
 import { useAsyncState } from '@vueuse/core'
 import { countDefinitionByUser } from '@/service/modules/projects-analysis'
 import type { ProcessDefinitionRes } from 
'@/service/modules/projects-analysis/types'
+import type { ChartData } from './types'
 
 export function useProcessDefinition() {
   const getProcessDefinition = () => {
     const { state } = useAsyncState(
-      countDefinitionByUser({ projectCode: 0 }),
-      {}
+      countDefinitionByUser({ projectCode: 0 }).then(
+        (res: ProcessDefinitionRes): ChartData => {
+          const xAxisData = res.userList.map((item) => item.userName)
+          const seriesData = res.userList.map((item) => item.count)
+
+          return { xAxisData, seriesData }
+        }
+      ),
+      { xAxisData: [], seriesData: [] }
     )
     return state
   }
 
-  const formatProcessDefinition = (data: ProcessDefinitionRes) => {
-    const xAxisData: Array<string> = data.userList.map((item) => item.userName)
-    const seriesData: Array<number> = data.userList.map((item) => item.count)
-
-    return { xAxisData, seriesData }
-  }
-
-  return { getProcessDefinition, formatProcessDefinition }
+  return { getProcessDefinition }
 }
diff --git a/dolphinscheduler-ui-next/src/views/home/use-process-state.ts 
b/dolphinscheduler-ui-next/src/views/home/use-process-state.ts
index 3e7c6c2..c2e00d8 100644
--- a/dolphinscheduler-ui-next/src/views/home/use-process-state.ts
+++ b/dolphinscheduler-ui-next/src/views/home/use-process-state.ts
@@ -14,3 +14,5 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
+import { useAsyncState } from '@vueuse/core'
diff --git a/dolphinscheduler-ui-next/src/views/home/use-table.ts 
b/dolphinscheduler-ui-next/src/views/home/use-table.ts
index 81bdc6a..5954d6f 100644
--- a/dolphinscheduler-ui-next/src/views/home/use-table.ts
+++ b/dolphinscheduler-ui-next/src/views/home/use-table.ts
@@ -22,7 +22,7 @@ export function useTable() {
   const { t } = useI18n()
 
   const columnsRef: TableColumns<any> = [
-    { title: '#', key: '#' },
+    { title: '#', key: 'id' },
     { title: t('home.number'), key: 'number' },
     { title: t('home.state'), key: 'state' },
   ]
diff --git a/dolphinscheduler-ui-next/src/views/home/use-task-state.ts 
b/dolphinscheduler-ui-next/src/views/home/use-task-state.ts
index 3e7c6c2..9182c20 100644
--- a/dolphinscheduler-ui-next/src/views/home/use-task-state.ts
+++ b/dolphinscheduler-ui-next/src/views/home/use-task-state.ts
@@ -14,3 +14,34 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
+import { useAsyncState } from '@vueuse/core'
+import { format } from 'date-fns'
+import { countTaskState } from '@/service/modules/projects-analysis'
+import type { TaskStateRes } from '@/service/modules/projects-analysis/types'
+import type { TaskStateTableData } from './types'
+
+export function useTaskState() {
+  const getTaskState = (date: Array<number>) => {
+    const { state } = useAsyncState(
+      countTaskState({
+        startDate: format(date[0], 'yyyy-MM-dd HH:mm:ss'),
+        endDate: format(date[1], 'yyyy-MM-dd HH:mm:ss'),
+        projectCode: 0,
+      }).then((res: TaskStateRes): Array<TaskStateTableData> => {
+        return res.taskCountDtos.map((item, index) => {
+          return {
+            id: index + 1,
+            state: item.taskStateType,
+            number: item.count,
+          }
+        })
+      }),
+      []
+    )
+
+    return state
+  }
+
+  return { getTaskState }
+}
diff --git a/dolphinscheduler-ui-next/src/views/login/index.tsx 
b/dolphinscheduler-ui-next/src/views/login/index.tsx
index 31fc87e..db88412 100644
--- a/dolphinscheduler-ui-next/src/views/login/index.tsx
+++ b/dolphinscheduler-ui-next/src/views/login/index.tsx
@@ -15,80 +15,86 @@
  * limitations under the License.
  */
 
-import { withKeys } from 'vue'
+import { defineComponent, toRefs, withKeys } from 'vue'
 import styles from './index.module.scss'
 import { NInput, NButton, NSwitch, NForm, NFormItem } from 'naive-ui'
 import { useValidate } from './use-validate'
 import { useTranslate } from './use-translate'
 import { useLogin } from './use-login'
 
-const login = () => {
-  const { state, t, locale } = useValidate()
+const login = defineComponent({
+  name: 'login',
+  setup() {
+    const { state, t, locale } = useValidate()
 
-  const { handleChange } = useTranslate(locale)
+    const { handleChange } = useTranslate(locale)
 
-  const { handleLogin } = useLogin(state)
+    const { handleLogin } = useLogin(state)
 
-  return (
-    <div class={styles.container}>
-      <div class={styles['language-switch']}>
-        <NSwitch
-          onUpdateValue={handleChange}
-          checked-value='en_US'
-          unchecked-value='zh_CN'
-        >
-          {{
-            checked: () => 'en_US',
-            unchecked: () => 'zh_CN',
-          }}
-        </NSwitch>
-      </div>
-      <div class={styles['login-model']}>
-        <div class={styles.logo}>
-          <div class={styles['logo-img']} />
+    return { t, handleChange, handleLogin, ...toRefs(state) }
+  },
+  render() {
+    return (
+      <div class={styles.container}>
+        <div class={styles['language-switch']}>
+          <NSwitch
+            onUpdateValue={this.handleChange}
+            checked-value='en_US'
+            unchecked-value='zh_CN'
+          >
+            {{
+              checked: () => 'en_US',
+              unchecked: () => 'zh_CN',
+            }}
+          </NSwitch>
         </div>
-        <div class={styles['form-model']}>
-          <NForm rules={state.rules} ref='loginFormRef'>
-            <NFormItem
-              label={t('login.userName')}
-              label-style={{ color: 'black' }}
-              path='userName'
+        <div class={styles['login-model']}>
+          <div class={styles.logo}>
+            <div class={styles['logo-img']} />
+          </div>
+          <div class={styles['form-model']}>
+            <NForm rules={this.rules} ref='loginFormRef'>
+              <NFormItem
+                label={this.t('login.userName')}
+                label-style={{ color: 'black' }}
+                path='userName'
+              >
+                <NInput
+                  type='text'
+                  size='large'
+                  v-model={[this.loginForm.userName, 'value']}
+                  placeholder={this.t('login.userName_tips')}
+                  autofocus
+                  onKeydown={withKeys(this.handleLogin, ['enter'])}
+                />
+              </NFormItem>
+              <NFormItem
+                label={this.t('login.userPassword')}
+                label-style={{ color: 'black' }}
+                path='userPassword'
+              >
+                <NInput
+                  type='password'
+                  size='large'
+                  v-model={[this.loginForm.userPassword, 'value']}
+                  placeholder={this.t('login.userPassword_tips')}
+                  onKeydown={withKeys(this.handleLogin, ['enter'])}
+                />
+              </NFormItem>
+            </NForm>
+            <NButton
+              round
+              type='info'
+              style={{ width: '100%' }}
+              onClick={this.handleLogin}
             >
-              <NInput
-                type='text'
-                size='large'
-                v-model={[state.loginForm.userName, 'value']}
-                placeholder={t('login.userName_tips')}
-                autofocus
-                onKeydown={withKeys(handleLogin, ['enter'])}
-              />
-            </NFormItem>
-            <NFormItem
-              label={t('login.userPassword')}
-              label-style={{ color: 'black' }}
-              path='userPassword'
-            >
-              <NInput
-                type='password'
-                size='large'
-                v-model={[state.loginForm.userPassword, 'value']}
-                placeholder={t('login.userPassword_tips')}
-                onKeydown={withKeys(handleLogin, ['enter'])}
-              />
-            </NFormItem>
-          </NForm>
-          <NButton
-            round
-            type='info'
-            style={{ width: '100%' }}
-            onClick={handleLogin}
-          >
-            {t('login.login')}
-          </NButton>
+              {this.t('login.login')}
+            </NButton>
+          </div>
         </div>
       </div>
-    </div>
-  )
-}
+    )
+  },
+})
 
 export default login

Reply via email to