Browse Source

Merge pull request #9161 from nocodb/nc-fix/integration-corrections

Nc fix/integration corrections
pull/9170/head
Ramesh Mane 4 months ago committed by GitHub
parent
commit
79609d5ec5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 39
      packages/nc-gui/components/dashboard/settings/data-sources/CreateBase.vue
  2. 60
      packages/nc-gui/components/dashboard/settings/data-sources/EditBase.vue
  3. 4
      packages/nc-gui/components/dashboard/settings/data-sources/SourceRestrictions.vue
  4. 46
      packages/nc-gui/components/project/AllTables.vue
  5. 2
      packages/nc-gui/components/project/SyncDataModal.vue
  6. 2
      packages/nc-gui/components/workspace/integrations/List.vue
  7. 5
      packages/nc-gui/components/workspace/integrations/newAvailableList.vue
  8. 4
      packages/nc-gui/lang/en.json

39
packages/nc-gui/components/dashboard/settings/data-sources/CreateBase.vue

@ -139,16 +139,10 @@ const validators = computed(() => {
} }
}) })
const { validate, validateInfos } = useForm(formState.value, validators) const { validate, validateInfos, clearValidate } = useForm(formState.value, validators)
const populateName = (v: string) => {
if (selectedIntegration.value) return
formState.value.dataSource.connection.database = `${v.trim()}_noco`
}
const onClientChange = () => { const onClientChange = () => {
formState.value.dataSource = { ...getDefaultConnectionConfig(formState.value.dataSource.client) } formState.value.dataSource = { ...getDefaultConnectionConfig(formState.value.dataSource.client) }
populateName(formState.value.title)
} }
const inflectionTypes = ['camelize', 'none'] const inflectionTypes = ['camelize', 'none']
@ -322,7 +316,6 @@ watch(
onMounted(async () => { onMounted(async () => {
await loadIntegrations(true, base.value?.id) await loadIntegrations(true, base.value?.id)
formState.value.title = await generateUniqueName() formState.value.title = await generateUniqueName()
populateName(formState.value.title)
nextTick(() => { nextTick(() => {
// todo: replace setTimeout and follow better approach // todo: replace setTimeout and follow better approach
@ -435,10 +428,7 @@ const filterIntegrationCategory = (c: IntegrationCategoryItemType) => [Integrati
<div class="h-6 self-start flex items-center"> <div class="h-6 self-start flex items-center">
<GeneralIcon icon="server1" class="!text-green-700 !h-4 !w-4" /> <GeneralIcon icon="server1" class="!text-green-700 !h-4 !w-4" />
</div> </div>
<div class="flex-1"> <div class="flex-1 text-base font-weight-700">Add Data Source</div>
<div class="flex-1 text-base font-weight-700">New Source</div>
<div class="text-xs text-gray-600">Connect with a new external data source, directly in real time.</div>
</div>
<div class="flex items-center gap-3"> <div class="flex items-center gap-3">
<div class="w-[15px] h-[15px] cursor-pointer" @dblclick="onEasterEgg"></div> <div class="w-[15px] h-[15px] cursor-pointer" @dblclick="onEasterEgg"></div>
@ -471,7 +461,7 @@ const filterIntegrationCategory = (c: IntegrationCategoryItemType) => [Integrati
<NcButton <NcButton
size="small" size="small"
type="primary" type="primary"
:disabled="!testSuccess" :disabled="!testSuccess || !selectedIntegration"
:loading="creatingSource" :loading="creatingSource"
class="nc-extdb-btn-submit" class="nc-extdb-btn-submit"
@click="createSource" @click="createSource"
@ -483,7 +473,7 @@ const filterIntegrationCategory = (c: IntegrationCategoryItemType) => [Integrati
</NcButton> </NcButton>
</div> </div>
</div> </div>
<div class="h-[calc(100%_-_66px)] flex"> <div class="h-[calc(100%_-_58px)] flex">
<div class="nc-add-source-left-panel nc-scrollbar-thin"> <div class="nc-add-source-left-panel nc-scrollbar-thin">
<div class="create-source bg-white relative flex flex-col gap-2 w-full max-w-[768px]"> <div class="create-source bg-white relative flex flex-col gap-2 w-full max-w-[768px]">
<a-form <a-form
@ -496,12 +486,11 @@ const filterIntegrationCategory = (c: IntegrationCategoryItemType) => [Integrati
class="flex flex-col gap-5.5" class="flex flex-col gap-5.5"
> >
<div class="nc-form-section"> <div class="nc-form-section">
<div class="nc-form-section-title">Source details</div>
<div class="nc-form-section-body"> <div class="nc-form-section-body">
<a-row :gutter="24"> <a-row :gutter="24">
<a-col :span="12"> <a-col :span="12">
<a-form-item label="Source name" v-bind="validateInfos.title"> <a-form-item label="Data Source Name" v-bind="validateInfos.title">
<a-input v-model:value="formState.title" @input="populateName(formState.title)" /> <a-input v-model:value="formState.title" />
</a-form-item> </a-form-item>
</a-col> </a-col>
</a-row> </a-row>
@ -560,10 +549,8 @@ const filterIntegrationCategory = (c: IntegrationCategoryItemType) => [Integrati
</div> </div>
</div> </div>
<template v-if="selectedIntegration">
<div class="nc-form-section"> <div class="nc-form-section">
<div class="flex items-center justify-between">
<div class="nc-form-section-title">Connection details</div>
</div>
<div class="nc-form-section-body"> <div class="nc-form-section-body">
<!-- SQLite File --> <!-- SQLite File -->
<template v-if="formState.dataSource.client === ClientType.SQLITE"> </template> <template v-if="formState.dataSource.client === ClientType.SQLITE"> </template>
@ -658,11 +645,7 @@ const filterIntegrationCategory = (c: IntegrationCategoryItemType) => [Integrati
<template <template
v-if="![ClientType.SQLITE, ClientType.SNOWFLAKE, ClientType.DATABRICKS].includes(formState.dataSource.client)" v-if="![ClientType.SQLITE, ClientType.SNOWFLAKE, ClientType.DATABRICKS].includes(formState.dataSource.client)"
> >
<a-collapse <a-collapse v-model:active-key="advancedOptionsExpansionPanel" ghost class="nc-source-advanced-options !mt-4">
v-model:active-key="advancedOptionsExpansionPanel"
ghost
class="nc-source-advanced-options !mt-4"
>
<template #expandIcon="{ isActive }"> <template #expandIcon="{ isActive }">
<NcButton <NcButton
type="text" type="text"
@ -715,7 +698,7 @@ const filterIntegrationCategory = (c: IntegrationCategoryItemType) => [Integrati
</a-collapse-panel> </a-collapse-panel>
</a-collapse> </a-collapse>
</template> </template>
</template>
<div> <div>
<!-- For spacing --> <!-- For spacing -->
</div> </div>
@ -726,7 +709,7 @@ const filterIntegrationCategory = (c: IntegrationCategoryItemType) => [Integrati
</div> </div>
</div> </div>
<div class="nc-add-source-right-panel"> <div class="nc-add-source-right-panel">
<DashboardSettingsDataSourcesSupportedDocs/> <DashboardSettingsDataSourcesSupportedDocs />
<NcDivider /> <NcDivider />
</div> </div>
</div> </div>
@ -739,7 +722,7 @@ const filterIntegrationCategory = (c: IntegrationCategoryItemType) => [Integrati
@apply p-6 flex-1 flex justify-center; @apply p-6 flex-1 flex justify-center;
} }
.nc-add-source-right-panel { .nc-add-source-right-panel {
@apply p-5 w-[320px] border-l-1 border-gray-200 flex flex-col gap-4 bg-gray-50 rounded-br-2xl; @apply p-4 w-[320px] border-l-1 border-gray-200 flex flex-col gap-4 bg-gray-50 rounded-br-2xl;
} }
:deep(.ant-collapse-header) { :deep(.ant-collapse-header) {
@apply !-mt-4 !p-0 flex items-center !cursor-default children:first:flex; @apply !-mt-4 !p-0 flex items-center !cursor-default children:first:flex;

60
packages/nc-gui/components/dashboard/settings/data-sources/EditBase.vue

@ -48,6 +48,8 @@ const easterEgg = ref(false)
const easterEggCount = ref(0) const easterEggCount = ref(0)
const advancedOptionsExpansionPanel = ref<string[]>([])
const onEasterEgg = () => { const onEasterEgg = () => {
easterEggCount.value += 1 easterEggCount.value += 1
if (easterEggCount.value >= 2) { if (easterEggCount.value >= 2) {
@ -335,8 +337,17 @@ const allowDataWrite = computed({
}, },
}) })
const handleUpdateAdvancedOptionsExpansionPanel = (open: boolean) => {
if (open) {
advancedOptionsExpansionPanel.value = ['1']
handleAutoScroll(true, 'nc-source-advanced-options')
} else {
advancedOptionsExpansionPanel.value = []
}
}
let timer: any let timer: any
const handleAutoScroll = (scroll: boolean, className: string) => { function handleAutoScroll(scroll: boolean, className: string) {
if (scroll) { if (scroll) {
if (timer) { if (timer) {
clearTimeout(timer) clearTimeout(timer)
@ -357,8 +368,9 @@ const handleAutoScroll = (scroll: boolean, className: string) => {
<template> <template>
<div class="edit-source bg-white relative h-full flex flex-col w-full"> <div class="edit-source bg-white relative h-full flex flex-col w-full">
<div class="h-full max-h-[calc(100%_-_65px)] nc-scrollbar-thin"> <div class="h-full max-h-[calc(100%_-_65px)] flex">
<div class="h-full max-w-[992px] p-6 mx-auto"> <div class="nc-edit-source-left-panel nc-scrollbar-thin">
<div class="h-full max-w-[768px] mx-auto">
<a-form <a-form
ref="form" ref="form"
:model="formState" :model="formState"
@ -369,11 +381,10 @@ const handleAutoScroll = (scroll: boolean, className: string) => {
class="flex flex-col gap-5.5" class="flex flex-col gap-5.5"
> >
<div class="nc-form-section"> <div class="nc-form-section">
<div class="nc-form-section-title">Source details</div>
<div class="nc-form-section-body"> <div class="nc-form-section-body">
<a-row :gutter="24"> <a-row :gutter="24">
<a-col :span="12"> <a-col :span="12">
<a-form-item label="Source name" v-bind="validateInfos.title"> <a-form-item label="Data Source Name" v-bind="validateInfos.title">
<a-input v-model:value="formState.title" class="nc-extdb-proj-name" /> <a-input v-model:value="formState.title" class="nc-extdb-proj-name" />
</a-form-item> </a-form-item>
</a-col> </a-col>
@ -420,8 +431,6 @@ const handleAutoScroll = (scroll: boolean, className: string) => {
</div> </div>
<div class="nc-form-section"> <div class="nc-form-section">
<div class="nc-form-section-title">Connection details</div>
<div class="nc-form-section-body"> <div class="nc-form-section-body">
<!-- SQLite File --> <!-- SQLite File -->
<template v-if="formState.dataSource.client === ClientType.SQLITE"> </template> <template v-if="formState.dataSource.client === ClientType.SQLITE"> </template>
@ -515,26 +524,26 @@ const handleAutoScroll = (scroll: boolean, className: string) => {
<template <template
v-if="![ClientType.SQLITE, ClientType.SNOWFLAKE, ClientType.DATABRICKS].includes(formState.dataSource.client)" v-if="![ClientType.SQLITE, ClientType.SNOWFLAKE, ClientType.DATABRICKS].includes(formState.dataSource.client)"
> >
<a-collapse <a-collapse v-model:active-key="advancedOptionsExpansionPanel" ghost class="nc-source-advanced-options !mt-4">
ghost
expand-icon-position="right"
class="nc-source-advanced-options !mt-4"
@change="handleAutoScroll(!!$event?.length, 'nc-source-advanced-options')"
>
<template #expandIcon="{ isActive }"> <template #expandIcon="{ isActive }">
<NcButton type="text" size="xsmall"> <NcButton
type="text"
size="small"
class="!-ml-1.5"
@click="handleUpdateAdvancedOptionsExpansionPanel(!advancedOptionsExpansionPanel.length)"
>
<div class="nc-form-section-title">Advanced options</div>
<GeneralIcon <GeneralIcon
icon="chevronDown" icon="chevronDown"
class="flex-none cursor-pointer transform transition-transform duration-500" class="ml-2 flex-none cursor-pointer transform transition-transform duration-500"
:class="{ '!rotate-180': isActive }" :class="{ '!rotate-180': isActive }"
/> />
</NcButton> </NcButton>
</template> </template>
<a-collapse-panel key="1"> <a-collapse-panel key="1" collapsible="disabled">
<template #header> <template #header>
<div class="flex"> <span></span>
<div class="nc-form-section-title">Advanced options</div>
</div>
</template> </template>
<div class="flex flex-col gap-4"> <div class="flex flex-col gap-4">
@ -574,6 +583,11 @@ const handleAutoScroll = (scroll: boolean, className: string) => {
</a-form> </a-form>
</div> </div>
</div> </div>
<div class="nc-edit-source-right-panel">
<DashboardSettingsDataSourcesSupportedDocs />
<NcDivider />
</div>
</div>
<div class="p-4 w-full flex items-center justify-between gap-3 border-t-1 border-gray-200"> <div class="p-4 w-full flex items-center justify-between gap-3 border-t-1 border-gray-200">
<div class="flex-1 flex items-center gap-3"> <div class="flex-1 flex items-center gap-3">
<div class="flex-1 flex items-center gap-3 text-[#C86827]"> <div class="flex-1 flex items-center gap-3 text-[#C86827]">
@ -624,14 +638,14 @@ const handleAutoScroll = (scroll: boolean, className: string) => {
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
.nc-add-source-left-panel { .nc-edit-source-left-panel {
@apply p-6 flex-1 flex justify-center; @apply p-6 flex-1 flex justify-center;
} }
.nc-add-source-right-panel { .nc-edit-source-right-panel {
@apply p-5 w-[320px] border-l-1 border-gray-200 flex flex-col gap-4 bg-gray-50 rounded-br-2xl; @apply p-4 w-[320px] border-l-1 border-gray-200 flex flex-col gap-4 bg-gray-50 rounded-br-2xl;
} }
:deep(.ant-collapse-header) { :deep(.ant-collapse-header) {
@apply !-mt-4 !p-0 flex items-center; @apply !-mt-4 !p-0 flex items-center !cursor-default children:first:flex;
} }
:deep(.ant-collapse-icon-position-right > .ant-collapse-item > .ant-collapse-header .ant-collapse-arrow) { :deep(.ant-collapse-icon-position-right > .ant-collapse-item > .ant-collapse-header .ant-collapse-arrow) {
@apply !right-0; @apply !right-0;

4
packages/nc-gui/components/dashboard/settings/data-sources/SourceRestrictions.vue

@ -12,7 +12,7 @@ const metaWrite = useVModel(props, 'allowMetaWrite', emits)
<template> <template>
<a-form-item class="nc-source-restictions-card"> <a-form-item class="nc-source-restictions-card">
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-1">
<div class="flex items-center gap-3"> <div class="flex items-center gap-3">
<NcTooltip :disabled="!metaWrite" placement="topLeft" class="flex"> <NcTooltip :disabled="!metaWrite" placement="topLeft" class="flex">
<template #title> <template #title>
@ -30,7 +30,7 @@ const metaWrite = useVModel(props, 'allowMetaWrite', emits)
</div> </div>
</a-form-item> </a-form-item>
<a-form-item class="nc-source-restictions-card"> <a-form-item class="nc-source-restictions-card">
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-1">
<div class="flex items-center gap-3"> <div class="flex items-center gap-3">
<a-switch <a-switch
v-model:checked="metaWrite" v-model:checked="metaWrite"

46
packages/nc-gui/components/project/AllTables.vue

@ -125,12 +125,11 @@ const onCreateBaseClick = () => {
data-testid="proj-view-btn__add-new-table" data-testid="proj-view-btn__add-new-table"
@click="openTableCreateDialog()" @click="openTableCreateDialog()"
> >
<div class="flex items-center gap-3"> <GeneralIcon icon="addOutlineBox" class="!h-8 !w-8 !text-brand-500" />
<GeneralIcon icon="addOutlineBox" class="!text-brand-500 !h-5 !w-5" /> <div class="flex flex-col gap-1">
<div class="label">{{ $t('general.create') }} {{ $t('general.new') }} {{ $t('objects.table') }}</div> <div class="label">{{ $t('general.create') }} {{ $t('general.new') }} {{ $t('objects.table') }}</div>
<div class="subtext">Start from scratch.</div>
</div> </div>
<div class="subtext">Start from scratch by creating a new table.</div>
</div> </div>
<div <div
@ -141,13 +140,19 @@ const onCreateBaseClick = () => {
data-testid="proj-view-btn__import-data" data-testid="proj-view-btn__import-data"
@click="isImportModalOpen = true" @click="isImportModalOpen = true"
> >
<div class="flex items-center gap-3"> <GeneralIcon icon="download" class="!h-7.5 !w-7.5 !text-orange-700" />
<GeneralIcon icon="download" class="!text-orange-700 !h-5 !w-5" /> <div class="flex flex-col gap-1">
<div class="label">{{ $t('activity.import') }} {{ $t('general.data') }}</div> <div class="label">{{ $t('activity.import') }} {{ $t('general.data') }}</div>
<div class="subtext">From files & external sources</div>
</div> </div>
<div class="subtext">Quickly bring in existing data from various files & external sources.</div>
</div> </div>
<NcTooltip v-if="isUIAllowed('sourceCreate')" placement="bottom" :disabled="!isDataSourceLimitReached" class="flex-none flex"> <NcTooltip
v-if="isUIAllowed('sourceCreate')"
placement="bottom"
:disabled="!isDataSourceLimitReached"
class="flex-none flex"
>
<template #title> <template #title>
{{ $t('tooltip.reachedSourceLimit') }} {{ $t('tooltip.reachedSourceLimit') }}
</template> </template>
@ -161,28 +166,13 @@ const onCreateBaseClick = () => {
}" }"
@click="onCreateBaseClick" @click="onCreateBaseClick"
> >
<div class="flex items-center gap-3"> <GeneralIcon icon="server1" class="!h-7 !w-7 !text-green-700" />
<GeneralIcon icon="server1" class="!text-green-700 !h-5 !w-5" /> <div class="flex flex-col gap-1">
<div class="label">{{ $t('labels.connectDataSource') }}</div> <div class="label">{{ $t('labels.connectDataSource') }}</div>
<div class="subtext">In realtime to external databases.</div>
</div> </div>
<div class="subtext">Connect directly in realtime to external databases.</div>
</div> </div>
</NcTooltip> </NcTooltip>
<div
v-if="isUIAllowed('tableCreate', { source: base?.sources?.[0] })"
v-e="['c:table:create-source']"
role="button"
class="nc-base-view-all-table-btn"
data-testid="proj-view-btn__create-source"
@click="syncDataModalOpen = true"
>
<div class="flex items-center gap-3">
<GeneralIcon icon="refresh" class="!text-blue-700 !h-5 !w-5" />
<div class="label capitalize">{{ $t('labels.syncData') }}</div>
</div>
<div class="subtext">Keep your data updated and in sync across multiple sources.</div>
</div>
</div> </div>
<div <div
v-if="base?.isLoading" v-if="base?.isLoading"
@ -277,13 +267,13 @@ const onCreateBaseClick = () => {
<style lang="scss" scoped> <style lang="scss" scoped>
.nc-base-view-all-table-btn { .nc-base-view-all-table-btn {
@apply flex-none flex flex-col gap-y-3 px-3 py-5 bg-gray-50 rounded-xl border-1 border-gray-100 min-w-[230px] max-w-[245px] cursor-pointer text-gray-800 hover:(bg-gray-100 border-gray-200) transition-all duration-300; @apply flex-none flex flex-col gap-y-3 p-4 bg-gray-50 rounded-xl border-1 border-gray-100 min-w-[230px] max-w-[245px] cursor-pointer text-gray-800 hover:(bg-gray-100 border-gray-200) transition-all duration-300;
&:hover { &:hover {
box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.08); box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.08);
} }
.nc-icon { .nc-icon {
@apply h-6 w-6; @apply h-10 w-10;
} }
.label { .label {

2
packages/nc-gui/components/project/SyncDataModal.vue

@ -22,7 +22,7 @@ const upvotesData = computed(() => {
const handleUpvote = (syncDataType: SyncDataType) => { const handleUpvote = (syncDataType: SyncDataType) => {
if (upvotesData.value.has(syncDataType)) return if (upvotesData.value.has(syncDataType)) return
$e(`a:sync-request:${syncDataType}`) $e(`a:integration-request:${syncDataType}`)
updateSyncDataUpvotes([...syncDataUpvotes.value, syncDataType]) updateSyncDataUpvotes([...syncDataUpvotes.value, syncDataType])
} }

2
packages/nc-gui/components/workspace/integrations/List.vue

@ -225,7 +225,7 @@ onKeyStroke('ArrowDown', onDown)
<div class="flex justify-between gap-12"> <div class="flex justify-between gap-12">
<div class="text-sm font-normal text-gray-600"> <div class="text-sm font-normal text-gray-600">
<div> <div>
Connections simplify managing stored configurations for different integrations. Manage connections for your integrations.
<a target="_blank" rel="noopener noreferrer"> Learn more </a> <a target="_blank" rel="noopener noreferrer"> Learn more </a>
</div> </div>
</div> </div>

5
packages/nc-gui/components/workspace/integrations/newAvailableList.vue

@ -83,10 +83,7 @@ const handleAddIntegration = (type: typeof integrationType) => {
'max-w-[740px]': !isModal, 'max-w-[740px]': !isModal,
}" }"
> >
<div> <div>Connect integrations with NocoDB. <a target="_blank" rel="noopener noreferrer"> Learn more </a></div>
Centralise your operations by aggregating information from various external platforms into NocoDB. Select from the
available integrations below to get started. <a target="_blank" rel="noopener noreferrer"> Learn more </a>
</div>
</div> </div>
<div class="integration-type-wrapper"> <div class="integration-type-wrapper">

4
packages/nc-gui/lang/en.json

@ -1787,8 +1787,8 @@
"passwordChanged": "Password changed successfully. Please login again.", "passwordChanged": "Password changed successfully. Please login again.",
"settingsSaved": "Settings saved successfully", "settingsSaved": "Settings saved successfully",
"roleUpdated": "Role updated successfully", "roleUpdated": "Role updated successfully",
"connectionAdded": "Connection Successfully Created", "connectionAdded": "Integration connected successfully",
"connectionAddedDesc": "All Base owners & creators in this Workspace can now use this connection to easily add a new Data Source to their Base." "connectionAddedDesc": "Base owners and creators can now add a data source without re-entering credentials."
} }
} }
} }

Loading…
Cancel
Save