2
0
mirror of https://github.com/frappe/books.git synced 2024-11-10 07:40:55 +00:00

feat: added importer settings

This commit is contained in:
18alantom 2022-02-23 17:15:20 +05:30
parent 916d0ecee4
commit 16c0bfe4fc
2 changed files with 146 additions and 54 deletions

View File

@ -175,6 +175,8 @@ export class Importer {
requiredMap: Map = {};
labelTemplateFieldMap: LabelTemplateFieldMap = {};
shouldSubmit: boolean = false;
labelIndex: number = -1;
csv: string[][] = [];
constructor(doctype: string) {
this.doctype = doctype;
@ -272,23 +274,38 @@ export class Importer {
}
selectFile(text: string): boolean {
const csv = parseCSV(text);
this.parsedLabels = csv[0];
const values = csv.slice(1);
/*
if (values.some((v) => v.length !== this.parsedLabels.length)) {
return false;
}
*/
this.parsedValues = values;
this._setAssigned();
this.csv = parseCSV(text);
this.initialize(0, true);
return true;
}
_setAssigned() {
initialize(labelIndex: number, force: boolean) {
if (
(typeof labelIndex !== 'number' && !labelIndex) ||
(labelIndex === this.labelIndex && !force)
) {
return;
}
console.log('initing', labelIndex);
this.labelIndex = labelIndex;
this.parsedLabels = this.csv[labelIndex];
const values = this.csv.slice(labelIndex + 1);
this.parsedValues = values;
this.setAssigned();
}
setAssigned() {
const labels = [...this.parsedLabels];
for (const k of Object.keys(this.assignedMap)) {
const l = this.assignedMap[k] as string;
if (!labels.includes(l)) {
this.assignedMap[k] = '';
}
}
labels.forEach((l) => {
if (this.assignedMap[l] !== '') {
return;
@ -343,6 +360,9 @@ export class Importer {
try {
await doc.insert();
if (this.shouldSubmit) {
await doc.submit();
}
} catch (err) {
const message = (err as Error).message;
@ -372,6 +392,3 @@ export class Importer {
return status;
}
}
// @ts-ignore
window.gtf = getTemplateFields;

View File

@ -36,35 +36,6 @@
@change="setImportType"
/>
<div
v-if="importType && isSubmittable"
class="
justify-center
items-center
gap-2
flex
justify-between
items-center
bg-gray-100
px-2
py-1
rounded
text-gray-900
"
>
<p>Should Submit</p>
<FormControl
size="small"
input-class="bg-gray-100"
:df="{
fieldname: 'shouldSubmit',
label: this.t`Submit on Import`,
fieldtype: 'Check',
}"
:value="Number(importer.shouldSubmit)"
@change="(value) => (importer.shouldSubmit = !!value)"
/>
</div>
<p
class="text-base text-base ml-2"
:class="fileName ? 'text-gray-900 font-semibold' : 'text-gray-700'"
@ -79,6 +50,86 @@
</p>
</div>
<!-- Settings -->
<div v-if="fileName" class="">
<h2 class="text-lg font-semibold">{{ t`Importer Settings` }}</h2>
<div class="mt-4 flex gap-2">
<button
class="w-28 bg-gray-100 focus:bg-gray-200 rounded-md"
@click="importer.initialize(0, true)"
>
<span class="text-red-400">
{{ t`Reset` }}
</span>
</button>
<div
v-if="file && isSubmittable"
class="
justify-center
items-center
gap-2
flex
justify-between
items-center
bg-gray-100
px-2
rounded
text-gray-900
w-40
"
>
<p>{{ frappe.t`Submit on Import` }}</p>
<FormControl
size="small"
input-class="bg-gray-100"
:df="{
fieldname: 'shouldSubmit',
fieldtype: 'Check',
}"
:value="Number(importer.shouldSubmit)"
@change="(value) => (importer.shouldSubmit = !!value)"
/>
</div>
<div
class="
flex flex-row
justify-center
items-center
justify-center
items-center
gap-2
flex
justify-between
items-center
bg-gray-100
pl-2
rounded
text-gray-900
w-40
"
>
<p class="text-gray-900">{{ t`Label Index` }}</p>
<input
type="number"
class="
bg-gray-100
outline-none
focus:bg-gray-200
px-2
py-1
rounded-md
w-10
text-right
"
min="1"
:max="importer.csv.length - 1"
:value="labelIndex + 1"
@change="setLabelIndex"
/>
</div>
</div>
</div>
<!-- Label Assigner -->
<div v-if="fileName" class="pb-4">
<h2 class="text-lg font-semibold">{{ t`Assign Imported Labels` }}</h2>
@ -106,7 +157,7 @@
</div>
<p
class="text-red-400 text-sm mt-1 -mb-1 p-0 h-0"
v-if="requiredUnassigned"
v-if="isRequiredUnassigned"
>
{{ t`* required fields` }}
</p>
@ -223,7 +274,7 @@ 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 { getSavePath, saveData, showMessageDialog, showToast } from '@/utils';
import { ipcRenderer } from 'electron';
import frappe from 'frappe';
export default {
@ -244,10 +295,16 @@ export default {
};
},
computed: {
labelIndex(){
return this.importer.labelIndex
},
requiredUnassigned() {
return this.importer.assignableLabels
.filter((k) => this.importer.requiredMap[k])
.some((k) => !this.importer.assignedMap[k]);
return this.importer.assignableLabels.filter(
(k) => this.importer.requiredMap[k] && !this.importer.assignedMap[k]
);
},
isRequiredUnassigned() {
return this.requiredUnassigned.length > 0;
},
assignedMatrix() {
return this.importer.assignedMatrix;
@ -350,6 +407,10 @@ export default {
this.saveTemplate();
},
setLabelIndex(e) {
const labelIndex = (e.target.value ?? 1) - 1;
this.importer.initialize(labelIndex);
},
async saveTemplate() {
const template = this.importer.template;
const templateName = this.importType + ' ' + this.t`Template`;
@ -382,10 +443,24 @@ export default {
this.importer.updateValue(event.target.value, i, j);
},
async importData() {
// TODO: pre import conditions
/*
if(){}
*/
if (this.isRequiredUnassigned) {
showMessageDialog({
message: this.t`Required Fields not Assigned`,
description: this
.t`Please assign the following fields ${this.requiredUnassigned.join(
', '
)}`,
});
return;
}
if (this.importer.assignedMatrix.length === 0) {
showMessageDialog({
message: this.t`No Data to Import`,
description: this.t`Please select a file with data to import.`,
});
return;
}
const { success, names } = await this.importer.importData();
if (!success || !names.length) {