This commit is contained in:
2025-12-09 01:53:28 +01:00
parent cd1814e261
commit 4296c8651f

View File

@@ -82,6 +82,51 @@
}
};
const refreshPlaceholderComponent = (component) => {
if (!component) return;
if (typeof component.updatePlaceholderState === 'function') {
try {
component.updatePlaceholderState();
} catch (err) {
log('PLACEHOLDER WARN', `updatePlaceholderState Fehler: ${err && err.message ? err.message : err}`, '#b45309');
}
} else if (typeof component.trigger === 'function') {
component.trigger('change:attributes');
}
if (component.view && typeof component.view.render === 'function') {
component.view.render();
}
if (component.em && typeof component.em.trigger === 'function') {
component.em.trigger('component:update', component);
}
};
const buildPlaceholderLabel = (payload) => {
const type = payload.type === 'database' ? 'database' : 'custom';
if (type === 'database') {
const table = (payload.table || 'TABELLE').toUpperCase();
const column = (payload.column || 'FELD').toUpperCase();
return `${table}.${column}`;
}
return (payload.key || 'PLATZHALTER').toUpperCase();
};
const buildPlaceholderHTML = (payload) => {
const type = payload.type === 'database' ? 'database' : 'custom';
const attrs = [
`data-gjs-type="${PLACEHOLDER_COMPONENT}"`,
`data-placeholder-type="${type}"`,
];
if (type === 'database') {
attrs.push(`data-placeholder-table="${payload.table || ''}"`);
attrs.push(`data-placeholder-column="${payload.column || ''}"`);
} else {
attrs.push(`data-placeholder-key="${payload.key || ''}"`);
}
const label = buildPlaceholderLabel(payload);
return `<span ${attrs.join(' ')}>{{${label}}}</span>`;
};
const buildField = (labelText, control) => {
const controlId = `bridge-placeholder-field-${Math.random().toString(36).slice(2)}`;
control.id = controlId;
@@ -95,12 +140,17 @@
return wrapper;
};
const openPlaceholderModal = (editor, component) => {
if (!editor || !component || !component.is || !component.is(PLACEHOLDER_COMPONENT)) return;
const openPlaceholderModal = (editor, component, opts = {}) => {
if (!editor) return;
const modal = editor.Modal;
if (!modal) return;
const attrs = component.getAttributes ? component.getAttributes() : {};
if (component && (!component.is || !component.is(PLACEHOLDER_COMPONENT))) {
log('PLACEHOLDER WARN', 'openPlaceholderModal wurde ohne gültige Placeholder-Komponente aufgerufen.', '#b45309');
return;
}
const attrs = component && component.getAttributes ? component.getAttributes() : (opts.initial || {});
const initialType = attrs['data-placeholder-type'] || 'custom';
const initialKey = attrs['data-placeholder-key'] || 'UEBERSCHRIFT';
const initialTable = attrs['data-placeholder-table'] || '';
@@ -260,6 +310,35 @@
modal.close();
});
const applyPayload = (payload) => {
if (typeof opts.onSubmit === 'function') {
const res = opts.onSubmit(payload, { component, modal });
return res !== false;
}
if (!component || typeof component.addAttributes !== 'function') {
log('PLACEHOLDER INFO', 'Keine Ziel-Komponente gefunden Placeholder-Daten werden verworfen.', '#888');
return true;
}
if (payload.type === 'custom') {
component.addAttributes({
'data-placeholder-type': 'custom',
'data-placeholder-key': payload.key,
'data-placeholder-table': '',
'data-placeholder-column': '',
});
} else {
component.addAttributes({
'data-placeholder-type': 'database',
'data-placeholder-key': '',
'data-placeholder-table': payload.table,
'data-placeholder-column': payload.column,
});
}
refreshPlaceholderComponent(component);
return true;
};
form.addEventListener('submit', (e) => {
e.preventDefault();
errorBox.textContent = '';
@@ -271,12 +350,15 @@
keyInput.focus();
return;
}
component.addAttributes({
'data-placeholder-type': 'custom',
'data-placeholder-key': key,
'data-placeholder-table': '',
'data-placeholder-column': '',
});
const payload = {
type: 'custom',
key,
table: '',
column: '',
};
if (!applyPayload(payload)) {
return;
}
} else {
const table = tableSelect.value || '';
const column = columnSelect.value || '';
@@ -289,12 +371,15 @@
}
return;
}
component.addAttributes({
'data-placeholder-type': 'database',
'data-placeholder-key': '',
'data-placeholder-table': table,
'data-placeholder-column': column,
});
const payload = {
type: 'database',
key: '',
table,
column,
};
if (!applyPayload(payload)) {
return;
}
}
modal.close();
});
@@ -304,14 +389,50 @@
loadTables();
}
modal.setTitle('Placeholder bearbeiten');
modal.setTitle('Placeholder konfigurieren');
modal.setContent(container);
modal.open();
if (editor.getSelected() !== component) {
if (component && editor.getSelected && editor.getSelected() !== component) {
editor.select && editor.select(component);
}
};
const ensureRtePlaceholderButton = (editor) => {
const rte = editor && editor.RichTextEditor;
if (!rte || rte.__bridgePlaceholderButton) return;
rte.__bridgePlaceholderButton = true;
rte.add('bridge-placeholder', {
icon: '<i class="fa fa-bookmark"></i>',
attributes: { title: 'Placeholder einfügen' },
result: (rteInstance) => {
const target = editor && editor.getSelected && editor.getSelected();
if (!target || !target.is || !target.is('text')) {
log('PLACEHOLDER INFO', 'Bitte zuerst ein Text-Element auswählen.', '#888');
return;
}
openPlaceholderModal(editor, null, {
onSubmit: (payload) => {
const html = buildPlaceholderHTML(payload);
if (rteInstance && typeof rteInstance.insertHTML === 'function') {
rteInstance.insertHTML(html);
} else if (typeof document !== 'undefined' && document.execCommand) {
document.execCommand('insertHTML', false, html);
} else {
log('PLACEHOLDER ERROR', 'Placeholder konnte nicht eingefügt werden (kein RTE).', 'red', 'error');
return false;
}
if (rteInstance && typeof rteInstance.focus === 'function') {
rteInstance.focus();
}
return true;
}
});
},
});
log('RTE', 'Placeholder-Button im RichTextEditor registriert.', '#DAA520');
};
function addOnce(bm, id, def, category = TARGET_CAT_ID) {
try {
bm.add(id, { ...def, category });
@@ -628,6 +749,13 @@
});
}
const bindRteButton = () => ensureRtePlaceholderButton(editor);
if (editor.RichTextEditor) {
bindRteButton();
} else if (typeof editor.on === 'function') {
editor.on('load', bindRteButton, { once: true });
}
addOnce(bm, 'cust-placeholder-custom', {
id: 'cust-placeholder-custom',
label: '🔖 Placeholder (Text)',