Files
bin/espocrm-table-var-col_claude-code-instructions.md
mkt cebe829dcd Add README, customization snapshot, and snapshot/restore tooling
Provisioning now restores all GUI customizations on reset+reprovision:

- create_pod_espocrm.sh: deploy the version-controlled espocrm-custom/ tree
  (CTag entity, layouts, i18n, clientDefs, custom views, custom CSS) into the
  pod, then chown www-data and rebuild. Replaces the earlier inline CSS-only
  step. Adds a live-phase cache rebuild so customizations and the client
  cacheTimestamp are refreshed on every run.
- espocrm-custom/: snapshot of custom/ and client/custom/ (source of truth).
- snapshot_espocrm_custom.sh: refresh the snapshot from a running pod.
- readme.md: usage, first-time host setup, image-update and reset workflows.
- Include the task/instruction notes and plan.md for reference.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 16:51:02 +02:00

93 lines
4.9 KiB
Markdown

# EspoCRM Customization: Variable Column Widths for Markdown Tables
Instructions for Claude Code. Goal: integrate a custom CSS file into the EspoCRM provisioning so that Markdown tables in text fields get content-based column widths instead of equal fixed widths. The EspoCRM installation is generated by a shell script into a Podman pod, so **both files below must be created by the provisioning script** — manual edits inside the pod would be lost on the next provisioning run.
## Problem and Root Cause
EspoCRM renders Markdown in text fields (e.g. Opportunity → `Beschreibung`) inside `.complex-text` containers. The core stylesheet contains this rule (verified live on this instance, EspoCRM 9.3.8, 2026-06-06):
```css
.alert table, .alert > .message table, .complex-text table,
.confirm-message table, .popover-content table {
table-layout: fixed;
width: 100%;
}
```
`table-layout: fixed` distributes the table width equally across all columns regardless of content. Measured effect on a 4-column table in a record detail view: every column 200 px wide, causing short columns (`Nr.`, `Bew.`) to waste space and the long `Anforderung` column to wrap into unnecessarily tall rows.
With `table-layout: auto`, columns size to their content. Verified by live style injection on the test record: column widths became 37 / 112 / 49 / 604 px — exactly the desired result.
## Solution: EspoCRM Custom CSS Mechanism
EspoCRM's official mechanism for custom stylesheets ([docs](https://docs.espocrm.com/development/custom-css/)): register the CSS file in the `cssList` metadata. Both involved directories (`client/custom/`, `custom/`) are upgrade-safe — EspoCRM upgrades do not touch them. The CSS filename is arbitrary; we use the declarative name `table-var-col.css`.
### File 1 (new): `<espocrm-root>/client/custom/css/table-var-col.css`
```css
/**
* Variable column widths for Markdown tables in text fields.
*
* EspoCRM core CSS forces `table-layout: fixed; width: 100%` on
* `.complex-text table`, which makes all columns equally wide.
* `auto` lets columns size to content instead.
*
* Registered via custom/Espo/Custom/Resources/metadata/app/client.json (cssList).
*/
.complex-text table {
table-layout: auto !important;
width: auto !important;
max-width: 100% !important;
}
```
Notes:
- The selector deliberately targets only `.complex-text` (text fields on record views), not the alert/popover tables of the core rule.
- `!important` guards against load-order variations; `cssList` entries are appended after the theme stylesheet, but this makes the override robust either way.
### File 2 (new or merge): `<espocrm-root>/custom/Espo/Custom/Resources/metadata/app/client.json`
```json
{
"cssList": [
"__APPEND__",
"client/custom/css/table-var-col.css"
]
}
```
**IMPORTANT — merge, do not overwrite:** This instance already has GUI customizations. If `client.json` already exists, append the path to the existing `cssList` array (keeping `"__APPEND__"` as its first element) and leave all other keys untouched. Check first.
## Integration into the Provisioning Script
1. Locate where the script already injects EspoCRM GUI customizations and follow the same convention (e.g. `podman cp`, volume mount, or heredoc).
2. Create both files after the EspoCRM installation step.
3. Match file ownership/permissions to the other EspoCRM application files (typically the webserver user inside the container, e.g. `www-data:www-data`). The CSS file must be readable by the webserver.
4. Clear the cache afterwards — `cssList` is metadata and is cached:
```bash
podman exec <container> php /var/www/html/clear_cache.php
# or, if the script already performs a rebuild:
podman exec <container> php /var/www/html/rebuild.php
```
(Adapt container name and EspoCRM root path to the script's actual values.)
## Testing
1. **Persistence test (the actual requirement):** re-run the provisioning script from scratch, then verify both files exist inside the pod:
`podman exec <container> ls -l /var/www/html/client/custom/css/table-var-col.css /var/www/html/custom/Espo/Custom/Resources/metadata/app/client.json`
2. Log in to the CRM, hard-reload (`Ctrl+F5`). In DevTools → Network, filter for `table-var-col` → the stylesheet must load with HTTP 200.
3. Open the test record (4-column Markdown table in `Beschreibung`):
`https://crm.creature-go.com/#Opportunity/view/6a23fc99e2391e7be`
4. Visual check: columns `Nr.`, `Einordnung`, `Bew.` at minimal width, `Anforderung` takes the remaining space; rows are one to two lines instead of uniformly tall.
5. Programmatic check in the DevTools console:
```js
getComputedStyle(document.querySelector('.complex-text table')).tableLayout
// expected: "auto" (without the fix: "fixed")
```
6. Regression check: open a record whose description contains no table and one with other Markdown (lists, headings) — rendering must be unchanged. Existing GUI customizations must still be active.