QA review tooltip + comment improvements (#1779)
Resolves https://github.com/webrecorder/browsertrix/issues/1761 <!-- Fixes #issue_number --> ### Changes - Switches QA review page chip tooltip colors to dark text on light background - Shows newest comment when hovering over comment cell in QA tab page list to match tooltip in QA review page list - Validates textarea max entry for description and comments
This commit is contained in:
parent
26abbddd62
commit
e7dbf914a3
@ -98,6 +98,6 @@ export const pageDetails = (page: ArchivedItemQAPage) =>
|
||||
name="chat-square-text-fill"
|
||||
class="mr-2 h-4 w-4 flex-none text-blue-600"
|
||||
></sl-icon>
|
||||
${page.notes[page.notes.length - 1]?.text}
|
||||
${page.notes[page.notes.length - 1].text}
|
||||
</div>`
|
||||
: nothing}`;
|
||||
|
@ -138,8 +138,10 @@ export class QaPage extends TailwindElement {
|
||||
tabindex="0"
|
||||
aria-selected=${this.selected}
|
||||
>
|
||||
<sl-tooltip placement="left" hoist>
|
||||
<div slot="content" class="text-xs">${pageDetails(page)}</div>
|
||||
<sl-tooltip class="invert-tooltip" placement="left" hoist>
|
||||
<div slot="content" class="max-w-60 text-xs">
|
||||
${pageDetails(page)}
|
||||
</div>
|
||||
<div
|
||||
class="absolute -left-4 top-[50%] flex w-8 translate-y-[-50%] flex-col place-items-center gap-1 rounded-full border border-gray-300 bg-neutral-0 p-2 leading-[14px] shadow transition-transform hover:scale-110"
|
||||
>
|
||||
|
@ -762,19 +762,31 @@ export class ArchivedItemDetailQA extends TailwindElement {
|
||||
<btrix-table-cell
|
||||
>${this.renderApprovalStatus(page)}</btrix-table-cell
|
||||
>
|
||||
<btrix-table-cell
|
||||
>${page.notes?.length
|
||||
? statusWithIcon(
|
||||
html`<sl-icon
|
||||
name="chat-square-text-fill"
|
||||
class="text-blue-600"
|
||||
></sl-icon>`,
|
||||
`${page.notes.length.toLocaleString()} ${pluralOf("comments", page.notes.length)}`,
|
||||
)
|
||||
: html`<span class="text-neutral-400"
|
||||
>${msg("None")}</span
|
||||
>`}</btrix-table-cell
|
||||
>
|
||||
<btrix-table-cell>
|
||||
${page.notes?.length
|
||||
? html`
|
||||
<sl-tooltip class="invert-tooltip">
|
||||
<div slot="content">
|
||||
<div class="text-xs text-neutral-400">
|
||||
${msg("Newest comment:")}
|
||||
</div>
|
||||
<div class="leading04 max-w-60 text-xs">
|
||||
${page.notes[page.notes.length - 1].text}
|
||||
</div>
|
||||
</div>
|
||||
${statusWithIcon(
|
||||
html`<sl-icon
|
||||
name="chat-square-text-fill"
|
||||
class="text-blue-600"
|
||||
></sl-icon>`,
|
||||
`${page.notes.length.toLocaleString()} ${pluralOf("comments", page.notes.length)}`,
|
||||
)}
|
||||
</sl-tooltip>
|
||||
`
|
||||
: html`<span class="text-neutral-400">
|
||||
${msg("None")}
|
||||
</span>`}
|
||||
</btrix-table-cell>
|
||||
</btrix-table-row>
|
||||
`,
|
||||
)}
|
||||
|
@ -43,6 +43,7 @@ import type { ArchivedItem, ArchivedItemPageComment } from "@/types/crawler";
|
||||
import type { ArchivedItemQAPage, QARun } from "@/types/qa";
|
||||
import { type AuthState } from "@/utils/AuthService";
|
||||
import { finishedCrawlStates, isActive, renderName } from "@/utils/crawler";
|
||||
import { maxLengthValidator } from "@/utils/form";
|
||||
import { formatISODateString, getLocale } from "@/utils/localization";
|
||||
|
||||
const DEFAULT_PAGE_SIZE = 100;
|
||||
@ -158,6 +159,8 @@ export class ArchivedItemQA extends TailwindElement {
|
||||
private readonly notify = new NotifyController(this);
|
||||
private readonly replaySwReg =
|
||||
navigator.serviceWorker.getRegistration("/replay/");
|
||||
private readonly validateItemDescriptionMax = maxLengthValidator(500);
|
||||
private readonly validatePageCommentMax = maxLengthValidator(500);
|
||||
|
||||
@query("#replayframe")
|
||||
private readonly replayFrame?: HTMLIFrameElement | null;
|
||||
@ -581,11 +584,18 @@ export class ArchivedItemQA extends TailwindElement {
|
||||
</sl-button>
|
||||
</btrix-dialog>
|
||||
|
||||
${this.renderReviewDialog()}
|
||||
`;
|
||||
}
|
||||
|
||||
private renderReviewDialog() {
|
||||
const { helpText, validate } = this.validateItemDescriptionMax;
|
||||
return html`
|
||||
<btrix-dialog
|
||||
class="reviewDialog [--width:60rem]"
|
||||
label=${msg("QA Review")}
|
||||
>
|
||||
<form class="qaReviewForm" @submit=${this.onReviewSubmit}>
|
||||
<form class="qaReviewForm" @submit=${this.onSubmitReview}>
|
||||
<div class="flex flex-col gap-6 md:flex-row">
|
||||
<div>
|
||||
<sl-radio-group
|
||||
@ -642,7 +652,11 @@ export class ArchivedItemQA extends TailwindElement {
|
||||
label=${msg("Update archived item description?")}
|
||||
name="description"
|
||||
value=${this.item?.description ?? ""}
|
||||
placeholder=${msg("No description")}
|
||||
placeholder=${msg("No description, yet")}
|
||||
rows="10"
|
||||
autocomplete="off"
|
||||
help-text=${helpText}
|
||||
@sl-input=${validate}
|
||||
></sl-textarea>
|
||||
</div>
|
||||
</div>
|
||||
@ -720,6 +734,7 @@ export class ArchivedItemQA extends TailwindElement {
|
||||
}
|
||||
|
||||
private renderComments() {
|
||||
const { helpText, validate } = this.validatePageCommentMax;
|
||||
return html`
|
||||
${when(
|
||||
this.page?.notes?.length,
|
||||
@ -770,8 +785,10 @@ export class ArchivedItemQA extends TailwindElement {
|
||||
name="pageComment"
|
||||
label=${msg("Add a comment")}
|
||||
placeholder=${msg("Enter page feedback")}
|
||||
minlength="1"
|
||||
maxlength="500"
|
||||
rows="4"
|
||||
autocomplete="off"
|
||||
help-text=${helpText}
|
||||
@sl-input=${validate}
|
||||
></sl-textarea>
|
||||
</form>
|
||||
`;
|
||||
@ -941,6 +958,9 @@ export class ArchivedItemQA extends TailwindElement {
|
||||
|
||||
if (!value) return;
|
||||
|
||||
const formEl = e.target as HTMLFormElement;
|
||||
if (!(await this.checkFormValidity(formEl))) return;
|
||||
|
||||
void this.commentDialog?.hide();
|
||||
|
||||
try {
|
||||
@ -975,6 +995,11 @@ export class ArchivedItemQA extends TailwindElement {
|
||||
}
|
||||
}
|
||||
|
||||
async checkFormValidity(formEl: HTMLFormElement) {
|
||||
await this.updateComplete;
|
||||
return !formEl.querySelector("[data-invalid]");
|
||||
}
|
||||
|
||||
private async deletePageComment(commentId: string): Promise<void> {
|
||||
try {
|
||||
await this.api.fetch(
|
||||
@ -1293,14 +1318,15 @@ export class ArchivedItemQA extends TailwindElement {
|
||||
);
|
||||
}
|
||||
|
||||
private async onReviewSubmit(e: SubmitEvent) {
|
||||
private async onSubmitReview(e: SubmitEvent) {
|
||||
e.preventDefault();
|
||||
const form = e.currentTarget as HTMLFormElement;
|
||||
const params = serialize(form);
|
||||
|
||||
if (!params.reviewStatus) {
|
||||
return;
|
||||
}
|
||||
if (!params.reviewStatus) return;
|
||||
|
||||
const formEl = e.target as HTMLFormElement;
|
||||
if (!(await this.checkFormValidity(formEl))) return;
|
||||
|
||||
try {
|
||||
const data = await this.api.fetch<{ updated: boolean }>(
|
||||
|
@ -196,6 +196,18 @@
|
||||
min-width: min-content;
|
||||
}
|
||||
|
||||
/* Style tooltip with white background */
|
||||
sl-tooltip.invert-tooltip {
|
||||
--sl-tooltip-arrow-size: 0;
|
||||
--sl-tooltip-background-color: var(--sl-color-neutral-0);
|
||||
--sl-tooltip-color: var(--sl-color-neutral-700);
|
||||
}
|
||||
|
||||
sl-tooltip.invert-tooltip::part(body) {
|
||||
outline: 1px solid var(--sl-panel-border-color);
|
||||
box-shadow: var(--sl-shadow-large);
|
||||
}
|
||||
|
||||
/* For single-input forms with submit button inline */
|
||||
/* Requires form control and button to be direct children */
|
||||
.inline-control-input,
|
||||
|
Loading…
Reference in New Issue
Block a user