Factorizer/Cluster ERP WikiCluster ERP Türkçe
Home / Web app

Reference

Record documents, viewer, and share

Reference for record-docs.js, viewer.js with the vendored PDF renderer, and share.js, which attach documents to any record, open files in the app, and share records.

Three shared features work on every record card of the web app: a Documents row (docs.section) that attaches files to the record, an in-app viewer that opens files instead of downloading them, and a share sheet. This page lists the calls each feature makes and the rules it follows. The documents module itself is on documents module.

Scope and source

  • Defined in: webapp/js/record-docs.js (recordDocsRow, makeRecordDocsScreen, makeAddDocView, createDocsCollector), webapp/js/viewer.js (openViewer, openViewerFromPath, registerRenderer, triggerDownload), webapp/js/vendor/pdfjs/, webapp/js/share.js (openShareSheet, buildRecordShare, buildRecordsShare)
  • Count: 2 viewer renderers (registerRenderer calls in webapp/js/viewer.js:151 and webapp/js/viewer.js:381); 3 share targets (webapp/js/share.js:84-86)

Record documents

Provider lookup

The documents feature never names the documents module. docsProvider() asks providerOf('record_documents') for the module that declares the capability in ModuleMeta.provides, and builds the list and type paths from that module's entity metadata (webapp/js/record-docs.js:23-37). Permission codes are <entity_type>.read, .create, and .delete of the provider's entity (webapp/js/record-docs.js:40). tests/test_metadata_driven_rules.py:63 checks that the provider is declared by capability.

Calls

Step Call Source
Show the row with a count GET <documents list>?entity_type=<type>&entity_id=<id>&limit=1 webapp/js/record-docs.js:294-326
List a record's documents GET <documents list>?entity_type=<type>&entity_id=<id>&limit=200 webapp/js/record-docs.js:58-63
Load document types GET <types list>?active_only=true webapp/js/record-docs.js:106, webapp/js/record-docs.js:207
Add a document POST <documents list>, then POST /attachments/ with the file, then POST <documents list><doc_id>/versions webapp/js/record-docs.js:103-194
Open or download GET <documents list><doc_id>/versions, then GET /attachments/<attachment_id>/download of the active version, else the newest webapp/js/record-docs.js:65-78
Remove DELETE <documents list><doc_id> after a confirm webapp/js/record-docs.js:262-280

The row appears on a record card unless the entity sets record_documents to false (webapp/js/gen-form.js:2477-2483), and only when a provider exists and the user holds its read permission (webapp/js/record-docs.js:294-296). An entity with create_with_documents collects documents on its create form through createDocsCollector and attaches them after the record exists (webapp/js/record-docs.js:328-457, webapp/js/gen-form.js:1914-1920). Attachments are stored by the platform; see attachments, notes, and storage.

Document viewer

openViewer({title, blob, contentType, filename}) pushes a viewer screen and picks a renderer by content type and file extension. Later registered renderers win ties (webapp/js/viewer.js:14-28, webapp/js/viewer.js:89-125).

Renderer Matches Features Source
pdf application/pdf or .pdf Pages rendered to canvas, page indicator and navigation, zoom, download webapp/js/viewer.js:151-380
image image/* or .png, .jpg, .jpeg, .gif, .webp, .svg Image display and download webapp/js/viewer.js:381-456

A file without a matching renderer shows viewer.unsupported with a download button; a renderer failure shows viewer.error with the same button (webapp/js/viewer.js:98-123). openViewerFromPath fetches a path as an authenticated blob first (webapp/js/viewer.js:127-133). A metadata action with a GET endpoint opens its result in the viewer; see actions and action sheet.

The PDF library is imported only when a PDF is opened. Its worker runs from webapp/js/vendor/pdfjs/pdf.worker.min.mjs (webapp/js/viewer.js:134-149). The vendored build is pdfjs-dist 6.2.108 under the Apache-2.0 licence (webapp/js/vendor/pdfjs/README.txt).

Share sheet

openShareSheet(ctx) raises a bottom sheet with a summary of one or more records and three targets (webapp/js/share.js:80-140).

Target Label key State Effect Source
Mail share.mail live Dispatches cluster:share-via-mail with a subject and body webapp/js/share.js:84, webapp/js/share.js:124-131
Message share.message not live Shows Coming soon (common.coming_soon) webapp/js/share.js:85, webapp/js/share.js:132-134
Print share.print not live Shows Coming soon webapp/js/share.js:86, webapp/js/share.js:132-134

buildRecordShare makes the subject <entity label>: <record title> and a body of up to 14 Label: value lines from simple form fields. buildRecordsShare lists several records with up to 6 lines each (webapp/js/share.js:15-57). Identifiers, files, and relations are left out because only simple field types are read (webapp/js/share.js:15-33). The home screen handles cluster:share-via-mail by queuing a prefilled draft and opening the Mail app (webapp/js/home.js:4658-4665).

Share is offered from a record card's navigation bar and from a list's selection bar (webapp/js/gen-form.js:2330-2333, webapp/js/gen-list.js:641-643).

Constraints and validation

  • A document without a file version shows docs.no_file instead of opening (webapp/js/record-docs.js:69-73).
  • Object URLs created for blobs are revoked after use (webapp/js/viewer.js:37-47, webapp/js/avatar.js:37-38).
  • Browser tests: web-client/_e2e_record_docs.mjs, web-client/_e2e_doc_viewer.mjs, web-client/_e2e_doc_version.mjs, web-client/_e2e_intranet_mydocs.mjs.

Terms introduced

Term Code identifier Definition Turkish term Source
record documents record_documents Files attached to any record through the documents provider. Belgeler webapp/js/record-docs.js:26
document viewer openViewer The in-app screen that renders a file by its type. belge görüntüleyici webapp/js/viewer.js:89
share sheet openShareSheet The bottom sheet that sends a record summary to a target. paylaşım kartı webapp/js/share.js:80

Verified against commit 92f8051 on 2026-11-13.

Verified against commit 92f8051 · 2026-11-13