@open-rap/compiler 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +21 -2
- package/dist/agent/server.d.ts +35 -0
- package/dist/agent/server.js +408 -0
- package/dist/agent/server.js.map +1 -0
- package/dist/authoring/abapgit.d.ts +38 -0
- package/dist/authoring/abapgit.js +242 -0
- package/dist/authoring/abapgit.js.map +1 -0
- package/dist/authoring/catalog.d.ts +48 -0
- package/dist/authoring/catalog.js +117 -0
- package/dist/authoring/catalog.js.map +1 -0
- package/dist/authoring/floorplan.d.ts +28 -0
- package/dist/authoring/floorplan.js +31 -0
- package/dist/authoring/floorplan.js.map +1 -0
- package/dist/authoring/generate.d.ts +57 -0
- package/dist/authoring/generate.js +630 -0
- package/dist/authoring/generate.js.map +1 -0
- package/dist/authoring/mcp.d.ts +15 -0
- package/dist/authoring/mcp.js +52 -0
- package/dist/authoring/mcp.js.map +1 -0
- package/dist/authoring/new.d.ts +35 -0
- package/dist/authoring/new.js +389 -0
- package/dist/authoring/new.js.map +1 -0
- package/dist/bdef/ast.d.ts +249 -0
- package/dist/bdef/ast.js +3 -0
- package/dist/bdef/ast.js.map +1 -0
- package/dist/bdef/lexer.d.ts +105 -0
- package/dist/bdef/lexer.js +148 -0
- package/dist/bdef/lexer.js.map +1 -0
- package/dist/bdef/parser.d.ts +22 -0
- package/dist/bdef/parser.js +1012 -0
- package/dist/bdef/parser.js.map +1 -0
- package/dist/build.d.ts +26 -0
- package/dist/build.js +62 -0
- package/dist/build.js.map +1 -0
- package/dist/cds/adapter.d.ts +91 -0
- package/dist/cds/adapter.js +381 -0
- package/dist/cds/adapter.js.map +1 -0
- package/dist/cds/expression-ast.d.ts +65 -0
- package/dist/cds/expression-ast.js +330 -0
- package/dist/cds/expression-ast.js.map +1 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.js +485 -0
- package/dist/cli.js.map +1 -0
- package/dist/dcl/parser.d.ts +59 -0
- package/dist/dcl/parser.js +338 -0
- package/dist/dcl/parser.js.map +1 -0
- package/dist/ddic/catalog.d.ts +17 -0
- package/dist/ddic/catalog.js +211 -0
- package/dist/ddic/catalog.js.map +1 -0
- package/dist/ddic/cds-types.d.ts +47 -0
- package/dist/ddic/cds-types.js +131 -0
- package/dist/ddic/cds-types.js.map +1 -0
- package/dist/ddic/table-source.d.ts +70 -0
- package/dist/ddic/table-source.js +500 -0
- package/dist/ddic/table-source.js.map +1 -0
- package/dist/ddic/xml.d.ts +65 -0
- package/dist/ddic/xml.js +201 -0
- package/dist/ddic/xml.js.map +1 -0
- package/dist/dev.d.ts +128 -0
- package/dist/dev.js +434 -0
- package/dist/dev.js.map +1 -0
- package/dist/diagnostics.d.ts +33 -0
- package/dist/diagnostics.js +53 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/gen/abap/derived-types.d.ts +26 -0
- package/dist/gen/abap/derived-types.js +323 -0
- package/dist/gen/abap/derived-types.js.map +1 -0
- package/dist/gen/abap/eml.d.ts +118 -0
- package/dist/gen/abap/eml.js +362 -0
- package/dist/gen/abap/eml.js.map +1 -0
- package/dist/gen/abap/enums.d.ts +13 -0
- package/dist/gen/abap/enums.js +74 -0
- package/dist/gen/abap/enums.js.map +1 -0
- package/dist/gen/abap/framework-http.d.ts +14 -0
- package/dist/gen/abap/framework-http.js +1049 -0
- package/dist/gen/abap/framework-http.js.map +1 -0
- package/dist/gen/abap/framework-query.d.ts +14 -0
- package/dist/gen/abap/framework-query.js +225 -0
- package/dist/gen/abap/framework-query.js.map +1 -0
- package/dist/gen/abap/framework-utils.d.ts +29 -0
- package/dist/gen/abap/framework-utils.js +3707 -0
- package/dist/gen/abap/framework-utils.js.map +1 -0
- package/dist/gen/abap/framework.d.ts +12 -0
- package/dist/gen/abap/framework.js +480 -0
- package/dist/gen/abap/framework.js.map +1 -0
- package/dist/gen/abap/generate.d.ts +40 -0
- package/dist/gen/abap/generate.js +238 -0
- package/dist/gen/abap/generate.js.map +1 -0
- package/dist/gen/abap/rewrite.d.ts +82 -0
- package/dist/gen/abap/rewrite.js +957 -0
- package/dist/gen/abap/rewrite.js.map +1 -0
- package/dist/gen/abap/shadow.d.ts +25 -0
- package/dist/gen/abap/shadow.js +175 -0
- package/dist/gen/abap/shadow.js.map +1 -0
- package/dist/gen/abap/tokens.d.ts +33 -0
- package/dist/gen/abap/tokens.js +87 -0
- package/dist/gen/abap/tokens.js.map +1 -0
- package/dist/gen/app/index.d.ts +25 -0
- package/dist/gen/app/index.js +322 -0
- package/dist/gen/app/index.js.map +1 -0
- package/dist/gen/csdl.d.ts +11 -0
- package/dist/gen/csdl.js +562 -0
- package/dist/gen/csdl.js.map +1 -0
- package/dist/gen/deploy.d.ts +12 -0
- package/dist/gen/deploy.js +53 -0
- package/dist/gen/deploy.js.map +1 -0
- package/dist/gen/docs/index.d.ts +35 -0
- package/dist/gen/docs/index.js +267 -0
- package/dist/gen/docs/index.js.map +1 -0
- package/dist/gen/docs/markdown.d.ts +23 -0
- package/dist/gen/docs/markdown.js +187 -0
- package/dist/gen/docs/markdown.js.map +1 -0
- package/dist/gen/docs/site.d.ts +17 -0
- package/dist/gen/docs/site.js +106 -0
- package/dist/gen/docs/site.js.map +1 -0
- package/dist/gen/keycloak.d.ts +21 -0
- package/dist/gen/keycloak.js +90 -0
- package/dist/gen/keycloak.js.map +1 -0
- package/dist/gen/launchpad/index.d.ts +48 -0
- package/dist/gen/launchpad/index.js +302 -0
- package/dist/gen/launchpad/index.js.map +1 -0
- package/dist/gen/launchpad/ui.d.ts +14 -0
- package/dist/gen/launchpad/ui.js +350 -0
- package/dist/gen/launchpad/ui.js.map +1 -0
- package/dist/gen/mcp.d.ts +23 -0
- package/dist/gen/mcp.js +244 -0
- package/dist/gen/mcp.js.map +1 -0
- package/dist/gen/sql-expressions.d.ts +12 -0
- package/dist/gen/sql-expressions.js +136 -0
- package/dist/gen/sql-expressions.js.map +1 -0
- package/dist/gen/sql.d.ts +38 -0
- package/dist/gen/sql.js +612 -0
- package/dist/gen/sql.js.map +1 -0
- package/dist/gen/ui/index.d.ts +7 -0
- package/dist/gen/ui/index.js +27 -0
- package/dist/gen/ui/index.js.map +1 -0
- package/dist/gen/ui/layout.d.ts +230 -0
- package/dist/gen/ui/layout.js +511 -0
- package/dist/gen/ui/layout.js.map +1 -0
- package/dist/gen/ui/static.d.ts +55 -0
- package/dist/gen/ui/static.js +2901 -0
- package/dist/gen/ui/static.js.map +1 -0
- package/dist/gen/ui/views.d.ts +10 -0
- package/dist/gen/ui/views.js +511 -0
- package/dist/gen/ui/views.js.map +1 -0
- package/dist/gen/vendor.d.ts +23 -0
- package/dist/gen/vendor.js +68 -0
- package/dist/gen/vendor.js.map +1 -0
- package/dist/gen/xml.d.ts +9 -0
- package/dist/gen/xml.js +42 -0
- package/dist/gen/xml.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/input/project.d.ts +50 -0
- package/dist/input/project.js +128 -0
- package/dist/input/project.js.map +1 -0
- package/dist/ir/access-controls.d.ts +11 -0
- package/dist/ir/access-controls.js +148 -0
- package/dist/ir/access-controls.js.map +1 -0
- package/dist/ir/authorizations.d.ts +25 -0
- package/dist/ir/authorizations.js +178 -0
- package/dist/ir/authorizations.js.map +1 -0
- package/dist/ir/behaviors.d.ts +16 -0
- package/dist/ir/behaviors.js +548 -0
- package/dist/ir/behaviors.js.map +1 -0
- package/dist/ir/builder.d.ts +20 -0
- package/dist/ir/builder.js +505 -0
- package/dist/ir/builder.js.map +1 -0
- package/dist/ir/config.d.ts +25 -0
- package/dist/ir/config.js +130 -0
- package/dist/ir/config.js.map +1 -0
- package/dist/ir/dictionary.d.ts +54 -0
- package/dist/ir/dictionary.js +328 -0
- package/dist/ir/dictionary.js.map +1 -0
- package/dist/ir/entities.d.ts +58 -0
- package/dist/ir/entities.js +676 -0
- package/dist/ir/entities.js.map +1 -0
- package/dist/ir/expressions.d.ts +33 -0
- package/dist/ir/expressions.js +327 -0
- package/dist/ir/expressions.js.map +1 -0
- package/dist/ir/handlers.d.ts +63 -0
- package/dist/ir/handlers.js +398 -0
- package/dist/ir/handlers.js.map +1 -0
- package/dist/ir/number-ranges.d.ts +24 -0
- package/dist/ir/number-ranges.js +74 -0
- package/dist/ir/number-ranges.js.map +1 -0
- package/dist/ir/seed.d.ts +23 -0
- package/dist/ir/seed.js +78 -0
- package/dist/ir/seed.js.map +1 -0
- package/dist/ir/service.d.ts +21 -0
- package/dist/ir/service.js +96 -0
- package/dist/ir/service.js.map +1 -0
- package/dist/launchpad/config.d.ts +47 -0
- package/dist/launchpad/config.js +321 -0
- package/dist/launchpad/config.js.map +1 -0
- package/dist/launchpad/workspace.d.ts +48 -0
- package/dist/launchpad/workspace.js +166 -0
- package/dist/launchpad/workspace.js.map +1 -0
- package/dist/srvd/parser.d.ts +36 -0
- package/dist/srvd/parser.js +193 -0
- package/dist/srvd/parser.js.map +1 -0
- package/dist/standard/data.d.ts +18 -0
- package/dist/standard/data.js +534 -0
- package/dist/standard/data.js.map +1 -0
- package/dist/standard/index.d.ts +36 -0
- package/dist/standard/index.js +507 -0
- package/dist/standard/index.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +4 -0
- package/dist/version.js.map +1 -0
- package/docs/AGENTS.md +79 -0
- package/docs/ANNOTATIONS.md +76 -0
- package/docs/DECISIONS.md +1554 -0
- package/docs/DEPLOYMENT.md +113 -0
- package/docs/DIAGNOSTICS.md +116 -0
- package/docs/FEATURES.md +287 -0
- package/docs/GUIDE.md +560 -0
- package/docs/KNOWN_GAPS.md +216 -0
- package/docs/MCP.md +84 -0
- package/docs/PLAN.md +690 -0
- package/docs/README.md +148 -0
- package/docs/REMOTE_APIS.md +121 -0
- package/docs/ROADMAP.md +35 -0
- package/docs/UTILITIES.md +95 -0
- package/package.json +49 -3
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `rapt launchpad`: the folder of a launchpad of applications (decision D37). Its server (the
|
|
3
|
+
* runtime, embedded in `vendor/`) serves the OpenUI5 launchpad, opens the sessions the
|
|
4
|
+
* applications read and forwards their requests; docker-compose starts it with the applications
|
|
5
|
+
* built by `rapt build` (one PostgreSQL each) and, in the `oidc` profile, Keycloak.
|
|
6
|
+
*/
|
|
7
|
+
import { CFIGNORE, cloudFoundryManifest, deploySection } from "../deploy.js";
|
|
8
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import { appUrlVariable } from "@open-rap/model";
|
|
11
|
+
import { generateApplication } from "../../build.js";
|
|
12
|
+
import { Diagnostics } from "../../diagnostics.js";
|
|
13
|
+
import { loadProject } from "../../input/project.js";
|
|
14
|
+
import { resolveLaunchpad } from "../../launchpad/config.js";
|
|
15
|
+
import { keycloakRealm } from "../keycloak.js";
|
|
16
|
+
import { packageDir, vendorPackage } from "../vendor.js";
|
|
17
|
+
import { LAUNCHPAD_COMPONENT, LAUNCHPAD_CONTROLLER, LAUNCHPAD_CSS, LAUNCHPAD_LOGO, LAUNCHPAD_VIEW, launchpadIndexHtml, launchpadManifest } from "./ui.js";
|
|
18
|
+
const SERVER = `#!/usr/bin/env node
|
|
19
|
+
// Generated by Open RAP Runtime: starts the launchpad of the applications.
|
|
20
|
+
// Configuration by environment variables: see README.md and .env.example.
|
|
21
|
+
import { fileURLToPath } from "node:url";
|
|
22
|
+
import { startLaunchpad } from "@open-rap/runtime";
|
|
23
|
+
|
|
24
|
+
const launchpad = await startLaunchpad({ dir: fileURLToPath(new URL(".", import.meta.url)) });
|
|
25
|
+
console.log(\`Launchpad ready at \${launchpad.url}\`);
|
|
26
|
+
for (const signal of ["SIGINT", "SIGTERM"]) {
|
|
27
|
+
process.once(signal, () => {
|
|
28
|
+
launchpad.close().then(() => process.exit(0), () => process.exit(1));
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
`;
|
|
32
|
+
const DOCKERFILE = `# syntax=docker/dockerfile:1
|
|
33
|
+
# Generated by Open RAP Runtime.
|
|
34
|
+
FROM node:22-alpine AS dependencies
|
|
35
|
+
WORKDIR /app
|
|
36
|
+
COPY package.json .npmrc ./
|
|
37
|
+
COPY vendor ./vendor
|
|
38
|
+
RUN npm install --omit=dev --omit=optional --no-audit --no-fund
|
|
39
|
+
|
|
40
|
+
FROM node:22-alpine
|
|
41
|
+
ENV NODE_ENV=production PORT=8090
|
|
42
|
+
WORKDIR /app
|
|
43
|
+
COPY --from=dependencies /app/node_modules ./node_modules
|
|
44
|
+
COPY . .
|
|
45
|
+
USER node
|
|
46
|
+
EXPOSE 8090
|
|
47
|
+
HEALTHCHECK --interval=10s --timeout=3s --retries=5 CMD wget -qO- http://127.0.0.1:8090/health || exit 1
|
|
48
|
+
CMD ["node", "server.mjs"]
|
|
49
|
+
`;
|
|
50
|
+
const DOCKERIGNORE = `node_modules
|
|
51
|
+
.env
|
|
52
|
+
`;
|
|
53
|
+
const posix = (p) => p.split(path.sep).join("/");
|
|
54
|
+
/** The applications with a generated folder run in docker-compose, behind the launchpad. */
|
|
55
|
+
function compose(name, model, apps, outDir) {
|
|
56
|
+
const local = apps.filter((a) => a.build !== undefined && outDir !== undefined);
|
|
57
|
+
const lines = [
|
|
58
|
+
"# Generated by Open RAP Runtime.",
|
|
59
|
+
"# docker compose up --build launchpad, applications and PostgreSQL, no login (AUTH_MODE=none)",
|
|
60
|
+
"# AUTH_MODE=oidc docker compose --profile oidc up --build",
|
|
61
|
+
"# with Keycloak (user alice / alice), see README.md",
|
|
62
|
+
"# The applications behind the launchpad share its login: same client, public URL and SESSION_SECRET.",
|
|
63
|
+
"x-login: &login",
|
|
64
|
+
" AUTH_MODE: ${AUTH_MODE:-none}",
|
|
65
|
+
" OIDC_ISSUER: http://localhost:8180/realms/rapt",
|
|
66
|
+
" OIDC_DISCOVERY_URL: http://keycloak:8080/realms/rapt/.well-known/openid-configuration",
|
|
67
|
+
" OIDC_CLIENT_ID: rapt-launchpad",
|
|
68
|
+
" OIDC_CLIENT_SECRET: rapt-launchpad-secret",
|
|
69
|
+
" SESSION_SECRET: ${SESSION_SECRET:-change-me-change-me-change-me-change-me}",
|
|
70
|
+
" PUBLIC_URL: http://localhost:8090/",
|
|
71
|
+
"",
|
|
72
|
+
"services:",
|
|
73
|
+
" launchpad:",
|
|
74
|
+
" build: .",
|
|
75
|
+
` image: ${name}:latest`,
|
|
76
|
+
" environment:",
|
|
77
|
+
" <<: *login",
|
|
78
|
+
...model.apps.map((a) => ` ${appUrlVariable(a.id)}: ${local.some((l) => l.id === a.id) ? `http://${a.id}:8080/` : a.url}`),
|
|
79
|
+
" ports:",
|
|
80
|
+
' - "8090:8090"',
|
|
81
|
+
];
|
|
82
|
+
if (local.length > 0) {
|
|
83
|
+
lines.push(" depends_on:", ...local.flatMap((a) => [` ${a.id}:`, " condition: service_healthy"]));
|
|
84
|
+
}
|
|
85
|
+
for (const app of local) {
|
|
86
|
+
lines.push("", ` ${app.id}:`, ` build: ${posix(path.relative(outDir, app.build)) || "."}`, " environment:", " <<: *login", ` DATABASE_URL: postgres://app:app@db-${app.id}:5432/app`, " depends_on:", ` db-${app.id}:`, " condition: service_healthy", "", ` db-${app.id}:`, " image: postgres:16-alpine", " environment:", " POSTGRES_DB: app", " POSTGRES_USER: app", " POSTGRES_PASSWORD: app", " healthcheck:", ' test: ["CMD-SHELL", "pg_isready -U app -d app"]', " interval: 5s", " retries: 20", " volumes:", ` - db-${app.id}-data:/var/lib/postgresql/data`);
|
|
87
|
+
}
|
|
88
|
+
lines.push("", " keycloak:", " image: quay.io/keycloak/keycloak:26.0", ' profiles: ["oidc"]', " command: start-dev --import-realm", " environment:", " KC_BOOTSTRAP_ADMIN_USERNAME: admin", " KC_BOOTSTRAP_ADMIN_PASSWORD: admin", " KC_HOSTNAME: http://localhost:8180", ' KC_HOSTNAME_BACKCHANNEL_DYNAMIC: "true"', " volumes:", " - ./keycloak:/opt/keycloak/data/import:ro", " ports:", ' - "8180:8080"');
|
|
89
|
+
if (local.length > 0) {
|
|
90
|
+
lines.push("", "volumes:", ...local.map((a) => ` db-${a.id}-data:`));
|
|
91
|
+
}
|
|
92
|
+
return `${lines.join("\n")}\n`;
|
|
93
|
+
}
|
|
94
|
+
function envExample(model) {
|
|
95
|
+
return `# Configuration of the generated launchpad (all optional).
|
|
96
|
+
PORT=8090
|
|
97
|
+
PUBLIC_URL=http://localhost:8090/
|
|
98
|
+
LOG_LEVEL=info
|
|
99
|
+
# none (development user DEV_USER, its roles DEV_ROLES — default: every tile) or oidc
|
|
100
|
+
AUTH_MODE=none
|
|
101
|
+
DEV_USER=DEVELOPER
|
|
102
|
+
# DEV_ROLES=travel_viewer
|
|
103
|
+
OIDC_ISSUER=http://localhost:8180/realms/rapt
|
|
104
|
+
OIDC_DISCOVERY_URL=
|
|
105
|
+
OIDC_CLIENT_ID=rapt-launchpad
|
|
106
|
+
OIDC_CLIENT_SECRET=rapt-launchpad-secret
|
|
107
|
+
OIDC_REQUIRED_ROLE=
|
|
108
|
+
# the same secret in the applications behind the launchpad: they read its sessions
|
|
109
|
+
SESSION_SECRET=change-me-change-me-change-me-change-me
|
|
110
|
+
# where the launchpad reaches the applications
|
|
111
|
+
${model.apps.map((a) => `${appUrlVariable(a.id)}=${a.url}`).join("\n")}
|
|
112
|
+
`;
|
|
113
|
+
}
|
|
114
|
+
function readme(name, model) {
|
|
115
|
+
const tiles = model.groups.flatMap((g) => g.tiles.map((t) => ({ group: g.title, tile: t })));
|
|
116
|
+
return `# ${name}
|
|
117
|
+
|
|
118
|
+
Launchpad generated by [Open RAP Runtime](https://clementringot.github.io/Open-Rap-Runtime): the entry
|
|
119
|
+
point of the applications, as the SAP Fiori launchpad, built with OpenUI5. It shows the tiles
|
|
120
|
+
assigned to the roles of the user, opens the applications at \`/apps/<id>/\` and forwards the
|
|
121
|
+
requests of their UIs to their services: the browser sees a single origin and logs in once.
|
|
122
|
+
|
|
123
|
+
## Run
|
|
124
|
+
|
|
125
|
+
With Docker (the applications generated next to it are built and started too):
|
|
126
|
+
|
|
127
|
+
\`\`\`sh
|
|
128
|
+
docker compose up --build # http://localhost:8090/ (no login)
|
|
129
|
+
AUTH_MODE=oidc docker compose --profile oidc up --build # Keycloak, user alice / alice
|
|
130
|
+
\`\`\`
|
|
131
|
+
|
|
132
|
+
With Node.js 22, the applications running: \`npm install\` then \`npm start\`
|
|
133
|
+
(\`APP_<ID>_URL\` gives where each application runs).
|
|
134
|
+
|
|
135
|
+
## The applications behind the launchpad
|
|
136
|
+
|
|
137
|
+
The launchpad opens the session (OIDC, authorization code with PKCE) and the applications read it:
|
|
138
|
+
they need the same \`SESSION_SECRET\`, \`AUTH_MODE=oidc\` with the same issuer, and the client and
|
|
139
|
+
\`PUBLIC_URL\` of the launchpad (a login asked by an application then comes back to it). The claims
|
|
140
|
+
the authorizations of the applications read are kept in the session: ${model.claims.length === 0 ? "none" : model.claims.map((c) => `\`${c}\``).join(", ")}.
|
|
141
|
+
|
|
142
|
+
| Application | Mounted at | Services | Variable |
|
|
143
|
+
|---|---|---|---|
|
|
144
|
+
${model.apps.map((a) => `| ${a.title} | \`/apps/${a.id}/\` | ${a.servicePaths.map((p) => `\`${p}\``).join("<br>") || "—"} | \`${appUrlVariable(a.id)}\` |`).join("\n")}
|
|
145
|
+
|
|
146
|
+
## Tiles
|
|
147
|
+
|
|
148
|
+
A tile is shown to the users having one of its roles (every user without roles); \`/go/<intent>\`
|
|
149
|
+
and \`/#<intent>\` open the application of an intent.
|
|
150
|
+
|
|
151
|
+
| Group | Tile | Intent | Roles | Count |
|
|
152
|
+
|---|---|---|---|---|
|
|
153
|
+
${tiles.map(({ group, tile }) => `| ${group} | ${tile.title} | ${tile.intent === undefined ? "" : `\`${tile.intent}\``} | ${tile.roles.length === 0 ? "every user" : tile.roles.map((r) => `\`${r}\``).join(", ")} | ${tile.count === undefined ? "" : `\`${tile.count}\``} |`).join("\n")}
|
|
154
|
+
|
|
155
|
+
${deploySection(name, "launchpad")}
|
|
156
|
+
On Cloud Foundry, each application is pushed on its own route; give their routes to the
|
|
157
|
+
launchpad with \`cf set-env ${name} APP_<ID>_URL https://…\`.
|
|
158
|
+
|
|
159
|
+
## Content
|
|
160
|
+
|
|
161
|
+
| Path | Content |
|
|
162
|
+
|---|---|
|
|
163
|
+
| \`launchpad/config.json\` | the tiles, groups and applications, read by the server |
|
|
164
|
+
| \`ui/\` | OpenUI5 launchpad |
|
|
165
|
+
| \`keycloak/rapt-realm.json\` | realm of the Keycloak of docker-compose (client \`rapt-launchpad\`) |
|
|
166
|
+
| \`vendor/\` | the runtime of Open RAP Runtime (MIT) |
|
|
167
|
+
`;
|
|
168
|
+
}
|
|
169
|
+
/** The files of the OpenUI5 launchpad (`ui/`), served by the launchpad server. */
|
|
170
|
+
export function generateLaunchpadUi(model) {
|
|
171
|
+
return [
|
|
172
|
+
{ path: "index.html", content: launchpadIndexHtml(model.title) },
|
|
173
|
+
{ path: "manifest.json", content: launchpadManifest(model.title) },
|
|
174
|
+
{ path: "Component.js", content: LAUNCHPAD_COMPONENT },
|
|
175
|
+
{ path: "view/Launchpad.view.xml", content: LAUNCHPAD_VIEW },
|
|
176
|
+
{ path: "controller/Launchpad.controller.js", content: LAUNCHPAD_CONTROLLER },
|
|
177
|
+
{ path: "css/style.css", content: LAUNCHPAD_CSS },
|
|
178
|
+
{ path: "logo.svg", content: LAUNCHPAD_LOGO },
|
|
179
|
+
];
|
|
180
|
+
}
|
|
181
|
+
/** Resolves `launchpad.json` and generates the files of the launchpad. */
|
|
182
|
+
export function generateLaunchpad(file, options = {}) {
|
|
183
|
+
const diagnostics = new Diagnostics();
|
|
184
|
+
const resolution = resolveLaunchpad(file, diagnostics, options.built === undefined ? {} : { built: options.built });
|
|
185
|
+
if (resolution === undefined || diagnostics.hasErrors()) {
|
|
186
|
+
return resolution === undefined ? { diagnostics, files: [] } : { diagnostics, model: resolution.model, files: [] };
|
|
187
|
+
}
|
|
188
|
+
const { model, apps } = resolution;
|
|
189
|
+
const runtimeDir = packageDir("@open-rap/runtime", "runtime", options.runtimeDir);
|
|
190
|
+
const modelDir = packageDir("@open-rap/model", "model");
|
|
191
|
+
if (runtimeDir === undefined || modelDir === undefined) {
|
|
192
|
+
diagnostics.error("APP001", "the @open-rap/runtime and @open-rap/model packages (built: dist/) are needed to embed the runtime; give --runtime <dir> or run pnpm build");
|
|
193
|
+
return { diagnostics, model, files: [] };
|
|
194
|
+
}
|
|
195
|
+
const runtime = JSON.parse(readFileSync(path.join(runtimeDir, "package.json"), "utf8"));
|
|
196
|
+
const version = (dependency) => runtime.dependencies?.[dependency] ?? runtime.devDependencies?.[dependency] ?? "*";
|
|
197
|
+
const slug = model.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
198
|
+
const name = slug === "" ? "rapt-launchpad" : slug.includes("launchpad") ? slug : `${slug}-launchpad`;
|
|
199
|
+
const openui5 = Object.keys(runtime.devDependencies ?? {}).filter((d) => d.startsWith("@openui5/"));
|
|
200
|
+
const pkg = {
|
|
201
|
+
name,
|
|
202
|
+
version: "1.0.0",
|
|
203
|
+
private: true,
|
|
204
|
+
description: `${/launchpad/i.test(model.title) ? model.title : `Launchpad ${model.title}`}, generated by Open RAP Runtime`,
|
|
205
|
+
type: "module",
|
|
206
|
+
engines: { node: ">=22" },
|
|
207
|
+
scripts: { start: "node server.mjs" },
|
|
208
|
+
dependencies: {
|
|
209
|
+
"@open-rap/runtime": "file:vendor/open-rap-runtime",
|
|
210
|
+
"@open-rap/model": "file:vendor/open-rap-model",
|
|
211
|
+
...Object.fromEntries(openui5.map((d) => [d, version(d)])),
|
|
212
|
+
"less-openui5": version("less-openui5"),
|
|
213
|
+
},
|
|
214
|
+
overrides: { "@open-rap/model": "$@open-rap/model" },
|
|
215
|
+
};
|
|
216
|
+
const realm = keycloakRealm({ clientId: "rapt-launchpad", clientName: "Launchpad generated by Open RAP Runtime", secret: "rapt-launchpad-secret", url: "http://localhost:8090", roles: model.roles, claims: model.claims });
|
|
217
|
+
const files = [
|
|
218
|
+
{ path: "package.json", content: `${JSON.stringify(pkg, null, 2)}\n` },
|
|
219
|
+
{ path: ".npmrc", content: "install-links=true\n" },
|
|
220
|
+
{ path: "server.mjs", content: SERVER },
|
|
221
|
+
{ path: "launchpad/config.json", content: `${JSON.stringify(model, null, 2)}\n` },
|
|
222
|
+
...generateLaunchpadUi(model).map((f) => ({ path: `ui/${f.path}`, content: f.content })),
|
|
223
|
+
{ path: "Dockerfile", content: DOCKERFILE },
|
|
224
|
+
// the applications built with it (D69) have their own image and route
|
|
225
|
+
{ path: ".dockerignore", content: `${DOCKERIGNORE}${options.built?.size ? "apps\n" : ""}` },
|
|
226
|
+
{ path: "manifest.yml", content: cloudFoundryManifest(name, { database: false, memory: "256M" }) },
|
|
227
|
+
{ path: ".cfignore", content: `${CFIGNORE}${options.built?.size ? "apps\n" : ""}` },
|
|
228
|
+
{ path: "docker-compose.yml", content: compose(name, model, apps, options.outDir === undefined ? undefined : path.resolve(options.outDir)) },
|
|
229
|
+
{ path: "keycloak/rapt-realm.json", content: `${JSON.stringify(realm, null, 2)}\n` },
|
|
230
|
+
{ path: ".env.example", content: envExample(model) },
|
|
231
|
+
{ path: "README.md", content: readme(name, model) },
|
|
232
|
+
...vendorPackage(modelDir, "open-rap-model", {}),
|
|
233
|
+
...vendorPackage(runtimeDir, "open-rap-runtime", { "@open-rap/model": "file:../open-rap-model" }),
|
|
234
|
+
];
|
|
235
|
+
return { diagnostics, model, files };
|
|
236
|
+
}
|
|
237
|
+
const APP_ID = /^[a-z][a-z0-9-]*$/;
|
|
238
|
+
/**
|
|
239
|
+
* `rapt launchpad`: the launchpad and, built from their sources (`source`, D69) into
|
|
240
|
+
* `apps/<id>/`, its applications. A single folder to deploy: docker-compose starts them all.
|
|
241
|
+
*/
|
|
242
|
+
export async function buildLaunchpad(file, options) {
|
|
243
|
+
const diagnostics = new Diagnostics();
|
|
244
|
+
const at = { file };
|
|
245
|
+
let entries = [];
|
|
246
|
+
try {
|
|
247
|
+
const source = JSON.parse(readFileSync(file, "utf8"));
|
|
248
|
+
entries = Array.isArray(source?.apps) ? source.apps : [];
|
|
249
|
+
}
|
|
250
|
+
catch {
|
|
251
|
+
// reported by resolveLaunchpad
|
|
252
|
+
}
|
|
253
|
+
const base = path.dirname(path.resolve(file));
|
|
254
|
+
const outDir = path.resolve(options.outDir);
|
|
255
|
+
const built = new Map();
|
|
256
|
+
const files = [];
|
|
257
|
+
const apps = [];
|
|
258
|
+
for (const entry of entries) {
|
|
259
|
+
const id = entry?.["id"];
|
|
260
|
+
const source = entry?.["source"];
|
|
261
|
+
if (typeof id !== "string" || !APP_ID.test(id) || typeof source !== "string" || source.trim() === "" || entry?.["build"] !== undefined || built.has(id)) {
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
const dir = path.resolve(base, source);
|
|
265
|
+
if (!existsSync(dir)) {
|
|
266
|
+
diagnostics.error("LPD009", `the application ${id}: no folder ${source} (source, relative to launchpad.json)`, at);
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
const service = entry?.["service"];
|
|
270
|
+
const result = await generateApplication(loadProject(dir), {
|
|
271
|
+
...(typeof service === "string" ? { service } : {}),
|
|
272
|
+
...(options.runtimeDir === undefined ? {} : { runtimeDir: options.runtimeDir }),
|
|
273
|
+
});
|
|
274
|
+
for (const d of result.diagnostics.items) {
|
|
275
|
+
if (d.severity !== "info") {
|
|
276
|
+
diagnostics.add(d.severity, d.code, `${id}: ${d.message}`, { file: d.file === undefined ? dir : path.join(dir, ...d.file.split("/")), ...(d.line === undefined ? {} : { line: d.line }), ...(d.column === undefined ? {} : { column: d.column }) });
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (result.model === undefined || result.files.length === 0) {
|
|
280
|
+
diagnostics.error("LPD009", `the application ${id} does not build (rapt check ${source})`, at);
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
let title;
|
|
284
|
+
try {
|
|
285
|
+
title = JSON.parse(result.files.find((f) => f.path === "ui/manifest.json")?.content ?? "")["sap.app"]?.title;
|
|
286
|
+
}
|
|
287
|
+
catch {
|
|
288
|
+
// an application without UI (Web API)
|
|
289
|
+
}
|
|
290
|
+
built.set(id, { dir: path.join(outDir, "apps", id), model: result.model, ...(title === undefined ? {} : { title }) });
|
|
291
|
+
files.push(...result.files.map((f) => ({ path: `apps/${id}/${f.path}`, content: f.content })));
|
|
292
|
+
apps.push({ id, source: dir, out: path.join(outDir, "apps", id), files: result.files.length });
|
|
293
|
+
}
|
|
294
|
+
const launchpad = generateLaunchpad(file, { ...options, built });
|
|
295
|
+
diagnostics.addAll(launchpad.diagnostics);
|
|
296
|
+
const model = launchpad.model === undefined ? {} : { model: launchpad.model };
|
|
297
|
+
if (diagnostics.hasErrors() || launchpad.files.length === 0) {
|
|
298
|
+
return { diagnostics, ...model, files: [], apps };
|
|
299
|
+
}
|
|
300
|
+
return { diagnostics, ...model, files: [...launchpad.files, ...files], apps };
|
|
301
|
+
}
|
|
302
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/gen/launchpad/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The UI of the launchpad (decision D37), plain OpenUI5 (sap.m, sap.f): the counterpart of the
|
|
3
|
+
* SAP Fiori launchpad, whose shell (sap.ushell) exists in SAPUI5 only. A ShellBar (home, search,
|
|
4
|
+
* user menu with the logout), the groups of tiles of `/launchpad/config` (GenericTile; a
|
|
5
|
+
* NumericContent for the tiles with a count) and the navigation by intent (`#Travel-manage`).
|
|
6
|
+
*/
|
|
7
|
+
export declare function launchpadIndexHtml(title: string): string;
|
|
8
|
+
export declare function launchpadManifest(title: string): string;
|
|
9
|
+
export declare const LAUNCHPAD_COMPONENT = "sap.ui.define([\n \"sap/ui/core/UIComponent\",\n \"sap/ui/model/json/JSONModel\"\n], function (UIComponent, JSONModel) {\n \"use strict\";\n\n return UIComponent.extend(\"rapt.launchpad.Component\", {\n metadata: { manifest: \"json\", interfaces: [\"sap.ui.core.IAsyncContentCreation\"] },\n\n init: function () {\n UIComponent.prototype.init.apply(this, arguments);\n this.setModel(new JSONModel({ title: \"\", user: {}, logout: \"\", groups: [], spaces: [], space: \"\", page: \"\", pages: [], counts: {}, loaded: false, error: \"\", emptyText: \"\" }));\n }\n });\n});\n";
|
|
10
|
+
export declare const LAUNCHPAD_VIEW = "<mvc:View controllerName=\"rapt.launchpad.controller.Launchpad\" xmlns:mvc=\"sap.ui.core.mvc\" xmlns=\"sap.m\" xmlns:f=\"sap.f\" xmlns:core=\"sap.ui.core\" displayBlock=\"true\" height=\"100%\">\n <Page id=\"page\" enableScrolling=\"true\" class=\"raptLaunchpad\">\n <customHeader>\n <f:ShellBar id=\"shellBar\" title=\"{/title}\" homeIcon=\"logo.svg\" homeIconTooltip=\"Home\" homeIconPressed=\".onHome\" avatarPressed=\".onAvatarPressed\">\n <f:searchManager>\n <f:SearchManager id=\"search\" placeholder=\"Search for apps\" liveChange=\".onSearch\" search=\".onSearch\"/>\n </f:searchManager>\n <f:profile>\n <Avatar id=\"avatar\" initials=\"{/user/initials}\" tooltip=\"{/user/name}\"/>\n </f:profile>\n </f:ShellBar>\n </customHeader>\n <content>\n <MessageStrip id=\"message\" visible=\"{= ${/error} !== '' }\" text=\"{/error}\" type=\"Error\" showIcon=\"true\" class=\"sapUiSmallMargin\"/>\n <IconTabHeader id=\"spaces\" visible=\"{= ${/spaces}.length > 1 }\" selectedKey=\"{/space}\" select=\".onSpaceSelect\" mode=\"Inline\"\n items=\"{path: '/spaces', templateShareable: false}\">\n <items><IconTabFilter key=\"{id}\" text=\"{title}\"/></items>\n </IconTabHeader>\n <HBox id=\"pageBar\" visible=\"{= ${/pages}.length > 1 }\" alignItems=\"Center\" class=\"raptLaunchpadPages\">\n <Label text=\"Page\" labelFor=\"pages\" class=\"sapUiTinyMarginEnd\"/>\n <Select id=\"pages\" selectedKey=\"{/page}\" change=\".onPageSelect\" items=\"{path: '/pages', templateShareable: false}\">\n <items><core:Item key=\"{id}\" text=\"{title}\"/></items>\n </Select>\n </HBox>\n <VBox id=\"groups\" class=\"raptLaunchpadGroups\"/>\n <Text id=\"empty\" visible=\"{= ${/emptyText} !== '' }\" text=\"{/emptyText}\" class=\"raptLaunchpadEmpty\"/>\n </content>\n </Page>\n</mvc:View>\n";
|
|
11
|
+
export declare const LAUNCHPAD_CONTROLLER = "sap.ui.define([\n \"sap/ui/core/mvc/Controller\",\n \"sap/m/GenericTile\",\n \"sap/m/TileContent\",\n \"sap/m/NumericContent\",\n \"sap/m/ImageContent\",\n \"sap/m/Title\",\n \"sap/m/FlexBox\",\n \"sap/m/VBox\",\n \"sap/m/Text\",\n \"sap/m/Button\",\n \"sap/m/ResponsivePopover\"\n], function (Controller, GenericTile, TileContent, NumericContent, ImageContent, Title, FlexBox, VBox, Text, Button, ResponsivePopover) {\n \"use strict\";\n\n var INTENT = /^([A-Za-z][A-Za-z0-9_]*-[A-Za-z][A-Za-z0-9_]*)(\\?.*)?$/;\n\n /** The menu of the user: its identifier, and the logout of the OIDC sessions. */\n function userMenu(sId, oUser, sLogout) {\n var aItems = [];\n if (oUser.id !== oUser.name) {\n aItems.push(new Text({ text: oUser.id }));\n }\n if (!sLogout) {\n aItems.push(new Text({ text: \"Development user (no login)\" }));\n }\n var oMenu = new ResponsivePopover(sId, { title: oUser.name, placement: \"Bottom\", contentMinWidth: \"12rem\" });\n if (aItems.length > 0) {\n oMenu.addContent(new VBox({ items: aItems }).addStyleClass(\"sapUiSmallMargin\"));\n }\n if (sLogout) {\n oMenu.setBeginButton(new Button(sId + \"-logout\", {\n text: \"Sign Out\",\n icon: \"sap-icon://log\",\n press: function () {\n window.location.assign(sLogout);\n }\n }));\n }\n return oMenu;\n }\n\n return Controller.extend(\"rapt.launchpad.controller.Launchpad\", {\n onInit: function () {\n var that = this;\n this._sQuery = \"\";\n fetch(\"/launchpad/config\", { credentials: \"same-origin\", headers: { accept: \"application/json\" } })\n .then(function (oResponse) {\n if (!oResponse.ok) {\n throw new Error(\"The launchpad answered \" + oResponse.status);\n }\n return oResponse.json();\n })\n .then(function (oConfig) {\n var oModel = that._model();\n oModel.setProperty(\"/title\", oConfig.title);\n oModel.setProperty(\"/user\", oConfig.user);\n oModel.setProperty(\"/logout\", oConfig.logout || \"\");\n oModel.setProperty(\"/groups\", oConfig.groups);\n oModel.setProperty(\"/spaces\", oConfig.spaces || [{ id: \"home\", title: oConfig.title, pages: [{ id: \"home\", title: oConfig.title, groups: oConfig.groups }] }]);\n that._selectSpace(that._rememberedSpace());\n document.title = oConfig.title;\n // #SemanticObject-action: straight to the application of the intent\n if (that._navigateToIntent()) {\n return;\n }\n that._render();\n that._loadCounts();\n oModel.setProperty(\"/loaded\", true);\n })\n .catch(function (oError) {\n that._model().setProperty(\"/error\", oError.message);\n });\n },\n\n _model: function () {\n return this.getOwnerComponent().getModel();\n },\n\n _tiles: function () {\n return this._model().getProperty(\"/groups\").reduce(function (aAll, oGroup) {\n return aAll.concat(oGroup.tiles);\n }, []);\n },\n\n /** The space shown last (local storage), else the first one. */\n _rememberedSpace: function () {\n try {\n return window.localStorage.getItem(\"rapt.launchpad.space\") || \"\";\n } catch (e) {\n return \"\";\n }\n },\n\n _selectSpace: function (sId, sPage) {\n var oModel = this._model();\n var aSpaces = oModel.getProperty(\"/spaces\");\n var oSpace = aSpaces.find(function (s) { return s.id === sId; }) || aSpaces[0];\n if (!oSpace) {\n return;\n }\n oModel.setProperty(\"/space\", oSpace.id);\n oModel.setProperty(\"/pages\", oSpace.pages);\n var oPage = oSpace.pages.find(function (p) { return p.id === sPage; }) || oSpace.pages[0];\n oModel.setProperty(\"/page\", oPage ? oPage.id : \"\");\n try {\n window.localStorage.setItem(\"rapt.launchpad.space\", oSpace.id);\n } catch (e) {\n // the space is not remembered\n }\n },\n\n onSpaceSelect: function (oEvent) {\n this._selectSpace(oEvent.getParameter(\"key\"));\n this._render();\n },\n\n onPageSelect: function (oEvent) {\n this._model().setProperty(\"/page\", oEvent.getParameter(\"selectedItem\").getKey());\n this._render();\n },\n\n /** The sections shown: those of the current page; while searching, every section of every space. */\n _shownGroups: function () {\n var oModel = this._model();\n if (this._sQuery) {\n return oModel.getProperty(\"/groups\");\n }\n var oPage = (oModel.getProperty(\"/pages\") || []).find(function (p) { return p.id === oModel.getProperty(\"/page\"); });\n return oPage ? oPage.groups : oModel.getProperty(\"/groups\");\n },\n\n _navigateToIntent: function () {\n var sHash = window.location.hash.replace(/^#/, \"\");\n try {\n sHash = decodeURIComponent(sHash);\n } catch (e) {\n // kept as written\n }\n var aMatch = INTENT.exec(sHash);\n if (!aMatch || aMatch[1] === \"Shell-home\") {\n return false;\n }\n var oTile = this._tiles().find(function (t) {\n return t.intent === aMatch[1];\n });\n if (!oTile) {\n this._model().setProperty(\"/error\", \"No application of the launchpad for the intent \" + aMatch[1]);\n return false;\n }\n var sQuery = aMatch[2] || \"\";\n window.location.replace(oTile.target + (sQuery && oTile.target.indexOf(\"?\") >= 0 ? \"&\" + sQuery.slice(1) : sQuery));\n return true;\n },\n\n _render: function () {\n var that = this;\n var oBox = this.byId(\"groups\");\n var sQuery = this._sQuery.toLowerCase();\n var iVisible = 0;\n oBox.destroyItems();\n this._shownGroups().forEach(function (oGroup) {\n var aTiles = oGroup.tiles.filter(function (t) {\n return !sQuery || [t.title, t.subtitle, t.info].some(function (s) {\n return !!s && s.toLowerCase().indexOf(sQuery) >= 0;\n });\n });\n if (aTiles.length === 0) {\n return;\n }\n iVisible += aTiles.length;\n var oTiles = new FlexBox({ wrap: \"Wrap\", renderType: \"Bare\" }).addStyleClass(\"raptLaunchpadTiles\");\n aTiles.forEach(function (oTile) {\n oTiles.addItem(that._tile(oTile));\n });\n oBox.addItem(new VBox({ items: [new Title({ text: oGroup.title, level: \"H2\", titleStyle: \"H4\" }).addStyleClass(\"raptLaunchpadGroupTitle\"), oTiles] }).addStyleClass(\"raptLaunchpadGroup\"));\n });\n this._model().setProperty(\"/emptyText\", iVisible > 0 ? \"\" : sQuery ? \"No app matches the search.\" : \"No application is assigned to your roles.\");\n },\n\n _tile: function (oTile) {\n var oContent;\n if (oTile.count) {\n oContent = new NumericContent({ value: \"{/counts/\" + oTile.id + \"}\", icon: oTile.icon, withMargin: false, nullifyValue: false, animateTextChange: false });\n } else if (oTile.icon) {\n oContent = new ImageContent({ src: oTile.icon });\n }\n return new GenericTile(this.createId(\"tile-\" + oTile.id), {\n header: oTile.title,\n subheader: oTile.subtitle,\n press: this._open.bind(this, oTile),\n tileContent: [new TileContent({ footer: oTile.info, content: oContent })]\n }).addStyleClass(\"raptLaunchpadTile\");\n },\n\n /** The dynamic tiles: the $count of an entity set of an application, with the access controls of the user. */\n _loadCounts: function () {\n var oModel = this._model();\n this._tiles().filter(function (t) {\n return !!t.count;\n }).forEach(function (oTile) {\n fetch(oTile.count, { credentials: \"same-origin\", headers: { accept: \"text/plain\" } })\n .then(function (oResponse) {\n return oResponse.ok ? oResponse.text() : \"\";\n })\n .then(function (sCount) {\n oModel.setProperty(\"/counts/\" + oTile.id, sCount.trim());\n })\n .catch(function () {\n oModel.setProperty(\"/counts/\" + oTile.id, \"\");\n });\n });\n },\n\n _open: function (oTile) {\n if (oTile.external) {\n window.open(oTile.target, \"_blank\", \"noopener\");\n } else {\n window.location.assign(oTile.target);\n }\n },\n\n onHome: function () {\n window.location.assign(\"/\");\n },\n\n onSearch: function (oEvent) {\n var sValue = oEvent.getParameter(\"newValue\");\n this._sQuery = (sValue === undefined ? oEvent.getParameter(\"query\") : sValue) || \"\";\n this._render();\n },\n\n onAvatarPressed: function (oEvent) {\n if (!this._oUserMenu) {\n this._oUserMenu = userMenu(this.createId(\"userMenu\"), this._model().getProperty(\"/user\"), this._model().getProperty(\"/logout\"));\n this.getView().addDependent(this._oUserMenu);\n }\n this._oUserMenu.openBy(oEvent.getParameter(\"avatar\"));\n }\n });\n});\n";
|
|
12
|
+
export declare const LAUNCHPAD_CSS = ".raptLaunchpadGroups { padding: 1rem 2rem 0 2rem; }\n.raptLaunchpadPages { padding: 0.75rem 2rem 0 2rem; }\n.raptLaunchpadGroup { margin-bottom: 1.5rem; }\n.raptLaunchpadGroupTitle { margin: 0 0 0.75rem 0; }\n.raptLaunchpadTile { margin: 0 1rem 1rem 0; }\n.raptLaunchpadEmpty { display: block; margin: 2rem; }\n@media (max-width: 599px) {\n .raptLaunchpadGroups { padding: 1rem 1rem 0 1rem; }\n .raptLaunchpadTile { margin: 0 0.5rem 0.5rem 0; }\n}\n";
|
|
13
|
+
/** The mark of the launchpad: four tiles. */
|
|
14
|
+
export declare const LAUNCHPAD_LOGO = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 32 32\" width=\"32\" height=\"32\">\n <rect x=\"3\" y=\"3\" width=\"11\" height=\"11\" rx=\"2.5\" fill=\"#0070f2\"/>\n <rect x=\"18\" y=\"3\" width=\"11\" height=\"11\" rx=\"2.5\" fill=\"#0070f2\" fill-opacity=\"0.6\"/>\n <rect x=\"3\" y=\"18\" width=\"11\" height=\"11\" rx=\"2.5\" fill=\"#0070f2\" fill-opacity=\"0.6\"/>\n <rect x=\"18\" y=\"18\" width=\"11\" height=\"11\" rx=\"2.5\" fill=\"#0070f2\"/>\n</svg>\n";
|