多维表格
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

368 lines
9.7 KiB

import type { IntegrationType, PaginatedType } from 'nocodb-sdk'
import { IntegrationsType } from 'nocodb-sdk'
import { ClientType } from '../lib/enums'
import GeneralBaseLogo from '~/components/general/BaseLogo.vue'
import type { IntegrationStoreEvents as IntegrationStoreEventsTypes } from '#imports'
enum IntegrationsPageMode {
LIST,
ADD,
EDIT,
}
const integrationType: Record<'PostgreSQL' | 'MySQL' | 'SQLITE', ClientType> = {
PostgreSQL: ClientType.PG,
MySQL: ClientType.MYSQL,
SQLITE: ClientType.SQLITE,
}
type IntegrationsSubType = (typeof integrationType)[keyof typeof integrationType]
function defaultValues(type: IntegrationsSubType) {
const genericValues = {
payload: {},
}
switch (type) {
case integrationType.PostgreSQL:
return {
...genericValues,
type: integrationType.PostgreSQL,
title: 'PostgreSQL',
logo: h(GeneralBaseLogo, {
'source-type': 'pg',
'class': 'logo',
}),
}
case integrationType.MySQL:
return {
...genericValues,
type: integrationType.MySQL,
title: 'MySQL',
logo: h(GeneralBaseLogo, {
'source-type': 'mysql2',
'class': 'logo',
}),
}
case integrationType.SQLITE:
return {
...genericValues,
type: integrationType.SQLITE,
title: 'SQLite',
logo: h(GeneralBaseLogo, {
'source-type': 'sqlite3',
'class': 'logo',
}),
}
}
}
const [useProvideIntegrationViewStore, _useIntegrationStore] = useInjectionState(() => {
const router = useRouter()
const route = router.currentRoute
const { api } = useApi()
const pageMode = ref<IntegrationsPageMode | null>(null)
const activeIntegration = ref<IntegrationType | null>(null)
const workspaceStore = useWorkspace()
const { activeWorkspaceId } = storeToRefs(workspaceStore)
const integrations = ref<IntegrationType[]>([])
const searchQuery = ref('')
const integrationPaginationData = ref<PaginatedType>({ page: 1, pageSize: 25, totalRows: 0 })
const deleteConfirmText = ref<string | null>()
const isLoadingIntegrations = ref(false)
const eventBus = useEventBus<IntegrationStoreEventsTypes>(Symbol('integrationStore'))
const { $e } = useNuxtApp()
const { t } = useI18n()
const isFromIntegrationPage = ref(false)
const successConfirmModal = ref({
isOpen: false,
title: t('msg.success.connectionAdded'),
connectionTitle: '',
description: t('msg.success.connectionAddedDesc'),
})
const requestIntegration = ref({
isOpen: false,
msg: '',
isLoading: false,
})
const activeViewTab = computed({
get() {
return (route.value.query?.tab as string) ?? 'integrations'
},
set(tab: string) {
if (requestIntegration.value.isOpen) {
requestIntegration.value.isOpen = false
}
router.push({ query: { ...route.value.query, tab } })
},
})
const loadIntegrations = async (
databaseOnly = false,
baseId = undefined,
page: number = integrationPaginationData.value.page!,
limit: number = integrationPaginationData.value.pageSize!,
) => {
try {
if (!activeWorkspaceId.value) return
isLoadingIntegrations.value = true
if (!databaseOnly && limit * (page - 1) > integrationPaginationData.value.totalRows!) {
integrationPaginationData.value.page = 1
page = 1
}
const { list, pageInfo } = await api.integration.list(
databaseOnly
? {
type: IntegrationsType.Database,
includeDatabaseInfo: true,
baseId,
}
: {
offset: limit * (page - 1),
limit,
...(searchQuery.value.trim() ? { query: searchQuery.value } : {}),
},
)
integrations.value = list
if (!databaseOnly) {
integrationPaginationData.value.totalRows = pageInfo.totalRows ?? 0
}
} catch (e) {
await message.error(await extractSdkResponseErrorMsg(e))
integrations.value = []
integrationPaginationData.value.totalRows = 0
integrationPaginationData.value.page = 1
} finally {
isLoadingIntegrations.value = false
}
}
const addIntegration = (type: IntegrationsSubType) => {
activeIntegration.value = defaultValues(type)
pageMode.value = IntegrationsPageMode.ADD
$e('c:integration:add')
}
const deleteIntegration = async (integration: IntegrationType, force = false) => {
if (!integration?.id) return
try {
await api.integration.delete(integration.id, {
query: force ? { force: 'true' } : {},
})
$e('a:integration:delete')
await loadIntegrations()
// await message.success(`Connection ${integration.title} deleted successfully`)
return true
} catch (e) {
const error = await extractSdkResponseErrorMsgv2(e)
if (error.error === NcErrorType.INTEGRATION_NOT_FOUND) {
await message.error(error.message?.replace(integration.id, integration.title!))
window.location.reload()
return
}
await message.error(await extractSdkResponseErrorMsg(e))
}
deleteConfirmText.value = null
}
const updateIntegration = async (integration: IntegrationType) => {
if (!integration.id) return
try {
await api.integration.update(integration.id, integration)
$e('a:integration:update')
await loadIntegrations()
pageMode.value = null
activeIntegration.value = null
await message.success(`Connection "${integration.title}" updated successfully`)
} catch (e) {
await message.error(await extractSdkResponseErrorMsg(e))
}
}
const saveIntegration = async (
integration: IntegrationType,
mode: 'create' | 'duplicate' = 'create',
loadDatasourceInfo = false,
baseId: string | undefined = undefined,
) => {
try {
const response = await api.integration.create(integration)
if (mode === 'create') {
$e('a:integration:create')
} else {
$e('a:integration:duplicate')
}
if (response && response?.id) {
if (!loadDatasourceInfo) {
integrations.value.push(response)
}
}
await loadIntegrations(loadDatasourceInfo, baseId)
if (mode === 'create') {
eventBus.emit(IntegrationStoreEvents.INTEGRATION_ADD, response)
}
pageMode.value = null
activeIntegration.value = null
if (response?.title && mode === 'create') {
if (isFromIntegrationPage.value) {
activeViewTab.value = 'connections'
successConfirmModal.value.connectionTitle = response.title ?? ''
successConfirmModal.value.isOpen = true
} else {
await message.success(`Connection "${response.title}" created successfully`)
}
}
} catch (e) {
await message.error(await extractSdkResponseErrorMsg(e))
}
}
const duplicateIntegration = async (integration: IntegrationType) => {
if (!integration?.id) return
try {
isLoadingIntegrations.value = true
saveIntegration(
{
title: integration.title,
config: {},
type: integration.type,
copy_from_id: integration.id,
},
'duplicate',
)
} catch (e) {
await message.error(await extractSdkResponseErrorMsg(e))
} finally {
isLoadingIntegrations.value = false
}
}
const getIntegration = async (
integration: IntegrationType,
options?: {
includeConfig?: boolean
includeSources?: boolean
},
) => {
if (!integration?.id) return
try {
const integrationWithConfig = await api.integration.read(integration.id, {
...(options || {}),
})
return integrationWithConfig
} catch (e) {
const error = await extractSdkResponseErrorMsgv2(e)
if (error.error === NcErrorType.INTEGRATION_NOT_FOUND) {
await message.error(error.message?.replace(integration.id!, integration.title!))
window.location.reload()
return
}
await message.error(await extractSdkResponseErrorMsg(e))
}
}
const editIntegration = async (integration: IntegrationType) => {
if (!integration?.id) return
try {
const integrationWithConfig = await getIntegration(integration, { includeConfig: true })
activeIntegration.value = integrationWithConfig
pageMode.value = IntegrationsPageMode.EDIT
$e('c:integration:edit')
} catch {}
}
const saveIntegraitonRequest = async (msg: string) => {
if (!msg?.trim()) return
requestIntegration.value.isLoading = true
try {
$e('a:integration:new-request', {
value: requestIntegration.value.msg,
})
requestIntegration.value.isLoading = false
requestIntegration.value.isOpen = false
requestIntegration.value.msg = ''
await message.success('Your request has been successfully submitted')
} catch (e) {
requestIntegration.value.isLoading = false
await message.error(await extractSdkResponseErrorMsg(e))
}
}
return {
IntegrationsPageMode,
integrationType,
pageMode,
activeIntegration,
integrations,
isLoadingIntegrations,
deleteConfirmText,
eventBus,
requestIntegration,
integrationPaginationData,
activeViewTab,
isFromIntegrationPage,
successConfirmModal,
searchQuery,
addIntegration,
loadIntegrations,
deleteIntegration,
updateIntegration,
saveIntegration,
editIntegration,
duplicateIntegration,
saveIntegraitonRequest,
getIntegration,
}
}, 'integrations-store')
export { useProvideIntegrationViewStore }
export function useIntegrationStore() {
const integrationStore = _useIntegrationStore()
if (integrationStore == null) return useProvideIntegrationViewStore()
return integrationStore
}