Browse Source

Merge pull request #3169 from nocodb/fix/3161-form-view-issues

fix(gui-v2): show form items in editable state and handle LTAR columns
pull/3179/head
Raju Udava 2 years ago committed by GitHub
parent
commit
73bcb09be7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      packages/nc-gui-v2/components/cell/DatePicker.vue
  2. 12
      packages/nc-gui-v2/components/cell/DateTimePicker.vue
  3. 17
      packages/nc-gui-v2/components/cell/Json.vue
  4. 9
      packages/nc-gui-v2/components/cell/TimePicker.vue
  5. 10
      packages/nc-gui-v2/components/cell/YearPicker.vue
  6. 19
      packages/nc-gui-v2/components/smartsheet/Form.vue
  7. 6
      packages/nc-gui-v2/components/virtual-cell/BelongsTo.vue
  8. 6
      packages/nc-gui-v2/components/virtual-cell/HasMany.vue
  9. 6
      packages/nc-gui-v2/components/virtual-cell/ManyToMany.vue
  10. 8
      packages/nc-gui-v2/components/virtual-cell/components/ItemChip.vue
  11. 30
      packages/nc-gui-v2/components/virtual-cell/components/ListChildItems.vue
  12. 8
      packages/nc-gui-v2/components/virtual-cell/components/ListItems.vue
  13. 7
      packages/nc-gui-v2/composables/useLTARStore.ts
  14. 7
      packages/nc-gui-v2/composables/useSmartsheetRowStore.ts
  15. 1
      packages/nc-gui-v2/composables/useViewData.ts
  16. 2
      packages/nc-gui-v2/context/index.ts

10
packages/nc-gui-v2/components/cell/DatePicker.vue

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { ColumnInj, EditModeInj, computed, inject, ref, watch } from '#imports' import { ColumnInj, ReadonlyInj, computed, inject, ref, watch } from '#imports'
interface Props { interface Props {
modelValue?: string | null modelValue?: string | null
@ -12,7 +12,7 @@ const emit = defineEmits(['update:modelValue'])
const columnMeta = inject(ColumnInj, null)! const columnMeta = inject(ColumnInj, null)!
const editEnabled = inject(EditModeInj)! const readOnly = inject(ReadonlyInj, false)
let isDateInvalid = $ref(false) let isDateInvalid = $ref(false)
@ -55,7 +55,7 @@ watch(
{ flush: 'post' }, { flush: 'post' },
) )
const placeholder = computed(() => (isDateInvalid ? 'Invalid date' : editEnabled.value ? 'Select date' : '')) const placeholder = computed(() => (isDateInvalid ? 'Invalid date' : readOnly ? 'Select date' : ''))
</script> </script>
<template> <template>
@ -65,10 +65,10 @@ const placeholder = computed(() => (isDateInvalid ? 'Invalid date' : editEnabled
class="!w-full px-1" class="!w-full px-1"
:format="dateFormat" :format="dateFormat"
:placeholder="placeholder" :placeholder="placeholder"
:allow-clear="!editEnabled" :allow-clear="!readOnly"
:input-read-only="true" :input-read-only="true"
:dropdown-class-name="randomClass" :dropdown-class-name="randomClass"
:open="editEnabled ? false : open" :open="readOnly ? false : open"
@click="open = !open" @click="open = !open"
> >
<template #suffixIcon></template> <template #suffixIcon></template>

12
packages/nc-gui-v2/components/cell/DateTimePicker.vue

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { EditModeInj } from '~/context' import { ReadonlyInj } from '#imports'
interface Props { interface Props {
modelValue: string | null | undefined modelValue: string | null | undefined
@ -12,7 +12,7 @@ const emit = defineEmits(['update:modelValue'])
const { isMysql } = useProject() const { isMysql } = useProject()
const editEnabled = inject(EditModeInj) const readOnly = inject(ReadonlyInj, false)
let isDateInvalid = $ref(false) let isDateInvalid = $ref(false)
@ -64,12 +64,12 @@ watch(
:bordered="false" :bordered="false"
class="!w-full px-1" class="!w-full px-1"
format="YYYY-MM-DD HH:mm" format="YYYY-MM-DD HH:mm"
:placeholder="isDateInvalid ? 'Invalid date' : !editEnabled ? 'Select date and time' : ''" :placeholder="isDateInvalid ? 'Invalid date' : !readOnly ? 'Select date and time' : ''"
:allow-clear="!editEnabled" :allow-clear="!readOnly"
:input-read-only="true" :input-read-only="true"
:dropdown-class-name="randomClass" :dropdown-class-name="randomClass"
:open="editEnabled ? false : open" :open="readOnly ? false : open"
:disabled="!editEnabled" :disabled="readOnly"
@click="open = !open" @click="open = !open"
@ok="open = !open" @ok="open = !open"
> >

17
packages/nc-gui-v2/components/cell/Json.vue

@ -2,7 +2,7 @@
import { Modal as AModal } from 'ant-design-vue' import { Modal as AModal } from 'ant-design-vue'
import Editor from '~/components/monaco/Editor.vue' import Editor from '~/components/monaco/Editor.vue'
import { ReadonlyInj, computed, inject, ref, useVModel, watch } from '#imports' import { ReadonlyInj, computed, inject, ref, useVModel, watch } from '#imports'
import { EditModeInj } from '~/context' import { EditModeInj, IsFormInj } from '~/context'
interface Props { interface Props {
modelValue: string | Record<string, any> | undefined modelValue: string | Record<string, any> | undefined
@ -18,22 +18,29 @@ const emits = defineEmits<Emits>()
const editEnabled = inject(EditModeInj, ref(false)) const editEnabled = inject(EditModeInj, ref(false))
const isForm = inject(IsFormInj, ref(false))
const readonly = inject(ReadonlyInj) const readonly = inject(ReadonlyInj)
const vModel = useVModel(props, 'modelValue', emits) const vModel = useVModel(props, 'modelValue', emits)
const localValueState = ref<string | undefined>() const localValueState = ref<string | undefined>()
let error = $ref<string | undefined>()
let isExpanded = $ref(false)
const localValue = computed<string | Record<string, any> | undefined>({ const localValue = computed<string | Record<string, any> | undefined>({
get: () => localValueState.value, get: () => localValueState.value,
set: (val: undefined | string | Record<string, any>) => { set: (val: undefined | string | Record<string, any>) => {
localValueState.value = typeof val === 'object' ? JSON.stringify(val, null, 2) : val localValueState.value = typeof val === 'object' ? JSON.stringify(val, null, 2) : val
/** if form and not expanded then sync directly */
if (isForm.value && !isExpanded) {
vModel.value = val
}
}, },
}) })
let error = $ref<string | undefined>()
let isExpanded = $ref(false)
const clear = () => { const clear = () => {
error = undefined error = undefined
@ -98,7 +105,7 @@ watch(editEnabled, () => {
<CilFullscreen v-else class="h-2.5" /> <CilFullscreen v-else class="h-2.5" />
</a-button> </a-button>
<div class="flex flex-row"> <div v-if="!isForm || isExpanded" class="flex flex-row">
<a-button type="text" size="small" :onclick="clear"><div class="text-xs">Cancel</div></a-button> <a-button type="text" size="small" :onclick="clear"><div class="text-xs">Cancel</div></a-button>
<a-button type="primary" size="small" :disabled="!!error || localValue === vModel"> <a-button type="primary" size="small" :disabled="!!error || localValue === vModel">

9
packages/nc-gui-v2/components/cell/TimePicker.vue

@ -1,7 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { onClickOutside } from '@vueuse/core' import { onClickOutside } from '@vueuse/core'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { EditModeInj } from '~/context'
interface Props { interface Props {
modelValue?: string | null | undefined modelValue?: string | null | undefined
@ -13,7 +12,7 @@ const emit = defineEmits(['update:modelValue'])
const { isMysql } = useProject() const { isMysql } = useProject()
const editEnabled = inject(EditModeInj) const readOnly = inject(ReadonlyInj, false)
let isTimeInvalid = $ref(false) let isTimeInvalid = $ref(false)
@ -76,10 +75,10 @@ watch(
use12-hours use12-hours
format="HH:mm" format="HH:mm"
class="!w-full px-1" class="!w-full px-1"
:placeholder="isTimeInvalid ? 'Invalid time' : !readOnlyMode ? 'Select time' : ''" :placeholder="isTimeInvalid ? 'Invalid time' : !readOnly ? 'Select time' : ''"
:allow-clear="!editEnabled" :allow-clear="!readOnly"
:input-read-only="true" :input-read-only="true"
:open="editEnabled ? false : open" :open="readOnly ? false : open"
:popup-class-name="randomClass" :popup-class-name="randomClass"
@click="open = !open" @click="open = !open"
@ok="open = !open" @ok="open = !open"

10
packages/nc-gui-v2/components/cell/YearPicker.vue

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { EditModeInj, computed, inject, onClickOutside, ref, watch } from '#imports' import { computed, inject, onClickOutside, ref, watch } from '#imports'
interface Props { interface Props {
modelValue?: number | string | null modelValue?: number | string | null
@ -10,7 +10,7 @@ const { modelValue } = defineProps<Props>()
const emit = defineEmits(['update:modelValue']) const emit = defineEmits(['update:modelValue'])
const editEnabled = inject(EditModeInj)! const readOnly = inject(ReadonlyInj, false)
let isYearInvalid = $ref(false) let isYearInvalid = $ref(false)
@ -53,7 +53,7 @@ watch(
{ flush: 'post' }, { flush: 'post' },
) )
const placeholder = computed(() => (isYearInvalid ? 'Invalid year' : editEnabled.value ? 'Select year' : '')) const placeholder = computed(() => (isYearInvalid ? 'Invalid year' : readOnly ? 'Select year' : ''))
</script> </script>
<template> <template>
@ -63,9 +63,9 @@ const placeholder = computed(() => (isYearInvalid ? 'Invalid year' : editEnabled
:bordered="false" :bordered="false"
class="!w-full px-1" class="!w-full px-1"
:placeholder="placeholder" :placeholder="placeholder"
:allow-clear="!editEnabled" :allow-clear="!readOnly"
:input-read-only="true" :input-read-only="true"
:open="editEnabled ? false : open" :open="readOnly ? false : open"
:dropdown-class-name="randomClass" :dropdown-class-name="randomClass"
@click="open = !open" @click="open = !open"
@change="open = !open" @change="open = !open"

19
packages/nc-gui-v2/components/smartsheet/Form.vue

@ -42,7 +42,7 @@ const secondsRemain = ref(0)
const isEditable = isUIAllowed('editFormView' as Permission) const isEditable = isUIAllowed('editFormView' as Permission)
const meta = inject(MetaInj) const meta = inject(MetaInj)!
const view = inject(ActiveViewInj) const view = inject(ActiveViewInj)
@ -53,6 +53,15 @@ const { showAll, hideAll, saveOrUpdate } = useViewColumns(view, meta as any, fal
setFormData() setFormData()
}) })
const { syncLTARRefs } = useProvideSmartsheetRowStore(
meta,
ref({
row: formState,
oldRow: {},
rowMeta: { new: true },
}),
)
const columns = computed(() => meta?.value?.columns || []) const columns = computed(() => meta?.value?.columns || [])
const localColumns = ref<Record<string, any>[]>([]) const localColumns = ref<Record<string, any>[]>([])
@ -92,7 +101,11 @@ async function submitForm() {
return return
} }
await insertRow(formState) const insertedRowData = await insertRow(formState)
if (insertedRowData) {
await syncLTARRefs(insertedRowData)
}
submitted.value = true submitted.value = true
} }
@ -527,6 +540,7 @@ onMounted(async () => {
class="nc-input" class="nc-input"
:class="`nc-form-input-${element.title.replaceAll(' ', '')}`" :class="`nc-form-input-${element.title.replaceAll(' ', '')}`"
:column="element" :column="element"
@click.stop.prevent
/> />
</a-form-item> </a-form-item>
@ -542,6 +556,7 @@ onMounted(async () => {
:class="`nc-form-input-${element.title.replaceAll(' ', '')}`" :class="`nc-form-input-${element.title.replaceAll(' ', '')}`"
:column="element" :column="element"
:edit-enabled="true" :edit-enabled="true"
@click.stop.prevent
/> />
</a-form-item> </a-form-item>

6
packages/nc-gui-v2/components/virtual-cell/BelongsTo.vue

@ -5,7 +5,7 @@ import {
ActiveCellInj, ActiveCellInj,
CellValueInj, CellValueInj,
ColumnInj, ColumnInj,
EditModeInj, ReadonlyInj,
ReloadViewDataHookInj, ReloadViewDataHookInj,
RowInj, RowInj,
defineAsyncComponent, defineAsyncComponent,
@ -31,7 +31,7 @@ const row = inject(RowInj)!
const active = inject(ActiveCellInj)! const active = inject(ActiveCellInj)!
const editEnabled = inject(EditModeInj) const readonly = inject(ReadonlyInj, false)
const listItemsDlg = ref(false) const listItemsDlg = ref(false)
@ -72,7 +72,7 @@ const unlinkRef = async (rec: Record<string, any>) => {
<ItemChip :item="value" :value="value[relatedTablePrimaryValueProp]" @unlink="unlinkRef(value)" /> <ItemChip :item="value" :value="value[relatedTablePrimaryValueProp]" @unlink="unlinkRef(value)" />
</template> </template>
</div> </div>
<div v-if="editEnabled" class="flex-1 flex justify-end gap-1 min-h-[30px] align-center"> <div v-if="!readonly" class="flex-1 flex justify-end gap-1 min-h-[30px] align-center">
<component <component
:is="addIcon" :is="addIcon"
class="text-sm nc-action-icon text-gray-500/50 hover:text-gray-500 select-none group-hover:(text-gray-500)" class="text-sm nc-action-icon text-gray-500/50 hover:text-gray-500 select-none group-hover:(text-gray-500)"

6
packages/nc-gui-v2/components/virtual-cell/HasMany.vue

@ -4,8 +4,8 @@ import type { Ref } from 'vue'
import { import {
CellValueInj, CellValueInj,
ColumnInj, ColumnInj,
EditModeInj,
IsFormInj, IsFormInj,
ReadonlyInj,
ReloadViewDataHookInj, ReloadViewDataHookInj,
RowInj, RowInj,
computed, computed,
@ -32,7 +32,7 @@ const reloadTrigger = inject(ReloadViewDataHookInj)!
const isForm = inject(IsFormInj) const isForm = inject(IsFormInj)
const editEnabled = inject(EditModeInj) const readonly = inject(ReadonlyInj, false)
const listItemsDlg = ref(false) const listItemsDlg = ref(false)
@ -94,7 +94,7 @@ const unlinkRef = async (rec: Record<string, any>) => {
@click="childListDlg = true" @click="childListDlg = true"
/> />
<MdiPlus <MdiPlus
v-if="editEnabled" v-if="!readonly"
class="select-none text-sm nc-action-icon text-gray-500/50 hover:text-gray-500" class="select-none text-sm nc-action-icon text-gray-500/50 hover:text-gray-500"
@click="listItemsDlg = true" @click="listItemsDlg = true"
/> />

6
packages/nc-gui-v2/components/virtual-cell/ManyToMany.vue

@ -4,8 +4,8 @@ import type { Ref } from 'vue'
import { import {
CellValueInj, CellValueInj,
ColumnInj, ColumnInj,
EditModeInj,
IsFormInj, IsFormInj,
ReadonlyInj,
ReloadViewDataHookInj, ReloadViewDataHookInj,
RowInj, RowInj,
computed, computed,
@ -31,7 +31,7 @@ const reloadTrigger = inject(ReloadViewDataHookInj)!
const isForm = inject(IsFormInj) const isForm = inject(IsFormInj)
const editEnabled = inject(EditModeInj) const readonly = inject(ReadonlyInj, false)
const listItemsDlg = ref(false) const listItemsDlg = ref(false)
@ -92,7 +92,7 @@ const unlinkRef = async (rec: Record<string, any>) => {
<MdiArrowExpand class="text-sm nc-action-icon text-gray-500/50 hover:text-gray-500" @click="childListDlg = true" /> <MdiArrowExpand class="text-sm nc-action-icon text-gray-500/50 hover:text-gray-500" @click="childListDlg = true" />
<MdiPlus <MdiPlus
v-if="editEnabled" v-if="!readonly"
class="text-sm nc-action-icon text-gray-500/50 hover:text-gray-500" class="text-sm nc-action-icon text-gray-500/50 hover:text-gray-500"
@click="listItemsDlg = true" @click="listItemsDlg = true"
/> />

8
packages/nc-gui-v2/components/virtual-cell/components/ItemChip.vue

@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ActiveCellInj, EditModeInj, IsFormInj, defineAsyncComponent, inject, ref, useLTARStoreOrThrow } from '#imports' import { ActiveCellInj, IsFormInj, ReadonlyInj, defineAsyncComponent, inject, ref, useLTARStoreOrThrow } from '#imports'
interface Props { interface Props {
value?: string | number | boolean value?: string | number | boolean
@ -14,7 +14,7 @@ const ExpandedForm: any = defineAsyncComponent(() => import('../../smartsheet/ex
const { relatedTableMeta } = useLTARStoreOrThrow()! const { relatedTableMeta } = useLTARStoreOrThrow()!
const editEnabled = inject(EditModeInj)! const readonly = inject(ReadonlyInj, false)
const active = inject(ActiveCellInj, ref(false)) const active = inject(ActiveCellInj, ref(false))
@ -37,13 +37,13 @@ export default {
> >
<span class="name">{{ value }}</span> <span class="name">{{ value }}</span>
<div v-show="active || isForm" v-if="editEnabled" class="flex align-center"> <div v-show="active || isForm" v-if="!readonly" class="flex align-center">
<MdiCloseThick class="unlink-icon text-xs text-gray-500/50 group-hover:text-gray-500" @click.stop="emit('unlink')" /> <MdiCloseThick class="unlink-icon text-xs text-gray-500/50 group-hover:text-gray-500" @click.stop="emit('unlink')" />
</div> </div>
<Suspense> <Suspense>
<ExpandedForm <ExpandedForm
v-if="editEnabled" v-if="!readonly"
v-model="expandedFormDlg" v-model="expandedFormDlg"
:row="{ row: item }" :row="{ row: item }"
:meta="relatedTableMeta" :meta="relatedTableMeta"

30
packages/nc-gui-v2/components/virtual-cell/components/ListChildItems.vue

@ -3,8 +3,8 @@ import { Empty, Modal } from 'ant-design-vue'
import type { ColumnType } from 'nocodb-sdk' import type { ColumnType } from 'nocodb-sdk'
import { import {
ColumnInj, ColumnInj,
EditModeInj,
IsFormInj, IsFormInj,
ReadonlyInj,
computed, computed,
useLTARStoreOrThrow, useLTARStoreOrThrow,
useSmartsheetRowStoreOrThrow, useSmartsheetRowStoreOrThrow,
@ -24,7 +24,7 @@ const isForm = inject(IsFormInj, ref(false))
const column = inject(ColumnInj) const column = inject(ColumnInj)
const editEnabled = inject(EditModeInj) const readonly = inject(ReadonlyInj, false)
const { const {
childrenList, childrenList,
@ -43,7 +43,7 @@ const { isNew, state, removeLTARRef } = useSmartsheetRowStoreOrThrow()
watch( watch(
[vModel, isForm], [vModel, isForm],
(nextVal) => { (nextVal) => {
if (nextVal[0] || nextVal[1]) { if ((nextVal[0] || nextVal[1]) && !isNew.value) {
loadChildrenList() loadChildrenList()
} }
}, },
@ -59,6 +59,12 @@ const unlinkRow = async (row: Record<string, any>) => {
} }
} }
const unlinkIfNewRow = async (row: Record<string, any>) => {
if (isNew.value) {
removeLTARRef(row, column?.value as ColumnType)
}
}
const container = computed(() => const container = computed(() =>
isForm?.value isForm?.value
? h('div', { ? h('div', {
@ -79,7 +85,7 @@ const expandedFormRow = ref()
<MdiReload v-if="!isForm" class="cursor-pointer text-gray-500" @click="loadChildrenList" /> <MdiReload v-if="!isForm" class="cursor-pointer text-gray-500" @click="loadChildrenList" />
<a-button v-if="editEnabled" type="primary" ghost class="!text-xs" size="small" @click="emit('attachRecord')"> <a-button v-if="!readonly" type="primary" ghost class="!text-xs" size="small" @click="emit('attachRecord')">
<div class="flex align-center gap-1"> <div class="flex align-center gap-1">
<MdiLinkVariantRemove class="text-xs" type="primary" @click="unlinkRow(row)" /> <MdiLinkVariantRemove class="text-xs" type="primary" @click="unlinkRow(row)" />
Link to '{{ meta.title }}' Link to '{{ meta.title }}'
@ -101,18 +107,19 @@ const expandedFormRow = ref()
> >
<div class="flex align-center"> <div class="flex align-center">
<div class="flex-grow overflow-hidden min-w-0"> <div class="flex-grow overflow-hidden min-w-0">
{{ row[relatedTablePrimaryValueProp] {{ row[relatedTablePrimaryValueProp] }}
}}<span class="text-gray-400 text-[11px] ml-1">(Primary key : {{ getRelatedTableRowId(row) }})</span> <span class="text-gray-400 text-[11px] ml-1">(Primary key : {{ getRelatedTableRowId(row) }})</span>
</div> </div>
<div class="flex-1"></div> <div class="flex-1"></div>
<div v-if="editEnabled" class="flex gap-2"> <div v-if="!readonly" class="flex gap-2">
<MdiLinkVariantRemove <MdiLinkVariantRemove
class="text-xs text-grey hover:(!text-red-500) cursor-pointer" class="text-xs text-grey hover:(!text-red-500) cursor-pointer"
@click.stop="unlinkRow(row)" @click.stop="unlinkRow(row)"
/> />
<MdiDeleteOutline <MdiDeleteOutline
v-if="!readonly"
class="text-xs text-grey hover:(!text-red-500) cursor-pointer" class="text-xs text-grey hover:(!text-red-500) cursor-pointer"
@click.stop="deleteRelatedRow(row)" @click.stop="deleteRelatedRow(row, unlinkIfNewRow)"
/> />
</div> </div>
</div> </div>
@ -128,7 +135,12 @@ const expandedFormRow = ref()
show-less-items show-less-items
/> />
</template> </template>
<a-empty v-else class="my-10" :image="Empty.PRESENTED_IMAGE_SIMPLE" /> <a-empty
v-else
:class="{ 'my-10': !isForm, 'my-1 !text-xs': isForm }"
:image="Empty.PRESENTED_IMAGE_SIMPLE"
:image-style="isForm ? { height: '20px' } : {}"
/>
</div> </div>
<Suspense> <Suspense>

8
packages/nc-gui-v2/components/virtual-cell/components/ListItems.vue

@ -47,8 +47,12 @@ const linkRow = async (row: Record<string, any>) => {
vModel.value = false vModel.value = false
} }
watch(vModel, () => { /** reload list on modal open */
if (vModel.value) { watch(vModel, (nextVal, prevVal) => {
if (nextVal && !prevVal) {
/** reset query and limit */
childrenExcludedListPagination.query = ''
childrenExcludedListPagination.page = 1
loadChildrenExcludedList() loadChildrenExcludedList()
} }
}) })

7
packages/nc-gui-v2/composables/useLTARStore.ts

@ -139,7 +139,7 @@ const [useProvideLTARStore, useLTARStore] = useInjectionState(
} }
} }
const deleteRelatedRow = async (row: Record<string, any>) => { const deleteRelatedRow = async (row: Record<string, any>, onSuccess?: (row: Record<string, any>) => void) => {
Modal.confirm({ Modal.confirm({
title: 'Do you want to delete the record?', title: 'Do you want to delete the record?',
type: 'warning', type: 'warning',
@ -148,7 +148,12 @@ const [useProvideLTARStore, useLTARStore] = useInjectionState(
try { try {
$api.dbTableRow.delete(NOCO, project.value.id as string, relatedTableMeta.value.id as string, id as string) $api.dbTableRow.delete(NOCO, project.value.id as string, relatedTableMeta.value.id as string, id as string)
reloadData?.() reloadData?.()
/** reload child list if not a new row */
if (!isNewRow?.value) {
await loadChildrenList() await loadChildrenList()
}
onSuccess?.(row)
} catch (e: any) { } catch (e: any) {
message.error(`Delete failed: ${await extractSdkResponseErrorMsg(e)}`) message.error(`Delete failed: ${await extractSdkResponseErrorMsg(e)}`)
} }

7
packages/nc-gui-v2/composables/useSmartsheetRowStore.ts

@ -5,7 +5,7 @@ import type { Ref } from 'vue'
import type { Row } from './useViewData' import type { Row } from './useViewData'
import { useInjectionState, useMetas, useNuxtApp, useProject, useVirtualCell } from '#imports' import { useInjectionState, useMetas, useNuxtApp, useProject, useVirtualCell } from '#imports'
import { NOCO } from '~/lib' import { NOCO } from '~/lib'
import { extractPkFromRow, extractSdkResponseErrorMsg } from '~/utils' import { deepCompare, extractPkFromRow, extractSdkResponseErrorMsg } from '~/utils'
const [useProvideSmartsheetRowStore, useSmartsheetRowStore] = useInjectionState((meta: Ref<TableType>, row: Ref<Row>) => { const [useProvideSmartsheetRowStore, useSmartsheetRowStore] = useInjectionState((meta: Ref<TableType>, row: Ref<Row>) => {
const { $api } = useNuxtApp() const { $api } = useNuxtApp()
@ -23,6 +23,11 @@ const [useProvideSmartsheetRowStore, useSmartsheetRowStore] = useInjectionState(
const { isHm, isMm, isBt } = $(useVirtualCell(ref(column))) const { isHm, isMm, isBt } = $(useVirtualCell(ref(column)))
if (isHm || isMm) { if (isHm || isMm) {
state.value[column.title!] = state.value[column.title!] || [] state.value[column.title!] = state.value[column.title!] || []
if (state.value[column.title!]!.find((ln: Record<string, any>) => deepCompare(ln, value))) {
return message.info('This value is already in the list')
}
state.value[column.title!]!.push(value) state.value[column.title!]!.push(value)
} else if (isBt) { } else if (isBt) {
state.value[column.title!] = value state.value[column.title!] = value

1
packages/nc-gui-v2/composables/useViewData.ts

@ -148,6 +148,7 @@ export function useViewData(
}) })
await syncCount() await syncCount()
return insertedData
} catch (error: any) { } catch (error: any) {
message.error(await extractSdkResponseErrorMsg(error)) message.error(await extractSdkResponseErrorMsg(error))
} }

2
packages/nc-gui-v2/context/index.ts

@ -19,7 +19,7 @@ export const IsGridInj: InjectionKey<boolean> = Symbol('is-grid-injection')
export const IsLockedInj: InjectionKey<boolean> = Symbol('is-locked-injection') export const IsLockedInj: InjectionKey<boolean> = Symbol('is-locked-injection')
export const CellValueInj: InjectionKey<Ref<any>> = Symbol('cell-value-injection') export const CellValueInj: InjectionKey<Ref<any>> = Symbol('cell-value-injection')
export const ActiveViewInj: InjectionKey<Ref<ViewType>> = Symbol('active-view-injection') export const ActiveViewInj: InjectionKey<Ref<ViewType>> = Symbol('active-view-injection')
export const ReadonlyInj: InjectionKey<any> = Symbol('readonly-injection') export const ReadonlyInj: InjectionKey<boolean> = Symbol('readonly-injection')
export const ReloadViewDataHookInj: InjectionKey<EventHook<void>> = Symbol('reload-view-data-injection') export const ReloadViewDataHookInj: InjectionKey<EventHook<void>> = Symbol('reload-view-data-injection')
export const FieldsInj: InjectionKey<Ref<any[]>> = Symbol('fields-injection') export const FieldsInj: InjectionKey<Ref<any[]>> = Symbol('fields-injection')
export const ViewListInj: InjectionKey<Ref<ViewType[]>> = Symbol('view-list-injection') export const ViewListInj: InjectionKey<Ref<ViewType[]>> = Symbol('view-list-injection')

Loading…
Cancel
Save