v2.3.1: corrige campo de CSS personalizado travado (Monaco criado oculto)

O editor era criado dentro de uma div com d-none: com display:none o
Monaco mede 0x0 e nasce sem área editável, enquanto o textarea ficava
oculto e disabled — resultado, campo impossível de editar.

- container passa a ser exibido ANTES do create (dimensões reais),
  mais layout() explícito e automaticLayout para relayout no resize;
- _force_default_lang evita o caminho de clonagem de linguagem do core
  (que quebra se a linguagem base não estiver registrada);
- textarea deixa de ser disabled: fica só oculto, com o valor do editor
  copiado nos eventos submit E formdata (form.submit() programático não
  dispara submit; formdata cobre os dois casos) — sem risco de perder a
  edição silenciosamente no POST;
- se o create falhar, rollback para o textarea comum.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Claude 2026-07-31 13:11:16 -03:00
parent e42eb2c798
commit b409b65895
2 changed files with 37 additions and 16 deletions

View file

@ -1,6 +1,6 @@
<?php <?php
define('PLUGIN_BUTTERFLY_VERSION', '2.3.0'); define('PLUGIN_BUTTERFLY_VERSION', '2.3.1');
// Minimal GLPI version, inclusive // Minimal GLPI version, inclusive
define("PLUGIN_BUTTERFLY_MIN_GLPI_VERSION", "11.0.0"); define("PLUGIN_BUTTERFLY_MIN_GLPI_VERSION", "11.0.0");

View file

@ -257,30 +257,46 @@ class Config extends \CommonDBTM {
); );
echo $value; echo $value;
echo '</textarea>'; echo '</textarea>';
echo '<div id="' . $containerId . '" class="d-none" style="height: 300px; border: 1px solid #dcdcdc"></div>'; echo '<div id="' . $containerId . '" class="d-none butterfly-css-monaco"></div>';
echo \Html::scriptBlock(' echo \Html::scriptBlock('
$(function() { $(function() {
if (window.GLPI === undefined || window.GLPI.Monaco === undefined) { if (window.GLPI === undefined || window.GLPI.Monaco === undefined) {
return; // sem Monaco nesta página — fica o textarea return; // sem Monaco nesta página — fica o textarea
} }
var taId = ' . json_encode($textareaId, JSON_HEX_TAG | JSON_HEX_AMP) . '; var $ta = $("#" + ' . json_encode($textareaId, JSON_HEX_TAG | JSON_HEX_AMP) . ');
var containerId = ' . json_encode($containerId, JSON_HEX_TAG | JSON_HEX_AMP) . '; var containerId = ' . json_encode($containerId, JSON_HEX_TAG | JSON_HEX_AMP) . ';
var fieldName = ' . json_encode($fullName, JSON_HEX_TAG | JSON_HEX_AMP) . '; var $container = $("#" + containerId);
window.GLPI.Monaco.createEditor(containerId, "scss", $("#" + taId).val(), []).then(() => {
$("#" + containerId).removeClass("d-none"); // O container precisa estar visível ANTES do create: com display:none
$("#" + taId).addClass("d-none").prop("disabled", true); // o Monaco mede 0x0 e nasce sem área editável
$("#" + containerId).closest("form").on("formdata", (e) => { $container.removeClass("d-none");
const editors = window.monaco.editor.getEditors().filter( $ta.addClass("d-none");
(editor) => editor._domElement.id === containerId
); window.GLPI.Monaco.createEditor(containerId, "scss", $ta.val(), [], {
if (editors.length) { _force_default_lang: true,
e.originalEvent.formData.delete(fieldName); automaticLayout: true,
e.originalEvent.formData.append(fieldName, editors[0].getValue()); minimap: { enabled: false },
} scrollBeyondLastLine: false,
fontSize: 13,
tabSize: 3
}).then((editor) => {
editor.editor.layout();
var $form = $container.closest("form");
// textarea segue habilitado (só oculto) e recebe o valor do editor.
// submit não dispara em form.submit() programático, por isso o
// formdata também: ele roda na montagem da entry list nos dois casos
$form.on("submit", function() {
$ta.val(editor.editor.getValue());
});
$form.on("formdata", function(e) {
$ta.val(editor.editor.getValue());
e.originalEvent.formData.set($ta.attr("name"), editor.editor.getValue());
}); });
}).catch(() => { }).catch(() => {
// editor falhou — mantém o textarea funcional // editor falhou — volta para o textarea comum
$container.addClass("d-none");
$ta.removeClass("d-none");
}); });
}); });
'); ');
@ -333,6 +349,11 @@ class Config extends \CommonDBTM {
border: 1px solid #eee; border: 1px solid #eee;
font-family: monospace; font-family: monospace;
} }
.butterfly-css-monaco {
width: 100%;
height: 300px;
border: 1px solid #dcdcdc;
}
.butterfly-themeselect-container .select2-selection__rendered, .butterfly-themeselect-container .select2-selection__rendered,
.butterfly-themeselect-dropdown .select2-results__option { .butterfly-themeselect-dropdown .select2-results__option {
height: 80px !important; height: 80px !important;