This is an automated email from the ASF dual-hosted git repository.
nicholasjiang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/paimon-webui.git
The following commit(s) were added to refs/heads/main by this push:
new a8d7d56 [Feature] Introduce CDC job submission form (#238)
a8d7d56 is described below
commit a8d7d5667c417732661a178f5f57abad2dd111b5
Author: yangyang zhong <[email protected]>
AuthorDate: Wed May 22 21:30:17 2024 +0800
[Feature] Introduce CDC job submission form (#238)
---
paimon-web-ui/src/api/models/cdc/index.ts | 8 +-
paimon-web-ui/src/api/models/cdc/interface.ts | 5 +-
paimon-web-ui/src/form-lib/cdc/use-paimon.ts | 196 ++++++++++----------
.../{index.ts => cdc/use-submit-cdc-job.ts} | 41 +++--
paimon-web-ui/src/form-lib/index.ts | 4 +-
paimon-web-ui/src/locales/en/modules/cdc.ts | 1 +
paimon-web-ui/src/locales/en/modules/common.ts | 1 +
paimon-web-ui/src/locales/zh/modules/cdc.ts | 1 +
paimon-web-ui/src/locales/zh/modules/common.ts | 1 +
.../src/views/cdc/components/list/index.tsx | 5 +-
.../src/views/cdc/components/list/use-table.ts | 198 +++++++++++----------
paimon-web-ui/src/views/cdc/index.tsx | 33 +++-
12 files changed, 276 insertions(+), 218 deletions(-)
diff --git a/paimon-web-ui/src/api/models/cdc/index.ts
b/paimon-web-ui/src/api/models/cdc/index.ts
index 98f2385..c7705d0 100644
--- a/paimon-web-ui/src/api/models/cdc/index.ts
+++ b/paimon-web-ui/src/api/models/cdc/index.ts
@@ -16,7 +16,7 @@ specific language governing permissions and limitations
under the License. */
-import type { CdcJobDefinition } from './interface'
+import type { CdcJobDefinition, CdcJobSubmit } from './interface'
import httpRequest from '@/api/request'
export * from './interface'
@@ -54,3 +54,9 @@ export const getCdcJobDefinition = (id: number) => {
export const deleteCdcJobDefinition = (id: number) => {
return httpRequest.delete(`/cdc-job-definition/${id}`)
}
+/**
+ * # Submit cdc job
+ */
+export const submitCdcJob = (id:number,form:CdcJobSubmit)=>{
+ return httpRequest.post(`/cdc-job-definition/${id}/submit`, form)
+}
diff --git a/paimon-web-ui/src/api/models/cdc/interface.ts
b/paimon-web-ui/src/api/models/cdc/interface.ts
index dec7b6e..997a6bf 100644
--- a/paimon-web-ui/src/api/models/cdc/interface.ts
+++ b/paimon-web-ui/src/api/models/cdc/interface.ts
@@ -25,4 +25,7 @@ export interface CdcJobDefinition {
config?: string;
createUser?: string;
}
-
\ No newline at end of file
+
+export interface CdcJobSubmit{
+ flinkSessionUrl:string
+}
diff --git a/paimon-web-ui/src/form-lib/cdc/use-paimon.ts
b/paimon-web-ui/src/form-lib/cdc/use-paimon.ts
index d8d2322..887be63 100644
--- a/paimon-web-ui/src/form-lib/cdc/use-paimon.ts
+++ b/paimon-web-ui/src/form-lib/cdc/use-paimon.ts
@@ -15,109 +15,101 @@ KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License. */
-import { getAllCatalogs } from "@/api/models/catalog"
-import type { IJsonItem } from "@/components/dynamic-form/types"
-import { useCatalogStore } from "@/store/catalog"
+import type { IJsonItem } from '@/components/dynamic-form/types'
+import { useCatalogStore } from '@/store/catalog'
export function usePaimon(item: any) {
- const { t } = useLocaleHooks()
- const tabType = item.data.tabType
- let catalogOptions: any = ref([{value:1}])
- const catalogStore = useCatalogStore()
- catalogStore.getAllCatalogs().then(()=>{
- catalogOptions.value = catalogStore.catalogs
- })
- const model = reactive({
- warehouse: '',
- metastore: '',
- url: '',
- other_configs: '',
- database: '',
- table_name: '',
- primary_key: '',
- partition_column: '',
- other_configs2: '',
- })
+ const { t } = useLocaleHooks()
+ const tabType = item.data.tabType
+ let catalogOptions: any = ref([{ value: 1 }])
+ const catalogStore = useCatalogStore()
+ catalogStore.getAllCatalogs().then(() => {
+ catalogOptions.value = catalogStore.catalogs?.map((e) => {
+ return { label: e.label, value: e.key }
+ })
+ })
+ const data = item.data
+ const model = reactive({ ...data })
- return {
- json: [
- {
- type: 'select',
- field: 'catalog',
- name: 'catalog',
- span: computed(() => tabType.value ===
'catalog_configuration' ? 24 : 0),
- props: {
- placeholder: '',
- },
- options: catalogOptions
-
- },
- {
- type: 'input',
- field: 'database',
- name: t('cdc.database'),
- props: {
- placeholder: ''
- },
- span: computed(() => tabType.value ===
'synchronization_configuration' ? 24 : 0),
- validate: {
- trigger: ['input', 'blur'],
- required: true,
- message: 'error',
- validator: (validator: any, value:
string) => {
- if (!value) {
- return new
Error('error')
- }
- }
- }
- },
- {
- type: 'input',
- field: 'table_name',
- name: t('cdc.table_name'),
- props: {
- placeholder: ''
- },
- span: computed(() => tabType.value ===
'synchronization_configuration' ? 24 : 0),
- validate: {
- trigger: ['input', 'blur'],
- required: true,
- message: 'error',
- validator: (validator: any, value:
string) => {
- if (!value) {
- return new
Error('error')
- }
- }
- }
- },
- {
- type: 'input',
- field: 'primary_key',
- name: t('cdc.primary_key'),
- span: computed(() => tabType.value ===
'synchronization_configuration' ? 24 : 0),
- props: {
- placeholder: ''
- }
- },
- {
- type: 'input',
- field: 'partition_column',
- name: t('cdc.partition_column'),
- span: computed(() => tabType.value ===
'synchronization_configuration' ? 24 : 0),
- props: {
- placeholder: ''
- }
- },
- {
- type: 'input',
- field: 'other_configs2',
- name: t('cdc.other_configs'),
- span: computed(() => tabType.value ===
'synchronization_configuration' ? 24 : 0),
- props: {
- placeholder: '',
- type: 'textarea',
- }
- },
- ] as IJsonItem[], model
- }
+ return {
+ json: [
+ {
+ type: 'select',
+ field: 'catalog',
+ name: 'catalog',
+ span: computed(() => (tabType.value === 'catalog_configuration' ? 24 :
0)),
+ props: {
+ placeholder: ''
+ },
+ options: catalogOptions
+ },
+ {
+ type: 'input',
+ field: 'database',
+ name: t('cdc.database'),
+ props: {
+ placeholder: ''
+ },
+ span: computed(() => (tabType.value ===
'synchronization_configuration' ? 24 : 0)),
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ message: 'error',
+ validator: (validator: any, value: string) => {
+ if (!value) {
+ return new Error('error')
+ }
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'table_name',
+ name: t('cdc.table_name'),
+ props: {
+ placeholder: ''
+ },
+ span: computed(() => (tabType.value ===
'synchronization_configuration' ? 24 : 0)),
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ message: 'error',
+ validator: (validator: any, value: string) => {
+ if (!value) {
+ return new Error('error')
+ }
+ }
+ }
+ },
+ {
+ type: 'input',
+ field: 'primary_key',
+ name: t('cdc.primary_key'),
+ span: computed(() => (tabType.value ===
'synchronization_configuration' ? 24 : 0)),
+ props: {
+ placeholder: ''
+ }
+ },
+ {
+ type: 'input',
+ field: 'partition_column',
+ name: t('cdc.partition_column'),
+ span: computed(() => (tabType.value ===
'synchronization_configuration' ? 24 : 0)),
+ props: {
+ placeholder: ''
+ }
+ },
+ {
+ type: 'input',
+ field: 'other_configs2',
+ name: t('cdc.other_configs'),
+ span: computed(() => (tabType.value ===
'synchronization_configuration' ? 24 : 0)),
+ props: {
+ placeholder: '',
+ type: 'textarea'
+ }
+ }
+ ] as IJsonItem[],
+ model
+ }
}
diff --git a/paimon-web-ui/src/form-lib/index.ts
b/paimon-web-ui/src/form-lib/cdc/use-submit-cdc-job.ts
similarity index 52%
copy from paimon-web-ui/src/form-lib/index.ts
copy to paimon-web-ui/src/form-lib/cdc/use-submit-cdc-job.ts
index 18a3d2c..eba9fb2 100644
--- a/paimon-web-ui/src/form-lib/index.ts
+++ b/paimon-web-ui/src/form-lib/cdc/use-submit-cdc-job.ts
@@ -15,17 +15,36 @@ KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License. */
-import { useCDCList } from './cdc/use-cdc-list'
-import { useMYSQL } from './cdc/use-mysql'
-import { usePaimon } from './cdc/use-paimon'
+import type { CdcJobSubmit } from "@/api/models/cdc"
+import type { IJsonItem } from "@/components/dynamic-form/types"
-import { useDatabase } from './metadata/use-database'
-import { useOptions } from './metadata/use-options'
+export function useSumbitCdcJob(item:any) {
+ const { t } = useLocaleHooks()
-export default {
- CDCLIST: useCDCList,
- MYSQL: useMYSQL,
- PAIMON: usePaimon,
- DATABASE: useDatabase,
- OPTIONS: useOptions
+ const model = reactive<CdcJobSubmit>({
+ flinkSessionUrl: item.flinkSessionUrl,
+ })
+
+ return {
+ json: [
+ {
+ type: 'input',
+ field: 'flinkSessionUrl',
+ name: t('common.flink_session_url'),
+ props: {
+ placeholder: ''
+ },
+ validate: {
+ trigger: ['input', 'blur'],
+ required: true,
+ message: 'error',
+ validator: (validator: any, value:
string) => {
+ if (!value) {
+ return new
Error('error')
+ }
+ }
+ }
+ }
+ ] as IJsonItem[], model
+ }
}
diff --git a/paimon-web-ui/src/form-lib/index.ts
b/paimon-web-ui/src/form-lib/index.ts
index 18a3d2c..16233b3 100644
--- a/paimon-web-ui/src/form-lib/index.ts
+++ b/paimon-web-ui/src/form-lib/index.ts
@@ -16,6 +16,7 @@ specific language governing permissions and limitations
under the License. */
import { useCDCList } from './cdc/use-cdc-list'
+import { useSumbitCdcJob } from './cdc/use-submit-cdc-job'
import { useMYSQL } from './cdc/use-mysql'
import { usePaimon } from './cdc/use-paimon'
@@ -27,5 +28,6 @@ export default {
MYSQL: useMYSQL,
PAIMON: usePaimon,
DATABASE: useDatabase,
- OPTIONS: useOptions
+ OPTIONS: useOptions,
+ CDCSUBMIT: useSumbitCdcJob
}
diff --git a/paimon-web-ui/src/locales/en/modules/cdc.ts
b/paimon-web-ui/src/locales/en/modules/cdc.ts
index 2ae4a73..5f88d83 100644
--- a/paimon-web-ui/src/locales/en/modules/cdc.ts
+++ b/paimon-web-ui/src/locales/en/modules/cdc.ts
@@ -49,4 +49,5 @@ export default {
synchronization_configuration: 'Synchronization Configuration',
primary_key: 'Primary Key',
partition_column: 'Partition Column',
+ submit_cdc_job:'Submit'
}
diff --git a/paimon-web-ui/src/locales/en/modules/common.ts
b/paimon-web-ui/src/locales/en/modules/common.ts
index c8c4c3a..ef0d72e 100644
--- a/paimon-web-ui/src/locales/en/modules/common.ts
+++ b/paimon-web-ui/src/locales/en/modules/common.ts
@@ -27,4 +27,5 @@ export default {
yes:'Yes',
no:'No',
action: 'Action',
+ flink_session_url: 'Flink Session Url'
}
diff --git a/paimon-web-ui/src/locales/zh/modules/cdc.ts
b/paimon-web-ui/src/locales/zh/modules/cdc.ts
index c95dd5d..0bb6e08 100644
--- a/paimon-web-ui/src/locales/zh/modules/cdc.ts
+++ b/paimon-web-ui/src/locales/zh/modules/cdc.ts
@@ -49,4 +49,5 @@ export default {
synchronization_configuration: '同步配置',
primary_key: '主键',
partition_column: '分区列',
+ submit_cdc_job:'提交 CDC 作业'
}
diff --git a/paimon-web-ui/src/locales/zh/modules/common.ts
b/paimon-web-ui/src/locales/zh/modules/common.ts
index 223a6d8..034791b 100644
--- a/paimon-web-ui/src/locales/zh/modules/common.ts
+++ b/paimon-web-ui/src/locales/zh/modules/common.ts
@@ -27,4 +27,5 @@ export default {
yes: '是',
no: '否',
action: '操作',
+ flink_session_url: 'Flink Session 集群地址'
}
diff --git a/paimon-web-ui/src/views/cdc/components/list/index.tsx
b/paimon-web-ui/src/views/cdc/components/list/index.tsx
index 21176dd..ed3edff 100644
--- a/paimon-web-ui/src/views/cdc/components/list/index.tsx
+++ b/paimon-web-ui/src/views/cdc/components/list/index.tsx
@@ -20,10 +20,11 @@ import { useTable } from './use-table'
export default defineComponent({
name: 'ListPage',
- setup() {
+ emits:['cdcJobSubmit'],
+ setup(_,ctx) {
const { t } = useLocaleHooks()
- const { tableVariables, getTableData } = useTable()
+ const { tableVariables, getTableData } = useTable(ctx)
getTableData()
return {
diff --git a/paimon-web-ui/src/views/cdc/components/list/use-table.ts
b/paimon-web-ui/src/views/cdc/components/list/use-table.ts
index 70a3be1..f0ca49a 100644
--- a/paimon-web-ui/src/views/cdc/components/list/use-table.ts
+++ b/paimon-web-ui/src/views/cdc/components/list/use-table.ts
@@ -15,106 +15,110 @@ KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License. */
-import { useCDCStore } from '@/store/cdc';
-import type { Router } from 'vue-router';
-import TableAction from '@/components/table-action';
-import { deleteCdcJobDefinition, getCdcJobDefinition, listAllCdcJob } from
'@/api/models/cdc';
-import { get } from 'lodash';
-export const useTable = () => {
- const router: Router = useRouter()
- const { t } = useLocaleHooks()
- const tableVariables = reactive({
- columns: [
- {
- title: t('cdc.job_name'),
- key: 'name',
- resizable: true
- },
- {
- title: t('cdc.synchronization_type'),
- key: 'cdcType',
- resizable: true,
- render: (row:any)=>{
- if(row.cdcType == 0){
- return t('cdc.single_table_synchronization')
- }else if(row.cdcType ==1){
- return t('cdc.whole_database_synchronization')
- }
- }
- },
- {
- title: t('cdc.job_description'),
- key: 'description',
- resizable: true
- },
- {
- title: t('cdc.create_user'),
- key: 'createUser',
- resizable: true
- },
- {
- title: t('cdc.create_time'),
- key: 'createTime',
- resizable: true
+import { useCDCStore } from '@/store/cdc'
+import type { Router } from 'vue-router'
+import TableAction from '@/components/table-action'
+import { deleteCdcJobDefinition, getCdcJobDefinition, listAllCdcJob } from
'@/api/models/cdc'
+export const useTable = (ctx: any) => {
+ const router: Router = useRouter()
+ const { t } = useLocaleHooks()
+ const tableVariables = reactive({
+ columns: [
+ {
+ title: t('cdc.job_name'),
+ key: 'name',
+ resizable: true
+ },
+ {
+ title: t('cdc.synchronization_type'),
+ key: 'cdcType',
+ resizable: true,
+ render: (row: any) => {
+ const message = row.cdcType ? 'cdc.whole_database_synchronization' :
'cdc.single_table_synchronization'
+ return t(message)
+ }
+ },
+ {
+ title: t('cdc.job_description'),
+ key: 'description',
+ resizable: true
+ },
+ {
+ title: t('cdc.create_user'),
+ key: 'createUser',
+ resizable: true
+ },
+ {
+ title: t('cdc.create_time'),
+ key: 'createTime',
+ resizable: true
+ },
+ {
+ title: t('cdc.update_time'),
+ key: 'updateTime',
+ resizable: true
+ },
+ {
+ title: t('cdc.operation'),
+ key: 'actions',
+ render: (row: any) =>
+ h(TableAction, {
+ row,
+ onHandleEdit: (row) => {
+ getCdcJobDefinition(row.id).then((res) => {
+ const CDCStore = useCDCStore()
+ CDCStore.setModel({
+ cells: JSON.parse(res.data.config).cells,
+ name: res.data.name,
+ editMode: 'edit',
+ id: res.data.id
+ })
+ router.push({ path: '/cdc_ingestion/dag' })
+ })
},
- {
- title: t('cdc.update_time'),
- key: 'updateTime',
- resizable: true
+ onHandleRun: (row: any) => {
+ const CDCStore = useCDCStore()
+ CDCStore.setModel({
+ id: row.id
+ })
+ ctx.emit('cdcJobSubmit')
},
- {
- title: t('cdc.operation'),
- key: 'actions',
- render: (row: any) =>
- h(TableAction, {
- row,
- onHandleEdit: (row) => {
- getCdcJobDefinition(row.id).then(res => {
- const CDCStore = useCDCStore()
- CDCStore.setModel({
- cells: JSON.parse(res.data.config).cells,
- name: res.data.name,
- editMode: 'edit',
- id:res.data.id
- })
- router.push({ path: '/cdc_ingestion/dag' })
- })
- },
- onHandleDelete:(row)=>{
- deleteCdcJobDefinition(row.id).then(()=>{
- getTableData()
- })
- }
- })
-
- }
- ],
- data: [],
- pagination: {
- showQuickJumper: true,
- showSizePicker: true,
- pageSize: 10,
- page: 1,
- count: 100,
- onUpdatePage: (page: number) => {
- tableVariables.pagination.page = page
- getTableData()
- },
- onUpdatePageSize: (pageSize: number) => {
- tableVariables.pagination.pageSize = pageSize
- tableVariables.pagination.page = 1
+ onHandleDelete: (row) => {
+ deleteCdcJobDefinition(row.id).then(() => {
getTableData()
+ })
}
- }
- })
- const getTableData = () => {
- listAllCdcJob(false, tableVariables.pagination.page,
tableVariables.pagination.pageSize).then(((res: any) => {
- tableVariables.data = res.data
- tableVariables.pagination.count = res.total
- }))
- }
- return {
- tableVariables,
- getTableData
+ })
+ }
+ ],
+ data: [],
+ pagination: {
+ showQuickJumper: true,
+ showSizePicker: true,
+ pageSize: 10,
+ page: 1,
+ count: 100,
+ onUpdatePage: (page: number) => {
+ tableVariables.pagination.page = page
+ getTableData()
+ },
+ onUpdatePageSize: (pageSize: number) => {
+ tableVariables.pagination.pageSize = pageSize
+ tableVariables.pagination.page = 1
+ getTableData()
+ }
}
+ })
+ const getTableData = () => {
+ listAllCdcJob(false, tableVariables.pagination.page,
tableVariables.pagination.pageSize).then(
+ (res: any) => {
+ tableVariables.data = res.data
+ tableVariables.pagination.count = res.total
+ }
+ )
+ }
+ return {
+ tableVariables,
+ getTableData
+ }
}
diff --git a/paimon-web-ui/src/views/cdc/index.tsx
b/paimon-web-ui/src/views/cdc/index.tsx
index 5742a08..65086cc 100644
--- a/paimon-web-ui/src/views/cdc/index.tsx
+++ b/paimon-web-ui/src/views/cdc/index.tsx
@@ -21,20 +21,26 @@ import styles from './index.module.scss';
import { Leaf } from '@vicons/ionicons5';
import { useCDCStore } from '@/store/cdc';
import type { Router } from 'vue-router';
+import { submitCdcJob, type CdcJobSubmit } from '@/api/models/cdc';
export default defineComponent({
name: 'CDCPage',
setup() {
const { t } = useLocaleHooks()
const showModalRef = ref(false)
-
+ const showSubmitCdcJobModalRef = ref(false)
const handleOpenModal = () => {
showModalRef.value = true
}
+ const handleOpenSubmitCdcJobModal = () => {
+ showSubmitCdcJobModalRef.value = true
+ }
+
const CDCStore = useCDCStore()
const router: Router = useRouter()
const CDCModalRef = ref()
+ const submitCdcJobModalRef = ref()
const handleConfirm = async(model: any) => {
CDCStore.setModel(model)
await CDCModalRef.value.formRef.validate()
@@ -42,12 +48,22 @@ export default defineComponent({
router.push({ path: '/cdc_ingestion/dag' })
}
+ const handleCdcSubmitConfirm = (form:CdcJobSubmit)=>{
+ const CDCStore = useCDCStore()
+ submitCdcJob(CDCStore.getModel.id,form)
+ showSubmitCdcJobModalRef.value = false
+ }
+
return {
t,
showModalRef,
+ showSubmitCdcJobModalRef,
handleOpenModal,
handleConfirm,
- CDCModalRef
+ CDCModalRef,
+ submitCdcJobModalRef,
+ handleOpenSubmitCdcJobModal,
+ handleCdcSubmitConfirm
}
},
render() {
@@ -69,7 +85,7 @@ export default defineComponent({
</div>
</div>
</n-card>
- <List></List>
+ <List onCdcJobSubmit={() => this.showSubmitCdcJobModalRef =
true}></List>
{
this.showModalRef &&
<Modal
@@ -81,6 +97,17 @@ export default defineComponent({
onConfirm={this.handleConfirm}
/>
}
+ {
+ this.showSubmitCdcJobModalRef &&
+ <Modal
+ ref='submitCdcJobModalRef'
+ showModal={this.showSubmitCdcJobModalRef}
+ title={this.t('cdc.submit_cdc_job')}
+ formType="CDCSUBMIT"
+ onCancel={() => this.showSubmitCdcJobModalRef = false}
+ onConfirm={this.handleCdcSubmitConfirm}
+ />
+ }
</n-space>
</n-card>
</div>