Issue 260 Dashboard Widget Cog Did Nothing - edmozley/freeitsm GitHub Wiki

The dashboard cog did nothing, and no widget could be created or edited

Reported: #260, November 2026 ยท Module: Tickets โ†’ Dashboard ยท Fixed in: the release after 4.10.0 (changelog #2740)


What you saw

On Tickets โ†’ Dashboard, clicking the cog on any widget did nothing: no edit window, no message. The browser console showed:

Uncaught ReferenceError: esc is not defined
    at onPropertyChange (widget-editor.js:229)
    at Object.populateForm (widget-editor.js:340)
    at openWidgetEditModal (dashboard/:3348)

The same fault was behind two buttons nobody had reported. In the Widget Library, New widget and Edit went through the same code and failed in the same way. So from 2.5.0 to 4.10.0, nobody could create a widget or change one from the screen. Adding, removing, reordering, duplicating and deleting widgets all still worked.


What was actually wrong

One name, two lines

The edit form is shared by the dashboard and the library through one script, assets/js/widget-editor.js (see the Developer Guide). Its escape helper is called escapeHtml().

In 2.5.0, the change that translated the last screens (#1895-#1903) rewrote two lines in onPropertyChange() - the part that rebuilds the Series dropdown - to translate the option text, and escaped it with esc(). Most FreeITSM scripts have an esc(). This one did not.

Why every way in failed

onPropertyChange() is not only run when you change What to count. Every way of opening the form calls it, so the dropdowns suit the widget:

  • the cog โ†’ populateForm() โ†’ onPropertyChange()
  • library Edit โ†’ populateForm() โ†’ onPropertyChange()
  • library New widget โ†’ resetForm() โ†’ onPropertyChange()

The error stopped each of them before the form was shown. The dashboard shows its modal on the line after populateForm(), so the click looked as if it did nothing.

Why it was easy to miss

There is no server error and nothing in a log. The page loads perfectly, and the charts draw. The failure only appears on a click, and only in the browser console. The existing escape-helper test checked that every helper escapes quotes. It did not check that the helper a script calls is one it has.


The fix

// assets/js/widget-editor.js, onPropertyChange()
seriesSelect.innerHTML = '<option value="">' +
    escapeHtml(we('form.series_none', 'None (single series)')) + '</option>';
...
seriesSelect.innerHTML += '<option value="' + s + '">' + escapeHtml(label) + '</option>';

The script's version number was bumped to ?v=3 on both pages, so browsers fetch the fixed copy.

No database change, nothing to run after upgrading. Widgets were never damaged - they just could not be opened.


Files changed

File Change
๐Ÿ”ต assets/js/widget-editor.js esc() โ†’ escapeHtml(), twice
๐Ÿ”ต tickets/dashboard/index.php widget-editor.js?v=3
๐Ÿ”ต tickets/dashboard/library.php widget-editor.js?v=3
๐Ÿงช tests/escape-helpers-quotes.php new check: no script in assets/js/ calls esc() without defining it or importing it (esc = P.esc, { esc } = window.Dom)

How it was proved

  • In a real browser. Headless Chrome opened the dashboard as an admin and clicked the first cog. With the fix, the edit window opened, filled with Tickets by status, and there were no errors. Control: the same click with the old file in place threw esc is not defined, and the window stayed shut.
  • php tests/escape-helpers-quotes.php - 6 passed. Control: against the old widget-editor.js it fails, naming that file. Its own two controls prove that it flags an undefined esc() and does not flag one imported from a shared module.
  • The sweep, first time round, listed 15 scripts. 14 import esc from a shared module (the Projects, Domains, Starters and Files screens), so the check now recognises that. Only widget-editor.js was really broken.

Not proven live: the library's New widget and Edit were not clicked in the browser. They fail and recover through the same function, which the cog run does exercise.


What this means for you

  • After upgrading, the cog opens the edit window again, and New widget and Edit work in the Widget Library.
  • Editing a widget changes it for everyone who has it on their dashboard - the library is shared. To change one just for yourself, Duplicate it in the library and add the copy.

Related

โš ๏ธ **GitHub.com Fallback** โš ๏ธ