Files
Netbox-Documentation/netbox_documentation/templates/netbox_documentation/document_edit.html
T

181 lines
9.2 KiB
HTML

{% extends 'generic/object_edit.html' %}
{% block javascript %}
{{ block.super }}
<style>
body.documentation-editor-page .container-xl { max-width: none !important; }
</style>
<script src="{% url 'plugins:netbox_documentation:editor_asset' asset_path='tinymce.min.js' %}"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
document.body.classList.add('documentation-editor-page');
const bodyField = document.querySelector('#id_body');
if (bodyField) {
const contentGroup = bodyField.closest('.field-group');
if (contentGroup) contentGroup.classList.add('documentation-content-group');
}
const editorAssetBase = "{% url 'plugins:netbox_documentation:editor_asset' asset_path='_' %}".replace(/_$/, '');
if (typeof tinymce === 'undefined') {
const editor = document.querySelector('[data-rich-text-editor]');
if (editor) {
const warning = document.createElement('div');
warning.className = 'alert alert-warning';
warning.textContent = 'Der Rich-Text-Editor konnte nicht vom lokalen Plugin-Endpunkt geladen werden. Bitte Browser-Konsole und Netzwerkprotokoll prüfen.';
editor.parentNode.insertBefore(warning, editor);
}
return;
}
tinymce.init({
selector: 'textarea[data-rich-text-editor]',
base_url: editorAssetBase.replace(/\/$/, ''),
suffix: '.min',
license_key: 'gpl',
height: 650,
menubar: 'file edit view insert format tools table help',
plugins: 'advlist anchor autolink charmap code fullscreen image link lists media preview searchreplace table visualblocks wordcount',
toolbar: [
'undo redo | blocks styles fontfamily fontsize | bold italic underline strikethrough | forecolor backcolor',
'alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table tablecellcolor link image media | removeformat code fullscreen'
],
toolbar_mode: 'sliding',
table_toolbar: 'tableprops tablecellprops tablecellcolor | tableinsertrowbefore tableinsertrowafter tabledeleterow | tableinsertcolbefore tableinsertcolafter tabledeletecol | tablemergecells tablesplitcells | tabledelete',
table_appearance_options: true,
table_advtab: true,
table_cell_advtab: true,
table_row_advtab: true,
table_sizing_mode: 'responsive',
table_default_attributes: {border: '1'},
table_default_styles: {'border-collapse': 'collapse'},
table_class_list: [
{title: 'Standard mit Rahmen', value: 'doc-table-bordered'},
{title: 'Kompakt', value: 'doc-table-compact'},
{title: 'Gestreifte Zeilen', value: 'doc-table-striped'},
{title: 'Blaue Kopfzeile', value: 'doc-table-header-blue'},
{title: 'Grüne Kopfzeile', value: 'doc-table-header-green'},
{title: 'Dunkle Kopfzeile', value: 'doc-table-header-dark'},
{title: 'Ohne Rahmen', value: 'doc-table-borderless'},
{title: 'Volle Breite', value: 'doc-table-full-width'}
],
table_cell_class_list: [
{title: 'Normal', value: ''},
{title: 'Gelb hervorheben', value: 'doc-cell-yellow'},
{title: 'Grün hervorheben', value: 'doc-cell-green'},
{title: 'Rot hervorheben', value: 'doc-cell-red'},
{title: 'Blau hervorheben', value: 'doc-cell-blue'},
{title: 'Vertikal mittig', value: 'doc-cell-middle'}
],
style_formats_merge: true,
style_formats: [
{title: 'Tabellenzelle: Gelb', selector: 'td,th', classes: 'doc-cell-yellow'},
{title: 'Tabellenzelle: Grün', selector: 'td,th', classes: 'doc-cell-green'},
{title: 'Tabellenzelle: Rot', selector: 'td,th', classes: 'doc-cell-red'},
{title: 'Tabellenzelle: Blau', selector: 'td,th', classes: 'doc-cell-blue'}
],
font_family_formats: 'Arial=arial,helvetica,sans-serif; Calibri=calibri,arial,sans-serif; Courier New=courier new,courier,monospace; Georgia=georgia,palatino,serif; Times New Roman=times new roman,times,serif; Verdana=verdana,geneva,sans-serif',
font_size_formats: '8pt 9pt 10pt 11pt 12pt 14pt 16pt 18pt 20pt 24pt 28pt 32pt 36pt 48pt',
content_style: `
body { font-family: Arial, sans-serif; font-size: 11pt; padding: 1rem; }
table { border-collapse: collapse; width: auto; }
th, td { border: 1px solid #adb5bd; padding: .45rem; }
table.doc-table-full-width { width: 100%; }
table.doc-table-compact th, table.doc-table-compact td { padding: .2rem .35rem; font-size: .875rem; }
table.doc-table-striped tbody tr:nth-child(even) td { background: #f1f3f5; }
table.doc-table-header-blue thead th { background: #206bc4; color: #fff; }
table.doc-table-header-green thead th { background: #2b8a3e; color: #fff; }
table.doc-table-header-dark thead th { background: #343a40; color: #fff; }
table.doc-table-borderless, table.doc-table-borderless th, table.doc-table-borderless td { border: 0; }
.doc-cell-yellow { background: #fff3bf !important; }
.doc-cell-green { background: #d3f9d8 !important; }
.doc-cell-red { background: #ffe3e3 !important; }
.doc-cell-blue { background: #dbeafe !important; }
.doc-cell-middle { vertical-align: middle !important; }
`,
browser_spellcheck: true,
contextmenu: 'link image table',
promotion: false,
branding: false,
convert_unsafe_embeds: true,
paste_data_images: true,
paste_merge_formats: false,
paste_webkit_styles: 'all',
paste_remove_styles_if_webkit: false,
paste_convert_word_fake_lists: true,
smart_paste: true,
images_reuse_filename: true,
relative_urls: false,
setup: editor => {
const selectedTableCells = () => {
const markedCells = Array.from(editor.getBody().querySelectorAll(
'td[data-mce-selected="1"], th[data-mce-selected="1"]'
));
if (markedCells.length) return markedCells;
const currentCell = editor.dom.getParent(editor.selection.getNode(), 'td,th');
return currentCell ? [currentCell] : [];
};
const applyCellColor = color => {
const cells = selectedTableCells();
if (!cells.length) return;
editor.undoManager.transact(() => {
cells.forEach(cell => editor.dom.setStyle(cell, 'background-color', color));
});
editor.nodeChanged();
};
const chooseCellColor = () => {
const picker = document.createElement('input');
picker.type = 'color';
picker.value = '#fff3bf';
picker.style.position = 'fixed';
picker.style.opacity = '0';
picker.addEventListener('input', () => applyCellColor(picker.value), {once: true});
picker.addEventListener('change', () => picker.remove(), {once: true});
document.body.appendChild(picker);
picker.click();
};
const palette = [
['Gelb', '#fff3bf'], ['Grün', '#d3f9d8'], ['Blau', '#dbeafe'],
['Rot', '#ffe3e3'], ['Orange', '#ffe8cc'], ['Grau', '#e9ecef'],
['Dunkelgrün', '#a5bf60'], ['Dunkelblau', '#206bc4'], ['Dunkelgrau', '#343a40']
];
editor.ui.registry.addMenuButton('tablecellcolor', {
icon: 'highlight-bg-color',
tooltip: 'Farbeimer für Tabellenzellen',
fetch: callback => callback([
...palette.map(([name, color]) => ({
type: 'menuitem',
text: name,
onAction: () => applyCellColor(color)
})),
{type: 'separator'},
{type: 'menuitem', text: 'Eigene Farbe …', onAction: chooseCellColor},
{type: 'menuitem', text: 'Zellfarbe entfernen', onAction: () => applyCellColor('')}
])
});
}
{% if object.pk %},
images_file_types: 'jpg,jpeg,png,gif,webp',
automatic_uploads: true,
images_upload_handler: (blobInfo, progress) => new Promise((resolve, reject) => {
const data = new FormData();
data.append('file', blobInfo.blob(), blobInfo.filename());
fetch("{% url 'plugins:netbox_documentation:document_media_upload' pk=object.pk %}", {
method: 'POST',
headers: {'X-CSRFToken': document.querySelector('input[name=csrfmiddlewaretoken]').value},
body: data,
credentials: 'same-origin'
}).then(async response => {
const payload = await response.json();
if (!response.ok) throw new Error(payload.error || 'Upload fehlgeschlagen');
resolve(payload.location);
}).catch(error => reject(error.message));
})
{% endif %}
});
});
</script>
{% endblock javascript %}
{% block pre_form_fields %}
{% if not object.pk %}
<div class="alert alert-info">Speichere die neue Dokumentation einmal. Danach können Bilder direkt über die Editor-Werkzeugleiste hochgeladen werden.</div>
{% endif %}
{% endblock pre_form_fields %}