Use internal rounded bar in <btrix-meter>
for QA analysis meters (#1869)
Closes #1851 This changes how we use the `<btrix-meter>` component: previously, we didn't set a `max` value on it, so it was drawing its internal (rounded) bar at 100% of the meter width, and then drawing the `<btrix-meter-bar>`s inside that 100% width bar. This changes that, and instead it now does the following: - Draws the internal rounded bar to the width of the proportion of their counts to the total page count; - Adjusts the `<btrix-meter-bar>`s to be proportional to the completed page count rather than the total page count - Uses the `"available"` slot in `<btrix-meter>` to draw the remaining "No data" bar & tooltip in the remaining space outside of the internal rounded bar This also includes a couple unrelated but adjacent changes: - Changes the page count text to say "Analysis starting" when the analysis run is starting, because there's no meaningful page count at that point. - Uses the pending state when the total page count is falsy (`undefined` or `0`), rather than just `undefined`
This commit is contained in:
parent
879e509b39
commit
a7382ebb98
@ -44,7 +44,7 @@ import { formatNumber, getLocale } from "@/utils/localization";
|
|||||||
import { pluralOf } from "@/utils/pluralize";
|
import { pluralOf } from "@/utils/pluralize";
|
||||||
|
|
||||||
type QAStatsThreshold = {
|
type QAStatsThreshold = {
|
||||||
lowerBoundary: `${number}` | "No data";
|
lowerBoundary: `${number}`;
|
||||||
count: number;
|
count: number;
|
||||||
};
|
};
|
||||||
type QAStats = Record<"screenshotMatch" | "textMatch", QAStatsThreshold[]>;
|
type QAStats = Record<"screenshotMatch" | "textMatch", QAStatsThreshold[]>;
|
||||||
@ -505,9 +505,7 @@ export class ArchivedItemDetailQA extends TailwindElement {
|
|||||||
<div>
|
<div>
|
||||||
<sl-tooltip
|
<sl-tooltip
|
||||||
content=${mostRecentSelected
|
content=${mostRecentSelected
|
||||||
? msg(
|
? msg("You’re viewing the latest analysis run results.")
|
||||||
"You’re viewing the latest analysis run results.",
|
|
||||||
)
|
|
||||||
: msg(
|
: msg(
|
||||||
"You’re viewing results from an older analysis run.",
|
"You’re viewing results from an older analysis run.",
|
||||||
)}
|
)}
|
||||||
@ -534,15 +532,13 @@ export class ArchivedItemDetailQA extends TailwindElement {
|
|||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2 text-neutral-500">
|
<div class="flex items-center gap-2 text-neutral-500">
|
||||||
${when(
|
<div class="text-sm font-normal">
|
||||||
qaRun.stats,
|
${qaRun.state === "starting"
|
||||||
(stats) => html`
|
? msg("Analysis starting")
|
||||||
<div class="text-sm font-normal">
|
: `${formatNumber(qaRun.stats.done)}/${formatNumber(qaRun.stats.found)}
|
||||||
${formatNumber(stats.done)} / ${formatNumber(stats.found)}
|
${pluralOf("pages", qaRun.stats.found)} ${msg("analyzed")}`}
|
||||||
${pluralOf("pages", stats.found)} ${msg("analyzed")}
|
</div>
|
||||||
</div>
|
|
||||||
`,
|
|
||||||
)}
|
|
||||||
<sl-tooltip
|
<sl-tooltip
|
||||||
content=${msg(
|
content=${msg(
|
||||||
"Match analysis compares pages during a crawl against their replay during an analysis run. A good match indicates that the crawl is probably good, whereas severe inconsistencies may indicate a bad crawl.",
|
"Match analysis compares pages during a crawl against their replay during an analysis run. A good match indicates that the crawl is probably good, whereas severe inconsistencies may indicate a bad crawl.",
|
||||||
@ -572,6 +568,7 @@ export class ArchivedItemDetailQA extends TailwindElement {
|
|||||||
? this.renderMeter(
|
? this.renderMeter(
|
||||||
qaRun.stats.found,
|
qaRun.stats.found,
|
||||||
this.qaStats.value.screenshotMatch,
|
this.qaStats.value.screenshotMatch,
|
||||||
|
isRunning,
|
||||||
)
|
)
|
||||||
: this.renderMeter()}
|
: this.renderMeter()}
|
||||||
</btrix-table-cell>
|
</btrix-table-cell>
|
||||||
@ -585,6 +582,7 @@ export class ArchivedItemDetailQA extends TailwindElement {
|
|||||||
? this.renderMeter(
|
? this.renderMeter(
|
||||||
qaRun.stats.found,
|
qaRun.stats.found,
|
||||||
this.qaStats.value.textMatch,
|
this.qaStats.value.textMatch,
|
||||||
|
isRunning,
|
||||||
)
|
)
|
||||||
: this.renderMeter()}
|
: this.renderMeter()}
|
||||||
</btrix-table-cell>
|
</btrix-table-cell>
|
||||||
@ -613,16 +611,39 @@ export class ArchivedItemDetailQA extends TailwindElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderMeter(pageCount?: number, barData?: QAStatsThreshold[]) {
|
private renderMeter(): TemplateResult<1>;
|
||||||
if (pageCount === undefined || !barData) {
|
private renderMeter(
|
||||||
|
pageCount: number,
|
||||||
|
barData: QAStatsThreshold[],
|
||||||
|
qaIsRunning: boolean | undefined,
|
||||||
|
): TemplateResult<1>;
|
||||||
|
private renderMeter(
|
||||||
|
pageCount?: number,
|
||||||
|
barData?: QAStatsThreshold[],
|
||||||
|
qaIsRunning?: boolean,
|
||||||
|
) {
|
||||||
|
if (!pageCount || !barData) {
|
||||||
return html`<sl-skeleton
|
return html`<sl-skeleton
|
||||||
class="h-4 flex-1 [--border-radius:var(--sl-border-radius-medium)]"
|
class="h-4 flex-1 [--border-radius:var(--sl-border-radius-medium)]"
|
||||||
effect="sheen"
|
effect="sheen"
|
||||||
></sl-skeleton>`;
|
></sl-skeleton>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
barData = barData.filter(
|
||||||
|
(bar) => (bar.lowerBoundary as string) !== "No data",
|
||||||
|
);
|
||||||
|
|
||||||
|
const analyzedPageCount = barData.reduce(
|
||||||
|
(prev, cur) => prev + cur.count,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
|
const remainingPageCount = pageCount - analyzedPageCount;
|
||||||
|
const remainderBarLabel = qaIsRunning ? msg("Pending") : msg("Incomplete");
|
||||||
|
|
||||||
|
console.log({ pageCount, barData, analyzedPageCount });
|
||||||
return html`
|
return html`
|
||||||
<btrix-meter class="flex-1" value=${pageCount}>
|
<btrix-meter class="flex-1" value=${analyzedPageCount} max=${pageCount}>
|
||||||
${barData.map((bar) => {
|
${barData.map((bar) => {
|
||||||
const threshold = qaStatsThresholds.find(
|
const threshold = qaStatsThresholds.find(
|
||||||
({ lowerBoundary }) => bar.lowerBoundary === lowerBoundary,
|
({ lowerBoundary }) => bar.lowerBoundary === lowerBoundary,
|
||||||
@ -632,23 +653,20 @@ export class ArchivedItemDetailQA extends TailwindElement {
|
|||||||
return bar.count !== 0
|
return bar.count !== 0
|
||||||
? html`
|
? html`
|
||||||
<btrix-meter-bar
|
<btrix-meter-bar
|
||||||
value=${(bar.count / pageCount) * 100}
|
value=${(bar.count / analyzedPageCount) * 100}
|
||||||
style="--background-color: ${threshold?.cssColor}"
|
style="--background-color: ${threshold?.cssColor ?? "none"}"
|
||||||
aria-label=${bar.lowerBoundary}
|
aria-label=${threshold?.label ?? ""}
|
||||||
>
|
>
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
${bar.lowerBoundary === "No data"
|
${threshold?.label}
|
||||||
? msg("No Data")
|
|
||||||
: threshold?.label}
|
|
||||||
<div class="text-xs opacity-80">
|
<div class="text-xs opacity-80">
|
||||||
${bar.lowerBoundary !== "No data"
|
${idx === 0
|
||||||
? html`${idx === 0
|
? `<${+qaStatsThresholds[idx + 1].lowerBoundary * 100}%`
|
||||||
? `<${+qaStatsThresholds[idx + 1].lowerBoundary * 100}%`
|
: idx === qaStatsThresholds.length - 1
|
||||||
: idx === qaStatsThresholds.length - 1
|
? `>=${threshold ? +threshold.lowerBoundary * 100 : 0}%`
|
||||||
? `>=${threshold ? +threshold.lowerBoundary * 100 : 0}%`
|
: `${threshold ? +threshold.lowerBoundary * 100 : 0}-${+qaStatsThresholds[idx + 1].lowerBoundary * 100 || 100}%`}
|
||||||
: `${threshold ? +threshold.lowerBoundary * 100 : 0}-${+qaStatsThresholds[idx + 1].lowerBoundary * 100 || 100}%`}
|
${msg("match", { desc: "label for match percentage" })}
|
||||||
match <br />`
|
<br />
|
||||||
: nothing}
|
|
||||||
${formatNumber(bar.count)} ${pluralOf("pages", bar.count)}
|
${formatNumber(bar.count)} ${pluralOf("pages", bar.count)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -656,6 +674,24 @@ export class ArchivedItemDetailQA extends TailwindElement {
|
|||||||
`
|
`
|
||||||
: nothing;
|
: nothing;
|
||||||
})}
|
})}
|
||||||
|
${remainingPageCount > 0
|
||||||
|
? html`
|
||||||
|
<btrix-meter-bar
|
||||||
|
slot="available"
|
||||||
|
value=${(remainingPageCount / pageCount) * 100}
|
||||||
|
aria-label=${remainderBarLabel}
|
||||||
|
style="--background-color: none"
|
||||||
|
>
|
||||||
|
<div class="text-center">
|
||||||
|
${remainderBarLabel}
|
||||||
|
<div class="text-xs opacity-80">
|
||||||
|
${formatNumber(remainingPageCount)}
|
||||||
|
${pluralOf("pages", remainingPageCount)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</btrix-meter-bar>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
</btrix-meter>
|
</btrix-meter>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user