diff --git a/packages/nocodb/package.json b/packages/nocodb/package.json index 6ab6e27338..2330bd932c 100644 --- a/packages/nocodb/package.json +++ b/packages/nocodb/package.json @@ -181,6 +181,7 @@ "slash": "^3.0.0", "socket.io": "^4.4.1", "sqlite3": "5.0.0", + "tinycolor2": "^1.4.2", "twilio": "^3.55.1", "unique-names-generator": "^4.3.1", "uuid": "^8.2.0", @@ -202,6 +203,7 @@ "@types/node": "^18.0.0", "@types/nodemailer": "^6.4.0", "@types/supertest": "^2.0.10", + "@types/tinycolor2": "^1.4.3", "@typescript-eslint/eslint-plugin": "^4.0.1", "@typescript-eslint/parser": "^4.0.1", "@webserverless/fc-express": "^0.1.4", diff --git a/packages/nocodb/src/lib/meta/api/sync/helpers/job.ts b/packages/nocodb/src/lib/meta/api/sync/helpers/job.ts index f1b6e295ab..f6d8890ce8 100644 --- a/packages/nocodb/src/lib/meta/api/sync/helpers/job.ts +++ b/packages/nocodb/src/lib/meta/api/sync/helpers/job.ts @@ -11,22 +11,57 @@ import hash from 'object-hash'; import dayjs from 'dayjs'; import utc from 'dayjs/plugin/utc'; +import tinycolor from 'tinycolor2'; import { importData, importLTARData } from './readAndProcessData'; dayjs.extend(utc); const selectColors = { - "blue": "#cfdfff", - "cyan": "#d0f0fd", - "teal": "#c2f5e9", - "green": "#d1f7c4", - "orange": "#fee2d5", - "yellow": "#ffeab6", - "red": "#ffdce5", - "pink": "#ffdaf6", - "purple": "#ede2fe", - "gray": "#eee" -} + // normal + blue: '#cfdfff', + cyan: '#d0f0fd', + teal: '#c2f5e9', + green: '#d1f7c4', + orange: '#fee2d5', + yellow: '#ffeab6', + red: '#ffdce5', + pink: '#ffdaf6', + purple: '#ede2fe', + gray: '#eee', + // medium + blueMedium: '#9cc7ff', + cyanMedium: '#77d1f3', + tealMedium: '#72ddc3', + greenMedium: '#93e088', + orangeMedium: '#ffa981', + yellowMedium: '#ffd66e', + redMedium: '#ff9eb7', + pinkMedium: '#f99de2', + purpleMedium: '#cdb0ff', + grayMedium: '#ccc', + // dark + blueDark: '#2d7ff9', + cyanDark: '#18bfff', + tealDark: '#20d9d2', + greenDark: '#20c933', + orangeDark: '#ff6f2c', + yellowDark: '#fcb400', + redDark: '#f82b60', + pinkDark: '#ff08c2', + purpleDark: '#8b46ff', + grayDark: '#666', + // darker + blueDarker: '#2750ae', + cyanDarker: '#0b76b7', + tealDarker: '#06a09b', + greenDarker: '#338a17', + orangeDarker: '#d74d26', + yellowDarker: '#b87503', + redDarker: '#ba1e45', + pinkDarker: '#b2158b', + purpleDarker: '#6b1cb0', + grayDarker: '#444', +}; export default async ( syncDB: AirtableSyncConfig, @@ -411,13 +446,15 @@ export default async ( // TODO fix record mapping (this causes every record to map first option, we can't handle them using data api as they don't provide option id within data we might instead get the correct mapping from schema file ) let dupNo = 1; const defaultName = (value as any).name; - while (options.find(el => el.title === (value as any).name)) { + while (options.find((el) => el.title === (value as any).name)) { (value as any).name = `${defaultName}_${dupNo++}`; } options.push({ order: order++, title: (value as any).name, - color: selectColors[(value as any).color] ? selectColors[(value as any).color] : null + color: selectColors[(value as any).color] + ? selectColors[(value as any).color] + : tinycolor.random().toHexString(), }); sMap.addToMappingTbl( @@ -538,9 +575,11 @@ export default async ( case 'select': case 'multiSelect': ncCol.colOptions = { - options: [...colOptions.data] - } - ncCol.dtxp = colOptions.data.map(el => `'${el.title}'`).join(','); + options: [...colOptions.data], + }; + // if options are empty, configure '' as default option + ncCol.dtxp = + colOptions.data.map((el) => `'${el.title}'`).join(',') || "''"; break; case undefined: break; @@ -1362,12 +1401,14 @@ export default async ( break; case UITypes.MultiSelect: - rec[key] = value.map((v) => { - if (v === '') { - return 'nc_empty'; - } - return `${v.replace(/,/g, '.')}`; - }).join(','); + rec[key] = value + .map((v) => { + if (v === '') { + return 'nc_empty'; + } + return `${v.replace(/,/g, '.')}`; + }) + .join(','); break; case UITypes.Attachment: @@ -2215,6 +2256,7 @@ export default async ( logDetailed, records: recordsMap[ncTbl.id], atNcAliasRef, + ncLinkMappingTable, }); } diff --git a/packages/nocodb/src/lib/meta/api/sync/helpers/readAndProcessData.ts b/packages/nocodb/src/lib/meta/api/sync/helpers/readAndProcessData.ts index 5f1f52493a..9b605a0349 100644 --- a/packages/nocodb/src/lib/meta/api/sync/helpers/readAndProcessData.ts +++ b/packages/nocodb/src/lib/meta/api/sync/helpers/readAndProcessData.ts @@ -136,6 +136,7 @@ export async function importLTARData({ logBasic = (_str) => {}, records, atNcAliasRef, + ncLinkMappingTable, }: { projectName: string; table: { title?: string; id?: string }; @@ -151,6 +152,7 @@ export async function importLTARData({ [ncTitle: string]: string; }; }; + ncLinkMappingTable: Record>[]; }) { const assocTableMetas: Array<{ modelMeta: { id?: string; title?: string }; @@ -182,6 +184,9 @@ export async function importLTARData({ // skip if already inserted if (colMeta.colOptions.fk_mm_model_id in insertedAssocRef) continue; + // self links: skip if the column under consideration is the add-on column NocoDB creates + if (ncLinkMappingTable.every((a) => a.nc.title !== colMeta.title)) continue; + // mark as inserted insertedAssocRef[colMeta.colOptions.fk_mm_model_id] = true;