fix clean history ui

This commit is contained in:
Julian Freeman
2026-04-17 13:56:38 -04:00
parent 6d2b117200
commit ad838086ed
5 changed files with 414 additions and 70 deletions

View File

@@ -1,20 +1,13 @@
<script setup lang="ts">
import { computed } from "vue";
import type {
CleanupHistoryResult,
CleanupFileStatus,
ProfileSummary,
} from "../../types/browser";
import type { CleanupFileStatus, ProfileSummary } from "../../types/browser";
import { profileAvatarSrc } from "../../utils/icons";
const props = defineProps<{
browserId: string;
browserFamilyId: string | null;
profiles: ProfileSummary[];
selectedProfileIds: string[];
cleanupBusy: boolean;
cleanupError: string;
cleanupResults: CleanupHistoryResult[];
}>();
const emit = defineEmits<{
@@ -69,36 +62,20 @@ function hasAnyHistoryFile(statuses: CleanupFileStatus[]) {
<template>
<section class="table-section">
<div v-if="cleanupError" class="inline-error">
{{ cleanupError }}
</div>
<div v-if="cleanupResults.length" class="result-strip">
<article
v-for="result in cleanupResults"
:key="result.profileId"
class="result-chip"
:class="{ error: result.error }"
>
<strong>{{ result.profileId }}</strong>
<span v-if="result.error">{{ result.error }}</span>
<span v-else-if="result.deletedFiles.length">
Deleted {{ result.deletedFiles.join(", ") }}
</span>
<span v-else>
Nothing to delete
</span>
</article>
</div>
<div class="history-toolbar">
<label class="toolbar-checkbox" :class="{ disabled: !selectableProfiles.length }">
<input
type="checkbox"
class="native-checkbox"
:checked="allSelected"
:disabled="!selectableProfiles.length || cleanupBusy"
@change="emit('toggleAllProfiles')"
/>
<span class="custom-checkbox" :class="{ checked: allSelected }" aria-hidden="true">
<svg viewBox="0 0 16 16">
<path d="M3.5 8.2L6.4 11.1L12.5 4.9" />
</svg>
</span>
<span>Select All</span>
</label>
<button
@@ -124,12 +101,20 @@ function hasAnyHistoryFile(statuses: CleanupFileStatus[]) {
<div class="data-table-body styled-scrollbar">
<article v-for="profile in profiles" :key="profile.id" class="data-table-row history-grid">
<div class="row-cell checkbox-cell">
<input
type="checkbox"
:checked="isSelected(profile.id)"
:disabled="!isSelectable(profile) || cleanupBusy"
@change="emit('toggleProfile', profile.id)"
/>
<label class="table-checkbox" :class="{ disabled: !isSelectable(profile) || cleanupBusy }">
<input
type="checkbox"
class="native-checkbox"
:checked="isSelected(profile.id)"
:disabled="!isSelectable(profile) || cleanupBusy"
@change="emit('toggleProfile', profile.id)"
/>
<span class="custom-checkbox" :class="{ checked: isSelected(profile.id) }" aria-hidden="true">
<svg viewBox="0 0 16 16">
<path d="M3.5 8.2L6.4 11.1L12.5 4.9" />
</svg>
</span>
</label>
</div>
<div class="profile-avatar table-avatar">
<img
@@ -200,35 +185,83 @@ function hasAnyHistoryFile(statuses: CleanupFileStatus[]) {
gap: 10px;
color: var(--text);
font-size: 0.88rem;
cursor: pointer;
}
.toolbar-checkbox.disabled {
opacity: 0.55;
cursor: default;
}
.result-strip {
display: flex;
gap: 8px;
overflow: auto;
padding-bottom: 2px;
.native-checkbox {
position: absolute;
opacity: 0;
pointer-events: none;
}
.result-chip {
display: grid;
gap: 4px;
min-width: 220px;
padding: 10px 12px;
border: 1px solid rgba(16, 185, 129, 0.2);
border-radius: 14px;
background: rgba(236, 253, 245, 0.92);
color: #065f46;
font-size: 0.82rem;
.table-checkbox {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.result-chip.error {
border-color: rgba(239, 68, 68, 0.18);
background: rgba(254, 242, 242, 0.96);
color: #b42318;
.table-checkbox.disabled {
cursor: default;
opacity: 0.5;
}
.custom-checkbox {
display: inline-flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
border: 1px solid rgba(148, 163, 184, 0.34);
border-radius: 7px;
background: linear-gradient(180deg, rgba(255, 255, 255, 0.98), rgba(241, 245, 249, 0.92));
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.78),
0 4px 10px rgba(15, 23, 42, 0.06);
transition:
border-color 160ms ease,
background 160ms ease,
box-shadow 160ms ease,
transform 160ms ease;
}
.custom-checkbox svg {
width: 12px;
height: 12px;
}
.custom-checkbox path {
fill: none;
stroke: #fff;
stroke-width: 2.2;
stroke-linecap: round;
stroke-linejoin: round;
opacity: 0;
transition: opacity 160ms ease;
}
.toolbar-checkbox:hover .custom-checkbox,
.table-checkbox:hover .custom-checkbox {
border-color: rgba(47, 111, 237, 0.38);
transform: translateY(-1px);
}
.custom-checkbox.checked {
border-color: rgba(47, 111, 237, 0.2);
background: linear-gradient(135deg, #2f6fed, #5aa1f7);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.22),
0 8px 18px rgba(47, 111, 237, 0.22);
}
.custom-checkbox.checked path {
opacity: 1;
}
.data-table {