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

geonetwork / geonetwork-ui / 13156188240

05 Feb 2025 11:17AM UTC coverage: 83.997% (-0.5%) from 84.514%
13156188240

Pull #1107

github

web-flow
Merge 37391736c into c1a684900
Pull Request #1107: [wip] Create with attachments

3306 of 4416 branches covered (74.86%)

Branch coverage included in aggregate %.

43 of 58 new or added lines in 13 files covered. (74.14%)

1 existing line in 1 file now uncovered.

9443 of 10762 relevant lines covered (87.74%)

275.37 hits per line

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

73.12
/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()
11✔
52

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

62
  newRecord = false
11✔
63

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

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

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

78
    this.facade.openRecord(
9✔
79
      currentRecord,
80
      currentRecordSource,
81
      currentRecordAlreadySaved
82
    )
83

84
    this.subscription.add(
9✔
85
      this.facade.record$.pipe(take(1)).subscribe((record) => {
86
        if (!record.uniqueIdentifier) {
9!
NEW
87
          this.newRecord = true
×
NEW
88
          this.facade.saveRecord()
×
89
        }
90
      })
91
    )
92

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

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

153
    this.subscription.add(
9✔
154
      this.facade.record$.subscribe((record) => {
155
        this.facade.checkHasRecordChanged(record)
10✔
156
      })
157
    )
158

159
    // if we're on the /duplicate route, go to /edit/{uuid} to update the uuid
160
    if (this.route.snapshot.routeConfig?.path.includes('duplicate')) {
9!
NEW
161
      this.router.navigate(['edit', currentRecord.uniqueIdentifier], {
×
162
        replaceUrl: true,
163
        state: { published: false },
164
      })
165
    }
166

167
    // if the record unique identifier changes, navigate to /edit/newUuid
168
    this.subscription.add(
9✔
169
      this.facade.record$
170
        .pipe(
171
          filter(
172
            (record) =>
173
              record?.uniqueIdentifier !== currentRecord.uniqueIdentifier
10✔
174
          ),
175
          take(1)
176
        )
177
        .subscribe((savedRecord) => {
178
          this.router.navigate(['edit', savedRecord.uniqueIdentifier], {
1✔
179
            state: { published: false },
180
          })
181
        })
182
    )
183
  }
184

185
  ngOnDestroy() {
186
    this.subscription.unsubscribe()
12✔
187
  }
188

189
  async previousPageButtonHandler() {
190
    const currentPage = await firstValueFrom(this.currentPage$)
×
191
    if (currentPage === 0) {
×
192
      this.router.navigate(['catalog', 'search'])
×
193
    } else {
194
      this.facade.setCurrentPage(currentPage - 1)
×
195
      this.scrollToTop()
×
196
    }
197
  }
198

199
  async nextPageButtonHandler() {
200
    const currentPage = await firstValueFrom(this.currentPage$)
×
201
    const pagesCount = await firstValueFrom(this.pagesLength$)
×
202
    if (currentPage < pagesCount - 1) {
×
203
      this.facade.setCurrentPage(currentPage + 1)
×
204
      this.scrollToTop()
×
205
    }
206
  }
207

208
  private scrollToTop() {
209
    this.scrollContainer.nativeElement.scroll({
×
210
      behavior: 'instant',
211
      top: 0,
212
    })
213
  }
214

215
  formatDate(date: Date): string {
216
    return date.toLocaleDateString(this.translateService.currentLang, {
×
217
      year: 'numeric',
218
      month: 'long',
219
      day: 'numeric',
220
      hour: 'numeric',
221
      minute: 'numeric',
222
    })
223
  }
224
}
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