ssb-dash-framework 0.2.0a1__tar.gz → 0.2.2__tar.gz

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.
Files changed (65) hide show
  1. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/PKG-INFO +14 -10
  2. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/pyproject.toml +23 -8
  3. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/__init__.py +44 -7
  4. ssb_dash_framework-0.2.2/src/ssb_dash_framework/assets/dashAgGridFunctions.js +260 -0
  5. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/assets/stylesheet.css +140 -4
  6. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/control/__init__.py +2 -1
  7. ssb_dash_framework-0.2.2/src/ssb_dash_framework/control/control_framework_base.py +590 -0
  8. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/__init__.py +40 -6
  9. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/aarsregnskap.py +17 -8
  10. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/agg_dist_plotter.py +3 -3
  11. ssb_dash_framework-0.2.2/src/ssb_dash_framework/modules/altinn_control_view.py +558 -0
  12. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/altinn_data_capture.py +5 -5
  13. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/altinn_editor/__init__.py +2 -0
  14. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/altinn_editor/altinn_editor_comment.py +2 -2
  15. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/altinn_editor/altinn_editor_contact.py +3 -4
  16. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/altinn_editor/altinn_editor_control.py +6 -7
  17. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/altinn_editor/altinn_editor_history.py +29 -7
  18. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/altinn_editor/altinn_editor_main_view.py +21 -19
  19. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/altinn_editor/altinn_editor_primary_table.py +101 -19
  20. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/altinn_editor/altinn_editor_submitted_forms.py +8 -4
  21. ssb_dash_framework-0.2.2/src/ssb_dash_framework/modules/altinn_editor/altinn_editor_supporting_table.py +244 -0
  22. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/altinn_editor/altinn_editor_unit_details.py +4 -5
  23. ssb_dash_framework-0.2.2/src/ssb_dash_framework/modules/altinn_editor/altinn_editor_utility.py +17 -0
  24. ssb_dash_framework-0.2.2/src/ssb_dash_framework/modules/bedriftstabell.py +310 -0
  25. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/bofregistry.py +38 -18
  26. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/building_blocks/canvas.py +6 -6
  27. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/building_blocks/figuredisplay.py +6 -6
  28. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/building_blocks/map_display.py +27 -27
  29. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/building_blocks/multimodule.py +6 -6
  30. ssb_dash_framework-0.2.2/src/ssb_dash_framework/modules/building_blocks/tables.py +411 -0
  31. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/freesearch.py +13 -14
  32. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/hb_method.py +13 -13
  33. ssb_dash_framework-0.2.2/src/ssb_dash_framework/modules/macro_module.py +1227 -0
  34. ssb_dash_framework-0.2.2/src/ssb_dash_framework/modules/nspek.py +412 -0
  35. ssb_dash_framework-0.2.2/src/ssb_dash_framework/modules/parquet_editor.py +933 -0
  36. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/pi_memorizer.py +7 -13
  37. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/skjemapdfviewer.py +10 -15
  38. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/visualizationbuilder.py +12 -16
  39. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/setup/app_setup.py +9 -9
  40. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/setup/main_layout.py +5 -10
  41. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/setup/variableselector.py +13 -14
  42. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/utils/__init__.py +0 -2
  43. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/utils/alert_handler.py +22 -22
  44. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/utils/app_logger.py +5 -5
  45. ssb_dash_framework-0.2.2/src/ssb_dash_framework/utils/core_query_functions.py +170 -0
  46. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/utils/datahelper.py +16 -15
  47. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/utils/debugger_modal.py +3 -3
  48. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/utils/eimerdb_helpers.py +4 -4
  49. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/utils/functions.py +10 -4
  50. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/utils/implementations.py +22 -28
  51. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/utils/module_validation.py +1 -1
  52. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/utils/r_helpers.py +24 -14
  53. ssb_dash_framework-0.2.0a1/src/ssb_dash_framework/control/control_framework_base.py +0 -250
  54. ssb_dash_framework-0.2.0a1/src/ssb_dash_framework/modules/altinn_control_view.py +0 -459
  55. ssb_dash_framework-0.2.0a1/src/ssb_dash_framework/modules/altinn_editor/altinn_editor_supporting_table.py +0 -320
  56. ssb_dash_framework-0.2.0a1/src/ssb_dash_framework/modules/building_blocks/tables.py +0 -678
  57. ssb_dash_framework-0.2.0a1/src/ssb_dash_framework/modules/control.py +0 -206
  58. ssb_dash_framework-0.2.0a1/src/ssb_dash_framework/utils/core_query_functions.py +0 -68
  59. ssb_dash_framework-0.2.0a1/src/ssb_dash_framework/utils/prosesslogg.py +0 -73
  60. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/LICENSE +0 -0
  61. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/README.md +0 -0
  62. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/__main__.py +0 -0
  63. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/modules/building_blocks/__init__.py +0 -0
  64. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/py.typed +0 -0
  65. {ssb_dash_framework-0.2.0a1 → ssb_dash_framework-0.2.2}/src/ssb_dash_framework/setup/__init__.py +0 -0
@@ -1,34 +1,38 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: ssb-dash-framework
3
- Version: 0.2.0a1
3
+ Version: 0.2.2
4
4
  Summary: SSB Dash Framework
5
- License: GPL-3.0
5
+ License-Expression: GPL-3.0
6
+ License-File: LICENSE
6
7
  Author: Magnus Theodor Engh
7
8
  Author-email: dor@ssb.no
8
9
  Requires-Python: >=3.10,<4.0
9
10
  Classifier: Development Status :: 4 - Beta
10
- Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Classifier: Programming Language :: Python :: 3.10
13
13
  Classifier: Programming Language :: Python :: 3.11
14
14
  Classifier: Programming Language :: Python :: 3.12
15
15
  Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Programming Language :: Python :: 3.14
16
17
  Requires-Dist: click (>=8.0.1)
17
18
  Requires-Dist: dapla-toolbelt (>=2.0.8,<5.0.0)
18
- Requires-Dist: dash (==2.18.2)
19
- Requires-Dist: dash-ag-grid (>=32.3.1,<33.0.0)
20
- Requires-Dist: dash-bootstrap-components (==1.7.1)
21
- Requires-Dist: dash-bootstrap-templates (>=1.2.4)
19
+ Requires-Dist: dash (>=3.3.0,<4.0.0)
20
+ Requires-Dist: dash-ag-grid (>=32.3.2,<33.0.0)
21
+ Requires-Dist: dash-bootstrap-components (>=2.0.4,<3.0.0)
22
+ Requires-Dist: dash-bootstrap-templates (>=2.1.0,<3.0.0)
23
+ Requires-Dist: duckdb (==1.3.2)
22
24
  Requires-Dist: geopandas (>=1.1.1,<2.0.0)
23
- Requires-Dist: ibis-framework[postgres] (>=11.0.0,<12.0.0)
25
+ Requires-Dist: ibis-framework[polars,postgres] (>=11.0.0,<12.0.0)
24
26
  Requires-Dist: ipykernel (>=6.29.5,<7.0.0)
25
27
  Requires-Dist: mpmath (>=1.3.0)
26
28
  Requires-Dist: orjson (>=3.10.16,<4.0.0)
27
29
  Requires-Dist: pandas (>=2.3.1,<3.0.0)
28
30
  Requires-Dist: psycopg2-binary (>=2.9.10,<3.0.0)
31
+ Requires-Dist: rpy2 (>=3.6.4,<4.0.0)
29
32
  Requires-Dist: rwrapr (>=0.9.1,<0.10.0)
30
33
  Requires-Dist: sqlalchemy (>=2.0.43,<3.0.0)
31
- Requires-Dist: ssb-eimerdb (>=0.2.5,<0.3.0)
34
+ Requires-Dist: ssb-eimerdb (>=0.2.6,<0.3.0)
35
+ Requires-Dist: ssb-poc-statlog-model (>=1.0.0,<2.0.0)
32
36
  Project-URL: Changelog, https://github.com/statisticsnorway/ssb-dash-framework/releases
33
37
  Project-URL: Documentation, https://statisticsnorway.github.io/ssb-dash-framework
34
38
  Project-URL: Homepage, https://github.com/statisticsnorway/ssb-dash-framework
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ssb-dash-framework"
3
- version = "0.2.0a1"
3
+ version = "0.2.2"
4
4
  description = "SSB Dash Framework"
5
5
  authors = [{ name = "Magnus Theodor Engh", email = "dor@ssb.no" }]
6
6
  license = "GPL-3.0"
@@ -10,20 +10,23 @@ dynamic = ["classifiers"]
10
10
  dependencies = [
11
11
  "click>=8.0.1",
12
12
  "pandas (>=2.3.1,<3.0.0)",
13
- "dash (==2.18.2)",
14
- "dash-bootstrap-components (==1.7.1)",
15
- "dash-ag-grid (>=32.3.1,<33.0.0)",
16
- "dash-bootstrap-templates (>=1.2.4)",
17
13
  "dapla-toolbelt (>=2.0.8, <5.0.0)", # Used for reading pdf's
18
14
  "mpmath>=1.3.0", # Pimemorizer uses this
19
15
  "orjson (>=3.10.16,<4.0.0)",
20
16
  "ipykernel (>=6.29.5,<7.0.0)",
21
17
  "psycopg2-binary (>=2.9.10,<3.0.0)",
22
18
  "geopandas (>=1.1.1,<2.0.0)",
23
- "ssb-eimerdb (>=0.2.5,<0.3.0)",
19
+ "ssb-eimerdb (>=0.2.6,<0.3.0)",
24
20
  "sqlalchemy (>=2.0.43,<3.0.0)",
25
- "ibis-framework[postgres] (>=11.0.0,<12.0.0)",
21
+ "ibis-framework[polars,postgres] (>=11.0.0,<12.0.0)",
26
22
  "rwrapr (>=0.9.1,<0.10.0)",
23
+ "dash-ag-grid (>=32.3.2,<33.0.0)",
24
+ "dash (>=3.3.0,<4.0.0)",
25
+ "dash-bootstrap-components (>=2.0.4,<3.0.0)",
26
+ "rpy2 (>=3.6.4,<4.0.0)",
27
+ "dash-bootstrap-templates (>=2.1.0,<3.0.0)",
28
+ "duckdb (==1.3.2)",
29
+ "ssb-poc-statlog-model (>=1.0.0,<2.0.0)",
27
30
  ]
28
31
 
29
32
  [project.urls]
@@ -43,7 +46,6 @@ requires-poetry = ">=2.0"
43
46
  pygments = ">=2.10.0"
44
47
  black = { extras = ["jupyter"], version = ">=23.1.0" }
45
48
  coverage = { extras = ["toml"], version = ">=6.2" }
46
- darglint = ">=1.8.1"
47
49
  furo = ">=2021.11.12"
48
50
  mypy = ">=0.930"
49
51
  pre-commit = ">=2.16.0"
@@ -58,6 +60,8 @@ typeguard = ">=2.13.3"
58
60
  xdoctest = { extras = ["colors"], version = ">=0.15.10" }
59
61
  myst-parser = { version = ">=0.16.1" }
60
62
  deptry = ">=0.23.0"
63
+ pydoclint = ">=0.8.3"
64
+ pandas-stubs = ">=2.3.1"
61
65
 
62
66
  [tool.poetry.requires-plugins]
63
67
  poetry-plugin-export = ">=1.9"
@@ -89,6 +93,16 @@ show_column_numbers = true
89
93
  show_error_context = true
90
94
  ignore_missing_imports = true
91
95
 
96
+ [tool.pydoclint]
97
+ style = "google"
98
+ exclude = '\.git|\.nox'
99
+ arg-type-hints-in-docstring = false
100
+ check-return-types = false
101
+ check-yield-types = false
102
+ allow-init-docstring = true
103
+ # native-mode-noqa-location = "definition"
104
+ quiet = true
105
+
92
106
  [tool.ruff]
93
107
  force-exclude = true # Apply excludes to pre-commit
94
108
  show-fixes = true
@@ -127,6 +141,7 @@ ignore = [
127
141
  "E501", # Supress line-too-long warnings: trust black's judgement on this one.
128
142
  "PLR2004", # Allow to compare with unnamed numerical constants.
129
143
  ]
144
+ external = ["DOC"] ## Avoiding removing any codes starting with `DOC` from any `# noqa` directives.
130
145
 
131
146
  [tool.ruff.lint.isort]
132
147
  force-single-line = true
@@ -1,26 +1,32 @@
1
1
  """SSB Dash Framework."""
2
2
 
3
3
  from .control import ControlFrameworkBase
4
+ from .control import register_control
4
5
  from .modules import Aarsregnskap
5
6
  from .modules import AarsregnskapTab
6
7
  from .modules import AarsregnskapWindow
7
8
  from .modules import AggDistPlotter
8
9
  from .modules import AggDistPlotterTab
9
10
  from .modules import AggDistPlotterWindow
10
- from .modules import AltinnControlView
11
+ from .modules import AltinnControlViewTab
11
12
  from .modules import AltinnControlViewWindow
12
13
  from .modules import AltinnDataCapture
13
14
  from .modules import AltinnDataCaptureTab
14
15
  from .modules import AltinnDataCaptureWindow
15
16
  from .modules import AltinnSkjemadataEditor
17
+ from .modules import AltinnSupportTable
18
+ from .modules import Bedriftstabell
19
+ from .modules import BedriftstabellTab
20
+ from .modules import BedriftstabellWindow
16
21
  from .modules import BofInformation
17
22
  from .modules import BofInformationTab
18
23
  from .modules import BofInformationWindow
19
24
  from .modules import Canvas
20
25
  from .modules import CanvasTab
21
26
  from .modules import CanvasWindow
22
- from .modules import Control
23
- from .modules import ControlWindow
27
+ from .modules import ControlView
28
+ from .modules import ControlViewTab
29
+ from .modules import ControlViewWindow
24
30
  from .modules import EditingTable
25
31
  from .modules import EditingTableTab
26
32
  from .modules import EditingTableWindow
@@ -32,18 +38,30 @@ from .modules import FreeSearchTab
32
38
  from .modules import FreeSearchWindow
33
39
  from .modules import HBMethod
34
40
  from .modules import HBMethodWindow
41
+ from .modules import MacroModule
42
+ from .modules import MacroModuleTab
43
+ from .modules import MacroModuleWindow
35
44
  from .modules import MapDisplay
36
45
  from .modules import MapDisplayTab
37
46
  from .modules import MapDisplayWindow
38
47
  from .modules import MultiModule
39
48
  from .modules import MultiModuleTab
40
49
  from .modules import MultiModuleWindow
50
+ from .modules import Naeringsspesifikasjon
51
+ from .modules import NaeringsspesifikasjonTab
52
+ from .modules import NaeringsspesifikasjonWindow
53
+ from .modules import ParquetEditor
54
+ from .modules import ParquetEditorChangelog
41
55
  from .modules import PimemorizerTab
42
56
  from .modules import SkjemapdfViewer
43
57
  from .modules import SkjemapdfViewerTab
44
58
  from .modules import SkjemapdfViewerWindow
45
59
  from .modules import VisualizationBuilder
46
60
  from .modules import VisualizationBuilderWindow
61
+ from .modules import apply_edits
62
+ from .modules import export_from_parqueteditor
63
+ from .modules import get_export_log_path
64
+ from .modules import get_log_path
47
65
  from .setup import VariableSelector
48
66
  from .setup import VariableSelectorOption
49
67
  from .setup import app_setup
@@ -57,13 +75,13 @@ from .utils import TabImplementation
57
75
  from .utils import WindowImplementation
58
76
  from .utils import _get_kostra_r
59
77
  from .utils import active_no_duplicates_refnr_list
60
- from .utils import apply_edits
61
78
  from .utils import conn_is_ibis
62
79
  from .utils import create_alert
63
80
  from .utils import create_database
64
81
  from .utils import create_database_engine
65
82
  from .utils import enable_app_logging
66
83
  from .utils import hb_method
84
+ from .utils import ibis_filter_with_dict
67
85
  from .utils import module_validator
68
86
  from .utils import sidebar_button
69
87
 
@@ -77,21 +95,26 @@ __all__ = [
77
95
  "AggDistPlotterTab",
78
96
  "AggDistPlotterWindow",
79
97
  "AlertHandler",
80
- "AltinnControlView",
98
+ "AltinnControlViewTab",
81
99
  "AltinnControlViewWindow",
82
100
  "AltinnDataCapture",
83
101
  "AltinnDataCaptureTab",
84
102
  "AltinnDataCaptureWindow",
85
103
  "AltinnSkjemadataEditor",
104
+ "AltinnSupportTable",
105
+ "Bedriftstabell",
106
+ "BedriftstabellTab",
107
+ "BedriftstabellWindow",
86
108
  "BofInformation",
87
109
  "BofInformationTab",
88
110
  "BofInformationWindow",
89
111
  "Canvas",
90
112
  "CanvasTab",
91
113
  "CanvasWindow",
92
- "Control",
93
114
  "ControlFrameworkBase",
94
- "ControlWindow",
115
+ "ControlView",
116
+ "ControlViewTab",
117
+ "ControlViewWindow",
95
118
  "DatabaseBuilderAltinnEimerdb",
96
119
  "DebugInspector",
97
120
  "DemoDataCreator",
@@ -106,6 +129,9 @@ __all__ = [
106
129
  "FreeSearchWindow",
107
130
  "HBMethod",
108
131
  "HBMethodWindow",
132
+ "MacroModule",
133
+ "MacroModuleTab",
134
+ "MacroModuleWindow",
109
135
  "MapDisplay",
110
136
  "MapDisplayTab",
111
137
  "MapDisplayWindow",
@@ -116,6 +142,11 @@ __all__ = [
116
142
  "MultiModuleWindow",
117
143
  "MultiModuleWindow",
118
144
  "MultiModuleWindow",
145
+ "Naeringsspesifikasjon",
146
+ "NaeringsspesifikasjonTab",
147
+ "NaeringsspesifikasjonWindow",
148
+ "ParquetEditor",
149
+ "ParquetEditorChangelog",
119
150
  "PimemorizerTab",
120
151
  "SkjemapdfViewer",
121
152
  "SkjemapdfViewerTab",
@@ -128,13 +159,19 @@ __all__ = [
128
159
  "WindowImplementation",
129
160
  "active_no_duplicates_refnr_list",
130
161
  "app_setup",
162
+ "apply_edits",
131
163
  "conn_is_ibis",
132
164
  "create_alert",
133
165
  "create_database",
134
166
  "create_database_engine",
135
167
  "enable_app_logging",
168
+ "export_from_parqueteditor",
169
+ "get_export_log_path",
170
+ "get_log_path",
171
+ "ibis_filter_with_dict",
136
172
  "main_layout",
137
173
  "module_validator",
174
+ "register_control",
138
175
  "set_variables",
139
176
  "sidebar_button",
140
177
  # "hb_method",
@@ -0,0 +1,260 @@
1
+ window.dashAgGridFunctions = window.dashAgGridFunctions || {};
2
+
3
+ // MacroModule
4
+ window.dashAgGridFunctions.MacroModule = {
5
+
6
+ // === Function formatHeatmapValue (Format values based on row type) ===
7
+ formatHeatmapValue(params, isPercentage) {
8
+ const value = params.value;
9
+
10
+ if (value === null || value === undefined) {
11
+ return '';
12
+ }
13
+
14
+ // Special handling for count row - just show number with thousand separator
15
+ if (params.data && params.data.id === 'count_row') {
16
+ return value.toLocaleString('nb-NO', {
17
+ minimumFractionDigits: 0,
18
+ maximumFractionDigits: 0
19
+ });
20
+ }
21
+
22
+ // Regular cells - format as percentage or number
23
+ if (isPercentage) {
24
+ return value.toLocaleString('nb-NO', {
25
+ style: 'percent',
26
+ minimumFractionDigits: 1,
27
+ maximumFractionDigits: 1
28
+ });
29
+ } else {
30
+ return value.toLocaleString('nb-NO', {
31
+ minimumFractionDigits: 0,
32
+ maximumFractionDigits: 0
33
+ });
34
+ }
35
+ },
36
+
37
+ // === Function formatDetailGridValue (Format numeric values in detail grid) ===
38
+ formatDetailGridValue(params) {
39
+ const value = params.value;
40
+
41
+ if (value === null || value === undefined || value === '') {
42
+ return '';
43
+ }
44
+
45
+ // Format as number with thousand separator
46
+ return value.toLocaleString('nb-NO', {
47
+ minimumFractionDigits: 0,
48
+ maximumFractionDigits: 0
49
+ });
50
+ },
51
+
52
+ // === Function displayDiffHeatMap (Heatmap colouring for a matrix-table with +/- 30% diff threshold) ===
53
+ displayDiffHeatMap(props) {
54
+
55
+ // Special handling for count row
56
+ if (props.data && props.data.id === 'count_row') {
57
+ return {
58
+ color: 'black',
59
+ };
60
+ }
61
+
62
+ const val = props.value;
63
+
64
+ if (val === null || val === undefined || isNaN(val)) {
65
+ return {};
66
+ }
67
+
68
+ const threshold = 0.3;
69
+ const normalized = val / threshold;
70
+
71
+ // base colors
72
+ const red = [252, 195, 174]; // normal red
73
+ const blue = [180, 213, 250]; // normal blue
74
+ const white = [255, 255, 255]; // white background
75
+
76
+ // darker shades for beyond 30% threshold
77
+ const darkRed = [252, 142, 104];
78
+ const darkBlue = [126, 165, 252];
79
+
80
+ let r, g, b;
81
+
82
+ if (normalized >= 1) {
83
+ // beyond positive threshold — dark blue
84
+ r = darkBlue[0];
85
+ g = darkBlue[1];
86
+ b = darkBlue[2];
87
+ } else if (normalized <= -1) {
88
+ // below negative threshold — use dark red
89
+ r = darkRed[0];
90
+ g = darkRed[1];
91
+ b = darkRed[2];
92
+ } else if (normalized >= 0) {
93
+ // normal range: interpolate white to blue
94
+ let clamped = Math.min(normalized, 1);
95
+ r = white[0] * (1 - clamped) + blue[0] * clamped;
96
+ g = white[1] * (1 - clamped) + blue[1] * clamped;
97
+ b = white[2] * (1 - clamped) + blue[2] * clamped;
98
+ } else {
99
+ // normal range: interpolate white to red
100
+ let clamped = Math.max(normalized, -1);
101
+ r = white[0] * (1 + clamped) + red[0] * -clamped;
102
+ g = white[1] * (1 + clamped) + red[1] * -clamped;
103
+ b = white[2] * (1 + clamped) + red[2] * -clamped;
104
+ }
105
+
106
+ return {
107
+ backgroundColor: `rgb(${Math.round(r)}, ${Math.round(g)}, ${Math.round(b)})`,
108
+ color: 'black',
109
+ };
110
+ },
111
+
112
+ // === Function displaySimpleHeatMap (Simple 2-choice (cold/warm for neg/pos) heatmap) ===
113
+ displaySimpleHeatMap(props) {
114
+
115
+ // Special handling for count row
116
+ if (props.data && props.data.id === 'count_row') {
117
+ return {
118
+ color: 'black',
119
+ };
120
+ }
121
+
122
+ const val = props.value;
123
+
124
+ if (val === null || val === undefined || isNaN(val)) {
125
+ return {};
126
+ }
127
+
128
+ // clamp value to [-1, 1] for interpolation
129
+ const clamped = Math.max(-1, Math.min(1, val));
130
+
131
+ // base colors
132
+ const red = [252, 195, 174];
133
+ const blue = [180, 213, 250];
134
+ const white = [255, 255, 255];
135
+
136
+ let r, g, b;
137
+
138
+ if (clamped >= 0) {
139
+ // interpolate from white to blue
140
+ r = white[0] * (1 - clamped) + blue[0] * clamped;
141
+ g = white[1] * (1 - clamped) + blue[1] * clamped;
142
+ b = white[2] * (1 - clamped) + blue[2] * clamped;
143
+ } else {
144
+ // interpolate from white to red
145
+ r = white[0] * (1 + clamped) + red[0] * -clamped;
146
+ g = white[1] * (1 + clamped) + red[1] * -clamped;
147
+ b = white[2] * (1 + clamped) + red[2] * -clamped;
148
+ }
149
+
150
+ return {
151
+ backgroundColor: `rgb(${Math.round(r)}, ${Math.round(g)}, ${Math.round(b)})`,
152
+ color: 'black',
153
+ };
154
+ },
155
+
156
+ // === Function displayDiffHighlight (Compare current cell's value to previous year, highlight if different) ===
157
+ displayDiffHighlight(props) {
158
+
159
+ if (!props.data) return {};
160
+
161
+ const field = props.colDef.field;
162
+ const value = props.value;
163
+
164
+ const normalize = (v) =>
165
+ v !== null && v !== undefined ? String(v).trim() : "";
166
+
167
+ // special handling for naring_b / naring_f
168
+ if (field === "naring_b" || field === "naring_f") {
169
+ const currentVal = normalize(value);
170
+ const prevVal = normalize(props.data[field + "_x"]);
171
+
172
+ const currentPrefix = currentVal.substring(0, 2); // first 2 digits
173
+ const prevPrefix = prevVal.substring(0, 2);
174
+
175
+ // CASE A: prefix changed → darker yellow
176
+ if (currentPrefix && prevPrefix && currentPrefix !== prevPrefix) {
177
+ return {
178
+ backgroundColor: "#ffe491ff",
179
+ color: "black",
180
+ };
181
+ }
182
+
183
+ // CASE B: prefix same → normal diff behaviour
184
+ if (prevVal && currentVal && prevVal !== currentVal) {
185
+ return {
186
+ backgroundColor: "#fff8c7ff", // light yellow
187
+ color: "black"
188
+ };
189
+ }
190
+
191
+ return {}; // no change
192
+ }
193
+
194
+ const prevField = field + "_x";
195
+ const prevValue = normalize(props.data[prevField]);
196
+ const currentValue = normalize(value);
197
+
198
+ if (prevValue && currentValue && prevValue !== currentValue) {
199
+ return {
200
+ backgroundColor: "#fff8c7ff",
201
+ color: "black"
202
+ };
203
+ }
204
+
205
+ return {};
206
+
207
+ },
208
+
209
+ // === Function displayNaringRowMismatch (Grey out row if first 2 digits of naring_b and naring_f differ) ===
210
+ displayNaringRowMismatch(props) {
211
+ if (!props.data) return false;
212
+
213
+ const naringB = props.data.naring_b;
214
+ const naringF = props.data.naring_f;
215
+
216
+ // if either value is missing, no styling
217
+ if (!naringB || !naringF) return false;
218
+
219
+ // compare first 2 digits
220
+ const prefixB = String(naringB).substring(0, 2);
221
+ const prefixF = String(naringF).substring(0, 2);
222
+
223
+ return prefixB !== prefixF;
224
+ },
225
+
226
+ // === Function displayDiffColumnHighlight (Mark tilgang & avgang on the diff-column) ===
227
+ displayDiffColumnHighlight(props) {
228
+ if (!props.data) return {};
229
+
230
+ const field = props.colDef.field;
231
+
232
+ const isDiffColumn = field.endsWith("_diff");
233
+ const isExitHighlightField =
234
+ (field === "orgnr_b" || field === "navn") &&
235
+ props.data.is_avgang &&
236
+ props.data.is_exiter;
237
+
238
+ // Guard: only apply to allowed columns
239
+ if (!isDiffColumn && !isExitHighlightField) return {};
240
+
241
+ // tilgang (still only for diff columns)
242
+ if (isDiffColumn && props.data.is_tilgang) {
243
+ return {
244
+ backgroundColor: "#c7f5c7",
245
+ color: "black",
246
+ };
247
+ }
248
+
249
+ // avgang (diff columns OR exiter name/orgnr)
250
+ if (props.data.is_avgang) {
251
+ return {
252
+ backgroundColor: "#ffc7c7",
253
+ color: "black",
254
+ };
255
+ }
256
+
257
+ return {};
258
+ }
259
+
260
+ };