mirror of
https://github.com/frappe/books.git
synced 2024-12-23 11:29:03 +00:00
feat: mark required fields
This commit is contained in:
parent
15bb03136a
commit
5f4cbe1795
@ -17,7 +17,7 @@ type Exclusion = {
|
||||
};
|
||||
|
||||
type Map = {
|
||||
[key: string]: string;
|
||||
[key: string]: string | boolean;
|
||||
};
|
||||
|
||||
interface TemplateField {
|
||||
@ -105,6 +105,7 @@ export class Importer {
|
||||
parsedLabels: string[] = [];
|
||||
parsedValues: string[][] = [];
|
||||
assignedMap: Map = {}; // target: import
|
||||
requiredMap: Map = {};
|
||||
|
||||
constructor(doctype: string) {
|
||||
this.doctype = doctype;
|
||||
@ -115,10 +116,25 @@ export class Importer {
|
||||
acc[k] = '';
|
||||
return acc;
|
||||
}, {});
|
||||
this.requiredMap = this.templateFields.reduce((acc: Map, k) => {
|
||||
acc[k.label] = k.required;
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
|
||||
get assignableLabels() {
|
||||
return Object.keys(this.map);
|
||||
const req: string[] = [];
|
||||
const nreq: string[] = [];
|
||||
Object.keys(this.map).forEach((k) => {
|
||||
if (this.requiredMap[k]) {
|
||||
req.push(k);
|
||||
return;
|
||||
}
|
||||
|
||||
nreq.push(k);
|
||||
});
|
||||
|
||||
return [...req, ...nreq];
|
||||
}
|
||||
|
||||
get unassignedLabels() {
|
||||
@ -129,25 +145,30 @@ export class Importer {
|
||||
}
|
||||
|
||||
get columnLabels() {
|
||||
const assigned: string[] = [];
|
||||
const unassigned: string[] = [];
|
||||
const req: string[] = [];
|
||||
const nreq: string[] = [];
|
||||
|
||||
this.assignableLabels.forEach((k) => {
|
||||
if (this.assignedMap[k]) {
|
||||
assigned.push(k);
|
||||
if (!this.assignedMap[k]) {
|
||||
return;
|
||||
}
|
||||
unassigned.push(k);
|
||||
|
||||
if (this.requiredMap[k]) {
|
||||
req.push(k);
|
||||
return;
|
||||
}
|
||||
|
||||
nreq.push(k);
|
||||
});
|
||||
|
||||
return [...assigned];
|
||||
return [...req, ...nreq];
|
||||
}
|
||||
|
||||
get assignedMatrix() {
|
||||
this.indices = this.columnLabels
|
||||
.map((k) => this.assignedMap[k])
|
||||
.filter(Boolean)
|
||||
.map((k) => this.parsedLabels.indexOf(k));
|
||||
.map((k) => this.parsedLabels.indexOf(k as string));
|
||||
|
||||
const rows = this.parsedValues.length;
|
||||
const cols = this.columnLabels.length;
|
||||
|
@ -47,21 +47,34 @@
|
||||
</div>
|
||||
|
||||
<!-- Label Assigner -->
|
||||
<div v-if="fileName">
|
||||
<div v-if="fileName" class="pb-4">
|
||||
<h2 class="text-lg font-semibold">{{ t`Assign Imported Labels` }}</h2>
|
||||
<div class="gap-2 mt-4 grid grid-flow-col overflow-x-scroll pb-4">
|
||||
<FormControl
|
||||
:show-label="true"
|
||||
size="small"
|
||||
class="w-28"
|
||||
input-class="bg-gray-100"
|
||||
v-for="(f, k) in importer.assignableLabels"
|
||||
:df="getAssignerField(f)"
|
||||
:value="importer.assignedMap[f] ?? ''"
|
||||
@change="(v) => onAssignedChange(f, v)"
|
||||
:key="f + '-' + k"
|
||||
/>
|
||||
<div class="gap-2 mt-4 grid grid-flow-col overflow-x-scroll">
|
||||
<div v-for="(f, k) in importer.assignableLabels" :key="f + '-' + k">
|
||||
<p class="text-gray-600 text-sm mb-1">
|
||||
{{ f }}
|
||||
<span
|
||||
v-if="importer.requiredMap[f] && !importer.assignedMap[f]"
|
||||
class="text-red-400"
|
||||
>*</span
|
||||
>
|
||||
</p>
|
||||
<FormControl
|
||||
size="small"
|
||||
class="w-28"
|
||||
input-class="bg-gray-100"
|
||||
:df="getAssignerField(f)"
|
||||
:value="importer.assignedMap[f] ?? ''"
|
||||
@change="(v) => onAssignedChange(f, v)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
class="text-red-400 text-sm mt-1 -mb-1 p-0 h-0"
|
||||
v-if="requiredUnassigned"
|
||||
>
|
||||
{{ t`* required fields` }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Data Verifier -->
|
||||
@ -133,16 +146,16 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import FormControl from '@/components/Controls/FormControl';
|
||||
import PageHeader from '@/components/PageHeader.vue';
|
||||
import { importable, Importer } from '@/dataImport';
|
||||
import frappe from 'frappe';
|
||||
import Button from '@/components/Button.vue';
|
||||
import { ipcRenderer } from 'electron';
|
||||
import { IPC_ACTIONS } from '@/messages';
|
||||
import { getSavePath, saveData, showToast } from '@/utils';
|
||||
import FormControl from '@/components/Controls/FormControl';
|
||||
import DropdownWithActions from '@/components/DropdownWithActions.vue';
|
||||
import FeatherIcon from '@/components/FeatherIcon.vue';
|
||||
import PageHeader from '@/components/PageHeader.vue';
|
||||
import { importable, Importer } from '@/dataImport';
|
||||
import { IPC_ACTIONS } from '@/messages';
|
||||
import { getSavePath, saveData, showToast } from '@/utils';
|
||||
import { ipcRenderer } from 'electron';
|
||||
import frappe from 'frappe';
|
||||
export default {
|
||||
components: {
|
||||
PageHeader,
|
||||
@ -159,6 +172,11 @@ export default {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
requiredUnassigned() {
|
||||
return this.importer.assignableLabels
|
||||
.filter((k) => this.importer.requiredMap[k])
|
||||
.some((k) => !this.importer.assignedMap[k]);
|
||||
},
|
||||
assignedMatrix() {
|
||||
return this.importer.assignedMatrix;
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user