geonetwork-ui 2.2.0-dev.dc3a671b → 2.2.0-dev.e3947702

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 (117) hide show
  1. package/esm2022/libs/api/metadata-converter/src/lib/gn4/atomic-operations.mjs +2 -1
  2. package/esm2022/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.mjs +36 -2
  3. package/esm2022/libs/api/repository/src/lib/gn4/index.mjs +3 -1
  4. package/esm2022/libs/common/domain/src/lib/model/record/metadata.model.mjs +1 -1
  5. package/esm2022/libs/feature/dataviz/src/lib/service/data.service.mjs +5 -4
  6. package/esm2022/libs/feature/editor/src/lib/record-form/record-form.component.mjs +5 -3
  7. package/esm2022/libs/feature/map/src/index.mjs +2 -1
  8. package/esm2022/libs/feature/map/src/lib/constant/index.mjs +2 -1
  9. package/esm2022/libs/feature/map/src/lib/constant/projections.mjs +2 -0
  10. package/esm2022/libs/feature/map/src/lib/feature-map.module.mjs +17 -3
  11. package/esm2022/libs/feature/map/src/lib/geocoding/geocoding.component.mjs +93 -0
  12. package/esm2022/libs/feature/map/src/lib/geocoding.service.mjs +40 -0
  13. package/esm2022/libs/feature/map/src/lib/utils/index.mjs +1 -3
  14. package/esm2022/libs/feature/map/src/lib/utils/map-utils.service.mjs +60 -29
  15. package/esm2022/libs/feature/record/src/lib/map-view/map-view.component.mjs +29 -20
  16. package/esm2022/libs/ui/elements/src/index.mjs +2 -1
  17. package/esm2022/libs/ui/elements/src/lib/downloads-list/downloads-list.component.mjs +3 -3
  18. package/esm2022/libs/ui/elements/src/lib/markdown-parser/markdown-parser.component.mjs +2 -2
  19. package/esm2022/libs/ui/elements/src/lib/ui-elements.module.mjs +3 -1
  20. package/esm2022/libs/ui/inputs/src/lib/button/button.component.mjs +2 -2
  21. package/esm2022/libs/ui/inputs/src/lib/editable-label/editable-label.directive.mjs +45 -0
  22. package/esm2022/libs/ui/inputs/src/lib/ui-inputs.module.mjs +8 -3
  23. package/esm2022/libs/ui/layout/src/lib/carousel/carousel.component.mjs +2 -2
  24. package/esm2022/libs/ui/search/src/lib/record-table/record-table.component.mjs +3 -3
  25. package/esm2022/libs/util/shared/src/lib/links/link-utils.mjs +29 -13
  26. package/esm2022/translations/de.json +99 -98
  27. package/esm2022/translations/en.json +17 -16
  28. package/esm2022/translations/es.json +1 -0
  29. package/esm2022/translations/fr.json +1 -0
  30. package/esm2022/translations/it.json +1 -0
  31. package/esm2022/translations/nl.json +1 -0
  32. package/esm2022/translations/pt.json +1 -0
  33. package/fesm2022/geonetwork-ui.mjs +452 -222
  34. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  35. package/libs/api/metadata-converter/src/lib/gn4/atomic-operations.d.ts +1 -0
  36. package/libs/api/metadata-converter/src/lib/gn4/atomic-operations.d.ts.map +1 -1
  37. package/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.d.ts.map +1 -1
  38. package/libs/api/repository/src/lib/gn4/index.d.ts +2 -0
  39. package/libs/api/repository/src/lib/gn4/index.d.ts.map +1 -1
  40. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts +10 -5
  41. package/libs/common/domain/src/lib/model/record/metadata.model.d.ts.map +1 -1
  42. package/libs/feature/dataviz/src/lib/service/data.service.d.ts +15 -2
  43. package/libs/feature/dataviz/src/lib/service/data.service.d.ts.map +1 -1
  44. package/libs/feature/editor/src/lib/record-form/record-form.component.d.ts.map +1 -1
  45. package/libs/feature/map/src/index.d.ts +1 -0
  46. package/libs/feature/map/src/index.d.ts.map +1 -1
  47. package/libs/feature/map/src/lib/constant/index.d.ts +1 -0
  48. package/libs/feature/map/src/lib/constant/index.d.ts.map +1 -1
  49. package/libs/feature/map/src/lib/constant/projections.d.ts.map +1 -0
  50. package/libs/feature/map/src/lib/feature-map.module.d.ts +13 -12
  51. package/libs/feature/map/src/lib/feature-map.module.d.ts.map +1 -1
  52. package/libs/feature/map/src/lib/geocoding/geocoding.component.d.ts +25 -0
  53. package/libs/feature/map/src/lib/geocoding/geocoding.component.d.ts.map +1 -0
  54. package/libs/feature/map/src/lib/geocoding.service.d.ts +18 -0
  55. package/libs/feature/map/src/lib/geocoding.service.d.ts.map +1 -0
  56. package/libs/feature/map/src/lib/utils/index.d.ts +0 -2
  57. package/libs/feature/map/src/lib/utils/index.d.ts.map +1 -1
  58. package/libs/feature/map/src/lib/utils/map-utils.service.d.ts +13 -11
  59. package/libs/feature/map/src/lib/utils/map-utils.service.d.ts.map +1 -1
  60. package/libs/feature/record/src/lib/map-view/map-view.component.d.ts +1 -3
  61. package/libs/feature/record/src/lib/map-view/map-view.component.d.ts.map +1 -1
  62. package/libs/ui/dataviz/src/lib/chart/chart.component.d.ts +1 -1
  63. package/libs/ui/elements/src/index.d.ts +1 -0
  64. package/libs/ui/elements/src/index.d.ts.map +1 -1
  65. package/libs/ui/elements/src/lib/downloads-list/downloads-list.component.d.ts +1 -1
  66. package/libs/ui/elements/src/lib/ui-elements.module.d.ts +1 -1
  67. package/libs/ui/elements/src/lib/ui-elements.module.d.ts.map +1 -1
  68. package/libs/ui/inputs/src/lib/editable-label/editable-label.directive.d.ts +13 -0
  69. package/libs/ui/inputs/src/lib/editable-label/editable-label.directive.d.ts.map +1 -0
  70. package/libs/ui/inputs/src/lib/ui-inputs.module.d.ts +18 -17
  71. package/libs/ui/inputs/src/lib/ui-inputs.module.d.ts.map +1 -1
  72. package/libs/util/shared/src/lib/links/link-utils.d.ts +19 -7
  73. package/libs/util/shared/src/lib/links/link-utils.d.ts.map +1 -1
  74. package/package.json +4 -1
  75. package/src/libs/api/metadata-converter/src/lib/gn4/atomic-operations.ts +3 -0
  76. package/src/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts +43 -0
  77. package/src/libs/api/repository/src/lib/gn4/index.ts +2 -0
  78. package/src/libs/common/domain/src/lib/index.ts +2 -0
  79. package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +12 -7
  80. package/src/libs/feature/dataviz/src/lib/service/data.service.ts +8 -5
  81. package/src/libs/feature/editor/src/lib/record-form/record-form.component.ts +2 -1
  82. package/src/libs/feature/map/src/index.ts +1 -0
  83. package/src/libs/feature/map/src/lib/constant/index.ts +1 -0
  84. package/src/libs/feature/map/src/lib/feature-map.module.ts +8 -0
  85. package/src/libs/feature/map/src/lib/geocoding/geocoding.component.css +0 -0
  86. package/src/libs/feature/map/src/lib/geocoding/geocoding.component.html +39 -0
  87. package/src/libs/feature/map/src/lib/geocoding/geocoding.component.ts +99 -0
  88. package/src/libs/feature/map/src/lib/geocoding.service.ts +59 -0
  89. package/src/libs/feature/map/src/lib/utils/index.ts +0 -2
  90. package/src/libs/feature/map/src/lib/utils/map-utils.service.ts +85 -50
  91. package/src/libs/feature/record/src/lib/map-view/map-view.component.ts +18 -3
  92. package/src/libs/ui/elements/src/index.ts +1 -0
  93. package/src/libs/ui/elements/src/lib/downloads-list/downloads-list.component.html +4 -1
  94. package/src/libs/ui/elements/src/lib/markdown-parser/markdown-parser.component.css +52 -52
  95. package/src/libs/ui/elements/src/lib/ui-elements.module.ts +1 -0
  96. package/src/libs/ui/inputs/src/lib/button/button.component.css +1 -1
  97. package/src/libs/ui/inputs/src/lib/editable-label/editable-label.directive.ts +47 -0
  98. package/src/libs/ui/inputs/src/lib/ui-inputs.module.ts +3 -0
  99. package/src/libs/ui/layout/src/lib/carousel/carousel.component.css +1 -1
  100. package/src/libs/ui/search/src/lib/record-table/record-table.component.html +2 -2
  101. package/src/libs/util/shared/src/lib/links/link-utils.ts +34 -11
  102. package/translations/de.json +99 -98
  103. package/translations/en.json +17 -16
  104. package/translations/es.json +1 -0
  105. package/translations/fr.json +1 -0
  106. package/translations/it.json +1 -0
  107. package/translations/nl.json +1 -0
  108. package/translations/pt.json +1 -0
  109. package/translations/sk.json +1 -0
  110. package/esm2022/libs/feature/map/src/lib/utils/map-utils-wms.service.mjs +0 -55
  111. package/esm2022/libs/feature/map/src/lib/utils/projections.mjs +0 -2
  112. package/libs/feature/map/src/lib/utils/map-utils-wms.service.d.ts +0 -17
  113. package/libs/feature/map/src/lib/utils/map-utils-wms.service.d.ts.map +0 -1
  114. package/libs/feature/map/src/lib/utils/projections.d.ts.map +0 -1
  115. package/src/libs/feature/map/src/lib/utils/map-utils-wms.service.ts +0 -58
  116. /package/libs/feature/map/src/lib/{utils → constant}/projections.d.ts +0 -0
  117. /package/src/libs/feature/map/src/lib/{utils → constant}/projections.ts +0 -0
@@ -2,18 +2,18 @@ import { HttpClient } from '@angular/common/http'
2
2
  import { Injectable } from '@angular/core'
3
3
  import type { FeatureCollection } from 'geojson'
4
4
  import { extend, Extent, isEmpty } from 'ol/extent'
5
- import OlFeature, { FeatureLike } from 'ol/Feature'
5
+ import Feature from 'ol/Feature'
6
6
  import GeoJSON from 'ol/format/GeoJSON'
7
7
  import { Geometry } from 'ol/geom'
8
8
  import Layer from 'ol/layer/Layer'
9
9
  import Map from 'ol/Map'
10
- import { fromLonLat } from 'ol/proj'
10
+ import { transformExtent } from 'ol/proj'
11
11
  import Source from 'ol/source/Source'
12
12
  import ImageWMS from 'ol/source/ImageWMS'
13
13
  import TileWMS from 'ol/source/TileWMS'
14
14
  import VectorSource from 'ol/source/Vector'
15
- import { Options, optionsFromCapabilities } from 'ol/source/WMTS'
16
- import { DragPan, MouseWheelZoom, defaults, Interaction } from 'ol/interaction'
15
+ import { optionsFromCapabilities } from 'ol/source/WMTS'
16
+ import { defaults, DragPan, Interaction, MouseWheelZoom } from 'ol/interaction'
17
17
  import {
18
18
  mouseOnly,
19
19
  noModifierKeys,
@@ -21,45 +21,53 @@ import {
21
21
  primaryAction,
22
22
  } from 'ol/events/condition'
23
23
  import WMTSCapabilities from 'ol/format/WMTSCapabilities'
24
- import { from, Observable, of } from 'rxjs'
24
+ import { from, Observable } from 'rxjs'
25
25
  import { map } from 'rxjs/operators'
26
26
  import {
27
27
  MapContextLayerModel,
28
28
  MapContextLayerTypeEnum,
29
+ MapContextLayerWmsModel,
29
30
  MapContextLayerWmtsModel,
30
31
  } from '../map-context/map-context.model'
31
- import { MapUtilsWMSService } from './map-utils-wms.service'
32
32
  import Collection from 'ol/Collection'
33
33
  import MapBrowserEvent from 'ol/MapBrowserEvent'
34
- import { DatasetDistribution } from '../../../../../../libs/common/domain/src/lib/model/record'
34
+ import {
35
+ CatalogRecord,
36
+ DatasetDistribution,
37
+ } from '../../../../../../libs/common/domain/src/lib/model/record'
38
+ import { ProxyService } from '../../../../../../libs/util/shared/src'
39
+ import { WmsEndpoint } from '@camptocamp/ogc-client'
40
+ import { LONLAT_CRS_CODES } from '../constant/projections'
41
+ import { fromEPSGCode, register } from 'ol/proj/proj4'
42
+ import proj4 from 'proj4/dist/proj4'
35
43
 
36
44
  const FEATURE_PROJECTION = 'EPSG:3857'
37
45
  const DATA_PROJECTION = 'EPSG:4326'
38
46
 
47
+ const GEOJSON = new GeoJSON()
48
+
39
49
  @Injectable({
40
50
  providedIn: 'root',
41
51
  })
42
52
  export class MapUtilsService {
43
- constructor(private http: HttpClient, private wmsUtils: MapUtilsWMSService) {}
53
+ constructor(private http: HttpClient, private proxy: ProxyService) {}
44
54
 
45
55
  createEmptyMap(): Map {
46
- const map = new Map({
56
+ return new Map({
47
57
  controls: [],
48
58
  pixelRatio: 1,
49
59
  })
50
- return map
51
60
  }
52
61
 
53
62
  readFeatureCollection = (
54
63
  featureCollection: FeatureCollection,
55
64
  featureProjection = FEATURE_PROJECTION,
56
65
  dataProjection = DATA_PROJECTION
57
- ): FeatureLike[] => {
58
- const olFeatures = new GeoJSON().readFeatures(featureCollection, {
66
+ ): Feature<Geometry>[] => {
67
+ return GEOJSON.readFeatures(featureCollection, {
59
68
  featureProjection,
60
69
  dataProjection,
61
- })
62
- return olFeatures
70
+ }) as Feature<Geometry>[]
63
71
  }
64
72
 
65
73
  isWMSLayer(layer: Layer<Source>): boolean {
@@ -78,20 +86,14 @@ export class MapUtilsService {
78
86
  ...source.getParams(),
79
87
  INFO_FORMAT: 'application/json',
80
88
  }
81
- const url = source.getFeatureInfoUrl(
82
- coordinate,
83
- resolution,
84
- projection,
85
- params
86
- )
87
- return url
89
+ return source.getFeatureInfoUrl(coordinate, resolution, projection, params)
88
90
  }
89
91
 
90
- getVectorFeaturesFromClick(olMap, event): OlFeature<Geometry>[] {
92
+ getVectorFeaturesFromClick(olMap, event): Feature<Geometry>[] {
91
93
  const features = []
92
94
  const hit = olMap.forEachFeatureAtPixel(
93
95
  event.pixel,
94
- (feature: OlFeature<Geometry>) => {
96
+ (feature: Feature<Geometry>) => {
95
97
  return feature
96
98
  },
97
99
  { layerFilter: (layer) => layer.getSource() instanceof VectorSource }
@@ -103,9 +105,9 @@ export class MapUtilsService {
103
105
  }
104
106
 
105
107
  getGFIFeaturesObservablesFromClick(
106
- olMap,
107
- event
108
- ): Observable<OlFeature<Geometry>[]>[] {
108
+ olMap: Map,
109
+ event: MapBrowserEvent<PointerEvent>
110
+ ): Observable<Feature<Geometry>[]>[] {
109
111
  const wmsLayers = olMap.getLayers().getArray().filter(this.isWMSLayer)
110
112
 
111
113
  if (wmsLayers.length > 0) {
@@ -128,8 +130,8 @@ export class MapUtilsService {
128
130
  /**
129
131
  * Will emit `null` if no extent could be computed
130
132
  */
131
- getLayerExtent(layer: MapContextLayerModel): Observable<Extent | null> {
132
- let geographicExtent: Observable<Extent>
133
+ async getLayerExtent(layer: MapContextLayerModel): Promise<Extent | null> {
134
+ let latLonExtent: Extent
133
135
  if (
134
136
  layer &&
135
137
  layer.type === 'geojson' &&
@@ -138,37 +140,55 @@ export class MapUtilsService {
138
140
  layer.data.features[0] &&
139
141
  layer.data.features[0].geometry
140
142
  ) {
141
- geographicExtent = of(layer.data).pipe(
142
- map((layerData) =>
143
- new GeoJSON()
144
- .readFeatures(layerData)
145
- .map((feature) => feature.getGeometry())
146
- .filter((geom) => !!geom)
147
- .reduce(
148
- (prev, curr) =>
149
- prev ? extend(prev, curr.getExtent()) : curr.getExtent(),
150
- null as Extent
151
- )
143
+ latLonExtent = new GeoJSON()
144
+ .readFeatures(layer.data)
145
+ .map((feature) => feature.getGeometry())
146
+ .filter((geom) => !!geom)
147
+ .reduce(
148
+ (prev, curr) =>
149
+ prev ? extend(prev, curr.getExtent()) : curr.getExtent(),
150
+ null as Extent
152
151
  )
153
- )
154
152
  } else if (layer && layer.type === 'wms') {
155
- geographicExtent = this.wmsUtils.getLayerLonLatBBox(layer)
153
+ latLonExtent = await this.getWmsLayerExtent(layer)
156
154
  } else if (layer && layer.type === 'wmts') {
157
155
  if (layer.extent) {
158
- geographicExtent = of(layer.extent)
156
+ latLonExtent = layer.extent
159
157
  } else {
160
- return of(layer.options.tileGrid.getExtent())
158
+ return layer.options.tileGrid.getExtent()
161
159
  }
162
160
  } else {
163
- return of(null)
161
+ return null
162
+ }
163
+ if (!latLonExtent || isEmpty(latLonExtent)) {
164
+ return null
164
165
  }
165
- return geographicExtent.pipe(
166
- map((extent) => [
167
- ...fromLonLat([extent[0], extent[1]], 'EPSG:3857'),
168
- ...fromLonLat([extent[2], extent[3]], 'EPSG:3857'),
169
- ]),
170
- map((extent) => (isEmpty(extent) ? null : extent))
166
+ return transformExtent(latLonExtent, 'EPSG:4326', 'EPSG:3857')
167
+ }
168
+
169
+ async getWmsLayerExtent(
170
+ layer: MapContextLayerWmsModel
171
+ ): Promise<Extent | null> {
172
+ const endpoint = await new WmsEndpoint(
173
+ this.proxy.getProxiedUrl(layer.url)
174
+ ).isReady()
175
+ const { boundingBoxes } = endpoint.getLayerByName(layer.name)
176
+ if (!Object.keys(boundingBoxes).length) {
177
+ return null
178
+ }
179
+ const lonLatCRS = Object.keys(boundingBoxes)?.find((crs) =>
180
+ LONLAT_CRS_CODES.includes(crs)
171
181
  )
182
+ if (lonLatCRS) {
183
+ return boundingBoxes[lonLatCRS].map(parseFloat)
184
+ } else {
185
+ const availableEPSGCode = Object.keys(boundingBoxes)[0]
186
+ register(proj4)
187
+ const proj = await fromEPSGCode(availableEPSGCode)
188
+ const bboxWithFiniteNumbers =
189
+ boundingBoxes[availableEPSGCode].map(parseFloat)
190
+ return transformExtent(bboxWithFiniteNumbers, proj, 'EPSG:4326')
191
+ }
172
192
  }
173
193
 
174
194
  getWmtsLayerFromCapabilities(
@@ -235,6 +255,21 @@ ${e.stack || e.message || e}`)
235
255
  .getArray()
236
256
  )
237
257
  }
258
+
259
+ getRecordExtent(record: Partial<CatalogRecord>): Extent {
260
+ if (!('spatialExtents' in record)) {
261
+ return null
262
+ }
263
+ // transform an array of geojson geometries into a bbox
264
+ const totalExtent = record.spatialExtents.reduce(
265
+ (prev, curr) => {
266
+ const geom = GEOJSON.readGeometry(curr.geometry)
267
+ return extend(prev, geom.getExtent())
268
+ },
269
+ [Infinity, Infinity, -Infinity, -Infinity]
270
+ )
271
+ return transformExtent(totalExtent, 'EPSG:4326', 'EPSG:3857')
272
+ }
238
273
  }
239
274
 
240
275
  export function dragPanCondition(
@@ -22,10 +22,14 @@ import { StyleLike } from 'ol/style/Style'
22
22
  import {
23
23
  BehaviorSubject,
24
24
  combineLatest,
25
+ from,
26
+ lastValueFrom,
25
27
  Observable,
26
28
  of,
29
+ startWith,
27
30
  Subscription,
28
31
  throwError,
32
+ withLatestFrom,
29
33
  } from 'rxjs'
30
34
  import {
31
35
  catchError,
@@ -99,7 +103,7 @@ export class MapViewComponent implements OnInit, OnDestroy {
99
103
 
100
104
  mapContext$ = this.currentLayers$.pipe(
101
105
  switchMap((layers) =>
102
- this.mapUtils.getLayerExtent(layers[0]).pipe(
106
+ from(this.mapUtils.getLayerExtent(layers[0])).pipe(
103
107
  catchError((error) => {
104
108
  console.warn(error) // FIXME: report this to the user somehow
105
109
  return of(undefined)
@@ -115,7 +119,19 @@ export class MapViewComponent implements OnInit, OnDestroy {
115
119
  ),
116
120
  tap(() => this.resetSelection())
117
121
  )
118
- )
122
+ ),
123
+ withLatestFrom(this.mdViewFacade.metadata$),
124
+ map(([context, metadata]) => {
125
+ if (context.view.extent) return context
126
+ const extent = this.mapUtils.getRecordExtent(metadata)
127
+ return {
128
+ ...context,
129
+ view: {
130
+ ...context.view,
131
+ extent,
132
+ },
133
+ }
134
+ })
119
135
  )
120
136
 
121
137
  constructor(
@@ -123,7 +139,6 @@ export class MapViewComponent implements OnInit, OnDestroy {
123
139
  private mapManager: MapManagerService,
124
140
  private mapUtils: MapUtilsService,
125
141
  private dataService: DataService,
126
- private proxy: ProxyService,
127
142
  private featureInfo: FeatureInfoService,
128
143
  private changeRef: ChangeDetectorRef,
129
144
  private styleService: MapStyleService
@@ -18,6 +18,7 @@ export * from './lib/pagination/pagination.component'
18
18
  export * from './lib/related-record-card/related-record-card.component'
19
19
  export * from './lib/search-results-error/search-results-error.component'
20
20
  export * from './lib/user-preview/user-preview.component'
21
+ export * from './lib/max-lines/max-lines.component'
21
22
  export * from './lib/record-api-form/record-api-form.component'
22
23
  export * from './lib/markdown-parser/markdown-parser.component'
23
24
  export * from './lib/image-overlay-preview/image-overlay-preview.component'
@@ -8,7 +8,10 @@
8
8
  >
9
9
  record.metadata.download
10
10
  </p>
11
- <div class="flex flex-wrap justify-start sm:justify-end sm:pb-4">
11
+ <div
12
+ class="flex flex-wrap justify-start sm:justify-end sm:pb-4"
13
+ data-cy="download-format-filters"
14
+ >
12
15
  <gn-ui-button
13
16
  class="m-1 format-filter"
14
17
  [extraClass]="
@@ -1,5 +1,5 @@
1
1
  /** Body **/
2
- :host /deep/ .markdown-body {
2
+ :host ::ng-deep .markdown-body {
3
3
  -ms-text-size-adjust: 100%;
4
4
  -webkit-text-size-adjust: 100%;
5
5
  margin: 0px 0px 1.5rem 0px;
@@ -9,68 +9,68 @@
9
9
 
10
10
  /** Emphasis **/
11
11
 
12
- :host /deep/ .markdown-body strong {
12
+ :host ::ng-deep .markdown-body strong {
13
13
  @apply font-bold;
14
14
  color: var(--color-secondary-darker);
15
15
  }
16
16
 
17
17
  /** Headings **/
18
18
 
19
- :host /deep/ .markdown-body h1,
20
- :host /deep/ .markdown-body h2,
21
- :host /deep/ .markdown-body h3,
22
- :host /deep/ .markdown-body h4,
23
- :host /deep/ .markdown-body h5,
24
- :host /deep/ .markdown-body h6 {
19
+ :host ::ng-deep .markdown-body h1,
20
+ :host ::ng-deep .markdown-body h2,
21
+ :host ::ng-deep .markdown-body h3,
22
+ :host ::ng-deep .markdown-body h4,
23
+ :host ::ng-deep .markdown-body h5,
24
+ :host ::ng-deep .markdown-body h6 {
25
25
  margin-top: 24px;
26
26
  margin-bottom: 16px;
27
27
  line-height: 1.25;
28
28
  @apply text-title font-title font-bold;
29
29
  }
30
30
 
31
- :host /deep/ .markdown-body h1 {
31
+ :host ::ng-deep .markdown-body h1 {
32
32
  margin: 0.67em 0;
33
33
  padding-bottom: 0.3em;
34
34
  font-size: 2em;
35
35
  color: var(--color-primary);
36
36
  }
37
37
 
38
- :host /deep/ .markdown-body h2 {
38
+ :host ::ng-deep .markdown-body h2 {
39
39
  padding-bottom: 0.3em;
40
40
  font-size: 1.5em;
41
41
  color: var(--color-secondary);
42
42
  }
43
43
 
44
- :host /deep/ .markdown-body h3 {
44
+ :host ::ng-deep .markdown-body h3 {
45
45
  font-size: 1.25em;
46
46
  color: var(--color-secondary);
47
47
  }
48
48
 
49
- :host /deep/ .markdown-body h4 {
49
+ :host ::ng-deep .markdown-body h4 {
50
50
  font-size: 1em;
51
51
  color: var(--color-secondary);
52
52
  }
53
53
 
54
- :host /deep/ .markdown-body h5 {
54
+ :host ::ng-deep .markdown-body h5 {
55
55
  font-size: 0.875em;
56
56
  color: var(--color-secondary);
57
57
  }
58
58
 
59
- :host /deep/ .markdown-body h6 {
59
+ :host ::ng-deep .markdown-body h6 {
60
60
  font-size: 0.85em;
61
61
  color: var(--color-secondary-lighter);
62
62
  }
63
63
 
64
64
  /** Paragraphs **/
65
65
 
66
- :host /deep/ .markdown-body p {
66
+ :host ::ng-deep .markdown-body p {
67
67
  margin-top: 0;
68
68
  margin-bottom: 10px;
69
69
  }
70
70
 
71
71
  /** Links **/
72
72
 
73
- :host /deep/ .markdown-body p > a {
73
+ :host ::ng-deep .markdown-body p > a {
74
74
  margin-top: 0;
75
75
  margin-bottom: 10px;
76
76
  color: var(--color-primary) !important;
@@ -78,13 +78,13 @@
78
78
  @apply font-bold;
79
79
  }
80
80
 
81
- :host /deep/ .markdown-body p > a:hover {
81
+ :host ::ng-deep .markdown-body p > a:hover {
82
82
  color: var(--color-primary-darker) !important;
83
83
  }
84
84
 
85
85
  /** Blockquotes **/
86
86
 
87
- :host /deep/ .markdown-body blockquote {
87
+ :host ::ng-deep .markdown-body blockquote {
88
88
  margin: 0;
89
89
  padding: 0 1em;
90
90
  color: var(--color-secondary-lighter);
@@ -93,7 +93,7 @@
93
93
 
94
94
  /** Code **/
95
95
 
96
- :host /deep/ .markdown-body pre {
96
+ :host ::ng-deep .markdown-body pre {
97
97
  margin-top: 0;
98
98
  margin-bottom: 0;
99
99
  font-size: 12px;
@@ -101,7 +101,7 @@
101
101
  word-wrap: normal;
102
102
  }
103
103
 
104
- :host /deep/ .markdown-body pre {
104
+ :host ::ng-deep .markdown-body pre {
105
105
  padding: 16px;
106
106
  overflow: auto;
107
107
  font-size: 85%;
@@ -110,7 +110,7 @@
110
110
  border-radius: 6px;
111
111
  }
112
112
 
113
- :host /deep/ .markdown-body code {
113
+ :host ::ng-deep .markdown-body code {
114
114
  padding: 0.2em 0.4em;
115
115
  margin: 0;
116
116
  font-size: 85%;
@@ -118,7 +118,7 @@
118
118
  border-radius: 6px;
119
119
  }
120
120
 
121
- :host /deep/ .markdown-body pre code {
121
+ :host ::ng-deep .markdown-body pre code {
122
122
  display: inline;
123
123
  max-width: auto;
124
124
  padding: 0;
@@ -131,7 +131,7 @@
131
131
 
132
132
  /** Horizontal rules **/
133
133
 
134
- :host /deep/ .markdown-body hr {
134
+ :host ::ng-deep .markdown-body hr {
135
135
  box-sizing: content-box;
136
136
  overflow: hidden;
137
137
  background: transparent;
@@ -143,12 +143,12 @@
143
143
  border: 0;
144
144
  }
145
145
 
146
- :host /deep/ .markdown-body hr::before {
146
+ :host ::ng-deep .markdown-body hr::before {
147
147
  display: table;
148
148
  content: '';
149
149
  }
150
150
 
151
- :host /deep/ .markdown-body hr::after {
151
+ :host ::ng-deep .markdown-body hr::after {
152
152
  display: table;
153
153
  clear: both;
154
154
  content: '';
@@ -156,55 +156,55 @@
156
156
 
157
157
  /** Lists **/
158
158
 
159
- :host /deep/ .markdown-body ul,
160
- :host /deep/ .markdown-body ol {
159
+ :host ::ng-deep .markdown-body ul,
160
+ :host ::ng-deep .markdown-body ol {
161
161
  margin-top: 0;
162
162
  margin-bottom: 0;
163
163
  padding-left: 2em;
164
164
  list-style: revert;
165
165
  }
166
166
 
167
- :host /deep/ .markdown-body ol ol,
168
- :host /deep/ .markdown-body ul ol {
167
+ :host ::ng-deep .markdown-body ol ol,
168
+ :host ::ng-deep .markdown-body ul ol {
169
169
  list-style-type: lower-roman;
170
170
  }
171
171
 
172
- :host /deep/ .markdown-body ul ul ol,
173
- :host /deep/ .markdown-body ul ol ol,
174
- :host /deep/ .markdown-body ol ul ol,
175
- :host /deep/ .markdown-body ol ol ol {
172
+ :host ::ng-deep .markdown-body ul ul ol,
173
+ :host ::ng-deep .markdown-body ul ol ol,
174
+ :host ::ng-deep .markdown-body ol ul ol,
175
+ :host ::ng-deep .markdown-body ol ol ol {
176
176
  list-style-type: lower-alpha;
177
177
  }
178
178
 
179
- :host /deep/ .markdown-body ol[type='a s'] {
179
+ :host ::ng-deep .markdown-body ol[type='a s'] {
180
180
  list-style-type: lower-alpha;
181
181
  }
182
182
 
183
- :host /deep/ .markdown-body ol[type='A s'] {
183
+ :host ::ng-deep .markdown-body ol[type='A s'] {
184
184
  list-style-type: upper-alpha;
185
185
  }
186
186
 
187
- :host /deep/ .markdown-body ol[type='i s'] {
187
+ :host ::ng-deep .markdown-body ol[type='i s'] {
188
188
  list-style-type: lower-roman;
189
189
  }
190
190
 
191
- :host /deep/ .markdown-body ol[type='I s'] {
191
+ :host ::ng-deep .markdown-body ol[type='I s'] {
192
192
  list-style-type: upper-roman;
193
193
  }
194
194
 
195
- :host /deep/ .markdown-body ol[type='1'] {
195
+ :host ::ng-deep .markdown-body ol[type='1'] {
196
196
  list-style: unset;
197
197
  list-style-type: decimal;
198
198
  }
199
199
 
200
- :host /deep/ .markdown-body div > ol:not([type]) {
200
+ :host ::ng-deep .markdown-body div > ol:not([type]) {
201
201
  list-style: unset;
202
202
  list-style-type: decimal;
203
203
  }
204
204
 
205
205
  /** Table **/
206
206
 
207
- :host /deep/ .markdown-body table {
207
+ :host ::ng-deep .markdown-body table {
208
208
  border-spacing: 0;
209
209
  border-collapse: collapse;
210
210
  display: block;
@@ -214,51 +214,51 @@
214
214
  padding-bottom: 15px;
215
215
  }
216
216
 
217
- :host /deep/ .markdown-body td,
218
- :host /deep/ .markdown-body th {
217
+ :host ::ng-deep .markdown-body td,
218
+ :host ::ng-deep .markdown-body th {
219
219
  padding: 0;
220
220
  }
221
221
 
222
- :host /deep/ .markdown-body th {
222
+ :host ::ng-deep .markdown-body th {
223
223
  color: var(--color-secondary);
224
224
  }
225
225
 
226
- :host /deep/ .markdown-body table th,
227
- :host /deep/ .markdown-body table td {
226
+ :host ::ng-deep .markdown-body table th,
227
+ :host ::ng-deep .markdown-body table td {
228
228
  padding: 6px 13px;
229
229
  border: 1px solid var(--color-gray-500);
230
230
  }
231
231
 
232
- :host /deep/ .markdown-body table td > :last-child {
232
+ :host ::ng-deep .markdown-body table td > :last-child {
233
233
  margin-bottom: 0;
234
234
  }
235
235
 
236
- :host /deep/ .markdown-body table tr {
236
+ :host ::ng-deep .markdown-body table tr {
237
237
  background-color: #ffffff;
238
238
  border-top: 1px solid var(--color-secondary-lighter);
239
239
  }
240
240
 
241
- :host /deep/ .markdown-body table tr:nth-child(2n) {
241
+ :host ::ng-deep .markdown-body table tr:nth-child(2n) {
242
242
  background-color: var(--color-gray-100);
243
243
  }
244
244
 
245
- :host /deep/ .markdown-body table img {
245
+ :host ::ng-deep .markdown-body table img {
246
246
  background-color: transparent;
247
247
  }
248
248
 
249
249
  /** Images **/
250
250
 
251
- :host /deep/ .markdown-body img {
251
+ :host ::ng-deep .markdown-body img {
252
252
  border-style: none;
253
253
  max-width: 100%;
254
254
  box-sizing: content-box;
255
255
  background-color: transparent;
256
256
  }
257
257
 
258
- :host /deep/ .markdown-body img[align='right'] {
258
+ :host ::ng-deep .markdown-body img[align='right'] {
259
259
  padding-left: 20px;
260
260
  }
261
261
 
262
- :host /deep/ .markdown-body img[align='left'] {
262
+ :host ::ng-deep .markdown-body img[align='left'] {
263
263
  padding-right: 20px;
264
264
  }
@@ -88,6 +88,7 @@ import { ImageOverlayPreviewComponent } from './image-overlay-preview/image-over
88
88
  AvatarComponent,
89
89
  UserPreviewComponent,
90
90
  PaginationButtonsComponent,
91
+ MaxLinesComponent,
91
92
  RecordApiFormComponent,
92
93
  MarkdownParserComponent,
93
94
  ImageOverlayPreviewComponent,
@@ -1,5 +1,5 @@
1
1
  /* makes sure icons will not make the buttons grow vertically */
2
- :host /deep/ mat-icon.mat-icon {
2
+ :host ::ng-deep mat-icon.mat-icon {
3
3
  margin-top: -0.325em;
4
4
  margin-bottom: -0.325em;
5
5
  }
@@ -0,0 +1,47 @@
1
+ import {
2
+ Directive,
3
+ ElementRef,
4
+ Renderer2,
5
+ AfterViewInit,
6
+ EventEmitter,
7
+ Output,
8
+ Input,
9
+ } from '@angular/core'
10
+
11
+ @Directive({
12
+ selector: '[gnUiEditableLabel]',
13
+ })
14
+ export class EditableLabelDirective implements AfterViewInit {
15
+ @Output() editableLabelChanged = new EventEmitter<string>()
16
+ @Input() gnUiEditableLabel?: boolean
17
+
18
+ constructor(private el: ElementRef, private renderer: Renderer2) {}
19
+
20
+ ngAfterViewInit() {
21
+ if (this.gnUiEditableLabel !== false) {
22
+ const appendedInput = this.renderer.createElement('input')
23
+
24
+ this.renderer.setStyle(appendedInput, 'background', 'inherit')
25
+ this.renderer.setStyle(appendedInput, 'color', 'inherit')
26
+ this.renderer.setStyle(appendedInput, 'font', 'inherit')
27
+ this.renderer.setStyle(appendedInput, 'border', 'inherit')
28
+ this.renderer.setStyle(appendedInput, 'width', '100%')
29
+ this.renderer.setStyle(appendedInput, 'padding', 'inherit')
30
+ this.renderer.setStyle(appendedInput, 'margin', '0')
31
+ this.renderer.setStyle(appendedInput, 'height', 'inherit')
32
+ this.renderer.setStyle(appendedInput, 'line-height', 'inherit')
33
+ this.renderer.setStyle(appendedInput, 'text-decoration', 'inherit')
34
+
35
+ const hostContent = this.el.nativeElement.textContent || ''
36
+ const formattedContent = hostContent.replace(/\s+/g, ' ').trim()
37
+ this.renderer.setProperty(appendedInput, 'value', formattedContent)
38
+ this.renderer.setProperty(this.el.nativeElement, 'innerHTML', '')
39
+
40
+ this.renderer.listen(appendedInput, 'input', (event) => {
41
+ this.editableLabelChanged.emit(event.target.value)
42
+ })
43
+
44
+ this.renderer.appendChild(this.el.nativeElement, appendedInput)
45
+ }
46
+ }
47
+ }