181 lines
9.2 KiB
HTML
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 %}
|