diff --git a/docs/en/low-code/designer.md b/docs/en/low-code/designer.md index fcaf31940c..341b334494 100644 --- a/docs/en/low-code/designer.md +++ b/docs/en/low-code/designer.md @@ -65,10 +65,12 @@ Pages can define data grid, kanban, calendar, gallery, standalone form, and dash * Entity * Create and edit forms * Visible grid/card fields -* Exportable fields for Excel and CSV +* Exportable fields for Excel, CSV, and file bundles * Field labels and column widths * Default sorting * Filter fields and defaults +* Default file/image export output +* Whether file bundle ZIP export is allowed Kanban pages add `groupByProperty`, calendar pages add date/time properties, gallery pages can use an image property, form pages reference a named form, and dashboard pages define rows and visualizations. @@ -76,7 +78,9 @@ Kanban pages add `groupByProperty`, calendar pages add date/time properties, gal Pages are exposed in React under `/dynamic/` and can also appear as dynamic menu items. -The **View Fields** section has separate **Show** and **Export** choices. Use **Show** for fields that should be rendered in the runtime view. Use **Export** for fields that may be included in Excel or CSV output. A visible field can be excluded from export, and an exportable field can be hidden from the page but still available through **Export options > All exportable fields**. +The **View Fields** section has separate **Show** and **Export** choices. Use **Show** for fields that should be rendered in the runtime view. Use **Export** for fields that may be included in Excel, CSV, or file bundle output. A visible field can be excluded from export, and an exportable field can be hidden from the page but still available through **Export options > All exportable fields**. + +The **Export Settings** section controls page-level file behavior. **Default File/Image Output** selects whether spreadsheet export writes file names, metadata columns, or temporary download-link columns by default. **Allow file bundle export** controls whether the runtime can show **Files (.zip)** for this page. Disable it when files should not leave the system as a bulk download even if individual fields remain visible. ## Forms diff --git a/docs/en/low-code/index.md b/docs/en/low-code/index.md index 4a0b6f05c2..3f239388e3 100644 --- a/docs/en/low-code/index.md +++ b/docs/en/low-code/index.md @@ -22,7 +22,7 @@ Use the designer to model entities, enums, properties, relations, pages, forms, * React data grid, kanban, calendar, gallery, form, and dashboard pages * Create and edit forms * Advanced filters -* Excel and CSV export +* Excel, CSV, and file bundle export No DTO, repository, application service, controller, or React CRUD page is required for the standard flow. @@ -110,19 +110,23 @@ React low-code filters are type-aware. The runtime shows only operators that mak ## Export -Every dynamic entity page can export data to Excel or CSV. Export requests use the current search, sorting, and filters from the runtime view, so a filtered page exports the matching subset instead of the whole entity. +Every dynamic entity page can export data to Excel or CSV. Pages with file or image fields can also export a file bundle as a ZIP. Export requests use the current search, sorting, and filters from the runtime view, so a filtered page exports the matching subset instead of the whole entity. The React runtime exports visible exportable columns by default. These columns come from the page fields configured in the Low-Code Designer. A field can be visible but not exportable, or hidden but still available in the **All exportable fields** option. Use this when a page should display operational data that should not leave the system through Excel or CSV. Server-only fields are always excluded, and foreign key values are displayed through their configured display property. -File and image fields are exported as file names by default. Export options can expand those fields into metadata columns or include small files as `data:;base64,...` values. The data URL option is intended for small files only; files over the configured `LowCode:Export:MaxDataUrlFileSizeBytes` limit are skipped with a marker instead of failing the whole export. +File and image fields are exported as file names by default. Export options can expand those fields into metadata columns or temporary download-link columns. Download-link columns include file name, URL, expiry, content type, size, dimensions, and status. The links are short-lived and should be treated like signed download links, not permanent public URLs. -Export downloads require a short-lived, single-use token. The token is bound to the tenant, page, entity, child page, and foreign-access context. Spreadsheet formula-like text values are escaped before writing CSV or Excel cells. +Use **Files (.zip)** when users need the actual uploaded files. The ZIP contains `manifest.csv` and files under `files/{recordId}/{fieldName}/{safeFileName}`. The manifest records missing, malformed, unlinked, and limit-skipped files instead of failing the whole export. + +Spreadsheet and ZIP exports require a short-lived, single-use download token. The token is bound to the tenant, page, entity, child page, and foreign-access context. File download links use separate short-lived tokens bound to the exported file value. Spreadsheet formula-like text values are escaped before writing CSV or Excel headers and cells. | Endpoint | Description | |----------|-------------| | `GET /api/low-code/pages/{pageName}/download-token` | Gets a short-lived download token | | `GET /api/low-code/pages/{pageName}/export/excel` | Exports filtered data as Excel | | `GET /api/low-code/pages/{pageName}/export/csv` | Exports filtered data as CSV | +| `GET /api/low-code/pages/{pageName}/export/files` | Exports selected file/image fields as a ZIP bundle | +| `GET /api/low-code/pages/export/files/{token}` | Downloads one temporary file link created by spreadsheet export | Useful export settings: @@ -130,7 +134,9 @@ Useful export settings: |---------|---------|---------| | `LowCode:Export:MaxRows` | `100000` | Maximum rows in one all-filtered export | | `LowCode:Export:DownloadTokenLifetimeSeconds` | `30` | Download token lifetime | -| `LowCode:Export:MaxDataUrlFileSizeBytes` | `16384` | Maximum file size for data URL export | +| `LowCode:Export:FileLinkTokenLifetimeSeconds` | `900` | Temporary file link lifetime | +| `LowCode:Export:MaxFileBundleFiles` | `1000` | Maximum files in one ZIP export | +| `LowCode:Export:MaxFileBundleBytes` | `268435456` | Maximum total file bytes in one ZIP export | ## Advanced Configuration diff --git a/docs/en/low-code/model-json.md b/docs/en/low-code/model-json.md index 5c7f1b6ada..2fe241b70c 100644 --- a/docs/en/low-code/model-json.md +++ b/docs/en/low-code/model-json.md @@ -239,6 +239,8 @@ Pages create runtime routes and menu entries. They also choose how entity data i "type": "dataGrid", "entityName": "Acme.Campaigns.Campaign", "group": "marketing", + "defaultFileExportMode": 0, + "allowFileBundleExport": true, "columns": [ { "propertyName": "Name", "order": 0 }, { "propertyName": "Status", "order": 1 }, @@ -258,10 +260,19 @@ Page columns support two independent flags: | Field | Default | Purpose | |-------|---------|---------| | `visible` | `true` | Renders the field in the React page view | -| `exportable` | `true` | Allows the field to be included in Excel and CSV export | +| `exportable` | `true` | Allows the field to be included in Excel, CSV, and file bundle export | If `columns` is present, export uses this list as the page-level export policy. `exportable: false` prevents the field from being exported even if a caller sends the field name manually. Server-only entity properties are never exportable. +Page export settings: + +| Field | Default | Purpose | +|-------|---------|---------| +| `defaultFileExportMode` | `0` | Default spreadsheet output for file/image fields. `0` = file name, `1` = metadata columns, `2` = temporary download-link columns | +| `allowFileBundleExport` | `true` | Allows **Files (.zip)** export for exportable file/image columns on the page | + +ZIP file bundle export only includes selected page columns that are file or image fields and are exportable. The ZIP contains `manifest.csv` plus files under `files/{recordId}/{fieldName}/{safeFileName}`. + | Page type | Required fields | Purpose | |-----------|-----------------|---------| | `dataGrid` | `entityName` | Searchable, sortable CRUD grid | diff --git a/docs/en/low-code/react-runtime.md b/docs/en/low-code/react-runtime.md index c809c89d7d..40c7822f72 100644 --- a/docs/en/low-code/react-runtime.md +++ b/docs/en/low-code/react-runtime.md @@ -151,7 +151,7 @@ The URL keeps the existing `lcFilters` query parameter shape. The runtime maps u ## Export -The runtime export button opens a small menu with direct Excel and CSV actions. Direct export uses the current search, sorting, filters, and visible exportable columns from the page definition maintained in the Low-Code Designer. Use **Export options** when users need a different row or column scope. +The runtime export button opens a small menu with direct Excel and CSV actions. If the selected page has exportable file or image fields, the menu also shows **Files (.zip)**. Direct export uses the current search, sorting, filters, and visible exportable columns from the page definition maintained in the Low-Code Designer. Use **Export options** when users need a different row, column, or file output scope. Available options: @@ -163,15 +163,19 @@ Available options: | Columns: all exportable fields | Exports page fields marked exportable in the Low-Code Designer, including fields that are hidden from the grid | | File/image: file name | Writes the uploaded file name, or an empty value | | File/image: metadata columns | Writes file name, content type, size, width, and height columns | -| File/image: data URL | Writes small linked files as `data:;base64,...`; large or unavailable files are written as markers | +| File/image: download links | Writes file name, temporary download URL, link expiry, content type, size, width, height, and status columns | -The runtime first requests a short-lived token and then calls the Excel or CSV export endpoint. The token is single-use and is bound to the current page, entity, tenant, child page, and foreign-access context. Text that looks like a spreadsheet formula is escaped in exported headers and cells. If a caller manually sends a non-exportable field name, the backend rejects the request. +Spreadsheet export stays tabular. It does not embed file bytes in cells. Use download-link columns when spreadsheet readers need a controlled way to fetch individual files, or use **Files (.zip)** when they need the actual file set. ZIP export contains `manifest.csv` and files under `files/{recordId}/{fieldName}/{safeFileName}`. The manifest reports missing, malformed, unlinked, skipped, and exported files. + +The runtime first requests a short-lived token and then calls the Excel, CSV, or ZIP export endpoint. The export token is single-use and is bound to the current page, entity, tenant, child page, and foreign-access context. Temporary file links use separate short-lived tokens bound to the exported record field and blob. Text that looks like a spreadsheet formula is escaped in exported headers and cells. If a caller manually sends a non-exportable field name, the backend rejects the request. | Endpoint | Description | |----------|-------------| | `GET /api/low-code/pages/{pageName}/download-token` | Gets a short-lived token | | `GET /api/low-code/pages/{pageName}/export/excel` | Downloads Excel | | `GET /api/low-code/pages/{pageName}/export/csv` | Downloads CSV | +| `GET /api/low-code/pages/{pageName}/export/files` | Downloads a ZIP with selected file/image fields | +| `GET /api/low-code/pages/export/files/{token}` | Downloads one temporary file link from spreadsheet link mode | Child and foreign-access pages use the matching `/children/{childEntityName}` and `/foreign-access/{sourceEntityName}` page endpoints. @@ -181,7 +185,9 @@ Troubleshooting: |---------|--------------| | Invalid or expired download token | The token is single-use, expired, or was requested for a different page/context | | Export row limit exceeded | Narrow the filters, export the current page, or increase `LowCode:Export:MaxRows` | -| File not exported marker | The file was missing, too large for data URL export, malformed, or no longer linked to the exported record | +| File link expired | Re-run export; temporary file links are intentionally short-lived | +| File not exported marker | The file was missing, malformed, no longer linked to the exported record, or skipped by ZIP file count/size limits | +| ZIP bundle export disabled | Enable file bundle export for the page in the Low-Code Designer | ## Files and Attachments