Browse Source

fix: custom url is part of ee only

Ramesh Mane 6 days ago
parent
commit
18cbfdd512
  1. 16
      packages/nc-gui/components/dlg/share-and-collaborate/CustomUrl.vue
  2. 136
      packages/nc-gui/components/dlg/share-and-collaborate/SharePage.vue
  3. 1
      packages/nc-gui/lang/en.json
  4. 3
      packages/nocodb/src/models/CustomUrl.ts
  5. 31
      packages/nocodb/src/models/View.ts
  6. 34
      packages/nocodb/src/schema/swagger-v2.json

16
packages/nc-gui/components/dlg/share-and-collaborate/CustomUrl.vue

@ -0,0 +1,16 @@
<script lang="ts" setup>
import type { ViewType } from 'nocodb-sdk'
interface Props {
view: ViewType & { meta: object & Record<string, any> }
dashboardUrl: string
}
const emits = defineEmits(['updateSharedView', 'copyCustomUrl'])
</script>
<template>
<span class="hidden"></span>
</template>
<style lang="scss" scoped></style>

136
packages/nc-gui/components/dlg/share-and-collaborate/SharePage.vue

@ -281,7 +281,7 @@ async function saveTheme() {
$e(`a:view:share:${viewTheme.value ? 'enable' : 'disable'}-theme`) $e(`a:view:share:${viewTheme.value ? 'enable' : 'disable'}-theme`)
} }
async function updateSharedView() { async function updateSharedView(custUrl = undefined) {
try { try {
if (!activeView.value?.meta) return if (!activeView.value?.meta) return
const meta = activeView.value.meta const meta = activeView.value.meta
@ -289,10 +289,13 @@ async function updateSharedView() {
await $api.dbViewShare.update(activeView.value.id!, { await $api.dbViewShare.update(activeView.value.id!, {
meta, meta,
password: activeView.value.password, password: activeView.value.password,
custom_url_path: customUrl.value ?? null, ...(custUrl !== undefined ? { custom_url_path: custUrl ?? null } : {}),
original_url: sharedViewUrl(false), original_url: sharedViewUrl(false),
}) })
activeView.value.custom_url_path = customUrl.value ?? null
if (custUrl !== undefined) {
activeView.value.custom_url_path = custUrl ?? null
}
} catch (e: any) { } catch (e: any) {
message.error(await extractSdkResponseErrorMsg(e)) message.error(await extractSdkResponseErrorMsg(e))
} }
@ -300,29 +303,11 @@ async function updateSharedView() {
return true return true
} }
const updateSharedViewWithDebounce = useDebounceFn(
async () => {
await updateSharedView()
},
250,
{ maxWait: 2000 },
)
async function savePreFilledMode() { async function savePreFilledMode() {
await updateSharedView() await updateSharedView()
} }
const isOpenCustomUrlLocal = ref(false) const dashboardBaseUrl = computed(() => {
const isOpenCustomUrl = computed(() => {
return !!activeView.value?.custom_url_path || isOpenCustomUrlLocal.value
})
const customUrlInputRef = ref()
const customUrl = ref()
const dashboardUrl1 = computed(() => {
// get base url for workspace // get base url for workspace
const baseUrl = getBaseUrl(workspaceStore.activeWorkspaceId) const baseUrl = getBaseUrl(workspaceStore.activeWorkspaceId)
@ -333,59 +318,13 @@ const dashboardUrl1 = computed(() => {
return dashboardUrl.value return dashboardUrl.value
}) })
const copyCustomUrl = () => { const copyCustomUrl = async (custUrl = '') => {
copy( return await copy(
`${dashboardUrl1.value}#/p/${customUrl.value}${ `${dashboardBaseUrl.value}#/p/${encodeURIComponent(custUrl || activeView.value?.custom_url_path || '')}${
preFillFormSearchParams.value && activeView.value?.type === ViewTypes.FORM ? `?${preFillFormSearchParams.value}` : '' preFillFormSearchParams.value && activeView.value?.type === ViewTypes.FORM ? `?${preFillFormSearchParams.value}` : ''
}`, }`,
) )
} }
const toggleCustomUrl = async () => {
isOpenCustomUrlLocal.value = !isOpenCustomUrl.value
if (!activeView.value) return
if (isUpdating.value.customUrl) return
isUpdating.value.customUrl = true
try {
if (isOpenCustomUrl.value) {
customUrl.value = null
} else {
customUrl.value = null
}
await updateSharedView()
} finally {
isUpdating.value.customUrl = false
if (isOpenCustomUrl.value) {
customUrlInputRef.value?.focus()
}
}
}
const isCustomUrlAvailable = ref(true)
const checkAvailability = async () => {
try {
const res = await $api.customUrl.checkAvailability({ id: activeView.value?.fk_custom_url_id!, custom_path: customUrl.value })
console.log('res', res)
} catch (e: any) {
console.error(e)
// message.error(await extractSdkResponseErrorMsg(e))
}
}
const checkAvailabilityWithDebounce = useDebounceFn(
async () => {
await checkAvailability()
},
250,
{ maxWait: 2000 },
)
onMounted(() => {
customUrl.value = activeView.value?.custom_url_path
})
</script> </script>
<template> <template>
@ -407,55 +346,14 @@ onMounted(() => {
<div class="mt-0.5 border-t-1 border-gray-100 pt-3"> <div class="mt-0.5 border-t-1 border-gray-100 pt-3">
<GeneralCopyUrl v-model:url="url" /> <GeneralCopyUrl v-model:url="url" />
</div> </div>
<div class="flex flex-col justify-between mt-1 py-2 px-3 bg-gray-50 rounded-md">
<div class="flex flex-row items-center justify-between"> <DlgShareAndCollaborateCustomUrl
<div class="flex text-black">Custom url</div> v-if="activeView"
<a-switch v-model:view="activeView"
v-e="['c:share:view:custom-url:toggle']" :dashboard-url="dashboardBaseUrl"
:checked="isOpenCustomUrl" :copy-custom-url="copyCustomUrl"
:loading="isUpdating.customUrl" @update-shared-view="updateSharedView"
class="share-custom-url-toggle !mt-0.25"
data-testid="share-custom-url-toggle"
size="small"
@click="toggleCustomUrl"
/>
</div>
<Transition mode="out-in" name="layout">
<div
v-if="isOpenCustomUrl"
class="flex items-center mt-2 pl-2 pr-1 w-full border-1 rounded-lg focus-within:(border-1 border-nc-border-brand shadow-selected)"
>
<div class="text-nc-content-gray-muted">{{ dashboardUrl1 }}#/p/</div>
<a-input
ref="customUrlInputRef"
v-model:value="customUrl"
placeholder="Enter custom url"
class="!rounded-lg !py-1 h-8"
data-testid="nc-modal-share-view__custom-url"
size="small"
:bordered="false"
autocomplete="off"
@update:value="checkAvailabilityWithDebounce"
/> />
<div>
<NcButton
v-if="customUrl && customUrl === activeView?.custom_url_path"
size="xs"
type="secondary"
@click="copyCustomUrl"
>
<template #icon>
<MdiContentCopy class="h-3.5" />
</template>
{{ $t('general.copy') }}
</NcButton>
<NcButton v-else size="xs" :disabled="!customUrl" @click.stop="updateSharedView">
{{ $t('general.save') }}
</NcButton>
</div>
</div>
</Transition>
</div>
<div class="flex flex-col justify-between mt-1 py-2 px-3 bg-gray-50 rounded-md"> <div class="flex flex-col justify-between mt-1 py-2 px-3 bg-gray-50 rounded-md">
<div class="flex flex-row items-center justify-between"> <div class="flex flex-row items-center justify-between">
<div class="flex text-black">{{ $t('activity.restrictAccessWithPassword') }}</div> <div class="flex text-black">{{ $t('activity.restrictAccessWithPassword') }}</div>

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

@ -630,6 +630,7 @@
"categories": "Categories", "categories": "Categories",
"fieldInaccessible": "Field inaccessible", "fieldInaccessible": "Field inaccessible",
"noConditionsAdded": "No conditions added", "noConditionsAdded": "No conditions added",
"thisCustomUrlIsAlreadyUsed": "This custom URL is already in use.",
"noAiIntegrationAvailable": "No AI Integrations available.", "noAiIntegrationAvailable": "No AI Integrations available.",
"nocoAiBaseBuilder": "Noco AI Base Builder", "nocoAiBaseBuilder": "Noco AI Base Builder",
"additionalDetails": "Additional Details", "additionalDetails": "Additional Details",

3
packages/nocodb/src/models/CustomUrl.ts

@ -1,6 +1,7 @@
import { CustomUrlType } from 'nocodb-sdk';
import Noco from '~/Noco'; import Noco from '~/Noco';
export default class CustomUrl { export default class CustomUrl implements CustomUrlType {
id?: string; id?: string;
fk_workspace_id?: string; fk_workspace_id?: string;
base_id?: string; base_id?: string;

31
packages/nocodb/src/models/View.ts

@ -130,14 +130,6 @@ export default class View implements ViewType {
if (view) { if (view) {
view.meta = parseMetaProp(view); view.meta = parseMetaProp(view);
if (view.fk_custom_url_id) {
const customUrl = await CustomUrl.get({
id: view.fk_custom_url_id,
});
view.custom_url_path = customUrl.custom_path || null;
}
await NocoCache.set(`${CacheScope.VIEW}:${view.id}`, view); await NocoCache.set(`${CacheScope.VIEW}:${view.id}`, view);
} }
} }
@ -180,14 +172,6 @@ export default class View implements ViewType {
); );
if (view) { if (view) {
if (view.fk_custom_url_id) {
const customUrl = await CustomUrl.get({
id: view.fk_custom_url_id,
});
view.custom_url_path = customUrl.custom_path || null;
}
await NocoCache.set( await NocoCache.set(
`${CacheScope.VIEW}:${fk_model_id}:${view.id}`, `${CacheScope.VIEW}:${fk_model_id}:${view.id}`,
view, view,
@ -228,13 +212,6 @@ export default class View implements ViewType {
); );
if (view) { if (view) {
view.meta = parseMetaProp(view); view.meta = parseMetaProp(view);
if (view.fk_custom_url_id) {
const customUrl = await CustomUrl.get({
id: view.fk_custom_url_id,
});
view.custom_url_path = customUrl.custom_path || null;
}
await NocoCache.set(`${CacheScope.VIEW}:${fk_model_id}:default`, view); await NocoCache.set(`${CacheScope.VIEW}:${fk_model_id}:default`, view);
} }
@ -266,14 +243,6 @@ export default class View implements ViewType {
); );
for (const view of viewsList) { for (const view of viewsList) {
view.meta = parseMetaProp(view); view.meta = parseMetaProp(view);
if (view.fk_custom_url_id) {
const customUrl = await CustomUrl.get({
id: view.fk_custom_url_id,
});
view.custom_url_path = customUrl.custom_path || null;
}
} }
await NocoCache.setList(CacheScope.VIEW, [modelId], viewsList); await NocoCache.setList(CacheScope.VIEW, [modelId], viewsList);
} }

34
packages/nocodb/src/schema/swagger-v2.json

@ -22132,6 +22132,40 @@
} }
}, },
"type": "object" "type": "object"
},
"CustomUrl": {
"description": "Model for Custom Url",
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Id associated to the Custom url"
},
"fk_workspace_id": {
"type": "string",
"description": "Workspace ID"
},
"base_id": {
"type": "string",
"description": "Base ID"
},
"fk_model_id": {
"type": "string",
"description": "Model ID"
},
"view_id": {
"type": "string",
"description": "View ID"
},
"original_path": {
"type": "string",
"description": "Original url used for redirection purpose"
},
"custom_path": {
"type": "string",
"description": "Custom url path"
}
}
} }
}, },
"responses": { "responses": {

Loading…
Cancel
Save