All files / app/features/history/pages/diff-page diff-page.component.ts

100% Statements 35/35
87.5% Branches 14/16
100% Functions 6/6
100% Lines 32/32

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 681x 1x 1x 1x 1x 1x 1x 1x 1x       1x 1x                             1x 19x   19x 19x   19x 8x 8x 7x     19x 7x 7x         19x 19x     1x 1x       5x 5x 5x 5x       19x 19x      
import { CmDiffViewComponent } from '../../../../shared/components/cm-diff-view/cm-diff-view.component';
import { DiffViewComponent } from '../../../../shared/components/diff-view/diff-view.component';
import { ModerationSidebarActionComponent } from '../../../../shared/components/moderation-sidebar-action/moderation-sidebar-action.component';
import { SidebarActionComponent } from '../../../../shared/components/sidebar-action/sidebar-action.component';
import { VersionLabelComponent } from '../../components/version-label/version-label.component';
import { DiffPageDataService } from '../../services/diff-page-data.service';
import { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';
import { LoggerService, StorageService } from '@drevo-web/core';
import { ApprovalStatus, ModerationResult, SidebarActionPriority } from '@drevo-web/shared';
 
type DiffViewType = 'cm' | 'jsdiff';
 
const STORAGE_KEY = 'diff-view-type';
const VALID_TYPES: readonly DiffViewType[] = ['cm', 'jsdiff'];
 
@Component({
    selector: 'app-diff-page',
    imports: [
        CmDiffViewComponent,
        DiffViewComponent,
        ModerationSidebarActionComponent,
        SidebarActionComponent,
        VersionLabelComponent,
    ],
    templateUrl: './diff-page.component.html',
    styleUrl: './diff-page.component.scss',
    changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DiffPageComponent {
    readonly data = inject(DiffPageDataService);
 
    private readonly logger = inject(LoggerService).withContext('DiffPageComponent');
    private readonly storage = inject(StorageService);
 
    readonly isModerationEnabled = computed(() => {
        const pairs = this.data.versionPairs();
        if (!pairs) return false;
        return pairs.previous.approved === ApprovalStatus.Approved;
    });
 
    readonly moderationPriority = computed<SidebarActionPriority>(() => {
        const pairs = this.data.versionPairs();
        return this.isModerationEnabled() && pairs?.current.approved === ApprovalStatus.Pending
            ? 'primary'
            : 'secondary';
    });
 
    private readonly _diffType = signal<DiffViewType>(this.loadDiffType());
    readonly diffType = this._diffType.asReadonly();
 
    onModerated(result: ModerationResult): void {
        this.data.updateCurrentApproval(result.approved, result.comment);
        this.logger.info('Version moderated', { versionId: result.versionId, approved: result.approved });
    }
 
    toggleDiffType(): void {
        const newType: DiffViewType = this._diffType() === 'cm' ? 'jsdiff' : 'cm';
        this._diffType.set(newType);
        this.storage.setString(STORAGE_KEY, newType);
        this.logger.info('Diff view type changed', { type: newType });
    }
 
    private loadDiffType(): DiffViewType {
        const stored = this.storage.getString(STORAGE_KEY);
        return stored && VALID_TYPES.includes(stored as DiffViewType) ? (stored as DiffViewType) : 'cm';
    }
}