|
|
@ -1,7 +1,11 @@ |
|
|
|
<script lang="ts" setup> |
|
|
|
<script lang="ts" setup> |
|
|
|
import { useClipboard } from '@vueuse/core' |
|
|
|
import { useClipboard } from '@vueuse/core' |
|
|
|
import { ViewTypes } from 'nocodb-sdk' |
|
|
|
import { ViewTypes } from 'nocodb-sdk' |
|
|
|
|
|
|
|
import { computed } from 'vue' |
|
|
|
|
|
|
|
import { useToast } from 'vue-toastification' |
|
|
|
|
|
|
|
import { useNuxtApp } from '#app' |
|
|
|
import { useSmartsheetStoreOrThrow } from '~/composables/useSmartsheetStore' |
|
|
|
import { useSmartsheetStoreOrThrow } from '~/composables/useSmartsheetStore' |
|
|
|
|
|
|
|
import { extractSdkResponseErrorMsg } from '~/utils/errorUtils' |
|
|
|
import MdiOpenInNewIcon from '~icons/mdi/open-in-new' |
|
|
|
import MdiOpenInNewIcon from '~icons/mdi/open-in-new' |
|
|
|
import MdiCopyIcon from '~icons/mdi/content-copy' |
|
|
|
import MdiCopyIcon from '~icons/mdi/content-copy' |
|
|
|
|
|
|
|
|
|
|
@ -9,19 +13,31 @@ const { isUIAllowed } = useUIPermission() |
|
|
|
const { view, $api } = useSmartsheetStoreOrThrow() |
|
|
|
const { view, $api } = useSmartsheetStoreOrThrow() |
|
|
|
|
|
|
|
|
|
|
|
const { copy } = useClipboard() |
|
|
|
const { copy } = useClipboard() |
|
|
|
|
|
|
|
const toast = useToast() |
|
|
|
|
|
|
|
const { $e } = useNuxtApp() |
|
|
|
|
|
|
|
|
|
|
|
let showShareModel = $ref(false) |
|
|
|
let showShareModel = $ref(false) |
|
|
|
|
|
|
|
const passwordProtected = $ref(false) |
|
|
|
const shared = ref() |
|
|
|
const shared = ref() |
|
|
|
|
|
|
|
|
|
|
|
const source = ref('Hello') |
|
|
|
const allowCSVDownload = computed({ |
|
|
|
|
|
|
|
get() { |
|
|
|
|
|
|
|
return !!(shared.value?.meta && typeof shared.value.meta === 'string' ? JSON.parse(shared.value.meta) : shared.value.meta) |
|
|
|
|
|
|
|
?.allowCSVDownload |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
set(allow) { |
|
|
|
|
|
|
|
shared.value.meta = { allowCSVDownload: allow } |
|
|
|
|
|
|
|
saveAllowCSVDownload() |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
const genShareLink = async () => { |
|
|
|
const genShareLink = async () => { |
|
|
|
shared.value = await $api.dbViewShare.create(view.value.id as string) |
|
|
|
shared.value = await $api.dbViewShare.create(view.value.id as string) |
|
|
|
// shared.meta = shared.meta && typeof shared.meta === 'string' ? JSON.parse(shared.meta) : shared.meta; |
|
|
|
// shared.meta = shared.meta && typeof shared.meta === 'string' ? JSON.parse(shared.meta) : shared.meta; |
|
|
|
// // todo: url |
|
|
|
// // todo: url |
|
|
|
// this.shareLink = shared; |
|
|
|
// shareLink = shared; |
|
|
|
// this.passwordProtect = shared.password !== null; |
|
|
|
// passwordProtect = shared.password !== null; |
|
|
|
// this.allowCSVDownload = shared.meta.allowCSVDownload; |
|
|
|
// allowCSVDownload = shared.meta.allowCSVDownload; |
|
|
|
showShareModel = true |
|
|
|
showShareModel = true |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -43,6 +59,38 @@ const sharedViewUrl = computed(() => { |
|
|
|
// todo: get dashboard url |
|
|
|
// todo: get dashboard url |
|
|
|
return `#/nc/${viewType}/${shared.value.uuid}` |
|
|
|
return `#/nc/${viewType}/${shared.value.uuid}` |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function saveAllowCSVDownload () { |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
const meta = shared.value.meta && typeof shared.value.meta === 'string' ? JSON.parse(shared.value.meta) : shared.value.meta |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// todo: update swagger |
|
|
|
|
|
|
|
await $api.dbViewShare.update(shared.value.id, { |
|
|
|
|
|
|
|
meta, |
|
|
|
|
|
|
|
} as any) |
|
|
|
|
|
|
|
toast.success('Successfully updated') |
|
|
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
|
|
toast.error(await extractSdkResponseErrorMsg(e)) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (allowCSVDownload?.value) { |
|
|
|
|
|
|
|
$e('a:view:share:enable-csv-download') |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
$e('a:view:share:disable-csv-download') |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const saveShareLinkPassword = async () => { |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
await $api.dbViewShare.update(shared.value.id, { |
|
|
|
|
|
|
|
password: shared.value.password, |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
toast.success('Successfully updated') |
|
|
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
|
|
toast.error(await extractSdkResponseErrorMsg(e)) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$e('a:view:share:enable-pwd') |
|
|
|
|
|
|
|
} |
|
|
|
</script> |
|
|
|
</script> |
|
|
|
|
|
|
|
|
|
|
|
<template> |
|
|
|
<template> |
|
|
@ -56,7 +104,7 @@ const sharedViewUrl = computed(() => { |
|
|
|
</a-button> |
|
|
|
</a-button> |
|
|
|
|
|
|
|
|
|
|
|
<!-- This view is shared via a private link --> |
|
|
|
<!-- This view is shared via a private link --> |
|
|
|
<a-modal v-model:visible="showShareModel" size="small" :title="$t('msg.info.privateLink')"> |
|
|
|
<a-modal v-model:visible="showShareModel" size="small" :title="$t('msg.info.privateLink')" :footer="null"> |
|
|
|
<div class="share-link-box nc-share-link-box"> |
|
|
|
<div class="share-link-box nc-share-link-box"> |
|
|
|
<div class="flex-1 h-min">{{ sharedViewUrl }}</div> |
|
|
|
<div class="flex-1 h-min">{{ sharedViewUrl }}</div> |
|
|
|
<!-- <v-spacer /> --> |
|
|
|
<!-- <v-spacer /> --> |
|
|
@ -65,64 +113,31 @@ const sharedViewUrl = computed(() => { |
|
|
|
</a> |
|
|
|
</a> |
|
|
|
<MdiCopyIcon class="text-grey text-sm cursor-pointer" @click="copy(sharedViewUrl)" /> |
|
|
|
<MdiCopyIcon class="text-grey text-sm cursor-pointer" @click="copy(sharedViewUrl)" /> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<!-- |
|
|
|
|
|
|
|
<v-expansion-panels v-model="advanceOptionsPanel" class="mx-auto" flat> |
|
|
|
<a-collapse ghost> |
|
|
|
<v-expansion-panel> |
|
|
|
<a-collapse-panel key="1" header="More Options"> |
|
|
|
<v-expansion-panel-header hide-actions> |
|
|
|
<div class="mb-2"> |
|
|
|
<v-spacer /> |
|
|
|
<a-checkbox v-model:checked="passwordProtected" class="text-xs">{{ $t('msg.info.beforeEnablePwd') }} </a-checkbox> |
|
|
|
<span class="grey--text caption" |
|
|
|
<!-- todo: add password toggle --> |
|
|
|
>More Options |
|
|
|
<div v-if="passwordProtected" class="flex gap-2 mt-2 mb-4"> |
|
|
|
<v-icon color="grey" small> mdi-chevron-{{ advanceOptionsPanel === 0 ? 'up' : 'down' }} </v-icon></span |
|
|
|
<a-input |
|
|
|
> |
|
|
|
v-model:value="shared.password" |
|
|
|
</v-expansion-panel-header> |
|
|
|
size="small" |
|
|
|
<v-expansion-panel-content> |
|
|
|
class="max-w-[250px]" |
|
|
|
<v-checkbox |
|
|
|
:placeholder="$t('placeholder.password.enter')" |
|
|
|
v-model="passwordProtect" |
|
|
|
|
|
|
|
class="caption" |
|
|
|
|
|
|
|
:label="$t('msg.info.beforeEnablePwd')" |
|
|
|
|
|
|
|
hide-details |
|
|
|
|
|
|
|
dense |
|
|
|
|
|
|
|
@change="onPasswordProtectChange" |
|
|
|
|
|
|
|
/> |
|
|
|
/> |
|
|
|
<div v-if="passwordProtect" class="d-flex flex-column align-center justify-center"> |
|
|
|
<a-button size="small" class="!text-xs" @click="saveShareLinkPassword">{{ |
|
|
|
<v-text-field |
|
|
|
$t('placeholder.password.save') |
|
|
|
v-model="shareLink.password" |
|
|
|
}}</a-button> |
|
|
|
autocomplete="new-password" |
|
|
|
|
|
|
|
browser-autocomplete="new-password" |
|
|
|
|
|
|
|
class="password-field mr-2 caption" |
|
|
|
|
|
|
|
style="max-width: 230px" |
|
|
|
|
|
|
|
:type="showShareLinkPassword ? 'text' : 'password'" |
|
|
|
|
|
|
|
:hint="$t('placeholder.password.enter')" |
|
|
|
|
|
|
|
persistent-hint |
|
|
|
|
|
|
|
dense |
|
|
|
|
|
|
|
solo |
|
|
|
|
|
|
|
flat |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
<template #append> |
|
|
|
|
|
|
|
<v-icon small @click="showShareLinkPassword = !showShareLinkPassword"> |
|
|
|
|
|
|
|
{{ showShareLinkPassword ? 'visibility_off' : 'visibility' }} |
|
|
|
|
|
|
|
</v-icon> |
|
|
|
|
|
|
|
</template> |
|
|
|
|
|
|
|
</v-text-field> |
|
|
|
|
|
|
|
<v-btn color="primary" class="caption" small @click="saveShareLinkPassword"> |
|
|
|
|
|
|
|
<!– Save password –> |
|
|
|
|
|
|
|
{{ $t('placeholder.password.save') }} |
|
|
|
|
|
|
|
</v-btn> |
|
|
|
|
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<v-checkbox |
|
|
|
</div> |
|
|
|
v-if="selectedView && selectedView.type === viewTypes.GRID" |
|
|
|
<div> |
|
|
|
v-model="allowCSVDownload" |
|
|
|
<a-checkbox v-if="shared && shared.type === ViewTypes.GRID" v-model:checked="allowCSVDownload" class="text-xs" |
|
|
|
class="caption" |
|
|
|
>Allow Download |
|
|
|
label="Allow Download" |
|
|
|
</a-checkbox> |
|
|
|
hide-details |
|
|
|
</div> |
|
|
|
dense |
|
|
|
</a-collapse-panel> |
|
|
|
@change="onAllowCSVDownloadChange" |
|
|
|
</a-collapse> |
|
|
|
/> |
|
|
|
|
|
|
|
</v-expansion-panel-content> |
|
|
|
|
|
|
|
</v-expansion-panel> |
|
|
|
|
|
|
|
</v-expansion-panels> --> |
|
|
|
|
|
|
|
<!-- </v-container> --> |
|
|
|
|
|
|
|
<!-- </v-card> --> |
|
|
|
|
|
|
|
</a-modal> |
|
|
|
</a-modal> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
</template> |
|
|
|