feat(client): add new report dialog to navigation header

pull/7968/head
Tayeb Chlyah 5 months ago
parent 85c304f583
commit e2aeb126e0

@ -175,6 +175,16 @@
span {{$t('common:header.newPage')}}
v-divider(vertical)
//- NEW REPORT
template(v-if='hasNewPagePermission && path && mode !== `edit`')
v-tooltip(bottom)
template(v-slot:activator='{ on }')
v-btn(icon, tile, height='64', v-on='on', @click='newReportModal = true', aria-label='New Report')
v-icon(color='grey') mdi-file-chart-outline
span New Report
v-divider(vertical)
//- ADMIN
template(v-if='isAuthenticated && isAdmin')
@ -237,6 +247,7 @@
span {{$t('common:header.login')}}
page-selector(mode='create', v-model='newPageModal', :open-handler='pageNewCreate', :locale='locale')
new-report-dialog(v-model='newReportModal')
page-selector(mode='move', v-model='movePageModal', :open-handler='pageMoveRename', :path='path', :locale='locale')
page-selector(mode='create', v-model='duplicateOpts.modal', :open-handler='pageDuplicateHandle', :path='duplicateOpts.path', :locale='duplicateOpts.locale')
page-delete(v-model='deletePageModal', v-if='path && path.length')
@ -260,7 +271,8 @@ import movePageMutation from 'gql/common/common-pages-mutation-move.gql'
export default {
components: {
PageDelete: () => import('./page-delete.vue'),
PageConvert: () => import('./page-convert.vue')
PageConvert: () => import('./page-convert.vue'),
NewReportDialog: () => import('./new-report-dialog.vue')
},
props: {
dense: {
@ -278,6 +290,7 @@ export default {
searchIsShown: true,
searchAdvMenuShown: false,
newPageModal: false,
newReportModal: false,
movePageModal: false,
convertPageModal: false,
deletePageModal: false,

@ -0,0 +1,242 @@
<template lang="pug">
v-dialog(
v-model='isShown'
max-width='850px'
overlay-color='blue darken-4'
overlay-opacity='.7'
)
v-card.new-report-dialog
.dialog-header.is-blue
v-icon.mr-3(color='white') mdi-file-chart-outline
.body-1 New Report
v-spacer
v-btn(icon, dark, @click='close')
v-icon mdi-close
v-card-text.pa-4
v-form(ref='form', v-model='valid')
v-row
v-col(cols='12', md='6')
.overline.mb-2 Generation Options
v-text-field(
v-model='form.snapshot'
label='Snapshot ID'
:rules='[v => !!v || "Snapshot is required"]'
required
outlined
dense
)
v-text-field(
v-model='form.sg_snapshot'
label='SG Snapshot ID (Optional)'
outlined
dense
)
v-checkbox(
v-model='form.mobile'
label='Mobile'
dense
)
v-checkbox(
v-model='form.cao'
label='CAO'
dense
)
v-col(cols='12', md='6')
.overline.mb-2 Report Details
v-text-field(
v-model='form.book.couchbase.customer'
label='Customer'
:rules='[v => !!v || "Customer is required"]'
required
outlined
dense
)
v-text-field(
v-model='form.book.author'
label='Author'
:rules='[v => !!v || "Author is required"]'
required
outlined
dense
)
v-text-field(
v-model='form.book.couchbase.email'
label='Email'
:rules='[v => !!v || "Email is required"]'
required
outlined
dense
)
v-text-field(
v-model='form.book.couchbase.role'
label='Role'
:rules='[v => !!v || "Role is required"]'
required
outlined
dense
)
v-text-field(
v-model='form.book.couchbase.service'
label='Service'
:rules='[v => !!v || "Service is required"]'
required
outlined
dense
)
v-menu(
v-model='dateMenu'
:close-on-content-click='false'
:nudge-right='40'
transition='scale-transition'
offset-y
min-width='290px'
)
template(v-slot:activator='{ on, attrs }')
v-text-field(
v-model='form.book.couchbase.serviceDate'
label='Service Date'
prepend-icon='mdi-calendar'
readonly
v-bind='attrs'
v-on='on'
:rules='[v => !!v || "Service Date is required"]'
required
outlined
dense
)
v-date-picker(v-model='form.book.couchbase.serviceDate', @input='dateMenu = false')
v-combobox(
v-model='attendees'
label='Attendees'
multiple
chips
deletable-chips
small-chips
:rules='[v => v.length > 0 || "Attendees are required"]'
required
outlined
dense
hint='Type and press enter to add'
persistent-hint
)
v-card-chin
v-spacer
v-btn(text, @click='close') Cancel
v-btn.px-4(color='primary', @click='createReport', :loading='loading', :disabled='!valid')
v-icon(left) mdi-check
span Create Report
</template>
<script>
export default {
props: {
value: {
type: Boolean,
default: false
}
},
data() {
return {
valid: true,
loading: false,
dateMenu: false,
attendees: ['Smith, John <john.smith@examplecompany.com>', 'Smith, Jane <jane.smith@examplecompany.com>'],
form: {
snapshot: '',
sg_snapshot: '',
mobile: false,
cao: false,
book: {
author: 'Tayeb Chlyah',
couchbase: {
customer: '',
email: 'tayeb.chlyah@couchbase.com',
role: 'Solutions Architect',
service: 'Architecture Review',
serviceDate: new Date().toISOString().substr(0, 10)
}
}
}
}
},
computed: {
isShown: {
get() { return this.value },
set(val) { this.$emit('input', val) }
}
},
methods: {
close() {
this.isShown = false
},
async createReport() {
if (!this.$refs.form.validate()) return
this.loading = true
const payload = {
generation: {
snapshot: this.form.snapshot,
sg_snapshot: this.form.sg_snapshot,
mobile: this.form.mobile,
cao: this.form.cao
},
book: {
author: this.form.book.author,
couchbase: {
...this.form.book.couchbase,
attendees: this.attendees
}
}
}
try {
const response = await fetch('/n8n/webhook/generate-report', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
})
if (response.ok) {
const data = await response.json()
if (data && data.path) {
window.location.assign(data.path)
this.close()
} else {
this.$store.commit('showNotification', {
message: 'Report generation started successfully',
style: 'success',
icon: 'check'
})
this.close()
}
} else {
throw new Error('Failed to generate report')
}
} catch (error) {
console.error('Report generation error:', error)
this.$store.commit('showNotification', {
message: 'Failed to generate report',
style: 'error',
icon: 'alert'
})
} finally {
this.loading = false
}
}
}
}
</script>
<style lang='scss'>
.new-report-dialog {
.v-card__text {
padding-top: 20px !important;
}
}
</style>
Loading…
Cancel
Save