diff --git a/apps/metadata-editor/src/app/edit/components/top-toolbar/top-toolbar.component.html b/apps/metadata-editor/src/app/edit/components/top-toolbar/top-toolbar.component.html
index 365dcea5af..177c9d3bf1 100644
--- a/apps/metadata-editor/src/app/edit/components/top-toolbar/top-toolbar.component.html
+++ b/apps/metadata-editor/src/app/edit/components/top-toolbar/top-toolbar.component.html
@@ -11,7 +11,33 @@
undo
-
Save status
+
+
+ check_circle
+ editor.record.saveStatus.notPublishedYet
+
+
+ check_circle
+ editor.record.saveStatus.publishedUpToDate
+
+
+ pending
+ editor.record.saveStatus.publishedChangesPending
+
+
help
diff --git a/apps/metadata-editor/src/app/edit/components/top-toolbar/top-toolbar.component.spec.ts b/apps/metadata-editor/src/app/edit/components/top-toolbar/top-toolbar.component.spec.ts
index 77c3cb5b09..6f7ad48d9f 100644
--- a/apps/metadata-editor/src/app/edit/components/top-toolbar/top-toolbar.component.spec.ts
+++ b/apps/metadata-editor/src/app/edit/components/top-toolbar/top-toolbar.component.spec.ts
@@ -2,6 +2,14 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'
import { TopToolbarComponent } from './top-toolbar.component'
import { Component } from '@angular/core'
import { PublishButtonComponent } from '../publish-button/publish-button.component'
+import { BehaviorSubject } from 'rxjs'
+import { EditorFacade } from '@geonetwork-ui/feature/editor'
+import { TranslateModule } from '@ngx-translate/core'
+
+class EditorFacadeMock {
+ changedSinceSave$ = new BehaviorSubject(false)
+ alreadySavedOnce$ = new BehaviorSubject(false)
+}
@Component({
selector: 'md-editor-publish-button',
@@ -13,10 +21,17 @@ class MockPublishButtonComponent {}
describe('TopToolbarComponent', () => {
let component: TopToolbarComponent
let fixture: ComponentFixture
+ let editorFacade: EditorFacadeMock
beforeEach(async () => {
await TestBed.configureTestingModule({
- imports: [TopToolbarComponent],
+ imports: [TopToolbarComponent, TranslateModule.forRoot()],
+ providers: [
+ {
+ provide: EditorFacade,
+ useClass: EditorFacadeMock,
+ },
+ ],
})
.overrideComponent(TopToolbarComponent, {
add: {
@@ -30,10 +45,47 @@ describe('TopToolbarComponent', () => {
fixture = TestBed.createComponent(TopToolbarComponent)
component = fixture.componentInstance
+ editorFacade = TestBed.inject(EditorFacade) as any
fixture.detectChanges()
})
it('should create', () => {
expect(component).toBeTruthy()
})
+
+ describe('save status', () => {
+ let saveStatus: string
+ beforeEach(() => {
+ component['saveStatus$'].subscribe((status) => {
+ saveStatus = status
+ })
+ })
+ describe('saved and not published', () => {
+ beforeEach(() => {
+ editorFacade.alreadySavedOnce$.next(false)
+ editorFacade.changedSinceSave$.next(true)
+ })
+ it('sets the correct status', () => {
+ expect(saveStatus).toBe('saved_not_published')
+ })
+ })
+ describe('saved, published and up to date', () => {
+ beforeEach(() => {
+ editorFacade.alreadySavedOnce$.next(true)
+ editorFacade.changedSinceSave$.next(false)
+ })
+ it('sets the correct status', () => {
+ expect(saveStatus).toBe('saved_published_up_to_date')
+ })
+ })
+ describe('saved, published, pending changes', () => {
+ beforeEach(() => {
+ editorFacade.alreadySavedOnce$.next(true)
+ editorFacade.changedSinceSave$.next(true)
+ })
+ it('sets the correct status', () => {
+ expect(saveStatus).toBe('saved_published_changes_pending')
+ })
+ })
+ })
})
diff --git a/apps/metadata-editor/src/app/edit/components/top-toolbar/top-toolbar.component.ts b/apps/metadata-editor/src/app/edit/components/top-toolbar/top-toolbar.component.ts
index c7717d8342..685820ca1c 100644
--- a/apps/metadata-editor/src/app/edit/components/top-toolbar/top-toolbar.component.ts
+++ b/apps/metadata-editor/src/app/edit/components/top-toolbar/top-toolbar.component.ts
@@ -3,6 +3,10 @@ import { CommonModule } from '@angular/common'
import { PublishButtonComponent } from '../publish-button/publish-button.component'
import { ButtonComponent } from '@geonetwork-ui/ui/inputs'
import { MatIconModule } from '@angular/material/icon'
+import { EditorFacade } from '@geonetwork-ui/feature/editor'
+import { combineLatest, Observable } from 'rxjs'
+import { map } from 'rxjs/operators'
+import { TranslateModule } from '@ngx-translate/core'
@Component({
selector: 'md-editor-top-toolbar',
@@ -12,9 +16,37 @@ import { MatIconModule } from '@angular/material/icon'
PublishButtonComponent,
ButtonComponent,
MatIconModule,
+ TranslateModule,
],
templateUrl: './top-toolbar.component.html',
styleUrls: ['./top-toolbar.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
-export class TopToolbarComponent {}
+export class TopToolbarComponent {
+ protected SaveStatus = [
+ 'saved_not_published',
+ 'saved_published_up_to_date',
+ 'saved_published_changes_pending',
+ // these are not used since the draft is saved locally
+ // TODO: use these states when the draft is saved on the server
+ // 'saving',
+ // 'saving_failed',
+ ] as const
+
+ protected saveStatus$: Observable =
+ combineLatest([
+ this.editorFacade.alreadySavedOnce$,
+ this.editorFacade.changedSinceSave$,
+ ]).pipe(
+ map(([alreadySavedOnce, changedSinceSave]) => {
+ if (!alreadySavedOnce) {
+ return 'saved_not_published'
+ }
+ return changedSinceSave
+ ? 'saved_published_changes_pending'
+ : 'saved_published_up_to_date'
+ })
+ )
+
+ constructor(private editorFacade: EditorFacade) {}
+}