Compare commits

..

2 Commits

Author SHA1 Message Date
Christian Georgi
1f8a78fe8a Update 2022-03-23 23:25:04 +01:00
Christian Georgi
7f9474244b Deploy test 2022-03-23 16:58:52 +01:00
117 changed files with 19964 additions and 3864 deletions

View File

@@ -1,25 +1,22 @@
{ {
"extends": [ "extends": "eslint:recommended",
"plugin:@sap/cds/recommended",
"eslint:recommended"
],
"env": { "env": {
"browser": true, "browser": true,
"es2022": true,
"node": true, "node": true,
"es6": true,
"jest": true, "jest": true,
"mocha": true "mocha": true
}, },
"parserOptions": {
"ecmaVersion": 2020
},
"globals": { "globals": {
"SELECT": true, "SELECT": true,
"INSERT": true, "INSERT": true,
"UPSERT": true,
"UPDATE": true, "UPDATE": true,
"DELETE": true, "DELETE": true,
"CREATE": true, "CREATE": true,
"DROP": true, "DROP": true,
"CDL": true,
"CQL": true,
"cds": true "cds": true
}, },
"rules": { "rules": {

View File

@@ -1,5 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: This channel is CLOSED.
about: Use SAP community instead
url: https://answers.sap.com/tags/9f13aee1-834c-4105-8e43-ee442775e5ce

View File

@@ -0,0 +1,10 @@
---
name: This channel is CLOSED.
about: Use our community at https://answers.sap.com/tags/9f13aee1-834c-4105-8e43-ee442775e5ce
title: ''
labels: ''
assignees: ''
---
Please use our community on https://answers.sap.com/tags/9f13aee1-834c-4105-8e43-ee442775e5ce

View File

@@ -5,13 +5,4 @@ updates:
directory: / directory: /
versioning-strategy: increase-if-necessary versioning-strategy: increase-if-necessary
schedule: schedule:
interval: weekly interval: daily
groups:
production-dependencies:
dependency-type: "production"
development-dependencies:
dependency-type: "development"
ignore:
- dependency-name: "chai"
# chai 5 doesn't work atm w/ cds.test, TODO fix that in cds.test
versions: ["5.x"]

View File

@@ -16,7 +16,7 @@ jobs:
strategy: strategy:
matrix: matrix:
node-version: [20.x, 18.x] node-version: [16.x, 14.x, 12.x]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2

6
.gitignore vendored
View File

@@ -12,14 +12,8 @@ target/
*.mtar *.mtar
connection.properties connection.properties
default-env.json default-env.json
.cdsrc-private.json
packages/messageBox packages/messageBox
reviews/msg-box reviews/msg-box
reviews/db/test.db reviews/db/test.db
*.openapi3.json *.openapi3.json
*.sqlite
*.db
@types/
@cds-models/

1
.registry/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*.tgz

80
.registry/server.js Normal file
View File

@@ -0,0 +1,80 @@
const { exec } = require ('child_process')
const isWin = process.platform === 'win32'
const express = require ('express')
const fs = require ('fs')
const app = express()
const { PORT=4444 } = process.env
const [,,port=PORT,scope='@capire'] = process.argv
const cwd = __dirname
// clean up on start (exit handler might not complete on Windows)
exec(isWin ? 'del *.tgz' : 'rm *.tgz', {cwd})
app.use('/-/:tarball', (req,res,next) => {
console.debug ('GET', req.params)
try {
const { tarball } = req.params
const [, pkg ] = /^\w+-(\w+)/.exec(tarball)
fs.lstat(tarball,(err => {
if (err) console.debug (`npm pack ../${pkg}`)
if (err) exec(`npm pack ../${pkg}`,{cwd},next)
else next()
}))
} catch (e) {
console.error(e)
res.sendStatus(500)
}
})
app.use('/-', express.static(__dirname))
app.get('/*', (req,res)=>{
const urlRegex = /^\/(@\w+)\/(\w+)/
const url = decodeURIComponent(req.url)
console.debug ('GET',url)
try {
if (!urlRegex.test(url)) return res.sendStatus(404)
const [, scpe, pkg ] = urlRegex.exec(url)
const package = require (`${scpe}/${pkg}/package.json`)
const tarball = `${scpe.slice(1)}-${pkg}-${package.version}.tgz`
// https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md
res.json({
"name": package.name,
"dist-tags": {
"latest": package.version
},
"versions": {
[package.version]: {
"name": package.name,
"version": package.version,
"dist": {
"tarball": `${server.url}/-/${tarball}`
},
}
},
})
} catch (e) {
if (e.code === 'MODULE_NOT_FOUND') return res.sendStatus(404)
console.error(e); throw e
}
})
const server = app.listen(port, ()=>{
const url = server.url = `http://localhost:${server.address().port}`
console.log (`npm set ${scope}:registry=${url}`)
exec(`npm set ${scope}:registry=${url}`)
console.log (`${scope} registry listening on ${url}`)
})
const _exit = ()=>{
server.close()
exec(`npm conf rm "${scope}:registry"`, ()=> { process.exit() })
}
process.on ('SIGTERM',_exit)
process.on ('SIGHUP',_exit)
process.on ('SIGINT',_exit)
process.on ('SIGUSR2',_exit)

View File

@@ -104,7 +104,7 @@
}, },
{ {
"file": "fiori/app/services.cds", "file": "fiori/app/services.cds",
"description": "### Annotations for SAP Fiori Elements\n\nAdds an SAP Fiori elements application to bookstore, thereby introducing:\n- OData Annotations in `.cds` files\n- Support for Fiori Draft\n- Support for Value Helps\n- Serving SAP Fiori apps locally\n\nSee the [Serving Fiori UIs](https://cap.cloud.sap/docs/advanced/fiori) documentation for more information.", "description": "### Annotations for SAP Fiori Elements\n\n- [Adds an SAP Fiori elements application](https://cap.cloud.sap/docs/guides/fiori/) to bookstore, thereby introducing to:\n- [OData Annotations](https://cap.cloud.sap/docs/guides/fiori#adding-odata-annotations) in `.cds` files\n- Support for [Fiori Draft](https://cap.cloud.sap/docs/guides/fiori#draft)\n- Support for [Value Helps](https://cap.cloud.sap/docs/guides/fiori#value-help)\n- Serving SAP Fiori apps locally\n",
"line": 1, "line": 1,
"selection": { "selection": {
"start": { "start": {

View File

@@ -4,11 +4,13 @@
// List of extensions which should be recommended for users of this workspace. // List of extensions which should be recommended for users of this workspace.
"recommendations": [ "recommendations": [
"qwtel.sqlite-viewer",
"sapse.vscode-cds", "sapse.vscode-cds",
"dbaeumer.vscode-eslint", "dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"mechatroner.rainbow-csv", "mechatroner.rainbow-csv",
"humao.rest-client", "humao.rest-client",
"alexcvzz.vscode-sqlite",
"hbenl.vscode-mocha-test-adapter",
"sdras.night-owl", "sdras.night-owl",
"vsls-contrib.codetour" "vsls-contrib.codetour"
], ],

20
.vscode/launch.json vendored
View File

@@ -13,7 +13,7 @@
"<node_internals>/**", "<node_internals>/**",
"**/node_modules/**", "**/node_modules/**",
"**/cds/lib/lazy.js", "**/cds/lib/lazy.js",
"**/cds/lib/req/cds-context.js", "**/cds/lib/req/cls.js",
"**/odata-v4/okra/**" "**/odata-v4/okra/**"
] ]
}, },
@@ -26,24 +26,10 @@
"<node_internals>/**", "<node_internals>/**",
"**/node_modules/**", "**/node_modules/**",
"**/cds/lib/lazy.js", "**/cds/lib/lazy.js",
"**/cds/lib/req/cds-context.js", "**/cds/lib/req/cls.js",
"**/odata-v4/okra/**" "**/odata-v4/okra/**"
] ]
}, }
{
"name": "Debug Mocha Tests",
"type": "node",
"request": "attach",
"port": 9229,
"continueOnAttach": true,
"skipFiles": [
"<node_internals>/**",
"**/node_modules/**",
"**/cds/lib/lazy.js",
"**/cds/lib/req/cds-context.js",
"**/odata-v4/okra/**",
]
},
], ],
"inputs": [ "inputs": [
{ {

11
.vscode/settings.json vendored
View File

@@ -10,16 +10,9 @@
"<node_internals>/**", "<node_internals>/**",
"**/node_modules/**", "**/node_modules/**",
"**/cds/lib/lazy.js", "**/cds/lib/lazy.js",
"**/cds/lib/req/cds-context.js", "**/cds/lib/req/cls.js",
"**/odata-v4/okra/**" "**/odata-v4/okra/**"
] ]
}, },
"eslint.probe": [ "mochaExplorer.parallel": true
"cds",
"csn",
"csv",
"csv (semicolon)",
"tsv",
"tab"
]
} }

View File

@@ -1,26 +1,19 @@
# Welcome to cap/samples # Welcome to cap/samples
Find here a collection of samples for the [SAP Cloud Application Programming Model](https://cap.cloud.sap) organized in a simplistic [monorepo setup](samples.md#all-in-one-monorepo). Find here a collection of samples for the [SAP Cloud Application Programming Model](https://cap.cloud.sap) organized in a simplistic [monorepo setup](samples.md#all-in-one-monorepo). &rarr; See [**Overview** of contained samples](samples.md)
[See **Overview** of contained samples](samples.md):
![](etc/samples.drawio.svg)
![](https://github.com/SAP-samples/cloud-cap-samples/workflows/CI/badge.svg) ![](https://github.com/SAP-samples/cloud-cap-samples/workflows/CI/badge.svg)
[![REUSE status](https://api.reuse.software/badge/github.com/SAP-samples/cloud-cap-samples)](https://api.reuse.software/info/github.com/SAP-samples/cloud-cap-samples) [![REUSE status](https://api.reuse.software/badge/github.com/SAP-samples/cloud-cap-samples)](https://api.reuse.software/info/github.com/SAP-samples/cloud-cap-samples)
### Preliminaries ### Preliminaries
1. Ensure you have the latest LTS version of Node.js installed (see [Getting Started](https://cap.cloud.sap/docs/get-started/)) 1. Install [**@sap/cds-dk**](https://cap.cloud.sap/docs/get-started/) globally:
2. Install [**@sap/cds-dk**](https://cap.cloud.sap/docs/get-started/) globally:
```sh ```sh
npm i -g @sap/cds-dk npm i -g @sap/cds-dk
``` ```
3. _Optional:_ [Use Visual Studio Code](https://cap.cloud.sap/docs/get-started/tools#vscode) 2. _Optional:_ [Use Visual Studio Code](https://cap.cloud.sap/docs/get-started/tools#vscode)
### Download ### Download
@@ -60,6 +53,24 @@ npx jest
``` ```
> While mocha is a bit smaller and faster, jest runs tests in parallel and isolation, which allows to run all tests. > While mocha is a bit smaller and faster, jest runs tests in parallel and isolation, which allows to run all tests.
### Serve `npm`
We've included a simple npm registry mock, which allows you to do an `npm install @capire/<package>` locally. Use it as follows:
1. Start the @capire registry:
```sh
npm run registry
```
> While running this will have `@capire:registry=http://localhost:4444` set with npmrc.
2. Install one of the @capire packages wherever you like, for example:
```sh
npm add @capire/common @capire/bookshop
```
## Code Tours ## Code Tours
Take one of the [guided tours](.tours) in VS Code through our CAP samples and learn which CAP features are showcased by the different parts of the repository. Just install the [CodeTour extension](https://marketplace.visualstudio.com/items?itemName=vsls-contrib.codetour) for VS Code. We'll add more code tours in the future. Stay tuned! Take one of the [guided tours](.tours) in VS Code through our CAP samples and learn which CAP features are showcased by the different parts of the repository. Just install the [CodeTour extension](https://marketplace.visualstudio.com/items?itemName=vsls-contrib.codetour) for VS Code. We'll add more code tours in the future. Stay tuned!

3752
bookshop/app/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,10 @@
{ {
"name": "approuter", "name": "approuter",
"dependencies": { "dependencies": {
"@sap/approuter": "^16.0.0" "@sap/approuter": "^10"
}, },
"engines": { "engines": {
"node": "^20.0.0" "node": "^16"
}, },
"scripts": { "scripts": {
"start": "node node_modules/@sap/approuter/approuter.js" "start": "node node_modules/@sap/approuter/approuter.js"

View File

@@ -10,7 +10,7 @@ const books = Vue.createApp ({
list: [], list: [],
book: undefined, book: undefined,
order: { quantity:1, succeeded:'', failed:'' }, order: { quantity:1, succeeded:'', failed:'' },
user: undefined user: {}
} }
}, },
@@ -40,50 +40,19 @@ const books = Vue.createApp ({
} catch (e) { } catch (e) {
books.order = { quantity, failed: e.response.data.error ? e.response.data.error.message : e.response.data } books.order = { quantity, failed: e.response.data.error ? e.response.data.error.message : e.response.data }
} }
}, }
async login() { }
}).mount("#app")
// initially fill list of books
books.fetch()
// show user info on request
document.addEventListener('keydown', async (event) => {
if (event.key === 'u') {
try { try {
const { data:user } = await axios.post('/user/login',{}) books.user = (await axios.get('/user/User')).data
if (user.id !== 'anonymous') books.user = user } catch (err) { }
} catch (err) { books.user = { id: err.message } }
},
async getUserInfo() {
try {
const { data:user } = await axios.get('/user/me')
if (user.id !== 'anonymous') books.user = user
} catch (err) { books.user = { id: err.message } }
},
} }
}).mount('#app')
books.getUserInfo()
books.fetch() // initially fill list of books
document.addEventListener('keydown', (event) => {
// hide user info on request
if (event.key === 'u') books.user = undefined
}) })
axios.interceptors.request.use(csrfToken)
function csrfToken (request) {
if (request.method === 'head' || request.method === 'get') return request
if ('csrfToken' in document) {
request.headers['x-csrf-token'] = document.csrfToken
return request
}
return fetchToken().then(token => {
document.csrfToken = token
request.headers['x-csrf-token'] = document.csrfToken
return request
}).catch(_ => {
document.csrfToken = null // set mark to not try again
return request
})
function fetchToken() {
return axios.get('/', { headers: { 'x-csrf-token': 'fetch' } })
.then(res => res.headers['x-csrf-token'])
}
}

View File

@@ -18,17 +18,11 @@
<body class="small-container", style="margin-top: 70px;"> <body class="small-container", style="margin-top: 70px;">
<div id='app'> <div id='app'>
<form class="user" @submit.prevent="login"> <div v-if="user.ID && user.ID !== 'anonymous'" class="user">
<div v-if="user"> <div>User: {{ user.ID }}</div>
<div v-if="user.tenant">Tenant: {{ user.tenant }}</div>
<div> User: {{ user.id }}</div>
<div>Locale: {{ user.locale }}</div> <div>Locale: {{ user.locale }}</div>
<div>Tenant: {{ user.tenant }}</div>
</div> </div>
<div v-else>
<input type="submit" value="Login" class="muted-button">
<!-- <a href="/user/login()">Login</a> -->
</div>
</form>
<h1> Capire Books </h1> <h1> Capire Books </h1>

View File

@@ -1,22 +1,19 @@
{ {
"welcomeFile": "app/index.html", "authenticationMethod": "route",
"routes": [ "routes": [
{ {
"source": "^/app/(.*)$", "source": "^/app/(.*)$",
"target": "$1", "target": "$1",
"localDir": ".", "localDir": ".",
"cacheControl": "no-cache, no-store, must-revalidate" "authenticationType": "xsuaa",
},
{
"source": "^/appconfig/",
"localDir": ".",
"cacheControl": "no-cache, no-store, must-revalidate" "cacheControl": "no-cache, no-store, must-revalidate"
}, },
{ {
"source": "^/(.*)$", "source": "^/(.*)$",
"target": "$1", "target": "$1",
"destination": "srv-api", "destination": "srv-api",
"csrfProtection": true "authenticationType": "xsuaa",
"csrfProtection": false
} }
] ]
} }

View File

@@ -1,5 +1,5 @@
ID,name,dateOfBirth,placeOfBirth,dateOfDeath,placeOfDeath ID;name;dateOfBirth;placeOfBirth;dateOfDeath;placeOfDeath
101,Emily Brontë,1818-07-30,"Thornton, Yorkshire",1848-12-19,"Haworth, Yorkshire" 101;Emily Brontë;1818-07-30;Thornton, Yorkshire;1848-12-19;Haworth, Yorkshire
107,Charlotte Brontë,1818-04-21,"Thornton, Yorkshire",1855-03-31,"Haworth, Yorkshire" 107;Charlotte Brontë;1818-04-21;Thornton, Yorkshire;1855-03-31;Haworth, Yorkshire
150,Edgar Allen Poe,1809-01-19,"Boston, Massachusetts",1849-10-07,"Baltimore, Maryland" 150;Edgar Allen Poe;1809-01-19;Boston, Massachusetts;1849-10-07;Baltimore, Maryland
170,Richard Carpenter,1929-08-14,"King’s Lynn, Norfolk",2012-02-26,"Hertfordshire, England" 170;Richard Carpenter;1929-08-14;King’s Lynn, Norfolk;2012-02-26;Hertfordshire, England
1 ID name dateOfBirth placeOfBirth dateOfDeath placeOfDeath
2 101 Emily Brontë 1818-07-30 Thornton, Yorkshire 1848-12-19 Haworth, Yorkshire
3 107 Charlotte Brontë 1818-04-21 Thornton, Yorkshire 1855-03-31 Haworth, Yorkshire
4 150 Edgar Allen Poe 1809-01-19 Boston, Massachusetts 1849-10-07 Baltimore, Maryland
5 170 Richard Carpenter 1929-08-14 King’s Lynn, Norfolk 2012-02-26 Hertfordshire, England

View File

@@ -1,6 +1,6 @@
ID,title,descr,author_ID,stock,price,currency_code,genre_ID ID;title;descr;author_ID;stock;price;currency_code;genre_ID
201,Wuthering Heights,"Wuthering Heights, Emily Brontë's only novel, was published in 1847 under the pseudonym ""Ellis Bell"". It was written between October 1845 and June 1846. Wuthering Heights and Anne Brontë's Agnes Grey were accepted by publisher Thomas Newby before the success of their sister Charlotte's novel Jane Eyre. After Emily's death, Charlotte edited the manuscript of Wuthering Heights and arranged for the edited version to be published as a posthumous second edition in 1850.",101,12,11.11,GBP,11 201;Wuthering Heights;"Wuthering Heights, Emily Brontë's only novel, was published in 1847 under the pseudonym ""Ellis Bell"". It was written between October 1845 and June 1846. Wuthering Heights and Anne Brontë's Agnes Grey were accepted by publisher Thomas Newby before the success of their sister Charlotte's novel Jane Eyre. After Emily's death, Charlotte edited the manuscript of Wuthering Heights and arranged for the edited version to be published as a posthumous second edition in 1850.";101;12;11.11;GBP;11
207,Jane Eyre,"Jane Eyre /ɛər/ (originally published as Jane Eyre: An Autobiography) is a novel by English writer Charlotte Brontë, published under the pen name ""Currer Bell"", on 16 October 1847, by Smith, Elder & Co. of London. The first American edition was published the following year by Harper & Brothers of New York. Primarily a bildungsroman, Jane Eyre follows the experiences of its eponymous heroine, including her growth to adulthood and her love for Mr. Rochester, the brooding master of Thornfield Hall. The novel revolutionised prose fiction in that the focus on Jane's moral and spiritual development is told through an intimate, first-person narrative, where actions and events are coloured by a psychological intensity. The book contains elements of social criticism, with a strong sense of Christian morality at its core and is considered by many to be ahead of its time because of Jane's individualistic character and how the novel approaches the topics of class, sexuality, religion and feminism.",107,11,12.34,GBP,11 207;Jane Eyre;"Jane Eyre /ɛər/ (originally published as Jane Eyre: An Autobiography) is a novel by English writer Charlotte Brontë, published under the pen name ""Currer Bell"", on 16 October 1847, by Smith, Elder & Co. of London. The first American edition was published the following year by Harper & Brothers of New York. Primarily a bildungsroman, Jane Eyre follows the experiences of its eponymous heroine, including her growth to adulthood and her love for Mr. Rochester, the brooding master of Thornfield Hall. The novel revolutionised prose fiction in that the focus on Jane's moral and spiritual development is told through an intimate, first-person narrative, where actions and events are coloured by a psychological intensity. The book contains elements of social criticism, with a strong sense of Christian morality at its core and is considered by many to be ahead of its time because of Jane's individualistic character and how the novel approaches the topics of class, sexuality, religion and feminism.";107;11;12.34;GBP;11
251,The Raven,"""The Raven"" is a narrative poem by American writer Edgar Allan Poe. First published in January 1845, the poem is often noted for its musicality, stylized language, and supernatural atmosphere. It tells of a talking raven's mysterious visit to a distraught lover, tracing the man's slow fall into madness. The lover, often identified as being a student, is lamenting the loss of his love, Lenore. Sitting on a bust of Pallas, the raven seems to further distress the protagonist with its constant repetition of the word ""Nevermore"". The poem makes use of folk, mythological, religious, and classical references.",150,333,13.13,USD,16 251;The Raven;"""The Raven"" is a narrative poem by American writer Edgar Allan Poe. First published in January 1845, the poem is often noted for its musicality, stylized language, and supernatural atmosphere. It tells of a talking raven's mysterious visit to a distraught lover, tracing the man's slow fall into madness. The lover, often identified as being a student, is lamenting the loss of his love, Lenore. Sitting on a bust of Pallas, the raven seems to further distress the protagonist with its constant repetition of the word ""Nevermore"". The poem makes use of folk, mythological, religious, and classical references.";150;333;13.13;USD;16
252,Eleonora,"""Eleonora"" is a short story by Edgar Allan Poe, first published in 1842 in Philadelphia in the literary annual The Gift. It is often regarded as somewhat autobiographical and has a relatively ""happy"" ending.",150,555,14,USD,15 252;Eleonora;"""Eleonora"" is a short story by Edgar Allan Poe, first published in 1842 in Philadelphia in the literary annual The Gift. It is often regarded as somewhat autobiographical and has a relatively ""happy"" ending.";150;555;14;USD;16
271,Catweazle,"Catweazle is a British fantasy television series, starring Geoffrey Bayldon in the title role, and created by Richard Carpenter for London Weekend Television. The first series, produced and directed by Quentin Lawrence, was screened in the UK on ITV in 1970. The second series, directed by David Reid and David Lane, was shown in 1971. Each series had thirteen episodes, most but not all written by Carpenter, who also published two books based on the scripts.",170,22,150,JPY,13 271;Catweazle;Catweazle is a British fantasy television series, starring Geoffrey Bayldon in the title role, and created by Richard Carpenter for London Weekend Television. The first series, produced and directed by Quentin Lawrence, was screened in the UK on ITV in 1970. The second series, directed by David Reid and David Lane, was shown in 1971. Each series had thirteen episodes, most but not all written by Carpenter, who also published two books based on the scripts.;170;22;150;JPY;13
1 ID title descr author_ID stock price currency_code genre_ID
2 201 Wuthering Heights Wuthering Heights, Emily Brontë's only novel, was published in 1847 under the pseudonym "Ellis Bell". It was written between October 1845 and June 1846. Wuthering Heights and Anne Brontë's Agnes Grey were accepted by publisher Thomas Newby before the success of their sister Charlotte's novel Jane Eyre. After Emily's death, Charlotte edited the manuscript of Wuthering Heights and arranged for the edited version to be published as a posthumous second edition in 1850. 101 12 11.11 GBP 11
3 207 Jane Eyre Jane Eyre /ɛər/ (originally published as Jane Eyre: An Autobiography) is a novel by English writer Charlotte Brontë, published under the pen name "Currer Bell", on 16 October 1847, by Smith, Elder & Co. of London. The first American edition was published the following year by Harper & Brothers of New York. Primarily a bildungsroman, Jane Eyre follows the experiences of its eponymous heroine, including her growth to adulthood and her love for Mr. Rochester, the brooding master of Thornfield Hall. The novel revolutionised prose fiction in that the focus on Jane's moral and spiritual development is told through an intimate, first-person narrative, where actions and events are coloured by a psychological intensity. The book contains elements of social criticism, with a strong sense of Christian morality at its core and is considered by many to be ahead of its time because of Jane's individualistic character and how the novel approaches the topics of class, sexuality, religion and feminism. 107 11 12.34 GBP 11
4 251 The Raven "The Raven" is a narrative poem by American writer Edgar Allan Poe. First published in January 1845, the poem is often noted for its musicality, stylized language, and supernatural atmosphere. It tells of a talking raven's mysterious visit to a distraught lover, tracing the man's slow fall into madness. The lover, often identified as being a student, is lamenting the loss of his love, Lenore. Sitting on a bust of Pallas, the raven seems to further distress the protagonist with its constant repetition of the word "Nevermore". The poem makes use of folk, mythological, religious, and classical references. 150 333 13.13 USD 16
5 252 Eleonora "Eleonora" is a short story by Edgar Allan Poe, first published in 1842 in Philadelphia in the literary annual The Gift. It is often regarded as somewhat autobiographical and has a relatively "happy" ending. 150 555 14 USD 15 16
6 271 Catweazle Catweazle is a British fantasy television series, starring Geoffrey Bayldon in the title role, and created by Richard Carpenter for London Weekend Television. The first series, produced and directed by Quentin Lawrence, was screened in the UK on ITV in 1970. The second series, directed by David Reid and David Lane, was shown in 1971. Each series had thirteen episodes, most but not all written by Carpenter, who also published two books based on the scripts. 170 22 150 JPY 13

View File

@@ -1,5 +0,0 @@
ID,locale,title,descr
201,de,Sturmhöhe,"Sturmhöhe (Originaltitel: Wuthering Heights) ist der einzige Roman der englischen Schriftstellerin Emily Brontë (1818–1848). Der 1847 unter dem Pseudonym Ellis Bell veröffentlichte Roman wurde vom viktorianischen Publikum weitgehend abgelehnt, heute gilt er als ein Klassiker der britischen Romanliteratur des 19. Jahrhunderts."
201,fr,Les Hauts de Hurlevent,"Les Hauts de Hurlevent (titre original : Wuthering Heights), parfois orthographié Les Hauts de Hurle-Vent, est l'unique roman d'Emily Brontë, publié pour la première fois en 1847 sous le pseudonyme d’Ellis Bell. Loin d'être un récit moralisateur, Emily Brontë achève néanmoins le roman dans une atmosphère sereine, suggérant le triomphe de la paix et du Bien sur la vengeance et le Mal."
207,de,Jane Eyre,"Jane Eyre. Eine Autobiographie (Originaltitel: Jane Eyre. An Autobiography), erstmals erschienen im Jahr 1847 unter dem Pseudonym Currer Bell, ist der erste veröffentlichte Roman der britischen Autorin Charlotte Brontë und ein Klassiker der viktorianischen Romanliteratur des 19. Jahrhunderts. Der Roman erzählt in Form einer Ich-Erzählung die Lebensgeschichte von Jane Eyre (ausgesprochen /ˌdʒeɪn ˈɛə/), die nach einer schweren Kindheit eine Stelle als Gouvernante annimmt und sich in ihren Arbeitgeber verliebt, jedoch immer wieder um ihre Freiheit und Selbstbestimmung kämpfen muss. Als klein, dünn, blass, stets schlicht dunkel gekleidet und mit strengem Mittelscheitel beschrieben, gilt die Heldin des Romans Jane Eyre nicht zuletzt aufgrund der Kino- und Fernsehversionen der melodramatischen Romanvorlage als die bekannteste englische Gouvernante der Literaturgeschichte"
252,de,Eleonora,"“Eleonora” ist eine Erzählung von Edgar Allan Poe. Sie wurde 1841 erstveröffentlicht. In ihr geht es um das Paradox der Treue in der Treulosigkeit."
1 ID locale title descr
2 201 de Sturmhöhe Sturmhöhe (Originaltitel: Wuthering Heights) ist der einzige Roman der englischen Schriftstellerin Emily Brontë (1818–1848). Der 1847 unter dem Pseudonym Ellis Bell veröffentlichte Roman wurde vom viktorianischen Publikum weitgehend abgelehnt, heute gilt er als ein Klassiker der britischen Romanliteratur des 19. Jahrhunderts.
3 201 fr Les Hauts de Hurlevent Les Hauts de Hurlevent (titre original : Wuthering Heights), parfois orthographié Les Hauts de Hurle-Vent, est l'unique roman d'Emily Brontë, publié pour la première fois en 1847 sous le pseudonyme d’Ellis Bell. Loin d'être un récit moralisateur, Emily Brontë achève néanmoins le roman dans une atmosphère sereine, suggérant le triomphe de la paix et du Bien sur la vengeance et le Mal.
4 207 de Jane Eyre Jane Eyre. Eine Autobiographie (Originaltitel: Jane Eyre. An Autobiography), erstmals erschienen im Jahr 1847 unter dem Pseudonym Currer Bell, ist der erste veröffentlichte Roman der britischen Autorin Charlotte Brontë und ein Klassiker der viktorianischen Romanliteratur des 19. Jahrhunderts. Der Roman erzählt in Form einer Ich-Erzählung die Lebensgeschichte von Jane Eyre (ausgesprochen /ˌdʒeɪn ˈɛə/), die nach einer schweren Kindheit eine Stelle als Gouvernante annimmt und sich in ihren Arbeitgeber verliebt, jedoch immer wieder um ihre Freiheit und Selbstbestimmung kämpfen muss. Als klein, dünn, blass, stets schlicht dunkel gekleidet und mit strengem Mittelscheitel beschrieben, gilt die Heldin des Romans Jane Eyre nicht zuletzt aufgrund der Kino- und Fernsehversionen der melodramatischen Romanvorlage als die bekannteste englische Gouvernante der Literaturgeschichte
5 252 de Eleonora “Eleonora” ist eine Erzählung von Edgar Allan Poe. Sie wurde 1841 erstveröffentlicht. In ihr geht es um das Paradox der Treue in der Treulosigkeit.

View File

@@ -0,0 +1,5 @@
ID;locale;title;descr
201;de;Sturmhöhe;Sturmhöhe (Originaltitel: Wuthering Heights) ist der einzige Roman der englischen Schriftstellerin Emily Brontë (1818–1848). Der 1847 unter dem Pseudonym Ellis Bell veröffentlichte Roman wurde vom viktorianischen Publikum weitgehend abgelehnt, heute gilt er als ein Klassiker der britischen Romanliteratur des 19. Jahrhunderts.
201;fr;Les Hauts de Hurlevent;Les Hauts de Hurlevent (titre original : Wuthering Heights), parfois orthographié Les Hauts de Hurle-Vent, est l'unique roman d'Emily Brontë, publié pour la première fois en 1847 sous le pseudonyme d’Ellis Bell. Loin d'être un récit moralisateur, Emily Brontë achève néanmoins le roman dans une atmosphère sereine, suggérant le triomphe de la paix et du Bien sur la vengeance et le Mal.
207;de;Jane Eyre;Jane Eyre. Eine Autobiographie (Originaltitel: Jane Eyre. An Autobiography), erstmals erschienen im Jahr 1847 unter dem Pseudonym Currer Bell, ist der erste veröffentlichte Roman der britischen Autorin Charlotte Brontë und ein Klassiker der viktorianischen Romanliteratur des 19. Jahrhunderts. Der Roman erzählt in Form einer Ich-Erzählung die Lebensgeschichte von Jane Eyre (ausgesprochen /ˌdʒeɪn ˈɛə/), die nach einer schweren Kindheit eine Stelle als Gouvernante annimmt und sich in ihren Arbeitgeber verliebt, jedoch immer wieder um ihre Freiheit und Selbstbestimmung kämpfen muss. Als klein, dünn, blass, stets schlicht dunkel gekleidet und mit strengem Mittelscheitel beschrieben, gilt die Heldin des Romans Jane Eyre nicht zuletzt aufgrund der Kino- und Fernsehversionen der melodramatischen Romanvorlage als die bekannteste englische Gouvernante der Literaturgeschichte
252;de;Eleonora;“Eleonora” ist eine Erzählung von Edgar Allan Poe. Sie wurde 1841 erstveröffentlicht. In ihr geht es um das Paradox der Treue in der Treulosigkeit.
1 ID locale title descr
2 201 de Sturmhöhe Sturmhöhe (Originaltitel: Wuthering Heights) ist der einzige Roman der englischen Schriftstellerin Emily Brontë (1818–1848). Der 1847 unter dem Pseudonym Ellis Bell veröffentlichte Roman wurde vom viktorianischen Publikum weitgehend abgelehnt, heute gilt er als ein Klassiker der britischen Romanliteratur des 19. Jahrhunderts.
3 201 fr Les Hauts de Hurlevent Les Hauts de Hurlevent (titre original : Wuthering Heights), parfois orthographié Les Hauts de Hurle-Vent, est l'unique roman d'Emily Brontë, publié pour la première fois en 1847 sous le pseudonyme d’Ellis Bell. Loin d'être un récit moralisateur, Emily Brontë achève néanmoins le roman dans une atmosphère sereine, suggérant le triomphe de la paix et du Bien sur la vengeance et le Mal.
4 207 de Jane Eyre Jane Eyre. Eine Autobiographie (Originaltitel: Jane Eyre. An Autobiography), erstmals erschienen im Jahr 1847 unter dem Pseudonym Currer Bell, ist der erste veröffentlichte Roman der britischen Autorin Charlotte Brontë und ein Klassiker der viktorianischen Romanliteratur des 19. Jahrhunderts. Der Roman erzählt in Form einer Ich-Erzählung die Lebensgeschichte von Jane Eyre (ausgesprochen /ˌdʒeɪn ˈɛə/), die nach einer schweren Kindheit eine Stelle als Gouvernante annimmt und sich in ihren Arbeitgeber verliebt, jedoch immer wieder um ihre Freiheit und Selbstbestimmung kämpfen muss. Als klein, dünn, blass, stets schlicht dunkel gekleidet und mit strengem Mittelscheitel beschrieben, gilt die Heldin des Romans Jane Eyre nicht zuletzt aufgrund der Kino- und Fernsehversionen der melodramatischen Romanvorlage als die bekannteste englische Gouvernante der Literaturgeschichte
5 252 de Eleonora “Eleonora” ist eine Erzählung von Edgar Allan Poe. Sie wurde 1841 erstveröffentlicht. In ihr geht es um das Paradox der Treue in der Treulosigkeit.

View File

@@ -1,16 +1,16 @@
ID,parent_ID,name ID;parent_ID;name
10,,Fiction 10;;Fiction
11,10,Drama 11;10;Drama
12,10,Poetry 12;10;Poetry
13,10,Fantasy 13;10;Fantasy
14,10,Science Fiction 14;10;Science Fiction
15,10,Romance 15;10;Romance
16,10,Mystery 16;10;Mystery
17,10,Thriller 17;10;Thriller
18,10,Dystopia 18;10;Dystopia
19,10,Fairy Tale 19;10;Fairy Tale
20,,Non-Fiction 20;;Non-Fiction
21,20,Biography 21;20;Biography
22,21,Autobiography 22;21;Autobiography
23,20,Essay 23;20;Essay
24,20,Speech 24;20;Speech
1 ID parent_ID name
2 10 Fiction
3 11 10 Drama
4 12 10 Poetry
5 13 10 Fantasy
6 14 10 Science Fiction
7 15 10 Romance
8 16 10 Mystery
9 17 10 Thriller
10 18 10 Dystopia
11 19 10 Fairy Tale
12 20 Non-Fiction
13 21 20 Biography
14 22 21 Autobiography
15 23 20 Essay
16 24 20 Speech

View File

@@ -4,11 +4,16 @@
* currencies, if not obtained through @capire/common. * currencies, if not obtained through @capire/common.
*/ */
// NOTE: We use cds.on('served') to delay the UPSERTs after the db init module.exports = async (db)=>{
// to run after all INSERTs from .csv files happened.
module.exports = cds.on('served', ()=> cds.run( const has_common = db.model.definitions['sap.common.Currencies'].elements.numcode
UPSERT.into ('sap.common.Currencies') .columns ( if (has_common) return
[ 'code', 'symbol', 'name' ]
const already_filled = await db.exists('sap.common.Currencies',{code:'EUR'})
if (already_filled) return
await INSERT.into ('sap.common.Currencies') .columns (
'code','symbol','name'
) .rows ( ) .rows (
[ 'EUR','€','Euro' ], [ 'EUR','€','Euro' ],
[ 'USD','$','US Dollar' ], [ 'USD','$','US Dollar' ],
@@ -16,4 +21,4 @@ module.exports = cds.on('served', ()=> cds.run(
[ 'ILS','₪','Shekel' ], [ 'ILS','₪','Shekel' ],
[ 'JPY','¥','Yen' ], [ 'JPY','¥','Yen' ],
) )
)) }

View File

@@ -3,9 +3,9 @@ namespace sap.capire.bookshop;
entity Books : managed { entity Books : managed {
key ID : Integer; key ID : Integer;
title : localized String(111) @mandatory; title : localized String(111);
descr : localized String(1111); descr : localized String(1111);
author : Association to Authors @mandatory; author : Association to Authors;
genre : Association to Genres; genre : Association to Genres;
stock : Integer; stock : Integer;
price : Decimal; price : Decimal;
@@ -15,7 +15,7 @@ entity Books : managed {
entity Authors : managed { entity Authors : managed {
key ID : Integer; key ID : Integer;
name : String(111) @mandatory; name : String(111);
dateOfBirth : Date; dateOfBirth : Date;
dateOfDeath : Date; dateOfDeath : Date;
placeOfBirth : String; placeOfBirth : String;

136
bookshop/db/src/.hdiconfig Normal file
View File

@@ -0,0 +1,136 @@
{
"file_suffixes": {
"csv": {
"plugin_name": "com.sap.hana.di.tabledata.source"
},
"hdbafllangprocedure": {
"plugin_name": "com.sap.hana.di.afllangprocedure"
},
"hdbanalyticprivilege": {
"plugin_name": "com.sap.hana.di.analyticprivilege"
},
"hdbcalculationview": {
"plugin_name": "com.sap.hana.di.calculationview"
},
"hdbcollection": {
"plugin_name": "com.sap.hana.di.collection"
},
"hdbconstraint": {
"plugin_name": "com.sap.hana.di.constraint"
},
"hdbdropcreatetable": {
"plugin_name": "com.sap.hana.di.dropcreatetable"
},
"hdbflowgraph": {
"plugin_name": "com.sap.hana.di.flowgraph"
},
"hdbfunction": {
"plugin_name": "com.sap.hana.di.function"
},
"hdbgraphworkspace": {
"plugin_name": "com.sap.hana.di.graphworkspace"
},
"hdbhadoopmrjob": {
"plugin_name": "com.sap.hana.di.virtualfunctionpackage.hadoop"
},
"hdbindex": {
"plugin_name": "com.sap.hana.di.index"
},
"hdblibrary": {
"plugin_name": "com.sap.hana.di.library"
},
"hdbmigrationtable": {
"plugin_name": "com.sap.hana.di.table.migration"
},
"hdbprocedure": {
"plugin_name": "com.sap.hana.di.procedure"
},
"hdbprojectionview": {
"plugin_name": "com.sap.hana.di.projectionview"
},
"hdbprojectionviewconfig": {
"plugin_name": "com.sap.hana.di.projectionview.config"
},
"hdbreptask": {
"plugin_name": "com.sap.hana.di.reptask"
},
"hdbresultcache": {
"plugin_name": "com.sap.hana.di.resultcache"
},
"hdbrole": {
"plugin_name": "com.sap.hana.di.role"
},
"hdbroleconfig": {
"plugin_name": "com.sap.hana.di.role.config"
},
"hdbsearchruleset": {
"plugin_name": "com.sap.hana.di.searchruleset"
},
"hdbsequence": {
"plugin_name": "com.sap.hana.di.sequence"
},
"hdbstatistics": {
"plugin_name": "com.sap.hana.di.statistics"
},
"hdbstructuredprivilege": {
"plugin_name": "com.sap.hana.di.structuredprivilege"
},
"hdbsynonym": {
"plugin_name": "com.sap.hana.di.synonym"
},
"hdbsynonymconfig": {
"plugin_name": "com.sap.hana.di.synonym.config"
},
"hdbsystemversioning": {
"plugin_name": "com.sap.hana.di.systemversioning"
},
"hdbtable": {
"plugin_name": "com.sap.hana.di.table"
},
"hdbtabledata": {
"plugin_name": "com.sap.hana.di.tabledata"
},
"hdbtabletype": {
"plugin_name": "com.sap.hana.di.tabletype"
},
"hdbtrigger": {
"plugin_name": "com.sap.hana.di.trigger"
},
"hdbview": {
"plugin_name": "com.sap.hana.di.view"
},
"hdbvirtualfunction": {
"plugin_name": "com.sap.hana.di.virtualfunction"
},
"hdbvirtualfunctionconfig": {
"plugin_name": "com.sap.hana.di.virtualfunction.config"
},
"hdbvirtualpackagehadoop": {
"plugin_name": "com.sap.hana.di.virtualpackage.hadoop"
},
"hdbvirtualpackagesparksql": {
"plugin_name": "com.sap.hana.di.virtualpackage.sparksql"
},
"hdbvirtualprocedure": {
"plugin_name": "com.sap.hana.di.virtualprocedure"
},
"hdbvirtualprocedureconfig": {
"plugin_name": "com.sap.hana.di.virtualprocedure.config"
},
"hdbvirtualtable": {
"plugin_name": "com.sap.hana.di.virtualtable"
},
"hdbvirtualtableconfig": {
"plugin_name": "com.sap.hana.di.virtualtable.config"
},
"properties": {
"plugin_name": "com.sap.hana.di.tabledata.properties"
},
"tags": {
"plugin_name": "com.sap.hana.di.tabledata.properties"
},
"txt": {
"plugin_name": "com.sap.hana.di.copyonly"
}
}
}

View File

@@ -0,0 +1,5 @@
[
"src/gen/**/*.hdbview",
"src/gen/**/*.hdbindex",
"src/gen/**/*.hdbconstraint"
]

View File

@@ -2,4 +2,3 @@ namespace sap.capire.bookshop; //> important for reflection
using from './db/schema'; using from './db/schema';
using from './srv/cat-service'; using from './srv/cat-service';
using from './srv/admin-service'; using from './srv/admin-service';
using from './srv/user-service';

98
bookshop/mta.yaml Normal file
View File

@@ -0,0 +1,98 @@
---
_schema-version: '3.1'
ID: capire.bookshop
version: 1.0.0
description: "A simple self-contained bookshop service."
parameters:
enable-parallel-deployments: true
build-parameters:
before-all:
- builder: custom
commands:
- npx -p @sap/cds-dk cds build --production
modules:
- name: bookshop-srv
type: nodejs
path: gen/srv
parameters:
buildpack: nodejs_buildpack
build-parameters:
builder: npm-ci
provides:
- name: srv-api # required by consumers of CAP services (e.g. approuter)
properties:
srv-url: ${default-url}
- name: mtx-api # potentially required by approuter
properties:
mtx-url: ${default-url}
requires:
- name: bookshop-auth
- name: bookshop-db
- name: bookshop-registry
properties:
SUBSCRIPTION_URL: ${protocol}://\${tenant_subdomain}-${default-uri}
SUBSCRIPTION_URL_REPLACEMENT_RULES: [ [ '-srv', '' ] ]
- name: bookshop
type: approuter.nodejs
path: app/ # from cds.env.folders. Consider also cds.env.build.target -> gen/app
parameters:
keep-existing-routes: true
disk-quota: 256M
memory: 256M
requires:
- name: srv-api
group: destinations
properties:
name: srv-api # must be used in xs-app.json as well
url: ~{srv-url}
forwardAuthToken: true
- name: bookshop-auth
- name: mtx-api
group: destinations
properties:
name: mtx-api # must be used in xs-app.json as well
url: ~{mtx-url}
properties:
TENANT_HOST_PATTERN: "^(.*)-${default-uri}"
resources:
- name: bookshop-auth
type: org.cloudfoundry.managed-service
parameters:
service: xsuaa
service-plan: application
path: ./xs-security.json
config:
xsappname: bookshop-${org}-${space}
tenant-mode: shared
- name: bookshop-db
type: org.cloudfoundry.managed-service
parameters:
service: service-manager
service-plan: container
properties:
hdi-service-name: ${service-name}
- name: bookshop-registry
type: org.cloudfoundry.managed-service
requires:
- name: mtx-api
parameters:
service: saas-registry
service-plan: application
config:
xsappname: bookshop-${org}-${space}
appName: bookshop-${org}-${space}
displayName: bookshop
description: A simple CAP project.
category: 'Category'
appUrls:
getDependencies: ~{mtx-api/mtx-url}/mtx/v1/provisioning/dependencies
onSubscription: ~{mtx-api/mtx-url}/mtx/v1/provisioning/tenant/{tenantId}
onSubscriptionAsync: false
onUnSubscriptionAsync: false
callbackTimeoutMillis: 300000

4025
bookshop/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -9,16 +9,41 @@
"index.cds", "index.cds",
"index.js" "index.js"
], ],
"devDependencies": {
"@cap-js/sqlite": "*"
},
"dependencies": { "dependencies": {
"@sap/cds": "^7", "@sap/cds": "^5",
"express": "^4.17.1" "@sap/cds-mtx": "^2",
"@sap/xssec": "^3",
"express": "^4.17.1",
"hdb": "^0.19.0",
"passport": "0.4.1"
}, },
"scripts": { "scripts": {
"genres": "cds serve test/genres.cds", "genres": "cds serve test/genres.cds",
"start": "cds-serve", "start": "cds run",
"watch": "cds watch" "watch": "cds watch"
},
"cds": {
"requires": {
"db": {
"kind": "sql"
},
"[production]": {
"db": {
"kind": "hana-mt"
},
"auth": {
"kind": "xsuaa"
},
"multitenancy": true,
"approuter": {
"kind": "cloudfoundry"
}
}
},
"mtx": {
"element-prefix": "Z_",
"namespace-blocklist": [],
"extension-allowlist": []
}
} }
} }

View File

@@ -20,12 +20,12 @@ npm run watch
| Links to capire | Sample files / folders | | Links to capire | Sample files / folders |
| --------------------------------------------------------------------------------------------------------- | ------------------------------------ | | --------------------------------------------------------------------------------------------------------- | ------------------------------------ |
| [Project Setup & Layouts](https://cap.cloud.sap/docs/get-started/jumpstart#project-structure) | [`./`](./) | | [Project Setup & Layouts](https://cap.cloud.sap/docs/get-started/projects#sharing-and-reusing-content) | [`./`](./) |
| [Domain Modeling with CDS](https://cap.cloud.sap/docs/guides/domain-modeling) | [`./db/schema.cds`](./db/schema.cds) | | [Domain Modeling with CDS](https://cap.cloud.sap/docs/guides/domain-models) | [`./db/schema.cds`](./db/schema.cds) |
| [Defining Services](https://cap.cloud.sap/docs/guides/providing-services#modeling-services) | [`./srv/*.cds`](./srv) | | [Defining Services](https://cap.cloud.sap/docs/guides/services#defining-services) | [`./srv/*.cds`](./srv) |
| [Single-purposed Services](https://cap.cloud.sap/docs/guides/providing-services#single-purposed-services) | [`./srv/*.cds`](./srv) | | [Single-purposed Services](https://cap.cloud.sap/docs/guides/services#single-purposed-services) | [`./srv/*.cds`](./srv) |
| [Providing & Consuming Providers](https://cap.cloud.sap/docs/guides/providing-services) | http://localhost:4004 | | [Providing & Consuming Providers](https://cap.cloud.sap/docs/guides/providing-services) | http://localhost:4004 |
| [Using Databases](https://cap.cloud.sap/docs/guides/databases) | [`./db/data/*.csv`](./db/data) | | [Using Databases](https://cap.cloud.sap/docs/guides/databases) | [`./db/data/*.csv`](./db/data) |
| [Adding Custom Logic](https://cap.cloud.sap/docs/guides/providing-services#adding-custom-logic) | [`./srv/*.js`](./srv) | | [Adding Custom Logic](https://cap.cloud.sap/docs/guides/service-impl) | [`./srv/*.js`](./srv) |
| Adding Tests | [`./test`](./test) | | Adding Tests | [`./test`](./test) |
| [Sharing for Reuse](https://cap.cloud.sap/docs/guides/extensibility/composition) | [`./index.cds`](./index.cds) | | [Sharing for Reuse](https://cap.cloud.sap/docs/guides/reuse-and-compose) | [`./index.cds`](./index.cds) |

View File

@@ -1,5 +1,5 @@
using { sap.capire.bookshop as my } from '../db/schema'; using { sap.capire.bookshop as my } from '../db/schema';
service AdminService @(requires:'admin', path:'/admin') { service AdminService @(requires:'admin') {
entity Books as projection on my.Books; entity Books as projection on my.Books;
entity Authors as projection on my.Authors; entity Authors as projection on my.Authors;
} }

View File

@@ -1,13 +1,12 @@
const cds = require('@sap/cds/lib') const cds = require('@sap/cds')
module.exports = class AdminService extends cds.ApplicationService { init(){ module.exports = cds.service.impl (function(){
this.before ('NEW','Authors', genid) this.before ('NEW','Authors', genid)
this.before ('NEW','Books', genid) this.before ('NEW','Books', genid)
return super.init() })
}}
/** Generate primary keys for target entity in request */ /** Generate primary keys for target entity in request */
async function genid (req) { async function genid (req) {
const {id} = await SELECT.one.from(req.target).columns('max(ID) as id') const {ID} = await cds.tx(req).run (SELECT.one.from(req.target).columns('max(ID) as ID'))
req.data.ID = id - id % 100 + 100 + 1 req.data.ID = ID - ID % 100 + 100 + 1
} }

View File

@@ -1,34 +1,28 @@
module.exports = class CatalogService extends cds.ApplicationService { init() { const cds = require('@sap/cds')
class CatalogService extends cds.ApplicationService { init(){
const { Books } = cds.entities ('sap.capire.bookshop') const { Books } = cds.entities ('sap.capire.bookshop')
const { ListOfBooks } = this.entities
// Add some discount for overstocked books
this.after('each', ListOfBooks, book => {
if (book.stock > 111) book.title += ` -- 11% discount!`
})
// Reduce stock of ordered books if available stock suffices // Reduce stock of ordered books if available stock suffices
this.on ('submitOrder', async req => { this.on ('submitOrder', async req => {
let { book:id, quantity } = req.data const {book,quantity} = req.data
let book = await SELECT.from (Books, id, b => b.stock) if (quantity < 1) return req.reject (400,`quantity has to be 1 or more`)
let b = await SELECT `stock` .from (Books,book)
// Validate input data if (!b) return req.error (404,`Book #${book} doesn't exist`)
if (!book) return req.error (404, `Book #${id} doesn't exist`) let {stock} = b
if (quantity < 1) return req.error (400, `quantity has to be 1 or more`) if (quantity > stock) return req.reject (409,`${quantity} exceeds stock for book #${book}`)
if (quantity > book.stock) return req.error (409, `${quantity} exceeds stock for book #${id}`) await UPDATE (Books,book) .with ({ stock: stock -= quantity })
// Reduce stock in database and return updated stock value
await UPDATE (Books, id) .with ({ stock: book.stock -= quantity })
return book
})
// Emit event when an order has been submitted
this.after('submitOrder', async (_,req) => {
let { book, quantity } = req.data
await this.emit ('OrderedBook', { book, quantity, buyer:req.user.id }) await this.emit ('OrderedBook', { book, quantity, buyer:req.user.id })
return { stock }
})
// Add some discount for overstocked books
this.after ('READ','ListOfBooks', each => {
if (each.stock > 111) each.title += ` -- 11% discount!`
}) })
// Delegate requests to the underlying generic service
return super.init() return super.init()
}} }}
module.exports = { CatalogService }

View File

@@ -1,15 +1,11 @@
/** @requires : 'authenticated-user'
* Exposes user information service UserService {
*/
service UserService @(path: '/user') { @odata.singleton
/** entity User {
* The current user ID : String;
*/
@odata.singleton entity me @cds.persistence.skip {
id : String; // user id
locale : String; locale : String;
tenant : String; tenant : String;
} }
action login() returns me;
} }

View File

@@ -1,9 +1,11 @@
const cds = require('@sap/cds') const cds = require('@sap/cds');
module.exports = class UserService extends cds.Service { init(){
this.on('READ', 'me', ({ tenant, user, locale }) => ({ id: user.id, locale, tenant })) module.exports = cds.service.impl((srv) => {
this.on('login', (req) => { srv.on('READ', 'User', ({ user }) => {
if (req.user._is_anonymous) return {
req._.res.set('WWW-Authenticate','Basic realm="Users"').sendStatus(401) ID: user.id,
else return this.read('me') locale: user.locale,
}) tenant: user.tenant,
}} };
});
});

View File

@@ -16,9 +16,9 @@ GET {{server}}/browse/$metadata
### ------------------------------------------------------------------------ ### ------------------------------------------------------------------------
# Browse Books as any user # Browse Books as any user
GET {{server}}/browse/ListOfBooks? GET {{server}}/browse/Books?
# &$select=title,stock # &$select=title,stock
&$expand=genre # &$expand=currency
# &sap-language=de # &sap-language=de
{{me}} {{me}}

70
bookshop/xs-security.json Normal file
View File

@@ -0,0 +1,70 @@
{
"scopes": [
{
"name": "$XSAPPNAME.admin",
"description": "admin"
},
{
"name": "$XSAPPNAME.MtxDiagnose",
"description": "Diagnose MTX"
},
{
"name": "$XSAPPNAME.mtcallback",
"description": "Subscribe to applications",
"grant-as-authority-to-apps": [
"$XSAPPNAME(application,sap-provisioning,tenant-onboarding)"
]
},
{
"name": "$XSAPPNAME.mtdeployment",
"description": "Deploy applications"
},
{
"name": "$XSAPPNAME.ExtendCDS",
"description": "Extend CDS applications"
},
{
"name": "$XSAPPNAME.ExtendCDSdelete",
"description": "Extend CDS applications with undeployments"
}
],
"attributes": [],
"role-templates": [
{
"name": "admin",
"description": "generated",
"scope-references": [
"$XSAPPNAME.admin"
],
"attribute-references": []
},
{
"name": "MultitenancyAdministrator",
"description": "Administrate multitenant applications",
"scope-references": [
"$XSAPPNAME.MtxDiagnose",
"$XSAPPNAME.mtdeployment",
"$XSAPPNAME.mtcallback"
]
},
{
"name": "ExtensionDeveloper",
"description": "Extend application",
"scope-references": [
"$XSAPPNAME.ExtendCDS"
]
},
{
"name": "ExtensionDeveloperUndeploy",
"description": "Undeploy extension",
"scope-references": [
"$XSAPPNAME.ExtendCDSdelete"
]
}
],
"authorities": [
"$XSAPPNAME.MtxDiagnose",
"$XSAPPNAME.mtdeployment",
"$XSAPPNAME.mtcallback"
]
}

View File

@@ -1,43 +0,0 @@
_schema-version: '3.1'
ID: capire.bookstore
version: 1.0.0
description: "A simple CAP project."
parameters:
enable-parallel-deployments: true
build-parameters:
before-all:
- builder: custom
commands:
- npm ci
- npx cds build --production
modules:
- name: bookstore-srv
type: nodejs
path: gen/srv
parameters:
buildpack: nodejs_buildpack
readiness-health-check-type: http
readiness-health-check-http-endpoint: /health
build-parameters:
builder: npm
provides:
- name: srv-api # required by consumers of CAP services (e.g. approuter)
properties:
srv-url: ${default-url}
requires:
- name: bookstore-destination
- name: bookstore-messaging
- name: samples-db
resources:
- name: bookstore-destination
type: org.cloudfoundry.managed-service
parameters:
service: destination
service-plan: lite
- name: bookstore-messaging
type: org.cloudfoundry.managed-service
parameters:
service: enterprise-messaging
service-plan: default
path: ./event-mesh.json

View File

@@ -7,7 +7,7 @@
"@capire/orders": "*", "@capire/orders": "*",
"@capire/common": "*", "@capire/common": "*",
"@capire/data-viewer": "*", "@capire/data-viewer": "*",
"@sap/cds": ">=5", "@sap/cds": "^5",
"express": "^4.17.1" "express": "^4.17.1"
}, },
"cds": { "cds": {
@@ -21,32 +21,14 @@
"model": "@capire/orders" "model": "@capire/orders"
}, },
"messaging": { "messaging": {
"[development]": { "[development]": { "kind": "file-based-messaging" },
"kind": "file-based-messaging" "[hybrid]": { "kind": "enterprise-messaging-shared" },
"[production]": { "kind": "enterprise-messaging" }
}, },
"[hybrid]": {
"kind": "enterprise-messaging-shared"
},
"[production]": {
"kind": "enterprise-messaging"
}
},
"db": { "kind": "sql" },
"[multimodule]": {
"db": { "db": {
"kind": "sqlite", "kind": "sql"
"impl": "@cap-js/sqlite",
"credentials": {
"url": "../db.sqlite"
}
}
} }
}, },
"log": { "log": { "service": true }
"service": true
}
},
"devDependencies": {
"@sap/cds-dk": "^7"
} }
} }

View File

@@ -13,3 +13,10 @@ cds.once('bootstrap',(app)=>{
// Add Swagger UI // Add Swagger UI
require('./srv/swagger-ui') require('./srv/swagger-ui')
// Returning cds.server
module.exports = cds.server
// For didactic reasons in capire
const { ReviewsService, OrdersService } = cds.requires
if (!ReviewsService.credentials && !OrdersService.credentials) cds.requires.messaging = false

View File

@@ -4,16 +4,16 @@
// respective reuse packages and services // respective reuse packages and services
// //
using { sap.capire.bookshop.Books } from '@capire/bookshop';
// //
// Extend Books with access to Reviews and average ratings // Extend Books with access to Reviews and average ratings
// //
using { sap.capire.bookshop.Books } from '@capire/bookshop';
using { ReviewsService.Reviews } from '@capire/reviews'; using { ReviewsService.Reviews } from '@capire/reviews';
extend Books with { extend Books with {
reviews : Composition of many Reviews on reviews.subject = $self.ID; reviews : Composition of many Reviews on reviews.subject = $self.ID;
rating : type of Reviews:rating; // average rating rating : Decimal;
numberOfReviews : Integer @title : '{i18n>NumberOfReviews}'; numberOfReviews : Integer;
} }
@@ -21,11 +21,18 @@ extend Books with {
// Extend Orders with Books as Products // Extend Orders with Books as Products
// //
using { sap.capire.orders.Orders } from '@capire/orders'; using { sap.capire.orders.Orders } from '@capire/orders';
extend Orders:Items with { extend Orders with {
extend Items with {
book : Association to Books on product.ID = book.ID book : Association to Books on product.ID = book.ID
} }
}
// Ensure models from all imported packages are loaded
// Add orders fiori app (in case of embedded orders service)
using from '@capire/orders/app/fiori'; using from '@capire/orders/app/fiori';
// Add data browser
using from '@capire/data-viewer'; using from '@capire/data-viewer';
// Incorporate pre-build extensions from...
using from '@capire/common'; using from '@capire/common';

View File

@@ -1,5 +1,5 @@
/* global Vue axios */ //> from vue.html /* global Vue axios */ //> from vue.html
const GET = (url) => axios.get('/odata/v4/-data'+url) const GET = (url) => axios.get('/-data'+url)
const storageGet = (key, def) => localStorage.getItem('data-viewer:'+key) || def const storageGet = (key, def) => localStorage.getItem('data-viewer:'+key) || def
const storageSet = (key, val) => localStorage.setItem('data-viewer:'+key, val) const storageSet = (key, val) => localStorage.setItem('data-viewer:'+key, val)
const columnKeysFirst = (c1, c2) => { const columnKeysFirst = (c1, c2) => {

View File

@@ -3,7 +3,7 @@
"version": "0.1.0", "version": "0.1.0",
"description": "A generic browser for data", "description": "A generic browser for data",
"dependencies": { "dependencies": {
"@sap/cds": ">=5.0.4" "@sap/cds": "^5.0.4"
}, },
"files": [ "files": [
"app", "app",

View File

@@ -2,12 +2,12 @@
* Exposes data + entity metadata * Exposes data + entity metadata
*/ */
@requires:'authenticated-user' @requires:'authenticated-user'
@odata service DataService @( path:'-data' ) { service DataService @( path:'-data' ) {
/** /**
* Metadata like name and columns/elements * Metadata like name and columns/elements
*/ */
entity Entities @cds.persistence.skip { entity Entities {
key name : String; key name : String;
columns: Composition of many { columns: Composition of many {
name : String; name : String;
@@ -19,8 +19,7 @@
/** /**
* The actual data, organized by column name * The actual data, organized by column name
*/ */
entity Data @cds.persistence.skip { entity Data {
key ID : String; // to be OData-compliant
record : array of { record : array of {
column : String; column : String;
data : String; data : String;

View File

@@ -36,11 +36,8 @@ class DataService extends cds.ApplicationService { init(){
const dataSource = findDataSource(dataSourceName, entityName) const dataSource = findDataSource(dataSourceName, entityName)
const res = await dataSource.run(query) const res = await dataSource.run(query)
return res.map((line) => { return res.map((line) => {
const record = Object.entries(line).map(([column, data]) => ({ column, data })) const record = Object.entries(line).map(([column, data]) => {return {column, data}})
return { return { record }
record,
ID: cds.utils.uuid() // just to be OData-compliant
}
}) })
}) })

View File

@@ -1,5 +0,0 @@
using from '@capire/bookstore';
using from '@capire/common';
using from '@capire/orders';
using from '@capire/reviews';
using from '@capire/fiori';

View File

@@ -1,13 +1,13 @@
<svg host="65bd71144e" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="357px" height="283px" viewBox="-0.5 -0.5 357 283" content="&lt;mxfile&gt;&lt;diagram id=&quot;QQJxv4aCTC7ZgE7HHOvM&quot; name=&quot;Page-1&quot;&gt;7VrZcqM4FP0av7q0L4+T9DIvU9VVeZhnFtlQwRYly7HTX98XgzBgOpNJG7eZGlKVwNECuudwdSSyoI+b41cXldlfNjXFgqD0uKCfFoQIIuF3BbzWACO6BtYuT2sInYGn/LupQRzQfZ6aXYPVkLe28HnZBxO73ZrE97DIOXvoV1vZIu0BZbQ2vceogKckKsxFtb/z1Gc1qsKwKvxPk6+zcGcsmvHFUfK8dna/be63IBQxXpdtotBRc9NdFqX20IHo5wV9dNb6+mxzfDRFFdd+zL78pLR9aGe2/j0NSN3gJSr2zbgXDCVRmTtTNSIi2pQL+rCNd9UfuC6g24fYwdnad5EAxNY+7zJbhgLoJT5XPg3Zv4YYw+jL6jQzx2htt1ClNC7fGG/cGf0WIAjOwyHLvXkqo6RqdgDhAZb5TQFXGE5X+dEELVXXu2fjkyri6FRYFI+2sO50c7paGZEkVSXv7LPplKRSxwi1JYF+0g6hG98m5C/GeXPsQE28vxoLD+9eoUpTSiSrm4QXQ9L6+nCWmW7kkXUUphosaoS9bns+8wsnDcXjdNNJ6Pa2an73fKvEjPMdK874zfimktyMb3Ztvp15yQ2k1rtnO+VGpWyMbUViKsRUbFOB+2xjfTO2+bXZTuxmA8TdPdkrXv1UuN36Dl4fYyIQp+NWImDhRbyBCMS1RWBdatwc3vjIqNVofheJMvFqKrKxEr+NbHlJ9pATs03/qOwwXCVFtNvlST/EvZBeBgiaN/GXp/LI+d71INRfTsdbgd3ZvUtML2FBp2vjew7FpMGd/yT4neDykeAGzJki8vlL39OPRby5wzebw/OeuSW4P3lzRPp91MNpmnWN9kVPYmD7+KCnOgoXPZ0k0A78XapQ81aFuHdVwKu75Iq2B+knAKrJslNKqfyYZIhmS4ZFewzXDQgvO6VC0Kn0pOetJzJzPTH+NtHX0hN7W7bX01PY4pmroNjMBcWHgppET3ygJzaZnIJlu5rl3e3Lssj/d73/wvXecp2LyUj+GFD4BJ2A4tD9M2hwys1oVtJC0miyRaoeEHjDbSk8sg85pwkgCLA7A4QsNI8pYOgp5CA7T+QpyGCqueIkMLLVOXdJibtSFAaqJVKcICw1ZIuw+dAuRzQoQSKGKFeSsY+aVIyXRGMmtSJIEBk+jrRrKw2yJpprwTAYmek86shm6qz0FL6Z3q1JxVpAClKnL8MaCc4HmUMuYaUDVhXWuUroD267EFClolhKLhHSlA1uwtmSUsGY4lphitRkarr6ruwqty7/T5ubCyczovl3f3Qjt3Q3974rO0gA/5hL6IjbEb/V3Ei9FFIpyBuKcKF0f5KozA3lEqYQLDimUvyCuaGQSSFzYMkoHtwFvI1gkGGwokwJWHBdKXvA5fkfQOrq5/+woZ9/AA==&lt;/diagram&gt;&lt;/mxfile&gt;" style="background-color: rgb(0, 68, 85);"> <svg host="65bd71144e" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="347px" height="279px" viewBox="-0.5 -0.5 347 279" content="&lt;mxfile&gt;&lt;diagram id=&quot;QQJxv4aCTC7ZgE7HHOvM&quot; name=&quot;Page-1&quot;&gt;7Vlbb+I4FP41vCLfL4/T7szuy0oj9WGfczEkasCRMYXur98TEufeqpoBCtUGCezv+Hq+z/bBWdDHzfFPF5XZ3zY1xYKg9LigfywI0QLBdwW81oDUrAbWLk9rCHXAU/6vqUEc0H2eml2D1ZC3tvB5OQQTu92axA+wyDl7GBZb2SIdAGW0NoNhVMBTEhVmUuyfPPVZjSoiO/wvk6+z0DMWurbEUfK8dna/bfpbEIq/VZ/avIlCW02/uyxK7aEH0e8L+uis9XVqc3w0ReXaodt+vGFtx+3M1n+kAqkrvETFvpn6gqEkKnNnqkpERJtyQR+28a76gXwBzT7EDlJr30cCEFv7vMtsGQzQStwVPk3ZvwY3w+zLKpmZY7S2WyhSGpdvjDeuQ38GCJzzcMhyb57KKKmqHUB7gGV+U0AOQ3KVH02QU5XfPRufVB5HJ2NRPNrCulPndLUyIkmqQt7ZZ9OzpFLHCLWWoADSTuHFOG+Ob7oct0TC+jAWBu9eoUhTgcimSrM2KG9UdeiUpht5ZD2RqQaLGm2v25Y7fiHRUDxPNz033avcuvwOuFaJmec6Vpzxq3FNrsg1OzfXzrzkBnbWm2c75UalbI5tRWIqxKXYppwPVza6Htv83GwndrMB4m6e7BWvPhVut76H18+cCMTpuZQIsFIDEbArikCcWwTWpcbdw4qPjFrN7u8iUSZeXY5s+WkrXk7JHnNitum3KhqGXFJEu12eDF08cOnUQVC98b882SPnB/mRq3+cntaxJg0x9ltuhbHavUvMYAeDXtbG96LTqfN7zuUzzg2YM0Xk85fhIOY83vTw0+YwvI5bCOuH5AayQxv16Jtq/SB70pIYtURHLdWTnrR0kkA78Q+pQn0xVYipKuhnqoJIueSKtk8Y4Gtn7lknRH9UMkTjJcOifSQbdqPEsmcVgl5KT/qL6Yncl54ofZ/oM+mJkvdlez49hRueLyModl+CYtcRFLueoPBUUL8X9O72ZVnk/8e978a9o2MvLOsrxL145s5yTOETNAKCRLfPoMEpN7P7khaSRpf7m4rQkEFBrsfgzDXkXZ8BQZL9QwC/4f+bOAXGYUXYvS8cVoRRXOAUmLnt/HKSEp+pKAxUS6Q4QVhqKtv7h7B/aAZKkIghypVk7FfDCqSWIComtSJIgIrpsBfFQNZEcy0YJpxfLqqYuU+9bz2F16i3EqdiTWELUlWoqDUS46tzSpYQm3KOGYJgQ5NflZOADQhLySVCmrJxJ3oJOyFjimuFKVJnUhNkuze4dfHuLTn9/h8=&lt;/diagram&gt;&lt;/mxfile&gt;" style="background-color: rgb(26, 26, 26);">
<defs/> <defs/>
<g> <g>
<path d="M 199 202 L 249 202 L 269 242 L 249 282 L 199 282 L 179 242 Z" fill="#ffe6cc" stroke="#d79b00" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/> <path d="M 192 148 L 242 148 L 262 188 L 242 228 L 192 228 L 172 188 Z" fill="#ffe6cc" stroke="#d79b00" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)"> <g transform="translate(-0.5 -0.5)">
<switch> <switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> <foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 242px; margin-left: 180px;"> <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 188px; margin-left: 173px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> <div style="box-sizing: border-box; font-size: 0; text-align: center; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
@capire/ @capire/
<br/> <br/>
<b> <b>
@@ -17,156 +17,18 @@
</div> </div>
</div> </div>
</foreignObject> </foreignObject>
<text x="224" y="246" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle"> <text x="217" y="192" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">
@capire/... @capire/...
</text> </text>
</switch> </switch>
</g> </g>
<path d="M 199 101 L 249 101 L 269 141 L 249 181 L 199 181 L 179 141 Z" fill="#f8cecc" stroke="#b85450" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/> <path d="M 192 48 L 242 48 L 262 88 L 242 128 L 192 128 L 172 88 Z" fill="#f8cecc" stroke="#b85450" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)"> <g transform="translate(-0.5 -0.5)">
<switch> <switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> <foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 141px; margin-left: 180px;"> <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 88px; margin-left: 173px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> <div style="box-sizing: border-box; font-size: 0; text-align: center; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
@capire/
<br/>
<b>
bookstore
</b>
</div>
</div>
</div>
</foreignObject>
<text x="224" y="145" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
@capire/...
</text>
</switch>
</g>
<path d="M 286 48 L 336 48 L 356 88 L 336 128 L 286 128 L 266 88 Z" fill="#d5e8d4" stroke="#82b366" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 88px; margin-left: 267px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
@capire/
<br/>
<b>
reviews
</b>
</div>
</div>
</div>
</foreignObject>
<text x="311" y="92" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
@capire/...
</text>
</switch>
</g>
<path d="M 286 153 L 336 153 L 356 193 L 336 233 L 286 233 L 266 193 Z" fill="#f5f5f5" stroke="#666666" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 193px; margin-left: 267px;">
<div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
@capire/
<br/>
<b>
common
</b>
</div>
</div>
</div>
</foreignObject>
<text x="311" y="197" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">
@capire/...
</text>
</switch>
</g>
<path d="M 111 153 L 161 153 L 181 193 L 161 233 L 111 233 L 91 193 Z" fill="#dae8fc" stroke="#6c8ebf" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 193px; margin-left: 92px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
@capire/
<br/>
<b>
orders
</b>
</div>
</div>
</div>
</foreignObject>
<text x="136" y="197" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
@capire/...
</text>
</switch>
</g>
<path d="M 276.35 172.29 L 266.36 166.32" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 260.57 162.86 L 270.6 163.61 L 266.36 166.32 L 265.98 171.34 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 170.74 172.47 L 181.53 166.1" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 187.34 162.66 L 181.88 171.12 L 181.53 166.1 L 177.3 163.37 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 224 202 L 224 189.99" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 224 183.24 L 228.5 192.24 L 224 189.99 L 219.5 192.24 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 276.51 109.01 L 266.17 115.31" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 260.4 118.82 L 265.75 110.3 L 266.17 115.31 L 270.43 117.98 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 111 48 L 161 48 L 181 88 L 161 128 L 111 128 L 91 88 Z" fill="#dae8fc" stroke="#6c8ebf" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 88px; margin-left: 92px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
@capire/
<br/>
<b>
suppliers
</b>
</div>
</div>
</div>
</foreignObject>
<text x="136" y="92" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
@capire/...
</text>
</switch>
</g>
<path d="M 21 101 L 71 101 L 91 141 L 71 181 L 21 181 L 1 141 Z" fill="#e1d5e7" stroke="#9673a6" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 141px; margin-left: 2px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
<b>
S/4
</b>
</div>
</div>
</div>
</foreignObject>
<text x="46" y="145" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
S/4
</text>
</switch>
</g>
<path d="M 80.76 120.53 L 93.49 113.03" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 99.31 109.61 L 93.84 118.05 L 93.49 113.03 L 89.27 110.3 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 80.91 161.17 L 93.31 168.33" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 99.15 171.71 L 89.11 171.1 L 93.31 168.33 L 93.61 163.31 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 170.59 108.83 L 181.72 115.53" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 187.5 119.02 L 177.47 118.23 L 181.72 115.53 L 182.11 110.52 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 199 1 L 249 1 L 269 41 L 249 81 L 199 81 L 179 41 Z" fill="#e1d5e7" stroke="#9673a6" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 41px; margin-left: 180px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
@capire/ @capire/
<br/> <br/>
<b> <b>
@@ -176,19 +38,134 @@
</div> </div>
</div> </div>
</foreignObject> </foreignObject>
<text x="224" y="45" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle"> <text x="217" y="92" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">
@capire/... @capire/...
</text> </text>
</switch> </switch>
</g> </g>
<path d="M 224 101 L 224 89.99" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/> <path d="M 276 98 L 326 98 L 346 138 L 326 178 L 276 178 L 256 138 Z" fill="#d5e8d4" stroke="#82b366" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 224 83.24 L 228.5 92.24 L 224 89.99 L 219.5 92.24 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/> <g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 138px; margin-left: 257px;">
<div style="box-sizing: border-box; font-size: 0; text-align: center; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
@capire/
<br/>
<b>
reviews
</b>
</div>
</div>
</div>
</foreignObject>
<text x="301" y="142" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">
@capire/...
</text>
</switch>
</g>
<path d="M 109 198 L 159 198 L 179 238 L 159 278 L 109 278 L 89 238 Z" fill="#f5f5f5" stroke="#666666" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 238px; margin-left: 90px;">
<div style="box-sizing: border-box; font-size: 0; text-align: center; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
@capire/
<br/>
<b>
common
</b>
</div>
</div>
</div>
</foreignObject>
<text x="134" y="242" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">
@capire/...
</text>
</switch>
</g>
<path d="M 108 98 L 158 98 L 178 138 L 158 178 L 108 178 L 88 138 Z" fill="#dae8fc" stroke="#6c8ebf" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 138px; margin-left: 89px;">
<div style="box-sizing: border-box; font-size: 0; text-align: center; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
@capire/
<br/>
<b>
orders
</b>
</div>
</div>
</div>
</foreignObject>
<text x="133" y="142" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">
@capire/...
</text>
</switch>
</g>
<path d="M 168.58 217.17 L 174.72 213.47" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 180.5 209.99 L 175.11 218.49 L 174.72 213.47 L 170.47 210.78 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 167.68 117.36 L 174.6 113.24" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 180.4 109.79 L 174.97 118.26 L 174.6 113.24 L 170.36 110.52 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 217 148 L 217 136.99" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 217 130.24 L 221.5 139.24 L 217 136.99 L 212.5 139.24 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 266.32 117.36 L 259.4 113.24" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 253.6 109.79 L 263.64 110.52 L 259.4 113.24 L 259.03 118.26 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 107 1 L 157 1 L 177 41 L 157 81 L 107 81 L 87 41 Z" fill="#dae8fc" stroke="#6c8ebf" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 41px; margin-left: 88px;">
<div style="box-sizing: border-box; font-size: 0; text-align: center; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
@capire/
<br/>
<b>
suppliers
</b>
</div>
</div>
</div>
</foreignObject>
<text x="132" y="45" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">
@capire/...
</text>
</switch>
</g>
<path d="M 21 53 L 71 53 L 91 93 L 71 133 L 21 133 L 1 93 Z" fill="#e1d5e7" stroke="#9673a6" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)">
<switch>
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 93px; margin-left: 2px;">
<div style="box-sizing: border-box; font-size: 0; text-align: center; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
<b>
S/4
</b>
</div>
</div>
</div>
</foreignObject>
<text x="46" y="97" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">
S/4
</text>
</switch>
</g>
<path d="M 80.55 72.11 L 89.76 66.54" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 95.53 63.05 L 90.16 71.56 L 89.76 66.54 L 85.5 63.86 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 81.75 111.49 L 89.27 115.38" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 95.26 118.48 L 85.2 118.34 L 89.27 115.38 L 89.33 110.35 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
<path d="M 167.25 60.49 L 173.88 64.16" fill="none" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/>
<path d="M 179.79 67.42 L 169.74 67.01 L 173.88 64.16 L 174.09 59.13 Z" fill="#ffffff" stroke="#ffffff" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/>
</g> </g>
<switch> <switch>
<g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/> <g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/>
<a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"> <a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank">
<text text-anchor="middle" font-size="10px" x="50%" y="100%"> <text text-anchor="middle" font-size="10px" x="50%" y="100%">
Text is not SVG - cannot display Viewer does not support full SVG 1.1
</text> </text>
</a> </a>
</switch> </switch>

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -1,13 +1,13 @@
<svg host="65bd71144e" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="569px" height="428px" viewBox="-0.5 -0.5 569 428" content="&lt;mxfile&gt;&lt;diagram id=&quot;QQJxv4aCTC7ZgE7HHOvM&quot; name=&quot;Page-1&quot;&gt;7Vpbc9soFP41fqxHCF0f7VyanWl2O3W3fcYSltkg4UH41l+/EIEtGdl1HTlRM508RBzDMfB9h/NxrAG8yTcfOVrMH1mK6cB10s0A3g5cFwAQy3/Ksq0sgQcrQ8ZJWpmcvWFCfmA90liXJMWltlUmwRgVZNE0JqwocCIaNsQ5Wze7zRhNG4YFynBjGsowSRDFVrfvJBXzyhq54d7+gEk2N98MAr3gHJnO2nE5Rylb10zwbgBvOGOieso3N5iqzWvuy/2RT3cT47gQ5wxwqwErRJd6bRPZ2ZOmh9HfIz1HsTUL52xZpFiNdQZwvJ4TgScLlKhP1xJqaZuLnMoWkI8Jy0miu5ZPWCRz3fiPZNmzR082ZqwQ9ygnVHHhAdMVFiRBaojg7Gm3v3JnxoiSrJDPvNra8Qpz1ZeOtF0wNYNSTogUmWz7Oy83jDL+vAQYuepPzZRx8kN+OaJmjtXALxq4UE9uopcPdLvmy7tVf9Jub7tGQk0Rb2omDcNHzHIs+FZ20Z9+AIHmhA4KYDiy3lMMxH5lm9fpZVBEmtbZzvkeefmgwW8nArSIMF6WpMBlOVDzCKja8CmXT5l6+oy4KDA/QRDwSgSpwTGNfM93WqkzI5TWes6iBCdJV8CBaOg3ofNjGzoDZx0633k5cp6F3A4ug9ZfRSIPTLlC13nMclFDVDrf9bJRvtsIXJSEFXLEaLHo6XFA8eyc0yA+eRpcMbLPiGvohTY5oBe/nB2+xQ5DhrJfwRskEZ7OzgneFOFo1lHwun7YBCd27cgFLYduF5EbtETuASS4SEdKsMhWSlDOivTrnEh2j+UH94QaMGRLqyQQNGG6KgClkGnAzO/uS46KrbHqyTmmracXn4KtZEueGIml90KOzbDZ88qEU6POjmBbx84EH8cUCbJqCrg28LS7z4w8n5cmhr0GTTzgmyPf+Kgmr4fVFdeBp92BfdxVtWbL1TOddss8i2GhxbCbZSmkB96z6E/DeOqcl7pnOOgqdcdNKFqD/1ppO7KgmSyTROqte5QIdhKf3197t0htS46/pfZ2g8BmQhwMWxKB63SgvmOLDN8Zf5oxdRy2ym8ZwEqV9SmEe6O+oQNfL4xNSaIG3V2+oGyL25H7SnJczjEWf8BrBy9qibyrgQcs8E4psCllyZNceYokggaovRBzmkLMvVSIdZkL65IK2ooqfENF1RTePggv1VM/cdSdmjKatEaXR5mwUYZ7pqb6cZeCDrBD+Vp3KWAXsE6Fcl8vU7Vr0nmXq7Mi3+9V5LshbPIEwgtD3/yOcMxRh6FvV9kmmK/IEX2m1FvfqqO9uGK9rjazi1/vOL3HdpAb1r5FlINDYQeDSxN8fOAq8A9m02Gc/1pNrmAFPkWS3uQPtsDFpdnDsKgnpTgQuEMnigNVlAO+E0O3QQ43iC/jGQjg0AMODEPoR17sBFHTL7hecrHLdCaBtOSW0QoRiqaEErH9k2HsDPOqF0i7iveOM4ypdTRSzBsKSWDlGO/CHAMc77SjDoPdrvWNUfIkcZdGrSnt66Qpt35CU0w/s5II9ausZBQTguUKavMiiVPnl1Or3CYSWnmkNDh1pIpr0UZ6X6iZ5JtMvdEzzCWPl4thjrj6lyw53Y758zFzorT0wuOGM4H0qp0TZakZJYtvenkdnC4fwMHvNb7Tcr5AYJ8vbgfni2tXF/9V9QZp+kbw+l3xZHdqXZcn5sTrmCfRYSHzdXliFzLr727cIoHeE1V26viqVNkp646p4nrxGzLFrmFazDDQJFtKpJrk8OdSclrpzk/TnUHmtOxZjf6zFNIN1vayEjfuMIaxH4cQ+B4MXAgOATx+yzn/ptQBViBqYgXi0MYqtqEC/i9DJZv79z4rYbF/exbe/Q8=&lt;/diagram&gt;&lt;/mxfile&gt;"> <svg host="65bd71144e" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="569px" height="428px" viewBox="-0.5 -0.5 569 428" content="&lt;mxfile&gt;&lt;diagram id=&quot;QQJxv4aCTC7ZgE7HHOvM&quot; name=&quot;Page-1&quot;&gt;7Vpdd9o4EP01PJZjWf7SY8jHds9pd3tKt30WtjDayBZHFknor18ployNDCXEELbtyUPsQRpLvndmrgZG8Lp4+kPg5eIjzwgb+V72NII3I98HMPLUP21Z15YYBbUhFzQzgzaGKf1OjNHMy1c0I1VnoOScSbrsGlNeliSVHRsWgj92h8056z51iXPzRG9jmKaYEWfYN5rJRW1N/Hhjf09ovrBPBhGqPymwHWwcVwuc8ceWCd6O4LXgXNZXxdM1Yfrl2fdSz7vb8WmzMEFKecgEv57wgNnK7G2qBis0vPdXf12ZNcq13bjgqzIjeq43gpPHBZVkusSp/vRRQa1sC1kwdQfUZcoLmpqh1T2R6cLc/Evz/NljoG7mvJR3uKBMc+E9YQ9E0hTrKVLw++b9qjczwYzmpboW9audPBChx7IrY5dcr6BSC6Jlru7Dxss1Z1w8bwEmvv7TK+WCflcPx8yusZ742QAXm8VNzfaBuW/5Cm70n7Kbt6jWQ552IgEafFVgEF4QKdZqiJnwDtioMEEBLEceNxQDKKxtiza9LIrY0DpvnG+QVxcG/H4iQIcIk1VFS1JVI72OiOkXPhPqKtdXn7CQJRF7CALORJAWHLMkDEKvlzpzylhr5DxJSZoOBRxIxmEXuhC50Fk429CF3uuRCxzkGrgsWn+WqUqYaju+9zEvZAtR5bwZ5aJ8+yRJWVFeqhlXy+WFpgNG5odkA7Q3G5wwsg+IaxjELjlggF7PjtBhhyVDdVnBG6UJmc0PCd4Mk2Q+UPD6YdwFB/lu5IKepDtE5EY9kbsFCSmzKy1Y1F1GccHL7MuCKnZP1Ad3lFkw1J1RSSDqwnRSACqpyoBd3+3nApdrazWL8+y9WR5qYCOZ1Vi7QFMvgq9EakeZl6Oc5cSC0I9tGzsbfIIwLOlD95F94Bl3nzh9zpc2hoMOTQIQ2pRvfdRrNdPaimvLU5Owd7uqt+i4eqZTs82DGBY7DLteVVJ5EBcW/VmMZt5hpXtOoqFKN+pC0Rv8pyrbiQPNdJWmSm/d4VTyvfj8/7V3j9R25Phbam8/ilwmoGjcUwh8bwD1jRwyfOPifs519uuV3yqAtSq7pBC+GPUNPXi+MLYtiRZ0t8WS8TXpR+4LLUi1IET+Bq8fvKQn8k4GHniRApsxnt6rnWdYIWiB2ggxryvE/GOF2NG18KWSCrqKKj6fouoK7xDEx+qpHzgaTk1ZCdqiy0dVsHFOLkxNXcZZCnrADeVTnaWA28DaF8qXephqHZMOO1wdF/nhW0a+H8MuTyA8MvQB2u9owNB3u2xTIh7oDn2m1duldUcv4oh1Xm3mNr9+pfKO3CCvaXyWKAfbwg5GxxZ4tOUqCrdWM2Ccv6wnV/KS7CPJxdQPviTlYNXDJsO3acWByB97CYp0Uw6EHoJ+hxx+hI7jGYjgOAAejGMYJgHyoqTrF5yuuLhtOltAemrL1QOmDM8oo3L9u8K4FeasB0i3i/crVRjb/OiUmPMJSeDUmODIGgO8YL+jAYPd7fVNcHqvcFdGoynd46Rtt37AM8I+8YpK/a2sYhSXkhcaavtDEq/NL6/VuU0VkiqldDi1o4vr0EZ5X+qVFE+5/kXPuFA8Xi3HBRb6X7oSbD0Rz2lmT2vplelGcInNrr09bak5o8uvZnsDZJd3YOv7mtDryS8QuPnFHyC/+G538R/db1Cmr5Q8/lQ8abLWaXliM97APEm2G5nn5YnbyGz/duMGS/wzUaVRxyelSqOsB6aKH6A3ZIrbw3SYYaFJ14wqNSngj6XkrNadH2aNQdW0/FmN/r2Syg0x9qoWN/4YQRSiGIIwgJEPwTaAu085h5+UBsAKJF2sAIpdrJALFQhfDJW63fzusxYWm1/Pwtv/AA==&lt;/diagram&gt;&lt;/mxfile&gt;">
<defs/> <defs/>
<g> <g>
<rect x="1" y="1" width="195" height="122" fill="rgb(255, 255, 255)" stroke="#828282" stroke-width="2" pointer-events="all"/> <rect x="1" y="1" width="195" height="122" fill="#ffffff" stroke="#828282" stroke-width="2" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)rotate(-90 11 13)"> <g transform="translate(-0.5 -0.5)rotate(-90 11 13)">
<switch> <switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> <foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-end; width: 107px; height: 1px; padding-top: 13px; margin-left: -96px;"> <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-end; width: 107px; height: 1px; padding-top: 13px; margin-left: -96px;">
<div data-drawio-colors="color: #4D4D4D; " style="box-sizing: border-box; font-size: 0px; text-align: right;"> <div style="box-sizing: border-box; font-size: 0; text-align: right; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(77, 77, 77); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; overflow-wrap: normal;"> <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #4D4D4D; line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; word-wrap: normal; ">
S/4 HANA S/4 HANA
</div> </div>
</div> </div>
@@ -21,10 +21,10 @@
<rect x="42.5" y="40" width="120" height="50" rx="7.5" ry="7.5" fill="#f8cecc" stroke="#b85450" stroke-width="2" pointer-events="all"/> <rect x="42.5" y="40" width="120" height="50" rx="7.5" ry="7.5" fill="#f8cecc" stroke="#b85450" stroke-width="2" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)"> <g transform="translate(-0.5 -0.5)">
<switch> <switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> <foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 65px; margin-left: 44px;"> <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 65px; margin-left: 44px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> <div style="box-sizing: border-box; font-size: 0; text-align: center; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
Business Business
<br/> <br/>
Partner Partner
@@ -32,18 +32,18 @@
</div> </div>
</div> </div>
</foreignObject> </foreignObject>
<text x="103" y="69" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle"> <text x="103" y="69" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">
Business... Business...
</text> </text>
</switch> </switch>
</g> </g>
<rect x="221" y="1" width="347" height="349" fill="rgb(255, 255, 255)" stroke="#828282" stroke-width="2" pointer-events="all"/> <rect x="221" y="1" width="347" height="349" fill="#ffffff" stroke="#828282" stroke-width="2" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)"> <g transform="translate(-0.5 -0.5)">
<switch> <switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> <foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-start; width: 331px; height: 1px; padding-top: 15px; margin-left: 230px;"> <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-start; width: 331px; height: 1px; padding-top: 15px; margin-left: 230px;">
<div data-drawio-colors="color: #4D4D4D; " style="box-sizing: border-box; font-size: 0px; text-align: left;"> <div style="box-sizing: border-box; font-size: 0; text-align: left; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(77, 77, 77); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #4D4D4D; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
<b> <b>
Incident Mgmt Incident Mgmt
</b> </b>
@@ -61,16 +61,16 @@
<rect x="418" y="73" width="115" height="50" rx="7.5" ry="7.5" fill="#dae8fc" stroke="#6c8ebf" stroke-width="2" pointer-events="all"/> <rect x="418" y="73" width="115" height="50" rx="7.5" ry="7.5" fill="#dae8fc" stroke="#6c8ebf" stroke-width="2" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)"> <g transform="translate(-0.5 -0.5)">
<switch> <switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> <foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 113px; height: 1px; padding-top: 98px; margin-left: 419px;"> <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 113px; height: 1px; padding-top: 98px; margin-left: 419px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> <div style="box-sizing: border-box; font-size: 0; text-align: center; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
Incidents Incidents
</div> </div>
</div> </div>
</div> </div>
</foreignObject> </foreignObject>
<text x="476" y="102" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle"> <text x="476" y="102" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">
Incidents Incidents
</text> </text>
</switch> </switch>
@@ -81,27 +81,27 @@
<rect x="255" y="73" width="120" height="50" rx="7.5" ry="7.5" fill="#ffe6cc" stroke="#d79b00" stroke-width="2" pointer-events="all"/> <rect x="255" y="73" width="120" height="50" rx="7.5" ry="7.5" fill="#ffe6cc" stroke="#d79b00" stroke-width="2" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)"> <g transform="translate(-0.5 -0.5)">
<switch> <switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> <foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 98px; margin-left: 256px;"> <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 98px; margin-left: 256px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> <div style="box-sizing: border-box; font-size: 0; text-align: center; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
Customers Customers
</div> </div>
</div> </div>
</div> </div>
</foreignObject> </foreignObject>
<text x="315" y="102" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle"> <text x="315" y="102" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">
Customers Customers
</text> </text>
</switch> </switch>
</g> </g>
<rect x="1" y="147" width="196.5" height="202" fill="rgb(255, 255, 255)" stroke="#828282" stroke-width="2" pointer-events="all"/> <rect x="1" y="147" width="196.5" height="202" fill="#ffffff" stroke="#828282" stroke-width="2" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)rotate(-90 11 159)"> <g transform="translate(-0.5 -0.5)rotate(-90 11 159)">
<switch> <switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> <foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-end; width: 187px; height: 1px; padding-top: 159px; margin-left: -176px;"> <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-end; width: 187px; height: 1px; padding-top: 159px; margin-left: -176px;">
<div data-drawio-colors="color: #4D4D4D; " style="box-sizing: border-box; font-size: 0px; text-align: right;"> <div style="box-sizing: border-box; font-size: 0; text-align: right; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(77, 77, 77); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; overflow-wrap: normal;"> <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #4D4D4D; line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; word-wrap: normal; ">
SuccessFactors SuccessFactors
</div> </div>
</div> </div>
@@ -115,10 +115,10 @@
<rect x="42.5" y="184" width="120" height="50" rx="7.5" ry="7.5" fill="#f8cecc" stroke="#b85450" stroke-width="2" pointer-events="all"/> <rect x="42.5" y="184" width="120" height="50" rx="7.5" ry="7.5" fill="#f8cecc" stroke="#b85450" stroke-width="2" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)"> <g transform="translate(-0.5 -0.5)">
<switch> <switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> <foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 209px; margin-left: 44px;"> <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 209px; margin-left: 44px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> <div style="box-sizing: border-box; font-size: 0; text-align: center; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
Workforce Workforce
<br/> <br/>
Person Person
@@ -126,7 +126,7 @@
</div> </div>
</div> </div>
</foreignObject> </foreignObject>
<text x="103" y="213" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle"> <text x="103" y="213" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">
Workforce... Workforce...
</text> </text>
</switch> </switch>
@@ -134,10 +134,10 @@
<rect x="42.5" y="267" width="120" height="50" rx="7.5" ry="7.5" fill="#f8cecc" stroke="#b85450" stroke-width="2" pointer-events="all"/> <rect x="42.5" y="267" width="120" height="50" rx="7.5" ry="7.5" fill="#f8cecc" stroke="#b85450" stroke-width="2" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)"> <g transform="translate(-0.5 -0.5)">
<switch> <switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> <foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 292px; margin-left: 44px;"> <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 292px; margin-left: 44px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> <div style="box-sizing: border-box; font-size: 0; text-align: center; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
Employee Employee
<br/> <br/>
Timesheet Timesheet
@@ -145,7 +145,7 @@
</div> </div>
</div> </div>
</foreignObject> </foreignObject>
<text x="103" y="296" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle"> <text x="103" y="296" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">
Employee... Employee...
</text> </text>
</switch> </switch>
@@ -155,16 +155,16 @@
<rect x="418" y="182" width="115" height="50" rx="7.5" ry="7.5" fill="#dae8fc" stroke="#6c8ebf" stroke-width="2" pointer-events="all"/> <rect x="418" y="182" width="115" height="50" rx="7.5" ry="7.5" fill="#dae8fc" stroke="#6c8ebf" stroke-width="2" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)"> <g transform="translate(-0.5 -0.5)">
<switch> <switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> <foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 113px; height: 1px; padding-top: 207px; margin-left: 419px;"> <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 113px; height: 1px; padding-top: 207px; margin-left: 419px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> <div style="box-sizing: border-box; font-size: 0; text-align: center; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
Messages Messages
</div> </div>
</div> </div>
</div> </div>
</foreignObject> </foreignObject>
<text x="476" y="211" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle"> <text x="476" y="211" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">
Messages Messages
</text> </text>
</switch> </switch>
@@ -175,10 +175,10 @@
<rect x="255" y="184" width="120" height="50" rx="7.5" ry="7.5" fill="#ffe6cc" stroke="#d79b00" stroke-width="2" pointer-events="all"/> <rect x="255" y="184" width="120" height="50" rx="7.5" ry="7.5" fill="#ffe6cc" stroke="#d79b00" stroke-width="2" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)"> <g transform="translate(-0.5 -0.5)">
<switch> <switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> <foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 209px; margin-left: 256px;"> <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 209px; margin-left: 256px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> <div style="box-sizing: border-box; font-size: 0; text-align: center; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
Service Service
<br/> <br/>
Worker Worker
@@ -186,7 +186,7 @@
</div> </div>
</div> </div>
</foreignObject> </foreignObject>
<text x="315" y="213" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle"> <text x="315" y="213" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">
Service... Service...
</text> </text>
</switch> </switch>
@@ -198,10 +198,10 @@
<rect x="255" y="267" width="120" height="50" rx="7.5" ry="7.5" fill="#ffe6cc" stroke="#d79b00" stroke-width="2" pointer-events="all"/> <rect x="255" y="267" width="120" height="50" rx="7.5" ry="7.5" fill="#ffe6cc" stroke="#d79b00" stroke-width="2" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)"> <g transform="translate(-0.5 -0.5)">
<switch> <switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> <foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 292px; margin-left: 256px;"> <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 292px; margin-left: 256px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> <div style="box-sizing: border-box; font-size: 0; text-align: center; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"> <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">
Worker Worker
<br/> <br/>
Availability Availability
@@ -209,7 +209,7 @@
</div> </div>
</div> </div>
</foreignObject> </foreignObject>
<text x="315" y="296" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle"> <text x="315" y="296" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">
Worker... Worker...
</text> </text>
</switch> </switch>
@@ -219,16 +219,16 @@
<path d="M 37 407 C 37 401.48 41.48 397 47 397 L 92.5 397 C 98.02 397 102.5 392.52 102.5 387 C 102.5 392.52 106.98 397 112.5 397 L 158 397 C 163.52 397 168 401.48 168 407" fill="none" stroke="#b85450" stroke-width="2" stroke-miterlimit="10" transform="translate(0,397)scale(1,-1)translate(0,-397)" pointer-events="all"/> <path d="M 37 407 C 37 401.48 41.48 397 47 397 L 92.5 397 C 98.02 397 102.5 392.52 102.5 387 C 102.5 392.52 106.98 397 112.5 397 L 158 397 C 163.52 397 168 401.48 168 407" fill="none" stroke="#b85450" stroke-width="2" stroke-miterlimit="10" transform="translate(0,397)scale(1,-1)translate(0,-397)" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)"> <g transform="translate(-0.5 -0.5)">
<switch> <switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> <foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 414px; margin-left: 103px;"> <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 414px; margin-left: 103px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> <div style="box-sizing: border-box; font-size: 0; text-align: center; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;"> <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: nowrap; ">
Backend Services Backend Services
</div> </div>
</div> </div>
</div> </div>
</foreignObject> </foreignObject>
<text x="103" y="426" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle"> <text x="103" y="426" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">
Backend Services Backend Services
</text> </text>
</switch> </switch>
@@ -236,16 +236,16 @@
<path d="M 249.5 407 C 249.5 401.48 253.98 397 259.5 397 L 305 397 C 310.52 397 315 392.52 315 387 C 315 392.52 319.48 397 325 397 L 370.5 397 C 376.02 397 380.5 401.48 380.5 407" fill="none" stroke="#d79b00" stroke-width="2" stroke-miterlimit="10" transform="translate(0,397)scale(1,-1)translate(0,-397)" pointer-events="all"/> <path d="M 249.5 407 C 249.5 401.48 253.98 397 259.5 397 L 305 397 C 310.52 397 315 392.52 315 387 C 315 392.52 319.48 397 325 397 L 370.5 397 C 376.02 397 380.5 401.48 380.5 407" fill="none" stroke="#d79b00" stroke-width="2" stroke-miterlimit="10" transform="translate(0,397)scale(1,-1)translate(0,-397)" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)"> <g transform="translate(-0.5 -0.5)">
<switch> <switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> <foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 414px; margin-left: 315px;"> <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 414px; margin-left: 315px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> <div style="box-sizing: border-box; font-size: 0; text-align: center; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;"> <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: nowrap; ">
Usage Views Usage Views
</div> </div>
</div> </div>
</div> </div>
</foreignObject> </foreignObject>
<text x="315" y="426" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle"> <text x="315" y="426" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">
Usage Views Usage Views
</text> </text>
</switch> </switch>
@@ -253,16 +253,16 @@
<path d="M 410 407 C 410 401.48 414.48 397 420 397 L 465.5 397 C 471.02 397 475.5 392.52 475.5 387 C 475.5 392.52 479.98 397 485.5 397 L 531 397 C 536.52 397 541 401.48 541 407" fill="none" stroke="#6c8ebf" stroke-width="2" stroke-miterlimit="10" transform="translate(0,397)scale(1,-1)translate(0,-397)" pointer-events="all"/> <path d="M 410 407 C 410 401.48 414.48 397 420 397 L 465.5 397 C 471.02 397 475.5 392.52 475.5 387 C 475.5 392.52 479.98 397 485.5 397 L 531 397 C 536.52 397 541 401.48 541 407" fill="none" stroke="#6c8ebf" stroke-width="2" stroke-miterlimit="10" transform="translate(0,397)scale(1,-1)translate(0,-397)" pointer-events="all"/>
<g transform="translate(-0.5 -0.5)"> <g transform="translate(-0.5 -0.5)">
<switch> <switch>
<foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"> <foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 414px; margin-left: 476px;"> <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 414px; margin-left: 476px;">
<div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"> <div style="box-sizing: border-box; font-size: 0; text-align: center; ">
<div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;"> <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: nowrap; ">
Extension Data Extension Data
</div> </div>
</div> </div>
</div> </div>
</foreignObject> </foreignObject>
<text x="476" y="426" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle"> <text x="476" y="426" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">
Extension Data Extension Data
</text> </text>
</switch> </switch>
@@ -274,7 +274,7 @@
<g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/> <g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/>
<a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"> <a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank">
<text text-anchor="middle" font-size="10px" x="50%" y="100%"> <text text-anchor="middle" font-size="10px" x="50%" y="100%">
Text is not SVG - cannot display Viewer does not support full SVG 1.1
</text> </text>
</a> </a>
</switch> </switch>

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 24 KiB

File diff suppressed because one or more lines are too long

View File

@@ -6,33 +6,16 @@ Author = Author
AuthorID = Author ID AuthorID = Author ID
Stock = Stock Stock = Stock
Name = Name Name = Name
Description = Description
Image = Image
AuthorName = Author's Name AuthorName = Author's Name
DateOfBirth = Date of Birth DateOfBirth = Date of Birth
DateOfDeath = Date of Death DateOfDeath = Date of Death
PlaceOfBirth = Place of Birth PlaceOfBirth = Place of Birth
PlaceOfDeath = Place of Death PlaceOfDeath = Place of Death
Age = Age Age = Age
Lifetime = Lifetime
Authors = Authors Authors = Authors
Order = Order Order = Order
Orders = Orders Orders = Orders
OrderNo = Order Number
OrderItems = Order Items
Customer = Customer
Product = Product
ProductID = Product ID
ProductTitle = Product Title
UnitPrice = Unit Price
Quantity = Quantity
Price = Price Price = Price
Currency = Currency
Date = Date
Rating = Rating
NumberOfReviews = Number of Reviews
Genre = Genre Genre = Genre
Genres = Genres Genres = Genres

View File

@@ -43,10 +43,5 @@ extend sap.capire.bookshop.Authors with {
virtual lifetime : String; virtual lifetime : String;
} }
annotate AdminService.Authors with {
age @Common.Label : '{i18n>Age}';
lifetime @Common.Label : '{i18n>Lifetime}'
}
// Workaround for Fiori popup for asking user to enter a new UUID on Create // Workaround for Fiori popup for asking user to enter a new UUID on Create
annotate AdminService.Authors with { ID @Core.Computed; } annotate AdminService.Authors with { ID @Core.Computed; }

View File

@@ -2,10 +2,10 @@
# __ldi.translation.uuid=c3431418-9caf-11e8-98d0-529269fb1459 # __ldi.translation.uuid=c3431418-9caf-11e8-98d0-529269fb1459
# JCI app descriptor contains lower case TITLE # JCI app descriptor contains lower case TITLE
appTitle=Manage Authors appTitle=Bookshop Authors
# JCI app descriptor contains lower case DESCRIPTION # JCI app descriptor contains lower case DESCRIPTION
appSubTitle=CAP Sample Application appSubTitle=Bookshop Authors
# JCI app descriptor contains lower case DESCRIPTION # JCI app descriptor contains lower case DESCRIPTION
appDescription=Bookshop Authors appDescription=Bookshop Authors

View File

@@ -11,7 +11,7 @@
}, },
"dataSources": { "dataSources": {
"AdminService": { "AdminService": {
"uri": "admin/", "uri": "/admin/",
"type": "OData", "type": "OData",
"settings": { "settings": {
"odataVersion": "4.0" "odataVersion": "4.0"
@@ -35,7 +35,7 @@
"additionalParameters": "ignored" "additionalParameters": "ignored"
}, },
"semanticObject": "Authors", "semanticObject": "Authors",
"action": "manage", "action": "display",
"title": "{{appTitle}}", "title": "{{appTitle}}",
"info": "{{appInfo}}", "info": "{{appInfo}}",
"subTitle": "{{appSubTitle}}", "subTitle": "{{appSubTitle}}",

View File

@@ -62,11 +62,6 @@ annotate AdminService.Books.texts with @(
} }
); );
annotate AdminService.Books.texts with {
ID @UI.Hidden;
ID_texts @UI.Hidden;
};
// Add Value Help for Locales // Add Value Help for Locales
annotate AdminService.Books.texts { annotate AdminService.Books.texts {
locale @( locale @(
@@ -81,6 +76,3 @@ extend service AdminService {
// Workaround for Fiori popup for asking user to enter a new UUID on Create // Workaround for Fiori popup for asking user to enter a new UUID on Create
annotate AdminService.Books with { ID @Core.Computed; } annotate AdminService.Books with { ID @Core.Computed; }
// Show Genre as drop down, not a dialog
annotate AdminService.Books with { genre @Common.ValueListWithFixedValues; }

View File

@@ -2,7 +2,7 @@
# __ldi.translation.uuid=c3431418-9caf-11e8-98d0-529269fb1459 # __ldi.translation.uuid=c3431418-9caf-11e8-98d0-529269fb1459
# JCI app descriptor contains lower case TITLE # JCI app descriptor contains lower case TITLE
appTitle=Manage Books appTitle=Bookshop Sample
# JCI app descriptor contains lower case DESCRIPTION # JCI app descriptor contains lower case DESCRIPTION
appSubTitle=CAP Sample Application appSubTitle=CAP Sample Application

View File

@@ -8,7 +8,7 @@
"i18n": "i18n/i18n.properties", "i18n": "i18n/i18n.properties",
"dataSources": { "dataSources": {
"AdminService": { "AdminService": {
"uri": "admin/", "uri": "/admin/",
"type": "OData", "type": "OData",
"settings": { "settings": {
"odataVersion": "4.0" "odataVersion": "4.0"
@@ -19,22 +19,6 @@
"id": "ui5template.basicSAPUI5ApplicationProject", "id": "ui5template.basicSAPUI5ApplicationProject",
"-id": "ui5template.smartTemplate", "-id": "ui5template.smartTemplate",
"-version": "1.40.12" "-version": "1.40.12"
},
"crossNavigation": {
"inbounds": {
"intent1": {
"signature": {
"parameters": {},
"additionalParameters": "allowed"
},
"semanticObject": "Books",
"action": "manage",
"title": "{{appTitle}}",
"info": "{{appInfo}}",
"subTitle": "{{appSubTitle}}",
"icon": "sap-icon://course-book"
}
}
} }
}, },
"sap.ui5": { "sap.ui5": {

View File

@@ -19,14 +19,6 @@
"title": "Browse Books", "title": "Browse Books",
"targetURL": "#Books-display" "targetURL": "#Books-display"
} }
},
{
"id": "BrowseGenres",
"tileType": "sap.ushell.ui.tile.StaticTile",
"properties": {
"title": "Browse Genres (OData v2)",
"targetURL": "#Genres-display"
}
} }
] ]
}, },
@@ -50,7 +42,7 @@
"tileType": "sap.ushell.ui.tile.StaticTile", "tileType": "sap.ushell.ui.tile.StaticTile",
"properties": { "properties": {
"title": "Manage Authors", "title": "Manage Authors",
"targetURL": "#Authors-manage" "targetURL": "#Authors-display"
} }
}, },
{ {
@@ -99,7 +91,7 @@
}, },
"BrowseAuthors": { "BrowseAuthors": {
"semanticObject": "Authors", "semanticObject": "Authors",
"action": "manage", "action": "display",
"title": "Browse Authors", "title": "Browse Authors",
"signature": { "signature": {
"parameters": { "parameters": {
@@ -115,24 +107,6 @@
"url": "/admin-authors/webapp" "url": "/admin-authors/webapp"
} }
}, },
"BrowseGenres": {
"semanticObject": "Genres",
"action": "display",
"title": "Browse Genres",
"signature": {
"parameters": {
"Genre.ID": {
"renameTo": "ID"
}
},
"additionalParameters": "ignored"
},
"resolutionResult": {
"applicationType": "SAPUI5",
"additionalInformation": "SAPUI5.Component=genres",
"url": "/genres/webapp"
}
},
"ManageBooks": { "ManageBooks": {
"semanticObject": "Books", "semanticObject": "Books",
"action": "manage", "action": "manage",

View File

@@ -33,7 +33,7 @@ annotate CatalogService.Books with @(UI : {
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// //
// Books List Page // Books Object Page
// //
annotate CatalogService.Books with @(UI : { annotate CatalogService.Books with @(UI : {
SelectionFields : [ SelectionFields : [
@@ -52,6 +52,9 @@ annotate CatalogService.Books with @(UI : {
}, },
{Value : genre.name}, {Value : genre.name},
{Value : price}, {Value : price},
{Value : currency.symbol}, {
Value : currency.symbol,
Label : ' '
},
] ]
}, ); }, );

View File

@@ -2,7 +2,7 @@
# __ldi.translation.uuid=c3431418-9caf-11e8-98d0-529269fb1459 # __ldi.translation.uuid=c3431418-9caf-11e8-98d0-529269fb1459
# JCI app descriptor contains lower case TITLE # JCI app descriptor contains lower case TITLE
appTitle=Browse Books appTitle=Bookshop Sample
# JCI app descriptor contains lower case DESCRIPTION # JCI app descriptor contains lower case DESCRIPTION
appSubTitle=CAP Sample Application appSubTitle=CAP Sample Application

View File

@@ -11,7 +11,7 @@
}, },
"dataSources": { "dataSources": {
"CatalogService": { "CatalogService": {
"uri": "browse/", "uri": "/browse/",
"type": "OData", "type": "OData",
"settings": { "settings": {
"odataVersion": "4.0" "odataVersion": "4.0"

View File

@@ -4,7 +4,6 @@
using { sap.capire.bookshop as my } from '@capire/bookstore'; using { sap.capire.bookshop as my } from '@capire/bookstore';
using { sap.common } from '@capire/common'; using { sap.common } from '@capire/common';
using { sap.common.Currencies } from '@sap/cds/common';
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// //
@@ -21,12 +20,21 @@ annotate my.Books with @(
currency_code currency_code
], ],
LineItem : [ LineItem : [
{ Value: ID, Label: '{i18n>Title}' }, {
{ Value: author.ID, Label: '{i18n>Author}' }, Value : ID,
Label : '{i18n>Title}'
},
{
Value : author.ID,
Label : '{i18n>Author}'
},
{Value : genre.name}, {Value : genre.name},
{Value : stock}, {Value : stock},
{Value : price}, {Value : price},
{ Value: currency.symbol }, {
Value : currency.symbol,
Label : ' '
},
] ]
} }
) { ) {
@@ -38,10 +46,6 @@ annotate my.Books with @(
author @ValueList.entity : 'Authors'; author @ValueList.entity : 'Authors';
}; };
annotate Currencies with {
symbol @Common.Label : '{i18n>Currency}';
}
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// //
// Books Details // Books Details
@@ -61,12 +65,17 @@ annotate my.Books with @(UI : {HeaderInfo : {
annotate my.Books with { annotate my.Books with {
ID @title : '{i18n>ID}'; ID @title : '{i18n>ID}';
title @title : '{i18n>Title}'; title @title : '{i18n>Title}';
genre @title: '{i18n>Genre}' @Common: { Text: genre.name, TextArrangement: #TextOnly }; genre @title : '{i18n>Genre}' @Common : {
author @title: '{i18n>Author}' @Common: { Text: author.name, TextArrangement: #TextOnly }; Text : genre.name,
TextArrangement : #TextOnly
};
author @title : '{i18n>Author}' @Common : {
Text : author.name,
TextArrangement : #TextOnly
};
price @title : '{i18n>Price}' @Measures.ISOCurrency : currency_code; price @title : '{i18n>Price}' @Measures.ISOCurrency : currency_code;
stock @title : '{i18n>Stock}'; stock @title : '{i18n>Stock}';
descr @title: '{i18n>Description}' @UI.MultiLineText; descr @UI.MultiLineText;
image @title: '{i18n>Image}';
} }
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@@ -87,10 +96,6 @@ annotate my.Genres with @(
} }
); );
annotate my.Genres with {
ID @Common.Text : name @Common.TextArrangement : #TextOnly;
}
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// //
// Genre Details // Genre Details

View File

@@ -1,8 +0,0 @@
using { sap.capire.bookshop } from '../../db/common';
annotate bookshop.GenreHierarchy {
ID @sap.hierarchy.node.for;
parent @sap.hierarchy.parent.node.for;
hierarchyLevel @sap.hierarchy.level.for;
drillState @sap.hierarchy.drill.state.for;
}

View File

@@ -1,7 +0,0 @@
sap.ui.define(["sap/suite/ui/generic/template/lib/AppComponent"], (AppComponent) =>
AppComponent.extend("genres.Component", {
metadata: {
manifest: "json",
},
})
);

View File

@@ -1,4 +0,0 @@
#XTIT
appTitle=Genres
#XTXT
appDescription=Browse Genres

View File

@@ -1,155 +0,0 @@
{
"_version": "1.8.0",
"sap.app": {
"id": "genres",
"type": "application",
"i18n": "i18n/i18n.properties",
"applicationVersion": {
"version": "1.0.0"
},
"title": "Browse Genres Hierarchy (OData v2)",
"description": "{{appDescription}}",
"tags": {
"keywords": []
},
"crossNavigation": {
"inbounds": {
"appShow": {
"title": "{{appTitle}}",
"semanticObject": "GenreHierarchy",
"action": "display",
"deviceTypes": {
"desktop": true,
"tablet": true,
"phone": true
},
"icon": "sap-icon://settings",
"size": "1x1"
}
},
"outbounds": {}
},
"ach": "",
"resources": "resources.json",
"dataSources": {
"main": {
"uri": "/odata/v2/browse",
"type": "OData",
"settings": {
"annotations": ["localAnnotations"],
"localUri": "localService/metadata.xml"
}
},
"localAnnotations": {
"type": "ODataAnnotation",
"uri": "annotations/localAnnotations.xml",
"settings": {
"localUri": "annotations/localAnnotations.xml"
}
}
},
"offline": false,
"sourceTemplate": {
"id": "ui5template.smartTemplate",
"version": "1.40.12"
}
},
"sap.ui": {
"technology": "UI5",
"icons": {
"icon": "",
"favIcon": "",
"phone": "",
"phone@2": "",
"tablet": "",
"tablet@2": ""
},
"deviceTypes": {
"desktop": true,
"tablet": true,
"phone": true
},
"supportedThemes": ["sap_hcb", "sap_belize", "sap_belize_deep", "sap_fiori_3"]
},
"sap.ui5": {
"resources": {
"js": [],
"css": []
},
"dependencies": {
"minUI5Version": "1.65.6",
"libs": {},
"components": {}
},
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"uri": "i18n/i18n.properties"
},
"@i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"uri": "i18n/i18n.properties"
},
"json": {
"type": "sap.ui.model.json.JSONModel"
},
"i18n|sap.suite.ui.generic.template.ListReport|Genres": {
"type": "sap.ui.model.resource.ResourceModel",
"uri": "i18n/ListReport/Genres/i18n.properties"
},
"": {
"dataSource": "main",
"preload": true,
"settings": {
"useBatch": true,
"defaultBindingMode": "TwoWay",
"defaultCountMode": "Inline",
"refreshAfterChange": true,
"metadataUrlParams": {
"sap-value-list": "none"
}
}
}
},
"contentDensities": {
"compact": true,
"cozy": true
}
},
"sap.ui.generic.app": {
"_version": "1.3.0",
"settings": {
"forceGlobalRefresh": false,
"useColumnLayoutForSmartForm": false,
"showBasicSearch": false
},
"pages": {
"ListReport|Genres": {
"entitySet": "GenreHierarchy",
"component": {
"name": "sap.suite.ui.generic.template.ListReport",
"list": true,
"settings": {
"condensedTableLayout": true,
"smartVariantManagement": true,
"tableType": "TreeTable",
"enableTableFilterInPageVariant": true,
"dataLoadSettings": {
"loadDataOnAppLaunch": "always"
}
}
}
}
}
},
"sap.fiori": {
"registrationIds": [],
"archeType": "transactional"
},
"sap.platform.hcp": {
"uri": ""
},
"sap.platform.cf": {
"oAuthScopes": []
}
}

View File

@@ -1,12 +0,0 @@
{
"name": "approuter",
"dependencies": {
"@sap/approuter": "^16.0.0"
},
"engines": {
"node": "^20.0.0"
},
"scripts": {
"start": "node node_modules/@sap/approuter/approuter.js"
}
}

View File

@@ -1,22 +0,0 @@
{
"welcomeFile": "app/index.html",
"routes": [
{
"source": "^/app/(.*)$",
"target": "$1",
"localDir": ".",
"cacheControl": "no-cache, no-store, must-revalidate"
},
{
"source": "^/appconfig/",
"localDir": ".",
"cacheControl": "no-cache, no-store, must-revalidate"
},
{
"source": "^/(.*)$",
"target": "$1",
"destination": "srv-api",
"csrfProtection": true
}
]
}

View File

@@ -5,6 +5,5 @@
using from './admin-authors/fiori-service'; using from './admin-authors/fiori-service';
using from './admin-books/fiori-service'; using from './admin-books/fiori-service';
using from './browse/fiori-service'; using from './browse/fiori-service';
using from './genres/fiori-service';
using from './common'; using from './common';
using from '@capire/bookstore/srv/mashup'; using from '@capire/bookstore/srv/mashup';

View File

@@ -1,14 +0,0 @@
namespace sap.capire.bookshop;
using { sap.capire.bookshop } from '@capire/bookstore/srv/mashup';
entity GenreHierarchy : bookshop.Genres {
hierarchyLevel : Integer default 0;
drillState : String default 'leaf';
parent : Association to GenreHierarchy;
children : Composition of many GenreHierarchy on children.parent = $self;
}
extend service CatalogService with {
@readonly entity GenreHierarchy as projection on bookshop.GenreHierarchy;
}

View File

@@ -1,16 +0,0 @@
ID;parent_ID;name;hierarchyLevel;drillState
10;;Fiction;0;expanded
11;10;Drama;1;leaf
12;10;Poetry;1;leaf
13;10;Fantasy;1;leaf
14;10;Science Fiction;1;leaf
15;10;Romance;1;leaf
16;10;Mystery;1;leaf
17;10;Thriller;1;leaf
18;10;Dystopia;1;leaf
20;;Non-Fiction;0;expanded
19;10;Fairy Tale;1;leaf
21;20;Biography;1;expanded
22;21;Autobiography;2;leaf
23;20;Essay;1;leaf
24;20;Speech;1;leaf
Internal Server Error - Bruno's Gitea
500 Internal Server Error

Gitea Version: 1.24.4