diff --git a/packages/nc-gui-v2/components.d.ts b/packages/nc-gui-v2/components.d.ts index 9b0fa75f45..79e596ccda 100644 --- a/packages/nc-gui-v2/components.d.ts +++ b/packages/nc-gui-v2/components.d.ts @@ -202,6 +202,7 @@ declare module '@vue/runtime-core' { MdiSearch: typeof import('~icons/mdi/search')['default'] MdiShieldLockOutline: typeof import('~icons/mdi/shield-lock-outline')['default'] MdiSlack: typeof import('~icons/mdi/slack')['default'] + MdiSort: typeof import('~icons/mdi/sort')['default'] MdiStar: typeof import('~icons/mdi/star')['default'] MdiStarOutline: typeof import('~icons/mdi/star-outline')['default'] MdiStore: typeof import('~icons/mdi/store')['default'] diff --git a/packages/nc-gui-v2/components/cell/Text.vue b/packages/nc-gui-v2/components/cell/Text.vue index 2c8e54d0d7..23575fc222 100644 --- a/packages/nc-gui-v2/components/cell/Text.vue +++ b/packages/nc-gui-v2/components/cell/Text.vue @@ -1,10 +1,9 @@ - + @@ -124,6 +142,7 @@ const { isSharedForm } = useSmartsheetStoreOrThrow() + @@ -144,7 +162,7 @@ const { isSharedForm } = useSmartsheetStoreOrThrow() ([]) - /** keep user selected File object */ - const storedFiles = ref([]) + const storedFiles = ref([]) const attachments = ref([]) @@ -54,37 +60,41 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState( /** remove a file from our stored attachments (either locally stored or saved ones) */ function removeFile(i: number) { if (isPublic.value) { - storedFilesData.value.splice(i, 1) storedFiles.value.splice(i, 1) - updateModelValue(storedFilesData.value.map((storedFile) => storedFile.file)) + updateModelValue(storedFiles.value.map((stored) => stored.file)) } else { attachments.value.splice(i, 1) + updateModelValue(attachments.value) } } /** save a file on select / drop, either locally (in-memory) or in the db */ async function onFileSelect(selectedFiles: FileList | File[]) { - if (!selectedFiles.length || isPublicGrid) return + if (!selectedFiles.length) return if (isPublic.value) { - storedFiles.value.push(...selectedFiles) - storedFilesData.value.push( + storedFiles.value.push( ...(await Promise.all( Array.from(selectedFiles).map( (file) => new Promise((resolve) => { - const res: AttachmentProps = { file, title: file.name } - if (isImage(file.name, (file as any).mimetype)) { + const res: AttachmentProps = { ...file, file, title: file.name, mimetype: file.type } + + if (isImage(file.name, (file).mimetype ?? file.type)) { const reader = new FileReader() - reader.onload = (e: any) => { + + reader.onload = (e) => { res.data = e.target?.result + resolve(res) } + reader.onerror = () => { resolve(res) } + reader.readAsDataURL(file) } else { resolve(res) @@ -94,7 +104,7 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState( )), ) - return updateModelValue(storedFilesData.value.map((storedFile) => storedFile.file)) + return updateModelValue(storedFiles.value.map((stored) => stored.file)) } const newAttachments = [] @@ -149,17 +159,14 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState( } /** our currently visible items, either the locally stored or the ones from db, depending on isPublicForm status */ - const visibleItems = computed(() => (isPublic.value ? storedFilesData.value : attachments.value) || ([] as any[])) + const visibleItems = computed(() => (isPublic.value ? storedFiles.value : attachments.value)) watch(files, (nextFiles) => nextFiles && onFileSelect(nextFiles)) return { attachments, - storedFilesData, visibleItems, isPublic, - isForm, - isPublicGrid, isReadonly, meta, column, diff --git a/packages/nc-gui-v2/components/general/HelpAndSupport.vue b/packages/nc-gui-v2/components/general/HelpAndSupport.vue index a5e414c7d4..6477d5322d 100644 --- a/packages/nc-gui-v2/components/general/HelpAndSupport.vue +++ b/packages/nc-gui-v2/components/general/HelpAndSupport.vue @@ -25,6 +25,7 @@ const openSwaggerLink = () => { -import { RelationTypes, UITypes, isVirtualCol } from 'nocodb-sdk' -import { useSharedFormStoreOrThrow } from '#imports' - -const { - sharedFormView, - submitForm, - v$, - formState, - notFound, - formColumns, - submitted, - secondsRemain, - passwordDlg, - password, - loadSharedView, -} = useSharedFormStoreOrThrow() - -function isRequired(_columnObj: Record, required = false) { - let columnObj = _columnObj - if ( - columnObj.uidt === UITypes.LinkToAnotherRecord && - columnObj.colOptions && - columnObj.colOptions.type === RelationTypes.BELONGS_TO - ) { - columnObj = formColumns.value?.find((c: Record) => c.id === columnObj.colOptions.fk_child_column_id) as Record< - string, - any - > - } - - return required || (columnObj && columnObj.rqd && !columnObj.cdf) -} - - - - - - - - - - - - - - - - - New form will be loaded after {{ secondsRemain }} seconds - - - Submit Another Form - - - - - - - - - - - - - - - NocoDB - - - - - - - {{ sharedFormView.heading }} - - - - {{ sharedFormView.subheading }} - - - - - - - - - - {{ field.description }} - - - {{ error.$message }} - - - - - - {{ field.description }} - - - {{ error.$message }} - - - - - - - Submit - - - - - - - - - - - - - - This shared view is protected - - - - - Unlock - - - - - - - diff --git a/packages/nc-gui-v2/components/smartsheet-toolbar/SortListMenu.vue b/packages/nc-gui-v2/components/smartsheet-toolbar/SortListMenu.vue index b91c78f768..704f21c48a 100644 --- a/packages/nc-gui-v2/components/smartsheet-toolbar/SortListMenu.vue +++ b/packages/nc-gui-v2/components/smartsheet-toolbar/SortListMenu.vue @@ -1,27 +1,34 @@ - + + + diff --git a/packages/nc-gui-v2/pages/[projectType]/form/[viewId]/index.vue b/packages/nc-gui-v2/pages/[projectType]/form/[viewId]/index.vue new file mode 100644 index 0000000000..97b17d9724 --- /dev/null +++ b/packages/nc-gui-v2/pages/[projectType]/form/[viewId]/index.vue @@ -0,0 +1,174 @@ + + + + + + + + {{ sharedFormView.heading }} + + {{ sharedFormView.subheading }} + + + + + + + + + + New form will be loaded after {{ secondsRemain }} seconds + + + + Submit Another Form + + + + + + + + + + + + + + + + + + + {{ field.description }} + + + + {{ error.$message }} + + + + + + + + {{ field.description }} + + + + {{ error.$message }} + + + + + + + + {{ $t('general.submit') }} + + + + + + + + + This shared view is protected + + + + + + + + Unlock + + + + + + + + diff --git a/packages/nc-gui-v2/utils/urlUtils.ts b/packages/nc-gui-v2/utils/urlUtils.ts index 95c3aeb41a..e6bf9d8c74 100644 --- a/packages/nc-gui-v2/utils/urlUtils.ts +++ b/packages/nc-gui-v2/utils/urlUtils.ts @@ -21,10 +21,11 @@ export const replaceUrlsWithLink = (text: string): boolean | string => { export const isValidURL = (str: string) => { const pattern = /^(?:(?:https?|ftp):\/\/)?(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00A1-\uFFFF0-9]-*)*[a-z\u00A1-\uFFFF0-9]+)(?:\.(?:[a-z\u00A1-\uFFFF0-9]-*)*[a-z\u00A1-\uFFFF0-9]+)*(?:\.(?:[a-z\u00A1-\uFFFF]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/i - return !!pattern.test(str) + + return pattern.test(str) } -export const openLink = (path: string, baseURL: string, target = '_blank') => { +export const openLink = (path: string, baseURL?: string, target = '_blank') => { const url = new URL(path, baseURL) window.open(url.href, target) } diff --git a/packages/nc-gui-v2/windi.config.ts b/packages/nc-gui-v2/windi.config.ts index 306b909724..5762ea30d4 100644 --- a/packages/nc-gui-v2/windi.config.ts +++ b/packages/nc-gui-v2/windi.config.ts @@ -65,10 +65,6 @@ export default defineConfig({ primary: 'rgba(var(--color-primary), var(--tw-bg-opacity))', accent: 'rgba(var(--color-accent), var(--tw-bg-opacity))', }, - ringColor: { - primary: 'rgba(var(--color-primary), var(--tw-ring-opacity))', - accent: 'rgba(var(--color-accent), var(--tw-ring-opacity))', - }, colors: { ...windiColors, ...themeColors,
- New form will be loaded after {{ secondsRemain }} seconds -
+ New form will be loaded after {{ secondsRemain }} seconds +