Browse Source

[Feature][UI] Add manual input for scheduling dates. (#10396)

* [Feature][UI] Add manual input for scheduling dates.

* [Fix][UI] Fix singlequote.

* [Feature][UI] Remove check for duplicate scheduling dates.
Amy0104 2 years ago
parent
commit
f0131d5b7a

+ 5 - 0
dolphinscheduler-ui/src/locales/en_US/project.ts

@@ -106,6 +106,11 @@ export default {
     all_send: 'All',
     whether_complement_data: 'Whether it is a complement process?',
     schedule_date: 'Schedule date',
+    select_date: 'Select Date',
+    enter_date: 'Enter Date',
+    schedule_date_tips:
+      'The format is yyyy-MM-dd HH:mm:ss with multiple comma splits',
+    schedule_date_limit: 'Enter more than 100 dates',
     mode_of_execution: 'Mode of execution',
     serial_execution: 'Serial execution',
     parallel_execution: 'Parallel execution',

+ 4 - 0
dolphinscheduler-ui/src/locales/zh_CN/project.ts

@@ -108,6 +108,10 @@ export default {
     all_send: '成功或失败都发',
     whether_complement_data: '是否是补数',
     schedule_date: '调度日期',
+    select_date: '日期选择',
+    enter_date: '手动输入',
+    schedule_date_tips: '格式为yyyy-MM-dd HH:mm:ss,多个逗号分割',
+    schedule_date_limit: '输入日期不满足<=100条',
     mode_of_execution: '执行方式',
     serial_execution: '串行执行',
     parallel_execution: '并行执行',

+ 38 - 10
dolphinscheduler-ui/src/views/projects/workflow/definition/components/start-modal.tsx

@@ -40,7 +40,8 @@ import {
   NSelect,
   NSwitch,
   NCheckbox,
-  NDatePicker
+  NDatePicker,
+  NRadioButton
 } from 'naive-ui'
 import {
   ArrowDownOutlined,
@@ -228,7 +229,7 @@ export default defineComponent({
         onConfirm={this.handleStart}
         confirmLoading={this.saving}
       >
-        <NForm ref='startFormRef'>
+        <NForm ref='startFormRef' model={this.startForm} rules={this.rules}>
           <NFormItem
             label={t('project.workflow.workflow_name')}
             path='workflow_name'
@@ -316,7 +317,7 @@ export default defineComponent({
           </NFormItem>
           {this.startForm.execType &&
             this.startForm.execType !== 'START_PROCESS' && (
-              <NSpace>
+              <NSpace vertical class={styles['width-100']}>
                 <NFormItem
                   label={t('project.workflow.mode_of_dependent')}
                   path='dependentMode'
@@ -366,14 +367,41 @@ export default defineComponent({
                 )}
                 <NFormItem
                   label={t('project.workflow.schedule_date')}
-                  path='startEndTime'
+                  path={
+                    this.startForm.dataDateType === 1
+                      ? 'startEndTime'
+                      : 'scheduleTime'
+                  }
                 >
-                  <NDatePicker
-                    type='datetimerange'
-                    clearable
-                    v-model:value={this.startForm.startEndTime}
-                    placement='top'
-                  />
+                  <NSpace vertical class={styles['width-100']}>
+                    <NRadioGroup
+                      name='data-date'
+                      v-model:value={this.startForm.dataDateType}
+                    >
+                      {[
+                        { label: t('project.workflow.select_date'), value: 1 },
+                        { label: t('project.workflow.enter_date'), value: 2 }
+                      ].map((item) => (
+                        <NRadioButton {...item} key={item.value} />
+                      ))}
+                    </NRadioGroup>
+
+                    {this.startForm.dataDateType === 1 ? (
+                      <NDatePicker
+                        type='datetimerange'
+                        clearable
+                        v-model:value={this.startForm.startEndTime}
+                        placement='top'
+                      />
+                    ) : (
+                      <NInput
+                        clearable
+                        type='textarea'
+                        v-model:value={this.startForm.scheduleTime}
+                        placeholder={t('project.workflow.schedule_date_tips')}
+                      />
+                    )}
+                  </NSpace>
                 </NFormItem>
               </NSpace>
             )}

+ 2 - 0
dolphinscheduler-ui/src/views/projects/workflow/definition/components/types.ts

@@ -15,6 +15,8 @@
  * limitations under the License.
  */
 
+export type { ProcessInstanceReq } from '@/service/modules/executors/types'
+
 export interface IEnvironmentOption {
   label: string
   value: string

+ 22 - 2
dolphinscheduler-ui/src/views/projects/workflow/definition/components/use-form.ts

@@ -51,7 +51,8 @@ export const useForm = () => {
     startForm: {
       processDefinitionCode: -1,
       startEndTime: [new Date(year, month, day), new Date(year, month, day)],
-      scheduleTime: null,
+      scheduleTime: '',
+      dataDateType: 1,
       failureStrategy: 'CONTINUE',
       warningType: 'NONE',
       warningGroupId: null,
@@ -67,7 +68,26 @@ export const useForm = () => {
       expectedParallelismNumber: '',
       dryRun: 0
     },
-    saving: false
+    saving: false,
+    rules: {
+      scheduleTime: {
+        trigger: ['input', 'blur'],
+        validator(unuse: any, value: string) {
+          if (!value) return
+          if (
+            !/(((19|20)[0-9]{2})-((0[1-9])|(1[0-2]))-((0[1-9])|((1|2)[0-9])|(3[0-1]))([ ])([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]))(,(((19|20)[0-9]{2})-((0[1-9])|(1[0-2]))-((0[1-9])|((1|2)[0-9])|(3[0-1]))([ ])([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])))*$/.test(
+              value
+            )
+          ) {
+            return new Error(t('project.workflow.schedule_date_tips'))
+          }
+          const dates = value.split(',')
+          if (dates.length > 100) {
+            return new Error(t('project.workflow.schedule_date_limit'))
+          }
+        }
+      }
+    }
   })
 
   const timingState = reactive({

+ 18 - 6
dolphinscheduler-ui/src/views/projects/workflow/definition/components/use-modal.ts

@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-import _, { cloneDeep } from 'lodash'
+import _, { cloneDeep, omit } from 'lodash'
 import { reactive, SetupContext } from 'vue'
 import { useI18n } from 'vue-i18n'
 import { useRoute, useRouter } from 'vue-router'
@@ -37,7 +37,7 @@ import {
 } from '@/service/modules/schedules'
 import { parseTime } from '@/common/common'
 import { EnvironmentItem } from '@/service/modules/environment/types'
-import { ITimingState } from './types'
+import { ITimingState, ProcessInstanceReq } from './types'
 
 export function useModal(
   state: any,
@@ -92,7 +92,12 @@ export function useModal(
     state.saving = true
     try {
       state.startForm.processDefinitionCode = code
-      if (state.startForm.startEndTime) {
+      const params = omit(state.startForm, [
+        'startEndTime',
+        'scheduleTime',
+        'dataDateType'
+      ]) as ProcessInstanceReq
+      if (state.startForm.dataDateType === 1) {
         const start = format(
           new Date(state.startForm.startEndTime[0]),
           'yyyy-MM-dd HH:mm:ss'
@@ -101,7 +106,14 @@ export function useModal(
           new Date(state.startForm.startEndTime[1]),
           'yyyy-MM-dd HH:mm:ss'
         )
-        state.startForm.scheduleTime = `${start},${end}`
+        params.scheduleTime = JSON.stringify({
+          complementStartDate: start,
+          complementEndDate: end
+        })
+      } else {
+        params.scheduleTime = JSON.stringify({
+          complementScheduleDateList: state.startForm.scheduleTime
+        })
       }
 
       const startParams = {} as any
@@ -110,11 +122,11 @@ export function useModal(
           startParams[item.prop] = item.value
         }
       }
-      state.startForm.startParams = !_.isEmpty(startParams)
+      params.startParams = !_.isEmpty(startParams)
         ? JSON.stringify(startParams)
         : ''
 
-      await startProcessInstance(state.startForm, variables.projectCode)
+      await startProcessInstance(params, variables.projectCode)
       window.$message.success(t('project.workflow.success'))
       state.saving = false
       ctx.emit('updateList')

+ 3 - 0
dolphinscheduler-ui/src/views/projects/workflow/definition/index.module.scss

@@ -115,3 +115,6 @@
     }
   }
 }
+.width-100 {
+  width: 100%;
+}