Merge branch 'dev' into feature-6978-sharelink-bundle

This commit is contained in:
shamoon
2026-01-26 10:59:37 -08:00
37 changed files with 1318 additions and 614 deletions

View File

@@ -1,9 +1,18 @@
<div class="row pt-3 pb-3 pb-md-2 align-items-center">
<div class="col-md text-truncate">
<h3 class="text-truncate" style="line-height: 1.4">
{{title}}
<h3 class="d-flex align-items-center mb-1" style="line-height: 1.4">
<span class="text-truncate">{{title}}</span>
@if (id) {
<span class="badge bg-primary text-primary-text-contrast ms-3 small fs-normal cursor-pointer" (click)="copyID()">
@if (copied) {
<i-bs width="1em" height="1em" name="clipboard-check"></i-bs>&nbsp;<ng-container i18n>Copied!</ng-container>
} @else {
ID: {{id}}
}
</span>
}
@if (subTitle) {
<span class="h6 mb-0 d-block d-md-inline fw-normal ms-md-3 text-truncate" style="line-height: 1.4">{{subTitle}}</span>
<span class="h6 mb-0 mt-1 d-block d-md-inline fw-normal ms-md-3 text-truncate" style="line-height: 1.4">{{subTitle}}</span>
}
@if (info) {
<button class="btn btn-sm btn-link text-muted me-auto p-0 p-md-2" title="What's this?" i18n-title type="button" [ngbPopover]="infoPopover" [autoClose]="true">

View File

@@ -1,5 +1,10 @@
h3 {
min-height: calc(1.325rem + 0.9vw);
.badge {
font-size: 0.65rem;
line-height: 1;
}
}
@media (min-width: 1200px) {

View File

@@ -1,3 +1,4 @@
import { Clipboard } from '@angular/cdk/clipboard'
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { Title } from '@angular/platform-browser'
import { environment } from 'src/environments/environment'
@@ -7,6 +8,7 @@ describe('PageHeaderComponent', () => {
let component: PageHeaderComponent
let fixture: ComponentFixture<PageHeaderComponent>
let titleService: Title
let clipboard: Clipboard
beforeEach(async () => {
TestBed.configureTestingModule({
@@ -15,6 +17,7 @@ describe('PageHeaderComponent', () => {
}).compileComponents()
titleService = TestBed.inject(Title)
clipboard = TestBed.inject(Clipboard)
fixture = TestBed.createComponent(PageHeaderComponent)
component = fixture.componentInstance
fixture.detectChanges()
@@ -24,7 +27,8 @@ describe('PageHeaderComponent', () => {
component.title = 'Foo'
component.subTitle = 'Bar'
fixture.detectChanges()
expect(fixture.nativeElement.textContent).toContain('Foo Bar')
expect(fixture.nativeElement.textContent).toContain('Foo')
expect(fixture.nativeElement.textContent).toContain('Bar')
})
it('should set html title', () => {
@@ -32,4 +36,16 @@ describe('PageHeaderComponent', () => {
component.title = 'Foo Bar'
expect(titleSpy).toHaveBeenCalledWith(`Foo Bar - ${environment.appTitle}`)
})
it('should copy id to clipboard, reset after 3 seconds', () => {
jest.useFakeTimers()
component.id = 42 as any
jest.spyOn(clipboard, 'copy').mockReturnValue(true)
component.copyID()
expect(clipboard.copy).toHaveBeenCalledWith('42')
expect(component.copied).toBe(true)
jest.advanceTimersByTime(3000)
expect(component.copied).toBe(false)
})
})

View File

@@ -1,3 +1,4 @@
import { Clipboard } from '@angular/cdk/clipboard'
import { Component, Input, inject } from '@angular/core'
import { Title } from '@angular/platform-browser'
import { NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'
@@ -13,8 +14,11 @@ import { environment } from 'src/environments/environment'
})
export class PageHeaderComponent {
private titleService = inject(Title)
private clipboard = inject(Clipboard)
_title = ''
private _title = ''
public copied: boolean = false
private copyTimeout: any
@Input()
set title(title: string) {
@@ -26,6 +30,9 @@ export class PageHeaderComponent {
return this._title
}
@Input()
id: number
@Input()
subTitle: string = ''
@@ -34,4 +41,12 @@ export class PageHeaderComponent {
@Input()
infoLink: string
public copyID() {
this.copied = this.clipboard.copy(this.id.toString())
clearTimeout(this.copyTimeout)
this.copyTimeout = setTimeout(() => {
this.copied = false
}, 3000)
}
}