diff --git a/cap-notebook/demoapp/app/_i18n/i18n.properties b/cap-notebook/demoapp/app/_i18n/i18n.properties index fd0c6145a..1191e2e0d 100644 --- a/cap-notebook/demoapp/app/_i18n/i18n.properties +++ b/cap-notebook/demoapp/app/_i18n/i18n.properties @@ -21,3 +21,44 @@ attachment_status = Status attachment_note = Note attachment = Attachment attachments = Attachments +reference = Reference +references = References + +#XFLD,50: Label for a section +Chapters=Chapters + +#XFLD,120: Label for entity +Chapter=Chapter + +#XFLD,120: Label for a field +ChapterTitle=Chapter Title + +#XFLD,120: Label for a field +ChapterType=Chapter Type + +#XFLD,50: Label for a section +Pages=Pages + +#XFLD,120: Label for entity +Page=Page + +#XFLD,120: Label for a field +PageTitle=Page Title + +#XFLD,120: Label for a field +PageType=Page Type + +#XFLD,50: Label for a section +Footnotes=Footnotes + +#XFLD,120: Label for a field +Description=Description + +#XFLD,120: Label for a field +URL=URL + +#XFLD,50: Label for a section +GeneralInformation=General Information + +#XFLD,50: Label for a section +Attachments=Attachments diff --git a/cap-notebook/demoapp/app/_i18n/i18n_de.properties b/cap-notebook/demoapp/app/_i18n/i18n_de.properties index cb712c12c..7046fa3e8 100644 --- a/cap-notebook/demoapp/app/_i18n/i18n_de.properties +++ b/cap-notebook/demoapp/app/_i18n/i18n_de.properties @@ -12,4 +12,40 @@ Stock = Bestand Order = Bestellung Orders = Bestellungen Price = Preis -Genre = Genre \ No newline at end of file +Genre = Genre + +#XFLD,50: Label for a section +Chapters=Kapitel + +#XFLD,120: Label for entity +Chapter=Kapitel + +#XFLD,120: Label for a field +ChapterTitle=Kapitel Titel + +#XFLD,120: Label for a field +ChapterType=Kapitel Typ + +#XFLD,50: Label for a section +Pages=Seiten + +#XFLD,120: Label for entity +Page=Seite + +#XFLD,120: Label for a field +PageTitle=Seiten Titel + +#XFLD,120: Label for a field +PageType=Seiten Typ + +#XFLD,50: Label for a section +Footnotes=Fußnoten + +#XFLD,120: Label for a field +Description=Beschreibung + +#XFLD,120: Label for a field +URL=URL + +#XFLD,50: Label for a section +GeneralInformation=Allgemeine Informationen \ No newline at end of file diff --git a/cap-notebook/demoapp/app/admin-books/fiori-service.cds b/cap-notebook/demoapp/app/admin-books/fiori-service.cds index d8cd8382b..de8e3171d 100644 --- a/cap-notebook/demoapp/app/admin-books/fiori-service.cds +++ b/cap-notebook/demoapp/app/admin-books/fiori-service.cds @@ -30,7 +30,7 @@ annotate AdminService.Books with @(UI: { { $Type : 'UI.ReferenceFacet', ID : 'ReferencesFacet', - Label : 'References', + Label : '{i18n>references}', Target: 'references/@UI.LineItem' }, { @@ -43,7 +43,19 @@ annotate AdminService.Books with @(UI: { $Type : 'UI.ReferenceFacet', Label : '{i18n>Admin}', Target: '@UI.FieldGroup#Admin' - } + }, + { + $Type : 'UI.ReferenceFacet', + Label : '{i18n>Chapters}', + ID : 'i18nChapters', + Target : 'chapters/@UI.LineItem#i18nChapters', + }, + { + $Type : 'UI.ReferenceFacet', + Label : '{i18n>Pages}', + ID : 'i18nPages', + Target : 'pages/@UI.LineItem#i18nPages', + }, ], FieldGroup #General: {Data: [ {Value: title}, @@ -67,6 +79,236 @@ annotate AdminService.Books with @(UI: { ]} }); +////////// + +// Chapters annotations +annotate AdminService.Chapters with @title : '{i18n>Chapter}'; + +annotate AdminService.Books.chapters with @( + title : '{i18n>Chapters}' +); + +annotate AdminService.Chapters with @( + UI.LineItem : [ + { + $Type : 'UI.DataField', + Value : title, + Label : '{i18n>ChapterTitle}', + }, + { + $Type : 'UI.DataField', + Value : chapterType, + Label : '{i18n>ChapterType}', + }, + { + $Type : 'UI.DataField', + Value : description, + Label : '{i18n>Description}', + }, + ], + UI.LineItem #i18nChapters : [ + { + $Type : 'UI.DataField', + Value : title, + Label : '{i18n>ChapterTitle}', + }, + { + $Type : 'UI.DataField', + Value : chapterType, + Label : '{i18n>ChapterType}', + }, + { + $Type : 'UI.DataField', + Value : description, + Label : '{i18n>Description}', + }, + ] +); + +annotate AdminService.Chapters with @( + UI.HeaderInfo : { + Title : { + $Type : 'UI.DataField', + Value : title, + }, + TypeName : '{i18n>Chapter}', + TypeNamePlural : '{i18n>Chapters}', + Description : { + $Type : 'UI.DataField', + Value : description, + }, + } +); + +annotate AdminService.Chapters with @( + UI.FieldGroup #GeneratedGroup1 : { + $Type : 'UI.FieldGroupType', + Data : [ + { + $Type : 'UI.DataField', + Value : title, + Label : '{i18n>ChapterTitle}', + }, + { + $Type : 'UI.DataField', + Value : chapterType, + Label : '{i18n>ChapterType}', + }, + { + $Type : 'UI.DataField', + Value : description, + Label : '{i18n>Description}', + }, + { + $Type : 'UI.DataField', + Value : url, + Label : '{i18n>URL}', + }, + ], + }, + UI.Facets : [ + { + $Type : 'UI.ReferenceFacet', + ID : 'GeneratedFacet1', + Label : '{i18n>GeneralInformation}', + Target : '@UI.FieldGroup#GeneratedGroup1', + }, + { + $Type : 'UI.ReferenceFacet', + ID : 'AttachmentsFacet', + Label : '{i18n>attachments}', + Target : 'attachments/@UI.LineItem' + }, + { + $Type : 'UI.ReferenceFacet', + ID : 'ReferencesFacet', + Label : '{i18n>references}', + Target : 'references/@UI.LineItem' + }, + { + $Type : 'UI.ReferenceFacet', + ID : 'FootnotesFacet', + Label : '{i18n>Footnotes}', + Target : 'footnotes/@UI.LineItem' + } + ] +); + +////////// + +// Pages annotations +annotate AdminService.Pages with @title : '{i18n>Page}'; + +annotate AdminService.Books.pages with @( + title : '{i18n>Pages}' +); + +annotate AdminService.Pages with @( + UI.LineItem : [ + { + $Type : 'UI.DataField', + Value : title, + Label : '{i18n>PageTitle}', + }, + { + $Type : 'UI.DataField', + Value : pageType, + Label : '{i18n>PageType}', + }, + { + $Type : 'UI.DataField', + Value : description, + Label : '{i18n>Description}', + }, + ], + UI.LineItem #i18nPages : [ + { + $Type : 'UI.DataField', + Value : title, + Label : '{i18n>PageTitle}', + }, + { + $Type : 'UI.DataField', + Value : pageType, + Label : '{i18n>PageType}', + }, + { + $Type : 'UI.DataField', + Value : description, + Label : '{i18n>Description}', + }, + ] +); + +annotate AdminService.Pages with @( + UI.HeaderInfo : { + Title : { + $Type : 'UI.DataField', + Value : title, + }, + TypeName : '{i18n>Page}', + TypeNamePlural : '{i18n>Pages}', + Description : { + $Type : 'UI.DataField', + Value : description, + }, + } +); + +annotate AdminService.Pages with @( + UI.FieldGroup #GeneratedGroup1 : { + $Type : 'UI.FieldGroupType', + Data : [ + { + $Type : 'UI.DataField', + Value : title, + Label : '{i18n>PageTitle}', + }, + { + $Type : 'UI.DataField', + Value : pageType, + Label : '{i18n>PageType}', + }, + { + $Type : 'UI.DataField', + Value : description, + Label : '{i18n>Description}', + }, + { + $Type : 'UI.DataField', + Value : url, + Label : '{i18n>URL}', + }, + ], + }, + UI.Facets : [ + { + $Type : 'UI.ReferenceFacet', + ID : 'GeneratedFacet1', + Label : '{i18n>GeneralInformation}', + Target : '@UI.FieldGroup#GeneratedGroup1', + }, + { + $Type : 'UI.ReferenceFacet', + ID : 'AttachmentsFacet', + Label : '{i18n>attachments}', + Target : 'attachments/@UI.LineItem' + }, + { + $Type : 'UI.ReferenceFacet', + ID : 'ReferencesFacet', + Label : '{i18n>references}', + Target : 'references/@UI.LineItem' + }, + { + $Type : 'UI.ReferenceFacet', + ID : 'FootnotesFacet', + Label : '{i18n>Footnotes}', + Target : 'footnotes/@UI.LineItem' + } + ] +); + //////////////////////////////////////////////////////////// // diff --git a/cap-notebook/demoapp/app/admin-books/webapp/manifest.json b/cap-notebook/demoapp/app/admin-books/webapp/manifest.json index 3d92bc9bb..24cc3f714 100644 --- a/cap-notebook/demoapp/app/admin-books/webapp/manifest.json +++ b/cap-notebook/demoapp/app/admin-books/webapp/manifest.json @@ -83,6 +83,16 @@ "pattern": "Books({key}/author({key2}):?query:", "name": "AuthorsDetails", "target": "AuthorsDetails" + }, + { + "pattern": "Books({key})/chapters({key2}):?query:", + "name": "chaptersObjectPage", + "target": "ChaptersObjectPage" + }, + { + "pattern": "Books({key})/pages({key2}):?query:", + "name": "pagesObjectPage", + "target": "PagesObjectPage" } ], "targets": { @@ -112,9 +122,14 @@ "settings": { "entitySet": "Books", "navigation": { - "Authors": { + "Chapters": { "detail": { - "route": "AuthorsDetails" + "route": "ChaptersObjectPage" + } + }, + "Pages": { + "detail": { + "route": "PagesObjectPage" } } }, @@ -144,6 +159,87 @@ } } }, + "ChaptersObjectPage": { + "type": "Component", + "id": "ChaptersObjectPage", + "name": "sap.fe.templates.ObjectPage", + "options": { + "settings": { + "editableHeaderContent": false, + "entitySet": "Chapters", + "controlConfiguration": { + "attachments/@com.sap.vocabularies.UI.v1.LineItem": { + "tableSettings": { + "type": "ResponsiveTable", + "selectionMode": "Auto", + "rowPress": ".extension.books.controller.custom.onRowPress" + } + }, + "references/@com.sap.vocabularies.UI.v1.LineItem": { + "tableSettings": { + "type": "ResponsiveTable", + "selectionMode": "Auto", + "rowPress": ".extension.books.controller.custom.onRowPress" + } + }, + "footnotes/@com.sap.vocabularies.UI.v1.LineItem": { + "tableSettings": { + "type": "ResponsiveTable", + "selectionMode": "Auto", + "rowPress": ".extension.books.controller.custom.onRowPress" + } + } + } + } + } + }, + "PagesObjectPage": { + "type": "Component", + "id": "PagesObjectPage", + "name": "sap.fe.templates.ObjectPage", + "options": { + "settings": { + "editableHeaderContent": false, + "entitySet": "Pages", + "navigation": {}, + "controlConfiguration": { + "attachments/@com.sap.vocabularies.UI.v1.LineItem": { + "tableSettings": { + "type": "ResponsiveTable", + "selectionMode": "Auto", + "rowPress": ".extension.books.controller.custom.onRowPress" + } + }, + "references/@com.sap.vocabularies.UI.v1.LineItem": { + "tableSettings": { + "type": "ResponsiveTable", + "selectionMode": "Auto", + "rowPress": ".extension.books.controller.custom.onRowPress" + } + }, + "footnotes/@com.sap.vocabularies.UI.v1.LineItem": { + "tableSettings": { + "type": "ResponsiveTable", + "selectionMode": "Auto", + "rowPress": ".extension.books.controller.custom.onRowPress" + } + } + } + } + } + }, + "SectionsObjectPage": { + "type": "Component", + "id": "SectionsObjectPage", + "name": "sap.fe.templates.ObjectPage", + "options": { + "settings": { + "editableHeaderContent": false, + "entitySet": "Sections", + "navigation": {} + } + } + }, "AuthorsDetails": { "type": "Component", "id": "AuthorsDetailsList", @@ -161,7 +257,13 @@ "sap.ui.controllerExtensions": { "sap.fe.templates.ObjectPage.ObjectPageController#books::BooksDetailsList": { "controllerName": "books.controller.custom" - } + }, + "sap.fe.templates.ObjectPage.ObjectPageController#books::ChaptersObjectPage": { + "controllerName": "books.controller.custom" + }, + "sap.fe.templates.ObjectPage.ObjectPageController#books::PagesObjectPage": { + "controllerName": "books.controller.custom" + } } } }, diff --git a/cap-notebook/demoapp/app/common.cds b/cap-notebook/demoapp/app/common.cds index 515445386..bf73758fd 100644 --- a/cap-notebook/demoapp/app/common.cds +++ b/cap-notebook/demoapp/app/common.cds @@ -254,18 +254,433 @@ annotate my.Books.footnotes with @UI: { @HTML5.CssDefaults: {width: '4%'} } ], -} { - note @(title: '{i18n>Note}'); - fileName @(title: '{i18n>Filename}'); - modifiedAt @(odata.etag: null); - content - @Core.ContentDisposition: { Filename: fileName } - @(title: '{i18n>Attachment}'); - folderId @UI.Hidden; - repositoryId @UI.Hidden ; - objectId @UI.Hidden ; - mimeType @UI.Hidden; - status @UI.Hidden; +} +{ + note @(title: '{i18n>Note}'); + fileName @(title: '{i18n>Filename}'); + modifiedAt @(odata.etag: null); + content + @Core.ContentDisposition: { Filename: fileName } + @(title: '{i18n>Attachment}'); + folderId @UI.Hidden; + repositoryId @UI.Hidden ; + objectId @UI.Hidden ; + mimeType @UI.Hidden; + status @UI.Hidden; +} + +annotate my.Chapters.attachments with @UI: { + HeaderInfo: { + $Type : 'UI.HeaderInfoType', + TypeName : '{i18n>Attachment}', + TypeNamePlural: '{i18n>Attachments}', + }, + LineItem : [ + {Value: type, @HTML5.CssDefaults: {width: '10%'}}, + {Value: fileName, @HTML5.CssDefaults: {width: '25%'}}, + {Value: content, @HTML5.CssDefaults: {width: '0%'}}, + {Value: createdAt, @HTML5.CssDefaults: {width: '20%'}}, + {Value: createdBy, @HTML5.CssDefaults: {width: '20%'}}, + {Value: note, @HTML5.CssDefaults: {width: '25%'}}, + { + $Type : 'UI.DataFieldForAction', + Label : 'Copy Attachments', + Action: 'AdminService.copyAttachments', + }, + { + $Type : 'UI.DataFieldForActionGroup', + ID : 'TableActionGroup', + Label : 'Create', + ![@UI.Hidden]: {$edmJson: {$Eq: [ {$Path: 'IsActiveEntity'}, true ]}}, + Actions: [ + { + $Type : 'UI.DataFieldForAction', + Label : 'Link', + Action: 'AdminService.createLink' + } + ] + }, + { + @UI.Hidden: {$edmJson: { + $If: [ + { $Eq: [ { $Path: 'IsActiveEntity' }, true ] }, + true, + { + $If: [ + { $Ne: [ { $Path: 'mimeType' }, 'application/internet-shortcut' ] }, + true, + false + ] + } + ] + } + }, + $Type : 'UI.DataFieldForAction', + Label : 'Edit Link', + Action: 'AdminService.editLink', + Inline: true, + IconUrl: 'sap-icon://edit', + @HTML5.CssDefaults: {width: '4%'} + } + ], +} +{ + note @(title: '{i18n>Note}'); + fileName @(title: '{i18n>Filename}'); + modifiedAt @(odata.etag: null); + content + @Core.ContentDisposition: { Filename: fileName } + @(title: '{i18n>Attachment}'); + folderId @UI.Hidden; + repositoryId @UI.Hidden ; + objectId @UI.Hidden ; + mimeType @UI.Hidden; + status @UI.Hidden; +} + +annotate my.Chapters.references with @UI: { + HeaderInfo: { + $Type : 'UI.HeaderInfoType', + TypeName : '{i18n>Reference}', + TypeNamePlural: '{i18n>References}', + }, + LineItem : [ + {Value: type, @HTML5.CssDefaults: {width: '10%'}}, + {Value: fileName, @HTML5.CssDefaults: {width: '25%'}}, + {Value: content, @HTML5.CssDefaults: {width: '0%'}}, + {Value: createdAt, @HTML5.CssDefaults: {width: '20%'}}, + {Value: createdBy, @HTML5.CssDefaults: {width: '20%'}}, + {Value: note, @HTML5.CssDefaults: {width: '25%'}}, + { + $Type : 'UI.DataFieldForAction', + Label : 'Copy References', + Action: 'AdminService.copyAttachments', + }, + { + $Type : 'UI.DataFieldForActionGroup', + ID : 'TableActionGroup', + Label : 'Create', + ![@UI.Hidden]: {$edmJson: {$Eq: [ {$Path: 'IsActiveEntity'}, true ]}}, + Actions: [ + { + $Type : 'UI.DataFieldForAction', + Label : 'Link', + Action: 'AdminService.createLink' + } + ] + }, + { + @UI.Hidden: {$edmJson: { + $If: [ + { $Eq: [ { $Path: 'IsActiveEntity' }, true ] }, + true, + { + $If: [ + { $Ne: [ { $Path: 'mimeType' }, 'application/internet-shortcut' ] }, + true, + false + ] + } + ] + } + }, + $Type : 'UI.DataFieldForAction', + Label : 'Edit Link', + Action: 'AdminService.editLink', + Inline: true, + IconUrl: 'sap-icon://edit', + @HTML5.CssDefaults: {width: '4%'} + } + ], +} +{ + note @(title: '{i18n>Note}'); + fileName @(title: '{i18n>Filename}'); + modifiedAt @(odata.etag: null); + content + @Core.ContentDisposition: { Filename: fileName } + @(title: '{i18n>Attachment}'); + folderId @UI.Hidden; + repositoryId @UI.Hidden ; + objectId @UI.Hidden ; + mimeType @UI.Hidden; + status @UI.Hidden; +} + +annotate my.Chapters.footnotes with @UI: { + HeaderInfo: { + $Type : 'UI.HeaderInfoType', + TypeName : '{i18n>Footnote}', + TypeNamePlural: '{i18n>Footnotes}', + }, + LineItem : [ + {Value: type, @HTML5.CssDefaults: {width: '10%'}}, + {Value: fileName, @HTML5.CssDefaults: {width: '25%'}}, + {Value: content, @HTML5.CssDefaults: {width: '0%'}}, + {Value: createdAt, @HTML5.CssDefaults: {width: '20%'}}, + {Value: createdBy, @HTML5.CssDefaults: {width: '20%'}}, + {Value: note, @HTML5.CssDefaults: {width: '25%'}}, + { + $Type : 'UI.DataFieldForAction', + Label : 'Copy Footnotes', + Action: 'AdminService.copyAttachments', + }, + { + $Type : 'UI.DataFieldForActionGroup', + ID : 'TableActionGroup', + Label : 'Create', + ![@UI.Hidden]: {$edmJson: {$Eq: [ {$Path: 'IsActiveEntity'}, true ]}}, + Actions: [ + { + $Type : 'UI.DataFieldForAction', + Label : 'Link', + Action: 'AdminService.createLink' + } + ] + }, + { + @UI.Hidden: {$edmJson: { + $If: [ + { $Eq: [ { $Path: 'IsActiveEntity' }, true ] }, + true, + { + $If: [ + { $Ne: [ { $Path: 'mimeType' }, 'application/internet-shortcut' ] }, + true, + false + ] + } + ] + } + }, + $Type : 'UI.DataFieldForAction', + Label : 'Edit Link', + Action: 'AdminService.editLink', + Inline: true, + IconUrl: 'sap-icon://edit', + @HTML5.CssDefaults: {width: '4%'} + } + ], +} +{ + note @(title: '{i18n>Note}'); + fileName @(title: '{i18n>Filename}'); + modifiedAt @(odata.etag: null); + content + @Core.ContentDisposition: { Filename: fileName } + @(title: '{i18n>Attachment}'); + folderId @UI.Hidden; + repositoryId @UI.Hidden ; + objectId @UI.Hidden ; + mimeType @UI.Hidden; + status @UI.Hidden; +} + +annotate my.Pages.attachments with @UI: { + HeaderInfo: { + $Type : 'UI.HeaderInfoType', + TypeName : '{i18n>Attachment}', + TypeNamePlural: '{i18n>Attachments}', + }, + LineItem : [ + {Value: type, @HTML5.CssDefaults: {width: '10%'}}, + {Value: fileName, @HTML5.CssDefaults: {width: '25%'}}, + {Value: content, @HTML5.CssDefaults: {width: '0%'}}, + {Value: createdAt, @HTML5.CssDefaults: {width: '20%'}}, + {Value: createdBy, @HTML5.CssDefaults: {width: '20%'}}, + {Value: note, @HTML5.CssDefaults: {width: '25%'}}, + { + $Type : 'UI.DataFieldForAction', + Label : 'Copy Attachments', + Action: 'AdminService.copyAttachments', + }, + { + $Type : 'UI.DataFieldForActionGroup', + ID : 'TableActionGroup', + Label : 'Create', + ![@UI.Hidden]: {$edmJson: {$Eq: [ {$Path: 'IsActiveEntity'}, true ]}}, + Actions: [ + { + $Type : 'UI.DataFieldForAction', + Label : 'Link', + Action: 'AdminService.createLink' + } + ] + }, + { + @UI.Hidden: {$edmJson: { + $If: [ + { $Eq: [ { $Path: 'IsActiveEntity' }, true ] }, + true, + { + $If: [ + { $Ne: [ { $Path: 'mimeType' }, 'application/internet-shortcut' ] }, + true, + false + ] + } + ] + } + }, + $Type : 'UI.DataFieldForAction', + Label : 'Edit Link', + Action: 'AdminService.editLink', + Inline: true, + IconUrl: 'sap-icon://edit', + @HTML5.CssDefaults: {width: '4%'} + } + ], +} +{ + note @(title: '{i18n>Note}'); + fileName @(title: '{i18n>Filename}'); + modifiedAt @(odata.etag: null); + content + @Core.ContentDisposition: { Filename: fileName } + @(title: '{i18n>Attachment}'); + folderId @UI.Hidden; + repositoryId @UI.Hidden ; + objectId @UI.Hidden ; + mimeType @UI.Hidden; + status @UI.Hidden; +} + +annotate my.Pages.references with @UI: { + HeaderInfo: { + $Type : 'UI.HeaderInfoType', + TypeName : '{i18n>Reference}', + TypeNamePlural: '{i18n>References}', + }, + LineItem : [ + {Value: type, @HTML5.CssDefaults: {width: '10%'}}, + {Value: fileName, @HTML5.CssDefaults: {width: '25%'}}, + {Value: content, @HTML5.CssDefaults: {width: '0%'}}, + {Value: createdAt, @HTML5.CssDefaults: {width: '20%'}}, + {Value: createdBy, @HTML5.CssDefaults: {width: '20%'}}, + {Value: note, @HTML5.CssDefaults: {width: '25%'}}, + { + $Type : 'UI.DataFieldForAction', + Label : 'Copy References', + Action: 'AdminService.copyAttachments', + }, + { + $Type : 'UI.DataFieldForActionGroup', + ID : 'TableActionGroup', + Label : 'Create', + ![@UI.Hidden]: {$edmJson: {$Eq: [ {$Path: 'IsActiveEntity'}, true ]}}, + Actions: [ + { + $Type : 'UI.DataFieldForAction', + Label : 'Link', + Action: 'AdminService.createLink' + } + ] + }, + { + @UI.Hidden: {$edmJson: { + $If: [ + { $Eq: [ { $Path: 'IsActiveEntity' }, true ] }, + true, + { + $If: [ + { $Ne: [ { $Path: 'mimeType' }, 'application/internet-shortcut' ] }, + true, + false + ] + } + ] + } + }, + $Type : 'UI.DataFieldForAction', + Label : 'Edit Link', + Action: 'AdminService.editLink', + Inline: true, + IconUrl: 'sap-icon://edit', + @HTML5.CssDefaults: {width: '4%'} + } + ], +} +{ + note @(title: '{i18n>Note}'); + fileName @(title: '{i18n>Filename}'); + modifiedAt @(odata.etag: null); + content + @Core.ContentDisposition: { Filename: fileName } + @(title: '{i18n>Attachment}'); + folderId @UI.Hidden; + repositoryId @UI.Hidden ; + objectId @UI.Hidden ; + mimeType @UI.Hidden; + status @UI.Hidden; +} + +annotate my.Pages.footnotes with @UI: { + HeaderInfo: { + $Type : 'UI.HeaderInfoType', + TypeName : '{i18n>Footnote}', + TypeNamePlural: '{i18n>Footnotes}', + }, + LineItem : [ + {Value: type, @HTML5.CssDefaults: {width: '10%'}}, + {Value: fileName, @HTML5.CssDefaults: {width: '25%'}}, + {Value: content, @HTML5.CssDefaults: {width: '0%'}}, + {Value: createdAt, @HTML5.CssDefaults: {width: '20%'}}, + {Value: createdBy, @HTML5.CssDefaults: {width: '20%'}}, + {Value: note, @HTML5.CssDefaults: {width: '25%'}}, + { + $Type : 'UI.DataFieldForAction', + Label : 'Copy Footnotes', + Action: 'AdminService.copyAttachments', + }, + { + $Type : 'UI.DataFieldForActionGroup', + ID : 'TableActionGroup', + Label : 'Create', + ![@UI.Hidden]: {$edmJson: {$Eq: [ {$Path: 'IsActiveEntity'}, true ]}}, + Actions: [ + { + $Type : 'UI.DataFieldForAction', + Label : 'Link', + Action: 'AdminService.createLink' + } + ] + }, + { + @UI.Hidden: {$edmJson: { + $If: [ + { $Eq: [ { $Path: 'IsActiveEntity' }, true ] }, + true, + { + $If: [ + { $Ne: [ { $Path: 'mimeType' }, 'application/internet-shortcut' ] }, + true, + false + ] + } + ] + } + }, + $Type : 'UI.DataFieldForAction', + Label : 'Edit Link', + Action: 'AdminService.editLink', + Inline: true, + IconUrl: 'sap-icon://edit', + @HTML5.CssDefaults: {width: '4%'} + } + ], +} +{ + note @(title: '{i18n>Note}'); + fileName @(title: '{i18n>Filename}'); + modifiedAt @(odata.etag: null); + content + @Core.ContentDisposition: { Filename: fileName } + @(title: '{i18n>Attachment}'); + folderId @UI.Hidden; + repositoryId @UI.Hidden ; + objectId @UI.Hidden ; + mimeType @UI.Hidden; + status @UI.Hidden; } //////////////////////////////////////////////////////////////////////////// diff --git a/cap-notebook/demoapp/db/schema.cds b/cap-notebook/demoapp/db/schema.cds index aed7d8725..0a0a82448 100644 --- a/cap-notebook/demoapp/db/schema.cds +++ b/cap-notebook/demoapp/db/schema.cds @@ -1,39 +1,67 @@ using { - Currency, - managed, - cuid, - sap.common.CodeList +Currency, +managed, +cuid, +sap.common.CodeList } from '@sap/cds/common'; namespace sap.capire.bookshop; entity Books : managed, cuid { - @mandatory title : localized String(111); - descr : localized String(1111); - @mandatory author : Association to Authors; - genre : Association to Genres; - stock : Integer; - price : Decimal; - currency : Currency; - image : LargeBinary @Core.MediaType: 'image/png'; +@mandatory title : localized String(111); +descr : localized String(1111); +@mandatory author : Association to Authors; +genre : Association to Genres; +stock : Integer; +price : Decimal; +currency : Currency; +image : LargeBinary @Core.MediaType: 'image/png'; + +// top-level chapters composition (root of the nested hierarchy) +chapters : Composition of many Chapters on chapters.book = $self; + +// top-level pages composition (same pattern as chapters) +pages : Composition of many Pages on pages.book = $self; + +// keep any other fields as before } entity Authors : managed, cuid { - @mandatory name : String(111); - dateOfBirth : Date; - dateOfDeath : Date; - placeOfBirth : String; - placeOfDeath : String; - books : Association to many Books - on books.author = $self; +@mandatory name : String(111); +dateOfBirth : Date; +dateOfDeath : Date; +placeOfBirth : String; +placeOfDeath : String; +books : Association to many Books +on books.author = $self; } /** Hierarchically organized Code List for Genres */ entity Genres : CodeList { - key ID : Integer; - parent : Association to Genres; - children : Composition of many Genres - on children.parent = $self; +key ID : Integer; +parent : Association to Genres; +children : Composition of many Genres +on children.parent = $self; +} + +// --- Nested composition entities to emulate deep structure --- + +// entity Chapters : cuid, managed { +// title : String(255); + +// // backlink to parent Book +// book : Association to Books; + +// // each chapter has many sections +// sections : Composition of many Sections on sections.chapter = $self; +// } + +entity Chapters : cuid, managed { + book : Association to Books; + title : String @title: 'Chapter Title'; + description : String; + url : String; + chapterType : String @title: 'Chapter Type'; } /** Adding {Notebooks,Writers} for user service */ @@ -47,6 +75,14 @@ entity Notebooks : managed, cuid { image : LargeBinary @Core.MediaType: 'image/png'; } +entity Pages : cuid, managed { + book : Association to Books; + title : String @title: 'Page Title'; + description : String; + url : String; + pageType : String @title: 'Page Type'; +} + entity Writers : managed, cuid { @mandatory name : String(111); dateOfBirth : Date; @@ -55,4 +91,4 @@ entity Writers : managed, cuid { placeOfDeath : String; notebooks : Association to many Notebooks on notebooks.writer = $self; -} \ No newline at end of file +} diff --git a/cap-notebook/demoapp/srv/admin-service.cds b/cap-notebook/demoapp/srv/admin-service.cds index eaa6b25b0..a2afc28c9 100644 --- a/cap-notebook/demoapp/srv/admin-service.cds +++ b/cap-notebook/demoapp/srv/admin-service.cds @@ -1,10 +1,13 @@ -using {sap.capire.bookshop as my} from '../db/schema'; - +using { sap.capire.bookshop as my } from '../db/schema'; service AdminService @(requires: ['admin','system-user']) { + entity Books as projection on my.Books; entity Authors as projection on my.Authors; + entity Chapters as projection on my.Chapters; + entity Pages as projection on my.Pages; + entity Books.attachments as projection on my.Books.attachments - actions { + actions { @(Common.SideEffects : {TargetEntities: ['']},) action copyAttachments(in:many $self, up__ID:String, objectIds:String); @@ -19,10 +22,10 @@ service AdminService @(requires: ['admin','system-user']) { @mandatory @assert.format:'^(https?:\/\/)(([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,}|localhost)(:\d{2,5})?(\/[^\s]*)?$' @Common.Label:'URL' url: String @UI.Placeholder: 'Example: https://www.example.com' ); action openAttachment() returns String; - } + }; entity Books.references as projection on my.Books.references - actions { + actions { @(Common.SideEffects : {TargetEntities: ['']},) action copyAttachments(in:many $self, up__ID:String, objectIds:String); @@ -37,10 +40,10 @@ service AdminService @(requires: ['admin','system-user']) { @mandatory @assert.format:'^(https?:\/\/)(([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,}|localhost)(:\d{2,5})?(\/[^\s]*)?$' @Common.Label:'URL' url: String @UI.Placeholder: 'Example: https://www.example.com' ); action openAttachment() returns String; - } - + }; + entity Books.footnotes as projection on my.Books.footnotes - actions { + actions { @(Common.SideEffects : {TargetEntities: ['']},) action copyAttachments(in:many $self, up__ID:String, objectIds:String); @@ -55,6 +58,115 @@ service AdminService @(requires: ['admin','system-user']) { @mandatory @assert.format:'^(https?:\/\/)(([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,}|localhost)(:\d{2,5})?(\/[^\s]*)?$' @Common.Label:'URL' url: String @UI.Placeholder: 'Example: https://www.example.com' ); action openAttachment() returns String; - } -} + }; + + entity Pages.attachments as projection on my.Pages.attachments + actions { + @(Common.SideEffects : {TargetEntities: ['']},) + action copyAttachments(in:many $self, up__ID:String, objectIds:String); + + @(Common.SideEffects : {TargetEntities: ['']},) + action createLink( + in:many $self, + @mandatory @Common.Label:'Name' name: String @UI.Placeholder: 'Enter a name for the link', + @mandatory @assert.format:'^(https?:\/\/)(([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,}|localhost)(:\d{2,5})?(\/[^\s]*)?$' @Common.Label:'URL' url: String @UI.Placeholder: 'Example: https://www.example.com' + ); + + action editLink( + @mandatory @assert.format:'^(https?:\/\/)(([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,}|localhost)(:\d{2,5})?(\/[^\s]*)?$' @Common.Label:'URL' url: String @UI.Placeholder: 'Example: https://www.example.com' + ); + action openAttachment() returns String; + }; + + entity Pages.references as projection on my.Pages.references + actions { + @(Common.SideEffects : {TargetEntities: ['']},) + action copyAttachments(in:many $self, up__ID:String, objectIds:String); + + @(Common.SideEffects : {TargetEntities: ['']},) + action createLink( + in:many $self, + @mandatory @Common.Label:'Name' name: String @UI.Placeholder: 'Enter a name for the link', + @mandatory @assert.format:'^(https?:\/\/)(([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,}|localhost)(:\d{2,5})?(\/[^\s]*)?$' @Common.Label:'URL' url: String @UI.Placeholder: 'Example: https://www.example.com' + ); + + action editLink( + @mandatory @assert.format:'^(https?:\/\/)(([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,}|localhost)(:\d{2,5})?(\/[^\s]*)?$' @Common.Label:'URL' url: String @UI.Placeholder: 'Example: https://www.example.com' + ); + action openAttachment() returns String; + }; + + // Chapters projections + entity Chapters.attachments as projection on my.Chapters.attachments + actions { + @(Common.SideEffects : {TargetEntities: ['']},) + action copyAttachments(in:many $self, up__ID:String, objectIds:String); + @(Common.SideEffects : {TargetEntities: ['']},) + action createLink( + in:many $self, + @mandatory @Common.Label:'Name' name: String @UI.Placeholder: 'Enter a name for the link', + @mandatory @assert.format:'^(https?:\/\/)(([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,}|localhost)(:\d{2,5})?(\/[^\s]*)?$' @Common.Label:'URL' url: String @UI.Placeholder: 'Example: https://www.example.com' + ); + + action editLink( + @mandatory @assert.format:'^(https?:\/\/)(([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,}|localhost)(:\d{2,5})?(\/[^\s]*)?$' @Common.Label:'URL' url: String @UI.Placeholder: 'Example: https://www.example.com' + ); + action openAttachment() returns String; + }; + + entity Chapters.references as projection on my.Chapters.references + actions { + @(Common.SideEffects : {TargetEntities: ['']},) + action copyAttachments(in:many $self, up__ID:String, objectIds:String); + + @(Common.SideEffects : {TargetEntities: ['']},) + action createLink( + in:many $self, + @mandatory @Common.Label:'Name' name: String @UI.Placeholder: 'Enter a name for the link', + @mandatory @assert.format:'^(https?:\/\/)(([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,}|localhost)(:\d{2,5})?(\/[^\s]*)?$' @Common.Label:'URL' url: String @UI.Placeholder: 'Example: https://www.example.com' + ); + + action editLink( + @mandatory @assert.format:'^(https?:\/\/)(([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,}|localhost)(:\d{2,5})?(\/[^\s]*)?$' @Common.Label:'URL' url: String @UI.Placeholder: 'Example: https://www.example.com' + ); + action openAttachment() returns String; + }; + + entity Chapters.footnotes as projection on my.Chapters.footnotes + actions { + @(Common.SideEffects : {TargetEntities: ['']},) + action copyAttachments(in:many $self, up__ID:String, objectIds:String); + + @(Common.SideEffects : {TargetEntities: ['']},) + action createLink( + in:many $self, + @mandatory @Common.Label:'Name' name: String @UI.Placeholder: 'Enter a name for the link', + @mandatory @assert.format:'^(https?:\/\/)(([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,}|localhost)(:\d{2,5})?(\/[^\s]*)?$' @Common.Label:'URL' url: String @UI.Placeholder: 'Example: https://www.example.com' + ); + + action editLink( + @mandatory @assert.format:'^(https?:\/\/)(([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,}|localhost)(:\d{2,5})?(\/[^\s]*)?$' @Common.Label:'URL' url: String @UI.Placeholder: 'Example: https://www.example.com' + ); + action openAttachment() returns String; + }; + + // Pages footnotes projection + entity Pages.footnotes as projection on my.Pages.footnotes + actions { + @(Common.SideEffects : {TargetEntities: ['']},) + action copyAttachments(in:many $self, up__ID:String, objectIds:String); + + @(Common.SideEffects : {TargetEntities: ['']},) + action createLink( + in:many $self, + @mandatory @Common.Label:'Name' name: String @UI.Placeholder: 'Enter a name for the link', + @mandatory @assert.format:'^(https?:\/\/)(([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,}|localhost)(:\d{2,5})?(\/[^\s]*)?$' @Common.Label:'URL' url: String @UI.Placeholder: 'Example: https://www.example.com' + ); + + action editLink( + @mandatory @assert.format:'^(https?:\/\/)(([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,}|localhost)(:\d{2,5})?(\/[^\s]*)?$' @Common.Label:'URL' url: String @UI.Placeholder: 'Example: https://www.example.com' + ); + action openAttachment() returns String; + }; +} diff --git a/cap-notebook/demoapp/srv/attachment-extension.cds b/cap-notebook/demoapp/srv/attachment-extension.cds index b0ad504e6..efca2f8fc 100644 --- a/cap-notebook/demoapp/srv/attachment-extension.cds +++ b/cap-notebook/demoapp/srv/attachment-extension.cds @@ -1,22 +1,134 @@ -using {sap.capire.bookshop.Books, sap.capire.bookshop.Notebooks} from '../db/schema'; -using {sap.attachments.Attachments, sap.attachments.StatusCode} from`com.sap.cds/sdm`; +using {sap.capire.bookshop.Books, sap.capire.bookshop.Chapters, sap.capire.bookshop.Pages, sap.capire.bookshop.Notebooks} from '../db/schema'; +using {sap.attachments.Attachments, sap.attachments.StatusCode} from 'com.sap.cds/sdm'; using {sap,managed,sap.common.CodeList} from '@sap/cds/common'; +// keep the original shallow attachments on Books extend entity Books with { - attachments : Composition of many Attachments @SDM.Attachments:{maxCount: 4, maxCountError:'Only 4 attachments allowed.'}; - references : Composition of many Attachments @SDM.Attachments:{maxCount: 5, maxCountError:'Only 5 attachments allowed.'}; - footnotes : Composition of many Attachments; + attachments : Composition of many Attachments @SDM.Attachments:{maxCount: 4, maxCountError:'Only 4 attachments allowed.'}; + references : Composition of many Attachments @SDM.Attachments:{maxCount: 5, maxCountError:'Only 5 attachments allowed.'}; + footnotes : Composition of many Attachments; } + extend entity Notebooks with { attachments : Composition of many Attachments @SDM.Attachments:{maxCount: 4, maxCountError:'Only 4 attachments allowed.'}; } + +extend entity Chapters with { + attachments: Composition of many Attachments; + references: Composition of many Attachments; + footnotes: Composition of many Attachments; +} + +extend entity Pages with { + attachments: Composition of many Attachments; + references: Composition of many Attachments; + footnotes: Composition of many Attachments; +} + + + entity Statuses @cds.autoexpose @readonly { - key code : StatusCode; - text : localized String(255); + key code : StatusCode; + text : localized String(255); +} + +extend Attachments with { + statusText : Association to Statuses on statusText.code = $self.status; +} + +annotate Books.attachments with { + status @( + Common.Text: { + $value: ![statusText.text], + ![@UI.TextArrangement]: #TextOnly + }, + ValueList: { entity: 'Statuses' }, + sap.value.list: 'fixed-values' + ); +} + + + +annotate Books.references with { + status @( + Common.Text: { + $value: ![statusText.text], + ![@UI.TextArrangement]: #TextOnly + }, + ValueList: { entity: 'Statuses' }, + sap.value.list: 'fixed-values' + ); +} + +annotate Chapters.attachments with { + status @( + Common.Text: { + $value: ![statusText.text], + ![@UI.TextArrangement]: #TextOnly + }, + ValueList: { entity: 'Statuses' }, + sap.value.list: 'fixed-values' + ); +} + +annotate Chapters.references with { + status @( + Common.Text: { + $value: ![statusText.text], + ![@UI.TextArrangement]: #TextOnly + }, + ValueList: { entity: 'Statuses' }, + sap.value.list: 'fixed-values' + ); +} + +annotate Pages.attachments with { + status @( + Common.Text: { + $value: ![statusText.text], + ![@UI.TextArrangement]: #TextOnly + }, + ValueList: { entity: 'Statuses' }, + sap.value.list: 'fixed-values' + ); +} + +annotate Pages.references with { + status @( + Common.Text: { + $value: ![statusText.text], + ![@UI.TextArrangement]: #TextOnly + }, + ValueList: { entity: 'Statuses' }, + sap.value.list: 'fixed-values' + ); } +annotate Chapters.footnotes with { + status @( + Common.Text: { + $value: ![statusText.text], + ![@UI.TextArrangement]: #TextOnly + }, + ValueList: { entity: 'Statuses' }, + sap.value.list: 'fixed-values' + ); +} + +annotate Pages.footnotes with { + status @( + Common.Text: { + $value: ![statusText.text], + ![@UI.TextArrangement]: #TextOnly + }, + ValueList: { entity: 'Statuses' }, + sap.value.list: 'fixed-values' + ); +} + + + extend Attachments with { - statusText : Association to Statuses on statusText.code = $self.status; customProperty1 : WDIRS_CodeList_TYPE @SDM.Attachments.AdditionalProperty: { name: 'Working:DocumentInfoRecordString' @@ -53,13 +165,3 @@ entity WDIRSCodeList : CodeList { }; type WDIRS_CodeList_TYPE : Association to one WDIRSCodeList; - -annotate Books.attachments with { - status @( - Common.Text: { - $value: ![statusText.text], - ![@UI.TextArrangement]: #TextOnly - }, - ValueList: {entity:'Statuses'} - ); -}