diff --git a/packages/nc-gui/components/dashboard/TreeView/ProjectNode.vue b/packages/nc-gui/components/dashboard/TreeView/ProjectNode.vue index 3fc77f2789..5bf8311063 100644 --- a/packages/nc-gui/components/dashboard/TreeView/ProjectNode.vue +++ b/packages/nc-gui/components/dashboard/TreeView/ProjectNode.vue @@ -344,30 +344,44 @@ const duplicateProject = (project: ProjectType) => { selectedProjectToDuplicate.value = project isDuplicateDlgOpen.value = true } -const { $jobs } = useNuxtApp() +const { $poller } = useNuxtApp() const DlgProjectDuplicateOnOk = async (jobData: { id: string; project_id: string }) => { await loadProjects('workspace') - $jobs.subscribe({ id: jobData.id }, undefined, async (status: string) => { - if (status === JobStatus.COMPLETED) { - await loadProjects('workspace') - - const project = projects.value.get(jobData.project_id) - - // open project after duplication - if (project) { - await navigateToProject({ - projectId: project.id, - type: project.type, - }) + $poller.subscribe( + { id: jobData.id }, + async (data: { + id: string + status?: string + data?: { + error?: { + message: string + } + message?: string + result?: any } - } else if (status === JobStatus.FAILED) { - message.error('Failed to duplicate project') - await loadProjects('workspace') - } - }) - + }) => { + if (data.status !== 'close') { + if (data.status === JobStatus.COMPLETED) { + await loadProjects('workspace') + + const project = projects.value.get(jobData.project_id) + + // open project after duplication + if (project) { + await navigateToProject({ + projectId: project.id, + type: project.type, + }) + } + } else if (data.status === JobStatus.FAILED) { + message.error('Failed to duplicate project') + await loadProjects('workspace') + } + } + }, + ) $e('a:project:duplicate') } diff --git a/packages/nc-gui/components/dashboard/TreeView/index.vue b/packages/nc-gui/components/dashboard/TreeView/index.vue index 304b78882f..426f031dc6 100644 --- a/packages/nc-gui/components/dashboard/TreeView/index.vue +++ b/packages/nc-gui/components/dashboard/TreeView/index.vue @@ -31,7 +31,7 @@ const { isUIAllowed } = useRoles() const { addTab } = useTabs() -const { $e, $jobs } = useNuxtApp() +const { $e, $poller } = useNuxtApp() const router = useRouter() @@ -119,19 +119,34 @@ const duplicateTable = async (table: TableType) => { 'modelValue': isOpen, 'table': table, 'onOk': async (jobData: { id: string }) => { - $jobs.subscribe({ id: jobData.id }, undefined, async (status: string, data?: any) => { - if (status === JobStatus.COMPLETED) { - await loadTables() - refreshCommandPalette() - const newTable = tables.value.find((el) => el.id === data?.result?.id) - if (newTable) addTab({ title: newTable.title, id: newTable.id, type: newTable.type as TabType }) - - openTable(newTable!) - } else if (status === JobStatus.FAILED) { - message.error(t('msg.error.failedToDuplicateTable')) - await loadTables() - } - }) + $poller.subscribe( + { id: jobData.id }, + async (data: { + id: string + status?: string + data?: { + error?: { + message: string + } + message?: string + result?: any + } + }) => { + if (data.status !== 'close') { + if (data.status === JobStatus.COMPLETED) { + await loadTables() + refreshCommandPalette() + const newTable = tables.value.find((el) => el.id === data?.data?.result?.id) + if (newTable) addTab({ title: newTable.title, id: newTable.id, type: newTable.type as TabType }) + + openTable(newTable!) + } else if (data.status === JobStatus.FAILED) { + message.error(t('msg.error.failedToDuplicateTable')) + await loadTables() + } + } + }, + ) $e('a:table:duplicate') }, diff --git a/packages/nc-gui/components/dashboard/settings/DataSources.vue b/packages/nc-gui/components/dashboard/settings/DataSources.vue index 190f1e37e1..1628edb602 100644 --- a/packages/nc-gui/components/dashboard/settings/DataSources.vue +++ b/packages/nc-gui/components/dashboard/settings/DataSources.vue @@ -31,8 +31,6 @@ const sources = ref([]) const activeBaseId = ref('') -const metadiffbases = ref([]) - const clientType = ref(ClientType.MYSQL) const isReloading = ref(false) @@ -55,8 +53,6 @@ async function loadBases(changed?: boolean) { if (baseList.list && baseList.list.length) { sources.value = baseList.list } - - await loadMetaDiff() } catch (e) { console.error(e) } finally { @@ -65,21 +61,6 @@ async function loadBases(changed?: boolean) { } } -async function loadMetaDiff() { - try { - metadiffbases.value = [] - - const metadiff = await $api.project.metaDiffGet(project.value.id as string) - for (const model of metadiff) { - if (model.detectedChanges?.length > 0) { - metadiffbases.value.push(model.base_id) - } - } - } catch (e) { - console.error(e) - } -} - const baseAction = (baseId?: string, action?: string) => { if (!baseId) return activeBaseId.value = baseId @@ -362,11 +343,7 @@ const isEditBaseModalOpen = computed({ @click="baseAction(sources[0].id, DataSourcesSubTab.Metadata)" >
- - - - - + {{ $t('tooltip.metaSync') }}
@@ -472,11 +449,7 @@ const isEditBaseModalOpen = computed({ @click="baseAction(base.id, DataSourcesSubTab.Metadata)" >
- - - - - + {{ $t('tooltip.metaSync') }}
@@ -505,7 +478,7 @@ const isEditBaseModalOpen = computed({ - +
- +
{ + if (data.status !== 'close') { + if (data.status === JobStatus.COMPLETED) { + // Table metadata recreated successfully + message.info(t('msg.info.metaDataRecreated')) + await loadTables() + await loadMetaDiff() + emit('baseSynced') + isLoading.value = false + } else if (status === JobStatus.FAILED) { + message.error('Failed to sync base metadata') + isLoading.value = false + } + } + }, + ) } catch (e: any) { message.error(await extractSdkResponseErrorMsg(e)) - } finally { - isLoading.value = false } } diff --git a/packages/nc-gui/components/dashboard/settings/data-sources/CreateBase.vue b/packages/nc-gui/components/dashboard/settings/data-sources/CreateBase.vue index d912c08b66..7b38e81944 100644 --- a/packages/nc-gui/components/dashboard/settings/data-sources/CreateBase.vue +++ b/packages/nc-gui/components/dashboard/settings/data-sources/CreateBase.vue @@ -44,6 +44,8 @@ const useForm = Form.useForm const testSuccess = ref(false) +const testingConnection = ref(false) + const form = ref() const { api } = useApi() @@ -52,6 +54,8 @@ const { $e } = useNuxtApp() const { t } = useI18n() +const creatingBase = ref(false) + const formState = ref({ title: '', dataSource: { ...getDefaultConnectionConfig(ClientType.MYSQL) }, @@ -225,26 +229,27 @@ function getConnectionConfig() { const focusInvalidInput = () => { form.value?.$el.querySelector('.ant-form-item-explain-error')?.parentNode?.parentNode?.querySelector('input')?.focus() } -const isConnSuccess = ref(false) + +const { $poller } = useNuxtApp() const createBase = async () => { try { await validate() - isConnSuccess.value = false } catch (e) { focusInvalidInput() - isConnSuccess.value = false return } try { if (!projectId.value) return + creatingBase.value = true + const connection = getConnectionConfig() const config = { ...formState.value.dataSource, connection } - await api.base.create(projectId.value, { + const jobData = await api.base.create(projectId.value, { alias: formState.value.title, type: formState.value.dataSource.client, config, @@ -252,12 +257,38 @@ const createBase = async () => { inflection_table: formState.value.inflection.inflectionTable, }) - $e('a:base:create:extdb') - - await loadProject(projectId.value, true) - await loadProjectTables(projectId.value, true) - emit('baseCreated') - emit('close') + $poller.subscribe( + { id: jobData.id }, + async (data: { + id: string + status?: string + data?: { + error?: { + message: string + } + message?: string + result?: any + } + }) => { + if (data.status !== 'close') { + if (data.status === JobStatus.COMPLETED) { + $e('a:base:create:extdb') + + if (projectId.value) { + await loadProject(projectId.value, true) + await loadProjectTables(projectId.value, true) + } + + emit('baseCreated') + emit('close') + creatingBase.value = false + } else if (status === JobStatus.FAILED) { + message.error('Failed to create base') + creatingBase.value = false + } + } + }, + ) } catch (e: any) { message.error(await extractSdkResponseErrorMsg(e)) } @@ -274,6 +305,8 @@ const testConnection = async () => { $e('a:base:create:extdb:test-connection', []) try { + testingConnection.value = true + if (formState.value.dataSource.client === ClientType.SQLITE) { testSuccess.value = true } else { @@ -290,7 +323,6 @@ const testConnection = async () => { if (result.code === 0) { testSuccess.value = true - isConnSuccess.value = true } else { testSuccess.value = false @@ -302,6 +334,8 @@ const testConnection = async () => { message.error(await extractSdkResponseErrorMsg(e)) } + + testingConnection.value = false } const handleImportURL = async () => { @@ -367,15 +401,6 @@ watch( diff --git a/packages/nc-gui/components/dashboard/settings/data-sources/EditBase.vue b/packages/nc-gui/components/dashboard/settings/data-sources/EditBase.vue index 5b1f9df97b..691d0bb428 100644 --- a/packages/nc-gui/components/dashboard/settings/data-sources/EditBase.vue +++ b/packages/nc-gui/components/dashboard/settings/data-sources/EditBase.vue @@ -43,6 +43,8 @@ const useForm = Form.useForm const testSuccess = ref(false) +const testingConnection = ref(false) + const form = ref() const { api } = useApi() @@ -51,6 +53,8 @@ const { $e } = useNuxtApp() const { t } = useI18n() +const editingBase = ref(false) + const formState = ref({ title: '', dataSource: { ...getDefaultConnectionConfig(ClientType.MYSQL) }, @@ -234,8 +238,6 @@ const editBase = async () => { } } -const isConnSuccess = ref(false) - const testConnection = async () => { try { await validate() @@ -247,6 +249,8 @@ const testConnection = async () => { $e('a:base:edit:extdb:test-connection', []) try { + testingConnection.value = true + if (formState.value.dataSource.client === ClientType.SQLITE) { testSuccess.value = true } else { @@ -263,7 +267,6 @@ const testConnection = async () => { if (result.code === 0) { testSuccess.value = true - isConnSuccess.value = true } else { testSuccess.value = false @@ -275,6 +278,8 @@ const testConnection = async () => { message.error(await extractSdkResponseErrorMsg(e)) } + + testingConnection.value = false } const handleImportURL = async () => { @@ -427,7 +432,7 @@ onMounted(async () => {
- + {{ $t('activity.useConnectionUrl') }}
@@ -519,7 +524,7 @@ onMounted(async () => { v-model:value="formState.inflection.inflectionTable" dropdown-class-name="nc-dropdown-inflection-table-name" > - {{ type }} + {{ tp }} @@ -528,7 +533,7 @@ onMounted(async () => { v-model:value="formState.inflection.inflectionColumn" dropdown-class-name="nc-dropdown-inflection-column-name" > - {{ type }} + {{ tp }} @@ -545,15 +550,23 @@ onMounted(async () => {
- + + {{ $t('activity.testDbConn') }} {{ $t('general.submit') }} @@ -569,7 +582,7 @@ onMounted(async () => { @@ -589,17 +602,6 @@ onMounted(async () => {
- - - -
-
{{ t('msg.info.dbConnected') }}
-
- {{ $t('general.cancel') }} - {{ $t('activity.okEditBase') }} -
-
-