Browse Source

feat(nc-gui): allow customizing transition duration in survey form

pull/3980/head
braks 2 years ago
parent
commit
4eb927f29e
  1. 87
      packages/nc-gui/components/smartsheet/toolbar/ShareView.vue
  2. 1
      packages/nc-gui/lib/types.ts
  3. 13
      packages/nc-gui/pages/[projectType]/form/[viewId]/index/survey.vue

87
packages/nc-gui/components/smartsheet/toolbar/ShareView.vue

@ -10,6 +10,7 @@ import {
ref, ref,
useCopy, useCopy,
useDashboard, useDashboard,
useDebounceFn,
useI18n, useI18n,
useNuxtApp, useNuxtApp,
useProject, useProject,
@ -112,6 +113,8 @@ async function saveTheme() {
$e(`a:view:share:${viewTheme.value ? 'enable' : 'disable'}-theme`) $e(`a:view:share:${viewTheme.value ? 'enable' : 'disable'}-theme`)
} }
const saveTransitionDuration = useDebounceFn(updateSharedViewMeta, 1000, { maxWait: 2000 })
async function updateSharedViewMeta() { async function updateSharedViewMeta() {
try { try {
const meta = shared.value.meta && isString(shared.value.meta) ? JSON.parse(shared.value.meta) : shared.value.meta const meta = shared.value.meta && isString(shared.value.meta) ? JSON.parse(shared.value.meta) : shared.value.meta
@ -222,10 +225,28 @@ watch(passwordProtected, (value) => {
v-if="shared.type === ViewTypes.FORM" v-if="shared.type === ViewTypes.FORM"
v-model:checked="surveyMode" v-model:checked="surveyMode"
data-cy="nc-modal-share-view__survey-mode" data-cy="nc-modal-share-view__survey-mode"
class="!text-xs" class="!text-sm"
> >
Use Survey Mode Use Survey Mode
</a-checkbox> </a-checkbox>
<Transition name="layout" mode="out-in">
<div v-if="surveyMode" class="flex flex-col justify-center pl-6">
<a-form-item class="!my-1" :has-feedback="false" name="transitionDuration">
<template #label>
<div class="text-xs">Transition duration (in MS)</div>
</template>
<a-input
v-model:value="shared.meta.transitionDuration"
data-cy="nc-form-signin__email"
size="small"
class="!w-32"
type="number"
@change="saveTransitionDuration"
/>
</a-form-item>
</div>
</Transition>
</div> </div>
<div> <div>
@ -234,43 +255,53 @@ watch(passwordProtected, (value) => {
v-if="shared.type === ViewTypes.FORM" v-if="shared.type === ViewTypes.FORM"
v-model:checked="viewTheme" v-model:checked="viewTheme"
data-cy="nc-modal-share-view__with-theme" data-cy="nc-modal-share-view__with-theme"
class="!text-xs" class="!text-sm"
> >
Use Theme Use Theme
</a-checkbox> </a-checkbox>
<div v-if="viewTheme" class="flex pl-2"> <Transition name="layout" mode="out-in">
<LazyGeneralColorPicker <div v-if="viewTheme" class="flex pl-6">
data-cy="nc-modal-share-view__theme-picker" <LazyGeneralColorPicker
:model-value="shared.meta.theme?.primaryColor" data-cy="nc-modal-share-view__theme-picker"
:colors="projectThemeColors" class="!p-0"
:row-size="9" :model-value="shared.meta.theme?.primaryColor"
:advanced="false" :colors="projectThemeColors"
@input="onChangeTheme" :row-size="9"
/> :advanced="false"
</div> @input="onChangeTheme"
/>
</div>
</Transition>
</div> </div>
<div> <div>
<!-- Password Protection --> <!-- Password Protection -->
<a-checkbox v-model:checked="passwordProtected" data-cy="nc-modal-share-view__with-password" class="!text-xs"> <a-checkbox v-model:checked="passwordProtected" data-cy="nc-modal-share-view__with-password" class="!text-sm !my-1">
{{ $t('msg.info.beforeEnablePwd') }} {{ $t('msg.info.beforeEnablePwd') }}
</a-checkbox> </a-checkbox>
<div v-if="passwordProtected" class="ml-6 flex gap-2 mt-2 mb-4"> <Transition name="layout" mode="out-in">
<a-input <div v-if="passwordProtected" class="pl-6 flex gap-2 mt-2 mb-4">
v-model:value="shared.password" <a-input
data-cy="nc-modal-share-view__password" v-model:value="shared.password"
size="small" data-cy="nc-modal-share-view__password"
class="!text-xs max-w-[250px]" size="small"
type="password" class="!text-xs max-w-[250px]"
:placeholder="$t('placeholder.password.enter')" type="password"
/> :placeholder="$t('placeholder.password.enter')"
/>
<a-button data-cy="nc-modal-share-view__save-password" size="small" class="!text-xs" @click="saveShareLinkPassword">
{{ $t('placeholder.password.save') }} <a-button
</a-button> data-cy="nc-modal-share-view__save-password"
</div> size="small"
class="!text-xs"
@click="saveShareLinkPassword"
>
{{ $t('placeholder.password.save') }}
</a-button>
</div>
</Transition>
</div> </div>
<div> <div>
@ -279,7 +310,7 @@ watch(passwordProtected, (value) => {
v-if="shared && (shared.type === ViewTypes.GRID || shared.type === ViewTypes.KANBAN)" v-if="shared && (shared.type === ViewTypes.GRID || shared.type === ViewTypes.KANBAN)"
v-model:checked="allowCSVDownload" v-model:checked="allowCSVDownload"
data-cy="nc-modal-share-view__with-csv-download" data-cy="nc-modal-share-view__with-csv-download"
class="!text-xs" class="!text-sm"
> >
{{ $t('labels.downloadAllowed') }} {{ $t('labels.downloadAllowed') }}
</a-checkbox> </a-checkbox>

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

@ -73,6 +73,7 @@ export interface TabItem {
export interface SharedViewMeta extends Record<string, any> { export interface SharedViewMeta extends Record<string, any> {
surveyMode?: boolean surveyMode?: boolean
transitionDuration?: number // in ms
withTheme?: boolean withTheme?: boolean
theme?: Partial<ThemeConfig> theme?: Partial<ThemeConfig>
allowCSVDownload?: boolean allowCSVDownload?: boolean

13
packages/nc-gui/pages/[projectType]/form/[viewId]/index/survey.vue

@ -29,7 +29,8 @@ enum AnimationTarget {
const { md } = useBreakpoints(breakpointsTailwind) const { md } = useBreakpoints(breakpointsTailwind)
const { v$, formState, formColumns, submitForm, submitted, secondsRemain, sharedFormView, onReset } = useSharedFormStoreOrThrow() const { v$, formState, formColumns, submitForm, submitted, secondsRemain, sharedFormView, sharedViewMeta, onReset } =
useSharedFormStoreOrThrow()
const isTransitioning = ref(false) const isTransitioning = ref(false)
@ -43,6 +44,8 @@ const el = ref<HTMLDivElement>()
provide(DropZoneRef, el) provide(DropZoneRef, el)
const transitionDuration = computed(() => sharedViewMeta.value.transitionDuration || 1000)
const steps = computed(() => { const steps = computed(() => {
if (!formColumns.value) return [] if (!formColumns.value) return []
@ -83,13 +86,13 @@ function transition(direction: TransitionDirection) {
setTimeout(() => { setTimeout(() => {
transitionName.value = transitionName.value =
transitionName.value === TransitionDirection.Left ? TransitionDirection.Right : TransitionDirection.Left transitionName.value === TransitionDirection.Left ? TransitionDirection.Right : TransitionDirection.Left
}, 500) }, transitionDuration.value / 2)
setTimeout(() => { setTimeout(() => {
isTransitioning.value = false isTransitioning.value = false
setTimeout(focusInput, 100) setTimeout(focusInput, 100)
}, 1000) }, transitionDuration.value)
} }
function animate(target: AnimationTarget) { function animate(target: AnimationTarget) {
@ -99,7 +102,7 @@ function animate(target: AnimationTarget) {
setTimeout(() => { setTimeout(() => {
isAnimating.value = false isAnimating.value = false
}, 500) }, transitionDuration.value / 2)
} }
async function goNext(animationTarget?: AnimationTarget) { async function goNext(animationTarget?: AnimationTarget) {
@ -212,7 +215,7 @@ onMounted(() => {
</div> </div>
<div class="h-full w-full flex items-center px-4 md:px-0"> <div class="h-full w-full flex items-center px-4 md:px-0">
<Transition :name="`slide-${transitionName}`" :duration="1000" mode="out-in"> <Transition :name="`slide-${transitionName}`" :duration="transitionDuration" mode="out-in">
<div <div
ref="el" ref="el"
:key="field.title" :key="field.title"

Loading…
Cancel
Save