mirror of
https://github.com/nocodb/nocodb.git
synced 2026-02-02 02:57:23 +00:00
Merge pull request #12012 from nocodb/develop
This commit is contained in:
@@ -75,7 +75,7 @@ const saveValue = (targetValue: string) => {
|
||||
vModel.value = value
|
||||
}
|
||||
let savingHandle: any
|
||||
const onInputKeyUp = (e: KeyboardEvent) => {
|
||||
const onInputKeyUp = (e: KeyboardEvent, debounce = true) => {
|
||||
const target: HTMLInputElement = e.target as HTMLInputElement
|
||||
if (target) {
|
||||
// mac's double space insert period
|
||||
@@ -87,9 +87,13 @@ const onInputKeyUp = (e: KeyboardEvent) => {
|
||||
if (savingHandle) {
|
||||
clearTimeout(savingHandle)
|
||||
}
|
||||
savingHandle = setTimeout(() => {
|
||||
if (!debounce) {
|
||||
saveValue(target.value)
|
||||
}, 100)
|
||||
} else {
|
||||
savingHandle = setTimeout(() => {
|
||||
saveValue(target.value)
|
||||
}, 100)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Handle the arrow keys as its default behavior is to increment/decrement the value
|
||||
@@ -132,6 +136,7 @@ const onInputKeyDown = (e: KeyboardEvent) => {
|
||||
e.stopPropagation()
|
||||
return
|
||||
}
|
||||
|
||||
pasteText(target, e.key)
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
@@ -153,6 +158,7 @@ const onInputPaste = (e: ClipboardEvent) => {
|
||||
e.stopPropagation()
|
||||
pasteText(target, value)
|
||||
}
|
||||
|
||||
const onInputBlur = (e: FocusEvent) => {
|
||||
emits('blur', e)
|
||||
if (e.target) {
|
||||
@@ -194,6 +200,7 @@ onMounted(() => {
|
||||
style="letter-spacing: 0.06rem; height: 24px !important"
|
||||
:style="inputStyle"
|
||||
:disabled="disabled"
|
||||
@keydown.enter.exact="onInputKeyUp($event, false)"
|
||||
@keydown.left.stop
|
||||
@keydown.right.stop
|
||||
@keydown.delete.stop
|
||||
|
||||
@@ -86,9 +86,9 @@ onMounted(() => {
|
||||
|
||||
<template>
|
||||
<CellPercentProgressBar
|
||||
v-if="parseProp(col!.meta).is_progress && (isForm)"
|
||||
v-if="parseProp(col!.meta).is_progress && (isForm || isExpandedFormOpen)"
|
||||
:style="{
|
||||
...(isForm && { 'min-height': '22px', 'height': '22px' }),
|
||||
...((isForm || isExpandedFormOpen) && { 'min-height': '22px', 'height': '22px' }),
|
||||
}"
|
||||
:is-show-number="true"
|
||||
:percentage="vModelNumber"
|
||||
|
||||
@@ -35,7 +35,7 @@ const slotHasChildren = (name?: string) => {
|
||||
<span
|
||||
style="mix-blend-mode: difference; color: #ffffff"
|
||||
:style="{
|
||||
'margin-left': `${-Math.min(percentage, 50)}%`,
|
||||
'margin-left': `${-Math.min(cPercentage, 50)}%`,
|
||||
}"
|
||||
>
|
||||
{{ `${percentage}%` }}
|
||||
@@ -45,7 +45,7 @@ const slotHasChildren = (name?: string) => {
|
||||
<span
|
||||
style="mix-blend-mode: overlay; color: #ffffff"
|
||||
:style="{
|
||||
'margin-left': `${-Math.min(percentage, 50)}%`,
|
||||
'margin-left': `${-Math.min(cPercentage, 50)}%`,
|
||||
}"
|
||||
>
|
||||
{{ `${percentage}%` }}
|
||||
|
||||
@@ -220,9 +220,8 @@ const showReadonlyField = computed(() => {
|
||||
|
||||
case 'percent': {
|
||||
return !(
|
||||
!readOnly.value &&
|
||||
editEnabled.value &&
|
||||
(isExpandedFormOpen.value ? localEditEnabled.value || !parseProp(column.value?.meta).is_progress : true)
|
||||
(!readOnly.value && editEnabled.value) ||
|
||||
(isExpandedFormOpen.value && (localEditEnabled.value || parseProp(column.value?.meta).is_progress))
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -169,6 +169,8 @@
|
||||
"upgradeToUseDashboardsSubtitle": "Upgrade to the {plan} plan to use dashboards to visualize your data.",
|
||||
"upgradeToUsePrivateBases": "Upgrade to unlock private bases",
|
||||
"upgradeToUsePrivateBasesSubtitle": "Private bases are available on the {plan} plan. Upgrade now to start using them.",
|
||||
"upgradeLicenseToUsePrivateBases": "Upgrade license to unlock private bases",
|
||||
"upgradeLicenseToUsePrivateBasesSubtitle": "Private bases are not available in Enterprise Starter license. Upgrade license key to start using them.",
|
||||
"upgradeToAddMoreAttachmentsInCellSubtitle": "You can only upload at most {limit} {filePlural} to this cell. Upgrade to the {plan} plan to add more files."
|
||||
},
|
||||
"general": {
|
||||
@@ -591,6 +593,7 @@
|
||||
"Team": "Team",
|
||||
"Plus": "Plus",
|
||||
"Business": "Business",
|
||||
"EnterpriseStarter": "Enterprise Starter",
|
||||
"Enterprise": "Enterprise"
|
||||
},
|
||||
"currentPlan": {
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
"marked": "^4.3.0",
|
||||
"monaco-editor": "^0.52.2",
|
||||
"monaco-sql-languages": "^0.11.0",
|
||||
"nocodb-sdk": "0.264.1",
|
||||
"nocodb-sdk": "workspace:^",
|
||||
"papaparse": "^5.5.2",
|
||||
"parse-github-url": "^1.0.3",
|
||||
"pdfobject": "^2.3.0",
|
||||
|
||||
@@ -15,6 +15,7 @@ export interface DashboardType {
|
||||
|
||||
password?: string;
|
||||
fk_custom_url_id?: string;
|
||||
uuid?: string;
|
||||
}
|
||||
|
||||
export enum WidgetTypes {
|
||||
|
||||
@@ -57,11 +57,15 @@ export enum PlanFeatureTypes {
|
||||
FEATURE_PRIVATE_BASES = 'feature_private_bases',
|
||||
}
|
||||
|
||||
// todo: separate as a new enum
|
||||
export enum PlanTitles {
|
||||
FREE = 'Free',
|
||||
PLUS = 'Plus',
|
||||
BUSINESS = 'Business',
|
||||
ENTERPRISE = 'Enterprise',
|
||||
|
||||
// on-prem
|
||||
ENTERPRISE_STARTER = 'EnterpriseStarter',
|
||||
}
|
||||
|
||||
export enum PlanPriceLookupKeys {
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
"mysql2": "^3.14.1",
|
||||
"nanoid": "^3.3.8",
|
||||
"nc-lib-gui": "0.264.1",
|
||||
"nocodb-sdk": "0.264.1",
|
||||
"nocodb-sdk": "workspace:^",
|
||||
"nodemailer": "^6.10.0",
|
||||
"object-hash": "^3.0.0",
|
||||
"object-sizeof": "^2.6.5",
|
||||
|
||||
@@ -52,6 +52,7 @@ export default class Noco {
|
||||
public readonly metaMgr: any;
|
||||
public readonly metaMgrv2: any;
|
||||
public env: string;
|
||||
protected static _nestApp: INestApplication;
|
||||
|
||||
protected config: any;
|
||||
protected requestContext: any;
|
||||
@@ -89,6 +90,10 @@ export default class Noco {
|
||||
return this._ncMeta;
|
||||
}
|
||||
|
||||
public static get nestApp() {
|
||||
return this._nestApp;
|
||||
}
|
||||
|
||||
public static get ncAudit(): AuditService {
|
||||
return this._ncAudit ?? this._ncMeta;
|
||||
}
|
||||
@@ -121,6 +126,7 @@ export default class Noco {
|
||||
bufferLogs: true,
|
||||
bodyParser: false,
|
||||
});
|
||||
Noco._nestApp = nestApp;
|
||||
this.initCustomLogger(nestApp);
|
||||
NcDebug.log('Custom logger initialized');
|
||||
nestApp.flushLogs();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { NcRequest } from 'nocodb-sdk';
|
||||
import { NcApiVersion, type NcRequest } from 'nocodb-sdk';
|
||||
import type { IBaseModelSqlV2 } from '~/db/IBaseModelSqlV2';
|
||||
import { type AttachmentUrlUploadJobData, JobTypes } from '~/interface/Jobs';
|
||||
import { EMIT_EVENT } from '~/constants';
|
||||
@@ -22,6 +22,10 @@ export class AttachmentUrlUploadPreparator {
|
||||
const postInsertOps: ((rowId: any) => Promise<string>)[] = [];
|
||||
const preInsertOps: (() => Promise<string>)[] = [];
|
||||
const postInsertAuditOps: ((rowId: any) => Promise<void>)[] = [];
|
||||
// return early if not v3
|
||||
if (baseModel.context.api_version !== NcApiVersion.V3) {
|
||||
return { postInsertOps, preInsertOps, postInsertAuditOps };
|
||||
}
|
||||
for (const col of attachmentCols) {
|
||||
let attachmentData: { id?: string; url: string }[];
|
||||
try {
|
||||
@@ -40,24 +44,27 @@ export class AttachmentUrlUploadPreparator {
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
postInsertOps.push(async (recordId) => {
|
||||
Noco.eventEmitter.emit(EMIT_EVENT.HANDLE_ATTACHMENT_URL_UPLOAD, {
|
||||
jobName: JobTypes.AttachmentUrlUpload,
|
||||
context: baseModel.context,
|
||||
modelId: baseModel.model.id,
|
||||
column: col,
|
||||
recordId,
|
||||
user: baseModel.context.user,
|
||||
attachments: attachmentData,
|
||||
req,
|
||||
} as AttachmentUrlUploadJobData);
|
||||
return '';
|
||||
});
|
||||
const columnKeyName = dataWrapper(data).getColumnKeyName(col);
|
||||
// remove temp_ ids so it doesn't get recorded in audit
|
||||
data[columnKeyName] = JSON.stringify(
|
||||
attachmentData.filter((dt) => !dt.id?.startsWith('temp_')),
|
||||
);
|
||||
// only process when temp id exists
|
||||
if (attachmentData.some((attr) => attr.id?.startsWith('temp_'))) {
|
||||
postInsertOps.push(async (recordId) => {
|
||||
Noco.eventEmitter.emit(EMIT_EVENT.HANDLE_ATTACHMENT_URL_UPLOAD, {
|
||||
jobName: JobTypes.AttachmentUrlUpload,
|
||||
context: baseModel.context,
|
||||
modelId: baseModel.model.id,
|
||||
column: col,
|
||||
recordId,
|
||||
user: baseModel.context.user,
|
||||
attachments: attachmentData,
|
||||
req,
|
||||
} as AttachmentUrlUploadJobData);
|
||||
return '';
|
||||
});
|
||||
const columnKeyName = dataWrapper(data).getColumnKeyName(col);
|
||||
// remove temp_ ids so it doesn't get recorded in audit
|
||||
data[columnKeyName] = JSON.stringify(
|
||||
attachmentData.filter((dt) => !dt.id?.startsWith('temp_')),
|
||||
);
|
||||
}
|
||||
}
|
||||
return { postInsertOps, preInsertOps, postInsertAuditOps };
|
||||
}
|
||||
|
||||
@@ -3,10 +3,6 @@
|
||||
!!! Do not edit this file manually !!!
|
||||
*/
|
||||
|
||||
|
||||
|
||||
import type { IntegrationEntry } from '@noco-local-integrations/core';
|
||||
|
||||
export default [
|
||||
|
||||
] as IntegrationEntry[];
|
||||
export default [] as IntegrationEntry[];
|
||||
|
||||
@@ -794,6 +794,33 @@ export default class Column<T = any> implements ColumnType {
|
||||
if (!col) {
|
||||
return;
|
||||
}
|
||||
// If the column is one of CreatedBy, LastModifiedBy, CreatedAt, or LastModifiedAt
|
||||
// and it is a system column, then delete its alias columns as well.
|
||||
// This deletion is only performed through meta-sync because system columns
|
||||
// cannot be deleted via API calls.
|
||||
if (
|
||||
(
|
||||
[
|
||||
UITypes.CreatedTime,
|
||||
UITypes.LastModifiedTime,
|
||||
UITypes.LastModifiedBy,
|
||||
UITypes.CreatedBy,
|
||||
] as UITypes[]
|
||||
).includes(col.uidt) &&
|
||||
col.system
|
||||
) {
|
||||
const aliasCols = await ncMeta.metaList2(
|
||||
context.workspace_id,
|
||||
context.base_id,
|
||||
MetaTable.COLUMNS,
|
||||
{
|
||||
condition: { uidt: col.uidt, system: false },
|
||||
},
|
||||
);
|
||||
for (const aliasCol of aliasCols) {
|
||||
await Column.delete(context, aliasCol.id, ncMeta);
|
||||
}
|
||||
}
|
||||
|
||||
// todo: or instead of delete reset related foreign key value to null and handle in BaseModel
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import {
|
||||
AppEvents,
|
||||
ClientType,
|
||||
isAIPromptCol,
|
||||
isLinksOrLTAR,
|
||||
isVirtualCol,
|
||||
ModelTypes,
|
||||
RelationTypes,
|
||||
SqlUiFactory,
|
||||
UITypes,
|
||||
} from 'nocodb-sdk';
|
||||
import { pluralize, singularize } from 'inflection';
|
||||
@@ -276,7 +278,7 @@ export class MetaDiffsService {
|
||||
}
|
||||
for (const column of oldMeta.columns) {
|
||||
if (
|
||||
[
|
||||
(<UITypes[]>[
|
||||
UITypes.LinkToAnotherRecord,
|
||||
UITypes.Links,
|
||||
UITypes.Rollup,
|
||||
@@ -285,8 +287,16 @@ export class MetaDiffsService {
|
||||
UITypes.QrCode,
|
||||
UITypes.Barcode,
|
||||
UITypes.Button,
|
||||
].includes(column.uidt) ||
|
||||
isAIPromptCol(column)
|
||||
]).includes(column.uidt) ||
|
||||
isAIPromptCol(column) ||
|
||||
// skip alias columns of CreatedTime, LastModifiedTime, CreatedBy, LastModifiedBy
|
||||
((<UITypes[]>[
|
||||
UITypes.CreatedTime,
|
||||
UITypes.LastModifiedTime,
|
||||
UITypes.LastModifiedBy,
|
||||
UITypes.CreatedBy,
|
||||
]).includes(column.uidt) &&
|
||||
!column.system)
|
||||
) {
|
||||
if (isLinksOrLTAR(column.uidt)) {
|
||||
virtualRelationColumns.push(column);
|
||||
@@ -703,6 +713,7 @@ export class MetaDiffsService {
|
||||
|
||||
// @ts-ignore
|
||||
const sqlClient = await NcConnectionMgrv2.getSqlClient(source);
|
||||
const sqlUi = SqlUiFactory.create({ client: source.type ?? ClientType.PG });
|
||||
const changes = await this.getMetaDiff(context, sqlClient, base, source);
|
||||
|
||||
/* Get all relations */
|
||||
@@ -831,7 +842,15 @@ export class MetaDiffsService {
|
||||
{ client: source.type },
|
||||
{},
|
||||
);
|
||||
column.uidt = metaFact.getUIDataType(column);
|
||||
|
||||
// check if new type is compatible with old uidt
|
||||
const allowedDatatypes = sqlUi.getDataTypeListForUiType(column);
|
||||
|
||||
// if UIDT not compatible with new type then change uidt
|
||||
if (!allowedDatatypes?.includes(column.dt)) {
|
||||
column.uidt = metaFact.getUIDataType(column);
|
||||
}
|
||||
|
||||
column.title = change.column.title;
|
||||
await Column.update(context, change.column.id, column);
|
||||
}
|
||||
|
||||
22
pnpm-lock.yaml
generated
22
pnpm-lock.yaml
generated
@@ -227,8 +227,8 @@ importers:
|
||||
specifier: ^0.11.0
|
||||
version: 0.11.0(antlr4ng-cli@1.0.7)
|
||||
nocodb-sdk:
|
||||
specifier: 0.264.1
|
||||
version: 0.264.1(debug@4.4.1)
|
||||
specifier: workspace:^
|
||||
version: link:../nocodb-sdk
|
||||
papaparse:
|
||||
specifier: ^5.5.2
|
||||
version: 5.5.3
|
||||
@@ -835,8 +835,8 @@ importers:
|
||||
specifier: 0.264.1
|
||||
version: 0.264.1
|
||||
nocodb-sdk:
|
||||
specifier: 0.264.1
|
||||
version: 0.264.1(debug@4.4.1)
|
||||
specifier: workspace:^
|
||||
version: link:../nocodb-sdk
|
||||
nodemailer:
|
||||
specifier: ^6.10.0
|
||||
version: 6.10.1
|
||||
@@ -11097,10 +11097,6 @@ packages:
|
||||
resolution: {integrity: sha512-67n1OfusL/ON57fwFJ6ZurSJa/msYVQmqlz9rCel2HJYj4Zeb8v9TcmRdEW+PV2i9Fm2358umSvzZukhw/E8DA==}
|
||||
engines: {node: '>=18.20.0 <20 || >=20.12.1'}
|
||||
|
||||
nocodb-sdk@0.264.1:
|
||||
resolution: {integrity: sha512-zaYoSuctL1jr/uqwsDJIml1VsDEaak8qriTtk0jlLoc0bXU5IPUO+IaQpYWe9uKGNT1nujvQezgnmK4kru7xww==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
node-abi@3.75.0:
|
||||
resolution: {integrity: sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -27276,16 +27272,6 @@ snapshots:
|
||||
json-stringify-safe: 5.0.1
|
||||
propagate: 2.0.1
|
||||
|
||||
nocodb-sdk@0.264.1(debug@4.4.1):
|
||||
dependencies:
|
||||
axios: 1.9.0(debug@4.4.1)
|
||||
chevrotain: 10.5.0
|
||||
dayjs: 1.11.13
|
||||
jsep: 1.4.0
|
||||
validator: 13.15.15
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
node-abi@3.75.0:
|
||||
dependencies:
|
||||
semver: 7.7.2
|
||||
|
||||
Reference in New Issue
Block a user