diff --git a/packages/nc-gui/components.d.ts b/packages/nc-gui/components.d.ts index 39218772d5..1be206af09 100644 --- a/packages/nc-gui/components.d.ts +++ b/packages/nc-gui/components.d.ts @@ -95,6 +95,8 @@ declare module '@vue/runtime-core' { MaterialSymbolsDarkModeOutline: typeof import('~icons/material-symbols/dark-mode-outline')['default'] MaterialSymbolsFileCopyOutline: typeof import('~icons/material-symbols/file-copy-outline')['default'] MaterialSymbolsKeyboardReturn: typeof import('~icons/material-symbols/keyboard-return')['default'] + MaterialSymbolsKeyboardShift: typeof import('~icons/material-symbols/keyboard-shift')['default'] + MaterialSymbolsLightMode: typeof import('~icons/material-symbols/light-mode')['default'] MaterialSymbolsLightModeOutline: typeof import('~icons/material-symbols/light-mode-outline')['default'] MaterialSymbolsRocketLaunchOutline: typeof import('~icons/material-symbols/rocket-launch-outline')['default'] MaterialSymbolsSendOutline: typeof import('~icons/material-symbols/send-outline')['default'] @@ -131,7 +133,6 @@ declare module '@vue/runtime-core' { MdiChevronDown: typeof import('~icons/mdi/chevron-down')['default'] MdiChevronLeft: typeof import('~icons/mdi/chevron-left')['default'] MdiChevronRight: typeof import('~icons/mdi/chevron-right')['default'] - MdiClipboard: typeof import('~icons/mdi/clipboard')['default'] MdiClose: typeof import('~icons/mdi/close')['default'] MdiCloseBox: typeof import('~icons/mdi/close-box')['default'] MdiCloseCircle: typeof import('~icons/mdi/close-circle')['default'] @@ -142,7 +143,6 @@ declare module '@vue/runtime-core' { MdiCommentTextOutline: typeof import('~icons/mdi/comment-text-outline')['default'] MdiContentCopy: typeof import('~icons/mdi/content-copy')['default'] MdiContentSave: typeof import('~icons/mdi/content-save')['default'] - MdiCopy: typeof import('~icons/mdi/copy')['default'] MdiCurrencyUsd: typeof import('~icons/mdi/currency-usd')['default'] MdiDatabaseOutline: typeof import('~icons/mdi/database-outline')['default'] MdiDatabaseSync: typeof import('~icons/mdi/database-sync')['default'] @@ -180,7 +180,6 @@ declare module '@vue/runtime-core' { MdiInformation: typeof import('~icons/mdi/information')['default'] MdiJson: typeof import('~icons/mdi/json')['default'] MdiKeyboardReturn: typeof import('~icons/mdi/keyboard-return')['default'] - MdiKeyChainVariant: typeof import('~icons/mdi/key-chain-variant')['default'] MdiKeyChange: typeof import('~icons/mdi/key-change')['default'] MdiKeyStar: typeof import('~icons/mdi/key-star')['default'] MdiLink: typeof import('~icons/mdi/link')['default'] @@ -207,7 +206,6 @@ declare module '@vue/runtime-core' { MdiRocketLaunchOutline: typeof import('~icons/mdi/rocket-launch-outline')['default'] MdiScriptTextKeyOutline: typeof import('~icons/mdi/script-text-key-outline')['default'] MdiScriptTextOutline: typeof import('~icons/mdi/script-text-outline')['default'] - MdiShieldAccountOutline: typeof import('~icons/mdi/shield-account-outline')['default'] MdiShieldKeyOutline: typeof import('~icons/mdi/shield-key-outline')['default'] MdiSlack: typeof import('~icons/mdi/slack')['default'] MdiSort: typeof import('~icons/mdi/sort')['default'] diff --git a/packages/nc-gui/components/cell/Email.vue b/packages/nc-gui/components/cell/Email.vue index f7738e109f..c5c20ced60 100644 --- a/packages/nc-gui/components/cell/Email.vue +++ b/packages/nc-gui/components/cell/Email.vue @@ -1,6 +1,6 @@ diff --git a/packages/nc-gui/components/dashboard/TreeView.vue b/packages/nc-gui/components/dashboard/TreeView.vue index 1d6d5ea031..0302a0f553 100644 --- a/packages/nc-gui/components/dashboard/TreeView.vue +++ b/packages/nc-gui/components/dashboard/TreeView.vue @@ -336,6 +336,7 @@ const onSearchCloseIconClick = () => { > +
langs.find((lang) => lang.name === selectedLa const code = $computed(() => { if (activeLang?.name === 'nocodb-sdk') { - return `${selectedClient === 'node' ? 'const { Api } require("nocodb-sdk");' : 'import { Api } from "nocodb-sdk";'} + return `${selectedClient === 'node' ? 'const { Api } = require("nocodb-sdk");' : 'import { Api } from "nocodb-sdk";'} const api = new Api({ - baseURL: ${JSON.stringify(apiUrl)}, + baseURL: "${(appInfo && appInfo.ncSiteUrl) || '/'}", headers: { "xc-auth": ${JSON.stringify(token as string)} } diff --git a/packages/nc-gui/components/smartsheet/Cell.vue b/packages/nc-gui/components/smartsheet/Cell.vue index 12636665a8..dfab72b7fa 100644 --- a/packages/nc-gui/components/smartsheet/Cell.vue +++ b/packages/nc-gui/components/smartsheet/Cell.vue @@ -10,11 +10,36 @@ import { ReadonlyInj, computed, inject, + isAttachment, + isAutoSaved, + isBoolean, + isCurrency, + isDate, + isDateTime, + isDecimal, + isDuration, + isEmail, + isFloat, + isInt, + isJSON, + isManualSaved, + isMultiSelect, + isPercent, + isPhoneNumber, + isPrimary, + isPrimaryKey, + isRating, + isSingleSelect, + isString, + isTextArea, + isTime, + isURL, + isYear, provide, ref, toRef, - useColumn, useDebounceFn, + useProject, useSmartsheetRowStoreOrThrow, useVModel, } from '#imports' @@ -46,9 +71,7 @@ provide(EditModeInj, useVModel(props, 'editEnabled', emit)) provide(ActiveCellInj, active) -if (readOnly?.value) { - provide(ReadonlyInj, readOnly) -} +provide(ReadonlyInj, readOnly) const isForm = inject(IsFormInj, ref(false)) @@ -58,6 +81,10 @@ const isLocked = inject(IsLockedInj, ref(false)) const { currentRow } = useSmartsheetRowStoreOrThrow() +const { sqlUi } = useProject() + +const abstractType = computed(() => column.value && sqlUi.value.getAbstractType(column.value)) + const syncValue = useDebounceFn( () => { currentRow.value.rowMeta.changed = false @@ -66,33 +93,6 @@ const syncValue = useDebounceFn( 500, { maxWait: 2000 }, ) -const { - isPrimary, - isURL, - isEmail, - isJSON, - isDate, - isYear, - isDateTime, - isTime, - isBoolean, - isDuration, - isRating, - isCurrency, - isAttachment, - isTextArea, - isString, - isInt, - isFloat, - isDecimal, - isSingleSelect, - isMultiSelect, - isPercent, - isPhoneNumber, - isAutoSaved, - isManualSaved, - isPrimaryKey, -} = useColumn(column) const vModel = computed({ get: () => props.modelValue, @@ -100,9 +100,9 @@ const vModel = computed({ if (val !== props.modelValue) { currentRow.value.rowMeta.changed = true emit('update:modelValue', val) - if (isAutoSaved.value) { + if (isAutoSaved(column.value)) { syncValue() - } else if (!isManualSaved.value) { + } else if (!isManualSaved(column.value)) { emit('save') currentRow.value.rowMeta.changed = true } @@ -112,7 +112,7 @@ const vModel = computed({ const syncAndNavigate = (dir: NavigateDir, e: KeyboardEvent) => { console.log('syncAndNavigate', e.target) - if (isJSON.value) return + if (isJSON(column.value)) return if (currentRow.value.rowMeta.changed || currentRow.value.rowMeta.new) { emit('save') @@ -127,32 +127,41 @@ const syncAndNavigate = (dir: NavigateDir, e: KeyboardEvent) => { diff --git a/packages/nc-gui/components/smartsheet/Grid.vue b/packages/nc-gui/components/smartsheet/Grid.vue index 7ce1602d06..fcaa154b32 100644 --- a/packages/nc-gui/components/smartsheet/Grid.vue +++ b/packages/nc-gui/components/smartsheet/Grid.vue @@ -524,19 +524,23 @@ provide(ReloadRowDataHookInj, reloadViewDataHook) watch( view, async (next, old) => { - if (next && next.id !== old?.id) { - // whenever tab changes or view changes save any unsaved data - if (old?.id) { - const oldMeta = await getMeta(old.fk_model_id!) - if (oldMeta) { - await saveOrUpdateRecords({ - viewMetaValue: old, - metaValue: oldMeta as TableType, - data: data.value, - }) + try { + if (next && next.id !== old?.id) { + // whenever tab changes or view changes save any unsaved data + if (old?.id) { + const oldMeta = await getMeta(old.fk_model_id!) + if (oldMeta) { + await saveOrUpdateRecords({ + viewMetaValue: old, + metaValue: oldMeta as TableType, + data: data.value, + }) + } } + await loadData() } - await loadData() + } catch (e) { + console.log(e) } }, { immediate: true }, diff --git a/packages/nc-gui/components/smartsheet/VirtualCell.vue b/packages/nc-gui/components/smartsheet/VirtualCell.vue index 9e935f9550..4ab569fbce 100644 --- a/packages/nc-gui/components/smartsheet/VirtualCell.vue +++ b/packages/nc-gui/components/smartsheet/VirtualCell.vue @@ -1,6 +1,22 @@ - - diff --git a/packages/nc-gui/components/smartsheet/header/VirtualCell.vue b/packages/nc-gui/components/smartsheet/header/VirtualCell.vue index f0dc511883..329ccac8a5 100644 --- a/packages/nc-gui/components/smartsheet/header/VirtualCell.vue +++ b/packages/nc-gui/components/smartsheet/header/VirtualCell.vue @@ -7,6 +7,12 @@ import { MetaInj, computed, inject, + isBt, + isFormula, + isHm, + isLookup, + isMm, + isRollup, isVirtualColRequired, provide, ref, @@ -14,7 +20,6 @@ import { useI18n, useMetas, useUIPermission, - useVirtualCell, } from '#imports' const props = defineProps<{ column: ColumnType; hideMenu?: boolean; required?: boolean | number }>() @@ -37,14 +42,12 @@ const meta = inject(MetaInj, ref()) const isForm = inject(IsFormInj, ref(false)) -const { isLookup, isBt, isRollup, isMm, isHm, isFormula } = useVirtualCell(column) - const colOptions = $computed(() => column.value?.colOptions) const tableTile = $computed(() => meta?.value?.title) const relationColumnOptions = $computed(() => { - if (isMm.value || isHm.value || isBt.value) { + if (isMm(column.value) || isHm(column.value) || isBt(column.value)) { return column.value?.colOptions as LinkToAnotherRecordType } else if ((column?.value?.colOptions as LookupType | RollupType)?.fk_relation_column_id) { return meta?.value?.columns?.find( @@ -62,10 +65,10 @@ const relatedTableTitle = $computed(() => relatedTableMeta?.title) const childColumn = $computed(() => { if (relatedTableMeta?.columns) { - if (isRollup.value) { + if (isRollup(column.value)) { return relatedTableMeta?.columns.find((c: ColumnType) => c.id === (colOptions as RollupType).fk_rollup_column_id) } - if (isLookup.value) { + if (isLookup(column.value)) { return relatedTableMeta?.columns.find((c: ColumnType) => c.id === (colOptions as LookupType).fk_lookup_column_id) } } @@ -76,22 +79,22 @@ const tooltipMsg = computed(() => { if (!column.value) { return '' } - if (isHm.value) { + if (isHm(column.value)) { return `'${tableTile}' ${t('labels.hasMany')} '${relatedTableTitle}'` - } else if (isMm.value) { + } else if (isMm(column.value)) { return `'${tableTile}' & '${relatedTableTitle}' ${t('labels.manyToMany')}` - } else if (isBt.value) { + } else if (isBt(column.value)) { return `'${column?.value?.title}' ${t('labels.belongsTo')} '${relatedTableTitle}'` - } else if (isLookup.value) { + } else if (isLookup(column.value)) { return `'${childColumn.title}' from '${relatedTableTitle}' (${childColumn.uidt})` - } else if (isFormula.value) { + } else if (isFormula(column.value)) { const formula = substituteColumnIdWithAliasInFormula( (column.value?.colOptions as FormulaType)?.formula, meta?.value?.columns as ColumnType[], (column.value?.colOptions as any)?.formula_raw, ) return `Formula - ${formula}` - } else if (isRollup.value) { + } else if (isRollup(column.value)) { return `'${childColumn.title}' of '${relatedTableTitle}' (${childColumn.uidt})` } return '' diff --git a/packages/nc-gui/components/smartsheet/header/VirtualCellIcon.vue b/packages/nc-gui/components/smartsheet/header/VirtualCellIcon.ts similarity index 62% rename from packages/nc-gui/components/smartsheet/header/VirtualCellIcon.vue rename to packages/nc-gui/components/smartsheet/header/VirtualCellIcon.ts index 5ad8dee881..029543fb48 100644 --- a/packages/nc-gui/components/smartsheet/header/VirtualCellIcon.vue +++ b/packages/nc-gui/components/smartsheet/header/VirtualCellIcon.ts @@ -1,8 +1,8 @@ - +} + +export default defineComponent({ + name: 'VirtualCellIcon', + props: { + columnMeta: { + type: Object as PropType, + required: false, + }, + }, + setup(props) { + const columnMeta = toRef(props, 'columnMeta') + + const column = inject(ColumnInj, columnMeta) as Ref + + let relationColumn: ColumnType & { colOptions: LookupType } + + return () => { + if (!column.value) return null - + if (column && column.value) { + if (isMm(column.value) || isHm(column.value) || isBt(column.value) || isLookup(column.value) || isRollup(column.value)) { + const meta = inject(MetaInj, ref()) + + relationColumn = meta.value?.columns?.find( + (c) => c.id === column.value?.colOptions?.fk_relation_column_id, + ) as ColumnType & { + colOptions: LinkToAnotherRecordType + } + } + } + + const { icon: Icon, color } = renderIcon(column.value, relationColumn) + + return h(Icon, { class: `${color} mx-1 !text-xs` }) + } + }, +}) diff --git a/packages/nc-gui/components/tabs/auth/UserManagement.vue b/packages/nc-gui/components/tabs/auth/UserManagement.vue index e86dd444c0..05941c2470 100644 --- a/packages/nc-gui/components/tabs/auth/UserManagement.vue +++ b/packages/nc-gui/components/tabs/auth/UserManagement.vue @@ -1,4 +1,5 @@