@cap-js/change-tracking 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,51 @@
1
+ ## Change Table Fields Description##
2
+ ####################################
3
+ #XTIT: Field Name
4
+ Changes.ID=Cambiamenti ID
5
+ #XTIT: Field Name
6
+ Changes.entityID=ID oggetto
7
+ #XTIT: Field Name
8
+ Changes.parentEntityID=ID superiore oggetto
9
+ #XTIT: Field Name
10
+ Changes.parentKey=Chiave sovraordinata
11
+ #XTIT: Field Name
12
+ Changes.serviceEntityPath=Percorso di entità del servizio
13
+ #XTIT: Field Name
14
+ Changes.attribute=Campo
15
+ #XTIT: Field Name
16
+ Changes.keys=Cambia le chiavi
17
+ #XTIT: Field Name
18
+ Changes.modification=Tipo di modifica
19
+ #XTIT: Field Name
20
+ Changes.valueChangedFrom=Valore precedente
21
+ #XTIT: Field Name
22
+ Changes.valueChangedTo=Nuovo valore
23
+ #XTIT: Field Name
24
+ Changes.entity=Tipo di oggetto
25
+ #XTIT: Field Name
26
+ Changes.serviceEntity=Tipo oggetto prestazione
27
+ #XTIT: Field Name
28
+ Changes.valueDataType=Valutare il tipo di dati
29
+
30
+ ## Change Log Table Fields Description##
31
+ ########################################
32
+ #XTIT: Field Name
33
+ ChangeLog.entity=Entità
34
+ #XTIT: Field Name
35
+ ChangeLog.entityKey=Chiave entità
36
+ #XTIT: Field Name
37
+ ChangeLog.serviceEntity=Entità di servizio
38
+
39
+
40
+ ## Change Log Modifications##
41
+ ########################################
42
+ #XFLD: Field label
43
+ ChangeLog.modification.create=Creare
44
+ #XFLD: Field label
45
+ ChangeLog.modification.update=Aggiornare
46
+ #XFLD: Field label
47
+ ChangeLog.modification.delete=Cancellare
48
+
49
+ ## Change History Table##
50
+ ########################################
51
+ ChangeHistory=Storico modifiche
@@ -0,0 +1,47 @@
1
+ ## Change Table Fields Description##
2
+ ####################################
3
+ #XTIT: Field Name
4
+ Changes.ID=\u5909\u66F4 ID
5
+ #XTIT: Field Name
6
+ Changes.entityID=\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8 ID
7
+ #XTIT: Field Name
8
+ Changes.parentEntityID=\u89AA\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8 ID
9
+ #XTIT: Field Name
10
+ Changes.parentKey=\u89AA\u30AD\u30FC
11
+ #XTIT: Field Name
12
+ Changes.serviceEntityPath=\u30B5\u30FC\u30D3\u30B9\u30A8\u30F3\u30C6\u30A3\u30C6\u30A3\u30D1\u30B9
13
+ #XTIT: Field Name
14
+ Changes.attribute=\u30D5\u30A3\u30FC\u30EB\u30C9
15
+ #XTIT: Field Name
16
+ Changes.keys=\u5909\u66F4\u30AD\u30FC
17
+ #XTIT: Field Name
18
+ Changes.modification=\u5909\u66F4\u30BF\u30A4\u30D7
19
+ #XTIT: Field Name
20
+ Changes.valueChangedFrom=\u53E4\u3044\u5024
21
+ #XTIT: Field Name
22
+ Changes.valueChangedTo=\u65B0\u3057\u3044\u5024
23
+ #XTIT: Field Name
24
+ Changes.entity=\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u30BF\u30A4\u30D7
25
+ #XTIT: Field Name
26
+ Changes.serviceEntity=\u30B5\u30FC\u30D3\u30B9\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u30BF\u30A4\u30D7
27
+ #XTIT: Field Name
28
+ Changes.valueDataType=\u5024\u306E\u30C7\u30FC\u30BF\u578B
29
+
30
+ ## Change Log Table Fields Description##
31
+ ########################################
32
+ #XTIT: Field Name
33
+ ChangeLog.entity=\u30A8\u30F3\u30C6\u30A3\u30C6\u30A3
34
+ #XTIT: Field Name
35
+ ChangeLog.entityKey=\u30A8\u30F3\u30C6\u30A3\u30C6\u30A3\u30AD\u30FC
36
+ #XTIT: Field Name
37
+ ChangeLog.serviceEntity=\u30B5\u30FC\u30D3\u30B9\u30A8\u30F3\u30C6\u30A3\u30C6\u30A3
38
+
39
+
40
+ ## Change Log Modifications##
41
+ ########################################
42
+ #XFLD: Field label
43
+ ChangeLog.modification.create=\u4F5C\u6210
44
+ #XFLD: Field label
45
+ ChangeLog.modification.update=\u66F4\u65B0
46
+ #XFLD: Field label
47
+ ChangeLog.modification.delete=\u524A\u9664
@@ -0,0 +1,51 @@
1
+ ## Change Table Fields Description##
2
+ ####################################
3
+ #XTIT: Field Name
4
+ Changes.ID=Identyfikator zmian
5
+ #XTIT: Field Name
6
+ Changes.entityID=Identyfikator obiektu
7
+ #XTIT: Field Name
8
+ Changes.parentEntityID=Identyfikator obiektu nadrz\u0119dnego
9
+ #XTIT: Field Name
10
+ Changes.parentKey=Klucz nadrz\u0119dny
11
+ #XTIT: Field Name
12
+ Changes.serviceEntityPath=\u015Acie\u017Cka encji us\u0142ugi
13
+ #XTIT: Field Name
14
+ Changes.attribute=Pole
15
+ #XTIT: Field Name
16
+ Changes.keys=Klucze zmian
17
+ #XTIT: Field Name
18
+ Changes.modification=Typ zmiany
19
+ #XTIT: Field Name
20
+ Changes.valueChangedFrom=Stara warto\u015B\u0107
21
+ #XTIT: Field Name
22
+ Changes.valueChangedTo=Nowa warto\u015B\u0107
23
+ #XTIT: Field Name
24
+ Changes.entity=Typ obiektu
25
+ #XTIT: Field Name
26
+ Changes.serviceEntity=Typ obiektu us\u0142ugi
27
+ #XTIT: Field Name
28
+ Changes.valueDataType=Typ danych warto\u015Bci
29
+
30
+ ## Change Log Table Fields Description##
31
+ ########################################
32
+ #XTIT: Field Name
33
+ ChangeLog.entity=Encja
34
+ #XTIT: Field Name
35
+ ChangeLog.entityKey=Klucz encji
36
+ #XTIT: Field Name
37
+ ChangeLog.serviceEntity=Encja us\u0142ugi
38
+
39
+
40
+ ## Change Log Modifications##
41
+ ########################################
42
+ #XFLD: Field label
43
+ ChangeLog.modification.create=Utw\u00F3rz
44
+ #XFLD: Field label
45
+ ChangeLog.modification.update=Aktualizuj
46
+ #XFLD: Field label
47
+ ChangeLog.modification.delete=Usu\u0144
48
+
49
+ ## Change History Table##
50
+ ########################################
51
+ ChangeHistory=Historia zmian
@@ -0,0 +1,51 @@
1
+ ## Change Table Fields Description##
2
+ ####################################
3
+ #XTIT: Field Name
4
+ Changes.ID=ID das altera\u00E7\u00F5es
5
+ #XTIT: Field Name
6
+ Changes.entityID=ID de objeto
7
+ #XTIT: Field Name
8
+ Changes.parentEntityID=ID do objeto superior
9
+ #XTIT: Field Name
10
+ Changes.parentKey=Chave superior
11
+ #XTIT: Field Name
12
+ Changes.serviceEntityPath=Caminho da entidade de servi\u00E7o
13
+ #XTIT: Field Name
14
+ Changes.attribute=Campo
15
+ #XTIT: Field Name
16
+ Changes.keys=Chaves de altera\u00E7\u00F5es
17
+ #XTIT: Field Name
18
+ Changes.modification=Tipo de altera\u00E7\u00E3o
19
+ #XTIT: Field Name
20
+ Changes.valueChangedFrom=Valor antigo
21
+ #XTIT: Field Name
22
+ Changes.valueChangedTo=Valor novo
23
+ #XTIT: Field Name
24
+ Changes.entity=Tipo de objeto
25
+ #XTIT: Field Name
26
+ Changes.serviceEntity=Tipo de objeto de servi\u00E7o
27
+ #XTIT: Field Name
28
+ Changes.valueDataType=Tipo de dados de valor
29
+
30
+ ## Change Log Table Fields Description##
31
+ ########################################
32
+ #XTIT: Field Name
33
+ ChangeLog.entity=Entidade
34
+ #XTIT: Field Name
35
+ ChangeLog.entityKey=Chave de entidade
36
+ #XTIT: Field Name
37
+ ChangeLog.serviceEntity=Entidade de servi\u00E7o
38
+
39
+
40
+ ## Change Log Modifications##
41
+ ########################################
42
+ #XFLD: Field label
43
+ ChangeLog.modification.create=Criar
44
+ #XFLD: Field label
45
+ ChangeLog.modification.update=Atualizar
46
+ #XFLD: Field label
47
+ ChangeLog.modification.delete=Eliminar
48
+
49
+ ## Change History Table##
50
+ ########################################
51
+ ChangeHistory=Histórico de alterações
@@ -0,0 +1,51 @@
1
+ ## Change Table Fields Description##
2
+ ####################################
3
+ #XTIT: Field Name
4
+ Changes.ID=\u0418\u0434. \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F
5
+ #XTIT: Field Name
6
+ Changes.entityID=\u0418\u0434. \u043E\u0431\u044A\u0435\u043A\u0442\u0430
7
+ #XTIT: Field Name
8
+ Changes.parentEntityID=\u0418\u0434. \u0432\u044B\u0448\u0435\u0441\u0442\u043E\u044F\u0449\u0435\u0433\u043E \u043E\u0431\u044A\u0435\u043A\u0442\u0430
9
+ #XTIT: Field Name
10
+ Changes.parentKey=\u0412\u044B\u0448\u0435\u0441\u0442\u043E\u044F\u0449\u0438\u0439 \u043A\u043B\u044E\u0447
11
+ #XTIT: Field Name
12
+ Changes.serviceEntityPath=\u041F\u0443\u0442\u044C \u043A \u0441\u0443\u0449\u043D\u043E\u0441\u0442\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430
13
+ #XTIT: Field Name
14
+ Changes.attribute=\u041F\u043E\u043B\u0435
15
+ #XTIT: Field Name
16
+ Changes.keys=\u041A\u043B\u044E\u0447\u0438 \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0439
17
+ #XTIT: Field Name
18
+ Changes.modification=\u0422\u0438\u043F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F
19
+ #XTIT: Field Name
20
+ Changes.valueChangedFrom=\u0421\u0442\u0430\u0440\u043E\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435
21
+ #XTIT: Field Name
22
+ Changes.valueChangedTo=\u041D\u043E\u0432\u043E\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435
23
+ #XTIT: Field Name
24
+ Changes.entity=\u0422\u0438\u043F \u043E\u0431\u044A\u0435\u043A\u0442\u0430
25
+ #XTIT: Field Name
26
+ Changes.serviceEntity=\u0422\u0438\u043F \u043E\u0431\u044A\u0435\u043A\u0442\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u0430
27
+ #XTIT: Field Name
28
+ Changes.valueDataType=\u0422\u0438\u043F \u0434\u0430\u043D\u043D\u044B\u0445 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F
29
+
30
+ ## Change Log Table Fields Description##
31
+ ########################################
32
+ #XTIT: Field Name
33
+ ChangeLog.entity=\u0421\u0443\u0449\u043D\u043E\u0441\u0442\u044C
34
+ #XTIT: Field Name
35
+ ChangeLog.entityKey=\u041A\u043B\u044E\u0447 \u0441\u0443\u0449\u043D\u043E\u0441\u0442\u0438
36
+ #XTIT: Field Name
37
+ ChangeLog.serviceEntity=\u0421\u0443\u0449\u043D\u043E\u0441\u0442\u044C \u0441\u0435\u0440\u0432\u0438\u0441\u0430
38
+
39
+
40
+ ## Change Log Modifications##
41
+ ########################################
42
+ #XFLD: Field label
43
+ ChangeLog.modification.create=\u0421\u043E\u0437\u0434\u0430\u0442\u044C
44
+ #XFLD: Field label
45
+ ChangeLog.modification.update=\u041E\u0431\u043D\u043E\u0432\u0438\u0442\u044C
46
+ #XFLD: Field label
47
+ ChangeLog.modification.delete=\u0423\u0434\u0430\u043B\u0438\u0442\u044C
48
+
49
+ ## Change History Table##
50
+ ########################################
51
+ ChangeHistory=История изменений
@@ -0,0 +1,51 @@
1
+ ## Change Table Fields Description##
2
+ ####################################
3
+ #XTIT: Field Name
4
+ Changes.ID=\u66F4\u6539\u6807\u8BC6
5
+ #XTIT: Field Name
6
+ Changes.entityID=\u5BF9\u8C61\u6807\u8BC6
7
+ #XTIT: Field Name
8
+ Changes.parentEntityID=\u7236\u5BF9\u8C61\u6807\u8BC6
9
+ #XTIT: Field Name
10
+ Changes.parentKey=\u7236\u53C2\u6570
11
+ #XTIT: Field Name
12
+ Changes.serviceEntityPath=\u670D\u52A1\u5B9E\u4F53\u8DEF\u5F84
13
+ #XTIT: Field Name
14
+ Changes.attribute=\u5B57\u6BB5
15
+ #XTIT: Field Name
16
+ Changes.keys=\u66F4\u6539\u53C2\u6570
17
+ #XTIT: Field Name
18
+ Changes.modification=\u66F4\u6539\u7C7B\u578B
19
+ #XTIT: Field Name
20
+ Changes.valueChangedFrom=\u65E7\u503C
21
+ #XTIT: Field Name
22
+ Changes.valueChangedTo=\u65B0\u503C
23
+ #XTIT: Field Name
24
+ Changes.entity=\u5BF9\u8C61\u7C7B\u578B
25
+ #XTIT: Field Name
26
+ Changes.serviceEntity=\u670D\u52A1\u5BF9\u8C61\u7C7B\u578B
27
+ #XTIT: Field Name
28
+ Changes.valueDataType=\u6570\u503C\u6570\u636E\u7C7B\u578B
29
+
30
+ ## Change Log Table Fields Description##
31
+ ########################################
32
+ #XTIT: Field Name
33
+ ChangeLog.entity=\u5B9E\u4F53
34
+ #XTIT: Field Name
35
+ ChangeLog.entityKey=\u5B9E\u4F53\u53C2\u6570
36
+ #XTIT: Field Name
37
+ ChangeLog.serviceEntity=\u670D\u52A1\u5B9E\u4F53
38
+
39
+
40
+ ## Change Log Modifications##
41
+ ########################################
42
+ #XFLD: Field label
43
+ ChangeLog.modification.create=\u521B\u5EFA
44
+ #XFLD: Field label
45
+ ChangeLog.modification.update=\u66F4\u65B0
46
+ #XFLD: Field label
47
+ ChangeLog.modification.delete=\u5220\u9664
48
+
49
+ ## Change History Table##
50
+ ########################################
51
+ ChangeHistory=\u6539\u53d8\u5386\u53f2
package/cds-plugin.js ADDED
@@ -0,0 +1,60 @@
1
+ const cds = require('@sap/cds')
2
+
3
+ const isChangeTracked = (entity) => (
4
+ entity['@changelog']
5
+ || entity.elements && Object.values(entity.elements).some(e => e['@changelog'])
6
+ )
7
+
8
+
9
+ // Unfold @changelog annotations in loaded model
10
+ cds.on('loaded', m => {
11
+
12
+ // Get definitions from Dummy entity in our models
13
+ const { 'sap.changelog.aspect': aspect } = m.definitions; if (!aspect) return // some other model
14
+ const { '@UI.Facets': [facet], elements: { changes } } = aspect
15
+ changes.on.pop() // remove ID -> filled in below
16
+
17
+ for (let name in m.definitions) {
18
+ const entity = m.definitions[name]
19
+ if (isChangeTracked(entity)) {
20
+
21
+ // Determine entity keys
22
+ const keys = [], { elements: elms } = entity
23
+ for (let e in elms) if (elms[e].key) keys.push(e)
24
+
25
+ // Add association to ChangeView...
26
+ const on = [...changes.on]; keys.forEach((k, i) => { i && on.push('||'); on.push({ ref: [k] }) })
27
+ const assoc = { ...changes, on }
28
+ const query = entity.projection || entity.query?.SELECT
29
+ if (query) {
30
+ (query.columns ??= ['*']).push({ as: 'changes', cast: assoc })
31
+ } else {
32
+ entity.elements.changes = assoc
33
+ }
34
+
35
+ // Add UI.Facet for Change History List
36
+ entity['@UI.Facets']?.push(facet)
37
+ }
38
+ }
39
+ })
40
+
41
+ // Add generic change tracking handlers
42
+ cds.on('served', () => {
43
+ const { track_changes, _afterReadChangeView } = require("./lib/change-log")
44
+ for (const srv of cds.services) {
45
+ if (srv instanceof cds.ApplicationService) {
46
+ let any = false
47
+ for (const entity of Object.values(srv.entities)) {
48
+ if (isChangeTracked(entity)) {
49
+ cds.db.before("CREATE", entity, track_changes)
50
+ cds.db.before("UPDATE", entity, track_changes)
51
+ cds.db.before("DELETE", entity, track_changes)
52
+ any = true
53
+ }
54
+ }
55
+ if (any && srv.entities.ChangeView) {
56
+ srv.after("READ", srv.entities.ChangeView, _afterReadChangeView)
57
+ }
58
+ }
59
+ }
60
+ })
package/index.cds ADDED
@@ -0,0 +1,108 @@
1
+ using { managed, cuid } from '@sap/cds/common';
2
+ namespace sap.changelog;
3
+
4
+ /**
5
+ * Used in cds-plugin.js as template for tracked entities
6
+ */
7
+ aspect aspect @(UI.Facets: [{
8
+ $Type : 'UI.ReferenceFacet',
9
+ ID : 'ChangeHistoryFacet',
10
+ Label : '{i18n>ChangeHistory}',
11
+ Target: 'changes/@UI.PresentationVariant',
12
+ //TODO: Use for lazy-loading once Fiori fixes bugs and v1.120 is released
13
+ //![@UI.PartOfPreview]: false
14
+ }]) {
15
+ // Essentially: Association to many Changes on changes.changeLog.entityKey = ID;
16
+ changes : Association to many ChangeView on changes.entityKey = ID;
17
+ key ID : UUID;
18
+ }
19
+
20
+
21
+ // This is a helper view to flatten the assoc path to the entityKey
22
+ @readonly
23
+ view ChangeView as
24
+ select from Changes {
25
+ *,
26
+ entityID as objectID, // no clue why we have to rename this?
27
+ parentEntityID as parentObjectID, // no clue why we have to rename this?
28
+ changeLog.entityKey as entityKey, // flattening assoc path -> this is the main reason for having this helper view
29
+ changeLog.createdAt as createdAt,
30
+ changeLog.createdBy as createdBy,
31
+ }
32
+ excluding {
33
+ entityID,
34
+ parentEntityID,
35
+ };
36
+
37
+ /**
38
+ * Top-level changes entity, e.g. UPDATE Incident by, at, ...
39
+ */
40
+ entity ChangeLog : managed, cuid {
41
+ serviceEntity : String @title: '{i18n>ChangeLog.serviceEntity}'; // definition name of target entity (on service level) - e.g. ProcessorsService.Incidents
42
+ entity : String @title: '{i18n>ChangeLog.entity}'; // definition name of target entity (on db level) - e.g. sap.capire.incidents.Incidents
43
+ entityKey : UUID @title: '{i18n>ChangeLog.entityKey}'; // primary key of target entity, e.g. Incidents.ID
44
+ createdAt : managed:createdAt @title: 'On';
45
+ createdBy : managed:createdBy @title: 'By';
46
+ changes : Composition of many Changes on changes.changeLog = $self;
47
+ }
48
+
49
+
50
+ /**
51
+ * Attribute-level Changes with simple capturing of one-level
52
+ * composition trees in parent... elements.
53
+ */
54
+ entity Changes {
55
+
56
+ key ID : UUID @UI.Hidden;
57
+ keys : String @title: '{i18n>Changes.keys}';
58
+ attribute : String @title: '{i18n>Changes.attribute}';
59
+ valueChangedFrom : String @title: '{i18n>Changes.valueChangedFrom}';
60
+ valueChangedTo : String @title: '{i18n>Changes.valueChangedTo}';
61
+
62
+ // Business meaningful object id
63
+ entityID : String @title: '{i18n>Changes.entityID}';
64
+ entity : String @title: '{i18n>Changes.entity}'; // similar to ChangeLog.entity, but could be nested entity in a composition tree
65
+ serviceEntity : String @title: '{i18n>Changes.serviceEntity}'; // similar to ChangeLog.serviceEntity, but could be nested entity in a composition tree
66
+
67
+ // Business meaningful parent object id
68
+ parentEntityID : String @title: '{i18n>Changes.parentEntityID}';
69
+ parentKey : UUID @title: '{i18n>Changes.parentKey}';
70
+ serviceEntityPath : String @title: '{i18n>Changes.serviceEntityPath}';
71
+
72
+ @title: '{i18n>Changes.modification}'
73
+ modification : String enum {
74
+ create = 'Create';
75
+ update = 'Edit';
76
+ delete = 'Delete';
77
+ };
78
+
79
+ valueDataType : String @title: '{i18n>Changes.valueDataType}';
80
+ changeLog : Association to ChangeLog @title: '{i18n>ChangeLog.ID}';
81
+ }
82
+
83
+ annotate ChangeView with @(UI: {
84
+ PresentationVariant: {
85
+ Visualizations: ['@UI.LineItem'],
86
+ RequestAtLeast: [
87
+ parentKey,
88
+ serviceEntity,
89
+ serviceEntityPath
90
+ ],
91
+ SortOrder : [{
92
+ Property : createdAt,
93
+ Descending: true
94
+ }],
95
+ },
96
+ LineItem : [
97
+ { Value: modification, @HTML5.CssDefaults: {width:'9%'} },
98
+ { Value: createdAt, @HTML5.CssDefaults: {width:'12%'} },
99
+ { Value: createdBy, @HTML5.CssDefaults: {width:'9%'} },
100
+ { Value: entity, @HTML5.CssDefaults: {width:'11%'} },
101
+ { Value: objectID, @HTML5.CssDefaults: {width:'14%'} },
102
+ { Value: attribute, @HTML5.CssDefaults: {width:'9%'} },
103
+ { Value: valueChangedTo, @HTML5.CssDefaults: {width:'11%'} },
104
+ { Value: valueChangedFrom, @HTML5.CssDefaults: {width:'11%'} },
105
+ { Value: parentObjectID, @HTML5.CssDefaults: {width:'14%'}, ![@UI.Hidden]: true }
106
+ ],
107
+ DeleteHidden : true,
108
+ });