Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .github/packages.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,41 @@
"syntax": "v751",
"note": "The HTTP transport comes once per stack, and each half activates on its own stack only: src/10/01 (cl_http_client on an SM59 destination) on Standard, src/10/02 (cl_web_http_client_manager on a BTP destination) on ABAP Cloud, src/10/03 only where SAP's ABAP AI SDK is installed. An activation error for the half your system does not have is expected - the samples create the transport by name and use the one that is there. That is also why this branch is linted at 7.51 although the package runs from 7.40 SP08: everything but src/10/02 parses at 7.40 SP08, and src/10/02 is ABAP Cloud code whose released enums need 7.51 syntax.",
"shared": []
},
{
"dir": "11",
"branch": "11-rap-file-upload",
"title": "RAP File Upload",
"runsOn": "Cloud + Standard ≥ 8.16 (2025)",
"syntax": "v757",
"note": "A deep action parameter whose abstract entity carries @Semantics.largeObject is younger than EML: the ABAP parses at 7.57, the feature itself arrived with ABAP Platform 2025 (and the matching BTP ABAP Environment and S/4HANA Cloud releases). If the static action uploadFile does not activate on your system, this package is out of reach.",
"shared": ["00"]
},
{
"dir": "12",
"branch": "12-rap-actions",
"title": "RAP Actions & Permissions",
"runsOn": "Cloud + Standard ≥ 8.16 (2025)",
"syntax": "v757",
"note": "The package is set to the release that carries all of its features. Instance feature control, actions with parameters and factory actions are older; the default function GetDefaultsForCreate and cl_abap_behv_aux are the young ones. GET PERMISSIONS sits in z2ui5_cl_smps_perm_req, which abaplint cannot parse and therefore does not check.",
"shared": ["00"]
},
{
"dir": "13",
"branch": "13-excel-email",
"title": "Excel & E-Mail",
"runsOn": "Cloud + Standard ≥ 7.58 (2023)",
"syntax": "v757",
"note": "The XCO XLSX library and cl_bcs_mail_message are released ABAP Cloud APIs; on-premise the package needs a release that carries both. The mail sample also needs outbound mail configured.",
"shared": []
},
{
"dir": "14",
"branch": "14-adobe-forms",
"title": "Adobe Forms",
"runsOn": "Standard only, ≥ 7.50",
"syntax": "v750",
"note": "Renders through the classic Adobe Forms runtime (FP_JOB_OPEN, the generated function module, FP_JOB_CLOSE), which is not released for ABAP Cloud. Needs Adobe Document Services configured.",
"shared": []
}
]
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ is a link to the class file, which is the qualification.

## 3. The generated one-package branches

abapGit imports a whole repository; there is no sparse checkout. Ten packages
abapGit imports a whole repository; there is no sparse checkout. Fourteen packages
with different floors would mean a system that wants OData also takes APC and
gets activation errors for technology it never asked for. So every package is
force-pushed to its own branch by `create-package-branches.yaml`, and the
Expand Down Expand Up @@ -409,7 +409,7 @@ pass over the classes on `main` — `stats.types` and the `*-too-new` findings.
- **The overview app stays out of the catalogue page** for the reason it was
always out: `Z2UI5_CL_SMPS_APP_000` is this same catalogue inside a system,
and as a card it contradicts a list built around what a sample needs — *needs
nothing beyond abap2UI5* — plus a technology chip that filters ten groups
nothing beyond abap2UI5* — plus a technology chip that filters fourteen groups
down to itself. `SAMPLES.md` and both JSON files keep it; their reader is in
the repository already.
- **Thumbnails** were photographed on every deploy by
Expand Down
29 changes: 20 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ The Claude Code plugin is two commands:

## Which package do I need?

Most readers need exactly one. The ten areas are unrelated technologies, none
Most readers need exactly one. The fourteen areas are unrelated technologies, none
depends on another — so find the row that says what you came to do, take that
package, and skip the rest:

Expand All @@ -80,6 +80,10 @@ package, and skip the rest:
| Play or serve a file the MIME repository already holds | [`src/08`](src/08/README.md) — MIME Play Audio | on-premise; activate one ICF service in `SICF` |
| Expose your app in the Fiori Launchpad — tile, startup parameters, cross-app navigation | [`src/09`](src/09/README.md) — Launchpad | a launchpad with a tile pointing at abap2UI5 |
| Call a large language model from your app — a chat, or a table summarized by AI | [`src/10`](src/10/README.md) — AI / LLM | an HTTPS destination to an LLM endpoint (SM59 or BTP), or SAP's ABAP AI SDK |
| Upload a file into a RAP business object through an action with a deep parameter | [`src/11`](src/11/README.md) — RAP File Upload | ≥ 2025, the release that carries deep action parameters with `@Semantics.largeObject`; the business object ships with the package |
| Ask a business object what is allowed, call actions with parameters, factory actions and default values, validate while the user types | [`src/12`](src/12/README.md) — RAP Actions & Permissions | ≥ 2025; the business object ships with the package |
| Read an uploaded Excel file, export a table as Excel, send it as a mail attachment | [`src/13`](src/13/README.md) — Excel & E-Mail | ≥ 2023 or ABAP Cloud; outbound mail configured for the mail sample |
| Render Adobe Forms to PDF and download one or several as a ZIP | [`src/14`](src/14/README.md) — Adobe Forms | on-premise; Adobe Document Services configured |

Each package README opens with a **What you need** section that turns the last
column into concrete steps; the table below adds the exact release floors.
Expand All @@ -98,6 +102,10 @@ column into concrete steps; the table below adds the exact release floors.
| [`src/08`](src/08) | **[MIME Play Audio](src/08/README.md)** — play a sound from the MIME repository | the ICF service `/SAP/PUBLIC/BC/ABAP/mime_demo` | Standard only, ≥ 7.50 |
| [`src/09`](src/09) | **[Launchpad](src/09/README.md)** — startup parameters, shell title, cross-app navigation | a Fiori Launchpad with a tile pointing at abap2UI5 | Cloud + Standard ≥ 7.40 SP08 |
| [`src/10`](src/10) | **[AI / LLM](src/10/README.md)** — chat with a language model, summarize a table with AI | an HTTPS destination to an LLM endpoint (SM59 or BTP), or SAP's ABAP AI SDK | Cloud + Standard ≥ 7.40 SP08 |
| [`src/11`](src/11) | **[RAP File Upload](src/11/README.md)** — a file into a business object, as a deep action parameter | ABAP Platform >= 2025; the BO ships with this repo | Cloud + Standard ≥ 8.16 (2025) |
| [`src/12`](src/12) | **[RAP Actions & Permissions](src/12/README.md)** — feature control, parameters, factory actions, defaults, projections | ABAP Platform >= 2025; the BO ships with this repo | Cloud + Standard ≥ 8.16 (2025) |
| [`src/13`](src/13) | **[Excel & E-Mail](src/13/README.md)** — read and write .xlsx with XCO, send it by mail | the XCO XLSX library; outbound mail for the mail sample | Cloud + Standard ≥ 7.58 (2023) |
| [`src/14`](src/14) | **[Adobe Forms](src/14/README.md)** — render forms to PDF, one file or a ZIP | Adobe Document Services (ADS) | Standard only, ≥ 7.50 |

The numbering is a reading order, not a dependency chain: `01` starts where
most systems already are — an activated OData service — and each package from
Expand All @@ -122,8 +130,9 @@ earlier:
development tenant. Three packages cannot go there, and it is the technology, not
the sample, that keeps them out: `06` locks through the function modules
`ENQUEUE_E_TABLE` / `ENQUEUE_READ` and holds a stateful ICF session, `07` needs
on-premise APC/AMC, `08` reads the MIME repository over an ICF path. None of those
is a released ABAP Cloud API.
on-premise APC/AMC, `08` reads the MIME repository over an ICF path, `14` renders
Adobe Forms through the classic `FP_JOB_OPEN` runtime. None of those is a released
ABAP Cloud API.

**Standard** is the on-premise release, given as the `SAP_BASIS` version with the
ABAP Platform name where there is one — `7.54` is 1909, `7.56` is 2021. The number
Expand All @@ -135,9 +144,11 @@ is the higher of two floors:
tree, and the number in the table is the lowest release the package parses clean
at.
- *the technology the package plays with.* EML lifts `03` and `04` to 1909, RAP
business events lift `05` to 2021. If `RAISE ENTITY EVENT` does not activate on
your system, `05` is out of reach and nothing else in this repository is
affected.
business events lift `05` to 2021, a deep action parameter carrying a file
lifts `11` to 2025, default functions and the RAP context class lift `12` to
2025, the XCO XLSX library and the ABAP Cloud mail API lift `13` to 2023. If one
of them does not activate on your system, that package is out of reach and
nothing else in this repository is affected.
- *the HTTP client of the stack.* `10` calls a language model over HTTPS, and
the two stacks release different clients for that — `cl_http_client` on an
SM59 destination on Standard, `cl_web_http_client_manager` on ABAP Cloud. So
Expand All @@ -151,7 +162,7 @@ of them.
## Setup

1. Install [abap2UI5](https://github.com/abap2UI5/abap2UI5).
2. Pull this repository with [abapGit](https://abapgit.org) — `main` for all ten
2. Pull this repository with [abapGit](https://abapgit.org) — `main` for all fourteen
packages, or the branch of the single package you came for (see
[One package at a time](#one-package-at-a-time)). `main` as a whole runs on
ABAP Platform >= 1909 or a BTP ABAP Environment — that is what EML asks for,
Expand Down Expand Up @@ -185,7 +196,7 @@ It is also the honest answer to *what does my system actually support*: the
overview looks every sample up at runtime instead of referencing it statically, so
a package your release cannot activate — or one you never installed — is listed
with its Open button disabled and a Status saying so, rather than taking the whole
overview down. Start it first, and the list tells you which of the ten packages
overview down. Start it first, and the list tells you which of the fourteen packages
this system can run.

## One package at a time
Expand Down Expand Up @@ -286,7 +297,7 @@ in CI. The node checks carry no dependencies, so they take seconds.
| `check-framework-pin` | the abaplint config pins abap2UI5 to a release tag, never to whatever is on `main` |
| `check-released-api` | every package whose *Runs on* says Cloud, linted at Cloud against the released objects — an API ABAP Cloud does not release is an error |
| `check-catalogue` | [`catalogue.json`](catalogue.json) and `catalogue-derived.json` still are what the generators would write — the same catalogue as data, committed for tooling that fetches one file instead of scanning the tree — and with them every package has a README row that parses, every app sits in a package, and none is missing its `@summary` or `@keywords` |
| `create-package-branches` | rebuilds the ten per-package branches, each verified with abaplint at its own release before it is pushed |
| `create-package-branches` | rebuilds the fourteen per-package branches, each verified with abaplint at its own release before it is pushed |

`check-overview` exists because the overview app names its samples as strings and
resolves them at runtime — that is what lets it survive a package the system cannot
Expand Down
39 changes: 37 additions & 2 deletions SAMPLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

# The sample catalogue

Every app in this repository — 35 of them — with what it shows and a
Every app in this repository — 45 of them — with what it shows and a
link to its source. This is the [overview app](src/z2ui5_cl_smps_app_000.clas.abap)
as a page you can read here, before installing anything.

Expand Down Expand Up @@ -103,6 +103,7 @@ type who does not know it exists. `Ctrl+F` on this page uses them.

| Sample | Class |
|---|---|
| Build the URL of a Launchpad App<br>Builds the URL of a launchpad app from semantic object, action and parameters - through cl_lsapi_manager where the system has it, as an intent URL of its own where it does not<br><sub>launchpad fiori flp url intent semantic object action link cl_lsapi_manager open_new_tab</sub> | [`Z2UI5_CL_SMPS_APP_025`](src/09/z2ui5_cl_smps_app_025.clas.abap) |
| Read Startup Parameters<br>what the tile passed in - client->get( )-t_comp_params<br><sub>launchpad fiori flp startup parameters intent</sub> | [`Z2UI5_CL_SMPS_APP_481`](src/09/z2ui5_cl_smps_app_481.clas.abap) |
| Set Shell Title<br>follow_up_action( cs_event-set_title_launchpad )<br><sub>launchpad fiori flp shell title follow_up_action</sub> | [`Z2UI5_CL_SMPS_APP_482`](src/09/z2ui5_cl_smps_app_482.clas.abap) |
| Cross-App Navigation Sender<br>hands two values over to another tile<br><sub>launchpad fiori flp cross app navigation sender intent</sub> | [`Z2UI5_CL_SMPS_APP_483`](src/09/z2ui5_cl_smps_app_483.clas.abap) |
Expand All @@ -116,11 +117,40 @@ type who does not know it exists. `Ctrl+F` on this page uses them.
| Chat with a Language Model<br>a chat with a real language model over HTTPS - the conversation goes out, the answer comes back, the provider is configuration<br><sub>ai llm chat chatbot feedinput feedlistitem anthropic openai</sub> | [`Z2UI5_CL_SMPS_APP_014`](src/10/z2ui5_cl_smps_app_014.clas.abap) |
| Summarize a Table with AI<br>a table of sales figures and one button - the rows go to a language model as context, its summary comes back into a panel<br><sub>ai llm chat summarize table prompt hygiene anthropic</sub> | [`Z2UI5_CL_SMPS_APP_015`](src/10/z2ui5_cl_smps_app_015.clas.abap) |

### RAP File Upload — `src/11`

| Sample | Class |
|---|---|
| Deep Action Parameter<br>EXECUTE uploadFile with a deep parameter - the file travels as a stream property, download and delete included<br><sub>file upload attachment rap action deep parameter largeobject stream eml fileuploader download</sub> | [`Z2UI5_CL_SMPS_APP_016`](src/11/z2ui5_cl_smps_app_016.clas.abap) |

### RAP Actions and Permissions — `src/12`

| Sample | Class |
|---|---|
| **RAP Actions** — Feature Control with GET PERMISSIONS<br>GET PERMISSIONS asks the business object what may happen to each request - the buttons follow its answer, and the business object refuses the rest anyway<br><sub>rap eml feature control instance features get permissions enabled disabled buttons</sub> | [`Z2UI5_CL_SMPS_APP_017`](src/12/z2ui5_cl_smps_app_017.clas.abap) |
| **RAP Actions** — Parameters, Factory Actions, Defaults<br>Actions with a parameter - a default function proposes a new request, a static factory action creates it, a factory action copies one, and reject asks for its reason in a popup<br><sub>rap eml action parameter abstract entity factory action default function popup create copy reject</sub> | [`Z2UI5_CL_SMPS_APP_018`](src/12/z2ui5_cl_smps_app_018.clas.abap) |
| **RAP Actions** — Validate on Change with a Determine Action<br>A determine action runs the validation of the business object while the user types - the quantity is checked on every change, and nothing is saved until Save<br><sub>rap eml determine action validation check on change valuestate messages without saving</sub> | [`Z2UI5_CL_SMPS_APP_019`](src/12/z2ui5_cl_smps_app_019.clas.abap) |
| **RAP Actions** — One Business Object, Two Contracts<br>One business object, two contracts - approve through the projection Z2UI5_C_SMPS_REQ or on the business object itself, and the handler records which one it was<br><sub>rap eml projection behavior definition contract cl_abap_behv_aux interface consumer approve</sub> | [`Z2UI5_CL_SMPS_APP_020`](src/12/z2ui5_cl_smps_app_020.clas.abap) |

### Excel and E-Mail — `src/13`

| Sample | Class |
|---|---|
| **Excel** — Read an Uploaded XLSX File with XCO<br>An .xlsx file from the FileUploader read with the XCO XLSX library - the first worksheet becomes an ABAP table and is shown as it arrived<br><sub>excel xlsx upload import read spreadsheet xco fileuploader table</sub> | [`Z2UI5_CL_SMPS_APP_021`](src/13/z2ui5_cl_smps_app_021.clas.abap) |
| **Excel** — Export a Table as XLSX File with XCO<br>The table on the screen written into an .xlsx file with the XCO XLSX library and handed to the browser as a download - a header row, then one row per line<br><sub>excel xlsx export download write spreadsheet xco table download_b64_file</sub> | [`Z2UI5_CL_SMPS_APP_022`](src/13/z2ui5_cl_smps_app_022.clas.abap) |
| **E-Mail** — Send a Table as XLSX Attachment<br>A mail with an .xlsx attachment, sent with cl_bcs_mail_message - recipient, subject and text from the screen, the attachment written with the XCO XLSX library<br><sub>email mail send attachment xlsx excel cl_bcs_mail_message smtp</sub> | [`Z2UI5_CL_SMPS_APP_023`](src/13/z2ui5_cl_smps_app_023.clas.abap) |

### Adobe Forms — `src/14`

| Sample | Class |
|---|---|
| Render to PDF, Download One or a ZIP<br>Renders Adobe Forms of the system to PDF with FP_JOB_OPEN and the generated function module - one form as a PDF download, several at once as one ZIP file<br><sub>adobe forms pdf ads fp_job_open print form output zip download cl_abap_zip</sub> | [`Z2UI5_CL_SMPS_APP_024`](src/14/z2ui5_cl_smps_app_024.clas.abap) |

---

## Not samples

16 classes here are not apps and carry no tile: behavior pools,
21 classes here are not apps and carry no tile: behavior pools,
demo data, an event consumer, the generated APC protocol class and the
language-model layer the AI samples call. They are
reached **by** a sample rather than looked up, which is why they are exempt from
Expand All @@ -145,3 +175,8 @@ able to say they exist.
| [`Z2UI5_CL_SMPS_LLM_SM59`](src/10/01/z2ui5_cl_smps_llm_sm59.clas.abap) | LLM - HTTP Transport over an SM59 Destination |
| [`Z2UI5_CL_SMPS_LLM_CLOUD`](src/10/02/z2ui5_cl_smps_llm_cloud.clas.abap) | LLM - HTTP Transport for ABAP Cloud |
| [`Z2UI5_CL_SMPS_LLM_ISLM`](src/10/03/z2ui5_cl_smps_llm_islm.clas.abap) | LLM - SAP ABAP AI SDK (ISLM) |
| [`Z2UI5_CL_SMPS_BP_FIL`](src/11/01/z2ui5_cl_smps_bp_fil.clas.abap) | abap2UI5 RAP sample - file behavior pool |
| [`Z2UI5_CL_SMPS_BP_REQ`](src/12/01/z2ui5_cl_smps_bp_req.clas.abap) | abap2UI5 RAP sample - request behavior pool |
| [`Z2UI5_CL_SMPS_DATA_REQ`](src/12/01/z2ui5_cl_smps_data_req.clas.abap) | abap2UI5 RAP sample - request demo data |
| [`Z2UI5_CL_SMPS_PERM_REQ`](src/12/01/z2ui5_cl_smps_perm_req.clas.abap) | abap2UI5 RAP sample - request permissions |
| [`Z2UI5_CL_SMPS_XLSX`](src/13/z2ui5_cl_smps_xlsx.clas.abap) | abap2UI5 sample - Excel read and write with XCO |
9 changes: 8 additions & 1 deletion abaplint.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,16 @@
// ABAP: the class .clas.xml is not listed, so object_naming and
// xml_consistency still cover the object. Drop this once abaplint parses
// the RAP event syntax.
//
// z2ui5_cl_smps_perm_req is the same case for the EML statement GET
// PERMISSIONS, which abaplint does not parse at any language version. It
// holds that one statement and nothing else, so the sample app calling
// it, z2ui5_cl_smps_app_017, stays fully checked. Drop it once abaplint
// parses GET PERMISSIONS.
"noIssues": [
"z2ui5_cl_smps_evt_tck\\.clas\\.abap$",
"z2ui5_cl_smps_evt_tck\\.clas\\.locals_imp\\.abap$"
"z2ui5_cl_smps_evt_tck\\.clas\\.locals_imp\\.abap$",
"z2ui5_cl_smps_perm_req\\.clas\\.abap$"
]
},
"dependencies": [
Expand Down
Loading
Loading