@sap/cds-dk 9.2.1 → 9.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/bin/bind.js +5 -8
  3. package/bin/up.js +12 -8
  4. package/lib/bind/cf.js +4 -0
  5. package/lib/bind/k8s.js +21 -0
  6. package/lib/bind/plugin.js +9 -0
  7. package/lib/build/buildTaskProviderFactory.js +8 -14
  8. package/lib/build/constants.js +1 -0
  9. package/lib/build/index.js +17 -2
  10. package/lib/build/plugin.js +5 -7
  11. package/lib/build/provider/hana/index.js +4 -4
  12. package/lib/env/schemas/cds-rc.js +2 -2
  13. package/lib/init/constants.js +3 -2
  14. package/lib/init/projectReader.js +2 -4
  15. package/lib/init/template/ams/index.js +1 -2
  16. package/lib/init/template/approuter/files/containerize.yaml.hbs +1 -1
  17. package/lib/init/template/approuter/index.js +1 -1
  18. package/lib/init/template/extension/files/.base/index.cds +6 -6
  19. package/lib/init/template/extension/index.js +5 -5
  20. package/lib/init/template/github-actions/files/{cf-github-deploy → github-deployment}/action.yaml +7 -5
  21. package/lib/init/template/github-actions/files/kyma-info/action.yaml +1 -1
  22. package/lib/init/template/github-actions/files/workflows/cf.yaml.hbs +10 -7
  23. package/lib/init/template/github-actions/files/workflows/kyma.yaml.hbs +6 -3
  24. package/lib/init/template/github-actions/files/workflows/test.yaml.hbs +5 -2
  25. package/lib/init/template/github-actions/index.js +8 -9
  26. package/lib/init/template/hana/index.js +2 -1
  27. package/lib/init/template/html5-repo/files/mta.yaml.hbs +5 -1
  28. package/lib/init/template/html5-repo/files/package.json.hbs +1 -1
  29. package/lib/init/template/html5-repo/index.js +24 -19
  30. package/lib/init/template/ias/files/mta.yaml.hbs +4 -3
  31. package/lib/init/template/ias/files/values.yaml.hbs +41 -40
  32. package/lib/init/template/mta/files/package.json +1 -1
  33. package/lib/init/template/nodejs/files/.vscode/extensions.json +0 -1
  34. package/lib/init/template/nodejs/files/package.json.hbs +3 -9
  35. package/lib/init/template/portal/files/mta.yaml.hbs +5 -1
  36. package/lib/init/template/portal/index.js +0 -1
  37. package/lib/init/template/sample/files/app/_i18n/i18n.properties +15 -0
  38. package/lib/init/template/sample/files/app/_i18n/i18n_de.properties +15 -0
  39. package/lib/init/template/sample/files/app/admin-books/fiori-service.cds +14 -15
  40. package/lib/init/template/sample/files/app/browse/fiori-service.cds +44 -44
  41. package/lib/init/template/sample/files/app/common.cds +99 -84
  42. package/lib/init/template/sample/files/db/schema.cds +22 -17
  43. package/lib/init/template/sample/files/package.json.hbs +1 -3
  44. package/lib/init/template/sample/files/srv/admin-service.cds +4 -3
  45. package/lib/init/template/sample/files/srv/cat-service.cds +28 -11
  46. package/lib/init/template/tiny-sample/files/nodejs/db/schema.cds +3 -3
  47. package/lib/init/template/typescript/files/package.json +1 -1
  48. package/lib/init/template/ui5/index.js +22 -0
  49. package/lib/lint/eslintHelp.json +5 -3
  50. package/npm-shrinkwrap.json +13 -13
  51. package/package.json +1 -1
  52. package/lib/init/template/sample/files/javascript/admin-service.js.hbs +0 -24
  53. package/lib/init/template/sample/files/javascript/cat-service.js.hbs +0 -43
  54. package/lib/init/template/sample/files/typescript/admin-service.ts.hbs +0 -16
  55. package/lib/init/template/sample/files/typescript/cat-service.ts.hbs +0 -38
@@ -9,13 +9,16 @@ on:
9
9
  branches:
10
10
  - main
11
11
 
12
+ permissions:
13
+ contents: read
14
+
12
15
  jobs:
13
16
  tests:
14
- runs-on: [self-hosted, {{#sap}}solinas{{/sap}}{{^sap}}ubuntu-latest{{/sap}}]
17
+ runs-on: {{#sap}}[self-hosted, solinas]{{/sap}}{{^sap}}ubuntu-latest{{/sap}}
15
18
  steps:
16
19
  - uses: actions/setup-node@v4
17
20
  with:
18
21
  node-version: 22
19
- - uses: actions/checkout@v4
22
+ - uses: actions/checkout@v5
20
23
  - run: npm install
21
24
  - run: npm test
@@ -34,34 +34,33 @@ module.exports = class GitHubActionTemplate extends require('../../plugin') {
34
34
  async combine() {
35
35
  const project = readProject()
36
36
  const { hasMta, hasHelm } = project, { force } = cds.cli.options
37
- project.literal = () => text => text
38
37
  project.sap = cds.cli.options.sap
39
38
  if (hasMta) {
40
39
  const cf = '.github/workflows/cf.yaml'
41
- if (!exists(cf) || force) {
40
+ if (force || !exists(cf)) {
42
41
  await renderAndCopy(path.join(__dirname, 'files/workflows/cf.yaml.hbs'), cf, project)
43
42
  }
44
43
  const cfSetup = '.github/actions/cf-setup'
45
- if (!exists(cfSetup) || force) {
44
+ if (force || !exists(cfSetup)) {
46
45
  await copy(path.join(__dirname, 'files/cf-setup'), cfSetup)
47
46
  }
48
- const cfGithub = '.github/actions/cf-github-deploy'
49
- if (!exists(cfGithub) || force) {
50
- await copy(path.join(__dirname, 'files/cf-github-deploy'), cfGithub)
47
+ const cfGithub = '.github/actions/github-deployment'
48
+ if (force || !exists(cfGithub)) {
49
+ await copy(path.join(__dirname, 'files/github-deployment'), cfGithub)
51
50
  }
52
51
  }
53
52
  if (hasHelm) {
54
53
  const kyma = '.github/workflows/kyma.yaml'
55
- if (!exists(kyma) || force) {
54
+ if (force || !exists(kyma)) {
56
55
  await renderAndCopy(path.join(__dirname, 'files/workflows/kyma.yaml.hbs'), kyma, project)
57
56
  }
58
57
  const kymaSetup = '.github/actions/kyma-setup'
59
- if (!exists(kymaSetup) || force) {
58
+ if (force || !exists(kymaSetup)) {
60
59
  await copy(path.join(__dirname, 'files/kyma-setup'), kymaSetup)
61
60
  }
62
61
 
63
62
  const kymaInfo = '.github/actions/kyma-info'
64
- if (!exists(kymaInfo) || force) {
63
+ if (force || !exists(kymaInfo)) {
65
64
  await copy(path.join(__dirname, 'files/kyma-info'), kymaInfo)
66
65
  }
67
66
  }
@@ -2,7 +2,7 @@ const { join } = require('path')
2
2
  const cds = require('../../../cds')
3
3
  const { read, write, exists, copy, rimraf } = cds.utils
4
4
  const { readProject } = require('../../projectReader')
5
- const { merge } = require('../../merge')
5
+ const { merge, sort } = require('../../merge')
6
6
  const mvn = require('../../mvn')
7
7
 
8
8
  const { srv4, hdbDeployer, serviceManager, hdiContainer, mtxSidecar4 } = require('../../registries/mta')
@@ -39,6 +39,7 @@ module.exports = class HanaTemplate extends require('../../plugin') {
39
39
  delete packageJson.dependencies['@sap/hana-client']
40
40
  await write('package.json', packageJson, { spaces: 2 })
41
41
  }
42
+ await sort('package.json', 'dependencies')
42
43
  }
43
44
 
44
45
  async combine() {
@@ -25,7 +25,11 @@ modules:
25
25
  type: com.sap.application.content
26
26
  path: {{#isNodejs}}gen{{/isNodejs}}{{#isJava}}.{{/isJava}}
27
27
  requires:
28
- - name: {{appName}}-auth
28
+ - name: {{appName}}-auth{{#hasIas}}
29
+ parameters:
30
+ config:
31
+ credential-type: X509_GENERATED
32
+ app-identifier: app-deployer{{/hasIas}}
29
33
  - name: srv-api
30
34
  - name: {{appName}}-html5-repo-host
31
35
  parameters:
@@ -6,7 +6,7 @@
6
6
  {{#profile}}
7
7
  "[{{profile}}]": {
8
8
  {{/profile}}
9
- "html5-runtime": true
9
+ "html5-repo": true
10
10
  {{#profile}}
11
11
  }
12
12
  {{/profile}}
@@ -23,25 +23,9 @@ module.exports = class Html5RepoTemplate extends require('../../plugin') {
23
23
 
24
24
  async run() {
25
25
  const project = readProject()
26
- const { appUIPaths, apps, appPath, configFile, hasUI5 } = project
26
+ const { appUIPaths, appPath, configFile } = project
27
27
  await merge(__dirname, 'files/package.json.hbs').into(configFile, { project })
28
28
 
29
- if (hasUI5) {
30
- for (const { app } of apps) {
31
- project.app = app
32
- await merge(__dirname, 'files/ui5.yaml.hbs').into(join(appPath, app, 'ui5.yaml'), { project })
33
- }
34
- for (const { app } of apps) {
35
- project.app = app
36
- await merge(__dirname, 'files/ui5-deploy.yaml.hbs').into(join(appPath, app, 'ui5-deploy.yaml'), { project })
37
- }
38
- }
39
-
40
- for (const { app } of apps) {
41
- project.app = app
42
- await merge(__dirname, 'files/app-package.json.hbs').into(join(appPath, app, 'package.json'), { project })
43
- }
44
-
45
29
  // app deployer requires a manifest.json
46
30
  await Promise.all(appUIPaths.map(p =>
47
31
  merge(__dirname, 'files/manifest.json')
@@ -51,17 +35,38 @@ module.exports = class Html5RepoTemplate extends require('../../plugin') {
51
35
 
52
36
  async combine() {
53
37
  const project = readProject()
54
- const { isJava, srvPath, appPath, hasMta, hasXsuaa, hasMultitenancy, hasWorkzoneStandard, hasHelm, hasHelmUnifiedRuntime, hasApprouter, hasContainerize, apps } = project
38
+ const {
39
+ isJava, srvPath, appPath, apps,
40
+ hasApprouter, hasContainerize, hasMultitenancy, hasWorkzoneStandard,
41
+ hasMta, hasXsuaa, hasHelm, hasHelmUnifiedRuntime, hasUI5
42
+ } = project
55
43
 
56
44
  await Promise.all(apps.map(async ({ app }) => {
57
45
  project.app = app
58
46
  project.hasIndexHtml = exists(join(appPath, app, 'webapp/index.html'))
59
47
  const additions = [odataApi]
60
48
  await merge(__dirname, 'files/xs-app.json.hbs').into(join(appPath, app, 'xs-app.json'), { with: project, additions })
49
+ await merge(__dirname, 'files/app-package.json.hbs').into(join(appPath, app, 'package.json'), { project })
61
50
  }))
62
51
 
52
+ if (hasUI5) {
53
+ for (const { app } of apps) {
54
+ project.app = app
55
+ await merge(__dirname, 'files/app-package.json.hbs').into(join(appPath, app, 'package.json'), { project })
56
+ }
57
+
58
+ for (const { app } of apps) {
59
+ project.app = app
60
+ await merge(__dirname, 'files/ui5.yaml.hbs').into(join(appPath, app, 'ui5.yaml'), { project })
61
+ }
62
+ for (const { app } of apps) {
63
+ project.app = app
64
+ await merge(__dirname, 'files/ui5-deploy.yaml.hbs').into(join(appPath, app, 'ui5-deploy.yaml'), { project })
65
+ }
66
+ }
67
+
63
68
  if (hasMultitenancy) {
64
- await merge({ cds: { requires: { 'html5-runtime':true } } }).into('mtx/sidecar/package.json')
69
+ await merge({ cds: { requires: { 'html5-repo': true } } }).into('mtx/sidecar/package.json')
65
70
  }
66
71
 
67
72
  if (hasMta) {
@@ -20,7 +20,7 @@ modules:
20
20
 
21
21
  - name: {{appName}}
22
22
  type: approuter.nodejs
23
- path: app/router
23
+ path: {{& approuterPath}}
24
24
  requires:
25
25
  - name: {{appName}}-auth
26
26
  parameters:
@@ -59,8 +59,11 @@ resources:
59
59
  display-name: {{appName}}
60
60
  {{#hasApprouter}}
61
61
  oauth2-configuration:
62
+ token-policy:
63
+ access-token-format: "jwt"
62
64
  redirect-uris:
63
65
  - ~{app-api/app-protocol}://*.~{app-api/app-uri}/login/callback
66
+ - ~{app-api/app-protocol}://~{app-api/app-uri}/login/callback
64
67
  post-logout-redirect-uris:
65
68
  - ~{app-api/app-protocol}://*.~{app-api/app-uri}/*/logout.html
66
69
  {{/hasApprouter}}
@@ -71,6 +74,4 @@ resources:
71
74
  {{#hasMultitenancy}}
72
75
  multi-tenant: true
73
76
  {{/hasMultitenancy}}
74
- {{#hasXsuaa}}
75
77
  xsuaa-cross-consumption: true
76
- {{/hasXsuaa}}
@@ -1,49 +1,50 @@
1
1
  {{#hasMultitenancy}}
2
2
  sidecar:
3
- bindings:
4
- auth:
5
- serviceInstanceName: identity
6
- parameters:
7
- credential-type: X509_GENERATED
8
- app-identifier: mtx
3
+ bindings:
4
+ auth:
5
+ serviceInstanceName: identity
6
+ parameters:
7
+ credential-type: X509_GENERATED
8
+ app-identifier: mtx
9
9
  {{/hasMultitenancy}}
10
10
  {{#hasApprouter}}
11
11
  approuter:
12
- bindings:
13
- auth:
14
- serviceInstanceName: identity
15
- parameters:
16
- credential-type: X509_GENERATED
17
- app-identifier: approuter
12
+ bindings:
13
+ auth:
14
+ serviceInstanceName: identity
15
+ parameters:
16
+ credential-type: X509_GENERATED
17
+ app-identifier: approuter
18
18
  {{/hasApprouter}}
19
19
  srv:
20
- bindings:
21
- auth:
22
- serviceInstanceName: identity
23
- parameters:
24
- credential-type: X509_GENERATED
25
- app-identifier: srv
20
+ bindings:
21
+ auth:
22
+ serviceInstanceName: identity
23
+ parameters:
24
+ credential-type: X509_GENERATED
25
+ app-identifier: srv
26
26
 
27
27
  identity:
28
- serviceOfferingName: identity
29
- servicePlanName: application
30
- parameters:
31
- display-name: {{appName}}
32
- {{#hasMultitenancy}}
33
- multi-tenant: true
34
- {{/hasMultitenancy}}
35
- {{#hasXsuaa}}
36
- xsuaa-cross-consumption: true
37
- {{/hasXsuaa}}
38
- {{#hasApprouter}}
39
- oauth2-configuration:
40
- redirect-uris:
41
- {{=<% %>=}}
42
- - https://*.{{ tpl .Values.global.domain . }}/login/callback
43
- <%={{ }}=%>
44
- post-logout-redirect-uris:
45
- {{=<% %>=}}
46
- - https://*.{{ tpl .Values.global.domain . }}/*/logout.html
47
- <%={{ }}=%>
48
- {{/hasApprouter}}
49
-
28
+ serviceOfferingName: identity
29
+ servicePlanName: application
30
+ parameters:
31
+ display-name: {{appName}}
32
+ {{#hasMultitenancy}}
33
+ multi-tenant: true
34
+ {{/hasMultitenancy}}
35
+ {{#hasXsuaa}}
36
+ xsuaa-cross-consumption: true
37
+ {{/hasXsuaa}}
38
+ {{#hasApprouter}}
39
+ oauth2-configuration:
40
+ token-policy:
41
+ access-token-format: "jwt"
42
+ redirect-uris:
43
+ {{=<% %>=}}
44
+ - https://*.{{ tpl .Values.global.domain . }}/login/callback
45
+ <%={{ }}=%>
46
+ post-logout-redirect-uris:
47
+ {{=<% %>=}}
48
+ - https://*.{{ tpl .Values.global.domain . }}/*/logout.html
49
+ <%={{ }}=%>
50
+ {{/hasApprouter}}
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "devDependencies": {
3
- "@sap/cds-dk": ">=8"
3
+ "@sap/cds-dk": "^9"
4
4
  }
5
5
  }
@@ -2,7 +2,6 @@
2
2
  "recommendations": [
3
3
  "SAPSE.vscode-cds",
4
4
  "dbaeumer.vscode-eslint",
5
- "esbenp.prettier-vscode",
6
5
  "mechatroner.rainbow-csv",
7
6
  "qwtel.sqlite-viewer",
8
7
  "humao.rest-client"
@@ -2,21 +2,15 @@
2
2
  "name": "{{ projectName }}",
3
3
  "version": "1.0.0",
4
4
  "description": "A simple CAP project.",
5
- "repository": "<Add your repository here>",
6
- "license": "UNLICENSED",
7
- "private": true,
8
5
  "dependencies": {
9
6
  "@sap/cds": "^9",
10
7
  "express": "^4"
11
8
  },
12
- "engines": {
13
- "node": ">=20"
14
- },
15
9
  "devDependencies": {
16
- "@cap-js/sqlite": "^2",
17
- "@cap-js/cds-types": "^0.13.0"
10
+ "@cap-js/sqlite": "^2"
18
11
  },
19
12
  "scripts": {
20
13
  "start": "cds-serve"
21
- }
14
+ },
15
+ "private": true
22
16
  }
@@ -37,7 +37,11 @@ modules:
37
37
  name: {{appName}}-portal-key
38
38
  config:
39
39
  content-endpoint: developer
40
- - name: {{appName}}-auth
40
+ - name: {{appName}}-auth{{#hasIas}}
41
+ parameters:
42
+ config:
43
+ credential-type: X509_GENERATED
44
+ app-identifier: portal-deployer{{/hasIas}}
41
45
  - name: {{appName}}-html5-repo-host
42
46
  - name: {{appName}}-app-deployer
43
47
  deployed-after:
@@ -23,7 +23,6 @@ module.exports = class PortalTemplate extends require('../../plugin') {
23
23
  const project = readProject()
24
24
  const { configFile } = project
25
25
  await merge(__dirname, 'files/package.json.hbs').into(configFile, { project })
26
- project.literal = () => text => text
27
26
  await renderAndCopy(path.join(__dirname, 'files/portal-site'), 'app/portal/portal-site', project)
28
27
  }
29
28
 
@@ -12,3 +12,18 @@ Stock = Stock
12
12
  Order = Order
13
13
  Orders = Orders
14
14
  Price = Price
15
+ Genre = Genre
16
+ Genres = Genres
17
+ DateOfBirth = Date of Birth
18
+ DateOfDeath = Date of Death
19
+ PlaceOfBirth = Place of Birth
20
+ PlaceOfDeath = Place of Death
21
+ Details = Details
22
+ Languages = Languages
23
+ Currencies = Currencies
24
+ MainGenre = Main Genre
25
+ SubGenres = Subgenres
26
+ Admin = Admin
27
+ Translations = Translations
28
+ General = General
29
+ Locale = Locale
@@ -12,3 +12,18 @@ Stock = Bestand
12
12
  Order = Bestellung
13
13
  Orders = Bestellungen
14
14
  Price = Preis
15
+ Genre = Genre
16
+ Genres = Genres
17
+ DateOfBirth = Geburtsdatum
18
+ DateOfDeath = Todesdatum
19
+ PlaceOfBirth = Geburtsort
20
+ PlaceOfDeath = Todesort
21
+ Details = Details
22
+ Languages = Sprachen
23
+ Currencies = Währungen
24
+ MainGenre = Hauptgenre
25
+ SubGenres = Subgenres
26
+ Admin = Admin
27
+ Translations = Übersetzungen
28
+ General = Allgemein
29
+ Locale = Gebietsschema
@@ -1,5 +1,4 @@
1
- using { AdminService } from '../../srv/admin-service.cds';
2
- using { sap.capire.bookshop } from '../../db/schema';
1
+ using {AdminService} from '../../srv/admin-service.cds';
3
2
 
4
3
  ////////////////////////////////////////////////////////////////////////////
5
4
  //
@@ -7,13 +6,13 @@ using { sap.capire.bookshop } from '../../db/schema';
7
6
  //
8
7
 
9
8
  annotate AdminService.Books with @(UI: {
10
- HeaderInfo : {
9
+ HeaderInfo : {
11
10
  TypeName : '{i18n>Book}',
12
11
  TypeNamePlural: '{i18n>Books}',
13
12
  Title : {Value: title},
14
13
  Description : {Value: author.name}
15
14
  },
16
- Facets: [
15
+ Facets : [
17
16
  {
18
17
  $Type : 'UI.ReferenceFacet',
19
18
  Label : '{i18n>General}',
@@ -49,7 +48,7 @@ annotate AdminService.Books with @(UI: {
49
48
  Label: '{i18n>Currency}'
50
49
  },
51
50
  ]},
52
- FieldGroup #Admin: {Data: [
51
+ FieldGroup #Admin : {Data: [
53
52
  {Value: createdBy},
54
53
  {Value: createdAt},
55
54
  {Value: modifiedBy},
@@ -67,23 +66,23 @@ annotate sap.capire.bookshop.Books with @fiori.draft.enabled;
67
66
  annotate AdminService.Books with @odata.draft.enabled;
68
67
 
69
68
  annotate AdminService.Books.texts with @(UI: {
70
- Identification: [{Value: title}],
69
+ Identification : [{Value: title}],
71
70
  SelectionFields: [
72
71
  locale,
73
72
  title
74
73
  ],
75
- LineItem: [
74
+ LineItem : [
76
75
  {
77
76
  Value: locale,
78
- Label: 'Locale'
77
+ Label: '{i18n>Locale}'
79
78
  },
80
79
  {
81
80
  Value: title,
82
- Label: 'Title'
81
+ Label: '{i18n>Title}'
83
82
  },
84
83
  {
85
84
  Value: descr,
86
- Label: 'Description'
85
+ Label: '{i18n>Description}'
87
86
  },
88
87
  ]
89
88
  });
@@ -105,13 +104,13 @@ annotate AdminService.Books.texts {
105
104
  using {sap} from '@sap/cds/common';
106
105
 
107
106
  extend service AdminService {
108
- @readonly entity Languages as projection on sap.common.Languages;
107
+ @readonly
108
+ entity Languages as projection on sap.common.Languages;
109
109
  }
110
110
 
111
- // Workaround for Fiori popup for asking user to enter a new UUID on Create
112
- annotate AdminService.Books with {
113
- ID @Core.Computed;
114
- }
111
+ // Workaround for Fiori popups for asking user to enter a valid UUID on Create
112
+ annotate AdminService.Authors : ID with @Core.Computed @odata.Type: 'Edm.String';
113
+ annotate AdminService.Books : ID with @Core.Computed @odata.Type: 'Edm.String';
115
114
 
116
115
  // Show Genre as drop down, not a dialog
117
116
  annotate AdminService.Books with {
@@ -1,57 +1,57 @@
1
- using { CatalogService } from '../../srv/cat-service.cds';
1
+ using {CatalogService} from '../../srv/cat-service.cds';
2
2
 
3
3
  ////////////////////////////////////////////////////////////////////////////
4
4
  //
5
5
  // Books Object Page
6
6
  //
7
- annotate CatalogService.Books with @(UI : {
8
- HeaderInfo: {
9
- TypeName : '{i18n>Book}',
10
- TypeNamePlural: '{i18n>Books}',
11
- Title : {Value: title},
12
- Description : {Value : author}
7
+ annotate CatalogService.Books with @(UI: {
8
+ HeaderInfo : {
9
+ TypeName : '{i18n>Book}',
10
+ TypeNamePlural: '{i18n>Books}',
11
+ Title : {Value: title},
12
+ Description : {Value: author}
13
+ },
14
+ HeaderFacets : [{
15
+ $Type : 'UI.ReferenceFacet',
16
+ Label : '{i18n>Description}',
17
+ Target: '@UI.FieldGroup#Descr'
18
+ }, ],
19
+ Facets : [{
20
+ $Type : 'UI.ReferenceFacet',
21
+ Label : '{i18n>Details}',
22
+ Target: '@UI.FieldGroup#Price'
23
+ }, ],
24
+ FieldGroup #Descr: {Data: [{Value: descr}, ]},
25
+ FieldGroup #Price: {Data: [
26
+ {Value: price},
27
+ {
28
+ Value: currency.symbol,
29
+ Label: '{i18n>Currency}'
13
30
  },
14
- HeaderFacets: [{
15
- $Type : 'UI.ReferenceFacet',
16
- Label : '{i18n>Description}',
17
- Target: '@UI.FieldGroup#Descr'
18
- }, ],
19
- Facets: [{
20
- $Type : 'UI.ReferenceFacet',
21
- Label : '{i18n>Details}',
22
- Target: '@UI.FieldGroup#Price'
23
- }, ],
24
- FieldGroup #Descr: {Data : [{Value : descr}, ]},
25
- FieldGroup #Price: {Data : [
26
- {Value: price},
27
- {
28
- Value: currency.symbol,
29
- Label: '{i18n>Currency}'
30
- },
31
- ]},
31
+ ]},
32
32
  });
33
33
 
34
34
  ////////////////////////////////////////////////////////////////////////////
35
35
  //
36
36
  // Books List Page
37
37
  //
38
- annotate CatalogService.Books with @(UI : {
39
- SelectionFields: [
40
- ID,
41
- price,
42
- currency_code
43
- ],
44
- LineItem: [
45
- {
46
- Value: ID,
47
- Label: '{i18n>Title}'
48
- },
49
- {
50
- Value: author,
51
- Label: '{i18n>Author}'
52
- },
53
- {Value: genre.name},
54
- {Value: price},
55
- {Value: currency.symbol},
56
- ]
38
+ annotate CatalogService.Books with @(UI: {
39
+ SelectionFields: [
40
+ ID,
41
+ price,
42
+ currency_code
43
+ ],
44
+ LineItem : [
45
+ {
46
+ Value: ID,
47
+ Label: '{i18n>Title}'
48
+ },
49
+ {
50
+ Value: author,
51
+ Label: '{i18n>Author}'
52
+ },
53
+ {Value: genre.name},
54
+ {Value: price},
55
+ {Value: currency.symbol},
56
+ ]
57
57
  });