Initial result display in create dialog

This commit is contained in:
shamoon 2025-11-04 21:12:57 -08:00
parent 6adeff1901
commit 01e9988bd2
No known key found for this signature in database
3 changed files with 191 additions and 63 deletions

View File

@ -3,6 +3,7 @@
<button type="button" class="btn-close" aria-label="Close" (click)="cancel()"></button>
</div>
<div class="modal-body">
@if (!createdBundle) {
<form [formGroup]="form" class="d-flex flex-column gap-3">
<div>
<p class="mb-1">
@ -48,12 +49,61 @@
<label class="form-check-label" for="shareArchiveSwitch" i18n>Share archive version (if available)</label>
</div>
</div>
<div class="alert alert-info mb-0" role="alert">
<ng-container i18n>Bulk share link creation is experimental. Saving will attempt to start the process and show the result as a notification.</ng-container>
</div>
</form>
} @else {
<div class="d-flex flex-column gap-3">
<div class="alert alert-success mb-0" role="status">
<h6 class="alert-heading mb-1" i18n>Share link requested</h6>
<p class="mb-0 small" i18n>
You can copy the link below or open the management screen to monitor its progress. The link will start working once it is ready.
</p>
</div>
<dl class="row mb-0 small">
<dt class="col-sm-4" i18n>Status</dt>
<dd class="col-sm-8">
<span class="badge text-bg-secondary text-uppercase">{{ statusLabel(createdBundle.status) }}</span>
</dd>
<dt class="col-sm-4" i18n>Slug</dt>
<dd class="col-sm-8"><code>{{ createdBundle.slug }}</code></dd>
<dt class="col-sm-4" i18n>Link</dt>
<dd class="col-sm-8">
<div class="input-group input-group-sm">
<input class="form-control" type="text" [value]="getShareUrl(createdBundle)" readonly>
<button
class="btn btn-outline-primary"
type="button"
(click)="copy(createdBundle)"
>
@if (copied) {
<i-bs name="clipboard-check"></i-bs>
}
@if (!copied) {
<i-bs name="clipboard"></i-bs>
}
<span class="visually-hidden" i18n>Copy link</span>
</button>
</div>
</dd>
<dt class="col-sm-4" i18n>Documents</dt>
<dd class="col-sm-8">{{ createdBundle.document_count }}</dd>
<dt class="col-sm-4" i18n>Expires</dt>
<dd class="col-sm-8">
@if (createdBundle.expiration) {
{{ createdBundle.expiration | date: 'short' }}
}
@if (!createdBundle.expiration) {
<span i18n>Never</span>
}
</dd>
<dt class="col-sm-4" i18n>File version</dt>
<dd class="col-sm-8">{{ fileVersionLabel(createdBundle.file_version) }}</dd>
@if (createdBundle.size_bytes !== undefined && createdBundle.size_bytes !== null) {
<dt class="col-sm-4" i18n>Size</dt>
<dd class="col-sm-8">{{ createdBundle.size_bytes | fileSize }}</dd>
}
</dl>
</div>
}
</div>
<div class="modal-footer">
<div class="d-flex align-items-center gap-2 w-100">
@ -61,6 +111,11 @@
<ng-container i18n>Large bundles can take significant time to prepare and / or download.</ng-container>
</div>
<button type="button" class="btn btn-outline-secondary btn-sm ms-auto" (click)="cancel()">{{ cancelBtnCaption }}</button>
@if (createdBundle) {
<button type="button" class="btn btn-outline-secondary btn-sm" (click)="openManage()" i18n>Open manage links</button>
}
@if (!createdBundle) {
<button
type="button"
class="btn btn-primary btn-sm d-inline-flex align-items-center gap-2"
@ -71,5 +126,6 @@
}
<span>{{ btnCaption }}</span>
</button>
}
</div>
</div>

View File

@ -1,21 +1,36 @@
import { Clipboard } from '@angular/cdk/clipboard'
import { CommonModule } from '@angular/common'
import { Component, Input, inject } from '@angular/core'
import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms'
import { ShareBundleCreatePayload } from 'src/app/data/share-bundle'
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
import {
ShareBundleCreatePayload,
ShareBundleSummary,
} from 'src/app/data/share-bundle'
import {
FileVersion,
SHARE_LINK_EXPIRATION_OPTIONS,
} from 'src/app/data/share-link'
import { FileSizePipe } from 'src/app/pipes/file-size.pipe'
import { ToastService } from 'src/app/services/toast.service'
import { environment } from 'src/environments/environment'
import { ConfirmDialogComponent } from '../confirm-dialog/confirm-dialog.component'
@Component({
selector: 'pngx-share-bundle-dialog',
templateUrl: './share-bundle-dialog.component.html',
standalone: true,
imports: [CommonModule, ReactiveFormsModule],
imports: [
CommonModule,
ReactiveFormsModule,
NgxBootstrapIconsModule,
FileSizePipe,
],
})
export class ShareBundleDialogComponent extends ConfirmDialogComponent {
private formBuilder = inject(FormBuilder)
private clipboard = inject(Clipboard)
private toastService = inject(ToastService)
private _documentIds: number[] = []
@ -29,10 +44,25 @@ export class ShareBundleDialogComponent extends ConfirmDialogComponent {
readonly expirationOptions = SHARE_LINK_EXPIRATION_OPTIONS
createdBundle: ShareBundleSummary | null = null
copied = false
onOpenManage?: () => void
readonly statusLabels: Record<ShareBundleSummary['status'], string> = {
pending: $localize`Pending`,
processing: $localize`Processing`,
ready: $localize`Ready`,
failed: $localize`Failed`,
}
readonly fileVersionLabels: Record<FileVersion, string> = {
[FileVersion.Archive]: $localize`Archive`,
[FileVersion.Original]: $localize`Original`,
}
constructor() {
super()
this.loading = false
this.title = $localize`Share Selected Documents`
this.btnCaption = $localize`Create`
}
@Input()
@ -47,6 +77,7 @@ export class ShareBundleDialogComponent extends ConfirmDialogComponent {
}
submit() {
if (this.createdBundle) return
this.payload = {
document_ids: this.documentIds,
file_version: this.form.value.shareArchiveVersion
@ -54,6 +85,41 @@ export class ShareBundleDialogComponent extends ConfirmDialogComponent {
: FileVersion.Original,
expiration_days: this.form.value.expirationDays,
}
this.buttonsEnabled = false
super.confirm()
}
getShareUrl(bundle: ShareBundleSummary): string {
const apiURL = new URL(environment.apiBaseUrl)
return `${apiURL.origin}${apiURL.pathname.replace(/\/api\/$/, '/share/')}${
bundle.slug
}`
}
copy(bundle: ShareBundleSummary): void {
const success = this.clipboard.copy(this.getShareUrl(bundle))
if (success) {
this.copied = true
this.toastService.showInfo($localize`Share link copied to clipboard.`)
setTimeout(() => {
this.copied = false
}, 3000)
}
}
openManage(): void {
if (this.onOpenManage) {
this.onOpenManage()
} else {
this.cancel()
}
}
statusLabel(status: ShareBundleSummary['status']): string {
return this.statusLabels[status] ?? status
}
fileVersionLabel(version: FileVersion): string {
return this.fileVersionLabels[version] ?? version
}
}

View File

@ -935,10 +935,16 @@ export class BulkEditorComponent
.createBundle(payload)
.pipe(first())
.subscribe({
next: () => {
next: (result) => {
dialog.loading = false
dialog.buttonsEnabled = true
dialog.buttonsEnabled = false
dialog.createdBundle = result
dialog.copied = false
dialog.payload = null
dialog.onOpenManage = () => {
modal.close()
this.manageShareLinks()
}
this.toastService.showInfo(
$localize`Bulk share link creation requested.`
)