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:
parent
916d0ecee4
commit
16c0bfe4fc
@ -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;
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user