chore: Merged fiori into bookstore and tests into subprojects
This commit is contained in:
5
bookstore/app/_i18n/i18n_de.properties
Normal file
5
bookstore/app/_i18n/i18n_de.properties
Normal file
@@ -0,0 +1,5 @@
|
||||
AuthorName = Name des Autors
|
||||
Age = Alter
|
||||
rder = Bestellung
|
||||
Orders = Bestellungen
|
||||
Price = Preis
|
||||
8
bookstore/app/_i18n/i18n_en.properties
Normal file
8
bookstore/app/_i18n/i18n_en.properties
Normal file
@@ -0,0 +1,8 @@
|
||||
Age = Age
|
||||
Lifetime = Lifetime
|
||||
|
||||
SubGenres = Subgenre
|
||||
|
||||
NumCode = Numeric Code
|
||||
MinorUnit = Minor Unit
|
||||
Exponent = Exponent
|
||||
52
bookstore/app/admin-authors/fiori-service.cds
Normal file
52
bookstore/app/admin-authors/fiori-service.cds
Normal file
@@ -0,0 +1,52 @@
|
||||
using {AdminService} from '@capire/bookshop';
|
||||
|
||||
annotate AdminService.Authors with @odata.draft.enabled;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Authors Object Page
|
||||
//
|
||||
annotate AdminService.Authors with @(UI : {
|
||||
HeaderInfo : {
|
||||
TypeName : 'Author',
|
||||
TypeNamePlural : 'Authors',
|
||||
Description : {Value : lifetime}
|
||||
},
|
||||
Facets : [
|
||||
{
|
||||
$Type : 'UI.ReferenceFacet',
|
||||
Label : '{i18n>Details}',
|
||||
Target : '@UI.FieldGroup#Details'
|
||||
},
|
||||
{
|
||||
$Type : 'UI.ReferenceFacet',
|
||||
Label : '{i18n>Books}',
|
||||
Target : 'books/@UI.LineItem'
|
||||
},
|
||||
],
|
||||
FieldGroup #Details : {Data : [
|
||||
{Value : placeOfBirth},
|
||||
{Value : placeOfDeath},
|
||||
{Value : dateOfBirth},
|
||||
{Value : dateOfDeath},
|
||||
{
|
||||
Value : age,
|
||||
Label : '{i18n>Age}'
|
||||
},
|
||||
]},
|
||||
});
|
||||
|
||||
|
||||
// Workaround to avoid errors for unknown db-specific calculated fields above
|
||||
extend sap.capire.bookshop.Authors with {
|
||||
virtual age : Integer;
|
||||
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
|
||||
annotate AdminService.Authors with { ID @Core.Computed; }
|
||||
7
bookstore/app/admin-authors/webapp/Component.js
Normal file
7
bookstore/app/admin-authors/webapp/Component.js
Normal file
@@ -0,0 +1,7 @@
|
||||
sap.ui.define(["sap/fe/core/AppComponent"], function (AppComponent) {
|
||||
"use strict";
|
||||
return AppComponent.extend("authors.Component", {
|
||||
metadata: { manifest: "json" },
|
||||
});
|
||||
});
|
||||
/* eslint no-undef:0 */
|
||||
11
bookstore/app/admin-authors/webapp/i18n/i18n.properties
Normal file
11
bookstore/app/admin-authors/webapp/i18n/i18n.properties
Normal file
@@ -0,0 +1,11 @@
|
||||
# This is the resource bundle of itelo
|
||||
# __ldi.translation.uuid=c3431418-9caf-11e8-98d0-529269fb1459
|
||||
|
||||
# JCI app descriptor contains lower case TITLE
|
||||
appTitle=Manage Authors
|
||||
|
||||
# JCI app descriptor contains lower case DESCRIPTION
|
||||
appSubTitle=CAP Sample Application
|
||||
|
||||
# JCI app descriptor contains lower case DESCRIPTION
|
||||
appDescription=Bookshop Authors
|
||||
141
bookstore/app/admin-authors/webapp/manifest.json
Normal file
141
bookstore/app/admin-authors/webapp/manifest.json
Normal file
@@ -0,0 +1,141 @@
|
||||
{
|
||||
"_version": "1.28.0",
|
||||
"sap.app": {
|
||||
"id": "authors",
|
||||
"type": "application",
|
||||
"title": "Manage Authors",
|
||||
"description": "Sample Application",
|
||||
"i18n": "i18n/i18n.properties",
|
||||
"applicationVersion": {
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"dataSources": {
|
||||
"AdminService": {
|
||||
"uri": "admin/",
|
||||
"type": "OData",
|
||||
"settings": {
|
||||
"odataVersion": "4.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sourceTemplate": {
|
||||
"id": "ui5template.basicSAPUI5ApplicationProject",
|
||||
"-id": "ui5template.smartTemplate",
|
||||
"version": "1.40.12"
|
||||
},
|
||||
"crossNavigation": {
|
||||
"inbounds": {
|
||||
"intent1": {
|
||||
"signature": {
|
||||
"parameters": {
|
||||
"Books.author.ID":{
|
||||
"renameTo": "ID"
|
||||
}
|
||||
},
|
||||
"additionalParameters": "ignored"
|
||||
},
|
||||
"semanticObject": "Authors",
|
||||
"action": "manage",
|
||||
"title": "{{appTitle}}",
|
||||
"info": "{{appInfo}}",
|
||||
"subTitle": "{{appSubTitle}}",
|
||||
"icon": "sap-icon://SAP-icons-TNT/user",
|
||||
"indicatorDataSource": {
|
||||
"dataSource": "AdminService",
|
||||
"path": "Authors/$count",
|
||||
"refresh": 1800
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sap.ui5": {
|
||||
"dependencies": {
|
||||
"minUI5Version": "1.81.0",
|
||||
"libs": {
|
||||
"sap.fe.templates": {}
|
||||
}
|
||||
},
|
||||
"models": {
|
||||
"i18n": {
|
||||
"type": "sap.ui.model.resource.ResourceModel",
|
||||
"uri": "i18n/i18n.properties"
|
||||
},
|
||||
"": {
|
||||
"dataSource": "AdminService",
|
||||
"settings": {
|
||||
"synchronizationMode": "None",
|
||||
"operationMode": "Server",
|
||||
"autoExpandSelect": true,
|
||||
"earlyRequests": true,
|
||||
"groupProperties": {
|
||||
"default": {
|
||||
"submit": "Auto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"routing": {
|
||||
"routes": [
|
||||
{
|
||||
"pattern": ":?query:",
|
||||
"name": "AuthorsList",
|
||||
"target": "AuthorsList"
|
||||
},
|
||||
{
|
||||
"pattern": "Authors({key}):?query:",
|
||||
"name": "AuthorsDetails",
|
||||
"target": "AuthorsDetails"
|
||||
}
|
||||
],
|
||||
"targets": {
|
||||
"AuthorsList": {
|
||||
"type": "Component",
|
||||
"id": "AuthorsList",
|
||||
"name": "sap.fe.templates.ListReport",
|
||||
"options": {
|
||||
"settings": {
|
||||
"entitySet": "Authors",
|
||||
"initialLoad": true,
|
||||
"navigation": {
|
||||
"Authors": {
|
||||
"detail": {
|
||||
"route": "AuthorsDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"AuthorsDetails": {
|
||||
"type": "Component",
|
||||
"id": "AuthorsDetailsList",
|
||||
"name": "sap.fe.templates.ObjectPage",
|
||||
"options": {
|
||||
"settings": {
|
||||
"entitySet": "Authors"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"contentDensities": {
|
||||
"compact": true,
|
||||
"cozy": true
|
||||
}
|
||||
},
|
||||
"sap.ui": {
|
||||
"technology": "UI5",
|
||||
"fullWidth": false,
|
||||
"deviceTypes":{
|
||||
"desktop": true,
|
||||
"tablet": true,
|
||||
"phone": true
|
||||
}
|
||||
},
|
||||
"sap.fiori": {
|
||||
"registrationIds": [],
|
||||
"archeType": "transactional"
|
||||
}
|
||||
}
|
||||
112
bookstore/app/admin-books/fiori-service.cds
Normal file
112
bookstore/app/admin-books/fiori-service.cds
Normal file
@@ -0,0 +1,112 @@
|
||||
using { AdminService } from '@capire/bookstore';
|
||||
using from '../common'; // to help UI linter get the complete annotations
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Books Object Page
|
||||
//
|
||||
|
||||
annotate AdminService.Books with @(
|
||||
UI: {
|
||||
Facets: [
|
||||
{$Type: 'UI.ReferenceFacet', Label: '{i18n>General}', Target: '@UI.FieldGroup#General'},
|
||||
{$Type: 'UI.ReferenceFacet', Label: '{i18n>Translations}', Target: 'texts/@UI.LineItem'},
|
||||
{$Type: 'UI.ReferenceFacet', Label: '{i18n>Details}', Target: '@UI.FieldGroup#Details'},
|
||||
{$Type: 'UI.ReferenceFacet', Label: '{i18n>Admin}', Target: '@UI.FieldGroup#Admin'},
|
||||
],
|
||||
FieldGroup#General: {
|
||||
Data: [
|
||||
{Value: title},
|
||||
{Value: author_ID},
|
||||
{Value: genre_ID},
|
||||
{Value: descr},
|
||||
]
|
||||
},
|
||||
FieldGroup#Details: {
|
||||
Data: [
|
||||
{Value: stock},
|
||||
{Value: price},
|
||||
{Value: currency_code, Label: '{i18n>Currency}'},
|
||||
]
|
||||
},
|
||||
FieldGroup#Admin: {
|
||||
Data: [
|
||||
{Value: createdBy},
|
||||
{Value: createdAt},
|
||||
{Value: modifiedBy},
|
||||
{Value: modifiedAt}
|
||||
]
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Value Help for Tree Table
|
||||
//
|
||||
annotate AdminService.Books with {
|
||||
genre @(Common: {
|
||||
Label : 'Genre',
|
||||
ValueList: {
|
||||
CollectionPath : 'Genres',
|
||||
Parameters : [
|
||||
{
|
||||
$Type : 'Common.ValueListParameterDisplayOnly',
|
||||
ValueListProperty: 'name',
|
||||
},
|
||||
{
|
||||
$Type : 'Common.ValueListParameterInOut',
|
||||
LocalDataProperty: genre_ID,
|
||||
ValueListProperty: 'ID',
|
||||
}
|
||||
],
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Hide ID because of the ValueHelp
|
||||
annotate AdminService.Genres with {
|
||||
ID @UI.Hidden;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Draft for Localized Data
|
||||
//
|
||||
|
||||
annotate sap.capire.bookshop.Books with @fiori.draft.enabled;
|
||||
annotate AdminService.Books with @odata.draft.enabled;
|
||||
|
||||
annotate AdminService.Books.texts with @(
|
||||
UI: {
|
||||
Identification: [{Value:title}],
|
||||
SelectionFields: [ locale, title ],
|
||||
LineItem: [
|
||||
{Value: locale, Label: 'Locale'},
|
||||
{Value: title, Label: 'Title'},
|
||||
{Value: descr, Label: 'Description'},
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
annotate AdminService.Books.texts with {
|
||||
ID @UI.Hidden;
|
||||
ID_texts @UI.Hidden;
|
||||
};
|
||||
|
||||
// Add Value Help for Locales
|
||||
annotate AdminService.Books.texts {
|
||||
locale @(
|
||||
ValueList.entity:'Languages', Common.ValueListWithFixedValues, //show as drop down, not a dialog
|
||||
)
|
||||
}
|
||||
// In addition we need to expose Languages through AdminService as a target for ValueList
|
||||
using { sap } from '@sap/cds/common';
|
||||
extend service AdminService {
|
||||
@readonly entity Languages as projection on sap.common.Languages;
|
||||
}
|
||||
|
||||
// Workaround for Fiori popup for asking user to enter a new UUID on Create
|
||||
annotate AdminService.Books with { ID @Core.Computed; }
|
||||
8
bookstore/app/admin-books/webapp/Component.js
Normal file
8
bookstore/app/admin-books/webapp/Component.js
Normal file
@@ -0,0 +1,8 @@
|
||||
sap.ui.define(["sap/fe/core/AppComponent"], function(AppComponent) {
|
||||
"use strict";
|
||||
return AppComponent.extend("books.Component", {
|
||||
metadata: { manifest: "json" }
|
||||
});
|
||||
});
|
||||
|
||||
/* eslint no-undef:0 */
|
||||
11
bookstore/app/admin-books/webapp/i18n/i18n.properties
Normal file
11
bookstore/app/admin-books/webapp/i18n/i18n.properties
Normal file
@@ -0,0 +1,11 @@
|
||||
# This is the resource bundle of itelo
|
||||
# __ldi.translation.uuid=c3431418-9caf-11e8-98d0-529269fb1459
|
||||
|
||||
# JCI app descriptor contains lower case TITLE
|
||||
appTitle=Manage Books
|
||||
|
||||
# JCI app descriptor contains lower case DESCRIPTION
|
||||
appSubTitle=CAP Sample Application
|
||||
|
||||
# JCI app descriptor contains lower case DESCRIPTION
|
||||
appDescription=CDS Sample Service
|
||||
145
bookstore/app/admin-books/webapp/manifest.json
Normal file
145
bookstore/app/admin-books/webapp/manifest.json
Normal file
@@ -0,0 +1,145 @@
|
||||
{
|
||||
"_version": "1.8.0",
|
||||
"sap.app": {
|
||||
"id": "books",
|
||||
"type": "application",
|
||||
"title": "Manage Books",
|
||||
"description": "Sample Application",
|
||||
"i18n": "i18n/i18n.properties",
|
||||
"dataSources": {
|
||||
"AdminService": {
|
||||
"uri": "admin/",
|
||||
"type": "OData",
|
||||
"settings": {
|
||||
"odataVersion": "4.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"-sourceTemplate": {
|
||||
"id": "ui5template.basicSAPUI5ApplicationProject",
|
||||
"-id": "ui5template.smartTemplate",
|
||||
"-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": {
|
||||
"dependencies": {
|
||||
"libs": {
|
||||
"sap.fe.templates": {}
|
||||
}
|
||||
},
|
||||
"models": {
|
||||
"i18n": {
|
||||
"type": "sap.ui.model.resource.ResourceModel",
|
||||
"uri": "i18n/i18n.properties"
|
||||
},
|
||||
"": {
|
||||
"dataSource": "AdminService",
|
||||
"settings": {
|
||||
"synchronizationMode": "None",
|
||||
"operationMode": "Server",
|
||||
"autoExpandSelect" : true,
|
||||
"earlyRequests": true,
|
||||
"groupProperties": {
|
||||
"default": {
|
||||
"submit": "Auto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"routing": {
|
||||
"routes": [
|
||||
{
|
||||
"pattern": ":?query:",
|
||||
"name": "BooksList",
|
||||
"target": "BooksList"
|
||||
},
|
||||
{
|
||||
"pattern": "Books({key}):?query:",
|
||||
"name": "BooksDetails",
|
||||
"target": "BooksDetails"
|
||||
},
|
||||
{
|
||||
"pattern": "Books({key}/author({key2}):?query:",
|
||||
"name": "AuthorsDetails",
|
||||
"target": "AuthorsDetails"
|
||||
}
|
||||
],
|
||||
"targets": {
|
||||
"BooksList": {
|
||||
"type": "Component",
|
||||
"id": "BooksList",
|
||||
"name": "sap.fe.templates.ListReport",
|
||||
"options": {
|
||||
"settings" : {
|
||||
"entitySet" : "Books",
|
||||
"initialLoad": true,
|
||||
"navigation" : {
|
||||
"Books" : {
|
||||
"detail" : {
|
||||
"route" : "BooksDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"BooksDetails": {
|
||||
"type": "Component",
|
||||
"id": "BooksDetailsList",
|
||||
"name": "sap.fe.templates.ObjectPage",
|
||||
"options": {
|
||||
"settings" : {
|
||||
"entitySet" : "Books",
|
||||
"navigation" : {
|
||||
"Authors" : {
|
||||
"detail" : {
|
||||
"route" : "AuthorsDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"AuthorsDetails": {
|
||||
"type": "Component",
|
||||
"id": "AuthorsDetailsList",
|
||||
"name": "sap.fe.templates.ObjectPage",
|
||||
"options": {
|
||||
"settings" : {
|
||||
"entitySet" : "Authors"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"contentDensities": {
|
||||
"compact": true,
|
||||
"cozy": true
|
||||
}
|
||||
},
|
||||
"sap.ui": {
|
||||
"technology": "UI5",
|
||||
"fullWidth": false
|
||||
},
|
||||
"sap.fiori": {
|
||||
"registrationIds": [],
|
||||
"archeType": "transactional"
|
||||
}
|
||||
}
|
||||
167
bookstore/app/appconfig/fioriSandboxConfig.json
Normal file
167
bookstore/app/appconfig/fioriSandboxConfig.json
Normal file
@@ -0,0 +1,167 @@
|
||||
{
|
||||
"services": {
|
||||
"LaunchPage": {
|
||||
"adapter": {
|
||||
"config": {
|
||||
"groups": [
|
||||
{
|
||||
"id": "Bookshop",
|
||||
"title": "Bookshop",
|
||||
"isPreset": true,
|
||||
"isVisible": true,
|
||||
"isGroupLocked": false,
|
||||
"tiles": [
|
||||
{
|
||||
"id": "BrowseBooks",
|
||||
"tileType": "sap.ushell.ui.tile.StaticTile",
|
||||
"properties": {
|
||||
"title": "Browse Books",
|
||||
"targetURL": "#Books-display"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "BrowseGenres",
|
||||
"tileType": "sap.ushell.ui.tile.StaticTile",
|
||||
"properties": {
|
||||
"title": "Browse Genres",
|
||||
"targetURL": "#Genres-display"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "Administration",
|
||||
"title": "Administration",
|
||||
"isPreset": true,
|
||||
"isVisible": true,
|
||||
"isGroupLocked": false,
|
||||
"tiles": [
|
||||
{
|
||||
"id": "ManageBooks",
|
||||
"tileType": "sap.ushell.ui.tile.StaticTile",
|
||||
"properties": {
|
||||
"title": "Manage Books",
|
||||
"targetURL": "#Books-manage"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "ManageAuthors",
|
||||
"tileType": "sap.ushell.ui.tile.StaticTile",
|
||||
"properties": {
|
||||
"title": "Manage Authors",
|
||||
"targetURL": "#Authors-manage"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "ManageOrders",
|
||||
"tileType": "sap.ushell.ui.tile.StaticTile",
|
||||
"properties": {
|
||||
"title": "Manage Orders",
|
||||
"targetURL": "#Orders-manage"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"NavTargetResolution": {
|
||||
"config": {
|
||||
"enableClientSideTargetResolution": true
|
||||
}
|
||||
},
|
||||
"ClientSideTargetResolution": {
|
||||
"adapter": {
|
||||
"config": {
|
||||
"inbounds": {
|
||||
"BrowseBooks": {
|
||||
"semanticObject": "Books",
|
||||
"action": "display",
|
||||
"title": "Browse Books",
|
||||
"signature": {
|
||||
"parameters": {
|
||||
"Books.ID": {
|
||||
"renameTo": "ID"
|
||||
},
|
||||
"Authors.books.ID": {
|
||||
"renameTo": "ID"
|
||||
}
|
||||
},
|
||||
"additionalParameters": "ignored"
|
||||
},
|
||||
"resolutionResult": {
|
||||
"applicationType": "SAPUI5",
|
||||
"additionalInformation": "SAPUI5.Component=bookshop",
|
||||
"url": "/browse/webapp"
|
||||
}
|
||||
},
|
||||
"BrowseAuthors": {
|
||||
"semanticObject": "Authors",
|
||||
"action": "manage",
|
||||
"title": "Browse Authors",
|
||||
"signature": {
|
||||
"parameters": {
|
||||
"Books.author.ID":{
|
||||
"renameTo": "ID"
|
||||
}
|
||||
},
|
||||
"additionalParameters": "ignored"
|
||||
},
|
||||
"resolutionResult": {
|
||||
"applicationType": "SAPUI5",
|
||||
"additionalInformation": "SAPUI5.Component=authors",
|
||||
"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": {
|
||||
"semanticObject": "Books",
|
||||
"action": "manage",
|
||||
"title": "Manage Books",
|
||||
"signature": {
|
||||
"parameters": {},
|
||||
"additionalParameters": "allowed"
|
||||
},
|
||||
"resolutionResult": {
|
||||
"applicationType": "SAPUI5",
|
||||
"additionalInformation": "SAPUI5.Component=books",
|
||||
"url": "/admin-books/webapp"
|
||||
}
|
||||
},
|
||||
"ManageOrders": {
|
||||
"semanticObject": "Orders",
|
||||
"action": "manage",
|
||||
"signature": {
|
||||
"parameters": {},
|
||||
"additionalParameters": "allowed"
|
||||
},
|
||||
"resolutionResult": {
|
||||
"applicationType": "SAPUI5",
|
||||
"additionalInformation": "SAPUI5.Component=orders",
|
||||
"url": "/orders/webapp"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
57
bookstore/app/browse/fiori-service.cds
Normal file
57
bookstore/app/browse/fiori-service.cds
Normal file
@@ -0,0 +1,57 @@
|
||||
using CatalogService from '@capire/bookstore';
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Books Object Page
|
||||
//
|
||||
annotate CatalogService.Books with @(UI : {
|
||||
HeaderInfo : {
|
||||
TypeName : '{i18n>Book}',
|
||||
TypeNamePlural : '{i18n>Books}',
|
||||
Description : {Value : author}
|
||||
},
|
||||
HeaderFacets : [{
|
||||
$Type : 'UI.ReferenceFacet',
|
||||
Label : '{i18n>Description}',
|
||||
Target : '@UI.FieldGroup#Descr'
|
||||
}, ],
|
||||
Facets : [{
|
||||
$Type : 'UI.ReferenceFacet',
|
||||
Label : '{i18n>Details}',
|
||||
Target : '@UI.FieldGroup#Price'
|
||||
}, ],
|
||||
FieldGroup #Descr : {Data : [{Value : descr}, ]},
|
||||
FieldGroup #Price : {Data : [
|
||||
{Value : price},
|
||||
{
|
||||
Value : currency.symbol,
|
||||
Label : '{i18n>Currency}'
|
||||
},
|
||||
]},
|
||||
});
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Books List Page
|
||||
//
|
||||
annotate CatalogService.Books with @(UI : {
|
||||
SelectionFields : [
|
||||
ID,
|
||||
price,
|
||||
currency_code
|
||||
],
|
||||
LineItem : [
|
||||
{
|
||||
Value : ID,
|
||||
Label : '{i18n>Title}'
|
||||
},
|
||||
{
|
||||
Value : author,
|
||||
Label : '{i18n>Author}'
|
||||
},
|
||||
{Value : genre.name},
|
||||
{Value : price},
|
||||
{Value : currency.symbol},
|
||||
]
|
||||
}, );
|
||||
7
bookstore/app/browse/webapp/Component.js
Normal file
7
bookstore/app/browse/webapp/Component.js
Normal file
@@ -0,0 +1,7 @@
|
||||
sap.ui.define(["sap/fe/core/AppComponent"], function(AppComponent) {
|
||||
"use strict";
|
||||
return AppComponent.extend("bookshop.Component", {
|
||||
metadata: { manifest: "json" }
|
||||
});
|
||||
});
|
||||
/* eslint no-undef:0 */
|
||||
11
bookstore/app/browse/webapp/i18n/i18n.properties
Normal file
11
bookstore/app/browse/webapp/i18n/i18n.properties
Normal file
@@ -0,0 +1,11 @@
|
||||
# This is the resource bundle of itelo
|
||||
# __ldi.translation.uuid=c3431418-9caf-11e8-98d0-529269fb1459
|
||||
|
||||
# JCI app descriptor contains lower case TITLE
|
||||
appTitle=Browse Books
|
||||
|
||||
# JCI app descriptor contains lower case DESCRIPTION
|
||||
appSubTitle=CAP Sample Application
|
||||
|
||||
# JCI app descriptor contains lower case DESCRIPTION
|
||||
appDescription=CDS Sample Service
|
||||
144
bookstore/app/browse/webapp/manifest.json
Normal file
144
bookstore/app/browse/webapp/manifest.json
Normal file
@@ -0,0 +1,144 @@
|
||||
{
|
||||
"_version": "1.28.0",
|
||||
"sap.app": {
|
||||
"id": "bookshop",
|
||||
"type": "application",
|
||||
"title": "Browse Books",
|
||||
"description": "Sample Application",
|
||||
"i18n": "i18n/i18n.properties",
|
||||
"applicationVersion": {
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"dataSources": {
|
||||
"CatalogService": {
|
||||
"uri": "browse/",
|
||||
"type": "OData",
|
||||
"settings": {
|
||||
"odataVersion": "4.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sourceTemplate": {
|
||||
"id": "ui5template.basicSAPUI5ApplicationProject",
|
||||
"-id": "ui5template.smartTemplate",
|
||||
"version": "1.40.12"
|
||||
},
|
||||
"crossNavigation": {
|
||||
"inbounds": {
|
||||
"intent1": {
|
||||
"signature": {
|
||||
"parameters": {
|
||||
"Books.ID":{
|
||||
"renameTo": "ID"
|
||||
},
|
||||
"Authors.books.ID": {
|
||||
"renameTo": "ID"
|
||||
}
|
||||
},
|
||||
"additionalParameters": "ignored"
|
||||
},
|
||||
"semanticObject": "Books",
|
||||
"action": "display",
|
||||
"title": "{{appTitle}}",
|
||||
"info": "{{appInfo}}",
|
||||
"subTitle": "{{appSubTitle}}",
|
||||
"icon": "sap-icon://course-book",
|
||||
"indicatorDataSource": {
|
||||
"dataSource": "CatalogService",
|
||||
"path": "Books/$count",
|
||||
"refresh": 1800
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sap.ui5": {
|
||||
"dependencies": {
|
||||
"minUI5Version": "1.81.0",
|
||||
"libs": {
|
||||
"sap.fe.templates": {}
|
||||
}
|
||||
},
|
||||
"models": {
|
||||
"i18n": {
|
||||
"type": "sap.ui.model.resource.ResourceModel",
|
||||
"uri": "i18n/i18n.properties"
|
||||
},
|
||||
"": {
|
||||
"dataSource": "CatalogService",
|
||||
"settings": {
|
||||
"synchronizationMode": "None",
|
||||
"operationMode": "Server",
|
||||
"autoExpandSelect": true,
|
||||
"earlyRequests": true,
|
||||
"groupProperties": {
|
||||
"default": {
|
||||
"submit": "Auto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"routing": {
|
||||
"routes": [
|
||||
{
|
||||
"pattern": ":?query:",
|
||||
"name": "BooksList",
|
||||
"target": "BooksList"
|
||||
},
|
||||
{
|
||||
"pattern": "Books({key}):?query:",
|
||||
"name": "BooksDetails",
|
||||
"target": "BooksDetails"
|
||||
}
|
||||
],
|
||||
"targets": {
|
||||
"BooksList": {
|
||||
"type": "Component",
|
||||
"id": "BooksList",
|
||||
"name": "sap.fe.templates.ListReport",
|
||||
"options": {
|
||||
"settings": {
|
||||
"entitySet": "Books",
|
||||
"initialLoad": true,
|
||||
"navigation": {
|
||||
"Books": {
|
||||
"detail": {
|
||||
"route": "BooksDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"BooksDetails": {
|
||||
"type": "Component",
|
||||
"id": "BooksDetailsList",
|
||||
"name": "sap.fe.templates.ObjectPage",
|
||||
"options": {
|
||||
"settings": {
|
||||
"entitySet": "Books"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"contentDensities": {
|
||||
"compact": true,
|
||||
"cozy": true
|
||||
}
|
||||
},
|
||||
"sap.ui": {
|
||||
"technology": "UI5",
|
||||
"fullWidth": false,
|
||||
"deviceTypes":{
|
||||
"desktop": true,
|
||||
"tablet": true,
|
||||
"phone": true
|
||||
}
|
||||
},
|
||||
"sap.fiori": {
|
||||
"registrationIds": [],
|
||||
"archeType": "transactional"
|
||||
}
|
||||
}
|
||||
233
bookstore/app/common.cds
Normal file
233
bookstore/app/common.cds
Normal file
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
Common Annotations shared by all apps
|
||||
*/
|
||||
|
||||
using { sap.capire.bookshop as my } from '@capire/bookstore';
|
||||
using { sap.common } from '@capire/common';
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Books Lists
|
||||
//
|
||||
annotate my.Books with @(
|
||||
Common.SemanticKey : [ID],
|
||||
UI : {
|
||||
Identification : [{ Value: title }],
|
||||
SelectionFields : [
|
||||
ID,
|
||||
author_ID,
|
||||
price,
|
||||
currency_code
|
||||
],
|
||||
LineItem : [
|
||||
{ Value: ID, Label: '{i18n>Title}' },
|
||||
{ Value: author.ID, Label: '{i18n>Author}' },
|
||||
{ Value: genre.name },
|
||||
{ Value: stock },
|
||||
{ Value: price },
|
||||
{ Value: currency.symbol },
|
||||
]
|
||||
}
|
||||
) {
|
||||
ID @Common: {
|
||||
SemanticObject : 'Books',
|
||||
Text: title,
|
||||
TextArrangement : #TextOnly
|
||||
};
|
||||
author @ValueList.entity : 'Authors';
|
||||
};
|
||||
|
||||
annotate common.Currencies with {
|
||||
symbol @Common.Label : '{i18n>Currency}';
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Books Details
|
||||
//
|
||||
annotate my.Books with @(UI : {HeaderInfo : {
|
||||
TypeName : '{i18n>Book}',
|
||||
TypeNamePlural : '{i18n>Books}',
|
||||
Title : { Value: title },
|
||||
Description : { Value: author.name }
|
||||
}, });
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Books Elements
|
||||
//
|
||||
annotate my.Books with {
|
||||
ID @title: '{i18n>ID}';
|
||||
title @title: '{i18n>Title}';
|
||||
genre @title: '{i18n>Genre}' @Common: { Text: genre.name, TextArrangement: #TextOnly };
|
||||
author @title: '{i18n>Author}' @Common: { Text: author.name, TextArrangement: #TextOnly };
|
||||
price @title: '{i18n>Price}' @Measures.ISOCurrency : currency_code;
|
||||
stock @title: '{i18n>Stock}';
|
||||
descr @title: '{i18n>Description}' @UI.MultiLineText;
|
||||
image @title: '{i18n>Image}';
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Authors List
|
||||
//
|
||||
annotate my.Authors with @(
|
||||
Common.SemanticKey : [ID],
|
||||
UI : {
|
||||
Identification : [{ Value: name}],
|
||||
SelectionFields : [name],
|
||||
LineItem : [
|
||||
{ Value: ID },
|
||||
{ Value: dateOfBirth },
|
||||
{ Value: dateOfDeath },
|
||||
{ Value: placeOfBirth },
|
||||
{ Value: placeOfDeath },
|
||||
],
|
||||
}
|
||||
) {
|
||||
ID @Common: {
|
||||
SemanticObject : 'Authors',
|
||||
Text: name,
|
||||
TextArrangement : #TextOnly,
|
||||
};
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Author Details
|
||||
//
|
||||
annotate my.Authors with @(UI : {
|
||||
HeaderInfo : {
|
||||
TypeName : '{i18n>Author}',
|
||||
TypeNamePlural : '{i18n>Authors}',
|
||||
Title : { Value: name },
|
||||
Description : { Value: dateOfBirth }
|
||||
},
|
||||
Facets : [{
|
||||
$Type : 'UI.ReferenceFacet',
|
||||
Target : 'books/@UI.LineItem'
|
||||
}, ],
|
||||
});
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Authors Elements
|
||||
//
|
||||
annotate my.Authors with {
|
||||
ID @title: '{i18n>ID}';
|
||||
name @title: '{i18n>Name}';
|
||||
dateOfBirth @title: '{i18n>DateOfBirth}';
|
||||
dateOfDeath @title: '{i18n>DateOfDeath}';
|
||||
placeOfBirth @title: '{i18n>PlaceOfBirth}';
|
||||
placeOfDeath @title: '{i18n>PlaceOfDeath}';
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Languages List
|
||||
//
|
||||
annotate common.Languages with @(
|
||||
Common.SemanticKey : [code],
|
||||
Identification : [{ Value: code}],
|
||||
UI : {
|
||||
SelectionFields : [
|
||||
name,
|
||||
descr
|
||||
],
|
||||
LineItem : [
|
||||
{ Value: code },
|
||||
{ Value: name },
|
||||
],
|
||||
}
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Language Details
|
||||
//
|
||||
annotate common.Languages with @(UI : {
|
||||
HeaderInfo : {
|
||||
TypeName : '{i18n>Language}',
|
||||
TypeNamePlural : '{i18n>Languages}',
|
||||
Title : { Value: name },
|
||||
Description : { Value: descr }
|
||||
},
|
||||
Facets : [{
|
||||
$Type : 'UI.ReferenceFacet',
|
||||
Label : '{i18n>Details}',
|
||||
Target : '@UI.FieldGroup#Details'
|
||||
}, ],
|
||||
FieldGroup #Details : {Data : [
|
||||
{ Value: code },
|
||||
{ Value: name },
|
||||
{ Value: descr }
|
||||
]},
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Currencies List
|
||||
//
|
||||
annotate common.Currencies with @(
|
||||
Common.SemanticKey : [code],
|
||||
Identification : [{ Value: code}],
|
||||
UI : {
|
||||
SelectionFields : [
|
||||
name,
|
||||
descr
|
||||
],
|
||||
LineItem : [
|
||||
{ Value: descr },
|
||||
{ Value: symbol },
|
||||
{ Value: code },
|
||||
],
|
||||
}
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Currency Details
|
||||
//
|
||||
annotate common.Currencies with @(UI : {
|
||||
HeaderInfo : {
|
||||
TypeName : '{i18n>Currency}',
|
||||
TypeNamePlural : '{i18n>Currencies}',
|
||||
Title : { Value: descr },
|
||||
Description : { Value: code }
|
||||
},
|
||||
Facets : [
|
||||
{
|
||||
$Type : 'UI.ReferenceFacet',
|
||||
Label : '{i18n>Details}',
|
||||
Target : '@UI.FieldGroup#Details'
|
||||
},
|
||||
{
|
||||
$Type : 'UI.ReferenceFacet',
|
||||
Label : '{i18n>Extended}',
|
||||
Target : '@UI.FieldGroup#Extended'
|
||||
},
|
||||
],
|
||||
FieldGroup #Details : {Data : [
|
||||
{ Value: name },
|
||||
{ Value: symbol },
|
||||
{ Value: code },
|
||||
{ Value: descr }
|
||||
]},
|
||||
FieldGroup #Extended : {Data : [
|
||||
{ Value: numcode },
|
||||
{ Value: minor },
|
||||
{ Value: exponent }
|
||||
]},
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Currencies Elements
|
||||
//
|
||||
annotate common.Currencies with {
|
||||
numcode @title: '{i18n>NumCode}';
|
||||
minor @title: '{i18n>MinorUnit}';
|
||||
exponent @title: '{i18n>Exponent}';
|
||||
}
|
||||
31
bookstore/app/fiori-apps.html
Normal file
31
bookstore/app/fiori-apps.html
Normal file
@@ -0,0 +1,31 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Bookshop</title>
|
||||
|
||||
<script>
|
||||
window["sap-ushell-config"] = {
|
||||
defaultRenderer: "fiori2",
|
||||
applications: {},
|
||||
};
|
||||
</script>
|
||||
|
||||
<script id="sap-ushell-bootstrap" src="https://ui5.sap.com/test-resources/sap/ushell/bootstrap/sandbox.js"></script>
|
||||
<script id="sap-ui-bootstrap" src="https://ui5.sap.com/resources/sap-ui-core.js"
|
||||
data-sap-ui-libs="sap.m, sap.ushell, sap.collaboration, sap.ui.layout" data-sap-ui-compatVersion="edge"
|
||||
data-sap-ui-theme="sap_horizon"></script>
|
||||
<script>
|
||||
sap.ui.getCore().attachInit(() =>
|
||||
sap.ushell.Container.createRenderer().placeAt("content")
|
||||
);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body class="sapUiBody" id="content">
|
||||
</body>
|
||||
|
||||
</html>
|
||||
33
bookstore/app/genres/fiori-service.cds
Normal file
33
bookstore/app/genres/fiori-service.cds
Normal file
@@ -0,0 +1,33 @@
|
||||
using { sap.capire.bookshop.Genres } from '@capire/bookstore';
|
||||
|
||||
annotate Genres with @cds.search: {name};
|
||||
annotate Genres with @readonly;
|
||||
annotate Genres with {
|
||||
name @title: '{i18n>Genre}';
|
||||
}
|
||||
|
||||
// Lists
|
||||
annotate Genres with @(
|
||||
Common.SemanticKey : [name],
|
||||
UI.SelectionFields : [name],
|
||||
UI.LineItem : [
|
||||
{ Value: name, Label: '{i18n>Name}' },
|
||||
],
|
||||
);
|
||||
|
||||
// Details
|
||||
annotate Genres with @(UI : {
|
||||
Identification : [{ Value: name }],
|
||||
HeaderInfo : {
|
||||
TypeName : '{i18n>Genre}',
|
||||
TypeNamePlural : '{i18n>Genres}',
|
||||
Title : { Value: name },
|
||||
Description : { Value: ID }
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Tree Views
|
||||
// annotate AdminService.Genres with @hierarchy; // upcomming simplification
|
||||
using from './tree-view';
|
||||
using from './value-help';
|
||||
42
bookstore/app/genres/tree-view.cds
Normal file
42
bookstore/app/genres/tree-view.cds
Normal file
@@ -0,0 +1,42 @@
|
||||
using { AdminService } from '@capire/bookstore';
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Genres Tree View
|
||||
//
|
||||
|
||||
// Tell Fiori about the structure of the hierarchy
|
||||
annotate AdminService.Genres with @Aggregation.RecursiveHierarchy #GenresHierarchy : {
|
||||
ParentNavigationProperty : parent, // navigates to a node's parent
|
||||
NodeProperty : ID, // identifies a node, usually the key
|
||||
};
|
||||
|
||||
// Fiori expects the following to be defined explicitly, even though they're always the same
|
||||
extend AdminService.Genres with @(
|
||||
// The columns expected by Fiori to be present in hierarchy entities
|
||||
Hierarchy.RecursiveHierarchy #GenresHierarchy : {
|
||||
LimitedDescendantCount : LimitedDescendantCount,
|
||||
DistanceFromRoot : DistanceFromRoot,
|
||||
DrillState : DrillState,
|
||||
LimitedRank : LimitedRank
|
||||
},
|
||||
// Disallow filtering on these properties from Fiori UIs
|
||||
Capabilities.FilterRestrictions.NonFilterableProperties: [
|
||||
'LimitedDescendantCount',
|
||||
'DistanceFromRoot',
|
||||
'DrillState',
|
||||
'LimitedRank'
|
||||
],
|
||||
// Disallow sorting on these properties from Fiori UIs
|
||||
Capabilities.SortRestrictions.NonSortableProperties : [
|
||||
'LimitedDescendantCount',
|
||||
'DistanceFromRoot',
|
||||
'DrillState',
|
||||
'LimitedRank'
|
||||
],
|
||||
) columns { // Ensure we can query these fields from database
|
||||
null as LimitedDescendantCount : Int16,
|
||||
null as DistanceFromRoot : Int16,
|
||||
null as DrillState : String,
|
||||
null as LimitedRank : Int16,
|
||||
};
|
||||
6
bookstore/app/genres/value-help.cds
Normal file
6
bookstore/app/genres/value-help.cds
Normal file
@@ -0,0 +1,6 @@
|
||||
// Value help with Tree View
|
||||
using from '../admin-books/fiori-service';
|
||||
annotate AdminService.Books:genre with @Common.ValueList.PresentationVariantQualifier: 'VH';
|
||||
annotate AdminService.Genres with @UI.PresentationVariant #VH: {
|
||||
RecursiveHierarchyQualifier : 'GenresHierarchy',
|
||||
};
|
||||
3
bookstore/app/genres/webapp/Component.js
Normal file
3
bookstore/app/genres/webapp/Component.js
Normal file
@@ -0,0 +1,3 @@
|
||||
sap.ui.define(["sap/fe/core/AppComponent"], ac => ac.extend("genres.Component", {
|
||||
metadata:{ manifest:'json' }
|
||||
}))
|
||||
4
bookstore/app/genres/webapp/i18n/i18n.properties
Normal file
4
bookstore/app/genres/webapp/i18n/i18n.properties
Normal file
@@ -0,0 +1,4 @@
|
||||
#XTIT
|
||||
appTitle=Browse Genres
|
||||
#XTXT
|
||||
appDescription=Genres as Tree View
|
||||
2
bookstore/app/genres/webapp/i18n/i18n_de.properties
Normal file
2
bookstore/app/genres/webapp/i18n/i18n_de.properties
Normal file
@@ -0,0 +1,2 @@
|
||||
appTitle=Zeige Genres
|
||||
appDescription=Genres als Baumansicht
|
||||
124
bookstore/app/genres/webapp/manifest.json
Normal file
124
bookstore/app/genres/webapp/manifest.json
Normal file
@@ -0,0 +1,124 @@
|
||||
{
|
||||
"_version": "1.8.0",
|
||||
"sap.app": {
|
||||
"id": "genres",
|
||||
"type": "application",
|
||||
"title": "{{appTitle}}",
|
||||
"description": "{{appDescription}}",
|
||||
"applicationVersion": {
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"dataSources": {
|
||||
"AdminService": {
|
||||
"uri": "admin/",
|
||||
"type": "OData",
|
||||
"settings": {
|
||||
"odataVersion": "4.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"crossNavigation": {
|
||||
"inbounds": {
|
||||
"Genres-display": {
|
||||
"signature": {
|
||||
"parameters": {},
|
||||
"additionalParameters": "allowed"
|
||||
},
|
||||
"semanticObject": "Genres",
|
||||
"action": "display"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sap.ui5": {
|
||||
"dependencies": {
|
||||
"minUI5Version": "1.122.0",
|
||||
"libs": {
|
||||
"sap.fe.templates": {}
|
||||
}
|
||||
},
|
||||
"models": {
|
||||
"i18n": {
|
||||
"type": "sap.ui.model.resource.ResourceModel",
|
||||
"uri": "i18n/i18n.properties"
|
||||
},
|
||||
"": {
|
||||
"dataSource": "AdminService",
|
||||
"settings": {
|
||||
"synchronizationMode": "None",
|
||||
"operationMode": "Server",
|
||||
"autoExpandSelect": true,
|
||||
"earlyRequests": true,
|
||||
"groupProperties": {
|
||||
"default": {
|
||||
"submit": "Auto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"routing": {
|
||||
"routes": [
|
||||
{
|
||||
"pattern": ":?query:",
|
||||
"name": "GenresList",
|
||||
"target": "GenresList"
|
||||
},
|
||||
{
|
||||
"pattern": "Genres({key}):?query:",
|
||||
"name": "GenresDetails",
|
||||
"target": "GenresDetails"
|
||||
}
|
||||
],
|
||||
"targets": {
|
||||
"GenresList": {
|
||||
"type": "Component",
|
||||
"id": "GenresList",
|
||||
"name": "sap.fe.templates.ListReport",
|
||||
"options": {
|
||||
"settings": {
|
||||
"contextPath": "/Genres",
|
||||
"navigation": {
|
||||
"Genres": {
|
||||
"detail": {
|
||||
"route": "GenresDetails"
|
||||
}
|
||||
}
|
||||
},
|
||||
"controlConfiguration": {
|
||||
"@com.sap.vocabularies.UI.v1.LineItem": {
|
||||
"tableSettings": {
|
||||
"hierarchyQualifier": "GenresHierarchy",
|
||||
"type": "TreeTable"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"GenresDetails": {
|
||||
"type": "Component",
|
||||
"id": "GenresDetails",
|
||||
"name": "sap.fe.templates.ObjectPage",
|
||||
"options": {
|
||||
"settings": {
|
||||
"contextPath": "/Genres"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"contentDensities": {
|
||||
"compact": true,
|
||||
"cozy": true
|
||||
}
|
||||
},
|
||||
"sap.ui": {
|
||||
"technology": "UI5",
|
||||
"fullWidth": false
|
||||
},
|
||||
"sap.fiori": {
|
||||
"registrationIds": [],
|
||||
"archeType": "transactional"
|
||||
}
|
||||
}
|
||||
11
bookstore/app/services.cds
Normal file
11
bookstore/app/services.cds
Normal file
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
This model controls what gets served to Fiori frontends...
|
||||
*/
|
||||
|
||||
using from './admin-authors/fiori-service';
|
||||
using from './admin-books/fiori-service';
|
||||
using from './browse/fiori-service';
|
||||
using from './genres/fiori-service';
|
||||
|
||||
using from './common';
|
||||
using from '@capire/bookstore/srv/mashup';
|
||||
@@ -1 +0,0 @@
|
||||
require('./srv/server')
|
||||
10
bookstore/db/hana/index.cds
Normal file
10
bookstore/db/hana/index.cds
Normal file
@@ -0,0 +1,10 @@
|
||||
//
|
||||
// Add Author.age and .lifetime with a DB-specific function
|
||||
//
|
||||
|
||||
using { AdminService } from '@capire/bookshop';
|
||||
|
||||
extend projection AdminService.Authors with {
|
||||
YEARS_BETWEEN(dateOfBirth, dateOfDeath) as age: Integer,
|
||||
YEAR(dateOfBirth) || ' – ' || YEAR(dateOfDeath) as lifetime : String
|
||||
}
|
||||
10
bookstore/db/sqlite/index.cds
Normal file
10
bookstore/db/sqlite/index.cds
Normal file
@@ -0,0 +1,10 @@
|
||||
//
|
||||
// Add Author.age and .lifetime with a DB-specific function
|
||||
//
|
||||
|
||||
using { AdminService } from '@capire/bookshop';
|
||||
|
||||
extend projection AdminService.Authors with {
|
||||
strftime('%Y',dateOfDeath)-strftime('%Y',dateOfBirth) as age: Integer,
|
||||
strftime('%Y',dateOfBirth) || ' – ' || strftime('%Y',dateOfDeath) as lifetime : String
|
||||
}
|
||||
@@ -7,11 +7,18 @@
|
||||
"@capire/orders": "*",
|
||||
"@capire/common": "*",
|
||||
"@capire/data-viewer": "*",
|
||||
"@cap-js/hana": ">=1",
|
||||
"@sap-cloud-sdk/http-client": "^4",
|
||||
"@sap-cloud-sdk/resilience": "^4",
|
||||
"@sap/cds": ">=5",
|
||||
"express": "^4.17.1",
|
||||
"@cap-js/hana": ">=1"
|
||||
"express": "^4.17.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cap-js/sqlite": ">=1"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "cds-serve",
|
||||
"watch": "cds watch"
|
||||
},
|
||||
"cds": {
|
||||
"requires": {
|
||||
@@ -24,11 +31,21 @@
|
||||
"model": "@capire/orders"
|
||||
},
|
||||
"messaging": true,
|
||||
"db": true
|
||||
"db": true,
|
||||
"db-ext": {
|
||||
"[development]": {
|
||||
"model": "db/sqlite"
|
||||
},
|
||||
"[production]": {
|
||||
"model": "db/hana"
|
||||
}
|
||||
}
|
||||
},
|
||||
"log": { "service": true }
|
||||
},
|
||||
"scripts": {
|
||||
"start": "cds-serve"
|
||||
}
|
||||
"sapux": [
|
||||
"app/admin-authors",
|
||||
"app/admin-books",
|
||||
"app/browse"
|
||||
]
|
||||
}
|
||||
|
||||
2
bookstore/server.js
Normal file
2
bookstore/server.js
Normal file
@@ -0,0 +1,2 @@
|
||||
require('./srv/mashup')
|
||||
require('./srv/trees')
|
||||
50
bookstore/srv/trees.js
Normal file
50
bookstore/srv/trees.js
Normal file
@@ -0,0 +1,50 @@
|
||||
const cds = require('@sap/cds/lib')
|
||||
|
||||
// PoC for simplified Fiori Tree Views
|
||||
cds.on('compile.for.runtime', csn => {
|
||||
for (let each of cds.linked(csn).definitions) {
|
||||
if (each.is_entity && each._service && each['@hierarchy']) _hierarchy (each)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const _hierarchy = entity => {
|
||||
|
||||
// Add annotations explaining the hierarchy structure to Fiori
|
||||
const Qualifier = entity.name.slice (entity._service.name.length+1) + 'Hierarchy'
|
||||
const parent = _parent4(entity)
|
||||
entity[`@Aggregation.RecursiveHierarchy#${Qualifier}.ParentNavigationProperty`] ??= {'=': parent.name }
|
||||
entity[`@Aggregation.RecursiveHierarchy#${Qualifier}.NodeProperty`] ??= {'=': parent.keys[0].ref[0] }
|
||||
|
||||
// Add expected hierarchy elements to the entity
|
||||
const columns = entity.projection.columns ??= ['*']
|
||||
const elements = entity.elements
|
||||
for (let e of Hierarchy.elements) {
|
||||
entity[`@Hierarchy.RecursiveHierarchy#${Qualifier}.${e.name}`] = {'=': e.name }
|
||||
if (e.name in elements) continue
|
||||
const { name, value, ...rest } = e
|
||||
elements[e.name] = Object.defineProperty ({ __proto__:e, ...rest }, 'parent', { value: entity })
|
||||
columns.push ({ ...value, as: name, cast: { type: e.type } })
|
||||
}
|
||||
|
||||
// Disable filter and sort for hierarchy elements
|
||||
entity['@Capabilities.FilterRestrictions.NonFilterableProperties'] =
|
||||
entity['@Capabilities.SortRestrictions.NonSortableProperties'] =
|
||||
Object.keys (Hierarchy.elements)
|
||||
}
|
||||
|
||||
|
||||
const _parent4 = entity => {
|
||||
const parent = entity['@hierarchy.parent'] || entity['@hierarchy.via']
|
||||
if (parent) return entity.elements [parent['=']||parent]
|
||||
else for (let e of entity.elements) // use first recursive uplink association
|
||||
if (e.is2one && e._target === entity) return e
|
||||
}
|
||||
|
||||
|
||||
const { Hierarchy } = cds.linked `aspect Hierarchy {
|
||||
LimitedDescendantCount : Int16 = null;
|
||||
DistanceFromRoot : Int16 = null;
|
||||
DrillState : String = null;
|
||||
LimitedRank : Int16 = null;
|
||||
}`.definitions
|
||||
Reference in New Issue
Block a user