From aa28804a511d8b4cd1532b814724d0629313ad2b Mon Sep 17 00:00:00 2001 From: Daniel Hutzel Date: Sat, 29 Jan 2022 23:49:30 +0100 Subject: [PATCH 01/17] Basic bookshop w/o reuse deps (#312) --- bookshop/app/services.cds | 2 -- bookshop/db/init.js | 24 ++++++++++++++++++++++++ bookshop/package.json | 1 - bookstore/srv/mashup.cds | 3 +++ common/index.cds | 2 +- 5 files changed, 28 insertions(+), 4 deletions(-) delete mode 100644 bookshop/app/services.cds create mode 100644 bookshop/db/init.js diff --git a/bookshop/app/services.cds b/bookshop/app/services.cds deleted file mode 100644 index ce737b46..00000000 --- a/bookshop/app/services.cds +++ /dev/null @@ -1,2 +0,0 @@ -// Incorporate pre-build extensions from... -using from '@capire/common'; diff --git a/bookshop/db/init.js b/bookshop/db/init.js new file mode 100644 index 00000000..0db736ca --- /dev/null +++ b/bookshop/db/init.js @@ -0,0 +1,24 @@ +/** + * In order to keep basic bookshop sample as simple as possible, we don't add + * reuse dependencies. This db/init.js ensures we still have a minimum set of + * currencies, if not obtained through @capire/common. + */ + +module.exports = async (db)=>{ + + const has_common = db.model.definitions['sap.common.Currencies'].elements.numcode + if (has_common) return + + 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 ( + [ 'EUR','€','Euro' ], + [ 'USD','$','US Dollar' ], + [ 'GBP','£','British Pound' ], + [ 'ILS','₪','Shekel' ], + [ 'JPY','¥','Yen' ], + ) +} diff --git a/bookshop/package.json b/bookshop/package.json index e7125251..1eb86ded 100644 --- a/bookshop/package.json +++ b/bookshop/package.json @@ -3,7 +3,6 @@ "version": "1.0.0", "description": "A simple self-contained bookshop service.", "dependencies": { - "@capire/common": "*", "@sap/cds": "^5.0.4", "express": "^4.17.1", "passport": "0.4.1" diff --git a/bookstore/srv/mashup.cds b/bookstore/srv/mashup.cds index 5bcc4446..061418c0 100644 --- a/bookstore/srv/mashup.cds +++ b/bookstore/srv/mashup.cds @@ -33,3 +33,6 @@ using from '@capire/orders/app/fiori'; // Add data browser using from '@capire/data-viewer'; + +// Incorporate pre-build extensions from... +using from '@capire/common'; diff --git a/common/index.cds b/common/index.cds index 39e42d28..cb89e28d 100644 --- a/common/index.cds +++ b/common/index.cds @@ -20,7 +20,7 @@ extend sap.common.Currencies with { * annotate sap.common.Countries with @cds.persistence.skip:false; */ -context sap.common_countries { +context sap.common.countries { extend sap.common.Countries { regions : Composition of many Regions on regions._parent = $self.code; From e6baa95f745123e801de25d312fb305a781fc13f Mon Sep 17 00:00:00 2001 From: Christian Georgi Date: Mon, 31 Jan 2022 19:03:06 +0100 Subject: [PATCH 02/17] Data browser: keep data row selection across refresh --- data-viewer/app/viewer/app.js | 27 ++++++++++++++++++++++++--- data-viewer/app/viewer/index.html | 10 +++++----- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/data-viewer/app/viewer/app.js b/data-viewer/app/viewer/app.js index e326ece6..be6970bf 100644 --- a/data-viewer/app/viewer/app.js +++ b/data-viewer/app/viewer/app.js @@ -15,7 +15,8 @@ const viewer = new Vue ({ entities: [], columns: [], data: [], - rowDetails: undefined, + rowDetails: {}, + rowKey: storageGet('rowKey') }, watch: { @@ -55,17 +56,37 @@ const viewer = new Vue ({ if (viewer.dataSource === 'db') url += `&dataSource=db` const {data} = await GET(url) viewer.data = data.value.map(d => d.record.map(r => r.data)) - viewer.rowDetails = undefined + const row = viewer.data.find(data => viewer._makeRowKey(data) === viewer.rowKey) + if (row) viewer._setRowDetails(row) + else viewer.rowDetails = {} }, inspectRow (eve) { viewer.rowDetails = {} const selectedRow = eve.currentTarget.rowIndex-1 - viewer.data[selectedRow].forEach((line, colIndex) => { + viewer.rowKey = viewer._makeRowKey(viewer.data[selectedRow]) + storageSet('rowKey', viewer.rowKey) + viewer._setRowDetails(viewer.data[selectedRow]) + }, + + _setRowDetails(row) { + viewer.rowDetails = {} + row.forEach((line, colIndex) => { viewer.rowDetails[viewer.columns[colIndex].name] = line }) }, + _makeRowKey(row) { + // to identify a row, build a key string out of all key columns' values + return row + .filter((_, colIndex) => viewer.columns[colIndex] && viewer.columns[colIndex].isKey) + .reduce(((prev, next) => prev += next), '') + }, + + isActiveRow(row) { + return viewer._makeRowKey(row) === viewer.rowKey + } + } }) diff --git a/data-viewer/app/viewer/index.html b/data-viewer/app/viewer/index.html index 121c4d4d..b5a80635 100644 --- a/data-viewer/app/viewer/index.html +++ b/data-viewer/app/viewer/index.html @@ -8,7 +8,7 @@ + Data Browser + + + +
-

{{ document.title }}{{ entity ? ' – ' + entity.name : '' }}

+

{{ document.title }}{{ entity ? ' – ' + entity.name : '' }}

-
- - -
-
- - - - -
-
- - - - - - - -
{{ col.name }}
{{ d }}
-
- -
- - - - - -
{{ value }}{{ key }}
-
-
+
+ +
+
+ + + + +
+
+ + + + + + + +
{{ col.name }}
{{ d }}
+
+ +
+ + + + + +
{{ value }}{{ key }}
+
+
+
+
From f8c23f4c54b0b266a837046732c9bf3d6d753032 Mon Sep 17 00:00:00 2001 From: Christian Georgi Date: Mon, 31 Jan 2022 19:53:35 +0100 Subject: [PATCH 04/17] Better layout; --- data-viewer/app/viewer/index.html | 34 ++++++++++++++++++------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/data-viewer/app/viewer/index.html b/data-viewer/app/viewer/index.html index de4940b5..3e91bb4a 100644 --- a/data-viewer/app/viewer/index.html +++ b/data-viewer/app/viewer/index.html @@ -7,6 +7,7 @@ - -
+ +

{{ document.title }}{{ entity ? ' – ' + entity.name : '' }}

@@ -37,14 +41,16 @@
- - - - - - - -
Entity Name
{{ e.name }}
+
@@ -54,7 +60,7 @@
-
+
@@ -64,8 +70,8 @@
{{ col.name }}
- -
+

+
From 7c0769e0597419e22a49c8b975feb72e3ee115f4 Mon Sep 17 00:00:00 2001 From: Christian Georgi Date: Tue, 1 Feb 2022 18:42:36 +0100 Subject: [PATCH 05/17] Stick table headers --- data-viewer/app/viewer/index.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data-viewer/app/viewer/index.html b/data-viewer/app/viewer/index.html index 3e91bb4a..c74e405e 100644 --- a/data-viewer/app/viewer/index.html +++ b/data-viewer/app/viewer/index.html @@ -7,13 +7,14 @@ @@ -61,7 +62,7 @@ -
+
{{ value }}
@@ -71,6 +72,9 @@
{{ col.name }}
+
+ Error: {{ error.code }} – {{ error.message }} +

From 7accf1ae237022d786fa0c1d928c4a825b68dfc2 Mon Sep 17 00:00:00 2001 From: Daniel Hutzel Date: Thu, 3 Feb 2022 04:35:56 +0100 Subject: [PATCH 08/17] Using only bob as reviewer (#315) --- reviews/db/data/sap.capire.reviews-Reviews.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reviews/db/data/sap.capire.reviews-Reviews.csv b/reviews/db/data/sap.capire.reviews-Reviews.csv index 9b7806dd..90112979 100644 --- a/reviews/db/data/sap.capire.reviews-Reviews.csv +++ b/reviews/db/data/sap.capire.reviews-Reviews.csv @@ -1,5 +1,5 @@ subject;rating;reviewer;title;text -201;5;adam;Intriguing;Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. +201;5;bob;Intriguing;Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. 201;4;bob;Fascinating;Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Id diam maecenas ultricies mi eget mauris pharetra et. Risus at ultrices mi tempus imperdiet nulla malesuada pellentesque. Pulvinar mattis nunc sed blandit libero. Facilisis magna etiam tempor orci eu. Nec sagittis aliquam malesuada bibendum arcu. Eu consequat ac felis donec. Ultricies tristique nulla aliquet enim tortor at auctor urna nunc. Tortor posuere ac ut consequat semper viverra nam libero. Amet nisl suscipit adipiscing bibendum est ultricies integer quis auctor. Scelerisque purus semper eget duis at tellus. Elementum tempus egestas sed sed risus pretium. Arcu dictum varius duis at. Amet luctus venenatis lectus magna fringilla urna. Eget velit aliquet sagittis id consectetur purus ut faucibus. Vitae auctor eu augue ut lectus. Fermentum iaculis eu non diam phasellus vestibulum. 207;2;bob;What is this?;Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Libero justo laoreet sit amet cursus sit amet dictum. Nunc faucibus a pellentesque sit. Dis parturient montes nascetur ridiculus mus mauris vitae ultricies. Enim nunc faucibus a pellentesque. Commodo quis imperdiet massa tincidunt nunc pulvinar sapien. Cras ornare arcu dui vivamus. Facilisi etiam dignissim diam quis enim lobortis. Et molestie ac feugiat sed. Urna neque viverra justo nec ultrices dui. Ullamcorper a lacus vestibulum sed arcu non. Volutpat ac tincidunt vitae semper quis. Dignissim sodales ut eu sem. Feugiat in fermentum posuere urna nec. At augue eget arcu dictum varius. 251;3;bob;It's dark...;Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Suscipit tellus mauris a diam. Velit aliquet sagittis id consectetur purus ut. Viverra adipiscing at in tellus integer. Vitae elementum curabitur vitae nunc. Mattis ullamcorper velit sed ullamcorper morbi. Diam quis enim lobortis scelerisque. Auctor neque vitae tempus quam pellentesque nec nam aliquam. Semper auctor neque vitae tempus. Quis eleifend quam adipiscing vitae proin. Neque convallis a cras semper auctor neque vitae. Imperdiet massa tincidunt nunc pulvinar sapien et ligula. Sit amet consectetur adipiscing elit ut aliquam purus. Pretium quam vulputate dignissim suspendisse. \ No newline at end of file From 8197559065bcd381fabc1962bf30baf3770dce66 Mon Sep 17 00:00:00 2001 From: sjvans <30337871+sjvans@users.noreply.github.com> Date: Thu, 3 Feb 2022 18:04:10 +0100 Subject: [PATCH 09/17] fix: app crashes if SELECT results in null (#298) --- bookshop/srv/cat-service.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bookshop/srv/cat-service.js b/bookshop/srv/cat-service.js index a9c629c0..9fa85cca 100644 --- a/bookshop/srv/cat-service.js +++ b/bookshop/srv/cat-service.js @@ -8,7 +8,9 @@ class CatalogService extends cds.ApplicationService { init(){ this.on ('submitOrder', async req => { const {book,quantity} = req.data if (quantity < 1) return req.reject (400,`quantity has to be 1 or more`) - let {stock} = await SELECT `stock` .from (Books,book) + let b = await SELECT `stock` .from (Books,book) + if (!b) return req.error (404,`Book #${book} doesn't exist`) + let {stock} = b if (quantity > stock) return req.reject (409,`${quantity} exceeds stock for book #${book}`) await UPDATE (Books,book) .with ({ stock: stock -= quantity }) await this.emit ('OrderedBook', { book, quantity, buyer:req.user.id }) From bc03cae550a4a4406f1dd325a464e12400fcd25e Mon Sep 17 00:00:00 2001 From: Daniel Hutzel Date: Fri, 4 Feb 2022 16:19:54 +0100 Subject: [PATCH 10/17] fix duplicate annotates (#317) --- fiori/app/admin-books/fiori-service.cds | 5 +++-- reviews/db/schema.cds | 5 ++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fiori/app/admin-books/fiori-service.cds b/fiori/app/admin-books/fiori-service.cds index 58b4cc1c..d7b1cd57 100644 --- a/fiori/app/admin-books/fiori-service.cds +++ b/fiori/app/admin-books/fiori-service.cds @@ -64,8 +64,9 @@ annotate AdminService.Books.texts with @( // Add Value Help for Locales annotate AdminService.Books.texts { - locale @ValueList:{entity:'Languages'}; - locale @Common.ValueListWithFixedValues:true; //show as drop down, not a dialog + 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'; diff --git a/reviews/db/schema.cds b/reviews/db/schema.cds index 456ef13d..2af0c7d8 100644 --- a/reviews/db/schema.cds +++ b/reviews/db/schema.cds @@ -32,7 +32,6 @@ entity Likes { // Auto-fill reviewers and review dates annotate Reviews with { - reviewer @cds.on.insert:$user; - date @cds.on.insert:$now; - date @cds.on.update:$now; + reviewer @cds.on:{insert:$user}; + date @cds.on:{insert:$now,update:$now}; } From 0f03ffd3eb5f4c0901ce071d92fa0d39743b9099 Mon Sep 17 00:00:00 2001 From: Vladimirs Semikins Date: Mon, 7 Feb 2022 10:38:28 +0200 Subject: [PATCH 11/17] adds @sap/cds dependency to package.json To avoid further questions (e.g. https://answers.sap.com/questions/13577720/i-push-my-capnodejsto-btp-environment-but-always-c.html) this PR will add missing `@sap/cds` dependency. --- hello/package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hello/package.json b/hello/package.json index 98ecf01e..5761592d 100644 --- a/hello/package.json +++ b/hello/package.json @@ -6,6 +6,9 @@ "start": "cds serve srv/world.cds", "start:ts": "cds-ts serve srv/world.cds" }, + "dependencies": { + "@sap/cds": "^5.0.4", + }, "devDependencies": { "@types/jest": "^27.0.2", "@types/node": "^16.11.6", From 0bce8d9ce0101d446d3c2b77ffea3e815b69437a Mon Sep 17 00:00:00 2001 From: Christian Georgi Date: Mon, 7 Feb 2022 09:52:17 +0100 Subject: [PATCH 12/17] Fix glitch --- hello/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hello/package.json b/hello/package.json index 5761592d..e7ca41d1 100644 --- a/hello/package.json +++ b/hello/package.json @@ -7,7 +7,7 @@ "start:ts": "cds-ts serve srv/world.cds" }, "dependencies": { - "@sap/cds": "^5.0.4", + "@sap/cds": "^5.0.4" }, "devDependencies": { "@types/jest": "^27.0.2", From dbc561d2e35646df8cb6fb4ae8baed90bb0b29b5 Mon Sep 17 00:00:00 2001 From: Christian Georgi Date: Tue, 1 Feb 2022 22:56:47 +0100 Subject: [PATCH 13/17] Show errors in UI, migrate to Vue 3 --- data-viewer/app/viewer/app.js | 19 +++++++++---------- data-viewer/app/viewer/index.html | 9 +++++---- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/data-viewer/app/viewer/app.js b/data-viewer/app/viewer/app.js index 41e806d2..51130af0 100644 --- a/data-viewer/app/viewer/app.js +++ b/data-viewer/app/viewer/app.js @@ -9,11 +9,9 @@ const columnKeysFirst = (c1, c2) => { return 0 // retain natural order of normal columns } -const vue = new Vue ({ +const vue = Vue.createApp ({ - el:'#app', - - data: { + data() { return { error: undefined, dataSource: storageGet('data-source', 'db'), skip: storageGet('skip', 0), @@ -24,7 +22,7 @@ const vue = new Vue ({ data: [], rowDetails: {}, rowKey: storageGet('rowKey') - }, + }}, watch: { dataSource: (v) => { storageSet('data-source', v); vue.fetchEntities() }, @@ -77,13 +75,13 @@ const vue = new Vue ({ else vue.rowDetails = {} vue.error = undefined } catch (err) { - if (err.response?.data?.error) { - vue.error = err.response?.data?.error - } else { - vue.error = err - } vue.data = [] vue.rowDetails = {} + if (err.response?.data?.error) { + vue.error = err.response.data.error + } else { + vue.error = { code:err.code, message:err.message } + } } }, @@ -116,5 +114,6 @@ const vue = new Vue ({ } }) +.mount('#app') vue.fetchEntities() diff --git a/data-viewer/app/viewer/index.html b/data-viewer/app/viewer/index.html index 1ec4f1ff..9fd723a1 100644 --- a/data-viewer/app/viewer/index.html +++ b/data-viewer/app/viewer/index.html @@ -5,7 +5,9 @@ Data Browser - + + +