Files
nocodb/packages/nc-gui/utils/validation.ts
Pranav C 33ee9bfa62 feat: Improved UI (#6222)
* feat: Improved ui (#6156)

* refactor: revert

Signed-off-by: Pranav C <pranavxc@gmail.com>

feat: shared base

Signed-off-by: Pranav C <pranavxc@gmail.com>

fix: remove duplicate import statement

Signed-off-by: Pranav C <pranavxc@gmail.com>

fix: disable starred & license menu

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

test: fix airtable wait issue

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

test: enable mysql in ci

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

test: fix checkbox order for sqlite

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

test: disable quick tests

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

test: fix dbType env variable for CI

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

test: workspace API access error fix

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

test: enable SQLite CI CD

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

test: use DB_TYPE env variable

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

test: enable SQLite UT

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

test: isHub cleanup

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

test: add check for EE Timezone spec

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

chore: cleanup

Signed-off-by: Pranav C <pranavxc@gmail.com>

chore: cleanup

Signed-off-by: Pranav C <pranavxc@gmail.com>

test: EE check fix

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

chore: test correction

Signed-off-by: Pranav C <pranavxc@gmail.com>

chore: sync latest changes

Signed-off-by: Pranav C <pranavxc@gmail.com>

test: set EE=false

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

test: set NC Edition to community in workflow file

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

chore: update sdk build command

Signed-off-by: Pranav C <pranavxc@gmail.com>

refactor: i18n and other changes

Signed-off-by: Pranav C <pranavxc@gmail.com>

feat: new ui

Signed-off-by: Pranav C <pranavxc@gmail.com>

* chore: sync tests

Signed-off-by: Pranav C <pranavxc@gmail.com>

* chore: lint

Signed-off-by: Pranav C <pranavxc@gmail.com>

* fix: shared view/base related bugs

Signed-off-by: Pranav C <pranavxc@gmail.com>

* test: checkbox verification sort order fix

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* test: fix sqlite reset

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* test: enable selfhosted runners

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* docs: table ops (draft)

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* Docs: screenshots for table-operations.md

* refactor: introduce missing buttons

Signed-off-by: Pranav C <pranavxc@gmail.com>

* fix: get all fields

Signed-off-by: Pranav C <pranavxc@gmail.com>

* test: UT fix- new data API response

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* test: EE is false

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* test: webhook lookup as string in CE

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* fix: include created_at and updated_at

Signed-off-by: Pranav C <pranavxc@gmail.com>

* test: fix UT newDataAPI response for PG

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* fix: separate api for webhook related plugins

Signed-off-by: Pranav C <pranavxc@gmail.com>

* test: msyql filter corrections

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* test: mysql group by test corrections

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* test: fix datatype for rating field in groupby spec for pg

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* test: kanban datatype correction

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* test: column edit for mysql- rating field

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* test: misc fixes

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* test: enable 4 workers

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* test: enable 2 workers per shard only

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* docs: table CRUD

* Rename table-operations.md to table-crud.md

* Create column-crud.md

* docs: row CRUD

* Rename row.md to row-crud.md

* docs: project crud

* docs: toolbar (skeleton)

* refactor: single page UI and bug fixes

Signed-off-by: Pranav C <pranavxc@gmail.com>

* chore: sync tests playwright

Signed-off-by: Pranav C <pranavxc@gmail.com>

* chore: add missing dependency

Signed-off-by: Pranav C <pranavxc@gmail.com>

* feat: single page ui, test corrections

Signed-off-by: Pranav C <pranavxc@gmail.com>

* chore: tests

Signed-off-by: Pranav C <pranavxc@gmail.com>

* test: project rename test correction

Signed-off-by: Pranav C <pranavxc@gmail.com>

* chore: remove only

Signed-off-by: Pranav C <pranavxc@gmail.com>

* test: remove wrong import statement

Signed-off-by: Pranav C <pranavxc@gmail.com>

* fix: delete option not visible in project context menu

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* test: move ws access within isEE()

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* test: fix groupby

* test: groupby fix

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* docs: signup & landing page

* docs: project crud

* docs: project-crud misc

* docs: toolbar fields

* docs: toolbar / filters

* docs: toolbar / group by

* docs: toolbar / sort

* docs: toolbar / row height

* docs: filters additional options

* docs: file re-order

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* docs: add links to column types

* docs: code snippets

* docs: links

* docs: lookup

* docs: rollup

* docs: formula

* docs: primary key

* docs: display value

* docs: development setup

* docs: swagger

* fix(nc-gui): encodeURIComponent for row id

- closes: #6202

* docs: language

* docs: expanded record

* docs: import airtable

* docs: airtable

* docs: webhook

* docs: revert file rename

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* docs: account settings

* docs: audit

* docs: meta management

* docs: project settings

* docs: shared base

* docs: shared view

* docs: meta sync

* docs: team-auth

* docs: views

* docs: fix URL

* docs: URL corrections

* fix:  shared base, view related bugs

Signed-off-by: Pranav C <pranavxc@gmail.com>

* test: EE check for WSaccess

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* test: exclude EE tests

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* fix: missing project delete

closes #6215

Signed-off-by: Pranav C <pranavxc@gmail.com>

* fix: merge existing project meta  if found

closes #6216

Signed-off-by: Pranav C <pranavxc@gmail.com>

* fix: merge existing project meta  if found

closes #6216

Signed-off-by: Pranav C <pranavxc@gmail.com>

---------

Signed-off-by: Pranav C <pranavxc@gmail.com>
Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>
Co-authored-by: Raju Udava <86527202+dstala@users.noreply.github.com>
Co-authored-by: DarkPhoenix2704 <anbarasun123@gmail.com>
Co-authored-by: Wing-Kam Wong <wingkwong.code@gmail.com>

* refactor: docs and other bug fixes

Signed-off-by: Pranav C <pranavxc@gmail.com>

* feat: populate default project on super admin signup

Signed-off-by: Pranav C <pranavxc@gmail.com>

* fix: include created project details in signup response if avail, missing Dockerfile

Signed-off-by: Pranav C <pranavxc@gmail.com>

* chore: use custom function for resolving ts path aliases

Signed-off-by: Pranav C <pranavxc@gmail.com>

* chore: add missing generate script

Signed-off-by: Pranav C <pranavxc@gmail.com>

* chore: webpack build correction - ts path resolve

Signed-off-by: Pranav C <pranavxc@gmail.com>

---------

Signed-off-by: Pranav C <pranavxc@gmail.com>
Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>
Co-authored-by: mertmit <mertmit99@gmail.com>
Co-authored-by: Raju Udava <86527202+dstala@users.noreply.github.com>
Co-authored-by: DarkPhoenix2704 <anbarasun123@gmail.com>
Co-authored-by: Wing-Kam Wong <wingkwong.code@gmail.com>
2023-08-24 02:58:19 +05:30

211 lines
6.7 KiB
TypeScript

import { getI18n } from '../plugins/a.i18n'
export const validateEmail = (v: string) =>
/^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/i.test(v)
export const validateTableName = {
validator: (_: unknown, value: string) => {
return new Promise((resolve, reject) => {
const { t } = getI18n().global
if (!value) {
// return 'Table name required'
return reject(new Error(t('msg.error.tableNameRequired')))
}
// exclude . / \
// rest all characters allowed
// https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/acreldb/n0rfg6x1shw0ppn1cwhco6yn09f7.htm#:~:text=By%20default%2C%20MySQL%20encloses%20column,not%20truncate%20a%20longer%20name.
const m = value.match(/[./\\]/g)
if (m) {
// return `Following characters are not allowed ${m.map((c) => JSON.stringify(c)).join(', ')}`
return reject(
new Error(`${t('msg.error.followingCharactersAreNotAllowed')} ${m.map((c) => JSON.stringify(c)).join(', ')}`),
)
}
return resolve(true)
})
},
}
export const validateColumnName = {
validator: (_: unknown, value: string) => {
return new Promise((resolve, reject) => {
const { t } = getI18n().global
if (!value) {
// return 'Column name required'
return reject(new Error(t('msg.error.columnNameRequired')))
}
// exclude . / \
// rest all characters allowed
// https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/acreldb/n0rfg6x1shw0ppn1cwhco6yn09f7.htm#:~:text=By%20default%2C%20MySQL%20encloses%20column,not%20truncate%20a%20longer%20name.
const m = value.match(/[./\\]/g)
if (m) {
// return `Following characters are not allowed ${m.map((c) => JSON.stringify(c)).join(', ')}`
return reject(
new Error(`${t('msg.error.followingCharactersAreNotAllowed')} ${m.map((c) => JSON.stringify(c)).join(', ')}`),
)
}
return resolve(true)
})
},
}
export const layoutTitleValidator = {
validator: (rule: any, value: any) => {
const { t } = getI18n().global
return new Promise((resolve, reject) => {
if (value?.length > 250) {
reject(new Error(t('msg.error.layoutNameExceeds50Characters')))
}
if (value[0] === ' ') {
reject(new Error(t('msg.error.layoutNameCannotStartWithSpace')))
}
resolve(true)
})
},
}
export const projectTitleValidator = {
validator: (rule: any, value: any) => {
const { t } = getI18n().global
return new Promise((resolve, reject) => {
if (value?.length > 50) {
reject(new Error(t('msg.error.projectNameExceeds50Characters')))
}
if (value[0] === ' ') {
reject(new Error(t('msg.error.projectNameCannotStartWithSpace')))
}
resolve(true)
})
},
}
export const fieldRequiredValidator = () => {
const { t } = getI18n().global
return {
required: true,
// message: `Required field`,
message: t('msg.error.requiredField'),
}
}
export const fieldLengthValidator = (sqlClientType: string) => {
return {
validator: (rule: any, value: any) => {
const { t } = getI18n().global
// no limit for sqlite but set as 255
let fieldLengthLimit = 255
if (sqlClientType === 'mysql2' || sqlClientType === 'mysql') {
fieldLengthLimit = 64
} else if (sqlClientType === 'pg') {
fieldLengthLimit = 59
} else if (sqlClientType === 'mssql') {
fieldLengthLimit = 128
}
return new Promise((resolve, reject) => {
if (value?.length > fieldLengthLimit) {
reject(new Error(t('msg.error.columnNameExceedsCharacters', { value: fieldLengthLimit })))
}
resolve(true)
})
},
}
}
export const importUrlValidator = {
validator: (rule: any, value: any) => {
return new Promise((resolve, reject) => {
const { t } = getI18n().global
if (
/(10)(\.([2]([0-5][0-5]|[01234][6-9])|[1][0-9][0-9]|[1-9][0-9]|[0-9])){3}|(172)\.(1[6-9]|2[0-9]|3[0-1])(\.(2[0-4][0-9]|25[0-5]|[1][0-9][0-9]|[1-9][0-9]|[0-9])){2}|(192)\.(168)(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){2}|(0.0.0.0)|localhost?/g.test(
value,
)
) {
// return reject(new Error('IP Not allowed!'))
return reject(new Error(t('msg.error.ipNotAllowed')))
}
return resolve(true)
})
},
}
export const importCsvUrlValidator = {
validator: (rule: any, value: any) => {
return new Promise((resolve, reject) => {
const { t } = getI18n().global
if (value && !/.*\.(csv)/.test(value)) {
// return reject(new Error('Target file is not an accepted file type. The accepted file type is .csv!'))
return reject(
new Error(`${t('msg.error.targetFileIsNotAnAcceptedFileType')}. ${t('msg.error.theAcceptedFileTypeIsCsv')}`),
)
}
return resolve(true)
})
},
}
export const importExcelUrlValidator = {
validator: (rule: any, value: any) => {
return new Promise((resolve, reject) => {
const { t } = getI18n().global
if (value && !/.*\.(xls|xlsx|xlsm|ods|ots)/.test(value)) {
return reject(
// new Error('Target file is not an accepted file type. The accepted file types are .xls, .xlsx, .xlsm, .ods, .ots!'),
new Error(
`${t('msg.error.targetFileIsNotAnAcceptedFileType')}. ${t('msg.error.theAcceptedFileTypesAreXlsXlsxXlsmOdsOts')}`,
),
)
}
return resolve(true)
})
},
}
export const extraParameterValidator = {
validator: (_: unknown, value: { key: string; value: string }[]) => {
return new Promise((resolve, reject) => {
const { t } = getI18n().global
for (const param of value) {
if (param.key === '') {
// return reject(new Error('Parameter key cannot be empty'))
return reject(new Error(t('msg.error.parameterKeyCannotBeEmpty')))
}
if (value.filter((el: any) => el.key === param.key).length !== 1) {
// return reject(new Error('Duplicate parameter keys are not allowed'))
return reject(new Error(t('msg.error.duplicateParameterKeysAreNotAllowed')))
}
}
return resolve(true)
})
},
}
export const emailValidator = {
validator: (_: unknown, value: string) => {
return new Promise((resolve, reject) => {
if (!value || value.length === 0) {
return reject(new Error('Email is required'))
}
const invalidEmails = (value || '').split(/\s*,\s*/).filter((e: string) => !validateEmail(e))
if (invalidEmails.length > 0) {
return reject(
new Error(`${invalidEmails.length > 1 ? ' Invalid emails:' : 'Invalid email:'} ${invalidEmails.join(', ')} `),
)
}
return resolve(true)
})
},
}