added new rml stuff

This commit is contained in:
Luca Haid
2025-11-03 12:59:00 +01:00
parent 37be99b284
commit 887552a734
7 changed files with 306 additions and 20 deletions
+91 -11
View File
@@ -115,6 +115,7 @@
const isSettingsOpen = ref(false); const isSettingsOpen = ref(false);
const theme = ref('system'); // 'light', 'dark', 'system' const theme = ref('system'); // 'light', 'dark', 'system'
const showThemePicker = ref(false); const showThemePicker = ref(false);
const savingData = ref(false); // <-- ADDED
const API_BASE_URL = window.TT_CONFIG.BASE_PATH || '/WorkorderCompany'; const API_BASE_URL = window.TT_CONFIG.BASE_PATH || '/WorkorderCompany';
@@ -211,9 +212,24 @@
}); });
}); });
// MODIFIED
const isChecklistComplete = computed(() => { const isChecklistComplete = computed(() => {
if (checklist.value.length === 0) return true; // Check documents
return checklist.value.every(item => item.completed); if (checklist.value.length > 0) {
if (!checklist.value.every(item => item.completed)) {
return false;
}
}
// Check new fields
if (tenantConfig.value?.requireCableLength && (!selectedWorkorder.value.cableLength || !selectedWorkorder.value.cableLength.trim())) {
return false;
}
if (tenantConfig.value?.requireCableType && (!selectedWorkorder.value.cableType || !selectedWorkorder.value.cableType.trim())) {
return false;
}
return true; // All checks passed
}); });
const translatedDocs = computed(() => { const translatedDocs = computed(() => {
@@ -291,7 +307,7 @@
documentation.docs = docRes.data.docs.map(d => ({...d, isPdf: d.mimetype === 'application/pdf'})); documentation.docs = docRes.data.docs.map(d => ({...d, isPdf: d.mimetype === 'application/pdf'}));
documentation.journals = docRes.data.journals; documentation.journals = docRes.data.journals;
if (configRes.data.success) { if (configRes.data.success) {
tenantConfig.value = configRes.data; tenantConfig.value = configRes.data; // <-- MODIFIED: This will now contain all flags
} }
} catch (e) { console.error("Could not load details", e); } } catch (e) { console.error("Could not load details", e); }
finally { isDetailsLoading.value = false; } finally { isDetailsLoading.value = false; }
@@ -329,6 +345,36 @@
finally { isEditingInfo.value = false; } finally { isEditingInfo.value = false; }
}; };
// START ADDED
const saveWorkorderData = async () => {
savingData.value = true;
try {
const response = await api.post('/updateWorkorderData', {
workorderId: selectedWorkorder.value.id,
cableLength: selectedWorkorder.value.cableLength,
cableType: selectedWorkorder.value.cableType
});
if (response.data.success) {
alert('Daten gespeichert.'); // PWA uses alert()
documentation.journals = response.data.journals; // Update journal
// Also update the main list item
const woInList = workorders.value.find(w => w.id === selectedWorkorder.value.id);
if (woInList) {
woInList.cableLength = selectedWorkorder.value.cableLength;
woInList.cableType = selectedWorkorder.value.cableType;
}
} else {
alert(response.data.message || 'Speichern fehlgeschlagen.');
}
} catch (e) {
console.error("Failed to save data", e);
alert('Ein Netzwerkfehler ist aufgetreten.');
} finally {
savingData.value = false;
}
};
// END ADDED
const addJournalEntry = async () => { const addJournalEntry = async () => {
if (!newJournalEntry.value.trim()) return; if (!newJournalEntry.value.trim()) return;
try { try {
@@ -401,13 +447,23 @@
finally { problemModal.show = false; problemModal.selectedInterventions = []; problemModal.details = {}; } finally { problemModal.show = false; problemModal.selectedInterventions = []; problemModal.details = {}; }
}; };
// MODIFIED
const handleCompleteClick = () => { const handleCompleteClick = () => {
if (isChecklistComplete.value) { if (isChecklistComplete.value) {
if (confirm("Möchten Sie diesen Auftrag wirklich abschließen?")) { if (confirm("Möchten Sie diesen Auftrag wirklich abschließen?")) {
completeWorkorder(); completeWorkorder();
} }
} else { } else {
missingTasksPopover.tasks = checklist.value.filter(t => !t.completed).map(t => t.text); const missingDocs = checklist.value.filter(t => !t.completed).map(t => t.text);
const missingData = [];
if (tenantConfig.value?.requireCableLength && (!selectedWorkorder.value.cableLength || !selectedWorkorder.value.cableLength.trim())) {
missingData.push("Kabellänge");
}
if (tenantConfig.value?.requireCableType && (!selectedWorkorder.value.cableType || !selectedWorkorder.value.cableType.trim())) {
missingData.push("Kabeltyp");
}
missingTasksPopover.tasks = [...missingDocs, ...missingData];
missingTasksPopover.show = true; missingTasksPopover.show = true;
setTimeout(() => missingTasksPopover.show = false, 4000); setTimeout(() => missingTasksPopover.show = false, 4000);
} }
@@ -415,10 +471,18 @@
const completeWorkorder = async () => { const completeWorkorder = async () => {
try { try {
await api.post('/completeWorkorder', { workorderId: selectedWorkorder.value.id }); // Server-side validation will catch errors if client-side check fails
await fetchWorkorders(); const response = await api.post('/completeWorkorder', { workorderId: selectedWorkorder.value.id });
closeDetails(); if (response.data.success) {
} catch(e) { console.error("Failed to complete workorder", e); } await fetchWorkorders();
closeDetails();
} else {
alert(response.data.message); // Show validation error from server
}
} catch(e) {
console.error("Failed to complete workorder", e);
alert(e.response?.data?.message || 'Fehler beim Abschließen.');
}
}; };
const selectFcp = (fcpValue) => { const selectFcp = (fcpValue) => {
@@ -456,8 +520,10 @@
checklist, fullscreenViewer, missingTasksPopover, translatedDocs, filteredJournals, installModal, isStandalone, checklist, fullscreenViewer, missingTasksPopover, translatedDocs, filteredJournals, installModal, isStandalone,
selectedFcp, isFcpSelectOpen, fcpOptions, selectedFcpText, fcpSearchTerm, filteredFcpOptions, fcpInputRef, selectedFcp, isFcpSelectOpen, fcpOptions, selectedFcpText, fcpSearchTerm, filteredFcpOptions, fcpInputRef,
isSettingsOpen, theme, showThemePicker, isSettingsOpen, theme, showThemePicker,
savingData, // <-- ADDED
fetchWorkorders, openDetails, closeDetails, getStatusInfo, formatDate, googleMapsLink, startEditInfo, saveAdditionalInfo, fetchWorkorders, openDetails, closeDetails, getStatusInfo, formatDate, googleMapsLink, startEditInfo, saveAdditionalInfo,
handleFileSelect, executeUpload, addJournalEntry, submitProblem, handleCompleteClick, selectFcp, setTheme handleFileSelect, executeUpload, addJournalEntry, submitProblem, handleCompleteClick, selectFcp, setTheme,
saveWorkorderData // <-- ADDED
}; };
}, },
template: ` template: `
@@ -593,6 +659,20 @@
<p v-else class="text-sm whitespace-pre-wrap text-slate-800 dark:text-slate-200">{{ selectedWorkorder.additionalInfo || 'Keine Notiz.' }}</p> <p v-else class="text-sm whitespace-pre-wrap text-slate-800 dark:text-slate-200">{{ selectedWorkorder.additionalInfo || 'Keine Notiz.' }}</p>
</div> </div>
<div v-if="tenantConfig && (tenantConfig.requireCableLength || tenantConfig.requireCableType)" class="bg-white dark:bg-slate-900 p-4 rounded-lg border border-slate-200 dark:border-slate-800 space-y-3 text-sm">
<h3 class="font-bold text-slate-700 dark:text-secondary">Zusatzdaten</h3>
<div v-if="tenantConfig.requireCableLength">
<label class="text-xs text-slate-500 dark:text-slate-300 font-semibold">Kabellänge (m)</label>
<input v-model="selectedWorkorder.cableLength" type="text" class="mt-1 w-full p-2 border rounded-md dark:bg-slate-800 dark:border-slate-700 dark:text-white" placeholder="z.B. 20m">
</div>
<div v-if="tenantConfig.requireCableType">
<label class="text-xs text-slate-500 dark:text-slate-300 font-semibold">Kabeltyp</label>
<input v-model="selectedWorkorder.cableType" type="text" class="mt-1 w-full p-2 border rounded-md dark:bg-slate-800 dark:border-slate-700 dark:text-white" placeholder="z.B. LWL-Kabel 4F">
</div>
<button @click="saveWorkorderData" :disabled="savingData" class="mt-2 w-full px-4 py-2 bg-secondary text-primary font-bold rounded-md text-sm disabled:bg-slate-300">
{{ savingData ? 'Speichert...' : 'Daten speichern' }}
</button>
</div>
<div class="bg-white dark:bg-slate-900 p-4 rounded-lg border border-slate-200 dark:border-slate-800"> <div class="bg-white dark:bg-slate-900 p-4 rounded-lg border border-slate-200 dark:border-slate-800">
<h3 class="font-bold text-slate-700 dark:text-secondary mb-3">Checkliste</h3> <h3 class="font-bold text-slate-700 dark:text-secondary mb-3">Checkliste</h3>
<div v-if="isDetailsLoading" class="space-y-3 animate-pulse"> <div v-if="isDetailsLoading" class="space-y-3 animate-pulse">
@@ -672,7 +752,7 @@
<button @click="handleCompleteClick" class="w-full px-4 py-3 bg-green-600 text-white font-bold rounded-md text-center disabled:bg-slate-300">Abschließen</button> <button @click="handleCompleteClick" class="w-full px-4 py-3 bg-green-600 text-white font-bold rounded-md text-center disabled:bg-slate-300">Abschließen</button>
<transition name="fade"> <transition name="fade">
<div v-if="missingTasksPopover.show" class="absolute bottom-full right-0 mb-2 w-72 bg-red-700 text-white text-sm rounded-lg shadow-lg p-3"> <div v-if="missingTasksPopover.show" class="absolute bottom-full right-0 mb-2 w-72 bg-red-700 text-white text-sm rounded-lg shadow-lg p-3">
<h4 class="font-bold mb-1">Fehlende Checklisten-Punkte:</h4> <h4 class="font-bold mb-1">Fehlende Punkte:</h4>
<ul class="list-disc list-inside space-y-1"> <ul class="list-disc list-inside space-y-1">
<li v-for="task in missingTasksPopover.tasks" :key="task">{{ task }}</li> <li v-for="task in missingTasksPopover.tasks" :key="task">{{ task }}</li>
</ul> </ul>
@@ -870,4 +950,4 @@
</script> </script>
<script src="/js/pages/WorkorderBase/WorkorderServiceWorker.js"></script> <script src="/js/pages/WorkorderBase/WorkorderServiceWorker.js"></script>
</body> </body>
</html> </html>
+2
View File
@@ -14,6 +14,8 @@ class WorkorderModel extends TTCrudBaseModel
public ?int $deadlineDate; public ?int $deadlineDate;
public ?int $appointmentDate; public ?int $appointmentDate;
public ?string $additionalInfo; public ?string $additionalInfo;
public ?string $cableLength;
public ?string $cableType;
public int $create; public int $create;
public int $createBy; public int $createBy;
@@ -143,6 +143,18 @@ class WorkorderCompanyController extends WorkorderBaseController {
$workorder = WorkorderModel::get($this->postData['workorderId']); $workorder = WorkorderModel::get($this->postData['workorderId']);
if (!$workorder) self::sendError("Arbeitsauftrag nicht gefunden."); if (!$workorder) self::sendError("Arbeitsauftrag nicht gefunden.");
// START ADDED VALIDATION
$tenantConfig = $this->getTenantConfigFromWorkorder($workorder->id);
if ($tenantConfig) {
if ($tenantConfig->requireCableLength && empty(trim($workorder->cableLength))) {
self::sendError("Bitte geben Sie die Kabellänge an, um den Auftrag abzuschließen.");
}
if ($tenantConfig->requireCableType && empty(trim($workorder->cableType))) {
self::sendError("Bitte geben Sie den Kabeltyp an, um den Auftrag abzuschließen.");
}
}
// END ADDED VALIDATION
$workorder->status = 'documented'; $workorder->status = 'documented';
WorkorderModel::update((array)$workorder); WorkorderModel::update((array)$workorder);
self::returnJson(['success' => true, 'message' => 'Arbeitsauftrag zur Prüfung eingereicht.']); self::returnJson(['success' => true, 'message' => 'Arbeitsauftrag zur Prüfung eingereicht.']);
@@ -155,7 +167,14 @@ class WorkorderCompanyController extends WorkorderBaseController {
self::returnJson(['success' => false, 'message' => 'Keine Mandantenkonfiguration gefunden.']); self::returnJson(['success' => false, 'message' => 'Keine Mandantenkonfiguration gefunden.']);
return; return;
} }
self::returnJson(['success' => true, 'documentationTypes' => json_decode($tenantConfig->documentationTypes, true), 'civilEngineeringDocsRequired' => $tenantConfig->civilEngineeringDocsRequired, 'interventionTypes' => json_decode($tenantConfig->interventionTypes, true)]); self::returnJson([
'success' => true,
'documentationTypes' => json_decode($tenantConfig->documentationTypes, true),
'civilEngineeringDocsRequired' => $tenantConfig->civilEngineeringDocsRequired,
'interventionTypes' => json_decode($tenantConfig->interventionTypes, true),
'requireCableLength' => $tenantConfig->requireCableLength,
'requireCableType' => $tenantConfig->requireCableType
]);
} }
protected function uploadDocumentationAction() { protected function uploadDocumentationAction() {
@@ -237,5 +256,52 @@ class WorkorderCompanyController extends WorkorderBaseController {
]); ]);
self::returnJson(['success' => true, 'message' => 'Tiefbau erfolgreich abgeschlossen.']); self::returnJson(['success' => true, 'message' => 'Tiefbau erfolgreich abgeschlossen.']);
} }
protected function updateWorkorderDataAction() {
if (empty($this->postData['workorderId'])) self::sendError("Arbeitsauftrags-ID fehlt.");
$workorder = WorkorderModel::get($this->postData['workorderId']);
if (!$workorder) self::sendError("Arbeitsauftrag nicht gefunden.");
$journalText = "Zusatzdaten aktualisiert:\n";
$changed = false;
if (isset($this->postData['cableLength'])) {
if ($workorder->cableLength != $this.postData['cableLength']) {
$journalText .= "Kabellänge: '{$workorder->cableLength}' -> '{$this->postData['cableLength']}'\n";
$workorder->cableLength = $this.postData['cableLength'];
$changed = true;
}
}
if (isset($this->postData['cableType'])) {
if ($workorder->cableType != $this.postData['cableType']) {
$journalText .= "Kabeltyp: '{$workorder->cableType}' -> '{$this->postData['cableType']}'\n";
$workorder->cableType = $this.postData['cableType'];
$changed = true;
}
}
if (!$changed) {
self::returnJson(['success' => true, 'message' => 'Keine Änderungen vorgenommen.']);
return;
}
WorkorderModel::update((array)$workorder);
WorkorderJournalModel::create([
'workorderId' => $workorder->id,
'text' => $journalText,
'create' => time(),
'createBy' => $this->user->id,
]);
// Re-fetch journals to return
$journals = WorkorderJournalModel::getAll(['workorderId' => intval($workorder->id)], null, 0, ['key' => 'create', 'order' => 'DESC']);
foreach ($journals as $journal) {
$journal->createByName = UserModel::getOne($journal->createBy)->name ?? 'Unbekannt';
}
self::returnJson(['success' => true, 'message' => 'Daten gespeichert.', 'journals' => $journals]);
}
//endregion //endregion
} }
@@ -10,6 +10,8 @@ class WorkorderTenantConfigModel extends TTCrudBaseModel {
public ?string $workorderActiveFilters; // JSON public ?string $workorderActiveFilters; // JSON
public ?string $interventionTypes; // JSON public ?string $interventionTypes; // JSON
public int $civilEngineeringDocsRequired; public int $civilEngineeringDocsRequired;
public int $requireCableLength;
public int $requireCableType;
public int $create; public int $create;
public int $createBy; public int $createBy;
@@ -31,4 +33,5 @@ class WorkorderTenantConfigModel extends TTCrudBaseModel {
$row = $result ? $result->fetch_assoc() : null; $row = $result ? $result->fetch_assoc() : null;
return $row ? new self($row) : null; return $row ? new self($row) : null;
}} }
}
@@ -0,0 +1,55 @@
<?php
declare(strict_types=1);
use Phinx\Migration\AbstractMigration;
final class WorkorderAddCableFields extends AbstractMigration
{
public function up(): void
{
if ($this->getEnvironment() == "thetool") {
$tableWorkorder = $this->table("Workorder");
$tableWorkorder
->addColumn("cableLength", "string", [
'null' => true,
'default' => null,
'after' => 'additionalInfo'
])
->addColumn("cableType", "string", [
'null' => true,
'default' => null,
'after' => 'cableLength'
])
->update();
$tableConfig = $this->table("WorkorderTenantConfig");
$tableConfig
->addColumn("requireCableLength", "boolean", [
'null' => false,
'default' => 0,
'after' => 'civilEngineeringDocsRequired'
])
->addColumn("requireCableType", "boolean", [
'null' => false,
'default' => 0,
'after' => 'requireCableLength'
])
->update();
}
}
public function down(): void
{
if ($this->getEnvironment() == "thetool") {
$this->table("Workorder")
->removeColumn("cableLength")
->removeColumn("cableType")
->save();
$this->table("WorkorderTenantConfig")
->removeColumn("requireCableLength")
->removeColumn("requireCableType")
->save();
}
}
}
+71 -3
View File
@@ -183,7 +183,7 @@ Vue.component('workorder-details-manager', {
:disabled="!canComplete || isReadOnly" :loading="completing" :disabled="!canComplete || isReadOnly" :loading="completing"
additional-class="btn-success w-100" icon="fas fa-check-double"/> additional-class="btn-success w-100" icon="fas fa-check-double"/>
<small v-if="!canComplete && !isReadOnly" class="form-text text-muted text-center mt-2"> <small v-if="!canComplete && !isReadOnly" class="form-text text-muted text-center mt-2">
Bitte laden Sie alle benötigten Dokumente hoch, um den Auftrag abzuschließen. Bitte laden Sie alle benötigten Dokumente hoch und füllen Sie alle Zusatzdaten (z.B. Kabellänge/-typ) aus, um den Auftrag abzuschließen.
</small> </small>
<div v-if="isReadOnly" class="alert alert-secondary text-center mt-2 p-2"> <div v-if="isReadOnly" class="alert alert-secondary text-center mt-2 p-2">
Auftrag bereits abgeschlossen oder storniert. Keine Aktionen mehr möglich. Auftrag bereits abgeschlossen oder storniert. Keine Aktionen mehr möglich.
@@ -245,6 +245,35 @@ Vue.component('workorder-details-manager', {
</div> </div>
</div> </div>
<div v-if="(requireCableLength || requireCableType)" class="card mb-3">
<div class="card-body">
<h5 class="card-title">Zusatzdaten</h5>
<p class="small text-muted">Diese Daten werden für den Abschluss benötigt.</p>
<tt-input
v-if="requireCableLength"
label="Kabellänge (m)"
v-model="workorder.cableLength"
:disabled="isReadOnly"
sm row
/>
<tt-input
v-if="requireCableType"
label="Kabeltyp"
v-model="workorder.cableType"
:disabled="isReadOnly"
sm row
/>
<tt-button
text="Daten speichern"
@click="saveWorkorderData"
:loading="savingData"
:disabled="isReadOnly || savingData"
additional-class="btn-info float-right"
icon="fas fa-save"
/>
</div>
</div>
<div class="card mb-3" v-if="isAdmin && selectedDocs.length > 0"> <div class="card mb-3" v-if="isAdmin && selectedDocs.length > 0">
<div class="card-header bg-warning"><h5><i class="fas fa-exclamation-triangle mr-2"></i>Korrektur anfordern</h5></div> <div class="card-header bg-warning"><h5><i class="fas fa-exclamation-triangle mr-2"></i>Korrektur anfordern</h5></div>
<div class="card-body"> <div class="card-body">
@@ -296,6 +325,9 @@ Vue.component('workorder-details-manager', {
uploadData: { files: [], documentType: 'photo_hup_mounted', description: '' }, uploadData: { files: [], documentType: 'photo_hup_mounted', description: '' },
interventionData: null, interventionData: null,
interventionTypes: [], interventionTypes: [],
requireCableLength: false,
requireCableType: false,
savingData: false,
// Admin state // Admin state
selectedDocs: [], correctionText: '', correctionLoading: false, showAcceptModal: false, showRevertModal: false, selectedDocs: [], correctionText: '', correctionLoading: false, showAcceptModal: false, showRevertModal: false,
}), }),
@@ -305,7 +337,19 @@ Vue.component('workorder-details-manager', {
return this.tenantDocTypes ?? []; return this.tenantDocTypes ?? [];
}, },
allDocTypes() { return [...this.requiredDocTypes, {value: 'other', text: 'Sonstiges Dokument (optional)'}]; }, allDocTypes() { return [...this.requiredDocTypes, {value: 'other', text: 'Sonstiges Dokument (optional)'}]; },
canComplete() { return this.requiredDocTypes.every(docType => this.isUploaded(docType.value)); }, canComplete() {
const docsUploaded = this.requiredDocTypes.every(docType => this.isUploaded(docType.value));
if (!docsUploaded) return false;
if (this.requireCableLength && (!this.workorder.cableLength || !this.workorder.cableLength.trim())) {
return false;
}
if (this.requireCableType && (!this.workorder.cableType || !this.workorder.cableType.trim())) {
return false;
}
return true; // All checks passed
},
docsWithStatus() { docsWithStatus() {
if (!this.journals?.length) return this.docs; if (!this.journals?.length) return this.docs;
const correctionJournal = [...this.journals].sort((a, b) => b.create - a.create).find(j => j.statusChange?.includes('correction_requested')); const correctionJournal = [...this.journals].sort((a, b) => b.create - a.create).find(j => j.statusChange?.includes('correction_requested'));
@@ -348,6 +392,8 @@ Vue.component('workorder-details-manager', {
if (data.success) { if (data.success) {
this.tenantDocTypes = data.documentationTypes; this.tenantDocTypes = data.documentationTypes;
this.interventionTypes = data.interventionTypes; this.interventionTypes = data.interventionTypes;
this.requireCableLength = data.requireCableLength || false;
this.requireCableType = data.requireCableType || false;
} }
} catch (e) { console.error("Mandantenkonfiguration nicht geladen", e); } } catch (e) { console.error("Mandantenkonfiguration nicht geladen", e); }
finally { this.loadingConfig = false; } finally { this.loadingConfig = false; }
@@ -404,6 +450,28 @@ Vue.component('workorder-details-manager', {
} else window.notify('error', data.message); } else window.notify('error', data.message);
} catch (e) { window.notify('error', 'Netzwerkfehler'); } } catch (e) { window.notify('error', 'Netzwerkfehler'); }
}, },
async saveWorkorderData() {
this.savingData = true;
try {
const { data } = await axios.post(`${window.TT_CONFIG.BASE_PATH}/WorkorderCompany/updateWorkorderData`, {
workorderId: this.workorderId,
cableLength: this.workorder.cableLength,
cableType: this.workorder.cableType
});
if (data.success) {
window.notify('success', data.message);
if (data.journals) {
this.journals = data.journals; // Update journal with new entry
}
} else {
window.notify('error', data.message || 'Speichern fehlgeschlagen.');
}
} catch (e) {
window.notify('error', 'Ein Netzwerkfehler ist aufgetreten.');
} finally {
this.savingData = false;
}
},
openInterventionModal() { openInterventionModal() {
this.interventionData = { types: [], details: { stuck: {}, stuck_fcp: {}, stuck_hup: {}, other: {} } }; this.interventionData = { types: [], details: { stuck: {}, stuck_fcp: {}, stuck_hup: {}, other: {} } };
}, },
@@ -489,4 +557,4 @@ Vue.component('workorder-details-manager', {
await this.loadTenantConfig(); await this.loadTenantConfig();
await this.fetchData(); await this.fetchData();
} }
}); });
@@ -77,9 +77,19 @@ Vue.component('workorder-tenant-config', {
<div class="row mt-3"> <div class="row mt-3">
<div class="col-md-6"> <div class="col-md-6">
<h6 class="mb-3">Optionen</h6> <h6 class="mb-3">Optionen</h6>
<tt-checkbox label="Dokumentation für Tiefbau erforderlich" <div v-if="editingId === config.id">
v-model="editableItem.civilEngineeringDocsRequired" sm v-if="editingId === config.id"/> <tt-checkbox label="Dokumentation für Tiefbau erforderlich"
<p v-else>Tiefbau-Doku: {{ config.civilEngineeringDocsRequired ? 'Ja' : 'Nein' }}</p> v-model="editableItem.civilEngineeringDocsRequired" sm/>
<tt-checkbox label="Kabellänge erforderlich"
v-model="editableItem.requireCableLength" sm/>
<tt-checkbox label="Kabeltyp erforderlich"
v-model="editableItem.requireCableType" sm/>
</div>
<div v-else>
<p>Tiefbau-Doku: <strong>{{ config.civilEngineeringDocsRequired ? 'Ja' : 'Nein' }}</strong></p>
<p>Kabellänge-Doku: <strong>{{ config.requireCableLength ? 'Ja' : 'Nein' }}</strong></p>
<p>Kabeltyp-Doku: <strong>{{ config.requireCableType ? 'Ja' : 'Nein' }}</strong></p>
</div>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<h6>Zugeordnete Firmen</h6> <h6>Zugeordnete Firmen</h6>
@@ -312,7 +322,9 @@ Vue.component('workorder-tenant-config', {
interventionTypes: [], interventionTypes: [],
workorderCreationFilters: '{}', workorderCreationFilters: '{}',
workorderActiveFilters: '{}', workorderActiveFilters: '{}',
civilEngineeringDocsRequired: 0 civilEngineeringDocsRequired: 0,
requireCableLength: 0,
requireCableType: 0
} }
: {visibleForAddressId: []}; : {visibleForAddressId: []};
this.showModal = true; this.showModal = true;