<script lang="ts" setup>
import { integrationCategoryNeedDefault } from 'nocodb-sdk'
import type { IntegrationType, UserType, WorkspaceUserType } from 'nocodb-sdk'
import dayjs from 'dayjs'

type SortFields = 'title' | 'sub_type' | 'created_at' | 'created_by' | 'source_count'

const {
  integrations,
  isLoadingIntegrations,
  deleteConfirmText,
  integrationPaginationData,
  successConfirmModal,
  searchQuery,
  loadIntegrations,
  deleteIntegration,
  editIntegration,
  duplicateIntegration,
  getIntegration,
  setDefaultIntegration,
} = useIntegrationStore()

const { loadAiIntegrations } = useNocoAi()

const { $api, $e } = useNuxtApp()

const { allCollaborators } = storeToRefs(useWorkspace())

const { bases } = storeToRefs(useBases())

const isDeleteIntegrationModalOpen = ref(false)
const toBeDeletedIntegration = ref<
  | (IntegrationType & {
      sources?: {
        id: string
        alias: string
        project_title: string
        base_id: string
      }[]
    })
  | null
>(null)

const isLoadingGetLinkedSources = ref(false)

const tableWrapper = ref<HTMLDivElement>()

const titleHeaderCellRef = ref<HTMLDivElement>()

const orderBy = ref<Partial<Record<SortFields, 'asc' | 'desc' | undefined>>>({})

const localCollaborators = ref<User[] | UserType[]>([])

const { width } = useElementBounding(titleHeaderCellRef)

const collaboratorsMap = computed<Map<string, (WorkspaceUserType & { id: string }) | User | UserType>>(() => {
  const map = new Map()

  ;(isEeUI ? allCollaborators.value : localCollaborators.value)?.forEach((coll) => {
    if (coll?.id) {
      map.set(coll.id, coll)
    }
  })
  return map
})

const filteredIntegrations = computed(() =>
  (integrations.value || []).sort((a, b) => {
    if (orderBy.value.title) {
      if (a.title && b.title) {
        return orderBy.value.title === 'asc' ? (a.title < b.title ? -1 : 1) : a.title > b.title ? -1 : 1
      }
    } else if (orderBy.value.sub_type) {
      if (a.sub_type && b.sub_type) {
        return orderBy.value.sub_type === 'asc' ? (a.sub_type < b.sub_type ? -1 : 1) : a.sub_type > b.sub_type ? -1 : 1
      }
    } else if (orderBy.value.created_at) {
      if (a?.created_at && b?.created_at) {
        return orderBy.value.created_at === 'asc'
          ? dayjs(a.created_at).local().isBefore(dayjs(b.created_at).local())
            ? -1
            : 1
          : dayjs(a.created_at).local().isAfter(dayjs(b.created_at).local())
          ? -1
          : 1
      }
    } else if (orderBy.value.created_by) {
      if (a.created_by && b.created_by && collaboratorsMap.value.get(a.created_by) && collaboratorsMap.value.get(b.created_by)) {
        return orderBy.value.created_by === 'asc'
          ? collaboratorsMap.value.get(a.created_by)?.email < collaboratorsMap.value.get(b.created_by)?.email
            ? -1
            : 1
          : collaboratorsMap.value.get(a.created_by)?.email > collaboratorsMap.value.get(b.created_by)?.email
          ? -1
          : 1
      }
    } else if (orderBy.value.source_count) {
      if (a.source_count !== undefined && b.source_count !== undefined) {
        return orderBy.value.source_count === 'asc' ? a.source_count - b.source_count : b.source_count - a.source_count
      }
    }
    return 0
  }),
)

async function loadConnections(
  page = integrationPaginationData.value.page,
  limit = integrationPaginationData.value.pageSize,
  updateCurrentPage = true,
) {
  try {
    if (updateCurrentPage) {
      integrationPaginationData.value.page = 1
    }

    await loadIntegrations(undefined, undefined, updateCurrentPage ? 1 : page, limit)
  } catch {}
}

const handleChangePage = async (page: number) => {
  integrationPaginationData.value.page = page
  await loadConnections(undefined, undefined, false)
}

const { onLeft, onRight, onUp, onDown } = usePaginationShortcuts({
  paginationDataRef: integrationPaginationData,
  changePage: handleChangePage,
  isViewDataLoading: isLoadingIntegrations,
})

const openDeleteIntegration = async (source: IntegrationType) => {
  isLoadingGetLinkedSources.value = true

  $e('c:integration:delete')
  deleteConfirmText.value = null
  isDeleteIntegrationModalOpen.value = true
  toBeDeletedIntegration.value = source

  const connectionDetails = await getIntegration(source, {
    includeSources: true,
  })
  toBeDeletedIntegration.value.sources = connectionDetails?.sources || []

  isLoadingGetLinkedSources.value = false
}

const onDeleteConfirm = async () => {
  const isDeleted = await deleteIntegration(toBeDeletedIntegration.value, true)

  if (isDeleted) {
    for (const source of toBeDeletedIntegration.value?.sources || []) {
      if (!source.base_id || !source.id || (source.base_id && !bases.value.get(source.base_id))) {
        continue
      }

      const base = bases.value.get(source.base_id)

      if (!Array.isArray(base?.sources)) {
        continue
      }

      bases.value.set(source.base_id, {
        ...(base || {}),
        sources: [...base.sources.filter((s) => s.id !== source.id)],
      })
    }

    if (toBeDeletedIntegration.value?.type && toBeDeletedIntegration.value.type === IntegrationCategoryType.AI) {
      loadAiIntegrations()
    }
  }
}

const loadOrgUsers = async () => {
  try {
    const response: any = await $api.orgUsers.list()

    if (!response?.list) return

    localCollaborators.value = response.list as UserType[]
  } catch (e: any) {
    message.error(await extractSdkResponseErrorMsg(e))
  }
}

const updateOrderBy = (field: SortFields) => {
  if (!integrations.value?.length) return

  // Only single field sort supported, other old field sort config will reset
  if (orderBy.value?.[field] === 'asc') {
    orderBy.value = {
      [field]: 'desc',
    }
  } else if (orderBy.value?.[field] === 'desc') {
    orderBy.value = {
      [field]: undefined,
    }
  } else {
    orderBy.value = {
      [field]: 'asc',
    }
  }
}

const handleSearchConnection = useDebounceFn(() => {
  loadConnections()
}, 250)

const renderAltOrOptlKey = () => {
  return isMac() ? '⌥' : 'ALT'
}

const isUserDeleted = (userId?: string) => {
  if (!userId) return false

  if (isEeUI) {
    return !!collaboratorsMap.value.get(userId)?.deleted
  } else {
    return !collaboratorsMap.value.get(userId)?.email
  }
}

const getUserNameByCreatedBy = (createdBy: string) => {
  return (
    collaboratorsMap.value.get(createdBy)?.display_name ||
    collaboratorsMap.value.get(createdBy)?.email?.slice(0, collaboratorsMap.value.get(createdBy)?.email?.indexOf('@'))
  )
}

useEventListener(tableWrapper, 'scroll', () => {
  const stickyHeaderCell = tableWrapper.value?.querySelector('th.cell-title')
  const nonStickyHeaderFirstCell = tableWrapper.value?.querySelector('th.cell-type')

  if (!stickyHeaderCell?.getBoundingClientRect().right || !nonStickyHeaderFirstCell?.getBoundingClientRect().left) {
    return
  }

  if (nonStickyHeaderFirstCell?.getBoundingClientRect().left < stickyHeaderCell?.getBoundingClientRect().right) {
    tableWrapper.value?.classList.add('sticky-shadow')
  } else {
    tableWrapper.value?.classList.remove('sticky-shadow')
  }
})

onMounted(async () => {
  if (!isEeUI) {
    await Promise.allSettled([!integrations.value.length && loadIntegrations(), loadOrgUsers()])
  } else if (!integrations.value.length) {
    await loadIntegrations()
  }
})
// Keyboard shortcuts for pagination
onKeyStroke('ArrowLeft', onLeft)
onKeyStroke('ArrowRight', onRight)
onKeyStroke('ArrowUp', onUp)
onKeyStroke('ArrowDown', onDown)
</script>

<template>
  <div class="h-full flex flex-col gap-6 nc-workspace-connections">
    <div class="flex flex-col justify-between gap-2 mx-1">
      <div class="text-sm font-normal text-gray-600">
        <div>
          Manage connections for your integrations.
          <a target="_blank" href="https://docs.nocodb.com/integrations/actions-on-connection" rel="noopener noreferrer">
            Learn more
          </a>
        </div>
      </div>
      <div class="flex items-center gap-3">
        <a-input
          v-model:value="searchQuery"
          type="text"
          class="nc-search-integration-input !min-w-[300px] !max-w-[400px] nc-input-sm flex-none"
          :placeholder="`${$t('general.search')} ${$t('general.connections').toLowerCase()}`"
          allow-clear
          @input="handleSearchConnection"
        >
          <template #prefix>
            <GeneralIcon icon="search" class="mr-2 h-4 w-4 text-gray-500" />
          </template>
        </a-input>
      </div>
    </div>
    <div class="table-container relative flex-1">
      <div
        ref="tableWrapper"
        class="nc-workspace-integration-table relative nc-scrollbar-thin !overflow-auto max-h-[calc(100%_-_40px)]"
        :class="{
          'h-full': filteredIntegrations?.length,
        }"
      >
        <table class="!sticky top-0 z-5 w-full">
          <thead>
            <tr>
              <th
                class="cell-title !hover:bg-gray-100 select-none cursor-pointer"
                :class="{
                  'cursor-not-allowed': !filteredIntegrations?.length,
                  '!text-gray-700': orderBy.title,
                }"
                @click="updateOrderBy('title')"
              >
                <div ref="titleHeaderCellRef" class="flex items-center gap-3">
                  <div>Name</div>
                  <GeneralIcon
                    v-if="orderBy.title"
                    icon="chevronDown"
                    class="flex-none"
                    :class="{
                      'transform rotate-180': orderBy?.title === 'asc',
                    }"
                  />
                  <GeneralIcon v-else icon="chevronUpDown" class="flex-none" />
                </div>
              </th>
              <th
                class="cell-type !hover:bg-gray-100 select-none cursor-pointer"
                :class="{
                  'cursor-not-allowed': !filteredIntegrations?.length,
                  '!text-gray-700': orderBy.sub_type,
                }"
                @click="updateOrderBy('sub_type')"
              >
                <div class="flex items-center gap-3">
                  <div>Type</div>
                  <GeneralIcon
                    v-if="orderBy.sub_type"
                    icon="chevronDown"
                    class="flex-none"
                    :class="{
                      'transform rotate-180': orderBy.sub_type === 'asc',
                    }"
                  />
                  <GeneralIcon v-else icon="chevronUpDown" class="flex-none" />
                </div>
              </th>

              <th
                class="cell-created-date !hover:bg-gray-100 select-none cursor-pointer"
                :class="{
                  'cursor-not-allowed': !filteredIntegrations?.length,
                  '!text-gray-700': orderBy.created_at,
                }"
                @click="updateOrderBy('created_at')"
              >
                <div class="flex items-center gap-3">
                  <div>Date added</div>
                  <GeneralIcon
                    v-if="orderBy.created_at"
                    icon="chevronDown"
                    class="flex-none"
                    :class="{
                      'transform rotate-180': orderBy.created_at === 'asc',
                    }"
                  />
                  <GeneralIcon v-else icon="chevronUpDown" class="flex-none" />
                </div>
              </th>
              <th
                class="cell-added-by !hover:bg-gray-100 select-none cursor-pointer"
                :class="{
                  'cursor-not-allowed': !filteredIntegrations?.length,
                  '!text-gray-700': orderBy.created_by,
                }"
                @click="updateOrderBy('created_by')"
              >
                <div class="flex items-center gap-3">
                  <div>Added by</div>
                  <GeneralIcon
                    v-if="orderBy.created_by"
                    icon="chevronDown"
                    class="flex-none"
                    :class="{
                      'transform rotate-180': orderBy.created_by === 'asc',
                    }"
                  />
                  <GeneralIcon v-else icon="chevronUpDown" class="flex-none" />
                </div>
              </th>
              <th
                class="cell-usage !hover:bg-gray-100 select-none cursor-pointer"
                :class="{
                  'cursor-not-allowed': !filteredIntegrations?.length,
                }"
                @click="updateOrderBy('source_count')"
              >
                <div class="flex items-center gap-3">
                  <div>Usage</div>
                  <GeneralIcon
                    v-if="orderBy?.source_count"
                    icon="chevronDown"
                    class="flex-none"
                    :class="{
                      'transform rotate-180': orderBy?.source_count === 'asc',
                    }"
                  />
                  <GeneralIcon v-else icon="chevronUpDown" class="flex-none" />
                </div>
              </th>
              <th class="cell-actions">
                <div>Actions</div>
              </th>
            </tr>
          </thead>
        </table>
        <template v-if="filteredIntegrations?.length">
          <table class="h-full max-h-[calc(100%_-_55px)] w-full">
            <tbody>
              <tr v-for="integration of filteredIntegrations" :key="integration.id" @click="editIntegration(integration)">
                <td class="cell-title">
                  <div
                    class="gap-3"
                    :style="{
                      maxWidth: `${width}px`,
                    }"
                  >
                    <NcTooltip placement="bottom" class="truncate" show-on-truncate-only>
                      <template #title> {{ integration.title }}</template>
                      {{ integration.title }}
                    </NcTooltip>
                    <span v-if="integration.is_private">
                      <NcBadge :border="false" class="text-primary !h-4.5 bg-brand-50 text-xs">{{
                        $t('general.private')
                      }}</NcBadge>
                    </span>
                  </div>
                </td>
                <td class="cell-type">
                  <div>
                    <NcBadge rounded="lg" class="flex items-center gap-2 px-0 py-1 !h-7 truncate !border-transparent">
                      <GeneralIntegrationIcon :type="integration.sub_type" />
                      <NcTooltip placement="bottom" show-on-truncate-only class="text-sm truncate">
                        <template #title> {{ clientTypesMap[integration?.sub_type]?.text || integration?.sub_type }}</template>

                        {{
                          integration.sub_type && clientTypesMap[integration.sub_type]
                            ? clientTypesMap[integration.sub_type]?.text
                            : integration.sub_type
                        }}
                      </NcTooltip>
                    </NcBadge>
                  </div>
                </td>
                <td class="cell-created-date">
                  <div>
                    <NcTooltip placement="bottom" show-on-truncate-only>
                      <template #title> {{ dayjs(integration.created_at).local().format('DD MMM YYYY') }}</template>

                      {{ dayjs(integration.created_at).local().format('DD MMM YYYY') }}
                    </NcTooltip>
                  </div>
                </td>
                <td class="cell-added-by">
                  <div>
                    <NcTooltip :disabled="!isUserDeleted(integration.created_by)" class="w-full">
                      <template #title>
                        {{ `User not part of this ${isEeUI ? 'workspace' : 'organisation'} anymore` }}
                      </template>
                      <div
                        v-if="integration.created_by && collaboratorsMap.get(integration.created_by)?.email"
                        class="w-full flex gap-3 items-center"
                      >
                        <GeneralUserIcon
                          :email="collaboratorsMap.get(integration.created_by)?.email"
                          size="base"
                          class="flex-none"
                          :class="{
                            '!grayscale': isUserDeleted(integration.created_by),
                          }"
                          :style="
                            isUserDeleted(integration.created_by)
                              ? {
                                  filter: 'grayscale(100%) brightness(115%)',
                                }
                              : {}
                          "
                        />
                        <div class="flex-1 flex flex-col max-w-[calc(100%_-_44px)]">
                          <div class="w-full flex gap-3">
                            <NcTooltip
                              class="text-sm !leading-5 capitalize font-semibold truncate"
                              :class="{
                                'text-gray-800': !isUserDeleted(integration.created_by),
                                'text-gray-500': isUserDeleted(integration.created_by),
                              }"
                              :disabled="isUserDeleted(integration.created_by)"
                              show-on-truncate-only
                              placement="bottom"
                            >
                              <template #title>
                                {{ getUserNameByCreatedBy(integration.created_by) }}
                              </template>
                              {{ getUserNameByCreatedBy(integration.created_by) }}
                            </NcTooltip>
                          </div>
                          <NcTooltip
                            class="text-xs !leading-4 truncate"
                            :class="{
                              'text-gray-600': !isUserDeleted(integration.created_by),
                              'text-gray-500': isUserDeleted(integration.created_by),
                            }"
                            :disabled="isUserDeleted(integration.created_by)"
                            show-on-truncate-only
                            placement="bottom"
                          >
                            <template #title>
                              {{ collaboratorsMap.get(integration.created_by)?.email }}
                            </template>
                            {{ collaboratorsMap.get(integration.created_by)?.email }}
                          </NcTooltip>
                        </div>
                      </div>
                      <div v-else class="w-full truncate text-gray-500">{{ integration.created_by }}</div>
                    </NcTooltip>
                  </div>
                </td>
                <td class="cell-usage">
                  <div>{{ integration?.source_count ?? 0 }}</div>
                </td>
                <td class="cell-actions" @click.stop>
                  <div class="justify-end">
                    <NcDropdown placement="bottomRight">
                      <NcButton size="small" type="secondary">
                        <GeneralIcon icon="threeDotVertical" />
                      </NcButton>
                      <template #overlay>
                        <NcMenu>
                          <NcMenuItem
                            v-if="integration.type && integrationCategoryNeedDefault(integration.type) && !integration.is_default"
                            @click="setDefaultIntegration(integration)"
                          >
                            <GeneralIcon class="text-gray-800" icon="star" />
                            <span>Set as default</span>
                          </NcMenuItem>
                          <NcMenuItem @click="editIntegration(integration)">
                            <GeneralIcon class="text-gray-800" icon="edit" />
                            <span>{{ $t('general.edit') }}</span>
                          </NcMenuItem>
                          <NcTooltip :disabled="integration?.sub_type !== ClientType.SQLITE">
                            <template #title>
                              Not allowed for type
                              {{
                                integration.sub_type && clientTypesMap[integration.sub_type]
                                  ? clientTypesMap[integration.sub_type]?.text
                                  : integration.sub_type
                              }}
                            </template>

                            <NcMenuItem
                              :disabled="integration?.sub_type === ClientType.SQLITE"
                              @click="duplicateIntegration(integration)"
                            >
                              <GeneralIcon
                                :class="{
                                  'text-current': integration?.sub_type === ClientType.SQLITE,
                                  'text-gray-800': integration?.sub_type !== ClientType.SQLITE,
                                }"
                                icon="duplicate"
                              />
                              <span>{{ $t('general.duplicate') }}</span>
                            </NcMenuItem>
                          </NcTooltip>
                          <NcDivider />
                          <NcMenuItem class="!text-red-500 !hover:bg-red-50" @click="openDeleteIntegration(integration)">
                            <GeneralIcon icon="delete" />
                            {{ $t('general.delete') }}
                          </NcMenuItem>
                        </NcMenu>
                      </template>
                    </NcDropdown>
                  </div>
                </td>
              </tr>
            </tbody>
          </table>
        </template>
      </div>

      <div
        v-show="isLoadingIntegrations"
        class="flex items-center justify-center absolute left-0 top-0 w-full h-full z-10 pb-10 pointer-events-none"
      >
        <div class="flex flex-col justify-center items-center gap-2">
          <GeneralLoader size="xlarge" />
          <span class="text-center">{{ $t('general.loading') }}</span>
        </div>
      </div>

      <div
        v-if="!isLoadingIntegrations && (!integrations?.length || !filteredIntegrations.length)"
        class="flex-none integration-table-empty flex items-center justify-center py-8 px-6 h-full max-h-[calc(100%_-_94px)]"
      >
        <div
          v-if="integrations?.length && !filteredIntegrations.length"
          class="px-2 py-6 text-gray-500 flex flex-col items-center gap-6 text-center"
        >
          <img
            src="~assets/img/placeholder/no-search-result-found.png"
            class="!w-[164px] flex-none"
            alt="No search results found"
          />

          {{ $t('title.noResultsMatchedYourSearch') }}
        </div>

        <div v-else class="flex-none text-center flex flex-col items-center gap-3">
          <a-empty :image="Empty.PRESENTED_IMAGE_SIMPLE" :description="$t('labels.noData')" class="!my-0" />
        </div>
      </div>
      <div
        v-if="integrationPaginationData.totalRows"
        class="flex flex-row justify-center items-center bg-gray-50 min-h-10"
        :class="{
          'pointer-events-none': isLoadingIntegrations,
        }"
      >
        <div class="flex justify-between items-center w-full px-6">
          <div>&nbsp;</div>
          <NcPagination
            v-model:current="integrationPaginationData.page"
            v-model:page-size="integrationPaginationData.pageSize"
            :total="+integrationPaginationData.totalRows"
            show-size-changer
            :use-stored-page-size="false"
            :prev-page-tooltip="`${renderAltOrOptlKey()}+←`"
            :next-page-tooltip="`${renderAltOrOptlKey()}+→`"
            :first-page-tooltip="`${renderAltOrOptlKey()}+↓`"
            :last-page-tooltip="`${renderAltOrOptlKey()}+↑`"
            @update:current="loadConnections(undefined, undefined, false)"
            @update:page-size="loadConnections(integrationPaginationData.page, $event, false)"
          />
          <div class="text-gray-500 text-xs">
            {{ integrationPaginationData.totalRows }} {{ integrationPaginationData.totalRows === 1 ? 'record' : 'records' }}
          </div>
        </div>
      </div>
    </div>

    <GeneralDeleteModal
      v-model:visible="isDeleteIntegrationModalOpen"
      :entity-name="$t('general.connection')"
      :on-delete="onDeleteConfirm"
      :delete-label="$t('general.delete')"
      :show-default-delete-msg="!isLoadingGetLinkedSources && !toBeDeletedIntegration?.sources?.length"
    >
      <template #entity-preview>
        <template v-if="isLoadingGetLinkedSources">
          <div class="rounded-lg overflow-hidden">
            <a-skeleton-input active class="h-9 !rounded-md !w-full"></a-skeleton-input>
          </div>
          <div class="rounded-lg overflow-hidden mt-2">
            <a-skeleton-input active class="h-9 !rounded-md !w-full"></a-skeleton-input>
          </div>
        </template>
        <div v-else-if="toBeDeletedIntegration" class="w-full flex flex-col text-gray-800">
          <div class="flex flex-row items-center py-2 px-3.25 bg-gray-50 rounded-lg text-gray-700 mb-4">
            <GeneralIntegrationIcon :type="toBeDeletedIntegration.sub_type" />
            <div
              class="text-ellipsis overflow-hidden select-none w-full pl-3"
              :style="{ wordBreak: 'keep-all', whiteSpace: 'nowrap', display: 'inline' }"
            >
              {{ toBeDeletedIntegration.title }}
            </div>
          </div>
          <div v-if="toBeDeletedIntegration?.sources?.length" class="flex flex-col pb-2 text-small leading-[18px] text-gray-500">
            <div class="mb-1">Following external data sources using this connection will also be removed</div>
            <ul class="!list-disc ml-6 mb-0">
              <li
                v-for="(source, idx) of toBeDeletedIntegration.sources"
                :key="idx"
                class="marker:text-gray-500 !marker:(flex items-center !-mt-1)"
              >
                <div class="flex items-center gap-1">
                  <div class="flex items-center">
                    &nbsp;
                    <GeneralProjectIcon
                      type="database"
                      class="!grayscale min-w-4 flex-none -ml-1"
                      :style="{
                        filter: 'grayscale(100%) brightness(115%)',
                      }"
                    />
                  </div>

                  <NcTooltip class="!truncate !max-w-[45%] flex-none" show-on-truncate-only>
                    <template #title>
                      {{ source.project_title }}
                    </template>

                    {{ source.project_title }}
                  </NcTooltip>
                  >
                  <GeneralBaseLogo
                    class="!grayscale min-w-4 flex-none"
                    :style="{
                      filter: 'grayscale(100%) brightness(115%)',
                    }"
                  />

                  <NcTooltip class="truncate !max-w-[45%] capitalize" show-on-truncate-only>
                    <template #title>
                      {{ source.alias }}
                    </template>

                    {{ source.alias }}
                  </NcTooltip>
                </div>
              </li>
            </ul>
            <div class="mt-2">Do you want to proceed anyway?</div>
          </div>
        </div>
      </template>
    </GeneralDeleteModal>

    <NcModal v-model:visible="successConfirmModal.isOpen" centered size="small" @keydown.esc="successConfirmModal.isOpen = false">
      <div class="flex gap-4">
        <div>
          <GeneralIcon icon="circleCheckSolid" class="flex-none !text-green-700 mt-0.5 !h-6 !w-6" />
        </div>

        <div class="flex flex-col gap-3">
          <div class="flex">
            <h3 class="!m-0 text-base font-weight-700 flex-1">
              {{ successConfirmModal.title }}
            </h3>
            <NcButton size="xsmall" type="text" @click="successConfirmModal.isOpen = false">
              <GeneralIcon icon="close" class="text-gray-600" />
            </NcButton>
          </div>
          <div class="text-sm text-gray-700">
            {{ successConfirmModal.description }}
          </div>

          <a target="_blank" href="https://docs.nocodb.com/data-sources/connect-to-data-source/" rel="noopener noreferrer">
            Learn more
          </a>
        </div>
      </div>
    </NcModal>
  </div>
</template>

<style lang="scss" scoped>
.source-card-link {
  @apply !text-black !no-underline;

  .nc-new-integration-type-title {
    @apply text-sm font-weight-600 text-gray-600;
  }
}

.source-card {
  @apply flex items-center border-1 rounded-lg p-3 cursor-pointer hover:bg-gray-50;
  width: 288px;

  .name {
    @apply ml-4 text-md font-semibold;
  }
}

:deep(.ant-input-affix-wrapper.nc-search-integration-input) {
  &:not(:has(.ant-input-clear-icon-hidden)):has(.ant-input-clear-icon) {
    @apply border-[var(--ant-primary-5)];
  }
}

.nc-new-integration-type-wrapper {
  @apply flex flex-col gap-3;
}

.table-container {
  @apply border-1 border-gray-200 rounded-lg overflow-hidden w-full;

  .nc-workspace-integration-table {
    &.sticky-shadow {
      th,
      td {
        &.cell-title {
          @apply border-r-1 border-gray-200;
        }
      }
    }

    &:not(.sticky-shadow) {
      th,
      td {
        &.cell-title {
          @apply border-r-1 border-transparent;
        }
      }
    }

    thead {
      @apply w-full;
      th {
        @apply bg-gray-50 text-sm text-gray-500 font-weight-500;

        &.cell-title {
          @apply sticky left-0 z-4 bg-gray-50;
        }
      }
    }

    tbody {
      @apply w-full;
      tr {
        @apply cursor-pointer;

        td {
          @apply text-sm text-gray-600;

          &.cell-title {
            @apply sticky left-0 z-4 bg-white !text-gray-800 font-semibold;
          }
        }
      }
    }

    tr {
      @apply h-[54px] flex border-b-1 border-gray-200 w-full;

      &:hover td {
        @apply !bg-gray-50;
      }

      &.selected td {
        @apply !bg-gray-50;
      }

      th,
      td {
        @apply h-full;

        & > div {
          @apply px-6 h-full flex-1 flex items-center;
        }

        &.cell-title {
          @apply flex-1 sticky left-0 z-5;
          & > div {
            @apply min-w-[250px];
          }
        }

        &.cell-added-by {
          @apply basis-[20%];
          & > div {
            @apply min-w-[250px];
          }
        }

        &.cell-type {
          @apply basis-[20%];
          & > div {
            @apply min-w-[178px];
          }
        }

        &.cell-created-date {
          @apply basis-[20%];
          & > div {
            @apply min-w-[158px];
          }
        }

        &.cell-usage {
          @apply w-[120px];
          & > div {
            @apply min-w-[118px];
          }
        }

        &.cell-actions {
          @apply w-[100px];
          & > div {
            @apply min-w-[98px];
          }
        }
      }
    }
  }
}

.cell-header {
  @apply text-xs font-semibold text-gray-500;
}
</style>
