Dynatrace App — spreadsheet-like editor for Grail lookup tables (/lookups/…).
React + Strato + @dynatrace-sdk, built with the App Toolkit (dt-app).
A zero-dependency vanilla-JS build of the same tool also exists (custom-app manifest + static
ui/, uploaded via App Management) — not included here.
| Route | View |
|---|---|
/ |
list every /lookups/… table (Strato DataTable, sortable/resizable); open, delete, create |
/edit?path=… |
editable grid (DataTable + TextInput cells), add/rename/delete columns, add/delete rows, edit display name / description / key field, Save. Also: Replace from CSV, Download CSV (backup, includes unsaved edits), Revert, unsaved-changes guard, invalid cells highlighted red on Save |
/new |
create a table from path + columns + optional initial rows, or import a CSV file (choose: column names from the file's first row, or set them manually — forced to the file's actual comma-delimited column count, with an optional "skip first row" toggle); key field is a required dropdown over the current columns |
Auth is injected by the app runtime (dev server proxy locally, AppEngine in-product).
| Op | Call | File |
|---|---|---|
| list | queryExecutionClient.queryExecute → fetch dt.system.files | filter startsWith(name,"/lookups/") |
ui/app/api/lookups.ts |
| read | queryExecutionClient → load "/lookups/<x>" |
lookups.ts |
| save | POST /platform/storage/resource-store/v1/files/tabular/lookup:upload (multipart request + content) |
lookups.ts |
| delete | POST /platform/storage/resource-store/v1/files:delete |
lookups.ts |
Serialization: every field double-quoted (embedded " doubled per RFC4180), header included,
skippedRecords: 1, parse pattern CSVDQS:c1 ',' CSVDQS:c2 — CSVDQS is DPL's built-in
RFC4180 quoted-CSV-field matcher, so commas and embedded double-quotes at any position round-trip
correctly. Values with a literal newline are still rejected on save (Grail splits uploaded content
into records by line before DPL runs, so an embedded \n would silently split one row into two
regardless of quoting).
storage:files:read storage:files:write storage:files:delete storage:system:read
Download lookup-editor-<version>.zip from the
latest release,
then Dynatrace → App Management → Upload app.
nvm use 24
npm install
npm run start # dt-app dev — opens browser, SSO loginnpm run build # dist/ui/
npm run package # → out/artifact.zip (upload via App Management)
npm run deploy # dt-app deploy → registers a new version directly- Save rewrites the whole table (no cell-level diff). Mitigations: Download CSV, Revert, concurrency warning.
- No server-side version history (Resource Store keeps none).
- Values with a literal newline blocked on save (flagged red). Commas / quotes / tabs / spaces are fine.
parsePatternis regenerated from current columns, not read back from the stored file.- Editable grid uses uncontrolled inputs + in-place mutation; fine for typical lookups. A very large table (10k+ rows) may still want a windowed rewrite.
- Confirmations use
window.confirm(works in AppEngine); only the text-input prompt was moved to a Strato Modal.