Skip to content

Commit

Permalink
Release 3.26.0
Browse files Browse the repository at this point in the history
  • Loading branch information
sleidig authored Nov 21, 2023
2 parents 5237502 + 8f1797e commit 4273959
Show file tree
Hide file tree
Showing 195 changed files with 8,342 additions and 4,122 deletions.
7 changes: 6 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,12 @@
}
}
],
"rules": {
"prettier/prettier": "error"
},
"plugins": ["prettier"],
"extends": [
"plugin:storybook/recommended"
"plugin:storybook/recommended",
"prettier"
]
}
15 changes: 0 additions & 15 deletions .github/workflows/master-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,3 @@ jobs:
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: snyk.sarif
run-e2e-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Cypress run
uses: cypress-io/github-action@v4
with:
command: npm run e2e
env:
# pass the Dashboard record key as an environment variable
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
# pass GitHub token to allow accurately detecting a build vs a re-run build
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# pass the project ID from the secrets through environment variable
CYPRESS_PROJECT_ID: ${{ secrets.CYPRESS_PROJECT_ID }}
12 changes: 0 additions & 12 deletions .github/workflows/pull-request-update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,3 @@ jobs:
cd /var/docker/pr-${{ github.event.number }}
docker compose pull
docker compose up -d
run-e2e-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Cypress run
uses: cypress-io/github-action@v5
with:
command: npm run e2e
env:
COMMIT_INFO_MESSAGE: ${{ github.event.pull_request.title }}
# pass GitHub token to allow accurately detecting a build vs a re-run build
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
16 changes: 16 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"overrides": [
{
"files": "*.html",
"options": {
"parser": "html"
}
},
{
"files": "*.component.html",
"options": {
"parser": "angular"
}
}
]
}
2 changes: 1 addition & 1 deletion build/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ RUN if [ "$SENTRY_AUTH_TOKEN" != "" ] ; then \

### PROD image

FROM nginx:1.25.2-alpine
FROM nginx:1.25.3-alpine
COPY ./build/default.conf /etc/nginx/templates/default.conf
COPY --from=builder /app/dist/ /usr/share/nginx/html
# The port on which the app will run in the Docker container
Expand Down
4 changes: 3 additions & 1 deletion doc/compodoc_sources/concepts/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ The config service provides a behavior subject which will notify all subscribers
This can be used for core tasks like setting up the routes or creating the navigation bar.

Top-level "view" components (i.e. components that are used to define a whole page, not just some building block for a part or section)
receive their config data through the standard Angular router and can access it by injecting `ActivatedRoute`.
receive their config data automatically assigned as `@Input()` properties mapped from config object property name to an identical component class property.
This is handled by the `RoutedViewComponent` internally.
(If needed for special cases, you can also access it through the standard Angular router and can access it by injecting `ActivatedRoute`.)


### Storing config in DB
Expand Down
10 changes: 10 additions & 0 deletions doc/compodoc_sources/concepts/entities.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Entities & Entity Schema
-----
For us, an "Entity" is an object in the database (and a representation of something in the user's real world, e.g. a "Child" or "School").
Entities are at the core of the Aam Digital platform and the primary way to customize the system is to adapt and add new entity types.

The Entity Schema defines the data structure as well as how it is displayed in the UI.
Entity instances also have some generic functionality inherited from the `Entity` base class.

------
_see the sub-pages here for details of the various concepts related to the Entity system_
39 changes: 39 additions & 0 deletions doc/compodoc_sources/concepts/entity-anonymization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Archive / Anonymize Entities
-----
Any entity can be archived (i.e. marked as inactive and hidden from UI by default) or anonymized (i.e. discarding most data and keeping a few selected properties for statistical reports).
This is often preferable to deleting a record completely. Deleting data also affects statistical reports, even for previous time periods.
By anonymizing records, all personal identifiable data can be removed and the remaining stub record can be stored indefinitely, as it is not subject to data protection regulations like GDPR anymore.

Anonymization is configured as part of the entity schema.
Data of fields that are not explicitly marked to be retained during anonymization is always deleted (anonymization by default).

To keep some data even after the user "anonymized" a record, configure the `anonymize` property of the `@DatabaseField` decorator:
- `anonymize: "retain"` will keep this field unchanged and prevent it from being deleted
- `anonymize: "retain-anonymized"` will trigger a special "partial" deletion that depends on the dataType (e.g. date types will be changed to 1st July of the given year, thereby largely removing details but keeping data to calculate a rough age)


## Cascading anonymization / deletion
Relationships between entities are automatically handled when the user anonymizes or deletes an entity.
Any related entities that reference the anonymized/deleted entity are checked
and - depending on their configured role - may be updated or anonymized as well.

The logic follows the scenarios shown below:
![](../../images/cascading-delete.png)


## Data Protection & GDPR regarding anonymization / pseudonomyzation
The "anonymize" function is implemented specifically for data protection rules requiring to delete personal data.
According to the EU's "General Data Protection Regulation" (GDPR) "anonymous" data does not fall under its regulations:

- GDPR is not applicable to anonymous data: "The principles of data protection should therefore not apply to [...] personal data rendered anonymous in such a manner that the data subject is not or no longer identifiable." [<sup>GDPR Recital 26</sup>](https://gdpr-info.eu/recitals/no-26/)
- "To determine whether a natural person is identifiable, account should be taken of all the means reasonably likely to be used, such as singling out, either by the controller or by another person to identify the natural person directly or indirectly."
- "To ascertain whether means are reasonably likely to be used to identify the natural person, account should be taken of all objective factors, such as the costs of and the amount of time required for identification, taking into consideration the available technology at the time of the processing and technological developments."
- "Pseudonymisation enables the personal data to become unidentifiable unless more information is available whereas anonymization allows the processing of personal data to irreversibly prevent re-identification." [<sup>source</sup>](https://www.privacycompany.eu/blogpost-en/what-are-the-differences-between-anonymisation-and-pseudonymisation)
- _also see this [good overview of anonymization misunderstandings and considerations](https://edps.europa.eu/system/files/2021-04/21-04-27_aepd-edps_anonymisation_en_5.pdf)_

In the case of records being retained "anonymized" in Aam Digital, we provide a context that makes re-identification even harder:
- only authorized users of the system can access even the anonymized record (where only a few properties have been retained). Unless the organisation actively shares the data, it remains as securely protected as the personal data managed in Aam Digital.
- those authorized users with access to the anonymized records (and therefor a theoretical chance to attempt re-identification) are team members of an organization. They have been screened to be responsible persons and are usually legally bound to keep information confidential.
- by default only a few, explicitly selected properties in anonymized records are retained (data minimization by default). As such, both re-identification likelihood and the impact in case of re-identification are reduced as far as possible.

--> If our anonymization process is configured thoughfully on a case by case basis to only retain a few data fields that are not easy indirect identifiers, it seems reasonably unlikely that the person can be identified after the anonymization process. Therefore, GDPR should not apply to these records and it is legitimate to retain these for statistical reporting.
11 changes: 8 additions & 3 deletions doc/compodoc_sources/concepts/entity-schema-system.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# Entity Schema
-----
The Entity Schema defines details of the properties of an entity type.
(An "entity" is an object of a certain type that users work with and save to the database, like "Child" or "School")

We define an entity type and its schema in code through a plain TypeScript class and some custom annotations.
Read more on the background and practical considerations in [How to create a new Entity Type](../how-to-guides/create-a-new-entity-type.html).

Expand Down Expand Up @@ -45,9 +43,16 @@ providing these through Angular dependency injection using `multi: true`.

Also see: [How to create a new Datatype](../how-to-guides/create-a-new-datatype.html).

## Schema options
### Schema options

The schema definitions contains information regarding the schema transformation as well as how a property can be displayed.
The [EntitySchemaField](../../interfaces/EntitySchemaField.html) interface shows all configuration options.
If the `editComponent` and the `viewComponent` are not set, the default components of this property's datatype will be used.
The `description` field allows adding further explanation which will be displayed as a tooltip.


## Generic Entity functionalities

### Metadata (created, updated)
Each record automatically holds basic data of timestamp and user who created and last updated the record.
(see `Entity` class)
1 change: 1 addition & 0 deletions doc/compodoc_sources/concepts/extendability.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ The following aspects are specifically designed to be extended:
- defining a screen completely, including data loaded, etc. and hook it into the platforms navigation and overall layout
- **Sub-Views**
- defining a screen to display custom details for the entity currently loaded in the active route. The core platform takes care of passing the current entity and config details to the view as inputs.
- *also see [How to create an Entity Details Panel](../how-to-guides/create-an-entity-details-panel.html)*
- **Dashboard Widgets**
- filling the given card template with custom data and visualization
- **Filters**
Expand Down
46 changes: 46 additions & 0 deletions doc/compodoc_sources/how-to-guides/create-entity-details-panel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# How to create an Entity Details Panel Component
Aam Digital as a platform takes care of loading the relevant entity and configs for an "Entity Details View",
which displays the information about a single entity (e.g. one specific student).
The `EntityDetailsComponent` handles this initialization from the route.
To display some details in a customized way, you can create "panel components" that receive a reference to the current entity and their config parameters as `@Input()` automatically.

![](../../images/entity-details-panels.png)
The tabs (in the config called "panels") within the Entity Details view can display one or more "panel components", as shown above.

To make these components as re-usable and simple as possible, we do not load config from the route here.
Instead, the components are initialized from config by the `DynamicComponentDirective`.
This automatically sets `@Input()` properties to the value with the same name in the config object.

Those background details aside, what that means for your implementation is:

## Implementing a new Panel Component

1. Create a new component class
2. Add an `@Input() entity: Entity;`. This will always contain the entity object, whose Details View is currently being displayed. You should not load this yourself from the database.
3. (If needed) Add more inputs for aspects that should be configurable about your component.
(e.g. `@Input() showDescription: boolean;`, which you can use in your template or code to adapt the component.)
These values are automatically set to whatever value is specified in the config object for your component at runtime in the database.
4. Register the new component in its parent module, so that it can be loaded under its name through the config.

An example config for the above:
```json
{
"component": "MySubView",
"config": { "showDescription": true }
}
```

Use the `ComponentRegistry` to register your component,
e.g. in its Module:
```javascript
export class MyModule {
constructor(components: ComponentRegistry) {
components.addAll([
[
"MySubView", // this is the name to use in the config document
() => import("./my-sub-view/my-sub-view.component").then((c) => c.MySubViewComponent),
],
]);
}
}
```
82 changes: 50 additions & 32 deletions doc/compodoc_sources/summary.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,18 @@
"file": "concepts/extendability.md"
},
{
"title": "Entity Schema",
"file": "concepts/entity-schema-system.md"
"title": "Entity System",
"file": "concepts/entities.md",
"children": [
{
"title": "Entity Schema",
"file": "concepts/entity-schema-system.md"
},
{
"title": "Archiving, Anonymizing and Deleting Entities",
"file": "concepts/entity-anonymization.md"
}
]
},
{
"title": "Configuration",
Expand Down Expand Up @@ -75,6 +85,28 @@
"title": "How-To Guides",
"file": "how-to-guides/_index.md",
"children": [
{
"title": "Development Processes",
"file": "how-to-guides/contribute-code.md",
"children": [
{
"title": "Write Automated Unit Tests",
"file": "how-to-guides/write-unit-tests.md"
},
{
"title": "Write E2E Tests",
"file": "how-to-guides/write-e2e-tests.md"
},
{
"title": "Document Code",
"file": "how-to-guides/write-documentation.md"
},
{
"title": "Review a Pull Request",
"file": "how-to-guides/review-pull-request.md"
}
]
},
{
"title": "Configure and Customize a System",
"file": "how-to-guides/configure-custom-system.md"
Expand All @@ -83,14 +115,14 @@
"title": "Navigate the Code Structure",
"file": "how-to-guides/navigate-code-structure.md"
},
{
"title": "Contribute Code to the Project",
"file": "how-to-guides/contribute-code.md"
},
{
"title": "Create a New Entity Type",
"file": "how-to-guides/create-new-entity-type.md"
},
{
"title": "Create an Entity Details Panel",
"file": "how-to-guides/create-entity-details-panel.md"
},
{
"title": "Create a New Datatype",
"file": "how-to-guides/create-new-datatype.md"
Expand All @@ -115,18 +147,6 @@
"title": "Log Errors",
"file": "how-to-guides/log-errors.md"
},
{
"title": "Write Automated Unit Tests",
"file": "how-to-guides/write-unit-tests.md"
},
{
"title": "Write E2E Tests",
"file": "how-to-guides/write-e2e-tests.md"
},
{
"title": "Document Code",
"file": "how-to-guides/write-documentation.md"
},
{
"title": "Use Queries and Indices",
"file": "how-to-guides/use-queries-and-indices.md"
Expand All @@ -135,25 +155,23 @@
"title": "Generate Demo Data",
"file": "how-to-guides/generate-demo-data.md"
},
{
"title": "Review a Pull Request",
"file": "how-to-guides/review-pull-request.md"
},
{
"title": "Format Data Export",
"file": "how-to-guides/exports.md"
},
{
"title": "Build Localizable Components",
"file": "how-to-guides/build-localizable-components.md"
},
{
"title": "Work with XLF",
"file": "how-to-guides/work-with-xlf.md"
},
{
"title": "Add Another Language",
"file": "how-to-guides/add-another-language.md"
"title": "Build localizable (translatable) UI",
"file": "how-to-guides/build-localizable-components.md",
"children": [
{
"title": "Work with XLF",
"file": "how-to-guides/work-with-xlf.md"
},
{
"title": "Add Another Language",
"file": "how-to-guides/add-another-language.md"
}
]
}
]
},
Expand Down
Binary file added doc/images/cascading-delete.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/images/entity-details-panels.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 0 additions & 42 deletions e2e/integration/MarkingChildAsDropout.cy.ts

This file was deleted.

Loading

0 comments on commit 4273959

Please sign in to comment.