• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

geonetwork / geonetwork-ui / 16500024661

24 Jul 2025 02:41PM UTC coverage: 83.914%. First build
16500024661

Pull #1292

github

web-flow
Merge 188cd3ece into faf845578
Pull Request #1292: Editor: Add metadata quality panel

3516 of 4713 branches covered (74.6%)

Branch coverage included in aggregate %.

41 of 43 new or added lines in 5 files covered. (95.35%)

10089 of 11500 relevant lines covered (87.73%)

272.03 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

78.18
/apps/metadata-editor/src/app/edit/components/top-toolbar/top-toolbar.component.ts
1
import { CommonModule } from '@angular/common'
4✔
2
import {
4✔
3
  ChangeDetectionStrategy,
4
  Component,
5
  EventEmitter,
6
  Output,
7
} from '@angular/core'
8
import { MatDialog, MatDialogModule } from '@angular/material/dialog'
4✔
9
import { MatTooltipModule } from '@angular/material/tooltip'
4✔
10
import { EditorFacade } from '@geonetwork-ui/feature/editor'
4✔
11
import { ConfirmationDialogComponent } from '@geonetwork-ui/ui/elements'
4✔
12
import { ButtonComponent } from '@geonetwork-ui/ui/inputs'
4✔
13
import { LetDirective } from '@ngrx/component'
4✔
14
import {
4✔
15
  TranslateDirective,
16
  TranslatePipe,
17
  TranslateService,
18
} from '@ngx-translate/core'
19
import { combineLatest, Observable } from 'rxjs'
4✔
20
import { map } from 'rxjs/operators'
4✔
21
import { PublishButtonComponent } from '../publish-button/publish-button.component'
4✔
22
import { MetadataQualityComponent } from '../metadata-quality/metadata-quality.component'
4✔
23
import {
4✔
24
  NgIconComponent,
25
  provideIcons,
26
  provideNgIconsConfig,
27
} from '@ng-icons/core'
28
import {
4✔
29
  iconoirBadgeCheck,
30
  iconoirCheckCircle,
31
  iconoirDownload,
32
  iconoirLightBulb,
33
  iconoirSidebarCollapse,
34
  iconoirTranslate,
35
  iconoirUndoAction,
36
} from '@ng-icons/iconoir'
37
import {
4✔
38
  matHelpOutlineOutline,
39
  matPendingOutline,
40
} from '@ng-icons/material-icons/outline'
41
import { matCircle } from '@ng-icons/material-icons/baseline'
4✔
42

43
@Component({
44
  selector: 'md-editor-top-toolbar',
45
  standalone: true,
46
  imports: [
47
    CommonModule,
48
    PublishButtonComponent,
49
    ButtonComponent,
50
    LetDirective,
51
    MatTooltipModule,
52
    MatDialogModule,
53
    MetadataQualityComponent,
54
    TranslateDirective,
55
    TranslatePipe,
56
    NgIconComponent,
57
  ],
58
  providers: [
59
    provideIcons({
60
      iconoirCheckCircle,
61
      matPendingOutline,
62
      iconoirSidebarCollapse,
63
      iconoirLightBulb,
64
      iconoirDownload,
65
      iconoirUndoAction,
66
      iconoirBadgeCheck,
67
      matHelpOutlineOutline,
68
      iconoirTranslate,
69
      matCircle,
70
    }),
71
    provideNgIconsConfig({
72
      size: '1.5rem',
73
    }),
74
  ],
75
  templateUrl: './top-toolbar.component.html',
76
  styleUrls: ['./top-toolbar.component.css'],
77
  changeDetection: ChangeDetectionStrategy.OnPush,
78
})
79
export class TopToolbarComponent {
4✔
80
  @Output() openSidePanel = new EventEmitter<
6✔
81
    null | 'multilingual' | 'metadataQuality'
82
  >()
83
  sidePanelOpen: 'multilingual' | 'metadataQuality' | null = null
6✔
84
  protected SaveStatus = [
6✔
85
    'record_not_published', // => when the record is not published yet but saved
86
    'record_up_to_date', // => when the record was just published (ie saved on the server)
87
    'draft_changes_pending', // => when the record was modified and not yet published
88
    // these are not used since the draft is saved locally in a synchronous way
89
    // TODO: use these states when the draft is saved on the server
90
    // 'draft_saving',
91
    // 'draft_saving_failed',
92
  ] as const
93

94
  protected saveStatus$: Observable<(typeof this.SaveStatus)[number]> =
6✔
95
    combineLatest([
96
      this.editorFacade.changedSinceSave$,
97
      this.editorFacade.isPublished$,
98
    ]).pipe(
99
      map(([changedSinceSave, isPublished]) => {
100
        if (changedSinceSave) {
45✔
101
          return 'draft_changes_pending'
8✔
102
        }
103
        return !isPublished ? 'record_not_published' : 'record_up_to_date'
37✔
104
      })
105
    )
106
  isRecordMultilingual$ = this.editorFacade.record$.pipe(
6✔
107
    map((record) => record.otherLanguages.length)
7✔
108
  )
109
  record$ = this.editorFacade.record$
6✔
110

111
  constructor(
112
    public dialog: MatDialog,
6!
113
    private translateService: TranslateService,
6!
114
    private editorFacade: EditorFacade
6✔
115
  ) {}
116

117
  confirmUndo() {
118
    const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
×
119
      data: {
120
        title: this.translateService.instant(
121
          'editor.record.undo.confirmation.title'
122
        ),
123
        message: this.translateService.instant(
124
          'editor.record.undo.confirmation.message'
125
        ),
126
        confirmText: this.translateService.instant(
127
          'editor.record.undo.confirmation.confirmText'
128
        ),
129
        cancelText: this.translateService.instant(
130
          'editor.record.undo.confirmation.cancelText'
131
        ),
132
      },
133
      restoreFocus: true,
134
    })
135

136
    dialogRef.afterClosed().subscribe((confirmed) => {
×
137
      if (confirmed) {
×
138
        this.editorFacade.undoRecordDraft()
×
139
      }
140
    })
141
  }
142

143
  toggleSidePanel(sidePanel: 'multilingual' | 'metadataQuality') {
NEW
144
    this.sidePanelOpen = this.sidePanelOpen === sidePanel ? null : sidePanel
×
NEW
145
    this.openSidePanel.emit(this.sidePanelOpen)
×
146
  }
147
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc