mirror of
https://github.com/nocodb/nocodb.git
synced 2026-02-01 23:48:33 +00:00
chore: oos changes (#9919)
Signed-off-by: mertmit <mertmit99@gmail.com>
This commit is contained in:
@@ -10,13 +10,20 @@ const visible = useVModel(props, 'visible', emit)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<GeneralModal v-model:visible="visible" size="small">
|
||||
<div class="flex flex-col p-6" @click.stop>
|
||||
<div class="flex flex-row pb-2 mb-4 font-medium text-lg border-b-1 border-gray-50 text-gray-800">Field Type Change</div>
|
||||
<NcModal v-model:visible="visible" size="small" :show-separator="false" :centered="false">
|
||||
<template #header>
|
||||
<div class="flex flex-row items-center gap-x-2">Field Type Change</div>
|
||||
</template>
|
||||
|
||||
<div class="mb-3 text-gray-800">
|
||||
<div class="flex item-center gap-2 mb-4">
|
||||
<component :is="iconMap.warning" id="nc-selected-item-icon" class="text-yellow-500 w-10 h-10" />
|
||||
<div class="flex flex-col" @click.stop>
|
||||
<div
|
||||
class="text-gray-800"
|
||||
:class="{
|
||||
'mb-3': $slots['entity-preview'],
|
||||
}"
|
||||
>
|
||||
<div class="flex item-center gap-2">
|
||||
<GeneralIcon id="nc-selected-item-icon" icon="alertTriangle" class="h-10 w-10 text-yellow-500" />
|
||||
This action cannot be undone. Converting data types may result in data loss. Proceed with caution!
|
||||
</div>
|
||||
</div>
|
||||
@@ -24,13 +31,14 @@ const visible = useVModel(props, 'visible', emit)
|
||||
<slot name="entity-preview"></slot>
|
||||
|
||||
<div class="flex flex-row gap-x-2 mt-2.5 pt-2.5 justify-end">
|
||||
<NcButton type="secondary" @click="visible = false">
|
||||
<NcButton size="small" type="secondary" @click="visible = false">
|
||||
{{ $t('general.cancel') }}
|
||||
</NcButton>
|
||||
|
||||
<NcButton
|
||||
key="submit"
|
||||
autofocus
|
||||
size="small"
|
||||
type="primary"
|
||||
html-type="submit"
|
||||
:loading="saving"
|
||||
@@ -42,5 +50,5 @@ const visible = useVModel(props, 'visible', emit)
|
||||
</NcButton>
|
||||
</div>
|
||||
</div>
|
||||
</GeneralModal>
|
||||
</NcModal>
|
||||
</template>
|
||||
|
||||
@@ -416,6 +416,10 @@ const onClickCopyFieldUrl = async (field: ColumnType) => {
|
||||
|
||||
isFieldIdCopied.value = true
|
||||
}
|
||||
|
||||
const onDeleteColumn = () => {
|
||||
eventBus.emit(SmartsheetStoreEvents.FIELD_RELOAD)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -697,7 +701,7 @@ const onClickCopyFieldUrl = async (field: ColumnType) => {
|
||||
</NcMenu>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
<SmartsheetHeaderDeleteColumnModal v-model:visible="showDeleteColumnModal" />
|
||||
<SmartsheetHeaderDeleteColumnModal v-model:visible="showDeleteColumnModal" :on-delete-column="onDeleteColumn" />
|
||||
<DlgColumnDuplicate
|
||||
v-if="column"
|
||||
ref="duplicateDialogRef"
|
||||
|
||||
@@ -24,7 +24,6 @@ export interface ExtensionManifest {
|
||||
height?: number
|
||||
}
|
||||
}
|
||||
disabled?: boolean
|
||||
links: {
|
||||
title: string
|
||||
href: string
|
||||
@@ -33,6 +32,8 @@ export interface ExtensionManifest {
|
||||
modalSize?: 'xs' | 'sm' | 'md' | 'lg'
|
||||
contentMinHeight?: string
|
||||
}
|
||||
order: number
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
abstract class ExtensionType {
|
||||
|
||||
@@ -264,6 +264,18 @@ onMounted(async () => {
|
||||
|
||||
<template>
|
||||
<ExtensionsExtensionWrapper>
|
||||
<template v-if="fullscreen" #headerExtra>
|
||||
<NcTooltip class="flex" placement="topRight" :disabled="!isExporting">
|
||||
<template #title> The CSV file is being prepared in the background. You'll be notified once it's ready. </template>
|
||||
<NcButton
|
||||
:disabled="!exportPayload?.viewId || isExporting"
|
||||
:loading="isExporting"
|
||||
size="small"
|
||||
@click="exportDataAsync"
|
||||
>{{ isExporting ? 'Generating' : 'Export' }}</NcButton
|
||||
>
|
||||
</NcTooltip>
|
||||
</template>
|
||||
<div
|
||||
ref="dataExporterRef"
|
||||
class="data-exporter"
|
||||
@@ -272,70 +284,12 @@ onMounted(async () => {
|
||||
}"
|
||||
>
|
||||
<div
|
||||
v-if="!fullscreen"
|
||||
class="p-3 flex flex-col gap-3"
|
||||
:class="{
|
||||
'bg-white': fullscreen,
|
||||
}"
|
||||
>
|
||||
<div v-if="fullscreen" class="flex items-center gap-3 max-w-full">
|
||||
<div class="flex flex-col gap-2 w-[calc(50%_-_6px)]">
|
||||
<div>Separator</div>
|
||||
<a-form-item class="!my-0 flex-1">
|
||||
<NcSelect
|
||||
v-model:value="exportPayload.delimiter"
|
||||
placeholder="-select separator-"
|
||||
:disabled="isExporting"
|
||||
class="nc-data-exporter-separator nc-select-shadow"
|
||||
dropdown-class-name="w-[180px]"
|
||||
@change="saveChanges"
|
||||
>
|
||||
<a-select-option v-for="delimiter of csvColumnSeparatorOptions" :key="delimiter.value" :value="delimiter.value">
|
||||
<div class="w-full flex items-center gap-2">
|
||||
<NcTooltip class="flex-1 truncate" show-on-truncate-only>
|
||||
<template #title>{{ delimiter.label }}</template>
|
||||
<span>{{ delimiter.label }}</span>
|
||||
</NcTooltip>
|
||||
<component
|
||||
:is="iconMap.check"
|
||||
v-if="exportPayload.delimiter === delimiter.value"
|
||||
id="nc-selected-item-icon"
|
||||
class="flex-none text-primary w-4 h-4"
|
||||
/>
|
||||
</div>
|
||||
</a-select-option>
|
||||
</NcSelect>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2 w-[calc(50%_-_6px)]">
|
||||
<div class="min-w-[65px]">Encoding</div>
|
||||
<a-form-item class="!my-0 flex-1">
|
||||
<NcSelect
|
||||
v-model:value="exportPayload.encoding"
|
||||
placeholder="-select encoding-"
|
||||
class="nc-data-exporter-encoding nc-select-shadow"
|
||||
dropdown-class-name="w-[190px]"
|
||||
:filter-option="filterOption"
|
||||
show-search
|
||||
@change="saveChanges"
|
||||
>
|
||||
<a-select-option v-for="encoding of charsetOptions" :key="encoding.label" :value="encoding.value">
|
||||
<div class="w-full flex items-center gap-2">
|
||||
<NcTooltip class="flex-1 truncate" show-on-truncate-only>
|
||||
<template #title>{{ encoding.label }}</template>
|
||||
<span>{{ encoding.label }}</span>
|
||||
</NcTooltip>
|
||||
<component
|
||||
:is="iconMap.check"
|
||||
v-if="exportPayload.encoding === encoding.value"
|
||||
id="nc-selected-item-icon"
|
||||
class="flex-none text-primary w-4 h-4"
|
||||
/>
|
||||
</div>
|
||||
</a-select-option>
|
||||
</NcSelect>
|
||||
</a-form-item>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between gap-2.5 flex-wrap">
|
||||
<div
|
||||
class="nc-data-exporter-select-wrapper flex-1 flex items-center border-1 border-nc-border-gray-medium rounded-lg relative shadow-default"
|
||||
@@ -435,112 +389,245 @@ onMounted(async () => {
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="data-exporter-body flex-1 flex flex-col"
|
||||
class="data-exporter-body flex-1 flex"
|
||||
:class="{
|
||||
'rounded-lg border-1 m-3': fullscreen,
|
||||
'': fullscreen,
|
||||
'flex-col': !fullscreen,
|
||||
}"
|
||||
>
|
||||
<div class="data-exporter-header">Recent Exports</div>
|
||||
<div v-if="exportedFiles.length" class="flex-1 flex flex-col nc-scrollbar-thin max-h-[calc(100%_-_25px)]">
|
||||
<template v-for="exp of exportedFiles">
|
||||
<div
|
||||
v-if="exp.status === JobStatus.COMPLETED ? exp.result : true"
|
||||
:key="exp.id"
|
||||
class="p-3 flex gap-2 justify-between border-b-1"
|
||||
:class="{
|
||||
'px-4 py-3': fullscreen,
|
||||
'px-3 py-2': !fullscreen,
|
||||
'bg-white hover:bg-gray-50': exp.status === JobStatus.COMPLETED,
|
||||
'bg-nc-bg-red-light': exp.status !== JobStatus.COMPLETED,
|
||||
}"
|
||||
>
|
||||
<div
|
||||
v-if="fullscreen"
|
||||
class="w-[320px] border-r-1 border-r-nc-border-gray-medium bg-white p-4 pt-t flex flex-col gap-5 nc-scrollbar-thin"
|
||||
>
|
||||
<div class="text-base font-bold text-nc-content-gray-extreme">Settings</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="text-nc-content-gray font-medium">Table</div>
|
||||
<a-form-item class="!my-0">
|
||||
<NcSelect
|
||||
v-model:value="exportPayload.tableId"
|
||||
placeholder="-select table-"
|
||||
:disabled="isExporting"
|
||||
class="nc-data-exporter-table-select-sidebar nc-select-shadow"
|
||||
:filter-option="filterOption"
|
||||
dropdown-class-name="w-[250px]"
|
||||
show-search
|
||||
@change="onTableSelect"
|
||||
>
|
||||
<a-select-option v-for="table of tableList" :key="table.label" :value="table.value">
|
||||
<div class="w-full flex items-center gap-2">
|
||||
<div class="min-w-5 flex items-center justify-center">
|
||||
<GeneralTableIcon :meta="{ meta: table.meta }" class="text-gray-500" />
|
||||
</div>
|
||||
<NcTooltip class="flex-1 truncate" show-on-truncate-only>
|
||||
<template #title>{{ table.label }}</template>
|
||||
<span>{{ table.label }}</span>
|
||||
</NcTooltip>
|
||||
<component
|
||||
:is="iconMap.check"
|
||||
v-if="exportPayload.tableId === table.value"
|
||||
id="nc-selected-item-icon"
|
||||
class="flex-none text-primary w-4 h-4"
|
||||
/>
|
||||
</div>
|
||||
</a-select-option>
|
||||
</NcSelect>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="text-nc-content-gray font-medium">View</div>
|
||||
<a-form-item class="!my-0 min-w-1/2">
|
||||
<NcSelect
|
||||
v-model:value="exportPayload.viewId"
|
||||
placeholder="-select view-"
|
||||
:disabled="isExporting"
|
||||
class="nc-data-exporter-view-select-sidebar nc-select-shadow"
|
||||
dropdown-class-name="w-[250px]"
|
||||
:filter-option="filterOption"
|
||||
show-search
|
||||
placement="bottomRight"
|
||||
@change="onViewSelect"
|
||||
>
|
||||
<a-select-option v-for="view of viewList" :key="view.label" :value="view.value">
|
||||
<div class="w-full flex items-center gap-2">
|
||||
<div class="min-w-5 flex items-center justify-center">
|
||||
<GeneralViewIcon :meta="{ meta: view.meta, type: view.type }" class="flex-none text-gray-500" />
|
||||
</div>
|
||||
<NcTooltip class="flex-1 truncate" show-on-truncate-only>
|
||||
<template #title>{{ view.label }}</template>
|
||||
<span>{{ view.label }}</span>
|
||||
</NcTooltip>
|
||||
<component
|
||||
:is="iconMap.check"
|
||||
v-if="exportPayload.viewId === view.value"
|
||||
id="nc-selected-item-icon"
|
||||
class="flex-none text-primary w-4 h-4"
|
||||
/>
|
||||
</div>
|
||||
</a-select-option>
|
||||
</NcSelect>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<div>Separator</div>
|
||||
<a-form-item class="!my-0 flex-1">
|
||||
<NcSelect
|
||||
v-model:value="exportPayload.delimiter"
|
||||
placeholder="-select separator-"
|
||||
:disabled="isExporting"
|
||||
class="nc-data-exporter-separator nc-select-shadow"
|
||||
dropdown-class-name="w-[180px]"
|
||||
@change="saveChanges"
|
||||
>
|
||||
<a-select-option v-for="delimiter of csvColumnSeparatorOptions" :key="delimiter.value" :value="delimiter.value">
|
||||
<div class="w-full flex items-center gap-2">
|
||||
<NcTooltip class="flex-1 truncate" show-on-truncate-only>
|
||||
<template #title>{{ delimiter.label }}</template>
|
||||
<span>{{ delimiter.label }}</span>
|
||||
</NcTooltip>
|
||||
<component
|
||||
:is="iconMap.check"
|
||||
v-if="exportPayload.delimiter === delimiter.value"
|
||||
id="nc-selected-item-icon"
|
||||
class="flex-none text-primary w-4 h-4"
|
||||
/>
|
||||
</div>
|
||||
</a-select-option>
|
||||
</NcSelect>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="min-w-[65px]">Encoding</div>
|
||||
<a-form-item class="!my-0 flex-1">
|
||||
<NcSelect
|
||||
v-model:value="exportPayload.encoding"
|
||||
placeholder="-select encoding-"
|
||||
class="nc-data-exporter-encoding nc-select-shadow"
|
||||
dropdown-class-name="w-[190px]"
|
||||
:filter-option="filterOption"
|
||||
show-search
|
||||
@change="saveChanges"
|
||||
>
|
||||
<a-select-option v-for="encoding of charsetOptions" :key="encoding.label" :value="encoding.value">
|
||||
<div class="w-full flex items-center gap-2">
|
||||
<NcTooltip class="flex-1 truncate" show-on-truncate-only>
|
||||
<template #title>{{ encoding.label }}</template>
|
||||
<span>{{ encoding.label }}</span>
|
||||
</NcTooltip>
|
||||
<component
|
||||
:is="iconMap.check"
|
||||
v-if="exportPayload.encoding === encoding.value"
|
||||
id="nc-selected-item-icon"
|
||||
class="flex-none text-primary w-4 h-4"
|
||||
/>
|
||||
</div>
|
||||
</a-select-option>
|
||||
</NcSelect>
|
||||
</a-form-item>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col flex-1 nc-scrollbar-thin">
|
||||
<div class="data-exporter-header sticky top-0 z-100">Recent Exports</div>
|
||||
<div v-if="exportedFiles.length" class="flex-1 flex flex-col max-h-[calc(100%_-_25px)]">
|
||||
<template v-for="exp of exportedFiles">
|
||||
<div
|
||||
class="flex-1 flex items-start gap-3"
|
||||
v-if="exp.status === JobStatus.COMPLETED ? exp.result : true"
|
||||
:key="exp.id"
|
||||
class="p-3 flex gap-2 justify-between border-b-1"
|
||||
:class="{
|
||||
'max-w-[calc(100%_-_74px)]': exp.status === JobStatus.COMPLETED && !exp.result.isNew,
|
||||
'max-w-[calc(100%_-_113px)]': exp.status === JobStatus.COMPLETED && exp.result.isNew,
|
||||
'max-w-[calc(100%_-_48px)]': exp.status !== JobStatus.COMPLETED && !exp.result.isNew,
|
||||
'max-w-[calc(100%_-_85px)]': exp.status !== JobStatus.COMPLETED && exp.result.isNew,
|
||||
'px-4 py-3': fullscreen,
|
||||
'px-3 py-2': !fullscreen,
|
||||
'bg-white hover:bg-gray-50': exp.status === JobStatus.COMPLETED,
|
||||
'bg-nc-bg-red-light': exp.status !== JobStatus.COMPLETED,
|
||||
}"
|
||||
>
|
||||
<NcTooltip v-if="[JobStatus.COMPLETED, JobStatus.FAILED].includes(exp.status)" class="flex">
|
||||
<template #title>
|
||||
{{ jobStatusTooltip[exp.status] }}
|
||||
</template>
|
||||
<GeneralIcon
|
||||
:icon="exp.status === JobStatus.COMPLETED ? 'circleCheckSolid' : 'alertTriangleSolid'"
|
||||
class="flex-none h-5 w-5"
|
||||
:class="{
|
||||
'!text-green-700': exp.status === JobStatus.COMPLETED,
|
||||
'!text-red-700': exp.status === JobStatus.FAILED,
|
||||
}"
|
||||
/>
|
||||
</NcTooltip>
|
||||
<div v-else class="h-5 flex items-center">
|
||||
<GeneralLoader size="regular" class="flex-none" />
|
||||
</div>
|
||||
<div
|
||||
class="flex-1 flex items-start gap-3"
|
||||
:class="{
|
||||
'max-w-[calc(100%_-_74px)]': exp.status === JobStatus.COMPLETED && !exp.result.isNew,
|
||||
'max-w-[calc(100%_-_113px)]': exp.status === JobStatus.COMPLETED && exp.result.isNew,
|
||||
'max-w-[calc(100%_-_48px)]': exp.status !== JobStatus.COMPLETED && !exp.result.isNew,
|
||||
'max-w-[calc(100%_-_85px)]': exp.status !== JobStatus.COMPLETED && exp.result.isNew,
|
||||
}"
|
||||
>
|
||||
<NcTooltip v-if="[JobStatus.COMPLETED, JobStatus.FAILED].includes(exp.status)" class="flex">
|
||||
<template #title>
|
||||
{{ jobStatusTooltip[exp.status] }}
|
||||
</template>
|
||||
<GeneralIcon
|
||||
:icon="exp.status === JobStatus.COMPLETED ? 'circleCheckSolid' : 'alertTriangleSolid'"
|
||||
class="flex-none h-5 w-5"
|
||||
:class="{
|
||||
'!text-green-700': exp.status === JobStatus.COMPLETED,
|
||||
'!text-red-700': exp.status === JobStatus.FAILED,
|
||||
}"
|
||||
/>
|
||||
</NcTooltip>
|
||||
<div v-else class="h-5 flex items-center">
|
||||
<GeneralLoader size="regular" class="flex-none" />
|
||||
</div>
|
||||
|
||||
<div class="flex-1 max-w-[calc(100%_-_28px)] flex flex-col gap-1">
|
||||
<div class="inline-flex gap-1 text-sm text-gray-800 -ml-[1px]">
|
||||
<span class="inline-flex items-center h-5">
|
||||
<GeneralIcon icon="file" class="flex-none text-gray-600/80 h-3.5 w-3.5" />
|
||||
</span>
|
||||
<NcTooltip class="truncate max-w-[calc(100%_-_20px)]" show-on-truncate-only>
|
||||
<template #title>
|
||||
<div class="flex-1 max-w-[calc(100%_-_28px)] flex flex-col gap-1">
|
||||
<div class="inline-flex gap-1 text-sm text-gray-800 -ml-[1px]">
|
||||
<span class="inline-flex items-center h-5">
|
||||
<GeneralIcon icon="file" class="flex-none text-gray-600/80 h-3.5 w-3.5" />
|
||||
</span>
|
||||
<NcTooltip class="truncate max-w-[calc(100%_-_20px)]" show-on-truncate-only>
|
||||
<template #title>
|
||||
{{ exp.result.title || titleHelper() }}
|
||||
</template>
|
||||
{{ exp.result.title || titleHelper() }}
|
||||
</template>
|
||||
{{ exp.result.title || titleHelper() }}
|
||||
</NcTooltip>
|
||||
</div>
|
||||
</NcTooltip>
|
||||
</div>
|
||||
|
||||
<div v-if="exp.result.timestamp" name="error" class="text-small leading-[18px] text-nc-content-gray-muted">
|
||||
{{ timeAgo(dayjs(exp.result.timestamp).toString()) }}
|
||||
<div v-if="exp.result.timestamp" name="error" class="text-small leading-[18px] text-nc-content-gray-muted">
|
||||
{{ timeAgo(dayjs(exp.result.timestamp).toString()) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="exp.result.isNew" class="flex h-7 flex items-center">
|
||||
<NcBadge color="green" :border="false" class="!bg-nc-bg-green-light !text-nc-content-green-dark">{{
|
||||
$t('general.new')
|
||||
}}</NcBadge>
|
||||
</div>
|
||||
<div v-if="exp.status === JobStatus.COMPLETED" class="flex" @click="handleDownload(urlHelper(exp.result.url))">
|
||||
<NcTooltip class="flex">
|
||||
<template #title>
|
||||
{{ $t('general.download') }}
|
||||
</template>
|
||||
<div v-if="exp.result.isNew" class="flex h-7 flex items-center">
|
||||
<NcBadge color="green" :border="false" class="!bg-nc-bg-green-light !text-nc-content-green-dark">{{
|
||||
$t('general.new')
|
||||
}}</NcBadge>
|
||||
</div>
|
||||
<div v-if="exp.status === JobStatus.COMPLETED" class="flex" @click="handleDownload(urlHelper(exp.result.url))">
|
||||
<NcTooltip class="flex">
|
||||
<template #title>
|
||||
{{ $t('general.download') }}
|
||||
</template>
|
||||
|
||||
<NcButton type="secondary" size="xs" class="!px-[5px]">
|
||||
<div class="flex items-center gap-2">
|
||||
<GeneralIcon icon="download" />
|
||||
</div>
|
||||
</NcButton>
|
||||
</NcTooltip>
|
||||
</div>
|
||||
<NcButton type="secondary" size="xs" class="!px-[5px]">
|
||||
<div class="flex items-center gap-2">
|
||||
<GeneralIcon icon="download" />
|
||||
</div>
|
||||
</NcButton>
|
||||
</NcTooltip>
|
||||
</div>
|
||||
|
||||
<div class="flex">
|
||||
<NcTooltip class="flex">
|
||||
<template #title>
|
||||
{{ $t('general.remove') }}
|
||||
</template>
|
||||
<div class="flex">
|
||||
<NcTooltip class="flex">
|
||||
<template #title>
|
||||
{{ $t('general.remove') }}
|
||||
</template>
|
||||
|
||||
<NcButton type="text" size="xs" class="!px-[5px]" @click="onRemoveExportedFile(exp.id)">
|
||||
<GeneralIcon icon="close" />
|
||||
</NcButton>
|
||||
</NcTooltip>
|
||||
<NcButton type="text" size="xs" class="!px-[5px]" @click="onRemoveExportedFile(exp.id)">
|
||||
<GeneralIcon icon="close" />
|
||||
</NcButton>
|
||||
</NcTooltip>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div v-else class="px-3 py-2 flex-1 flex items-center justify-center text-gray-800">
|
||||
<a-empty
|
||||
:image-style="{
|
||||
height: '24px',
|
||||
}"
|
||||
:image="Empty.PRESENTED_IMAGE_SIMPLE"
|
||||
description="No exports"
|
||||
class="!my-0"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
<div v-else class="px-3 py-2 flex-1 flex items-center justify-center text-gray-800">
|
||||
<a-empty
|
||||
:image-style="{
|
||||
height: '24px',
|
||||
}"
|
||||
:image="Empty.PRESENTED_IMAGE_SIMPLE"
|
||||
description="No exports"
|
||||
class="!my-0"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
}
|
||||
],
|
||||
"config": {
|
||||
"modalSize": "sm",
|
||||
"contentMinHeight": "310px"
|
||||
}
|
||||
},
|
||||
"order": 2
|
||||
}
|
||||
|
||||
@@ -21,5 +21,6 @@
|
||||
"config": {
|
||||
"modalSize": "sm",
|
||||
"contentMinHeight": "198px"
|
||||
}
|
||||
},
|
||||
"order": 3
|
||||
}
|
||||
|
||||
@@ -136,15 +136,15 @@ export enum CsvColumnSeparator {
|
||||
|
||||
export const csvColumnSeparatorOptions = [
|
||||
{
|
||||
label: ',',
|
||||
label: 'Comma (,)',
|
||||
value: CsvColumnSeparator[','],
|
||||
},
|
||||
{
|
||||
label: ';',
|
||||
label: 'Semi-colon (;)',
|
||||
value: CsvColumnSeparator[';'],
|
||||
},
|
||||
{
|
||||
label: '|',
|
||||
label: 'Pipe (|)',
|
||||
value: CsvColumnSeparator['|'],
|
||||
},
|
||||
{
|
||||
|
||||
4
packages/nocodb/src/cache/NocoCache.ts
vendored
4
packages/nocodb/src/cache/NocoCache.ts
vendored
@@ -1,7 +1,7 @@
|
||||
import RedisCacheMgr from './RedisCacheMgr';
|
||||
import RedisMockCacheMgr from './RedisMockCacheMgr';
|
||||
import type CacheMgr from './CacheMgr';
|
||||
import { CacheGetType } from '~/utils/globals';
|
||||
import { CACHE_PREFIX, CacheGetType } from '~/utils/globals';
|
||||
|
||||
export default class NocoCache {
|
||||
private static client: CacheMgr;
|
||||
@@ -21,7 +21,7 @@ export default class NocoCache {
|
||||
|
||||
// TODO(cache): fetch orgs once it's implemented
|
||||
const orgs = 'noco';
|
||||
this.prefix = `nc:${orgs}`;
|
||||
this.prefix = `${CACHE_PREFIX}:${orgs}`;
|
||||
}
|
||||
|
||||
public static async set(key, value): Promise<boolean> {
|
||||
|
||||
3
packages/nocodb/src/cache/RedisCacheMgr.ts
vendored
3
packages/nocodb/src/cache/RedisCacheMgr.ts
vendored
@@ -1,6 +1,7 @@
|
||||
import debug from 'debug';
|
||||
import Redis from 'ioredis';
|
||||
import CacheMgr from './CacheMgr';
|
||||
import { CACHE_PREFIX } from '~/utils/globals';
|
||||
|
||||
const _log = debug('nc:cache');
|
||||
|
||||
@@ -22,7 +23,7 @@ export default class RedisCacheMgr extends CacheMgr {
|
||||
|
||||
// TODO(cache): fetch orgs once it's implemented
|
||||
const orgs = 'noco';
|
||||
this.prefix = `nc:${orgs}`;
|
||||
this.prefix = `${CACHE_PREFIX}:${orgs}`;
|
||||
this.context = 'RedisCacheMgr';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import debug from 'debug';
|
||||
import Redis from 'ioredis-mock';
|
||||
import CacheMgr from './CacheMgr';
|
||||
import { CACHE_PREFIX } from '~/utils/globals';
|
||||
|
||||
const _log = debug('nc:cache');
|
||||
|
||||
@@ -13,7 +14,7 @@ export default class RedisMockCacheMgr extends CacheMgr {
|
||||
|
||||
// TODO(cache): fetch orgs once it's implemented
|
||||
const orgs = 'noco';
|
||||
this.prefix = `nc:${orgs}`;
|
||||
this.prefix = `${CACHE_PREFIX}:${orgs}`;
|
||||
this.context = 'RedisMockCacheMgr';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,16 +106,11 @@ describe('Integration Model', () => {
|
||||
'bypass',
|
||||
'bypass',
|
||||
MetaTable.INTEGRATIONS,
|
||||
isEE ? null : 'test-id',
|
||||
'test-id',
|
||||
null,
|
||||
isEE
|
||||
? {
|
||||
_and: [
|
||||
{
|
||||
id: {
|
||||
eq: 'test-id',
|
||||
},
|
||||
},
|
||||
{
|
||||
_or: [
|
||||
{
|
||||
|
||||
@@ -44,6 +44,7 @@ import { QueueService as FallbackQueueService } from '~/modules/jobs/fallback/fa
|
||||
import { JOBS_QUEUE } from '~/interface/Jobs';
|
||||
import { RecoverLinksMigration } from '~/modules/jobs/migration-jobs/nc_job_003_recover_links';
|
||||
import { CleanupDuplicateColumnMigration } from '~/modules/jobs/migration-jobs/nc_job_004_cleanup_duplicate_column';
|
||||
import { CACHE_PREFIX } from '~/utils/globals';
|
||||
|
||||
export const JobsModuleMetadata = {
|
||||
imports: [
|
||||
@@ -52,6 +53,7 @@ export const JobsModuleMetadata = {
|
||||
? [
|
||||
BullModule.forRoot({
|
||||
url: process.env.NC_REDIS_JOB_URL,
|
||||
prefix: CACHE_PREFIX === 'nc' ? undefined : `${CACHE_PREFIX}`,
|
||||
}),
|
||||
BullModule.registerQueue({
|
||||
name: JOBS_QUEUE,
|
||||
|
||||
@@ -245,3 +245,8 @@ export const RootScopeTables = {
|
||||
MetaTable.INTEGRATIONS_STORE,
|
||||
],
|
||||
};
|
||||
|
||||
export const CACHE_PREFIX =
|
||||
process.env.NC_CACHE_PREFIX && process.env.NC_CACHE_PREFIX.trim().length > 0
|
||||
? process.env.NC_CACHE_PREFIX
|
||||
: 'nc';
|
||||
|
||||
19
scripts/self-hosted-gh-runner/Dockerfile
Normal file
19
scripts/self-hosted-gh-runner/Dockerfile
Normal file
@@ -0,0 +1,19 @@
|
||||
FROM ghcr.io/actions/actions-runner:latest
|
||||
|
||||
USER root
|
||||
|
||||
# Install dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libnss3 libatk-bridge2.0-0 libdrm-dev libxkbcommon-dev libgbm-dev libasound-dev \
|
||||
libatspi2.0-0 libxshmfence-dev python3 python3-pip curl zip sudo rsync jq \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Node.js (and npm, which includes npx)
|
||||
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - && \
|
||||
apt-get install -y nodejs && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Playwright
|
||||
RUN npx playwright install --with-deps chromium
|
||||
|
||||
USER runner
|
||||
50
scripts/self-hosted-gh-runner/values.yaml
Normal file
50
scripts/self-hosted-gh-runner/values.yaml
Normal file
@@ -0,0 +1,50 @@
|
||||
template:
|
||||
spec:
|
||||
initContainers:
|
||||
- name: init-dind-externals
|
||||
image: runner:latest
|
||||
imagePullPolicy: Never
|
||||
command:
|
||||
["cp", "-r", "-v", "/home/runner/externals/.", "/home/runner/tmpDir/"]
|
||||
volumeMounts:
|
||||
- name: dind-externals
|
||||
mountPath: /home/runner/tmpDir
|
||||
containers:
|
||||
- name: runner
|
||||
image: runner:latest
|
||||
imagePullPolicy: Never
|
||||
command: ["/home/runner/run.sh"]
|
||||
env:
|
||||
- name: DOCKER_HOST
|
||||
value: unix:///run/docker/docker.sock
|
||||
volumeMounts:
|
||||
- name: work
|
||||
mountPath: /home/runner/_work
|
||||
- name: dind-sock
|
||||
mountPath: /run/docker
|
||||
readOnly: true
|
||||
- name: dind
|
||||
image: docker:dind
|
||||
args:
|
||||
- dockerd
|
||||
- --host=unix:///run/docker/docker.sock
|
||||
- --group=$(DOCKER_GROUP_GID)
|
||||
env:
|
||||
- name: DOCKER_GROUP_GID
|
||||
value: "123"
|
||||
securityContext:
|
||||
privileged: true
|
||||
volumeMounts:
|
||||
- name: work
|
||||
mountPath: /home/runner/_work
|
||||
- name: dind-sock
|
||||
mountPath: /run/docker
|
||||
- name: dind-externals
|
||||
mountPath: /home/runner/externals
|
||||
volumes:
|
||||
- name: work
|
||||
emptyDir: {}
|
||||
- name: dind-sock
|
||||
emptyDir: {}
|
||||
- name: dind-externals
|
||||
emptyDir: {}
|
||||
Reference in New Issue
Block a user