@cap-js/change-tracking 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,33 @@ All notable changes to this project will be documented in this file.
4
4
  This project adheres to [Semantic Versioning](http://semver.org/).
5
5
  The format is based on [Keep a Changelog](http://keepachangelog.com/).
6
6
 
7
+ ## Version 1.0.4 - 08.01.24
8
+
9
+ ### Added
10
+
11
+ - Side effect annotation now allows automatic refresh after a custom action caused changes
12
+
13
+ ### Changed
14
+
15
+ - Added a check to disable change tracking for views with a UNION
16
+
17
+ ### Fixed
18
+
19
+ - Handling of associations within change tracked entities
20
+ - Handling of change log when custom actions on child entities are called
21
+
22
+ ## Version 1.0.3 - 10.11.23
23
+
24
+ ### Added
25
+
26
+ - Added note about using `SAPUI5 v1.120.0` or later for proper lazy loading of the *Change History* table.
27
+ - In README, add warning about tracking personal data.
28
+
29
+ ### Changed
30
+
31
+ - Support cases where parent/child entries are created simultaneously.
32
+ - Allow for lazy loading of change history table (with SAP UI5 release 1.120.0).
33
+
7
34
  ## Version 1.0.2 - 31.10.23
8
35
 
9
36
  ### Changed
@@ -25,3 +52,4 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
25
52
  ### Added
26
53
 
27
54
  - Initial release
55
+
package/README.md CHANGED
@@ -8,23 +8,28 @@ The `@cap-js/change-tracking` package is a [CDS plugin](https://cap.cloud.sap/do
8
8
  2. [Add `@changelog` annotations to your CDS models](#annotations)
9
9
  3. [Et voilà:](#change-history-view)
10
10
 
11
- <img width="1300" alt="change-history-custom" src="_assets/changes.png">
11
+ <img width="1300" alt="change-history-loading" src="_assets/change-history.gif">
12
12
 
13
13
 
14
14
 
15
15
  ### Table of Contents
16
16
 
17
- - [Preliminaries](#preliminaries)
18
- - [Setup](#setup)
19
- - [Annotations](#annotations)
20
- - [Human-readable Types and Fields](#human-readable-types-and-fields)
21
- - [Human-readable IDs](#human-readable-ids)
22
- - [Human-readable Values](#human-readable-values)
23
- - [Test-drive locally](#test-drive-locally)
24
- - [Change History View](#change-history-view)
25
- - [Contributing](#contributing)
26
- - [Code of Conduct](#code-of-conduct)
27
- - [Licensing](#licensing)
17
+ - [Change Tracking Plugin for SAP Cloud Application Programming Model (CAP)](#change-tracking-plugin-for-sap-cloud-application-programming-model-cap)
18
+ - [Table of Contents](#table-of-contents)
19
+ - [Preliminaries](#preliminaries)
20
+ - [Setup](#setup)
21
+ - [Annotations](#annotations)
22
+ - [Human-readable Types and Fields](#human-readable-types-and-fields)
23
+ - [Human-readable IDs](#human-readable-ids)
24
+ - [Human-readable Values](#human-readable-values)
25
+ - [Test-drive locally](#test-drive-locally)
26
+ - [Change History View](#change-history-view)
27
+ - [Customizations](#customizations)
28
+ - [Altered table view](#altered-table-view)
29
+ - [Disable lazy loading](#disable-lazy-loading)
30
+ - [Contributing](#contributing)
31
+ - [Code of Conduct](#code-of-conduct)
32
+ - [Licensing](#licensing)
28
33
 
29
34
 
30
35
 
@@ -64,6 +69,9 @@ npm add @cap-js/change-tracking
64
69
 
65
70
  ## Annotations
66
71
 
72
+ > [!WARNING]
73
+ > Please be aware that [**sensitive** or **personal** data](https://cap.cloud.sap/docs/guides/data-privacy/annotations#annotating-personal-data) should not be change tracked, since viewing the log allows users to circumvent [audit-logging](https://cap.cloud.sap/docs/guides/data-privacy/audit-logging#setup).
74
+
67
75
  All we need to do is to identify what should be change-tracked by annotating respective entities and elements in our model with the `@changelog` annotation. Following the [best practice of separation of concerns](https://cap.cloud.sap/docs/guides/domain-modeling#separation-of-concerns), we do so in a separate file _srv/change-tracking.cds_:
68
76
 
69
77
  ```cds
@@ -162,13 +170,19 @@ With the steps above, we have successfully set up change tracking for our refere
162
170
 
163
171
  ## Change History View
164
172
 
173
+ > [!IMPORTANT]
174
+ > To ensure proper lazy loading of the Change History table, please use **SAPUI5 version 1.120.0** or higher.<br>
175
+ > If you wish to *disable* this feature, please see the customization section on how to [disable lazy loading](#disable-lazy-loading).
176
+
165
177
  <img width="1300" alt="change-history" src="_assets/changes.png">
166
178
 
167
179
  If you have a Fiori Element application, the CDS plugin automatically provides and generates a view `sap.changelog.ChangeView`, the facet of which is automatically added to the Fiori Object Page of your change-tracked entities/elements. In the UI, this corresponds to the *Change History* table which serves to help you to view and search the stored change records of your modeled entities.
168
180
 
169
- ### Customizations
181
+ ## Customizations
182
+
183
+ ### Altered table view
170
184
 
171
- The view can be easily adapted and configured to your own needs by simply changing or extending it. For example, let's assume we only want to show the first 5 columns in equal spacing, we would extend `srv/change-tracking.cds` as follows:
185
+ The *Change History* view can be easily adapted and configured to your own needs by simply changing or extending it. For example, let's assume we only want to show the first 5 columns in equal spacing, we would extend `srv/change-tracking.cds` as follows:
172
186
 
173
187
  ```cds
174
188
  using from '@cap-js/change-tracking';
@@ -190,6 +204,24 @@ In the UI, the *Change History* table now contains 5 equally-spaced columns with
190
204
 
191
205
  For more information and examples on adding Fiori Annotations, see [Adding SAP Fiori Annotations](https://cap.cloud.sap/docs/advanced/fiori#fiori-annotations).
192
206
 
207
+ ### Disable lazy loading
208
+
209
+ To disable the lazy loading feature of the *Change History* table, you can add the following annotation to your `srv/change-tracking.cds`:
210
+
211
+ ```cds
212
+ using from '@cap-js/change-tracking';
213
+
214
+ annotate sap.changelog.aspect @(UI.Facets: [{
215
+ $Type : 'UI.ReferenceFacet',
216
+ ID : 'ChangeHistoryFacet',
217
+ Label : '{i18n>ChangeHistory}',
218
+ Target: 'changes/@UI.PresentationVariant',
219
+ ![@UI.PartOfPreview]
220
+ }]);
221
+
222
+ ```
223
+
224
+ The system now uses the SAPUI5 default setting `![@UI.PartOfPreview]: true`, such that the table will always shown when navigating to that respective Object page.
193
225
 
194
226
  ## Contributing
195
227
 
package/cds-plugin.js CHANGED
@@ -1,10 +1,28 @@
1
1
  const cds = require('@sap/cds')
2
2
 
3
3
  const isChangeTracked = (entity) => (
4
- entity['@changelog']
5
- || entity.elements && Object.values(entity.elements).some(e => e['@changelog'])
4
+ (entity['@changelog']
5
+ || entity.elements && Object.values(entity.elements).some(e => e['@changelog'])) && entity.query?.SET?.op !== 'union'
6
6
  )
7
7
 
8
+ // Add the appropriate Side Effects attribute to the custom action
9
+ const addSideEffects = (actions, flag, element) => {
10
+ for (const se of Object.values(actions)) {
11
+ const target = flag ? 'TargetProperties' : 'TargetEntities'
12
+ const sideEffectAttr = se[`@Common.SideEffects.${target}`]
13
+ const property = flag ? 'changes' : { '=': `${element}.changes` }
14
+ if (sideEffectAttr?.length >= 0) {
15
+ sideEffectAttr.findIndex(
16
+ (item) =>
17
+ (item['='] ? item['='] : item) ===
18
+ (property['='] ? property['='] : property)
19
+ ) === -1 && sideEffectAttr.push(property)
20
+ } else {
21
+ se[`@Common.SideEffects.${target}`] = [property]
22
+ }
23
+ }
24
+ }
25
+
8
26
 
9
27
  // Unfold @changelog annotations in loaded model
10
28
  cds.on('loaded', m => {
@@ -23,7 +41,9 @@ cds.on('loaded', m => {
23
41
  for (let e in elms) if (elms[e].key) keys.push(e)
24
42
 
25
43
  // Add association to ChangeView...
26
- const on = [...changes.on]; keys.forEach((k, i) => { i && on.push('||'); on.push({ ref: [k] }) })
44
+ const on = [...changes.on]; keys.forEach((k, i) => { i && on.push('||'); on.push({
45
+ ref: k === 'up_' ? [k,'ID'] : [k] // REVISIT: up_ handling is a dirty hack for now
46
+ })})
27
47
  const assoc = { ...changes, on }
28
48
  const query = entity.projection || entity.query?.SELECT
29
49
  if (query) {
@@ -34,6 +54,31 @@ cds.on('loaded', m => {
34
54
 
35
55
  // Add UI.Facet for Change History List
36
56
  entity['@UI.Facets']?.push(facet)
57
+
58
+ // The changehistory list should be refreshed after the custom action is triggered
59
+ if (entity.actions) {
60
+
61
+ // Update the changehistory list on the current entity when the custom action of the entity is triggered
62
+ if (entity['@UI.Facets']) {
63
+ addSideEffects(entity.actions, true)
64
+ }
65
+
66
+ // When the custom action of the child entity is performed, the change history list of the parent entity is updated
67
+ if (entity.elements) {
68
+ //ToDo: Revisit Breaklook with node.js Expert
69
+ breakLoop: for (const [ele, eleValue] of Object.entries(entity.elements)) {
70
+ const parentEntity = m.definitions[eleValue.target]
71
+ if (parentEntity && parentEntity['@UI.Facets'] && eleValue.type === 'cds.Association') {
72
+ for (const value of Object.values(parentEntity.elements)) {
73
+ if (value.target === name) {
74
+ addSideEffects(entity.actions, false, ele)
75
+ break breakLoop
76
+ }
77
+ }
78
+ }
79
+ }
80
+ }
81
+ }
37
82
  }
38
83
  }
39
84
  })
package/index.cds CHANGED
@@ -9,8 +9,7 @@ aspect aspect @(UI.Facets: [{
9
9
  ID : 'ChangeHistoryFacet',
10
10
  Label : '{i18n>ChangeHistory}',
11
11
  Target: 'changes/@UI.PresentationVariant',
12
- //TODO: Use for lazy-loading once Fiori fixes bugs and v1.120 is released
13
- //![@UI.PartOfPreview]: false
12
+ ![@UI.PartOfPreview]: false
14
13
  }]) {
15
14
  // Essentially: Association to many Changes on changes.changeLog.entityKey = ID;
16
15
  changes : Association to many ChangeView on changes.entityKey = ID;
package/lib/change-log.js CHANGED
@@ -359,7 +359,7 @@ async function track_changes (req) {
359
359
  if (!changes) return
360
360
 
361
361
  await _formatChangeLog(changes, req)
362
- if (isComposition && !isDraftEnabled) {
362
+ if (isComposition) {
363
363
  [ target, entityKey ] = await _prepareChangeLogForComposition(target, entityKey, changes, this)
364
364
  }
365
365
  const dbEntity = getDBEntity(target)
@@ -85,7 +85,9 @@ async function getObjectId (entityName, fields, curObj) {
85
85
  if (IDval) try {
86
86
  // REVISIT: This always reads all elements -> should read required ones only!
87
87
  let ID = assoc.keys?.[0]?.ref[0] || 'ID'
88
- _db_data = await SELECT.one.from(assoc._target).where({[ID]: IDval}) || {}
88
+ // When parent/child nodes are created simultaneously, data is taken from draft table
89
+ _db_data = await SELECT.one.from(assoc._target).where({[ID]: IDval}) ||
90
+ await SELECT.one.from(`${assoc._target}.drafts`).where({[ID]: IDval}) || {}
89
91
  } catch (e) {
90
92
  LOG.error("Failed to generate object Id for an association entity.", e)
91
93
  throw new Error("Failed to generate object Id for an association entity.", e)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cap-js/change-tracking",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "CDS plugin providing out-of-the box support for automatic capturing, storing, and viewing of the change records of modeled entities.",
5
5
  "repository": "cap-js/change-tracking",
6
6
  "author": "SAP SE (https://www.sap.com)",