From 11d835054de9d51031b6284dd98f9498b62c02a3 Mon Sep 17 00:00:00 2001 From: jochen Date: Sun, 5 May 2024 11:05:19 +0200 Subject: [PATCH] Update HTML export --- CHANGELOG.md | 4 +- datacontract/breaking/breaking_rules.py | 4 + .../model/data_contract_specification.py | 2 + datacontract/templates/datacontract.html | 86 ++++++++++++++++--- datacontract/templates/style/output.css | 44 ++++++++-- tests/fixtures/export/datacontract.yaml | 1 + tests/test_changelog.py | 6 +- 7 files changed, 124 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a544383..b630f86c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,10 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Added import glue (#166) - Added test support for `azure` (#146) - Added support for `delta` tables on S3 (#24) - Added new command `datacontract catalog` that generates a data contract catalog with an `index.html` file. - +- Added field format information to HTML export + ### Fixed - RDF Export: Fix error if owner is not a URI/URN diff --git a/datacontract/breaking/breaking_rules.py b/datacontract/breaking/breaking_rules.py index 1520272a..ca36f1c5 100644 --- a/datacontract/breaking/breaking_rules.py +++ b/datacontract/breaking/breaking_rules.py @@ -20,6 +20,10 @@ class BreakingRules: field_ref_removed = Severity.WARNING field_ref_updated = Severity.WARNING + field_title_added = Severity.INFO + field_title_removed = Severity.INFO + field_title_updated = Severity.INFO + field_type_added = Severity.WARNING field_type_removed = Severity.WARNING field_type_updated = Severity.ERROR diff --git a/datacontract/model/data_contract_specification.py b/datacontract/model/data_contract_specification.py index 8788f64d..3decdfa8 100644 --- a/datacontract/model/data_contract_specification.py +++ b/datacontract/model/data_contract_specification.py @@ -63,6 +63,7 @@ class Definition(pyd.BaseModel): class Field(pyd.BaseModel): ref: str = pyd.Field(default=None, alias="$ref") ref_obj: Definition = pyd.Field(default=None, exclude=True) + title: str = None type: str = None format: str = None required: bool = None @@ -95,6 +96,7 @@ class Model(pyd.BaseModel): class Info(pyd.BaseModel): title: str = None version: str = None + status: str = None description: str = None owner: str = None contact: Contact = None diff --git a/datacontract/templates/datacontract.html b/datacontract/templates/datacontract.html index 3cc86384..2138f190 100644 --- a/datacontract/templates/datacontract.html +++ b/datacontract/templates/datacontract.html @@ -78,6 +78,13 @@

Info

{{ datacontract.info.version }}
+ {% if datacontract.info.status %} +
+
Status
+
{{ datacontract.info.status }}
+
+ {% endif %} + {% if datacontract.info.description %}
Description
@@ -353,7 +360,7 @@

- - - diff --git a/datacontract/templates/style/output.css b/datacontract/templates/style/output.css index 4074fadf..de2cc769 100644 --- a/datacontract/templates/style/output.css +++ b/datacontract/templates/style/output.css @@ -736,12 +736,8 @@ video { width: 2.5rem; } -.w-16 { - width: 4rem; -} - -.w-3\/12 { - width: 25%; +.w-2\/12 { + width: 16.666667%; } .w-4 { @@ -929,6 +925,11 @@ video { border-radius: 0.375rem; } +.bg-blue-50 { + --tw-bg-opacity: 1; + background-color: rgb(239 246 255 / var(--tw-bg-opacity)); +} + .bg-gray-100 { --tw-bg-opacity: 1; background-color: rgb(243 244 246 / var(--tw-bg-opacity)); @@ -954,6 +955,11 @@ video { background-color: rgb(255 255 255 / var(--tw-bg-opacity)); } +.bg-yellow-50 { + --tw-bg-opacity: 1; + background-color: rgb(254 252 232 / var(--tw-bg-opacity)); +} + .bg-opacity-75 { --tw-bg-opacity: 0.75; } @@ -1054,6 +1060,10 @@ video { vertical-align: middle; } +.font-mono { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; +} + .text-2xl { font-size: 1.5rem; line-height: 2rem; @@ -1091,6 +1101,10 @@ video { font-weight: 600; } +.italic { + font-style: italic; +} + .leading-5 { line-height: 1.25rem; } @@ -1103,6 +1117,11 @@ video { line-height: 1.75rem; } +.text-blue-600 { + --tw-text-opacity: 1; + color: rgb(37 99 235 / var(--tw-text-opacity)); +} + .text-gray-400 { --tw-text-opacity: 1; color: rgb(156 163 175 / var(--tw-text-opacity)); @@ -1133,6 +1152,11 @@ video { color: rgb(255 255 255 / var(--tw-text-opacity)); } +.text-yellow-600 { + --tw-text-opacity: 1; + color: rgb(202 138 4 / var(--tw-text-opacity)); +} + .shadow { --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); @@ -1166,6 +1190,10 @@ video { --tw-ring-color: rgb(0 0 0 / var(--tw-ring-opacity)); } +.ring-blue-500\/10 { + --tw-ring-color: rgb(59 130 246 / 0.1); +} + .ring-gray-300 { --tw-ring-opacity: 1; --tw-ring-color: rgb(209 213 219 / var(--tw-ring-opacity)); @@ -1179,6 +1207,10 @@ video { --tw-ring-color: rgb(17 24 39 / 0.05); } +.ring-yellow-500\/10 { + --tw-ring-color: rgb(234 179 8 / 0.1); +} + .ring-opacity-5 { --tw-ring-opacity: 0.05; } diff --git a/tests/fixtures/export/datacontract.yaml b/tests/fixtures/export/datacontract.yaml index 95a10389..11ad54b9 100644 --- a/tests/fixtures/export/datacontract.yaml +++ b/tests/fixtures/export/datacontract.yaml @@ -3,6 +3,7 @@ id: orders-unit-test info: title: Orders Unit Test version: 1.0.0 + status: active owner: checkout description: The orders data contract contact: diff --git a/tests/test_changelog.py b/tests/test_changelog.py index bcb00dbd..90a8bf32 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -599,7 +599,7 @@ def test_definition_added(): output = result.stdout assert result.exit_code == 0 - assert "15 changes: 0 error, 13 warning, 2 info\n" in output + assert "16 changes: 0 error, 13 warning, 3 info\n" in output assert ( r"""warning [field_ref_added] at ./fixtures/breaking/datacontract-definitions-v2.yaml @@ -719,7 +719,7 @@ def test_definition_removed(): output = result.stdout assert result.exit_code == 0 - assert "15 changes: 3 error, 9 warning, 3 info\n" in output + assert "16 changes: 3 error, 9 warning, 4 info\n" in output assert ( r"""warning [field_ref_removed] at ./fixtures/breaking/datacontract-definitions-v1.yaml @@ -839,7 +839,7 @@ def test_definition_updated(): output = result.stdout assert result.exit_code == 0 - assert "15 changes: 12 error, 1 warning, 2 info\n" in output + assert "16 changes: 12 error, 1 warning, 3 info\n" in output assert ( r"""warning [field_ref_updated] at ./fixtures/breaking/datacontract-definitions-v3.yaml
+ {{ model_name }} {{ model.type }}
{{ model.description }}
@@ -366,28 +373,81 @@

{% for field_name, field in model.fields.items() %}

+
- {{ field_name }} + {% if field.title %} +
{{ field.title }}
+ {% endif %} +
{{ field_name }}
{# TODO nested fields #}
- {% if field.required %} - R - {% endif %} - {% if field.unique %} - U - {% endif %} - {% if field.type %} {{ field.type }} {% endif %} -
{{ field.description or "No description" }}
- {# TODO add format information #} + {% if field.description %} +
{{ field.description }}
+ {% else %} +
No description
+ {% endif %} + + {% if field.example %} +
+ Example: {{ field.example }} +
+ {% endif %} + +
+ {% if field.primary %} + primary + {% endif %} + {% if field.required %} + required + {% endif %} + {% if field.unique %} + unique + {% endif %} + {% if field.format %} + format:{{ field.format }} + {% endif %} + {% if field.minLength %} + minLength:{{ field.minLength }} + {% endif %} + {% if field.maxLength %} + maxLength:{{ field.maxLength }} + {% endif %} + {% if field.pattern %} + pattern:{{ field.pattern }} + {% endif %} + {% if field.precision %} + precision:{{ field.precision }} + {% endif %} + {% if field.scale %} + scale:{{ field.scale }} + {% endif %} + {% if field.minimum %} + minimum:{{ field.minimum }} + {% endif %} + {% if field.exclusiveMinimum %} + exclusiveMinimum:{{ field.exclusiveMinimum }} + {% endif %} + {% if field.maximum %} + maximum:{{ field.maximum }} + {% endif %} + {% if field.exclusiveMaximum %} + exclusiveMaximum:{{ field.exclusiveMaximum }} + {% endif %} + {% if field.classification %} + {{ field.classification }} + {% endif %} + {% if field.pii %} + PII + {% endif %} +
+