tool_dd_label
A UI-only editor that renders a tool's multi-language label set — the JSON stored in a component_json (dd1372) field — as an editable key × language matrix, and writes edits straight back into the field's editor. It generates the dd1372 labels payload; it has no server actions.
UI-only tool
tool_dd_label ships no server/ package — there is no tools/tool_dd_label/server/ directory. All behavior is client-side; the tool never calls tool_request. It reads and writes the caller component_json's in-memory editor value, and persistence is deferred to that component's own save.
What it does / why & when to use it
A Dédalo tool's interface strings — button captions, panel titles, confirmation prompts — are stored as a flat array of label objects in a component_json field, dd1372 (Tool labels). Each element is { lang, name, value }: name is the machine-readable label key, lang is an IETF-style language code (lg-eng, lg-spa), and value is the translated string. Multiple elements share a name and differ by lang.
tool_dd_label renders that array as a matrix so a tool author edits a table instead of raw JSON:
- rows = the unique
namekeys (self.ar_names, derived fromar_data); - columns = one per project language, from
page_globals.dedalo_projects_default_langs(self.loaded_langs).
Each cell is a contenteditable div. It is used while authoring or translating a tool — to compose the labels its UI reads. It is not a content-translation tool.
How it works (server + client)
Server. None. tools/tool_dd_label/ ships only register.json, js/, css/ and img/. Any action dispatched against this tool through dd_tools_api is refused at the dispatch gate (no server module).
Client (tools/tool_dd_label/js/):
index.jsis a barrel re-export oftool_dd_label.js.tool_dd_label.jsis the instance. It wires the standardtool_commonlifecycle:render/buildfromtool_common,destroy/refreshfromcommon, andeditfromrender_tool_dd_label.init(options)callstool_common.prototype.init, then: loadspage_globals.dedalo_projects_default_langsintoself.loaded_langs; resolves the caller's first editor (self.caller.editors[0]— the JSON editor of thecomponent_json); reads the editor's current in-memory value viaeditor.get()(the editor returns either{json}or{text}depending on its parse state; both are normalized to a plain object) so unsaved edits are preserved; coerces the result to an arrayself.ar_data; and derivesself.ar_namesas the unique, ordered list ofnamevalues. If the caller has no editor, the error is caught intoself.errorand the base error renderer is shown.render_tool_dd_label.js::editbuilds the wrapper (ui.tool.build_wrapper_edit) and the content.get_content_databuilds a<ul class="label_matix">CSS-grid element withgrid-template-columns: 2em repeat(<lang_count + 1>, 1fr)— a 2em action column, anamecolumn, and one column per language — then a header row plus onerender_rowper entry inar_names. The<ul>is stored asself.label_matixso the add-row handler can append to it.render_rowbuilds each<li>: a leftmost action cell (an add button on the header row that appends a new blank data row; a remove button on data rows that confirms viaconfirm(), then splices everyar_dataentry matching the row's key, drops the key fromar_names, callsupdate_data(), and removes the node); acontenteditablename cell whose edit (on blur / Enter) normalizes the text (trim → lowercase → spaces replaced with underscores), renames the matchingar_dataitems and thear_namesentry, and flushes; and one language cell per language viarender_language_label.render_language_labelbuilds eachname × langcell: on the header row a read-only div showing the language's display label; on data rows acontenteditablediv pre-filled with the stored value (looked up inar_databyname+lang), with aplaceholderdataset of the key name. On blur and on Enter it callsself.save_label_lang_sequence(textContent, key, lang).save_label_lang_sequence(value, key, lang)upserts or deletes one cell: an empty value with no existing record is a no-op; an empty value with an existing record splices it out; a non-empty value updates the matching record in place or pushes a new{lang, name, value}. It then callsupdate_data().update_data()flushesar_datato the caller: it deep-clones the array (JSON.parse(JSON.stringify(...))), pushes it into the editor witheditor.set({json}), and notifies the component withself.caller.set_value(immutable_value, 0). It skips redundant writes by comparing againstself.last_value. It does not save to the server — persistence requires the user to click save on the callercomponent_json.on_close_actions(open_as)destroys the instance when opened as a modal so it can be reopened.
Actions & options
tool_dd_label has no API actions — it is UI-only.
| Action | Permission gate | Background | Reads from options |
|---|---|---|---|
| (none) | — | — | — |
(no server module). What the client reads instead:
| Source | Field | Meaning |
|---|---|---|
| caller | caller.editors[0] |
the component_json (dd1372) JSON editor whose in-memory value the tool edits |
| globals | page_globals.dedalo_projects_default_langs |
the project languages → one matrix column each |
| derived | ar_data, ar_names |
the live {lang, name, value} array and the ordered unique key list driving the rows |
How it is registered & surfaced
tools/tool_dd_label/register.json is a column-keyed dump (a seeded matrix-row snapshot, not hand-authored); importTools() passes it through as-is (see register.json reference). The essentials it carries:
dd1326name =tool_dd_label;dd1327version =1.0.2;dd1328minimum Dédalo version =6.0.1;dd1644developer = Dédalo team.dd799label = Label composition (localized across project languages).dd612description = "Creates tool labels in all available langs. This tool will generate JSON data and only will be applied to component_json (dd1372)".dd1350affected_tipos =["dd1372"]→ the tool attaches only tocomponent_jsonfields of tipodd1372.dd1335properties ={}(empty). The client'son_close_actionsstill branches onopen_as(modal/window), defaulting when properties do not set one.
Surfacing (getElementTools, src/core/tools/registry.ts): restricted by affected_tipos to dd1372, so the tool appears on the Tool labels field of a tool registry record. The record itself lives in the Tools development section (section tipo dd1340).
Examples
There is no tool_request to show. The data the tool edits is the dd1372 label array — one object per key × language:
[
{ "lang": "lg-eng", "name": "process", "value": "Process" },
{ "lang": "lg-spa", "name": "process", "value": "Procesar" },
{ "lang": "lg-eng", "name": "confirm", "value": "Are you sure?" },
{ "lang": "lg-spa", "name": "confirm", "value": "¿Está seguro?" }
]
process and confirm become the two matrix rows; lg-eng and lg-spa become two columns; each value fills the corresponding cell. Emptying a cell removes that {lang, name, value} element; renaming the row's key rewrites name on every element that shares it.
Related
- tool_lang — automatic translation of a content component's data (a different subject: it translates records, not tool labels).
- Creating new tools — where tool labels fit in the registration flow; register.json reference — the
dd1372labels field. - Server contract · Security — why a UI-only tool with no
server/package is refused cleanly at dispatch. - JS lifecycle — the
init/build/render/editflow this tool follows. - Tools catalog — full list of shipped tools.
- Source:
tools/tool_dd_label/register.json(noserver/package),tools/tool_dd_label/js/{index,tool_dd_label,render_tool_dd_label}.js,tools/tool_dd_label/css/tool_dd_label.less.