mirror of
https://github.com/nocodb/nocodb.git
synced 2026-05-03 07:57:00 +00:00
186 lines
5.0 KiB
Vue
186 lines
5.0 KiB
Vue
<script setup lang="ts">
|
|
import type { StringOrNullType } from 'nocodb-sdk'
|
|
|
|
interface ShareBase {
|
|
uuid?: string
|
|
url?: string
|
|
role?: string
|
|
fk_custom_url_id?: StringOrNullType
|
|
}
|
|
|
|
enum ShareBaseRole {
|
|
Editor = 'editor',
|
|
Viewer = 'viewer',
|
|
}
|
|
|
|
const { dashboardUrl } = useDashboard()
|
|
|
|
const { $api, $e } = useNuxtApp()
|
|
|
|
const { showEEFeatures } = useEeConfig()
|
|
|
|
const { copy } = useCopy()
|
|
|
|
const sharedBase = ref<null | ShareBase>(null)
|
|
|
|
const { base, isPrivateBase } = storeToRefs(useBase())
|
|
|
|
const { appInfo } = useGlobal()
|
|
|
|
const url = computed(() => {
|
|
if (!sharedBase.value || !sharedBase.value.uuid) return ''
|
|
|
|
return encodeURI(`${dashboardUrl.value}/base/${sharedBase.value.uuid}`)
|
|
})
|
|
|
|
const loadBase = async () => {
|
|
try {
|
|
if (!base.value.id) return
|
|
|
|
const res = await $api.base.sharedBaseGet(base.value.id)
|
|
|
|
sharedBase.value = {
|
|
uuid: res.uuid,
|
|
url: res.url,
|
|
role: res.roles,
|
|
fk_custom_url_id: res?.fk_custom_url_id || null,
|
|
}
|
|
} catch (e: any) {
|
|
message.error(await extractSdkResponseErrorMsg(e))
|
|
}
|
|
}
|
|
|
|
const createShareBase = async (role = ShareBaseRole.Viewer, custUrl = undefined) => {
|
|
try {
|
|
if (!base.value.id) return
|
|
|
|
const res = await $api.base.sharedBaseUpdate(base.value.id, {
|
|
roles: role,
|
|
original_url: url.value,
|
|
...(custUrl !== undefined ? { custom_url_path: custUrl ?? null } : {}),
|
|
})
|
|
|
|
sharedBase.value = res ?? {}
|
|
sharedBase.value!.role = role
|
|
|
|
base.value.uuid = res.uuid
|
|
|
|
if (custUrl !== undefined) {
|
|
sharedBase.value!.fk_custom_url_id = res.fk_custom_url_id
|
|
base.value.fk_custom_url_id = res.fk_custom_url_id
|
|
}
|
|
} catch (e: any) {
|
|
message.error(await extractSdkResponseErrorMsg(e))
|
|
}
|
|
|
|
$e('a:shared-base:enable', { role })
|
|
}
|
|
|
|
const disableSharedBase = async () => {
|
|
try {
|
|
if (!base.value.id) return
|
|
|
|
await $api.base.sharedBaseDisable(base.value.id)
|
|
sharedBase.value = null
|
|
|
|
base.value.uuid = undefined
|
|
} catch (e: any) {
|
|
message.error(await extractSdkResponseErrorMsg(e))
|
|
}
|
|
|
|
$e('a:shared-base:disable')
|
|
}
|
|
|
|
onMounted(() => {
|
|
if (!sharedBase.value) {
|
|
loadBase()
|
|
}
|
|
})
|
|
|
|
const isSharedBaseEnabled = computed(() => {
|
|
// If base is private, then we have to restrict sharing
|
|
if (isPrivateBase.value) return false
|
|
return !!sharedBase.value?.uuid
|
|
})
|
|
const isToggleBaseLoading = ref(false)
|
|
const isRoleToggleLoading = ref(false)
|
|
|
|
const toggleSharedBase = async () => {
|
|
if (isToggleBaseLoading.value) return
|
|
isToggleBaseLoading.value = true
|
|
|
|
try {
|
|
if (isSharedBaseEnabled.value) {
|
|
await disableSharedBase()
|
|
} else {
|
|
await createShareBase()
|
|
}
|
|
} catch (e: any) {
|
|
message.error(await extractSdkResponseErrorMsg(e))
|
|
} finally {
|
|
isToggleBaseLoading.value = false
|
|
}
|
|
}
|
|
|
|
const onRoleToggle = async () => {
|
|
if (!sharedBase.value) return
|
|
if (isRoleToggleLoading.value) return
|
|
|
|
isRoleToggleLoading.value = true
|
|
try {
|
|
await createShareBase(ShareBaseRole.Viewer)
|
|
} catch (e: any) {
|
|
message.error(await extractSdkResponseErrorMsg(e))
|
|
} finally {
|
|
isRoleToggleLoading.value = false
|
|
}
|
|
}
|
|
|
|
const copyCustomUrl = async (custUrl = '') => {
|
|
return await copy(`${appInfo.value.ncSiteUrl}/p/${encodeURIComponent(custUrl)}`)
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="flex flex-col py-2 px-3 gap-2 w-full" data-testid="nc-share-base-sub-modal">
|
|
<div class="flex flex-col w-full p-3 border-1 border-nc-border-gray-light rounded-md">
|
|
<div class="flex flex-row w-full justify-between">
|
|
<div class="text-nc-content-gray-emphasis font-medium">{{ $t('activity.enablePublicAccess') }}</div>
|
|
<a-switch
|
|
v-if="!isPrivateBase"
|
|
v-e="['c:share:base:enable:toggle']"
|
|
:checked="isSharedBaseEnabled"
|
|
:loading="isToggleBaseLoading"
|
|
class="ml-2"
|
|
@click="toggleSharedBase"
|
|
/>
|
|
<div v-else class="text-nc-content-gray-muted">{{ $t('labels.sharingRestricted') }}</div>
|
|
</div>
|
|
<div v-if="isSharedBaseEnabled" class="flex flex-col gap-3 w-full mt-3 border-t-1 pt-3 border-nc-border-gray-light">
|
|
<GeneralCopyUrl v-model:url="url" />
|
|
<DlgShareAndCollaborateCustomUrl
|
|
v-if="sharedBase?.uuid && showEEFeatures"
|
|
:id="sharedBase.fk_custom_url_id"
|
|
:backend-url="appInfo.ncSiteUrl"
|
|
:copy-custom-url="copyCustomUrl"
|
|
:disabled="isPrivateBase"
|
|
@update-custom-url="createShareBase(undefined, $event)"
|
|
/>
|
|
<div
|
|
v-if="!appInfo.ee && sharedBase?.role === ShareBaseRole.Editor"
|
|
class="flex flex-row justify-between bg-nc-bg-gray-extralight px-3 py-2 rounded-md"
|
|
>
|
|
<div class="text-nc-content-gray-extreme">{{ $t('activity.editingAccess') }}</div>
|
|
<a-switch
|
|
v-e="['c:share:base:role:toggle']"
|
|
:loading="isRoleToggleLoading"
|
|
:checked="sharedBase?.role === ShareBaseRole.Editor"
|
|
class="ml-2"
|
|
@click="onRoleToggle"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|