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

geonetwork / geonetwork-ui / 13176645502

06 Feb 2025 10:21AM UTC coverage: 84.055% (+0.005%) from 84.05%
13176645502

Pull #1107

github

web-flow
Merge d561f1700 into 73bac9979
Pull Request #1107: [wip] Create with attachments

3294 of 4400 branches covered (74.86%)

Branch coverage included in aggregate %.

49 of 54 new or added lines in 14 files covered. (90.74%)

1 existing line in 1 file now uncovered.

9432 of 10740 relevant lines covered (87.82%)

275.94 hits per line

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

76.34
/apps/metadata-editor/src/app/edit/edit-page.component.ts
1
import { CommonModule } from '@angular/common'
3✔
2
import {
3✔
3
  Component,
4
  ElementRef,
5
  OnDestroy,
6
  OnInit,
7
  ViewChild,
8
} from '@angular/core'
9
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'
3✔
10
import { ActivatedRoute, Router } from '@angular/router'
3✔
11
import { marker } from '@biesbjerg/ngx-translate-extract-marker'
3✔
12
import { PublicationVersionError } from '@geonetwork-ui/common/domain/model/error'
3✔
13
import {
3✔
14
  EditorFacade,
15
  RecordFormComponent,
16
} from '@geonetwork-ui/feature/editor'
17
import {
3✔
18
  NotificationsContainerComponent,
19
  NotificationsService,
20
} from '@geonetwork-ui/feature/notifications'
21
import { ButtonComponent } from '@geonetwork-ui/ui/inputs'
3✔
22
import { TranslateModule, TranslateService } from '@ngx-translate/core'
3✔
23
import { combineLatest, filter, firstValueFrom, Subscription, take } from 'rxjs'
3✔
24
import { map, skip } from 'rxjs/operators'
3✔
25
import { SidebarComponent } from '../dashboard/sidebar/sidebar.component'
3✔
26
import { PageSelectorComponent } from './components/page-selector/page-selector.component'
3✔
27
import { TopToolbarComponent } from './components/top-toolbar/top-toolbar.component'
3✔
28

29
marker('editor.record.form.bottomButtons.comeBackLater')
3✔
30
marker('editor.record.form.bottomButtons.previous')
3✔
31
marker('editor.record.form.bottomButtons.next')
3✔
32

33
@Component({
34
  selector: 'md-editor-edit',
35
  templateUrl: './edit-page.component.html',
36
  styleUrls: ['./edit-page.component.css'],
37
  standalone: true,
38
  imports: [
39
    RecordFormComponent,
40
    CommonModule,
41
    ButtonComponent,
42
    MatProgressSpinnerModule,
43
    TopToolbarComponent,
44
    NotificationsContainerComponent,
45
    PageSelectorComponent,
46
    TranslateModule,
47
    SidebarComponent,
48
  ],
49
})
50
export class EditPageComponent implements OnInit, OnDestroy {
3✔
51
  subscription = new Subscription()
12✔
52

53
  currentPage$ = this.facade.currentPage$
12✔
54
  pagesLength$ = this.facade.editorConfig$.pipe(
12✔
55
    map((config) => config.pages.length)
10✔
56
  )
57
  isLastPage$ = combineLatest([this.currentPage$, this.pagesLength$]).pipe(
12✔
58
    map(([currentPage, pagesCount]) => currentPage >= pagesCount - 1)
10✔
59
  )
60
  hasRecordChanged$ = this.facade.hasRecordChanged$.pipe(skip(1))
12✔
61

62
  newRecord = false
12✔
63

64
  @ViewChild('scrollContainer') scrollContainer: ElementRef<HTMLElement>
65

66
  constructor(
67
    private route: ActivatedRoute,
12!
68
    private facade: EditorFacade,
12!
69
    private notificationsService: NotificationsService,
12!
70
    private translateService: TranslateService,
12!
71
    private router: Router
12✔
72
  ) {}
73

74
  ngOnInit(): void {
75
    const [currentRecord, currentRecordSource] =
76
      this.route.snapshot.data['record']
10✔
77

78
    this.facade.openRecord(currentRecord, currentRecordSource)
10✔
79

80
    this.subscription.add(
10✔
81
      this.facade.record$.pipe(take(1)).subscribe((record) => {
82
        if (!record.uniqueIdentifier) {
10✔
83
          this.newRecord = true
1✔
84
          this.facade.saveRecord()
1✔
85
        }
86
      })
87
    )
88

89
    this.subscription.add(
10✔
90
      this.facade.saveError$.subscribe((error) => {
91
        if (error instanceof PublicationVersionError) {
2✔
92
          this.notificationsService.showNotification(
1✔
93
            {
94
              type: 'error',
95
              title: this.translateService.instant(
96
                'editor.record.publishVersionError.title'
97
              ),
98
              text: this.translateService.instant(
99
                'editor.record.publishVersionError.body',
100
                { currentVersion: error.detectedApiVersion }
101
              ),
102
              closeMessage: this.translateService.instant(
103
                'editor.record.publishVersionError.closeMessage'
104
              ),
105
            },
106
            undefined,
107
            error
108
          )
109
        } else {
110
          this.notificationsService.showNotification(
1✔
111
            {
112
              type: 'error',
113
              title: this.translateService.instant(
114
                'editor.record.publishError.title'
115
              ),
116
              text: `${this.translateService.instant(
117
                'editor.record.publishError.body'
118
              )} ${error.message}`,
119
              closeMessage: this.translateService.instant(
120
                'editor.record.publishError.closeMessage'
121
              ),
122
            },
123
            undefined,
124
            error
125
          )
126
        }
127
      })
128
    )
129

130
    this.subscription.add(
10✔
131
      this.facade.saveSuccess$.subscribe(() => {
132
        if (!this.newRecord) {
1✔
133
          this.notificationsService.showNotification(
1✔
134
            {
135
              type: 'success',
136
              title: this.translateService.instant(
137
                'editor.record.publishSuccess.title'
138
              ),
139
              text: `${this.translateService.instant(
140
                'editor.record.publishSuccess.body'
141
              )}`,
142
            },
143
            2500
144
          )
145
        }
146
      })
147
    )
148

149
    this.subscription.add(
10✔
150
      this.facade.record$.subscribe((record) => {
151
        this.facade.checkHasRecordChanged(record)
11✔
152
      })
153
    )
154

155
    // if we're on the /duplicate route, go to /edit/{uuid} to update the uuid
156
    if (this.route.snapshot.routeConfig?.path.includes('duplicate')) {
10!
NEW
157
      this.router.navigate(['edit', currentRecord.uniqueIdentifier], {
×
158
        replaceUrl: true,
159
      })
160
    }
161

162
    // if the record unique identifier changes, navigate to /edit/newUuid
163
    this.subscription.add(
10✔
164
      this.facade.record$
165
        .pipe(
166
          filter(
167
            (record) =>
168
              record?.uniqueIdentifier !== currentRecord.uniqueIdentifier
10✔
169
          ),
170
          take(1)
171
        )
172
        .subscribe((savedRecord) => {
173
          this.router.navigate(['edit', savedRecord.uniqueIdentifier], {
2✔
174
            replaceUrl: true,
175
          })
176
        })
177
    )
178
  }
179

180
  ngOnDestroy() {
181
    this.subscription.unsubscribe()
13✔
182
  }
183

184
  async previousPageButtonHandler() {
185
    const currentPage = await firstValueFrom(this.currentPage$)
×
186
    if (currentPage === 0) {
×
187
      this.router.navigate(['catalog', 'search'])
×
188
    } else {
189
      this.facade.setCurrentPage(currentPage - 1)
×
190
      this.scrollToTop()
×
191
    }
192
  }
193

194
  async nextPageButtonHandler() {
195
    const currentPage = await firstValueFrom(this.currentPage$)
×
196
    const pagesCount = await firstValueFrom(this.pagesLength$)
×
197
    if (currentPage < pagesCount - 1) {
×
198
      this.facade.setCurrentPage(currentPage + 1)
×
199
      this.scrollToTop()
×
200
    }
201
  }
202

203
  private scrollToTop() {
204
    this.scrollContainer.nativeElement.scroll({
×
205
      behavior: 'instant',
206
      top: 0,
207
    })
208
  }
209

210
  formatDate(date: Date): string {
211
    return date.toLocaleDateString(this.translateService.currentLang, {
×
212
      year: 'numeric',
213
      month: 'long',
214
      day: 'numeric',
215
      hour: 'numeric',
216
      minute: 'numeric',
217
    })
218
  }
219
}
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