Skip to content

Commit

Permalink
Implemented: Updated the DataManager Logs page to be dynamic in Job M…
Browse files Browse the repository at this point in the history
…anager(hotwax#680)
  • Loading branch information
R-Sourabh committed Sep 20, 2024
1 parent c20f911 commit ab25739
Show file tree
Hide file tree
Showing 13 changed files with 256 additions and 107 deletions.
8 changes: 4 additions & 4 deletions src/components/DownloadLogsFilePopover.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<template>
<ion-content>
<ion-list>
<ion-list-header>Log Id</ion-list-header>
<ion-list-header>{{ translate('Log Id') }}</ion-list-header>
<ion-item button>
Log file
{{ translate('Log file') }}
</ion-item>
<ion-item button>
Uploaded file
{{ translate('Uploaded file') }}
</ion-item>
<ion-item button lines="none">
Failed records
{{ translate('Failed records') }}
</ion-item>
</ion-list>
</ion-content>
Expand Down
210 changes: 121 additions & 89 deletions src/components/ImportLogsDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,143 +12,118 @@
<div class="search ion-padding">
<section>
<ion-item lines="none">
<h1>Import logs</h1>
<h1>{{ translate('Import logs') }}</h1>
</ion-item>
<ion-list>
<ion-item>
<ion-icon slot="start" :icon="pulseOutline" />
<ion-label>Job</ion-label>
<ion-label slot="end" class="ion-text-wrap">Job Id</ion-label>
<ion-label>{{ translate('Job') }}</ion-label>
<ion-label slot="end" class="ion-text-wrap">{{ currentJob.jobId }}</ion-label>
</ion-item>
<ion-item>
<ion-icon slot="start" :icon="fileTrayFullOutline" />
<ion-label>Files received</ion-label>
<ion-label slot="end">14</ion-label>
<ion-label>{{ translate('Files received') }}</ion-label>
<ion-label slot="end">{{ getDataLogs.length }}</ion-label>
</ion-item>
<ion-item>
<ion-icon slot="start" :icon="codeWorkingOutline" />
<ion-label>Files processed</ion-label>
<ion-label slot="end">14</ion-label>
<ion-label>{{ translate('Files processed') }}</ion-label>
<ion-label slot="end">{{ getProcessedFileCount() }}</ion-label>
</ion-item>
<ion-item lines="none">
<ion-icon slot="start" :icon="warningOutline" />
<ion-label>Files with errors</ion-label>
<ion-label slot="end">14</ion-label>
<ion-label>{{ translate('Files with errors') }}</ion-label>
<ion-label slot="end">{{ getErrorFileCount() }}</ion-label>
</ion-item>
</ion-list>
</section>
</div>
<div class="filters ion-padding">
<ion-label lines="none">
<p class="overline">Config Id</p>
<h1>Config Name</h1>
<p class="overline">{{ currentJob.runtimeData?.configId }}</p>
<h1>{{ configDetails[0]?.description }}</h1>
</ion-label>
<ion-list>
<ion-item>
<ion-icon slot="start" :icon="shareSocialOutline" />
<ion-label>Multithreading</ion-label>
<ion-label slot="end">facilityId</ion-label>
<ion-label>{{ translate('Multithreading') }}</ion-label>
<ion-label slot="end">{{ currentJob.runtimeData?.groupBy ? currentJob.runtimeData?.groupBy : "-" }}</ion-label>
</ion-item>
<ion-item>
<ion-icon slot="start" :icon="globeOutline" />
<ion-label>SFTP</ion-label>
<ion-label slot="end" class="ion-text-wrap">path/SFTP</ion-label>
<ion-label class="ion-text-wrap">{{ translate('SFTP') }}</ion-label>
<ion-label class="ion-text-wrap" slot="end">{{ configDetails[0]?.importPath }}</ion-label>
</ion-item>
<ion-item>
<ion-icon slot="start" :icon="optionsOutline" />
<ion-label>Mode</ion-label>
<ion-label slot="end">Queued</ion-label>
<ion-label>{{ translate('Mode') }}</ion-label>
<ion-label slot="end">{{ configDetails[0]?.executionModeId ? configDetails[0]?.executionModeId : "-"}}</ion-label>
</ion-item>
</ion-list>
</div>
</div>

<div class="ion-padding">
<ion-chip outline>
<ion-label>All</ion-label>
<ion-icon :icon="checkmarkOutline"/>
</ion-chip>
<ion-chip outline>
<ion-label>Failed log</ion-label>
</ion-chip>
<ion-chip outline>
<ion-label>Failed records</ion-label>
<ion-chip v-for="(chip, index) in chips" :key="index" outline @click="updateLogs(chip.label)">
<ion-label>{{ chip.label }}</ion-label>
<ion-icon v-if="chip.selected" :icon="checkmarkOutline" />
</ion-chip>
</div>

<div class="list-item">
<ion-item lines="none">
<ion-icon slot="start" :icon="documentTextOutline" />

<div class="empty-state" v-if="isLoading">
<ion-spinner name="crescent" />
</div>
<div v-else-if="filteredLogs.length" >
<div class="list-item" v-for="(log, index) in filteredLogs" :key="index">
<ion-item lines="none">
<ion-icon slot="start" :icon="documentTextOutline" />
<ion-label>
<p class="overline">{{ log.logId }}</p>
{{ log.contentName }}
<p>{{ getDateTime(log.createdDate) }}</p>
</ion-label>
</ion-item>

<ion-label>
<p class="overline">Log id</p>
File Name
<p>07/09/2024 10:00 PM</p>
{{ getDateTime(log.startDateTime) }}
<p>{{ translate('Started') }}</p>
</ion-label>
</ion-item>

<ion-label>
07/09/2024 10:00 PM
<p>Started</p>
</ion-label>

<ion-label>
07/09/2024 10:00 PM
<p>Finished</p>
</ion-label>

<ion-badge color="success">Finished</ion-badge>

<ion-label>
<ion-icon slot="start" :icon="cloudDownloadOutline" />
<p>Failed records</p>
</ion-label>

<ion-button fill="clear" color="medium" @click="openDownloadLogsFilePopover($event)">
<ion-icon slot="icon-only" :icon="ellipsisVerticalOutline" />
</ion-button>
</div>

<div class="list-item">
<ion-item lines="none">
<ion-icon slot="start" :icon="documentTextOutline" />

<ion-label>
<p class="overline">Log id</p>
File Name
<p>07/09/2024 10:00 PM</p>
{{ getDateTime(log.finishDateTime) }}
<p>{{ translate('Finished') }}</p>
</ion-label>
</ion-item>

<ion-label>
07/09/2024 10:00 PM
<p>Started</p>
</ion-label>

<ion-label>
07/09/2024 10:00 PM
<p>Finished</p>
</ion-label>

<ion-badge color="danger">Failed</ion-badge>

<ion-label>
<ion-icon slot="start" :icon="cloudDownloadOutline" />
<p>Failed records</p>
</ion-label>

<ion-button fill="clear" color="medium" @click="openDownloadLogsFilePopover($event)">
<ion-icon slot="icon-only" :icon="ellipsisVerticalOutline" />
</ion-button>

<ion-badge color="success" v-if="log.statusId === 'SERVICE_FINISHED'">{{ translate('Finished') }}</ion-badge>
<ion-badge color="danger" v-if="log.statusId === 'SERVICE_FAILED'">{{ translate('Failed') }}</ion-badge>
<ion-badge color="success" v-if="log.statusId === 'SERVICE_RUNNING' || log.statusId === 'SERVICE_QUEUED'">{{ translate('Running') }}</ion-badge>

<ion-label v-if="log.errorRecordContentId">
<ion-icon slot="start" :icon="cloudDownloadOutline" />
<p>{{ translate('Failed records') }}</p>
</ion-label>
<div v-else></div>

<ion-button fill="clear" color="medium" @click="openDownloadLogsFilePopover($event)">
<ion-icon slot="icon-only" :icon="ellipsisVerticalOutline" />
</ion-button>
</div>
</div>
<div v-else class="empty-state">
{{ translate('No logs found') }}
</div>
</ion-content>
</ion-page>
</template>

<script>
import { checkmarkOutline, codeWorkingOutline, cloudDownloadOutline, documentTextOutline, ellipsisVerticalOutline, fileTrayFullOutline, globeOutline, optionsOutline, pulseOutline, shareSocialOutline, warningOutline } from "ionicons/icons";
import { IonBackButton, IonBadge, IonButton, IonChip, IonContent, IonHeader, IonIcon, IonItem, IonLabel, IonList, IonPage, IonTitle, IonToolbar, popoverController } from "@ionic/vue";
import { IonBackButton, IonBadge, IonButton, IonChip, IonContent, IonHeader, IonIcon, IonItem, IonLabel, IonList, IonPage, IonSpinner, IonTitle, IonToolbar, popoverController } from "@ionic/vue";
import { defineComponent } from 'vue'
import { mapGetters, useStore } from 'vuex'
import { translate } from '@hotwax/dxp-components'
import DownloadLogsFilePopover from "./DownloadLogsFilePopover.vue";
import { DateTime } from 'luxon'
import DownloadLogsFilePopover from "@/components/DownloadLogsFilePopover.vue";
export default defineComponent ({
name: "ImportLogsDetail",
Expand All @@ -164,20 +139,76 @@ export default defineComponent ({
IonLabel,
IonList,
IonPage,
IonSpinner,
IonTitle,
IonToolbar,
},
data() {
return {
configDetails: {},
chips: [
{ label: 'All', selected: true },
{ label: 'Failed logs', selected: false },
{ label: 'Failed records', selected: false }
],
filteredLogs: [],
isLoading: true,
}
},
computed: {
...mapGetters({
currentJob: 'job/getCurrentJob',
getDataLogs: 'job/getDataLogs',
getJob: 'job/getJob',
}),
},
async mounted() {
await this.fetchJobs();
this.updateLogs('All');
const job = await this.getJob(this.$route.params.jobId)
this.filteredLogs = await this.store.dispatch('job/fetchDataManagerLogs', job.runtimeData?.configId)
this.configDetails = await this.store.dispatch('job/fetchDataManagerConfig', job.runtimeData?.configId)
this.isLoading = false;
},
methods : {
updateLogs(label) {
if (label === 'All') {
this.filteredLogs = this.getDataLogs
} else if (label === 'Failed logs') {
this.filteredLogs = this.getDataLogs.filter(log => log.statusId === 'SERVICE_FAILED')
} else if (label === 'Failed records') {
this.filteredLogs = this.getDataLogs.filter(log => log.errorRecordContentId !== null)
}
this.chips.map((chip) => {
chip.selected = chip.label === label;
});
},
getDateTime(time) {
return DateTime.fromMillis(time).toLocaleString(DateTime.DATETIME_SHORT).replace(',', '')
},
getProcessedFileCount() {
return this.getDataLogs.filter((log) => log.statusId === "SERVICE_FINISHED").length
},
getErrorFileCount() {
return this.getDataLogs.filter((log) => log.errorRecordContentId !== null).length
},
async openDownloadLogsFilePopover(event) {
const popover = await popoverController.create({
component: DownloadLogsFilePopover,
showBackdrop: false,
event: event
});
return popover.present()
}
},
async fetchJobs(){
await this.store.dispatch("job/fetchJobs", {
"inputFields": this.$route.params.jobId
});
},
},
setup() {
const store = useStore();
return {
checkmarkOutline,
codeWorkingOutline,
Expand All @@ -190,7 +221,8 @@ export default defineComponent ({
pulseOutline,
shareSocialOutline,
warningOutline,
translate
translate,
store
}
}
})
Expand Down
31 changes: 20 additions & 11 deletions src/components/JobConfiguration.vue
Original file line number Diff line number Diff line change
Expand Up @@ -113,27 +113,27 @@
</ion-item>
</div>
<!-- Import logs -->
<section>
<section v-if="currentJob.runtimeData?.configId">
<ion-item lines="none">
<h1>Import logs</h1>
<ion-button slot="end" fill="clear" @click="openImportLogsDetails()">View details</ion-button>
<h1>{{ translate('Import logs') }}</h1>
<ion-button slot="end" fill="clear" @click="openImportLogsDetails()">{{ translate('View details') }}</ion-button>
</ion-item>
<ion-progress-bar></ion-progress-bar>
<ion-progress-bar :value="(getProcessedFileCount() + getErrorFileCount()) / getDataLogs.length * 0.1"></ion-progress-bar>
<ion-list>
<ion-item>
<ion-icon slot="start" :icon="fileTrayFullOutline" />
<ion-label>Files received</ion-label>
<ion-label slot="end">14</ion-label>
<ion-label>{{ translate('Files received') }}</ion-label>
<ion-label slot="end">{{ getDataLogs.length }}</ion-label>
</ion-item>
<ion-item>
<ion-icon slot="start" :icon="codeWorkingOutline" />
<ion-label>Files processed</ion-label>
<ion-label slot="end">14</ion-label>
<ion-label>{{ translate('Files processed') }}</ion-label>
<ion-label slot="end">{{ getProcessedFileCount() }}</ion-label>
</ion-item>
<ion-item lines="none">
<ion-icon slot="start" :icon="warningOutline" />
<ion-label>Files with errors</ion-label>
<ion-label slot="end">14</ion-label>
<ion-label>{{ translate('Files with errors') }}</ion-label>
<ion-label slot="end">{{ getErrorFileCount() }}</ion-label>
</ion-item>
</ion-list>
</section>
Expand Down Expand Up @@ -244,6 +244,7 @@ export default defineComponent({
currentEComStore: 'user/getCurrentEComStore',
currentJob: 'job/getCurrentJob',
pendingJobs: 'job/getPendingJobs',
getDataLogs: 'job/getDataLogs',
}),
isRequiredParametersMissing() {
return this.customRequiredParameters.some((parameter: any) => !parameter.value?.trim())
Expand All @@ -254,8 +255,16 @@ export default defineComponent({
}
},
methods: {
getProcessedFileCount() {
if(this.getDataLogs && this.getDataLogs.length) {
return this.getDataLogs?.filter((log: any) => log.statusId === "SERVICE_FINISHED").length
}
},
getErrorFileCount() {
return this.getDataLogs?.filter((log: any) => log.errorRecordContentId !== null).length
},
openImportLogsDetails() {
this.router.push({ name: 'ImportLogsDetail', replace: false });
this.router.push({ name: 'ImportLogsDetail', params: { jobId: this.currentJob.systemJobEnumId }, replace: true });
},
getDateTime(time: any) {
return DateTime.fromMillis(time).toISO()
Expand Down
Loading

0 comments on commit ab25739

Please sign in to comment.