makeGenDetail in webapp/js/gen-detail.js renders a record from EntityMeta.detail_view. The web app shows a detail view as one scrolling page: the form tabs merge into one record card, every other tab becomes a row that opens its own screen, and role facets and linked records follow. This page lists the tab types, the facet rules, and the helpers in entity.js and avatar.js. The record card itself is described on generic form.
Scope and source¶
- Defined in:
webapp/js/gen-detail.js(makeGenDetail),webapp/js/entity.js(makeEntityList,adminSections),webapp/js/avatar.js(recordAvatarBlock,createAvatarPicker,loadPhotoInto) - Count: 9 tab types in
DetailTabMeta.tab_type(src/cluster_erp/core/metadata.py:255-270), all 9 handled byrenderSectionor the form card (webapp/js/gen-detail.js:345-366)
Page structure¶
makeGenDetail(moduleName, entityKey, entityId) loads the record with GenApi.get and paints (webapp/js/gen-detail.js:33-58):
- Tabs whose
conditiondoes not match the loaded record are dropped. The condition uses the same rule as form groups: a pipe-separated set, inverted bynegate(webapp/js/gen-detail.js:66-78). - Every
formtab without anentitycontributes itsfield_groupsto one record card. A form tab with no groups means all groups (webapp/js/gen-detail.js:80-101). - Every other tab becomes a chevron row. A tap pushes a screen rendered by
renderSection(webapp/js/gen-detail.js:103-127). - Role facets are loaded and appended (
webapp/js/gen-detail.js:129-132). - A record that carries
entity_typeandentity_idshows a Linked record row (gen.linked_record) that opens the owner record. A deactivated owner shows a notice instead (webapp/js/gen-detail.js:134-179).
After a save on the card, the whole page is repainted with the updated record, so facets and section rows do not keep old data (webapp/js/gen-detail.js:840-875).
Tab types¶
tab_type |
Rendered as | Source |
|---|---|---|
form (no entity) |
Part of the merged record card | webapp/js/gen-detail.js:79-101 |
form with entity, or sub_entity_table |
A child list (renderSubTable) |
webapp/js/gen-detail.js:348, webapp/js/gen-detail.js:876-895 |
sub_entity_tree |
A child tree loaded with limit: 500 |
webapp/js/gen-detail.js:350, webapp/js/gen-detail.js:1277-1297 |
completeness |
The requirement list from completeness_endpoint |
webapp/js/gen-detail.js:351-353, webapp/js/gen-detail.js:398-439 |
custom |
The widget named by custom_widget (default: the tab key) from the owner module's bundle |
webapp/js/gen-detail.js:353-355, webapp/js/gen-detail.js:368-396 |
read_model_panel |
A panel whose data endpoints, columns, and blocks come from the tab's config |
webapp/js/gen-detail.js:355-357, webapp/js/gen-detail.js:441-460 |
permission_checklist |
The permission grants of a role | webapp/js/gen-detail.js:357-359, webapp/js/gen-detail.js:619-708 |
role_checklist |
The role assignments of a user | webapp/js/gen-detail.js:359-361, webapp/js/gen-detail.js:710-775 |
access_summary |
The effective permissions of a user | webapp/js/gen-detail.js:361-363, webapp/js/gen-detail.js:777-838 |
A cross-module child tab (entity_module with parent_id_field) takes its parent id from the loaded record. A tab with scope_param filters the child list by the record id; read_only hides add and edit (webapp/js/gen-detail.js:876-895). A custom tab whose owner app is not installed or not licensed shows error.entitlement.module_not_installed (webapp/js/gen-detail.js:375-391). See gated app bundles.
Role facets¶
A party card shows the roles the party plays (EntityMeta.facets, FacetMeta). renderFacets loads each facet's rows by party id and adds them as chevron rows in a wrapper that edit mode hides (webapp/js/gen-detail.js:181-229). Rules in loadFacetRows (webapp/js/gen-detail.js:231-340):
| Facet field | Effect |
|---|---|
requires_flag |
The facet is hidden unless the party record has that flag set |
sections[].party_scoped |
The section renders as one list row for the party, up to 200 records |
sections[].scope_param |
The section's list is filtered by the facet record and is read-only |
The facet model is explained on party unification. A list row of a facet entity with identity opens the canonical party card instead of the facet's own card (webapp/js/gen-list.js:816-825).
Entity browser and admin sections¶
makeEntityList(moduleName, entityKey, pushView) in entity.js is a second list-and-detail browser used by the Settings app for administration screens and notification rules (webapp/js/entity.js:93, webapp/js/home.js:3486, webapp/js/home.js:3503-3510). adminSections(moduleName, excludeEntities) builds the admin rows from the module's sidebar: list sections and the entities of settings tabs (webapp/js/entity.js:364-387).
Photo and avatar¶
An entity that declares photo (AvatarMeta) gets an avatar on its card and in lists.
| Function | Behaviour | Source |
|---|---|---|
photoPath |
Builds /<module><photo.endpoint>, default endpoint /{id}/photo |
webapp/js/avatar.js:27-30 |
loadPhotoInto |
Fetches the photo as a blob and shows it through an object URL | webapp/js/avatar.js:34-53 |
recordAvatarBlock |
The card header with initials or photo; upload and removal when the user holds <entity_type>.update |
webapp/js/avatar.js:55-157 |
createAvatarPicker |
A photo picker on the create form; the file is uploaded after creation | webapp/js/avatar.js:159 |
Initials use a colour chosen from a fixed list by a hash of the title (webapp/js/avatar.js:13-19). Lists load photos only for rows that become visible (webapp/js/gen-list.js:744-780). The server side of attachments and photos is on attachments, notes, and storage.
Constraints and validation¶
- Deleting from a sub-list asks for a deactivation reason (
webapp/js/gen-detail.js:1184-1185,webapp/js/gen-detail.js:1394-1395). See soft delete and deactivation. - A missing entity in metadata shows No results found (
common.no_results) instead of an error (webapp/js/gen-detail.js:40-44). - Browser tests:
web-client/_e2e_settings_full.mjs,web-client/_e2e_party_form_fixes.mjs,web-client/_e2e_logs_profile.mjs.
Terms introduced¶
| Term | Code identifier | Definition | Turkish term | Source |
|---|---|---|---|---|
| section row | renderSection |
A row on the detail page that opens a non-form tab as its own screen. | bölüm satırı | webapp/js/gen-detail.js:345 |
| linked record | renderLinkedRecord |
The row that opens the record a polymorphic reference points at. | İlişkili kayıt | webapp/js/gen-detail.js:140 |
| read-model panel | renderReadModelPanel |
A detail tab whose data endpoints and layout come entirely from its config. |
okuma modeli paneli | webapp/js/gen-detail.js:447 |
Related pages¶
Verified against commit 92f8051 on 2026-11-13.