|
|
@ -1,29 +1,22 @@ |
|
|
|
<script lang="ts" setup> |
|
|
|
<script lang="ts" setup> |
|
|
|
import { RelationTypes, UITypes, isVirtualCol } from 'nocodb-sdk' |
|
|
|
import { RelationTypes, UITypes, isVirtualCol } from 'nocodb-sdk' |
|
|
|
import { StreamBarcodeReader } from 'vue-barcode-reader' |
|
|
|
import { useSharedFormStoreOrThrow } from '#imports' |
|
|
|
import { NOCO, useSharedFormStoreOrThrow } from '#imports' |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import QrCodeScan from '~icons/mdi/qrcode-scan' |
|
|
|
const { sharedFormView, submitForm, v$, formState, notFound, formColumns, submitted, secondsRemain, isLoading } = |
|
|
|
|
|
|
|
|
|
|
|
// const meta = inject(MetaInj, ref()) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const { t } = useI18n() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const showCodeScannerOverlay = ref(false) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const lastScannedCode = ref('') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const scannerIsReady = ref(false) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: better use directly scannerIsReady |
|
|
|
|
|
|
|
const showScannerField = computed(() => scannerIsReady.value) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const { formColumns } = |
|
|
|
|
|
|
|
useSharedFormStoreOrThrow() |
|
|
|
useSharedFormStoreOrThrow() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function isRequired(_columnObj: Record<string, any>, required = false) { |
|
|
|
|
|
|
|
let columnObj = _columnObj |
|
|
|
|
|
|
|
if ( |
|
|
|
|
|
|
|
columnObj.uidt === UITypes.LinkToAnotherRecord && |
|
|
|
|
|
|
|
columnObj.colOptions && |
|
|
|
|
|
|
|
columnObj.colOptions.type === RelationTypes.BELONGS_TO |
|
|
|
|
|
|
|
) { |
|
|
|
|
|
|
|
columnObj = formColumns.value?.find((c) => c.id === columnObj.colOptions.fk_child_column_id) as Record<string, any> |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return !!(required || (columnObj && columnObj.rqd && !columnObj.cdf)) |
|
|
|
|
|
|
|
} |
|
|
|
</script> |
|
|
|
</script> |
|
|
|
|
|
|
|
|
|
|
|
<template> |
|
|
|
<template> |
|
|
@ -108,13 +101,24 @@ const { formColumns } = |
|
|
|
:edit-enabled="true" |
|
|
|
:edit-enabled="true" |
|
|
|
/> |
|
|
|
/> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="flex flex-col gap-2 text-slate-500 dark:text-slate-300 text-[0.75rem] my-2 px-1"> |
|
|
|
|
|
|
|
<div v-for="error of v$.localState[field.title]?.$errors" :key="error" class="text-red-500"> |
|
|
|
|
|
|
|
{{ error.$message }} |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{{ field.description }} |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div> |
|
|
|
<div> |
|
|
|
SCANNER PLACEHOLDER |
|
|
|
SCANNER PLACEHOLDER |
|
|
|
|
|
|
|
|
|
|
|
<a-button class="nc-btn-find-row-by-scan nc-toolbar-btn" @click="showCodeScannerOverlay = true"> |
|
|
|
<a-button class="nc-btn-find-row-by-scan nc-toolbar-btn" @click="showCodeScannerOverlay = true"> |
|
|
|
<div class="flex items-center gap-1"> |
|
|
|
<div class="flex items-center gap-1"> |
|
|
|
<QrCodeScan /> |
|
|
|
<QrCodeScan /> |
|
|
|
<span class="!text-xs font-weight-normal"> {{ $t('activity.fillByCodeScan') }}</span> |
|
|
|
<span class="!text-xs font-weight-normal"> |
|
|
|
|
|
|
|
{{ $t('activity.findRowByCodeScan') }}</span |
|
|
|
|
|
|
|
> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</a-button> |
|
|
|
</a-button> |
|
|
|
<a-modal |
|
|
|
<a-modal |
|
|
@ -128,16 +132,12 @@ const { formColumns } = |
|
|
|
@cancel="scannerIsReady = false" |
|
|
|
@cancel="scannerIsReady = false" |
|
|
|
> |
|
|
|
> |
|
|
|
<div class="relative flex flex-col h-full"> |
|
|
|
<div class="relative flex flex-col h-full"> |
|
|
|
<a-form-item :label="$t('labels.columnToScanFor')"> |
|
|
|
|
|
|
|
<a-select v-model:value="selectedCodeColumnIdToScanFor" class="w-full" :options="codeFieldOptions" /> |
|
|
|
|
|
|
|
</a-form-item> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div> |
|
|
|
<div> |
|
|
|
<StreamBarcodeReader v-show="showScannerField" @decode="onDecode" @loaded="onLoaded"> |
|
|
|
<StreamBarcodeReader |
|
|
|
</StreamBarcodeReader> |
|
|
|
v-show="showScannerField" |
|
|
|
<div v-if="showPleaseSelectColumnMessage" class="text-left text-wrap mt-2 text-[#e65100] text-xs"> |
|
|
|
@decode="onDecode" |
|
|
|
{{ $t('msg.info.codeScanner.selectColumn') }} |
|
|
|
@loaded="onLoaded" |
|
|
|
</div> |
|
|
|
></StreamBarcodeReader> |
|
|
|
<div v-if="showScannerIsLoadingMessage" class="text-left text-wrap mt-2 text-[#e65100] text-xs"> |
|
|
|
<div v-if="showScannerIsLoadingMessage" class="text-left text-wrap mt-2 text-[#e65100] text-xs"> |
|
|
|
{{ $t('msg.info.codeScanner.loadingScanner') }} |
|
|
|
{{ $t('msg.info.codeScanner.loadingScanner') }} |
|
|
|
</div> |
|
|
|
</div> |
|
|
@ -146,13 +146,8 @@ const { formColumns } = |
|
|
|
</a-modal> |
|
|
|
</a-modal> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<div class="flex flex-col gap-2 text-slate-500 dark:text-slate-300 text-[0.75rem] my-2 px-1"> |
|
|
|
|
|
|
|
<div v-for="error of v$.localState[field.title]?.$errors" :key="error" class="text-red-500"> |
|
|
|
|
|
|
|
{{ error.$message }} |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{{ field.description }} |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|