Browse Source

Merge remote-tracking branch 'humannocode/geodata-prototyping-restart' into geodata-prototyping-restart

pull/4749/head
flisowna 2 years ago
parent
commit
7fdfcb552a
  1. 250
      packages/nc-gui/components/smartsheet/Gallery.vue
  2. 2
      packages/nc-gui/components/smartsheet/Grid.vue
  3. 2
      packages/nc-gui/components/smartsheet/Map.vue
  4. 59
      packages/nc-gui/components/smartsheet/expanded-form/Header.vue
  5. 37
      packages/nc-gui/components/smartsheet/expanded-form/index.vue
  6. 2
      packages/nc-gui/components/smartsheet/header/Menu.vue
  7. 3
      packages/nc-gui/components/smartsheet/toolbar/FieldsMenu.vue
  8. 3
      packages/nc-gui/components/smartsheet/toolbar/MappedBy.vue
  9. 4
      packages/nc-gui/composables/useMapViewDataStore.ts
  10. 14
      packages/nc-gui/composables/useViewColumns.ts
  11. 1
      packages/nc-gui/composables/useViewData.ts
  12. 2
      packages/nc-gui/lang/ar.json
  13. 2
      packages/nc-gui/lang/bn_IN.json
  14. 4
      packages/nc-gui/lang/cs.json
  15. 2
      packages/nc-gui/lang/da.json
  16. 2
      packages/nc-gui/lang/de.json
  17. 2
      packages/nc-gui/lang/en.json
  18. 2
      packages/nc-gui/lang/es.json
  19. 2
      packages/nc-gui/lang/eu.json
  20. 2
      packages/nc-gui/lang/fa.json
  21. 2
      packages/nc-gui/lang/fi.json
  22. 2
      packages/nc-gui/lang/fr.json
  23. 2
      packages/nc-gui/lang/he.json
  24. 2
      packages/nc-gui/lang/hi.json
  25. 2
      packages/nc-gui/lang/hr.json
  26. 2
      packages/nc-gui/lang/id.json
  27. 2
      packages/nc-gui/lang/it.json
  28. 2
      packages/nc-gui/lang/ja.json
  29. 2
      packages/nc-gui/lang/ko.json
  30. 2
      packages/nc-gui/lang/lv.json
  31. 2
      packages/nc-gui/lang/nl.json
  32. 2
      packages/nc-gui/lang/no.json
  33. 2
      packages/nc-gui/lang/pl.json
  34. 2
      packages/nc-gui/lang/pt.json
  35. 2
      packages/nc-gui/lang/pt_BR.json
  36. 2
      packages/nc-gui/lang/ru.json
  37. 2
      packages/nc-gui/lang/sk.json
  38. 2
      packages/nc-gui/lang/sl.json
  39. 2
      packages/nc-gui/lang/sv.json
  40. 2
      packages/nc-gui/lang/th.json
  41. 2
      packages/nc-gui/lang/tr.json
  42. 2
      packages/nc-gui/lang/uk.json
  43. 2
      packages/nc-gui/lang/vi.json
  44. 2
      packages/nc-gui/lang/zh-Hans.json
  45. 2
      packages/nc-gui/lang/zh-Hant.json
  46. 1
      packages/nc-gui/lib/enums.ts
  47. 1
      packages/nc-gui/lib/types.ts
  48. 8
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/helpers/getAst.ts
  49. 6
      packages/nocodb/src/lib/meta/api/publicApis/publicDataExportApis.ts
  50. 1
      packages/nocodb/src/lib/meta/api/viewApis.ts
  51. 32
      packages/nocodb/src/lib/models/MapView.ts
  52. 25
      packages/nocodb/src/lib/models/View.ts
  53. 33
      tests/playwright/pages/Dashboard/ExpandedForm/index.ts
  54. 48
      tests/playwright/tests/expandedFormUrl.spec.ts

250
packages/nc-gui/components/smartsheet/Gallery.vue

@ -51,6 +51,7 @@ const {
galleryData, galleryData,
changePage, changePage,
addEmptyRow, addEmptyRow,
deleteRow,
navigateToSiblingRow, navigateToSiblingRow,
} = useViewData(meta, view) } = useViewData(meta, view)
@ -85,6 +86,30 @@ const isRowEmpty = (record: any, col: any) => {
return Array.isArray(val) && val.length === 0 return Array.isArray(val) && val.length === 0
} }
const { isSqlView } = useSmartsheetStoreOrThrow()
const { isUIAllowed } = useUIPermission()
const hasEditPermission = $computed(() => isUIAllowed('xcDatatableEditable'))
// TODO: extract this code (which is duplicated in grid and gallery) into a separate component
const _contextMenu = ref(false)
const contextMenu = computed({
get: () => _contextMenu.value,
set: (val) => {
if (hasEditPermission) {
_contextMenu.value = val
}
},
})
const contextMenuTarget = ref<{ row: number } | null>(null)
const showContextMenu = (e: MouseEvent, target?: { row: number }) => {
if (isSqlView.value) return
e.preventDefault()
if (target) {
contextMenuTarget.value = target
}
}
const attachments = (record: any): Attachment[] => { const attachments = (record: any): Attachment[] => {
try { try {
if (coverImageColumn?.title && record.row[coverImageColumn.title]) { if (coverImageColumn?.title && record.row[coverImageColumn.title]) {
@ -175,113 +200,138 @@ watch(view, async (nextView) => {
</script> </script>
<template> <template>
<div class="flex flex-col h-full w-full overflow-auto nc-gallery" data-testid="nc-gallery-wrapper"> <a-dropdown
<div class="nc-gallery-container grid gap-2 my-4 px-3"> v-model:visible="contextMenu"
<div v-for="record in data" :key="`record-${record.row.id}`"> :trigger="isSqlView ? [] : ['contextmenu']"
<LazySmartsheetRow :row="record"> overlay-class-name="nc-dropdown-grid-context-menu"
<a-card >
hoverable <template #overlay>
class="!rounded-lg h-full overflow-hidden break-all max-w-[450px]" <a-menu class="shadow !rounded !py-0" @click="contextMenu = false">
:data-testid="`nc-gallery-card-${record.row.id}`" <a-menu-item v-if="contextMenuTarget" @click="deleteRow(contextMenuTarget.row)">
@click="expandFormClick($event, record)" <div v-e="['a:row:delete']" class="nc-project-menu-item">
> <!-- Delete Row -->
<template v-if="galleryData?.fk_cover_image_col_id" #cover> {{ $t('activity.deleteRow') }}
<a-carousel v-if="!reloadAttachments && attachments(record).length" autoplay class="gallery-carousel" arrows> </div>
<template #customPaging> </a-menu-item>
<a>
<div class="pt-[12px]"> <a-menu-item v-if="contextMenuTarget" @click="openNewRecordFormHook.trigger()">
<div></div> <div v-e="['a:row:insert']" class="nc-project-menu-item">
<!-- Insert New Row -->
{{ $t('activity.insertRow') }}
</div>
</a-menu-item>
</a-menu>
</template>
<div class="flex flex-col h-full w-full overflow-auto nc-gallery" data-testid="nc-gallery-wrapper">
<div class="nc-gallery-container grid gap-2 my-4 px-3">
<div v-for="(record, rowIndex) in data" :key="`record-${record.row.id}`">
<LazySmartsheetRow :row="record">
<a-card
hoverable
class="!rounded-lg h-full overflow-hidden break-all max-w-[450px]"
:data-testid="`nc-gallery-card-${record.row.id}`"
@click="expandFormClick($event, record)"
@contextmenu="showContextMenu($event, { row: rowIndex })"
>
<template v-if="galleryData?.fk_cover_image_col_id" #cover>
<a-carousel v-if="!reloadAttachments && attachments(record).length" autoplay class="gallery-carousel" arrows>
<template #customPaging>
<a>
<div class="pt-[12px]">
<div></div>
</div>
</a>
</template>
<template #prevArrow>
<div style="z-index: 1"></div>
</template>
<template #nextArrow>
<div style="z-index: 1"></div>
</template>
<template v-for="(attachment, index) in attachments(record)">
<LazyCellAttachmentImage
v-if="isImage(attachment.title, attachment.mimetype ?? attachment.type)"
:key="`carousel-${record.row.id}-${index}`"
class="h-52 object-contain"
:srcs="getPossibleAttachmentSrc(attachment)"
/>
</template>
</a-carousel>
<MdiFileImageBox v-else class="w-full h-48 my-4 text-cool-gray-200" />
</template>
<div v-for="col in fieldsWithoutCover" :key="`record-${record.row.id}-${col.id}`">
<div
v-if="!isRowEmpty(record, col) || isLTAR(col.uidt)"
class="flex flex-col space-y-1 px-4 mb-6 bg-gray-50 rounded-lg w-full"
>
<div class="flex flex-row w-full justify-start border-b-1 border-gray-100 py-2.5">
<div class="w-full text-gray-600">
<LazySmartsheetHeaderVirtualCell v-if="isVirtualCol(col)" :column="col" :hide-menu="true" />
<LazySmartsheetHeaderCell v-else :column="col" :hide-menu="true" />
</div> </div>
</a>
</template>
<template #prevArrow>
<div style="z-index: 1"></div>
</template>
<template #nextArrow>
<div style="z-index: 1"></div>
</template>
<template v-for="(attachment, index) in attachments(record)">
<LazyCellAttachmentImage
v-if="isImage(attachment.title, attachment.mimetype ?? attachment.type)"
:key="`carousel-${record.row.id}-${index}`"
class="h-52 object-contain"
:srcs="getPossibleAttachmentSrc(attachment)"
/>
</template>
</a-carousel>
<MdiFileImageBox v-else class="w-full h-48 my-4 text-cool-gray-200" />
</template>
<div v-for="col in fieldsWithoutCover" :key="`record-${record.row.id}-${col.id}`">
<div
v-if="!isRowEmpty(record, col) || isLTAR(col.uidt)"
class="flex flex-col space-y-1 px-4 mb-6 bg-gray-50 rounded-lg w-full"
>
<div class="flex flex-row w-full justify-start border-b-1 border-gray-100 py-2.5">
<div class="w-full text-gray-600">
<LazySmartsheetHeaderVirtualCell v-if="isVirtualCol(col)" :column="col" :hide-menu="true" />
<LazySmartsheetHeaderCell v-else :column="col" :hide-menu="true" />
</div> </div>
</div>
<div class="flex flex-row w-full pb-3 pt-2 pl-2 items-center justify-start"> <div class="flex flex-row w-full pb-3 pt-2 pl-2 items-center justify-start">
<LazySmartsheetVirtualCell <LazySmartsheetVirtualCell
v-if="isVirtualCol(col)" v-if="isVirtualCol(col)"
v-model="record.row[col.title]" v-model="record.row[col.title]"
:column="col" :column="col"
:row="record" :row="record"
/> />
<LazySmartsheetCell <LazySmartsheetCell
v-else v-else
v-model="record.row[col.title]" v-model="record.row[col.title]"
:column="col" :column="col"
:edit-enabled="false" :edit-enabled="false"
:read-only="true" :read-only="true"
/> />
</div>
</div> </div>
</div> </div>
</div> </a-card>
</a-card> </LazySmartsheetRow>
</LazySmartsheetRow> </div>
</div> </div>
</div>
<div class="flex-1" /> <div class="flex-1" />
<LazySmartsheetPagination /> <LazySmartsheetPagination />
</div>
<Suspense> </a-dropdown>
<LazySmartsheetExpandedForm
v-if="expandedFormRow && expandedFormDlg" <Suspense>
v-model="expandedFormDlg" <LazySmartsheetExpandedForm
:row="expandedFormRow" v-if="expandedFormRow && expandedFormDlg"
:state="expandedFormRowState" v-model="expandedFormDlg"
:meta="meta" :row="expandedFormRow"
:view="view" :state="expandedFormRowState"
/> :meta="meta"
</Suspense> :view="view"
/>
<Suspense> </Suspense>
<LazySmartsheetExpandedForm
v-if="expandedFormOnRowIdDlg" <Suspense>
:key="route.query.rowId" <LazySmartsheetExpandedForm
v-model="expandedFormOnRowIdDlg" v-if="expandedFormOnRowIdDlg"
:row="{ row: {}, oldRow: {}, rowMeta: {} }" :key="route.query.rowId"
:meta="meta" v-model="expandedFormOnRowIdDlg"
:row-id="route.query.rowId" :row="{ row: {}, oldRow: {}, rowMeta: {} }"
:view="view" :meta="meta"
show-next-prev-icons :row-id="route.query.rowId"
@next="navigateToSiblingRow(NavigateDir.NEXT)" :view="view"
@prev="navigateToSiblingRow(NavigateDir.PREV)" show-next-prev-icons
/> @next="navigateToSiblingRow(NavigateDir.NEXT)"
</Suspense> @prev="navigateToSiblingRow(NavigateDir.PREV)"
</div> />
</Suspense>
</template> </template>
<style scoped> <style scoped>

2
packages/nc-gui/components/smartsheet/Grid.vue

@ -793,7 +793,7 @@ const closeAddColumnDropdown = () => {
class="nc-row-no text-xs text-gray-500" class="nc-row-no text-xs text-gray-500"
:class="{ toggle: !readOnly, hidden: row.rowMeta.selected }" :class="{ toggle: !readOnly, hidden: row.rowMeta.selected }"
> >
{{ rowIndex + 1 }} {{ ((paginationData.page ?? 1) - 1) * 25 + rowIndex + 1 }}
</div> </div>
<div <div
v-if="!readOnly" v-if="!readOnly"

2
packages/nc-gui/components/smartsheet/Map.vue

@ -189,7 +189,6 @@ watch([formattedData, mapMetaData, markersClusterGroupRef], () => {
addMarker(lat, long, row) addMarker(lat, long, row)
}) })
// syncCount()
}) })
watch(view, async (nextView) => { watch(view, async (nextView) => {
@ -201,7 +200,6 @@ watch(view, async (nextView) => {
const count = computed(() => paginationData.value.totalRows) const count = computed(() => paginationData.value.totalRows)
// syncCount()
</script> </script>
<template> <template>

59
packages/nc-gui/components/smartsheet/expanded-form/Header.vue

@ -12,7 +12,7 @@ import {
const props = defineProps<{ view?: ViewType }>() const props = defineProps<{ view?: ViewType }>()
const emit = defineEmits(['cancel']) const emit = defineEmits(['cancel', 'duplicateRow'])
const route = useRoute() const route = useRoute()
@ -72,6 +72,22 @@ useEventListener(document, 'keydown', async (e: KeyboardEvent) => {
} }
} }
}) })
const showDeleteRowModal = ref(false)
const { deleteRowById } = useViewData(meta, ref(props.view))
const onDeleteRowClick = () => {
showDeleteRowModal.value = true
}
const onConfirmDeleteRowClick = async () => {
showDeleteRowModal.value = false
await deleteRowById(primaryKey.value)
reloadTrigger.trigger()
emit('cancel')
message.success('Row deleted')
}
</script> </script>
<template> <template>
@ -127,6 +143,47 @@ useEventListener(document, 'keydown', async (e: KeyboardEvent) => {
</div> </div>
</a-button> </a-button>
<a-dropdown>
<a-button v-e="['c:actions']" class="nc-actions-menu-btn nc-toolbar-btn">
<div class="flex gap-1 items-center">
<!-- More -->
<span class="!text-sm font-weight-medium">{{ $t('general.more') }}</span>
<MdiMenuDown class="text-grey" />
</div>
</a-button>
<template #overlay>
<div class="bg-gray-50 py-2 shadow-lg !border">
<div>
<div
v-e="['a:actions:duplicate-row']"
class="nc-menu-item"
:class="{ disabled: isNew }"
@click="!isNew && emit('duplicateRow')"
>
<MdiContentCopy class="text-gray-500" />
{{ $t('activity.duplicateRow') }}
</div>
<a-modal v-model:visible="showDeleteRowModal" title="Delete row?" @ok="onConfirmDeleteRowClick">
<p>Are you sure you want to delete this row?</p>
</a-modal>
<div
v-e="['a:actions:delete-row']"
class="nc-menu-item"
:class="{ disabled: isNew }"
@click="!isNew && onDeleteRowClick()"
>
<MdiDelete class="text-gray-500" />
{{ $t('activity.deleteRow') }}
</div>
</div>
</div>
</template>
</a-dropdown>
<a-dropdown-button class="nc-expand-form-save-btn" type="primary" :disabled="!isUIAllowed('tableRowUpdate')" @click="save"> <a-dropdown-button class="nc-expand-form-save-btn" type="primary" :disabled="!isUIAllowed('tableRowUpdate')" @click="save">
<template #overlay> <template #overlay>
<a-menu class="nc-expand-form-save-dropdown-menu"> <a-menu class="nc-expand-form-save-dropdown-menu">

37
packages/nc-gui/components/smartsheet/expanded-form/index.vue

@ -23,10 +23,6 @@ import {
} from '#imports' } from '#imports'
import type { Row } from '~/lib' import type { Row } from '~/lib'
const props = defineProps<Props>()
const emits = defineEmits(['update:modelValue', 'cancel', 'next', 'prev'])
interface Props { interface Props {
modelValue?: boolean modelValue?: boolean
row: Row row: Row
@ -39,6 +35,12 @@ interface Props {
showNextPrevIcons?: boolean showNextPrevIcons?: boolean
} }
const props = defineProps<Props>()
const emits = defineEmits(['update:modelValue', 'cancel', 'next', 'prev'])
const { t } = useI18n()
const row = ref(props.row) const row = ref(props.row)
const state = toRef(props, 'state') const state = toRef(props, 'state')
@ -60,6 +62,8 @@ provide(MetaInj, meta)
const { commentsDrawer, changedColumns, state: rowState, isNew, loadRow } = useProvideExpandedFormStore(meta, row) const { commentsDrawer, changedColumns, state: rowState, isNew, loadRow } = useProvideExpandedFormStore(meta, row)
const duplicatingRowInProgress = ref(false)
if (props.loadRow) { if (props.loadRow) {
await loadRow() await loadRow()
} }
@ -101,6 +105,23 @@ const onClose = () => {
isExpanded.value = false isExpanded.value = false
} }
const onDuplicateRow = () => {
duplicatingRowInProgress.value = true
const newRow = Object.assign(
{},
{
row: row.value.row,
oldRow: {},
rowMeta: { new: true },
},
)
setTimeout(async () => {
row.value = newRow
duplicatingRowInProgress.value = false
message.success(t('msg.success.rowDuplicatedWithoutSavedYet'))
}, 500)
}
const reloadParentRowHook = inject(ReloadRowDataHookInj, createEventHook()) const reloadParentRowHook = inject(ReloadRowDataHookInj, createEventHook())
// override reload trigger and use it to reload grid and the form itself // override reload trigger and use it to reload grid and the form itself
@ -145,7 +166,7 @@ export default {
class="nc-drawer-expanded-form" class="nc-drawer-expanded-form"
:class="{ active: isExpanded }" :class="{ active: isExpanded }"
> >
<SmartsheetExpandedFormHeader :view="props.view" @cancel="onClose" /> <SmartsheetExpandedFormHeader :view="props.view" @cancel="onClose" @duplicate-row="onDuplicateRow" />
<div class="!bg-gray-100 rounded flex-1 relative"> <div class="!bg-gray-100 rounded flex-1 relative">
<template v-if="props.showNextPrevIcons"> <template v-if="props.showNextPrevIcons">
@ -166,8 +187,12 @@ export default {
<div class="flex h-full nc-form-wrapper items-stretch min-h-[max(70vh,100%)]"> <div class="flex h-full nc-form-wrapper items-stretch min-h-[max(70vh,100%)]">
<div class="flex-1 overflow-auto scrollbar-thin-dull nc-form-fields-container"> <div class="flex-1 overflow-auto scrollbar-thin-dull nc-form-fields-container">
<div class="w-[500px] mx-auto"> <div class="w-[500px] mx-auto">
<div v-if="duplicatingRowInProgress" class="flex items-center justify-center h-[100px]">
<a-spin size="large" />
</div>
<div <div
v-for="(col, i) of fields" v-for="(col, i) of fields"
v-else
v-show="!isVirtualCol(col) || !isNew || col.uidt === UITypes.LinkToAnotherRecord" v-show="!isVirtualCol(col) || !isNew || col.uidt === UITypes.LinkToAnotherRecord"
:key="col.title" :key="col.title"
class="mt-2 py-2" class="mt-2 py-2"
@ -234,9 +259,11 @@ export default {
.nc-next-arrow { .nc-next-arrow {
@apply absolute opacity-70 rounded-full transition-transform transition-background transition-opacity transform bg-white hover:(bg-gray-200) active:(scale-125 opacity-100) text-xl; @apply absolute opacity-70 rounded-full transition-transform transition-background transition-opacity transform bg-white hover:(bg-gray-200) active:(scale-125 opacity-100) text-xl;
} }
.nc-prev-arrow { .nc-prev-arrow {
@apply left-4 top-4; @apply left-4 top-4;
} }
.nc-next-arrow { .nc-next-arrow {
@apply right-4 top-4; @apply right-4 top-4;
} }

2
packages/nc-gui/components/smartsheet/header/Menu.vue

@ -280,7 +280,7 @@ const hideField = async () => {
</a-menu-item> </a-menu-item>
<a-divider class="!my-0" /> <a-divider class="!my-0" />
<a-menu-item v-if="!virtual && !column?.pv" @click="setAsPrimaryValue"> <a-menu-item v-if="(!virtual || column?.uidt === UITypes.Formula) && !column?.pv" @click="setAsPrimaryValue">
<div class="nc-column-set-primary nc-header-menu-item"> <div class="nc-column-set-primary nc-header-menu-item">
<MdiStar class="text-primary" /> <MdiStar class="text-primary" />

3
packages/nc-gui/components/smartsheet/toolbar/FieldsMenu.vue

@ -55,6 +55,8 @@ const { eventBus } = useSmartsheetStoreOrThrow()
eventBus.on((event) => { eventBus.on((event) => {
if (event === SmartsheetStoreEvents.FIELD_RELOAD) { if (event === SmartsheetStoreEvents.FIELD_RELOAD) {
loadViewColumns() loadViewColumns()
} else if (event === SmartsheetStoreEvents.MAPPED_BY_COLUMN_CHANGE) {
loadViewColumns()
} }
}) })
@ -204,6 +206,7 @@ useMenuCloseOnEsc(open)
v-model:checked="field.show" v-model:checked="field.show"
v-e="['a:fields:show-hide']" v-e="['a:fields:show-hide']"
class="shrink" class="shrink"
:disabled="field.isViewEssentialField"
@change="saveOrUpdate(field, index)" @change="saveOrUpdate(field, index)"
> >
<div class="flex items-center"> <div class="flex items-center">

3
packages/nc-gui/components/smartsheet/toolbar/MappedBy.vue

@ -14,6 +14,8 @@ import {
watch, watch,
} from '#imports' } from '#imports'
const { eventBus } = useSmartsheetStoreOrThrow()
const meta = inject(MetaInj, ref()) const meta = inject(MetaInj, ref())
const activeView = inject(ActiveViewInj, ref()) const activeView = inject(ActiveViewInj, ref())
@ -48,6 +50,7 @@ const geoDataMappingFieldColumnId = computed({
await loadMapMeta() await loadMapMeta()
await loadMapData() await loadMapData()
;(activeView.value?.view as MapType).fk_geo_data_col_id = val ;(activeView.value?.view as MapType).fk_geo_data_col_id = val
eventBus.emit(SmartsheetStoreEvents.MAPPED_BY_COLUMN_CHANGE)
} }
}, },
}) })

4
packages/nc-gui/composables/useMapViewDataStore.ts

@ -61,17 +61,13 @@ const [useProvideMapViewStore, useMapViewStore] = useInjectionState(
})) }))
async function syncCount() { async function syncCount() {
// const shouldUpdateRowsCounter = !isPublic.value
// if (shouldUpdateRowsCounter) {
const { count } = await $api.dbViewRow.count( const { count } = await $api.dbViewRow.count(
NOCO, NOCO,
project?.value?.title as string, project?.value?.title as string,
meta?.value?.id as string, meta?.value?.id as string,
viewMeta?.value?.id as string, viewMeta?.value?.id as string,
) )
console.log('in Sync')
paginationData.value.totalRows = count paginationData.value.totalRows = count
// }
} }
async function loadMapMeta() { async function loadMapMeta() {

14
packages/nc-gui/composables/useViewColumns.ts

@ -1,4 +1,4 @@
import { isSystemColumn } from 'nocodb-sdk' import { isSystemColumn, MapType, ViewTypes } from 'nocodb-sdk'
import type { ColumnType, TableType, ViewType } from 'nocodb-sdk' import type { ColumnType, TableType, ViewType } from 'nocodb-sdk'
import type { ComputedRef, Ref } from 'vue' import type { ComputedRef, Ref } from 'vue'
import { IsPublicInj, computed, inject, ref, useNuxtApp, useProject, useUIPermission, watch } from '#imports' import { IsPublicInj, computed, inject, ref, useNuxtApp, useProject, useUIPermission, watch } from '#imports'
@ -25,6 +25,13 @@ export function useViewColumns(
() => isPublic.value || !isUIAllowed('hideAllColumns') || !isUIAllowed('showAllColumns') || isSharedBase.value, () => isPublic.value || !isUIAllowed('hideAllColumns') || !isUIAllowed('showAllColumns') || isSharedBase.value,
) )
const isColumnViewEssential = (column: ColumnType) => {
// TODO: consider at some point ti delegate this via a cleaner design pattern to view specific check logic
// which could be inside of a view specific helper class (and generalized via an interface)
// (on the other hand, the logic complexity is still very low atm - might be overkill)
return view.value?.type === ViewTypes.MAP && (view.value?.view as MapType)?.fk_geo_data_col_id === column.id
}
const metaColumnById = computed<Record<string, ColumnType>>(() => { const metaColumnById = computed<Record<string, ColumnType>>(() => {
if (!meta.value?.columns) return {} if (!meta.value?.columns) return {}
@ -38,6 +45,7 @@ export function useViewColumns(
}) })
const loadViewColumns = async () => { const loadViewColumns = async () => {
if (!meta || !view) return if (!meta || !view) return
let order = 1 let order = 1
@ -62,8 +70,10 @@ export function useViewColumns(
title: column.title, title: column.title,
fk_column_id: column.id, fk_column_id: column.id,
...currentColumnField, ...currentColumnField,
show: currentColumnField.show || isColumnViewEssential(currentColumnField),
order: currentColumnField.order || order++, order: currentColumnField.order || order++,
system: isSystemColumn(metaColumnById?.value?.[currentColumnField.fk_column_id!]), system: isSystemColumn(metaColumnById?.value?.[currentColumnField.fk_column_id!]),
isViewEssentialField: isColumnViewEssential(column),
} }
}) })
.sort((a: Field, b: Field) => a.order - b.order) .sort((a: Field, b: Field) => a.order - b.order)
@ -98,7 +108,7 @@ export function useViewColumns(
if (isLocalMode.value) { if (isLocalMode.value) {
fields.value = fields.value?.map((field: Field) => ({ fields.value = fields.value?.map((field: Field) => ({
...field, ...field,
show: false, show: !!field.isViewEssentialField,
})) }))
reloadData?.() reloadData?.()
return return

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

@ -546,5 +546,6 @@ export function useViewData(
removeLastEmptyRow, removeLastEmptyRow,
removeRowIfNew, removeRowIfNew,
navigateToSiblingRow, navigateToSiblingRow,
deleteRowById,
} }
} }

2
packages/nc-gui/lang/ar.json

@ -387,6 +387,7 @@
"saveAndStay": "Save & Stay", "saveAndStay": "Save & Stay",
"insertRow": "إدراج صف جديد", "insertRow": "إدراج صف جديد",
"deleteRow": "حذف الصف", "deleteRow": "حذف الصف",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "حذف الصفوف المحددة", "deleteSelectedRow": "حذف الصفوف المحددة",
"importExcel": "استيراد Excel", "importExcel": "استيراد Excel",
"importCSV": "استيراد CSV", "importCSV": "استيراد CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Column duplicated successfully", "columnDuplicated": "Column duplicated successfully",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "تم تحديث ACL واجهة المستخدم للجداول بنجاح", "updatedUIACL": "تم تحديث ACL واجهة المستخدم للجداول بنجاح",
"pluginUninstalled": "تم إلغاء تثبيت الإضافة بنجاح", "pluginUninstalled": "تم إلغاء تثبيت الإضافة بنجاح",
"pluginSettingsSaved": "تم حفظ إعدادات الإضافة بنجاح", "pluginSettingsSaved": "تم حفظ إعدادات الإضافة بنجاح",

2
packages/nc-gui/lang/bn_IN.json

@ -387,6 +387,7 @@
"saveAndStay": "Save & Stay", "saveAndStay": "Save & Stay",
"insertRow": "নতন সিন", "insertRow": "নতন সিন",
"deleteRow": "সিন", "deleteRow": "সিন",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "নিিত সিিন", "deleteSelectedRow": "নিিত সিিন",
"importExcel": "একল আমদি করন", "importExcel": "একল আমদি করন",
"importCSV": "Import CSV", "importCSV": "Import CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Column duplicated successfully", "columnDuplicated": "Column duplicated successfully",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Updated UI ACL for tables successfully", "updatedUIACL": "Updated UI ACL for tables successfully",
"pluginUninstalled": "Plugin uninstalled successfully", "pluginUninstalled": "Plugin uninstalled successfully",
"pluginSettingsSaved": "Plugin settings saved successfully", "pluginSettingsSaved": "Plugin settings saved successfully",

4
packages/nc-gui/lang/cs.json

@ -206,7 +206,7 @@
"advancedSettings": "Pokročilá nastavení", "advancedSettings": "Pokročilá nastavení",
"codeSnippet": "Úryvek kódu", "codeSnippet": "Úryvek kódu",
"keyboardShortcut": "Klávesové zkratky", "keyboardShortcut": "Klávesové zkratky",
"generateRandomName": "Generate Random Name" "generateRandomName": "Vytvořit náhodné jméno"
}, },
"labels": { "labels": {
"createdBy": "Vytvořil/a", "createdBy": "Vytvořil/a",
@ -387,6 +387,7 @@
"saveAndStay": "Uložit a zůstat", "saveAndStay": "Uložit a zůstat",
"insertRow": "Vložit nový řádek", "insertRow": "Vložit nový řádek",
"deleteRow": "Odstranit řádek", "deleteRow": "Odstranit řádek",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Odstranit vybrané řádky", "deleteSelectedRow": "Odstranit vybrané řádky",
"importExcel": "Importovat Excel", "importExcel": "Importovat Excel",
"importCSV": "Importovat CSV", "importCSV": "Importovat CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Sloupec úspěšně duplikován", "columnDuplicated": "Sloupec úspěšně duplikován",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Úspěšná aktualizace uživatelského rozhraní ACL pro tabulky", "updatedUIACL": "Úspěšná aktualizace uživatelského rozhraní ACL pro tabulky",
"pluginUninstalled": "Plugin byl úspěšně odinstalován", "pluginUninstalled": "Plugin byl úspěšně odinstalován",
"pluginSettingsSaved": "Nastavení zásuvného modulu bylo úspěšně uloženo", "pluginSettingsSaved": "Nastavení zásuvného modulu bylo úspěšně uloženo",

2
packages/nc-gui/lang/da.json

@ -387,6 +387,7 @@
"saveAndStay": "Gem og bliv", "saveAndStay": "Gem og bliv",
"insertRow": "Indsæt ny række", "insertRow": "Indsæt ny række",
"deleteRow": "DELETE ROW.", "deleteRow": "DELETE ROW.",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Slet de valgte rækker", "deleteSelectedRow": "Slet de valgte rækker",
"importExcel": "Import Excel.", "importExcel": "Import Excel.",
"importCSV": "Import CSV.", "importCSV": "Import CSV.",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Kolonne duplikeret med succes", "columnDuplicated": "Kolonne duplikeret med succes",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Opdateret UI ACL for tabeller med succes", "updatedUIACL": "Opdateret UI ACL for tabeller med succes",
"pluginUninstalled": "Plugin afinstalleret med succes", "pluginUninstalled": "Plugin afinstalleret med succes",
"pluginSettingsSaved": "Plugin-indstillingerne er gemt med succes", "pluginSettingsSaved": "Plugin-indstillingerne er gemt med succes",

2
packages/nc-gui/lang/de.json

@ -388,6 +388,7 @@
"saveAndStay": "Speichern & Bleiben", "saveAndStay": "Speichern & Bleiben",
"insertRow": "Neue Zeile einfügen", "insertRow": "Neue Zeile einfügen",
"deleteRow": "Zeile löschen", "deleteRow": "Zeile löschen",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Ausgewählte Zeilen löschen", "deleteSelectedRow": "Ausgewählte Zeilen löschen",
"importExcel": "Excel-Datei importieren", "importExcel": "Excel-Datei importieren",
"importCSV": "CSV-Datei importieren", "importCSV": "CSV-Datei importieren",
@ -717,6 +718,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Spalte erfolgreich dupliziert", "columnDuplicated": "Spalte erfolgreich dupliziert",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "UI ACL für Tabellen erfolgreich aktualisiert", "updatedUIACL": "UI ACL für Tabellen erfolgreich aktualisiert",
"pluginUninstalled": "Plugin erfolgreich deinstalliert", "pluginUninstalled": "Plugin erfolgreich deinstalliert",
"pluginSettingsSaved": "Plugin-Einstellungen erfolgreich gespeichert", "pluginSettingsSaved": "Plugin-Einstellungen erfolgreich gespeichert",

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

@ -388,6 +388,7 @@
"saveAndStay": "Save & Stay", "saveAndStay": "Save & Stay",
"insertRow": "Insert New Row", "insertRow": "Insert New Row",
"deleteRow": "Delete Row", "deleteRow": "Delete Row",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Delete Selected Rows", "deleteSelectedRow": "Delete Selected Rows",
"importExcel": "Import Excel", "importExcel": "Import Excel",
"importCSV": "Import CSV", "importCSV": "Import CSV",
@ -727,6 +728,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Column duplicated successfully", "columnDuplicated": "Column duplicated successfully",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Updated UI ACL for tables successfully", "updatedUIACL": "Updated UI ACL for tables successfully",
"pluginUninstalled": "Plugin uninstalled successfully", "pluginUninstalled": "Plugin uninstalled successfully",
"pluginSettingsSaved": "Plugin settings saved successfully", "pluginSettingsSaved": "Plugin settings saved successfully",

2
packages/nc-gui/lang/es.json

@ -387,6 +387,7 @@
"saveAndStay": "Ahorrar y quedarse", "saveAndStay": "Ahorrar y quedarse",
"insertRow": "Insertar nueva fila", "insertRow": "Insertar nueva fila",
"deleteRow": "Borrar fila", "deleteRow": "Borrar fila",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Eliminar filas seleccionadas", "deleteSelectedRow": "Eliminar filas seleccionadas",
"importExcel": "Importar Excel", "importExcel": "Importar Excel",
"importCSV": "Importar CSV", "importCSV": "Importar CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Columna duplicada con éxito", "columnDuplicated": "Columna duplicada con éxito",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Actualizada con éxito la interfaz de usuario ACL para las tablas", "updatedUIACL": "Actualizada con éxito la interfaz de usuario ACL para las tablas",
"pluginUninstalled": "Plugin desinstalado correctamente", "pluginUninstalled": "Plugin desinstalado correctamente",
"pluginSettingsSaved": "La configuración del plugin se ha guardado correctamente", "pluginSettingsSaved": "La configuración del plugin se ha guardado correctamente",

2
packages/nc-gui/lang/eu.json

@ -387,6 +387,7 @@
"saveAndStay": "Save & Stay", "saveAndStay": "Save & Stay",
"insertRow": "Insert New Row", "insertRow": "Insert New Row",
"deleteRow": "Delete Row", "deleteRow": "Delete Row",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Delete Selected Rows", "deleteSelectedRow": "Delete Selected Rows",
"importExcel": "Import Excel", "importExcel": "Import Excel",
"importCSV": "Import CSV", "importCSV": "Import CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Column duplicated successfully", "columnDuplicated": "Column duplicated successfully",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Updated UI ACL for tables successfully", "updatedUIACL": "Updated UI ACL for tables successfully",
"pluginUninstalled": "Plugin uninstalled successfully", "pluginUninstalled": "Plugin uninstalled successfully",
"pluginSettingsSaved": "Plugin settings saved successfully", "pluginSettingsSaved": "Plugin settings saved successfully",

2
packages/nc-gui/lang/fa.json

@ -387,6 +387,7 @@
"saveAndStay": "Save & Stay", "saveAndStay": "Save & Stay",
"insertRow": "وارد کردن ردیف جدید", "insertRow": "وارد کردن ردیف جدید",
"deleteRow": "حذف ردیف جدید", "deleteRow": "حذف ردیف جدید",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "حذف ردیفهای انتخاب شده", "deleteSelectedRow": "حذف ردیفهای انتخاب شده",
"importExcel": "وارد کردن فایل Excel", "importExcel": "وارد کردن فایل Excel",
"importCSV": "Import CSV", "importCSV": "Import CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Column duplicated successfully", "columnDuplicated": "Column duplicated successfully",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Updated UI ACL for tables successfully", "updatedUIACL": "Updated UI ACL for tables successfully",
"pluginUninstalled": "Plugin uninstalled successfully", "pluginUninstalled": "Plugin uninstalled successfully",
"pluginSettingsSaved": "Plugin settings saved successfully", "pluginSettingsSaved": "Plugin settings saved successfully",

2
packages/nc-gui/lang/fi.json

@ -387,6 +387,7 @@
"saveAndStay": "Save & Stay", "saveAndStay": "Save & Stay",
"insertRow": "Lisää uusi rivi", "insertRow": "Lisää uusi rivi",
"deleteRow": "Poista rivi", "deleteRow": "Poista rivi",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Poista valitut rivit", "deleteSelectedRow": "Poista valitut rivit",
"importExcel": "Tuonti excel", "importExcel": "Tuonti excel",
"importCSV": "Tuo CSV", "importCSV": "Tuo CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Sarake monistettu onnistuneesti", "columnDuplicated": "Sarake monistettu onnistuneesti",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Päivitetty UI ACL taulukoille onnistuneesti", "updatedUIACL": "Päivitetty UI ACL taulukoille onnistuneesti",
"pluginUninstalled": "Liitännäisen poisto onnistui onnistuneesti", "pluginUninstalled": "Liitännäisen poisto onnistui onnistuneesti",
"pluginSettingsSaved": "Liitännäisen asetukset tallennettu onnistuneesti", "pluginSettingsSaved": "Liitännäisen asetukset tallennettu onnistuneesti",

2
packages/nc-gui/lang/fr.json

@ -387,6 +387,7 @@
"saveAndStay": "Enregistrer et rester", "saveAndStay": "Enregistrer et rester",
"insertRow": "Insérer une nouvelle ligne", "insertRow": "Insérer une nouvelle ligne",
"deleteRow": "Supprimer la ligne", "deleteRow": "Supprimer la ligne",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Supprimer les lignes sélectionnées", "deleteSelectedRow": "Supprimer les lignes sélectionnées",
"importExcel": "Importer depuis Excel", "importExcel": "Importer depuis Excel",
"importCSV": "Importer un fichier CSV", "importCSV": "Importer un fichier CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Colonne dupliquée avec succès", "columnDuplicated": "Colonne dupliquée avec succès",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Mise à jour réussie de l'ACL de l'interface utilisateur pour les tables", "updatedUIACL": "Mise à jour réussie de l'ACL de l'interface utilisateur pour les tables",
"pluginUninstalled": "Le plugin a été désinstallé avec succès", "pluginUninstalled": "Le plugin a été désinstallé avec succès",
"pluginSettingsSaved": "Les paramètres du plugin ont été enregistrés avec succès", "pluginSettingsSaved": "Les paramètres du plugin ont été enregistrés avec succès",

2
packages/nc-gui/lang/he.json

@ -387,6 +387,7 @@
"saveAndStay": "Save & Stay", "saveAndStay": "Save & Stay",
"insertRow": "הכנס שורה חדשה", "insertRow": "הכנס שורה חדשה",
"deleteRow": "מחק שורה", "deleteRow": "מחק שורה",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "מחק את השורות שנבחרו", "deleteSelectedRow": "מחק את השורות שנבחרו",
"importExcel": "ייבוא Excel", "importExcel": "ייבוא Excel",
"importCSV": "Import CSV", "importCSV": "Import CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Column duplicated successfully", "columnDuplicated": "Column duplicated successfully",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Updated UI ACL for tables successfully", "updatedUIACL": "Updated UI ACL for tables successfully",
"pluginUninstalled": "Plugin uninstalled successfully", "pluginUninstalled": "Plugin uninstalled successfully",
"pluginSettingsSaved": "Plugin settings saved successfully", "pluginSettingsSaved": "Plugin settings saved successfully",

2
packages/nc-gui/lang/hi.json

@ -387,6 +387,7 @@
"saveAndStay": "Save & Stay", "saveAndStay": "Save & Stay",
"insertRow": "नई पि", "insertRow": "नई पि",
"deleteRow": "पि हट", "deleteRow": "पि हट",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "चयनित पि हट", "deleteSelectedRow": "चयनित पि हट",
"importExcel": "आयत एकल", "importExcel": "आयत एकल",
"importCSV": "Import CSV", "importCSV": "Import CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Column duplicated successfully", "columnDuplicated": "Column duplicated successfully",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Updated UI ACL for tables successfully", "updatedUIACL": "Updated UI ACL for tables successfully",
"pluginUninstalled": "Plugin uninstalled successfully", "pluginUninstalled": "Plugin uninstalled successfully",
"pluginSettingsSaved": "Plugin settings saved successfully", "pluginSettingsSaved": "Plugin settings saved successfully",

2
packages/nc-gui/lang/hr.json

@ -387,6 +387,7 @@
"saveAndStay": "Save & Stay", "saveAndStay": "Save & Stay",
"insertRow": "Umetnite novi red", "insertRow": "Umetnite novi red",
"deleteRow": "Brisanje retka", "deleteRow": "Brisanje retka",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Izbrišite odabrane retke", "deleteSelectedRow": "Izbrišite odabrane retke",
"importExcel": "Uvoz Excel", "importExcel": "Uvoz Excel",
"importCSV": "Import CSV", "importCSV": "Import CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Column duplicated successfully", "columnDuplicated": "Column duplicated successfully",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Updated UI ACL for tables successfully", "updatedUIACL": "Updated UI ACL for tables successfully",
"pluginUninstalled": "Plugin uninstalled successfully", "pluginUninstalled": "Plugin uninstalled successfully",
"pluginSettingsSaved": "Plugin settings saved successfully", "pluginSettingsSaved": "Plugin settings saved successfully",

2
packages/nc-gui/lang/id.json

@ -387,6 +387,7 @@
"saveAndStay": "Simpan & Menginap", "saveAndStay": "Simpan & Menginap",
"insertRow": "Masukkan baris baru.", "insertRow": "Masukkan baris baru.",
"deleteRow": "Hapus Baris", "deleteRow": "Hapus Baris",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Hapus baris yang dipilih", "deleteSelectedRow": "Hapus baris yang dipilih",
"importExcel": "Impor Excel.", "importExcel": "Impor Excel.",
"importCSV": "Impor CSV", "importCSV": "Impor CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Kolom berhasil diduplikasi", "columnDuplicated": "Kolom berhasil diduplikasi",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Berhasil memperbarui ACL UI untuk tabel", "updatedUIACL": "Berhasil memperbarui ACL UI untuk tabel",
"pluginUninstalled": "Plugin berhasil dihapus instalasinya", "pluginUninstalled": "Plugin berhasil dihapus instalasinya",
"pluginSettingsSaved": "Pengaturan plugin berhasil disimpan", "pluginSettingsSaved": "Pengaturan plugin berhasil disimpan",

2
packages/nc-gui/lang/it.json

@ -387,6 +387,7 @@
"saveAndStay": "Risparmia e resta", "saveAndStay": "Risparmia e resta",
"insertRow": "Inserisci nuova riga", "insertRow": "Inserisci nuova riga",
"deleteRow": "Elimina riga.", "deleteRow": "Elimina riga.",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Elimina righe selezionate", "deleteSelectedRow": "Elimina righe selezionate",
"importExcel": "Importa Excel.", "importExcel": "Importa Excel.",
"importCSV": "Importazione CSV", "importCSV": "Importazione CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Colonna duplicata con successo", "columnDuplicated": "Colonna duplicata con successo",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Aggiornamento dell'UI ACL per le tabelle con successo", "updatedUIACL": "Aggiornamento dell'UI ACL per le tabelle con successo",
"pluginUninstalled": "Il plugin è stato disinstallato con successo", "pluginUninstalled": "Il plugin è stato disinstallato con successo",
"pluginSettingsSaved": "Le impostazioni del plugin sono state salvate con successo", "pluginSettingsSaved": "Le impostazioni del plugin sono state salvate con successo",

2
packages/nc-gui/lang/ja.json

@ -387,6 +387,7 @@
"saveAndStay": "保存して続ける", "saveAndStay": "保存して続ける",
"insertRow": "行を挿入", "insertRow": "行を挿入",
"deleteRow": "行を削除", "deleteRow": "行を削除",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "選択行を削除", "deleteSelectedRow": "選択行を削除",
"importExcel": "エクセルファイルをインポート", "importExcel": "エクセルファイルをインポート",
"importCSV": "CSV のインポート", "importCSV": "CSV のインポート",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "カラムを複製しました", "columnDuplicated": "カラムを複製しました",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "テーブルの UI ACL を更新しました", "updatedUIACL": "テーブルの UI ACL を更新しました",
"pluginUninstalled": "プラグインをアンインストールしました", "pluginUninstalled": "プラグインをアンインストールしました",
"pluginSettingsSaved": "プラグインの設定を保存しました", "pluginSettingsSaved": "プラグインの設定を保存しました",

2
packages/nc-gui/lang/ko.json

@ -387,6 +387,7 @@
"saveAndStay": "Save & Stay", "saveAndStay": "Save & Stay",
"insertRow": "행 삽입", "insertRow": "행 삽입",
"deleteRow": "행 삭제", "deleteRow": "행 삭제",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "선택한 행 삭제", "deleteSelectedRow": "선택한 행 삭제",
"importExcel": "엑셀 가져오기", "importExcel": "엑셀 가져오기",
"importCSV": "CSV 가져오기", "importCSV": "CSV 가져오기",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Column duplicated successfully", "columnDuplicated": "Column duplicated successfully",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Updated UI ACL for tables successfully", "updatedUIACL": "Updated UI ACL for tables successfully",
"pluginUninstalled": "Plugin uninstalled successfully", "pluginUninstalled": "Plugin uninstalled successfully",
"pluginSettingsSaved": "Plugin settings saved successfully", "pluginSettingsSaved": "Plugin settings saved successfully",

2
packages/nc-gui/lang/lv.json

@ -387,6 +387,7 @@
"saveAndStay": "Saglabāt un palikt", "saveAndStay": "Saglabāt un palikt",
"insertRow": "Pievienot jaunu ierakstu", "insertRow": "Pievienot jaunu ierakstu",
"deleteRow": "Dzēst ierakstu", "deleteRow": "Dzēst ierakstu",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Dzēst izvēlētos ierakstus", "deleteSelectedRow": "Dzēst izvēlētos ierakstus",
"importExcel": "Importēt Excel", "importExcel": "Importēt Excel",
"importCSV": "CSV importēšana", "importCSV": "CSV importēšana",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Sekmīgi dublēta sleja", "columnDuplicated": "Sekmīgi dublēta sleja",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Veiksmīgi atjaunināts UI ACL tabulām", "updatedUIACL": "Veiksmīgi atjaunināts UI ACL tabulām",
"pluginUninstalled": "Spraudnis veiksmīgi atinstalēts", "pluginUninstalled": "Spraudnis veiksmīgi atinstalēts",
"pluginSettingsSaved": "Veiksmīgi saglabāti spraudņa iestatījumi", "pluginSettingsSaved": "Veiksmīgi saglabāti spraudņa iestatījumi",

2
packages/nc-gui/lang/nl.json

@ -387,6 +387,7 @@
"saveAndStay": "Sparen & Blijven", "saveAndStay": "Sparen & Blijven",
"insertRow": "Voeg nieuwe rij toe", "insertRow": "Voeg nieuwe rij toe",
"deleteRow": "Verwijder rij", "deleteRow": "Verwijder rij",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Verwijder geselecteerde rijen", "deleteSelectedRow": "Verwijder geselecteerde rijen",
"importExcel": "Excel importeren", "importExcel": "Excel importeren",
"importCSV": "CSV importeren", "importCSV": "CSV importeren",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Kolom succesvol gedupliceerd", "columnDuplicated": "Kolom succesvol gedupliceerd",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "UI ACL voor tabellen met succes bijgewerkt", "updatedUIACL": "UI ACL voor tabellen met succes bijgewerkt",
"pluginUninstalled": "Plugin succesvol verwijderd", "pluginUninstalled": "Plugin succesvol verwijderd",
"pluginSettingsSaved": "Plugin-instellingen succesvol opgeslagen", "pluginSettingsSaved": "Plugin-instellingen succesvol opgeslagen",

2
packages/nc-gui/lang/no.json

@ -387,6 +387,7 @@
"saveAndStay": "Save & Stay", "saveAndStay": "Save & Stay",
"insertRow": "Sett inn ny rad", "insertRow": "Sett inn ny rad",
"deleteRow": "Slett rad", "deleteRow": "Slett rad",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Slett utvalgte rader", "deleteSelectedRow": "Slett utvalgte rader",
"importExcel": "Importer Excel.", "importExcel": "Importer Excel.",
"importCSV": "Import CSV", "importCSV": "Import CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Column duplicated successfully", "columnDuplicated": "Column duplicated successfully",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Updated UI ACL for tables successfully", "updatedUIACL": "Updated UI ACL for tables successfully",
"pluginUninstalled": "Plugin uninstalled successfully", "pluginUninstalled": "Plugin uninstalled successfully",
"pluginSettingsSaved": "Plugin settings saved successfully", "pluginSettingsSaved": "Plugin settings saved successfully",

2
packages/nc-gui/lang/pl.json

@ -387,6 +387,7 @@
"saveAndStay": "Oszczędzaj i zostań", "saveAndStay": "Oszczędzaj i zostań",
"insertRow": "Wstaw nowy rząd", "insertRow": "Wstaw nowy rząd",
"deleteRow": "Usuń rząd", "deleteRow": "Usuń rząd",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Usuń wybrane wiersze", "deleteSelectedRow": "Usuń wybrane wiersze",
"importExcel": "Importuj Excel.", "importExcel": "Importuj Excel.",
"importCSV": "Importuj z CSV", "importCSV": "Importuj z CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Kolumna powielona z powodzeniem", "columnDuplicated": "Kolumna powielona z powodzeniem",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Pomyślnie zaktualizowano UI ACL dla tabel", "updatedUIACL": "Pomyślnie zaktualizowano UI ACL dla tabel",
"pluginUninstalled": "Wtyczka odinstalowana pomyślnie", "pluginUninstalled": "Wtyczka odinstalowana pomyślnie",
"pluginSettingsSaved": "Ustawienia wtyczki zapisane pomyślnie", "pluginSettingsSaved": "Ustawienia wtyczki zapisane pomyślnie",

2
packages/nc-gui/lang/pt.json

@ -387,6 +387,7 @@
"saveAndStay": "Salvar & Ficar", "saveAndStay": "Salvar & Ficar",
"insertRow": "Insira a nova linha", "insertRow": "Insira a nova linha",
"deleteRow": "Excluir linha", "deleteRow": "Excluir linha",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Excluir linhas selecionadas", "deleteSelectedRow": "Excluir linhas selecionadas",
"importExcel": "Importar Excel.", "importExcel": "Importar Excel.",
"importCSV": "Importar CSV", "importCSV": "Importar CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Coluna duplicada com sucesso", "columnDuplicated": "Coluna duplicada com sucesso",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "UI ACL actualizada para tabelas com sucesso", "updatedUIACL": "UI ACL actualizada para tabelas com sucesso",
"pluginUninstalled": "Plugin desinstalado com sucesso", "pluginUninstalled": "Plugin desinstalado com sucesso",
"pluginSettingsSaved": "Configurações de plugin guardadas com sucesso", "pluginSettingsSaved": "Configurações de plugin guardadas com sucesso",

2
packages/nc-gui/lang/pt_BR.json

@ -387,6 +387,7 @@
"saveAndStay": "Salvar & Ficar", "saveAndStay": "Salvar & Ficar",
"insertRow": "Insira a nova linha", "insertRow": "Insira a nova linha",
"deleteRow": "Excluir linha", "deleteRow": "Excluir linha",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Excluir linhas selecionadas", "deleteSelectedRow": "Excluir linhas selecionadas",
"importExcel": "Importar Excel.", "importExcel": "Importar Excel.",
"importCSV": "Importar CSV", "importCSV": "Importar CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Coluna duplicada com sucesso", "columnDuplicated": "Coluna duplicada com sucesso",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "UI ACL actualizada para tabelas com sucesso", "updatedUIACL": "UI ACL actualizada para tabelas com sucesso",
"pluginUninstalled": "Plugin desinstalado com sucesso", "pluginUninstalled": "Plugin desinstalado com sucesso",
"pluginSettingsSaved": "Configurações de plugin guardadas com sucesso", "pluginSettingsSaved": "Configurações de plugin guardadas com sucesso",

2
packages/nc-gui/lang/ru.json

@ -387,6 +387,7 @@
"saveAndStay": "Сохранить и остаться", "saveAndStay": "Сохранить и остаться",
"insertRow": "Вставить новую строку", "insertRow": "Вставить новую строку",
"deleteRow": "Удалить строку", "deleteRow": "Удалить строку",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Удалить выбранные строки", "deleteSelectedRow": "Удалить выбранные строки",
"importExcel": "Импорт из Excel", "importExcel": "Импорт из Excel",
"importCSV": "Импорт CSV", "importCSV": "Импорт CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Столбец успешно скопирован", "columnDuplicated": "Столбец успешно скопирован",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Успешно обновлен пользовательский интерфейс ACL для таблиц", "updatedUIACL": "Успешно обновлен пользовательский интерфейс ACL для таблиц",
"pluginUninstalled": "Плагин успешно удален", "pluginUninstalled": "Плагин успешно удален",
"pluginSettingsSaved": "Настройки плагина сохранены", "pluginSettingsSaved": "Настройки плагина сохранены",

2
packages/nc-gui/lang/sk.json

@ -387,6 +387,7 @@
"saveAndStay": "Uložiť a zostať", "saveAndStay": "Uložiť a zostať",
"insertRow": "Vložiť nový riadok", "insertRow": "Vložiť nový riadok",
"deleteRow": "Odstrániť riadok", "deleteRow": "Odstrániť riadok",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Odstránenie vybraných riadkov", "deleteSelectedRow": "Odstránenie vybraných riadkov",
"importExcel": "Importovať aplikáciu Excel", "importExcel": "Importovať aplikáciu Excel",
"importCSV": "Import CSV", "importCSV": "Import CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Stĺpec bol úspešne duplikovaný", "columnDuplicated": "Stĺpec bol úspešne duplikovaný",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Úspešne aktualizované používateľské rozhranie ACL pre tabuľky", "updatedUIACL": "Úspešne aktualizované používateľské rozhranie ACL pre tabuľky",
"pluginUninstalled": "Plugin úspešne odinštalovaný", "pluginUninstalled": "Plugin úspešne odinštalovaný",
"pluginSettingsSaved": "Nastavenia zásuvného modulu boli úspešne uložené", "pluginSettingsSaved": "Nastavenia zásuvného modulu boli úspešne uložené",

2
packages/nc-gui/lang/sl.json

@ -387,6 +387,7 @@
"saveAndStay": "Shranjevanje in bivanje", "saveAndStay": "Shranjevanje in bivanje",
"insertRow": "Vstavite novo vrstico", "insertRow": "Vstavite novo vrstico",
"deleteRow": "Izbriši vrstico", "deleteRow": "Izbriši vrstico",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Izbrišite izbrane vrstice", "deleteSelectedRow": "Izbrišite izbrane vrstice",
"importExcel": "Uvoz Excel.", "importExcel": "Uvoz Excel.",
"importCSV": "Uvoz CSV", "importCSV": "Uvoz CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Stolpec je bil uspešno podvojen", "columnDuplicated": "Stolpec je bil uspešno podvojen",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Uspešno posodobljen uporabniški vmesnik ACL za tabele", "updatedUIACL": "Uspešno posodobljen uporabniški vmesnik ACL za tabele",
"pluginUninstalled": "Vtičnik uspešno odstranjen", "pluginUninstalled": "Vtičnik uspešno odstranjen",
"pluginSettingsSaved": "Nastavitve vtičnika so bile uspešno shranjene", "pluginSettingsSaved": "Nastavitve vtičnika so bile uspešno shranjene",

2
packages/nc-gui/lang/sv.json

@ -387,6 +387,7 @@
"saveAndStay": "Spara och stanna", "saveAndStay": "Spara och stanna",
"insertRow": "Infoga ny rad", "insertRow": "Infoga ny rad",
"deleteRow": "Radera raden", "deleteRow": "Radera raden",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Ta bort valda rader", "deleteSelectedRow": "Ta bort valda rader",
"importExcel": "Import excel", "importExcel": "Import excel",
"importCSV": "Importera CSV", "importCSV": "Importera CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Kolumnen duplicerades framgångsrikt", "columnDuplicated": "Kolumnen duplicerades framgångsrikt",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Uppdaterade UI ACL för tabeller framgångsrikt", "updatedUIACL": "Uppdaterade UI ACL för tabeller framgångsrikt",
"pluginUninstalled": "Plugin avinstallerades framgångsrikt", "pluginUninstalled": "Plugin avinstallerades framgångsrikt",
"pluginSettingsSaved": "Plugin-inställningarna har sparats framgångsrikt", "pluginSettingsSaved": "Plugin-inställningarna har sparats framgångsrikt",

2
packages/nc-gui/lang/th.json

@ -387,6 +387,7 @@
"saveAndStay": "Save & Stay", "saveAndStay": "Save & Stay",
"insertRow": "แทรกแถวใหม", "insertRow": "แทรกแถวใหม",
"deleteRow": "ลบแถว", "deleteRow": "ลบแถว",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "ลบแถวทเลอก", "deleteSelectedRow": "ลบแถวทเลอก",
"importExcel": "นำเขา Excel", "importExcel": "นำเขา Excel",
"importCSV": "Import CSV", "importCSV": "Import CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Column duplicated successfully", "columnDuplicated": "Column duplicated successfully",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Updated UI ACL for tables successfully", "updatedUIACL": "Updated UI ACL for tables successfully",
"pluginUninstalled": "Plugin uninstalled successfully", "pluginUninstalled": "Plugin uninstalled successfully",
"pluginSettingsSaved": "Plugin settings saved successfully", "pluginSettingsSaved": "Plugin settings saved successfully",

2
packages/nc-gui/lang/tr.json

@ -387,6 +387,7 @@
"saveAndStay": "Kaydet ve Kal", "saveAndStay": "Kaydet ve Kal",
"insertRow": "Yeni Satır Ekle", "insertRow": "Yeni Satır Ekle",
"deleteRow": "Satırı Sil", "deleteRow": "Satırı Sil",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Seçilen Satırları Sil", "deleteSelectedRow": "Seçilen Satırları Sil",
"importExcel": "Excel içe aktar", "importExcel": "Excel içe aktar",
"importCSV": "CSV içe aktar", "importCSV": "CSV içe aktar",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Sütun başarıyla çoğaltıldı", "columnDuplicated": "Sütun başarıyla çoğaltıldı",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Tablolar için UI ACL başarıyla güncellendi", "updatedUIACL": "Tablolar için UI ACL başarıyla güncellendi",
"pluginUninstalled": "Eklenti başarıyla kaldırıldı", "pluginUninstalled": "Eklenti başarıyla kaldırıldı",
"pluginSettingsSaved": "Eklenti ayarları başarıyla kaydedildi", "pluginSettingsSaved": "Eklenti ayarları başarıyla kaydedildi",

2
packages/nc-gui/lang/uk.json

@ -387,6 +387,7 @@
"saveAndStay": "Зберегти та залишитись", "saveAndStay": "Зберегти та залишитись",
"insertRow": "Вставити новий рядок", "insertRow": "Вставити новий рядок",
"deleteRow": "Видалити рядок", "deleteRow": "Видалити рядок",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Видалити вибрані рядки", "deleteSelectedRow": "Видалити вибрані рядки",
"importExcel": "Імпортувати з Excel", "importExcel": "Імпортувати з Excel",
"importCSV": "Імпортувати з CSV", "importCSV": "Імпортувати з CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Стовпець успішно продубльовано", "columnDuplicated": "Стовпець успішно продубльовано",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Успішно оновлено UI ACL для таблиць", "updatedUIACL": "Успішно оновлено UI ACL для таблиць",
"pluginUninstalled": "Плагін успішно видалено", "pluginUninstalled": "Плагін успішно видалено",
"pluginSettingsSaved": "Налаштування плагіну успішно збережено", "pluginSettingsSaved": "Налаштування плагіну успішно збережено",

2
packages/nc-gui/lang/vi.json

@ -387,6 +387,7 @@
"saveAndStay": "Save & Stay", "saveAndStay": "Save & Stay",
"insertRow": "Chèn hàng mới", "insertRow": "Chèn hàng mới",
"deleteRow": "Xóa hàng", "deleteRow": "Xóa hàng",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "Xóa các hàng đã chọn", "deleteSelectedRow": "Xóa các hàng đã chọn",
"importExcel": "Nhập Excel.", "importExcel": "Nhập Excel.",
"importCSV": "Import CSV", "importCSV": "Import CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Column duplicated successfully", "columnDuplicated": "Column duplicated successfully",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Updated UI ACL for tables successfully", "updatedUIACL": "Updated UI ACL for tables successfully",
"pluginUninstalled": "Plugin uninstalled successfully", "pluginUninstalled": "Plugin uninstalled successfully",
"pluginSettingsSaved": "Plugin settings saved successfully", "pluginSettingsSaved": "Plugin settings saved successfully",

2
packages/nc-gui/lang/zh-Hans.json

@ -387,6 +387,7 @@
"saveAndStay": "保存并留在此页", "saveAndStay": "保存并留在此页",
"insertRow": "插入新行", "insertRow": "插入新行",
"deleteRow": "删除行", "deleteRow": "删除行",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "删除所选行", "deleteSelectedRow": "删除所选行",
"importExcel": "导入 Excel", "importExcel": "导入 Excel",
"importCSV": "导入 CSV", "importCSV": "导入 CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "此列的副本创建成功", "columnDuplicated": "此列的副本创建成功",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "已成功更新表的 UI ACL", "updatedUIACL": "已成功更新表的 UI ACL",
"pluginUninstalled": "插件卸载成功", "pluginUninstalled": "插件卸载成功",
"pluginSettingsSaved": "插件设置保存成功", "pluginSettingsSaved": "插件设置保存成功",

2
packages/nc-gui/lang/zh-Hant.json

@ -387,6 +387,7 @@
"saveAndStay": "Save & Stay", "saveAndStay": "Save & Stay",
"insertRow": "插入新行", "insertRow": "插入新行",
"deleteRow": "刪除行", "deleteRow": "刪除行",
"duplicateRow": "Duplicate Row",
"deleteSelectedRow": "刪除所選行", "deleteSelectedRow": "刪除所選行",
"importExcel": "匯入 Excel", "importExcel": "匯入 Excel",
"importCSV": "匯入 CSV", "importCSV": "匯入 CSV",
@ -716,6 +717,7 @@
}, },
"success": { "success": {
"columnDuplicated": "Column duplicated successfully", "columnDuplicated": "Column duplicated successfully",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)",
"updatedUIACL": "Updated UI ACL for tables successfully", "updatedUIACL": "Updated UI ACL for tables successfully",
"pluginUninstalled": "外掛移除安裝成功", "pluginUninstalled": "外掛移除安裝成功",
"pluginSettingsSaved": "外掛設定儲存成功", "pluginSettingsSaved": "外掛設定儲存成功",

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

@ -88,6 +88,7 @@ export enum SmartsheetStoreEvents {
DATA_RELOAD = 'data-reload', DATA_RELOAD = 'data-reload',
FIELD_RELOAD = 'field-reload', FIELD_RELOAD = 'field-reload',
FIELD_ADD = 'field-add', FIELD_ADD = 'field-add',
MAPPED_BY_COLUMN_CHANGE = 'mapped-by-column-change',
} }
export enum DataSourcesSubTab { export enum DataSourcesSubTab {

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

@ -32,6 +32,7 @@ export interface Field {
title: string title: string
fk_column_id?: string fk_column_id?: string
system?: boolean system?: boolean
isViewEssentialField?: boolean
} }
export type Roles<T extends Role | ProjectRole = Role | ProjectRole> = Record<T | string, boolean> export type Roles<T extends Role | ProjectRole = Role | ProjectRole> = Record<T | string, boolean>

8
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/helpers/getAst.ts

@ -81,13 +81,13 @@ const getAst = async ({
...(await obj), ...(await obj),
[col.title]: [col.title]:
allowedCols && (!includePkByDefault || !col.pk) allowedCols && (!includePkByDefault || !col.pk)
? allowedCols[col.id] && ? (allowedCols[col.id] &&
(!isSystemColumn(col) || view.show_system_fields) && (!isSystemColumn(col) || view.show_system_fields) &&
(!fields?.length || fields.includes(col.title)) && (!fields?.length || fields.includes(col.title)) &&
value value)
: fields?.length : (fields?.length
? fields.includes(col.title) && value ? fields.includes(col.title) && value
: value, : value),
}; };
}, Promise.resolve({})); }, Promise.resolve({}));
}; };

6
packages/nocodb/src/lib/meta/api/publicApis/publicDataExportApis.ts

@ -19,7 +19,8 @@ async function exportExcel(req: Request, res: Response) {
if ( if (
view.type !== ViewTypes.GRID && view.type !== ViewTypes.GRID &&
view.type !== ViewTypes.KANBAN && view.type !== ViewTypes.KANBAN &&
view.type !== ViewTypes.GALLERY view.type !== ViewTypes.GALLERY &&
view.type !== ViewTypes.MAP
) )
NcError.notFound('Not found'); NcError.notFound('Not found');
@ -67,7 +68,8 @@ async function exportCsv(req: Request, res: Response) {
if ( if (
view.type !== ViewTypes.GRID && view.type !== ViewTypes.GRID &&
view.type !== ViewTypes.KANBAN && view.type !== ViewTypes.KANBAN &&
view.type !== ViewTypes.GALLERY view.type !== ViewTypes.GALLERY &&
view.type !== ViewTypes.MAP
) )
NcError.notFound('Not found'); NcError.notFound('Not found');

1
packages/nocodb/src/lib/meta/api/viewApis.ts

@ -89,6 +89,7 @@ async function showAllColumns(req: Request<any, any>, res) {
} }
async function hideAllColumns(req: Request<any, any>, res) { async function hideAllColumns(req: Request<any, any>, res) {
res.json( res.json(
await View.hideAllColumns( await View.hideAllColumns(
req.params.viewId, req.params.viewId,

32
packages/nocodb/src/lib/models/MapView.ts

@ -3,6 +3,7 @@ import { MapType } from 'nocodb-sdk';
import { CacheGetType, CacheScope, MetaTable } from '../utils/globals'; import { CacheGetType, CacheScope, MetaTable } from '../utils/globals';
import View from './View'; import View from './View';
import NocoCache from '../cache/NocoCache'; import NocoCache from '../cache/NocoCache';
import MapViewColumn from './MapViewColumn';
export default class MapView implements MapType { export default class MapView implements MapType {
fk_view_id: string; fk_view_id: string;
@ -41,21 +42,6 @@ export default class MapView implements MapType {
return view && new MapView(view); return view && new MapView(view);
} }
public static async IsColumnBeingUsedInMapView(
columnId: string,
ncMeta = Noco.ncMeta
) {
return (
(
await ncMeta.metaList2(null, null, MetaTable.MAP_VIEW, {
condition: {
fk_geo_data_col_id: columnId,
},
})
).length > 0
);
}
static async insert(view: Partial<MapView>, ncMeta = Noco.ncMeta) { static async insert(view: Partial<MapView>, ncMeta = Noco.ncMeta) {
const insertObj = { const insertObj = {
project_id: view.project_id, project_id: view.project_id,
@ -65,8 +51,9 @@ export default class MapView implements MapType {
meta: view.meta, meta: view.meta,
}; };
const viewRef = await View.get(view.fk_view_id);
if (!(view.project_id && view.base_id)) { if (!(view.project_id && view.base_id)) {
const viewRef = await View.get(view.fk_view_id);
insertObj.project_id = viewRef.project_id; insertObj.project_id = viewRef.project_id;
insertObj.base_id = viewRef.base_id; insertObj.base_id = viewRef.base_id;
} }
@ -96,6 +83,19 @@ export default class MapView implements MapType {
// set cache // set cache
await NocoCache.set(key, o); await NocoCache.set(key, o);
} }
if (body.fk_geo_data_col_id != null) {
const mapViewColumns = await MapViewColumn.list(mapId);
const mapViewMappedByColumn = mapViewColumns.find(
(mapViewColumn) =>
mapViewColumn.fk_column_id === body.fk_geo_data_col_id
);
await View.updateColumn(body.fk_view_id, mapViewMappedByColumn.id, {
show: true,
});
}
// update meta // update meta
return await ncMeta.metaUpdate(null, null, MetaTable.MAP_VIEW, updateObj, { return await ncMeta.metaUpdate(null, null, MetaTable.MAP_VIEW, updateObj, {
fk_view_id: mapId, fk_view_id: mapId,

25
packages/nocodb/src/lib/models/View.ts

@ -433,9 +433,7 @@ export default class View implements ViewType {
} else { } else {
show = false; show = false;
} }
} } else if (view.type === ViewTypes.KANBAN && !copyFromView) {
else if (view.type === ViewTypes.KANBAN && !copyFromView) {
const kanbanView = await KanbanView.get(view_id, ncMeta); const kanbanView = await KanbanView.get(view_id, ncMeta);
if (vCol.id === kanbanView?.fk_grp_col_id) { if (vCol.id === kanbanView?.fk_grp_col_id) {
// include grouping field if it exists // include grouping field if it exists
@ -452,14 +450,12 @@ export default class View implements ViewType {
// other columns will be hidden // other columns will be hidden
show = false; show = false;
} }
} } else if (view.type === ViewTypes.MAP && !copyFromView) {
else if (view.type === ViewTypes.MAP && !copyFromView) {
const mapView = await MapView.get(view_id, ncMeta); const mapView = await MapView.get(view_id, ncMeta);
if (vCol.id === mapView?.fk_geo_data_col_id) { if (vCol.id === mapView?.fk_geo_data_col_id) {
show = true; show = true;
}
} }
}
// if columns is list of virtual columns then get the parent column // if columns is list of virtual columns then get the parent column
const col = vCol.fk_column_id const col = vCol.fk_column_id
@ -1223,9 +1219,20 @@ export default class View implements ViewType {
// get existing cache // get existing cache
const dataList = await NocoCache.getList(scope, [viewId]); const dataList = await NocoCache.getList(scope, [viewId]);
const colsEssentialForView =
view.type === ViewTypes.MAP
? [(await MapView.get(viewId)).fk_geo_data_col_id]
: [];
const mergedIgnoreColdIds = [...ignoreColdIds, ...colsEssentialForView];
if (dataList?.length) { if (dataList?.length) {
for (const o of dataList) { for (const o of dataList) {
if (!ignoreColdIds?.length || !ignoreColdIds.includes(o.fk_column_id)) { if (
!mergedIgnoreColdIds?.length ||
!mergedIgnoreColdIds.includes(o.fk_column_id)
) {
// set data // set data
o.show = false; o.show = false;
// set cache // set cache
@ -1242,7 +1249,7 @@ export default class View implements ViewType {
{ {
fk_view_id: viewId, fk_view_id: viewId,
}, },
ignoreColdIds?.length mergedIgnoreColdIds?.length
? { ? {
_not: { _not: {
fk_column_id: { fk_column_id: {

33
tests/playwright/pages/Dashboard/ExpandedForm/index.ts

@ -7,6 +7,7 @@ export class ExpandedFormPage extends BasePage {
readonly addNewTableButton: Locator; readonly addNewTableButton: Locator;
readonly copyUrlButton: Locator; readonly copyUrlButton: Locator;
readonly toggleCommentsButton: Locator; readonly toggleCommentsButton: Locator;
readonly moreOptionsButton: Locator;
constructor(dashboard: DashboardPage) { constructor(dashboard: DashboardPage) {
super(dashboard.rootPage); super(dashboard.rootPage);
@ -14,12 +15,44 @@ export class ExpandedFormPage extends BasePage {
this.addNewTableButton = this.dashboard.get().locator('.nc-add-new-table'); this.addNewTableButton = this.dashboard.get().locator('.nc-add-new-table');
this.copyUrlButton = this.dashboard.get().locator('.nc-copy-row-url:visible'); this.copyUrlButton = this.dashboard.get().locator('.nc-copy-row-url:visible');
this.toggleCommentsButton = this.dashboard.get().locator('.nc-toggle-comments:visible'); this.toggleCommentsButton = this.dashboard.get().locator('.nc-toggle-comments:visible');
this.moreOptionsButton = this.dashboard.get().locator('.nc-actions-menu-btn:visible').last();
} }
get() { get() {
return this.dashboard.get().locator(`.nc-drawer-expanded-form`); return this.dashboard.get().locator(`.nc-drawer-expanded-form`);
} }
async clickDuplicateRow() {
await this.moreOptionsButton.click();
// wait for the menu to appear
await this.rootPage.waitForTimeout(1000);
await this.rootPage.locator('.nc-menu-item:has-text("Duplicate Row")').click();
// wait for loader to disappear
// await this.dashboard.waitForLoaderToDisappear();
await this.rootPage.waitForTimeout(2000);
}
async clickDeleteRow() {
await this.moreOptionsButton.click();
// wait for the menu to appear
await this.rootPage.waitForTimeout(1000);
await this.rootPage.locator('.nc-menu-item:has-text("Delete Row")').click();
await this.rootPage.locator('.ant-btn-primary:has-text("OK")').click();
}
async isDisabledDuplicateRow() {
await this.moreOptionsButton.click();
const isDisabled = await this.rootPage.locator('.nc-menu-item.disabled:has-text("Duplicate Row")');
return await isDisabled.count();
}
async isDisabledDeleteRow() {
await this.moreOptionsButton.click();
const isDisabled = await this.rootPage.locator('.nc-menu-item.disabled:has-text("Delete Row")');
return await isDisabled.count();
}
async getShareRowUrl() { async getShareRowUrl() {
await this.copyUrlButton.click(); await this.copyUrlButton.click();
await this.verifyToast({ message: 'Copied to clipboard' }); await this.verifyToast({ message: 'Copied to clipboard' });

48
tests/playwright/tests/expandedFormUrl.spec.ts

@ -1,8 +1,9 @@
import { test } from '@playwright/test'; import { expect, test } from '@playwright/test';
import { DashboardPage } from '../pages/Dashboard'; import { DashboardPage } from '../pages/Dashboard';
import { GalleryPage } from '../pages/Dashboard/Gallery'; import { GalleryPage } from '../pages/Dashboard/Gallery';
import { GridPage } from '../pages/Dashboard/Grid'; import { GridPage } from '../pages/Dashboard/Grid';
import setup from '../setup'; import setup from '../setup';
import { ToolbarPage } from '../pages/Dashboard/common/Toolbar';
test.describe('Expanded form URL', () => { test.describe('Expanded form URL', () => {
let dashboard: DashboardPage; let dashboard: DashboardPage;
@ -132,3 +133,48 @@ test.describe('Expanded form URL', () => {
await viewTestTestTable('gallery'); await viewTestTestTable('gallery');
}); });
}); });
test.describe('Expanded record duplicate & delete options', () => {
let dashboard: DashboardPage, toolbar: ToolbarPage;
let context: any;
test.beforeEach(async ({ page }) => {
context = await setup({ page });
dashboard = new DashboardPage(page, context.project);
toolbar = dashboard.grid.toolbar;
});
test('Grid', async () => {
await dashboard.closeTab({ title: 'Team & Auth' });
await dashboard.treeView.openTable({ title: 'Actor' });
// create filter to narrow down the number of records
await toolbar.clickFilter();
await toolbar.filter.add({
columnTitle: 'FirstName',
opType: 'is equal',
value: 'NICK',
isLocallySaved: false,
});
await toolbar.clickFilter();
await dashboard.grid.verifyRowCount({ count: 3 });
// expand row & duplicate
await dashboard.grid.openExpandedRow({ index: 0 });
await dashboard.expandedForm.clickDuplicateRow();
await dashboard.expandedForm.save();
await dashboard.grid.verifyRowCount({ count: 4 });
// expand row & delete
await dashboard.grid.openExpandedRow({ index: 3 });
await dashboard.expandedForm.clickDeleteRow();
await dashboard.grid.verifyRowCount({ count: 3 });
// expand row, duplicate & verify menu
await dashboard.grid.openExpandedRow({ index: 0 });
await dashboard.expandedForm.clickDuplicateRow();
expect(await dashboard.expandedForm.isDisabledDeleteRow()).toBe(1);
expect(await dashboard.expandedForm.isDisabledDuplicateRow()).toBe(1);
});
});

Loading…
Cancel
Save