Browse Source

fix(nc-gui): show modal for request integration

pull/9169/head
Ramesh Mane 4 months ago
parent
commit
1b918d53b7
  1. 10
      packages/nc-gui/components/dashboard/settings/data-sources/CreateBase.vue
  2. 6
      packages/nc-gui/components/workspace/integrations/ConnectionsTab.vue
  3. 137
      packages/nc-gui/components/workspace/integrations/IntegrationsTab.vue

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

@ -416,9 +416,7 @@ function handleAutoScroll(scroll: boolean, className: string) {
} }
} }
const filterIntegrationCategory = (c: IntegrationCategoryItemType) => const filterIntegrationCategory = (c: IntegrationCategoryItemType) => [IntegrationCategoryType.DATABASE].includes(c.value)
[IntegrationCategoryType.DATABASE, IntegrationCategoryType.OTHERS].includes(c.value)
const filterIntegration = (c: IntegrationItemType) => c.categories.includes(IntegrationCategoryType.DATABASE)
</script> </script>
<template> <template>
@ -723,11 +721,7 @@ const filterIntegration = (c: IntegrationItemType) => c.categories.includes(Inte
</div> </div>
</a-form> </a-form>
<WorkspaceIntegrationsTab <WorkspaceIntegrationsTab is-modal :filter-category="filterIntegrationCategory" />
is-modal
:filter-category="filterIntegrationCategory"
:filter-integration="filterIntegration"
/>
<WorkspaceIntegrationsEditOrAdd load-datasource-info :base-id="baseId" /> <WorkspaceIntegrationsEditOrAdd load-datasource-info :base-id="baseId" />
</div> </div>
</div> </div>

6
packages/nc-gui/components/workspace/integrations/ConnectionsTab.vue

@ -229,18 +229,18 @@ onKeyStroke('ArrowDown', onDown)
<template> <template>
<div class="h-full flex flex-col gap-6 nc-workspace-connections"> <div class="h-full flex flex-col gap-6 nc-workspace-connections">
<div class="flex justify-between gap-12"> <div class="flex flex-col justify-between gap-2 mx-1">
<div class="text-sm font-normal text-gray-600"> <div class="text-sm font-normal text-gray-600">
<div> <div>
Manage connections for your 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>
<div class="flex items-center justify-end gap-3 mx-1"> <div class="flex items-center gap-3">
<a-input <a-input
v-model:value="searchQuery" v-model:value="searchQuery"
type="text" type="text"
class="nc-search-integration-input !min-w-[300px] nc-input-sm flex-none" class="nc-search-integration-input !min-w-[300px] !max-w-[400px] nc-input-sm flex-none"
:placeholder="`${$t('general.search')} ${$t('general.connections').toLowerCase()}`" :placeholder="`${$t('general.search')} ${$t('general.connections').toLowerCase()}`"
allow-clear allow-clear
@input="handleSearchConnection" @input="handleSearchConnection"

137
packages/nc-gui/components/workspace/integrations/IntegrationsTab.vue

@ -1,4 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { VNodeRef } from '@vue/runtime-core'
import NcModal from '~/components/nc/Modal.vue' import NcModal from '~/components/nc/Modal.vue'
/* eslint-disable @typescript-eslint/consistent-type-imports */ /* eslint-disable @typescript-eslint/consistent-type-imports */
import { IntegrationCategoryType, type IntegrationItemType, SyncDataType } from '#imports' import { IntegrationCategoryType, type IntegrationItemType, SyncDataType } from '#imports'
@ -26,12 +27,12 @@ const { syncDataUpvotes, updateSyncDataUpvotes } = useGlobal()
const { pageMode, IntegrationsPageMode, requestIntegration, addIntegration, saveIntegraitonRequest } = useIntegrationStore() const { pageMode, IntegrationsPageMode, requestIntegration, addIntegration, saveIntegraitonRequest } = useIntegrationStore()
const focusTextArea: VNodeRef = (el) => el && el?.focus?.()
const activeCategory = ref<IntegrationCategoryItemType | null>(null) const activeCategory = ref<IntegrationCategoryItemType | null>(null)
const searchQuery = ref<string>('') const searchQuery = ref<string>('')
const requestNewIntegrationRef = ref<HTMLDivElement>()
const integrationListRef = ref<HTMLDivElement>() const integrationListRef = ref<HTMLDivElement>()
const { width: integrationListContainerWidth } = useElementSize(integrationListRef) const { width: integrationListContainerWidth } = useElementSize(integrationListRef)
@ -73,6 +74,7 @@ const integrationsMapByCategory = computed(() => {
acc[curr.value] = { acc[curr.value] = {
title: curr.title, title: curr.title,
list: getIntegrationsByCategory(curr.value, searchQuery.value), list: getIntegrationsByCategory(curr.value, searchQuery.value),
isAvailable: curr.isAvailable,
} }
return acc return acc
@ -82,6 +84,7 @@ const integrationsMapByCategory = computed(() => {
{ {
title: string title: string
list: IntegrationItemType[] list: IntegrationItemType[]
isAvailable?: boolean
} }
>, >,
) )
@ -121,23 +124,6 @@ const handleAddIntegration = (category: IntegrationCategoryType, integration: In
addIntegration(integration.value) addIntegration(integration.value)
} }
const handleSetRequestIntegrationRef = (node) => {
requestNewIntegrationRef.value = node as HTMLDivElement
return node
}
const handleOpenRequestIntegration = () => {
requestIntegration.value.isOpen = true
nextTick(() => {
requestNewIntegrationRef.value?.scrollIntoView?.({ behavior: 'smooth' })
requestNewIntegrationRef.value?.querySelector('textarea')?.focus?.()
requestNewIntegrationRef.value?.querySelector('textarea')?.select?.()
})
}
</script> </script>
<template> <template>
@ -153,54 +139,6 @@ const handleOpenRequestIntegration = () => {
@keydown.esc="isAddNewIntegrationModalOpen = false" @keydown.esc="isAddNewIntegrationModalOpen = false"
> >
<a-layout> <a-layout>
<!-- <a-layout-sider class="nc-integration-layout-sidebar"> -->
<!-- <div class="h-full flex flex-col gap-3"> -->
<!-- <div class="px-5 pt-3 text-sm text-gray-500 font-bold"> -->
<!-- {{ $t('title.categories') }} -->
<!-- </div> -->
<!-- <div class="px-3 pb-3 flex-1 flex flex-col gap-1 overflow-y-auto nc-scrollbar-thin"> -->
<!-- <div -->
<!-- class="nc-integration-category-item" -->
<!-- :class="{ -->
<!-- active: activeCategory === null, -->
<!-- }" -->
<!-- data-testid="all-integrations" -->
<!-- @click="activeCategory = null" -->
<!-- > -->
<!-- <div class="nc-integration-category-item-icon-wrapper bg-gray-200"> -->
<!-- <GeneralIcon icon="globe" class="stroke-transparent !text-gray-700" /> -->
<!-- </div> -->
<!-- <div class="nc-integration-category-item-content-wrapper"> -->
<!-- <div class="nc-integration-category-item-title">All Integrations</div> -->
<!-- &lt;!&ndash; <div class="nc-integration-category-item-subtitle">Content needed</div>&ndash;&gt; -->
<!-- </div> -->
<!-- </div> -->
<!-- <div -->
<!-- v-for="category of integrationCategories" -->
<!-- :key="category.value" -->
<!-- class="nc-integration-category-item" -->
<!-- :class="{ -->
<!-- active: activeCategory === category, -->
<!-- }" -->
<!-- :data-testid="category.value" -->
<!-- @click="activeCategory = category" -->
<!-- > -->
<!-- <div -->
<!-- class="nc-integration-category-item-icon-wrapper" -->
<!-- :style="{ -->
<!-- backgroundColor: category.iconBgColor, -->
<!-- }" -->
<!-- > -->
<!-- <component :is="category.icon" class="nc-integration-category-item-icon" :style="category.iconStyle" /> -->
<!-- </div> -->
<!-- <div class="nc-integration-category-item-content-wrapper"> -->
<!-- <div class="nc-integration-category-item-title">{{ $t(category.title) }}</div> -->
<!-- &lt;!&ndash; <div class="nc-integration-category-item-subtitle">{{ $t(category.subtitle) }}</div>&ndash;&gt; -->
<!-- </div> -->
<!-- </div> -->
<!-- </div> -->
<!-- </div> -->
<!-- </a-layout-sider> -->
<a-layout-content class="nc-integration-layout-content"> <a-layout-content class="nc-integration-layout-content">
<div v-if="isModal" class="p-4 w-full flex items-center justify-between gap-3 border-b-1 border-gray-200"> <div v-if="isModal" class="p-4 w-full flex items-center justify-between gap-3 border-b-1 border-gray-200">
<NcButton type="text" size="small" @click="isAddNewIntegrationModalOpen = false"> <NcButton type="text" size="small" @click="isAddNewIntegrationModalOpen = false">
@ -223,19 +161,20 @@ const handleOpenRequestIntegration = () => {
> >
<div class="px-6 pt-6"> <div class="px-6 pt-6">
<div <div
class="flex items-center justify-between flex-wrap gap-3 m-auto" class="flex items-end justify-end flex-wrap gap-3 m-auto"
:style="{ :style="{
maxWidth: listWrapperMaxWidth, maxWidth: listWrapperMaxWidth,
}" }"
> >
<div class="text-sm font-normal text-gray-600"> <div class="flex-1">
<div class="text-sm font-normal text-gray-600 mb-2">
<div>Connect integrations with NocoDB. <a target="_blank" rel="noopener noreferrer"> Learn more </a></div> <div>Connect integrations with NocoDB. <a target="_blank" rel="noopener noreferrer"> Learn more </a></div>
</div> </div>
<a-input <a-input
v-model:value="searchQuery" v-model:value="searchQuery"
type="text" type="text"
class="nc-input-border-on-value nc-search-integration-input !min-w-[300px] !max-w-[400px] nc-input-sm flex-none" class="nc-input-border-on-value nc-search-integration-input !min-w-[300px] !max-w-[400px] nc-input-sm flex-none"
placeholder="Search integration..." placeholder="Search integration"
allow-clear allow-clear
> >
<template #prefix> <template #prefix>
@ -243,6 +182,10 @@ const handleOpenRequestIntegration = () => {
</template> </template>
</a-input> </a-input>
</div> </div>
<NcButton type="ghost" size="small" class="!text-primary" @click="requestIntegration.isOpen = true">
Request integration
</NcButton>
</div>
</div> </div>
<div <div
@ -262,7 +205,15 @@ const handleOpenRequestIntegration = () => {
:key="key" :key="key"
class="integration-type-wrapper" class="integration-type-wrapper"
> >
<div class="category-type-title">{{ $t(category.title) }}</div> <div class="category-type-title flex gap-2">
{{ $t(category.title) }}
<NcBadge
v-if="!category.isAvailable"
:border="false"
class="text-brand-500 !h-5 bg-brand-50 text-xs font-normal px-2"
>{{ $t('msg.toast.futureRelease') }}</NcBadge
>
</div>
<div v-if="category.list.length" class="integration-type-list"> <div v-if="category.list.length" class="integration-type-list">
<NcTooltip <NcTooltip
v-for="integration of category.list" v-for="integration of category.list"
@ -302,38 +253,27 @@ const handleOpenRequestIntegration = () => {
</NcTooltip> </NcTooltip>
</div> </div>
</div> </div>
<div </template>
v-if="key === IntegrationCategoryType.OTHERS"
:key="`${key}-request-integration`"
:ref="handleSetRequestIntegrationRef"
class="integration-type-wrapper !mt-4"
>
<div>
<div
class="source-card-request-integration"
:class="{
active: requestIntegration.isOpen,
}"
>
<div
v-if="!requestIntegration.isOpen"
class="source-card-item border-none"
@click="handleOpenRequestIntegration"
>
<div class="flex items-center justify-center rounded-lg w-[44px] h-[44px]">
<GeneralIcon icon="plusSquare" class="flex-none w-8 h-8 !text-brand-500" />
</div> </div>
<div class="name">Request New Integration</div>
</div> </div>
</div>
</div>
<NcModal
v-model:visible="requestIntegration.isOpen"
centered
size="medium"
@keydown.esc="requestIntegration.isOpen = false"
>
<div v-show="requestIntegration.isOpen" class="flex flex-col gap-4"> <div v-show="requestIntegration.isOpen" class="flex flex-col gap-4">
<div class="flex items-center justify-between gap-4"> <div class="flex items-center justify-between gap-4">
<div class="text-base font-bold text-gray-800">Request Integration</div> <div class="text-base font-bold text-gray-800">Request Integration</div>
<NcButton size="xsmall" type="text" @click="requestIntegration.isOpen = false"> <NcButton size="small" type="text" @click="requestIntegration.isOpen = false">
<GeneralIcon icon="close" class="text-gray-600" /> <GeneralIcon icon="close" class="text-gray-600" />
</NcButton> </NcButton>
</div> </div>
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
<a-textarea <a-textarea
:ref="focusTextArea"
v-model:value="requestIntegration.msg" v-model:value="requestIntegration.msg"
class="!rounded-md !text-sm !min-h-[120px] max-h-[500px] nc-scrollbar-thin" class="!rounded-md !text-sm !min-h-[120px] max-h-[500px] nc-scrollbar-thin"
size="large" size="large"
@ -355,14 +295,7 @@ const handleOpenRequestIntegration = () => {
</NcButton> </NcButton>
</div> </div>
</div> </div>
</div> </NcModal>
</div>
</div>
</template>
</div>
</div>
</div>
</div>
</a-layout-content> </a-layout-content>
</a-layout> </a-layout>
</component> </component>
@ -493,7 +426,7 @@ const handleOpenRequestIntegration = () => {
} }
.name { .name {
@apply text-gray-500; @apply text-gray-800;
} }
} }

Loading…
Cancel
Save