Browse Source

fix(nc-gui): move get prefill link in share form modal

pull/7786/head
Ramesh Mane 7 months ago
parent
commit
8bd4215c00
  1. 110
      packages/nc-gui/components/dlg/share-and-collaborate/SharePage.vue
  2. 70
      packages/nc-gui/components/smartsheet/Form.vue
  3. 2
      packages/nc-gui/composables/useSharedFormViewStore.ts
  4. 6
      packages/nc-gui/lang/en.json
  5. 3
      packages/nc-gui/lib/enums.ts
  6. 1
      packages/nc-gui/lib/types.ts
  7. 5
      packages/nc-gui/store/views.ts

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

@ -7,6 +7,8 @@ const { view: _view, $api } = useSmartsheetStoreOrThrow()
const { $e } = useNuxtApp()
const { getBaseUrl, appInfo } = useGlobal()
const { t } = useI18n()
const { dashboardUrl } = useDashboard()
const viewStore = useViewsStore()
@ -52,6 +54,10 @@ const url = computed(() => {
return sharedViewUrl() ?? ''
})
const forPreFillUrl = computed(() => {
return sharedViewUrl(true) ?? ''
})
const passwordProtectedLocal = ref(false)
const passwordProtected = computed(() => {
@ -149,17 +155,31 @@ const surveyMode = computed({
},
})
const preFilledMode = computed({
get: () => parseProp(activeView.value?.meta)?.preFilledMode || PreFilledMode.Default,
set: (preFilled) => {
const formPreFill = computed({
get: () => ({
preFillEnabled: parseProp(activeView.value?.meta)?.preFillEnabled ?? false,
preFilledMode: parseProp(activeView.value?.meta)?.preFilledMode || t('general.default'),
}),
set: (value) => {
if (!activeView.value?.meta) return
activeView.value.meta = { ...activeView.value.meta, preFilledMode: preFilled }
if (formPreFill.value.preFillEnabled !== value.preFillEnabled) {
$e(`a:view:share:prefilled-mode-${value.preFillEnabled ? 'enabled' : 'disabled'}`)
}
if (formPreFill.value.preFilledMode !== value.preFilledMode) {
$e(`a:view:share:${value.preFillEnabled || 'default'}-prefilled-mode`)
}
activeView.value.meta = {
...activeView.value.meta,
...value,
}
savePreFilledMode()
},
})
function sharedViewUrl() {
function sharedViewUrl(isPreFillUrl: boolean = false) {
if (!activeView.value) return
let viewType
@ -191,7 +211,13 @@ function sharedViewUrl() {
dashboardUrl1 = `${baseUrl}${appInfo.value?.dashboardPath}`
}
return encodeURI(`${dashboardUrl1}#/nc/${viewType}/${activeView.value.uuid}${surveyMode.value ? '/survey' : ''}`)
return encodeURI(
`${dashboardUrl1}#/nc/${viewType}/${activeView.value.uuid}${surveyMode.value ? '/survey' : ''}${
isPreFillUrl && formPreFill.value.preFillEnabled && viewStore.preFillFormSearchParams
? `?${viewStore.preFillFormSearchParams}`
: ''
}`,
)
}
const toggleViewShare = async () => {
@ -270,7 +296,6 @@ async function updateSharedView() {
async function savePreFilledMode() {
await updateSharedView()
$e(`a:view:share:${preFilledMode.value}-prefilled-mode`)
}
</script>
@ -361,29 +386,74 @@ async function savePreFilledMode() {
v-if="activeView?.type === ViewTypes.FORM"
class="nc-pre-filled-mode-wrapper flex flex-col justify-between gap-y-3 mt-1 py-2 px-3 bg-gray-50 rounded-md"
>
<div>
<div class="flex flex-row justify-between">
<div class="text-black">{{ $t('activity.preFilledFields.title') }}</div>
<a-switch
:checked="formPreFill.preFillEnabled"
v-e="['c:share:view:surver-mode:toggle']"
data-testid="nc-modal-share-view__surveyMode"
@update:checked="
(value) => {
formPreFill = {
...formPreFill,
preFillEnabled: value,
}
}
"
>
</a-switch>
</div>
<div v-if="formPreFill.preFillEnabled">
<!-- <div class="text-black">{{ $t('activity.preFilledFields.title') }}</div> -->
<a-select
v-model:value="preFilledMode"
:value="formPreFill.preFilledMode"
:allow-clear="formPreFill.preFilledMode !== t('general.default')"
class="nc-pre-filled-mode !rounded-md w-full"
dropdown-class-name="nc-dropdown-pre-filled-mode border-1 !rounded-md border-gray-200"
@update:value="
(value) => {
formPreFill = {
...formPreFill,
preFilledMode: value || '',
}
}
"
>
<template #suffixIcon>
<GeneralIcon icon="arrowDown" class="text-gray-700" />
</template>
<a-select-option v-for="mode of Object.values(PreFilledMode)" :key="mode" :value="mode">
<div class="flex gap-2 items-center">
<div class="flex-1">{{ $t(`activity.preFilledFields.${mode}`) }}</div>
<component
:is="iconMap.check"
v-if="preFilledMode === mode"
id="nc-selected-item-icon"
class="text-primary w-4 h-4"
/>
</div>
</a-select-option>
<template v-for="mode of Object.values(PreFilledMode)" :key="mode">
<a-select-option v-if="mode !== PreFilledMode.Default" :value="mode">
<div class="flex gap-2 items-center">
<div class="flex-1">{{ $t(`activity.preFilledFields.${mode}`) }}</div>
<component
:is="iconMap.check"
v-if="formPreFill.preFilledMode === mode"
id="nc-selected-item-icon"
class="text-primary w-4 h-4"
/>
</div>
</a-select-option>
</template>
</a-select>
<NcTooltip
:disabled="!!viewStore.preFillFormSearchParams"
:class="{
'!cursor-not-allowed': !viewStore.preFillFormSearchParams,
}"
>
<template #title> {{ $t('tooltip.fillTheFormFieldFirst') }} </template>
<div
class="mt-0.5 border-t-1 border-gray-100 pt-3"
:class="{
'pointer-events-none': !viewStore.preFillFormSearchParams,
}"
>
<GeneralCopyUrl v-model:url="forPreFillUrl" />
</div>
</NcTooltip>
</div>
</div>
</template>

70
packages/nc-gui/components/smartsheet/Form.vue

@ -43,6 +43,7 @@ import {
useViewColumnsOrThrow,
useViewData,
watch,
useViewsStore,
} from '#imports'
import type { ImageCropperConfig } from '~/lib'
@ -104,6 +105,8 @@ const isPublic = inject(IsPublicInj, ref(false))
const { loadFormView, insertRow, formColumnData, formViewData, updateFormView } = useViewData(meta, view)
const { preFillFormSearchParams } = storeToRefs(useViewsStore())
const reloadEventHook = inject(ReloadViewDataHookInj, createEventHook())
reloadEventHook.on(async () => {
@ -199,6 +202,22 @@ const updateView = useDebounceFn(
{ maxWait: 2000 },
)
const updatePreFillFormSearchParams = useDebounceFn(() => {
if (isLocked.value || !isUIAllowed('dataInsert')) return
const preFilledData = { ...formState, ...state.value }
const searchParams = new URLSearchParams()
for (const c of visibleColumns.value) {
if (c.title && preFilledData[c.title] && !isVirtualCol(c) && !(UITypes.Attachment === c.uidt)) {
searchParams.append(c.title, preFilledData[c.title])
}
}
preFillFormSearchParams.value = searchParams.toString()
}, 250)
async function submitForm() {
if (isLocked.value || !isUIAllowed('dataInsert')) return
@ -220,38 +239,6 @@ async function submitForm() {
submitted.value = true
}
async function getPreFilledLink() {
if (isLocked.value || !isUIAllowed('dataInsert') || !view.value?.uuid) return
const preFilledData = { ...formState, ...state.value }
const searchParams = new URLSearchParams()
for (const c of visibleColumns.value) {
if (c.title && preFilledData[c.title] && !isVirtualCol(c)) {
searchParams.append(c.title, preFilledData[c.title])
}
}
// get base url for workspace
const baseUrl = getBaseUrl(workspaceStore.activeWorkspaceId)
let dashboardUrl1 = dashboardUrl.value
if (baseUrl) {
dashboardUrl1 = `${baseUrl}${appInfo.value?.dashboardPath}`
}
copy(
encodeURI(
`${dashboardUrl1}#/nc/form/${view.value?.uuid}${parseProp(view.value?.meta).surveyMode ? '/survey' : ''}${
searchParams.toString() ? `?${searchParams.toString()}` : ''
}`,
),
)
message.info(t('msg.info.copiedToClipboard'))
}
async function clearForm() {
if (isLocked.value || !isUIAllowed('dataInsert')) return
@ -639,6 +626,10 @@ watch([focusLabel, activeRow], () => {
}
})
watch([formState, state], () => {
updatePreFillFormSearchParams()
})
useEventListener(
formRef,
'focusout',
@ -1332,21 +1323,6 @@ useEventListener(
{{ $t('activity.clearForm') }}
</NcButton>
<div class="flex items-center gap-3">
<NcTooltip :disabled="!!view?.uuid">
<template #title>{{ $t('tooltip.formIsNotShared') }}</template>
<NcButton
v-if="isUIAllowed('dataInsert') && visibleColumns.length"
type="primary"
size="small"
:disabled="!isUIAllowed('dataInsert') || !visibleColumns.length || isLocked || !view?.uuid"
class="nc-form-get-pre-filled-link nc-form-focus-element"
data-testid="nc-form-get-pre-filled-link"
data-title="nc-form-get-pre-filled-link"
@click="getPreFilledLink"
>
{{ $t('activity.getPreFilledLink') }}
</NcButton>
</NcTooltip>
<NcButton
html-type="submit"
type="primary"

2
packages/nc-gui/composables/useSharedFormViewStore.ts

@ -255,7 +255,7 @@ const [useProvideSharedFormStore, useSharedFormStore] = useInjectionState((share
}
function handlePreFillForm() {
if (Object.keys(route.query).length && sharedViewMeta.value.preFilledMode !== PreFilledMode.Disabled) {
if (Object.keys(route.query).length && sharedViewMeta.value.preFillEnabled) {
columns.value = columns.value?.map((c) => {
if (
!c.title ||

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

@ -928,9 +928,7 @@
"addFieldFromFormView": "Add Field",
"selectAllFields": "Select all fields",
"preFilledFields": {
"title": "Pre-filled Fields",
"default": "Allow pre-filling fields",
"disabled": "Disable pre-filling fields",
"title": "Enable Pre-fill",
"locked": "Lock pre-filled fields as read-only",
"hidden": "Hide pre-filled fields",
"lockedFieldTooltip": "Pre-filled value"
@ -966,7 +964,7 @@
"clientKey": "Select .key file",
"clientCert": "Select .cert file",
"clientCA": "Select CA file",
"formIsNotShared": "Form is not shared"
"fillTheFormFieldFirst": "Fill the form fields first"
},
"placeholder": {
"selectSlackChannels": "Select Slack channels",

3
packages/nc-gui/lib/enums.ts

@ -138,8 +138,7 @@ export enum ImportSource {
}
export enum PreFilledMode {
Default = 'default',
Disabled = 'disabled',
Default = '',
Locked = 'locked',
Hidden = 'hidden',
}

1
packages/nc-gui/lib/types.ts

@ -115,6 +115,7 @@ interface SharedViewMeta extends Record<string, any> {
theme?: Partial<ThemeConfig>
allowCSVDownload?: boolean
rtl?: boolean
preFillEnabled?: boolean
preFilledMode?: PreFilledMode
}

5
packages/nc-gui/store/views.ts

@ -116,6 +116,8 @@ export const useViewsStore = defineStore('viewsStore', () => {
// Used for Grid View Pagination
const isPaginationLoading = ref(true)
const preFillFormSearchParams = ref('')
const loadViews = async ({
tableId,
ignoreLoading,
@ -282,6 +284,8 @@ export const useViewsStore = defineStore('viewsStore', () => {
if (!view) return
if (!view.base_id) return
preFillFormSearchParams.value = ''
const tableName = tablesStore.baseTables.get(view.base_id)?.find((t) => t.id === view.fk_model_id)?.title
const baseName = bases.basesList.find((p) => p.id === view.base_id)?.title
@ -322,6 +326,7 @@ export const useViewsStore = defineStore('viewsStore', () => {
activeSorts,
activeNestedFilters,
isActiveViewLocked,
preFillFormSearchParams,
}
})

Loading…
Cancel
Save