diff --git a/packages/nc-gui/components/cell/Url.vue b/packages/nc-gui/components/cell/Url.vue index 2d9af3343b..16d7f4042b 100644 --- a/packages/nc-gui/components/cell/Url.vue +++ b/packages/nc-gui/components/cell/Url.vue @@ -2,7 +2,7 @@ import type { VNodeRef } from '@vue/runtime-core' import { message } from 'ant-design-vue' import { useI18n } from 'vue-i18n' -import { ColumnInj, EditModeInj, computed, inject, isValidURL } from '#imports' +import { CellUrlDisableOverlayInj, ColumnInj, EditModeInj, computed, inject, isValidURL, ref } from '#imports' import MiCircleWarning from '~icons/mi/circle-warning' const { modelValue: value } = defineProps() @@ -16,6 +16,7 @@ const column = inject(ColumnInj)! const editEnabled = inject(EditModeInj)! +const disableOverlay = inject(CellUrlDisableOverlayInj) // Used in the logic of when to display error since we are not storing the url if its not valid const localState = ref(value) @@ -39,6 +40,7 @@ const url = computed(() => { return `https://${value}` }) +const urlOptions = useCellUrlConfig(url) const focus: VNodeRef = (el) => (el as HTMLInputElement)?.focus() @@ -59,7 +61,22 @@ watch(
- {{ value }} + + {{ value }} + + + {{ urlOptions.overlay }} + {{ value }} diff --git a/packages/nc-gui/components/smartsheet/Grid.vue b/packages/nc-gui/components/smartsheet/Grid.vue index 5389221ce0..ed0d0f4831 100644 --- a/packages/nc-gui/components/smartsheet/Grid.vue +++ b/packages/nc-gui/components/smartsheet/Grid.vue @@ -5,6 +5,7 @@ import { message } from 'ant-design-vue' import { useI18n } from 'vue-i18n' import { ActiveViewInj, + CellUrlDisableOverlayInj, ChangePageInj, FieldsInj, IsFormInj, @@ -109,6 +110,9 @@ provide(ChangePageInj, changePage) provide(ReadonlyInj, !hasEditPermission) +const disableUrlOverlay = ref(false) +provide(CellUrlDisableOverlayInj, disableUrlOverlay) + reloadViewDataHook?.on(async () => { await loadData() }) @@ -201,6 +205,10 @@ const makeEditable = (row: Row, col: ColumnType) => { /** handle keypress events */ const onKeyDown = async (e: KeyboardEvent) => { + if (e.key === 'Alt') { + disableUrlOverlay.value = true + return + } if (selected.row === null || selected.col === null) return /** on tab key press navigate through cells */ switch (e.key) { @@ -284,8 +292,14 @@ const onKeyDown = async (e: KeyboardEvent) => { break } } +const onKeyUp = async (e: KeyboardEvent) => { + if (e.key === 'Alt') { + disableUrlOverlay.value = false + } +} useEventListener(document, 'keydown', onKeyDown) +useEventListener(document, 'keyup', onKeyUp) /** On clicking outside of table reset active cell */ const smartTable = ref(null) diff --git a/packages/nc-gui/components/virtual-cell/Lookup.vue b/packages/nc-gui/components/virtual-cell/Lookup.vue index 8c3544f063..afce758a8f 100644 --- a/packages/nc-gui/components/virtual-cell/Lookup.vue +++ b/packages/nc-gui/components/virtual-cell/Lookup.vue @@ -2,7 +2,7 @@ import type { ColumnType, LinkToAnotherRecordType, LookupType } from 'nocodb-sdk' import { RelationTypes, UITypes, isVirtualCol } from 'nocodb-sdk' import type { Ref } from 'vue' -import { CellValueInj, ColumnInj, MetaInj, ReadonlyInj, computed, inject, provide, useColumn, useMetas } from '#imports' +import { CellUrlDisableOverlayInj, CellValueInj, ColumnInj, MetaInj, ReadonlyInj, computed, inject, provide, useColumn, useMetas } from '#imports' const { metas, getMeta } = useMetas() @@ -32,6 +32,7 @@ const lookupColumn = computed( ) provide(MetaInj, lookupTableMeta) +provide(CellUrlDisableOverlayInj, ref(true)) const lookupColumnMetaProps = useColumn(lookupColumn) diff --git a/packages/nc-gui/composables/index.ts b/packages/nc-gui/composables/index.ts index cea4437711..fd818866f4 100644 --- a/packages/nc-gui/composables/index.ts +++ b/packages/nc-gui/composables/index.ts @@ -24,3 +24,4 @@ export * from './useSmartsheetStore' export * from './useLTARStore' export * from './useExpandedFormStore' export * from './useSharedFormViewStore' +export * from './useCellUrlConfig' diff --git a/packages/nc-gui/composables/useCellUrlConfig.ts b/packages/nc-gui/composables/useCellUrlConfig.ts new file mode 100644 index 0000000000..2f6044193d --- /dev/null +++ b/packages/nc-gui/composables/useCellUrlConfig.ts @@ -0,0 +1,48 @@ +import type { ComputedRef } from 'vue' +import { useRoute } from '#imports' + +export interface CellUrlOptions { + behavior?: string + overlay?: string +} + +const parseUrlRules = (serialized: string | undefined): Array<[RegExp, CellUrlOptions]> | undefined => { + if (!serialized) return undefined + try { + const rules: Array<[RegExp, {}]> = Object.entries(JSON.parse(serialized)).map(([key, value]) => [ + new RegExp(key), + value as {}, + ]) + return rules + } catch (err) { + console.error(err) + return undefined + } +} + +const [useProvideCellUrlConfig, useCellUrlGeneralConfig] = useInjectionState(() => { + const route = useRoute() + + return { + behavior: route.query.url_behavior as string | undefined, + overlay: route.query.url_overlay as string | undefined, + rules: parseUrlRules(route.query.url_rules as string), + } +}, 'cell-url-config') + +export { useProvideCellUrlConfig } + +export function useCellUrlConfig(url: ComputedRef) { + const config = useCellUrlGeneralConfig() + if (!config) return undefined + return computed(() => { + const { behavior, overlay, rules } = config + const options = { behavior, overlay } + if (rules && (!behavior || !overlay)) { + for (const [regex, value] of rules) { + if (url.value.match(regex)) return Object.assign(options, value) + } + } + return options + }) +} diff --git a/packages/nc-gui/context/index.ts b/packages/nc-gui/context/index.ts index 3a08d13944..5caebcb1c4 100644 --- a/packages/nc-gui/context/index.ts +++ b/packages/nc-gui/context/index.ts @@ -28,3 +28,4 @@ export const FieldsInj: InjectionKey> = Symbol('fields-injection') export const ViewListInj: InjectionKey> = Symbol('view-list-injection') export const EditModeInj: InjectionKey> = Symbol('edit-mode-injection') export const SharedViewPasswordInj: InjectionKey> = Symbol('shared-view-password-injection') +export const CellUrlDisableOverlayInj: InjectionKey> = Symbol('cell-url-disable-url') diff --git a/packages/nc-gui/pages/[projectType]/view/[viewId].vue b/packages/nc-gui/pages/[projectType]/view/[viewId].vue index 6187bce03c..0b5c7c0810 100644 --- a/packages/nc-gui/pages/[projectType]/view/[viewId].vue +++ b/packages/nc-gui/pages/[projectType]/view/[viewId].vue @@ -8,6 +8,7 @@ import { extractSdkResponseErrorMsg, provide, ref, + useProvideCellUrlConfig, useRoute, useSharedView, } from '#imports' @@ -24,6 +25,8 @@ const reloadEventHook = createEventHook() provide(ReloadViewDataHookInj, reloadEventHook) provide(ReadonlyInj, true) +useProvideCellUrlConfig() + const { loadSharedView } = useSharedView() const showPassword = ref(false)