-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Implemented: support to save mappings and apply already available mappings(#192)
- Loading branch information
Showing
21 changed files
with
1,006 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
<template> | ||
<ion-header> | ||
<ion-toolbar> | ||
<ion-buttons slot="start"> | ||
<ion-button @click="closeModal"> | ||
<ion-icon :icon="close" /> | ||
</ion-button> | ||
</ion-buttons> | ||
<ion-title>{{ $t("CSV Mapping") }}</ion-title> | ||
</ion-toolbar> | ||
</ion-header> | ||
|
||
<ion-item> | ||
<ion-label>{{ $t("Mapping name") }}</ion-label> | ||
<ion-input :placeholder="$t('Field mapping name')" v-model="mappingName" /> | ||
</ion-item> | ||
|
||
<ion-content class="ion-padding"> | ||
<div> | ||
<ion-list> | ||
<ion-item :key="field" v-for="(fieldValues, field) in fieldMapping"> | ||
<ion-label>{{ $t(fieldValues.label) }}</ion-label> | ||
<ion-input v-if="mappingType === 'EXPORD'" slot="end" v-model="fieldValues.value"></ion-input> | ||
<ion-select v-else interface="popover" :placeholder = "$t('Select')" v-model="fieldValues.value"> | ||
<ion-select-option :key="index" v-for="(prop, index) in fileColumns">{{ prop }}</ion-select-option> | ||
</ion-select> | ||
</ion-item> | ||
</ion-list> | ||
</div> | ||
<ion-fab vertical="bottom" horizontal="end" slot="fixed"> | ||
<ion-fab-button @click="saveMapping"> | ||
<ion-icon :icon="saveOutline" /> | ||
</ion-fab-button> | ||
</ion-fab> | ||
</ion-content> | ||
</template> | ||
|
||
<script lang="ts"> | ||
import { | ||
IonButtons, | ||
IonButton, | ||
IonContent, | ||
IonHeader, | ||
IonIcon, | ||
IonFab, | ||
IonFabButton, | ||
IonInput, | ||
IonTitle, | ||
IonToolbar, | ||
IonLabel, | ||
IonItem, | ||
IonList, | ||
IonSelect, | ||
IonSelectOption, | ||
modalController | ||
} from "@ionic/vue"; | ||
import { defineComponent } from "vue"; | ||
import { close, save, saveOutline } from "ionicons/icons"; | ||
import { useStore, mapGetters } from "vuex"; | ||
import { showToast } from '@/utils'; | ||
import { translate } from "@/i18n"; | ||
export default defineComponent({ | ||
name: "CreateMappingModal", | ||
components: { | ||
IonButtons, | ||
IonButton, | ||
IonContent, | ||
IonFab, | ||
IonFabButton, | ||
IonHeader, | ||
IonIcon, | ||
IonInput, | ||
IonSelect, | ||
IonSelectOption, | ||
IonTitle, | ||
IonToolbar, | ||
IonLabel, | ||
IonItem, | ||
IonList | ||
}, | ||
data() { | ||
return { | ||
mappingName: "", | ||
fieldMapping: {} as any, | ||
fileColumns: [] as any | ||
} | ||
}, | ||
props: ["content", "mappings", "mappingType"], | ||
mounted() { | ||
// mappings needs to be in format { <key>: { value: <value>, label: <label>, isSelected | optional: <boolean> }} | ||
this.fieldMapping = JSON.parse(JSON.stringify(this.mappings)); | ||
this.fileColumns = Object.keys(this.content[0]); | ||
}, | ||
computed: { | ||
...mapGetters({ | ||
fieldMappings: 'user/getFieldMappings' | ||
}) | ||
}, | ||
methods: { | ||
closeModal() { | ||
modalController.dismiss({ dismissed: true }); | ||
}, | ||
async saveMapping() { | ||
if(!this.mappingName) { | ||
showToast(translate("Enter mapping name")); | ||
return | ||
} | ||
if (!this.areAllFieldsSelected()) { | ||
showToast(translate("Map all fields")); | ||
return | ||
} | ||
const id = this.generateUniqueMappingPrefId(); | ||
// removing label from mappings as we don't need to save label with the mappings as it will just increase the size of the value | ||
Object.keys(this.fieldMapping).map((mapping) => { | ||
this.fieldMapping[mapping] && delete this.fieldMapping[mapping].label | ||
return; | ||
}) | ||
await this.store.dispatch("user/createFieldMapping", { id, name: this.mappingName, value: this.fieldMapping, mappingType: this.mappingType }) | ||
this.closeModal(); | ||
}, | ||
areAllFieldsSelected() { | ||
return Object.values(this.fieldMapping).every((field: any) => field.value !== ""); | ||
}, | ||
//Todo: Generating unique identifiers as we are currently storing in local storage. Need to remove it as we will be storing data on server. | ||
generateUniqueMappingPrefId(): any { | ||
const id = Math.floor(Math.random() * 1000); | ||
return !this.fieldMappings[id] ? id : this.generateUniqueMappingPrefId(); | ||
} | ||
}, | ||
setup() { | ||
const store = useStore(); | ||
return { | ||
close, | ||
save, | ||
saveOutline, | ||
store | ||
}; | ||
} | ||
}); | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
<template> | ||
<section> | ||
<ion-item> | ||
<ion-label>{{ $t("Mapping name") }}</ion-label> | ||
<ion-input v-model="currentMapping.name" /> | ||
</ion-item> | ||
|
||
<ion-list> | ||
<ion-item :key="field" v-for="(fieldValues, field) in currentMapping.value"> | ||
<ion-label>{{ fields[field] ? fields[field].label : field }}</ion-label> | ||
<ion-input v-model="fieldValues.value" /> | ||
</ion-item> | ||
</ion-list> | ||
|
||
<div class="ion-padding-top actions desktop-only"> | ||
<div> | ||
<ion-button size="small" @click="updateMapping()"> | ||
<ion-icon slot="start" :icon="saveOutline"/> | ||
{{ $t("Save Changes") }} | ||
</ion-button> | ||
<ion-button size="small" fill="outline" color="danger" @click="deleteMapping()"> | ||
<ion-icon slot="start" :icon="trashOutline" /> | ||
{{ $t("Delete mapping") }} | ||
</ion-button> | ||
</div> | ||
</div> | ||
|
||
<div class="ion-padding-top actions mobile-only"> | ||
<ion-button expand="block" @click="updateMapping()"> | ||
<ion-icon slot="start" :icon="saveOutline"/> | ||
{{ $t("Save Changes") }} | ||
</ion-button> | ||
<ion-button fill="outline" color="danger" expand="block" @click="deleteMapping()"> | ||
<ion-icon slot="start" :icon="trashOutline" /> | ||
{{ $t("Delete mapping") }} | ||
</ion-button> | ||
</div> | ||
</section> | ||
</template> | ||
|
||
<script lang="ts"> | ||
import { | ||
alertController, | ||
IonButton, | ||
IonIcon, | ||
IonInput, | ||
IonLabel, | ||
IonItem, | ||
IonList | ||
} from "@ionic/vue"; | ||
import { defineComponent } from "vue"; | ||
import { close, save, saveOutline, trashOutline } from "ionicons/icons"; | ||
import { useStore, mapGetters } from "vuex"; | ||
import { showToast } from "@/utils"; | ||
import { translate } from "@/i18n"; | ||
export default defineComponent({ | ||
name: "MappingConfiguration", | ||
components: { | ||
IonButton, | ||
IonIcon, | ||
IonInput, | ||
IonLabel, | ||
IonItem, | ||
IonList | ||
}, | ||
computed: { | ||
...mapGetters({ | ||
currentMapping: 'user/getCurrentMapping' | ||
}) | ||
}, | ||
data() { | ||
return { | ||
fields: {} as any | ||
} | ||
}, | ||
mounted() { | ||
const fields = process.env["VUE_APP_MAPPING_" + this.currentMapping.mappingType]; | ||
this.fields = fields ? JSON.parse(fields) : {}; | ||
}, | ||
methods: { | ||
async deleteMapping() { | ||
const message = this.$t("Are you sure you want to delete this CSV mapping? This action cannot be undone."); | ||
const alert = await alertController.create({ | ||
header: this.$t("Delete mapping"), | ||
message, | ||
buttons: [ | ||
{ | ||
text: this.$t("Cancel"), | ||
}, | ||
{ | ||
text: this.$t("Delete"), | ||
handler: () => { | ||
this.store.dispatch("user/deleteFieldMapping", this.currentMapping)} | ||
} | ||
], | ||
}); | ||
return alert.present(); | ||
}, | ||
areAllFieldsSelected() { | ||
return Object.values(this.currentMapping.value).every((field: any) => field.value !== ""); | ||
}, | ||
async updateMapping() { | ||
if(!this.currentMapping.name) { | ||
showToast(translate("Enter mapping name")); | ||
return; | ||
} | ||
if (!this.areAllFieldsSelected()) { | ||
showToast(translate("Map all fields")); | ||
return; | ||
} | ||
const message = this.$t("Are you sure you want to update this CSV mapping? This action cannot be undone."); | ||
const alert = await alertController.create({ | ||
header: this.$t("Update mapping"), | ||
message, | ||
buttons: [ | ||
{ | ||
text: this.$t("Cancel"), | ||
}, | ||
{ | ||
text: this.$t("Update"), | ||
handler: () => { | ||
this.store.dispatch('user/updateFieldMapping', this.currentMapping) | ||
} | ||
} | ||
], | ||
}); | ||
return alert.present(); | ||
} | ||
}, | ||
setup() { | ||
const store = useStore(); | ||
return { | ||
close, | ||
save, | ||
saveOutline, | ||
trashOutline, | ||
store | ||
}; | ||
} | ||
}); | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.