diff --git a/README.md b/README.md index 85424b6a..f307450f 100644 --- a/README.md +++ b/README.md @@ -590,7 +590,202 @@ sudo find custom/ -type f -name "*.json" -exec chmod 664 {} \; sudo find custom/ -type d -exec chmod 775 {} \; ``` -## 9. Portal-Freigabe-System +## 9. Reports und Report-Panels + +EspoCRM bietet über das Advanced Pack zwei Arten von Report-Integrationen: **Report-Filter** und **Report-Panels**. Diese ermöglichen die dynamische Anzeige von gefilterten Listen in Entity-Views. + +### Report-Filter + +Report-Filter ermöglichen es, vordefinierte Filter auf List-Views anzuwenden, die in Datenbanktabellen gespeichert sind. + +#### Struktur und Dateien: + +1. **entityDefs/{EntityType}.json** - Filter-Definition +```json +{ + "collection": { + "filters": { + "reportFilterXXXXXXXXXX": { + "isReportFilter": true, + "id": "reportFilterIdHere" + } + } + } +} +``` + +2. **selectDefs/{EntityType}.json** - Filter-Klasse +```json +{ + "primaryFilterClassNameMap": { + "reportFilterXXXXXXXXXX": "Espo\\Modules\\Advanced\\Classes\\Select\\Common\\PrimaryFilters\\ReportFilter" + } +} +``` + +3. **clientDefs/{EntityType}.json** - Frontend-Integration +```json +{ + "filterList": [ + "__APPEND__", + { + "isReportFilter": true, + "name": "reportFilterXXXXXXXXXX", + "accessDataList": [ + { + "teamIdList": ["team-id-here"] + } + ] + } + ] +} +``` + +4. **i18n/{Language}/{EntityType}.json** - Übersetzungen +```json +{ + "presetFilters": { + "reportFilterXXXXXXXXXX": "Filter-Name" + } +} +``` + +### Report-Panels + +Report-Panels zeigen Listen von Entitäten in Side-Panels der Detail-View an. Sie können Team-basierte Zugriffskontrolle haben. + +#### Struktur: + +**clientDefs/{EntityType}.json** - Panel-Definition +```json +{ + "sidePanels": { + "detail": [ + "__APPEND__", + { + "isReportPanel": true, + "name": "reportPanelXXXXXXXXXX", + "label": "Panel-Titel", + "view": "advanced:views/report-panel/record/panels/report-panel-side", + "reportPanelId": "reportPanelIdHere", + "reportType": "List", + "reportEntityType": "EntityType", + "displayType": "List", + "displayTotal": false, + "displayOnlyTotal": false, + "useSiMultiplier": true, + "accessDataList": [ + { + "scope": "EntityType" + }, + { + "teamIdList": ["team-id-here"] + } + ] + } + ] + } +} +``` + +### Wichtige Eigenschaften: + +- **`isReportFilter`/`isReportPanel`**: Markiert den Eintrag als Report-Element +- **`accessDataList`**: Array von Zugriffsbedingungen (Team-IDs, Scopes) +- **`reportType`**: `"List"` für Listen-Reports +- **`displayType`**: Anzeige-Typ (`"List"`, `"Chart"`, etc.) +- **`view`**: Spezielle Report-Panel-View aus dem Advanced Pack +- **`__APPEND__`**: Erweitert bestehende Arrays statt sie zu überschreiben + +### Best Practices: + +1. **Naming Convention**: + - Filter: `reportFilter{uniqueId}` (z.B. `reportFilter6972174b6540731c1`) + - Panels: `reportPanel{uniqueId}` (z.B. `reportPanel697216784307d43ad`) + +2. **Team-basierte Zugriffskontrolle**: + - Definiere `teamIdList` in `accessDataList` für eingeschränkten Zugriff + - Mehrere Teams können kombiniert werden + +3. **Mehrsprachigkeit**: + - Labels in allen Sprachen definieren (de_DE, en_US) + - Fehlerhafte Labels können zu UI-Problemen führen + +4. **Datei-Abhängigkeiten**: + - Report-Filter benötigen 4 Dateien: entityDefs, selectDefs, clientDefs, i18n + - Report-Panels benötigen 1 Datei: clientDefs + - Fehlende Dateien führen zu nicht-funktionalen Filtern + +5. **Placeholder-Dateien**: + - `logicDefs/{EntityType}.json` kann als leeres Objekt `{}` angelegt werden + - Ermöglicht zukünftige Erweiterungen ohne Struktur-Änderungen + +### Beispiel-Implementation: + +**Szenario**: UserTask-Filter für Team "vermieterhelden" + +```bash +# entityDefs/BpmnUserTask.json +{ + "collection": { + "filters": { + "reportFilter6972174b6540731c1": { + "isReportFilter": true, + "id": "6972174b6540731c1" + } + } + } +} + +# selectDefs/BpmnUserTask.json +{ + "primaryFilterClassNameMap": { + "reportFilter6972174b6540731c1": "Espo\\Modules\\Advanced\\Classes\\Select\\Common\\PrimaryFilters\\ReportFilter" + } +} + +# clientDefs/BpmnUserTask.json +{ + "filterList": [ + "__APPEND__", + { + "isReportFilter": true, + "name": "reportFilter6972174b6540731c1", + "accessDataList": [ + { + "teamIdList": ["68da9bdd622c9958a"] + } + ] + } + ] +} + +# i18n/en_US/BpmnUserTask.json +{ + "presetFilters": { + "reportFilter6972174b6540731c1": "UserTask" + } +} +``` + +### Troubleshooting: + +- **Filter erscheint nicht**: Prüfe ob alle 4 Dateien existieren und Rebuild durchgeführt wurde +- **Zugriffsfehler**: Überprüfe `teamIdList` und User-Team-Zuordnung +- **Leere Liste**: Report-Definition in DB prüfen (Tabelle: `report`) +- **Falsches Label**: i18n-Dateien in allen Sprachen prüfen + +### Nach Änderungen: + +```bash +# Rebuild durchführen +docker exec espocrm php /var/www/html/command.php Rebuild + +# Oder Check-Script verwenden +./custom/scripts/check_and_rebuild.sh +``` + +## 10. Portal-Freigabe-System Um Entitäten für Portalnutzer (Contact-Entität) freizugeben, wurde ein konsistentes Freigabe-System implementiert: diff --git a/custom/Espo/Custom/Resources/i18n/en_US/BpmnUserTask.json b/custom/Espo/Custom/Resources/i18n/en_US/BpmnUserTask.json new file mode 100644 index 00000000..85d0f58b --- /dev/null +++ b/custom/Espo/Custom/Resources/i18n/en_US/BpmnUserTask.json @@ -0,0 +1,5 @@ +{ + "presetFilters": { + "reportFilter6972174b6540731c1": "UserTask" + } +} \ No newline at end of file diff --git a/custom/Espo/Custom/Resources/layouts/CVmhErstgespraech/sidePanelsDetail.json b/custom/Espo/Custom/Resources/layouts/CVmhErstgespraech/sidePanelsDetail.json index 3c08e6b3..eb2d48a4 100644 --- a/custom/Espo/Custom/Resources/layouts/CVmhErstgespraech/sidePanelsDetail.json +++ b/custom/Espo/Custom/Resources/layouts/CVmhErstgespraech/sidePanelsDetail.json @@ -2,9 +2,6 @@ "_delimiter_": { "disabled": true }, - "tasks": { - "disabled": true - }, "default": { "index": 0 }, @@ -13,5 +10,8 @@ }, "history": { "index": 2 + }, + "tasks": { + "index": 3 } } \ No newline at end of file diff --git a/custom/Espo/Custom/Resources/metadata/clientDefs/BpmnUserTask.json b/custom/Espo/Custom/Resources/metadata/clientDefs/BpmnUserTask.json new file mode 100644 index 00000000..35418b23 --- /dev/null +++ b/custom/Espo/Custom/Resources/metadata/clientDefs/BpmnUserTask.json @@ -0,0 +1,44 @@ +{ + "sidePanels": { + "detail": [ + "__APPEND__", + { + "isReportPanel": true, + "name": "reportPanel697216784307d43ad", + "label": "uSERtASKSs", + "view": "advanced:views/report-panel/record/panels/report-panel-side", + "reportPanelId": "697216784307d43ad", + "reportType": "List", + "reportEntityType": "BpmnUserTask", + "displayType": "List", + "displayTotal": false, + "displayOnlyTotal": false, + "useSiMultiplier": true, + "accessDataList": [ + { + "scope": "BpmnUserTask" + }, + { + "teamIdList": [ + "68da9bdd622c9958a" + ] + } + ] + } + ] + }, + "filterList": [ + "__APPEND__", + { + "isReportFilter": true, + "name": "reportFilter6972174b6540731c1", + "accessDataList": [ + { + "teamIdList": [ + "68da9bdd622c9958a" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/custom/Espo/Custom/Resources/metadata/entityDefs/BpmnUserTask.json b/custom/Espo/Custom/Resources/metadata/entityDefs/BpmnUserTask.json new file mode 100644 index 00000000..40cc1d6a --- /dev/null +++ b/custom/Espo/Custom/Resources/metadata/entityDefs/BpmnUserTask.json @@ -0,0 +1,10 @@ +{ + "collection": { + "filters": { + "reportFilter6972174b6540731c1": { + "isReportFilter": true, + "id": "6972174b6540731c1" + } + } + } +} \ No newline at end of file diff --git a/custom/Espo/Custom/Resources/metadata/logicDefs/BpmnUserTask.json b/custom/Espo/Custom/Resources/metadata/logicDefs/BpmnUserTask.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/custom/Espo/Custom/Resources/metadata/logicDefs/BpmnUserTask.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/custom/Espo/Custom/Resources/metadata/selectDefs/BpmnUserTask.json b/custom/Espo/Custom/Resources/metadata/selectDefs/BpmnUserTask.json new file mode 100644 index 00000000..4f304c03 --- /dev/null +++ b/custom/Espo/Custom/Resources/metadata/selectDefs/BpmnUserTask.json @@ -0,0 +1,5 @@ +{ + "primaryFilterClassNameMap": { + "reportFilter6972174b6540731c1": "Espo\\Modules\\Advanced\\Classes\\Select\\Common\\PrimaryFilters\\ReportFilter" + } +} \ No newline at end of file diff --git a/data/config.php b/data/config.php index 53895c02..fe18406e 100644 --- a/data/config.php +++ b/data/config.php @@ -348,8 +348,8 @@ return [ 0 => 'youtube.com', 1 => 'google.com' ], - 'cacheTimestamp' => 1768949725, - 'microtime' => 1768949725.049459, + 'cacheTimestamp' => 1769084905, + 'microtime' => 1769084905.531304, 'siteUrl' => 'https://crm.bitbylaw.com', 'fullTextSearchMinLength' => 4, 'appTimestamp' => 1768843902,