Files
thetool/public/js/pages/ContractView/ContractView.js
2024-11-15 09:13:38 +00:00

182 lines
8.9 KiB
JavaScript

Vue.component('tt-detail-table', {
//language=Vue
template: `
<table class="table table-sm table-striped view-table">
<tbody>
<tr v-for="(item, key) in detailItems" :key="key">
<td v-html="item.label.replaceAll('s', 's<wbr>') + ':'"></td>
<td>
<template v-if="item.hasOwnProperty('url')">
<a :href="item.url" target="_blank">{{item.value}}</a>
</template>
<template v-else>
{{item.value.includes('1970') ? '' : item.value}}
</template>
</td>
</tr>
</tbody>
</table>`, props: ['detailItems'],
})
Vue.component('contract-journal', {
//language=Vue
template: `
<div>
<tt-card>
<template v-slot:header>
<h5 class="text-center">Journaleinträge</h5>
</template>
<div class="contract-journal-grid">
<template v-for="(entry, index) in journalEntries">
<!-- odd index should have class contract-journal-striped-background-->
<div :class="index % 2 === 0 ? 'contract-journal-striped-background' : ''" style="padding-right: 8px" class="text-monospace">{{entry.create}} ({{entry.creator}})</div>
<div :class="index % 2 === 0 ? 'contract-journal-striped-background' : ''"><i :class="entry.icon" :title="entry.iconTitle"></i></div>
<!-- if entry.text is longer than 180 characters add fa-caret in front of the text and use parseTextAddUrls to include html <a>-->
<template v-if="entry.text.length > 130">
<div
:class="index % 2 === 0 ? 'contract-journal-striped-background' : ''"
v-if="!expandedTexts.includes(index)"
@click="expandedTexts.push(index)" style="cursor: pointer;">
<div :class="entry.textClass" v-html="parseTextAddUrls(entry, 'fas fa-caret-down').substring(0, 130) + '...'"></div>
</div>
<div :class="index % 2 === 0 ? 'contract-journal-striped-background' : ''" v-if="expandedTexts.includes(index)" style="cursor: pointer;" @click="expandedTexts = expandedTexts.filter(i => i !== index)">
<div :class="entry.textClass" v-html="parseTextAddUrls(entry, 'fas fa-caret-up', true)"></div>
</div>
</template>
<template v-else>
<div :class="index % 2 === 0 ? 'contract-journal-striped-background' : ''"><div :class="entry.textClass" v-html="parseTextAddUrls(entry)"></div></div>
</template>
<hr style="grid-column: 1 / span 3; border-top: 1px solid #e9ecef; margin: 0;">
</template>
<div class="ml-3" style="grid-column: 1 / span 3">
<button type="button" class="btn btn-sm btn-info" @click="showNewJournal = !showNewJournal"
><i class="fas fa-plus"></i> Journaleintrag hinzufügen
</button>
</div>
<div class="card-body border-top mt-2" v-if="showNewJournal" id="new-journal" style="grid-column: 1 / span 3">
<form method="post" :action="window.TT_CONFIG['CONTRACT_NEW_JOURNAL_URL']" enctype="multipart/form-data">
<input type="hidden" name="contract_id" :value="contractId"/>
<label for="new_journal_type" class="form-label">Typ</label>
<select name="type" id="new_journal_type" class="form-control mb-2">
<option value="phone">Telefongespräch</option>
<option value="text">Kommentar</option>
<option value="file">Dateiupload</option>
</select>
<label for="new_journal_text" class="form-label">Text</label>
<textarea name="text" id="new_journal_text" class="form-control mb-2" style="height:120px;"></textarea>
<div id="new-journal-file-container" class="hidden">
<label for="new_journal_file" class="form-label">Dateianhang</label>
<input type="file" name="journal_file" id="new_journal_file" class="form-control mb-2"/>
</div>
<button class="btn btn-sm btn-primary" type="submit"><i class="fas fa-save mr-1"></i> Speichern</button>
</form>
</div>
</div>
</tt-card>
</div>
`, props: ['journalEntries', 'contractId'], data() {
return {
expandedTexts: [], showNewJournal: false, window: window
}
}, methods: {
parseTextAddUrls(entry, addIcon = null, replaceNewLines = false) {
let text = JSON.parse(JSON.stringify(entry)).text
if (replaceNewLines) {
text = text.replace(/(?:\r\n|\r|\n)/g, '<br>')
}
// if addIcon is set, add it to the beginning of the text
if (addIcon) {
text = `<i class="${addIcon} mr-1"></i> ${text}`
}
if (entry.url && entry["urlText"]) {
return text.replace('[URL]', `<a href="${entry.url}" target="_blank">${entry["urlText"]}</a>`)
}
return text
}
}
})
Vue.component('contract-view', {
//language=Vue
template: `
<div>
<tt-card>
<template v-slot:header>
<div class="contract-view-header">
<tt-button :href="window.TT_CONFIG['BACK_URL']" sm text="Zurück" icon="fas fa-arrow-left" additional-class="btn-primary"/>
<h2 class="text-center" :class="isPrivateProduct ? 'text-dark-red' : 'text-primary'">
{{window.TT_CONFIG.HEADER}}</h2>
<tt-button :href="window.TT_CONFIG['EDIT_URL']" sm text="Vertrag bearbeiten" icon="fas fa-edit" additional-class="btn-success"/>
</div>
<h3 class="text-center">{{subHeader}}</h3>
</template>
<div class="contract-view">
<tt-card no-body-padding-top class="contract-view-details-grid">
<h5 class="text-center">Vertragsdaten</h5>
<tt-detail-table :detail-items="contractDetails"/>
</tt-card>
<div class="contract-view-actions-grid">
<tt-card no-body-padding-top class="contract-view-actions">
<h5 class="text-center">Aktionen</h5>
<tt-button v-for="action in window.TT_CONFIG['CONTRACT_ACTIONS']" :href="action.url" sm :text="action.text" :icon="action.icon"
:additional-class="action.class" :confirm-text="action.confirmText" :key="action.text" class="mt-2"/>
</tt-card>
</div>
<contract-journal class="contract-view-journal-grid"
:journal-entries="window.TT_CONFIG['CONTRACT_JOURNAL']"
:contract-id="window.TT_CONFIG['CONTRACT_ID']"/>
<tt-card no-body-padding-top body-overflow-x-auto style="grid-column: 1" class="contract-view-links-grid">
<h5 class="text-center">Vertragslinks</h5>
<div v-html="contractLinkTableHTML"></div>
</tt-card>
</div>
</tt-card>
</div>
`, data() {
return {
window: window,
header: window.TT_CONFIG["HEADER"],
subHeader: window.TT_CONFIG["SUB_HEADER"],
contractDetails: window.TT_CONFIG["CONTRACT_DETAILS"],
contractLinkTableHTML: null,
}
}, computed: {
isPrivateProduct() {
return window.TT_CONFIG["HEADER"].includes('Privat')
}
},
async mounted() {
const response = await axios.get(window.TT_CONFIG["CONTRACT_LINK_TABLE_URL"])
this.contractLinkTableHTML = response.data
console.log(response.data)
}
})