This repository has been archived on 2026-04-20. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
chrom-tool/src/components/browser-data/BrowserDataView.vue
Julian Freeman 16eb25d552 fix table ui
2026-04-16 19:38:46 -04:00

176 lines
5.0 KiB
Vue

<script setup lang="ts">
import type {
ActiveSection,
AssociatedProfileSummary,
BookmarkAssociatedProfileSummary,
BookmarkSortKey,
BrowserView,
ExtensionSortKey,
ProfileSortKey,
} from "../../types/browser";
import AssociatedProfilesModal from "./AssociatedProfilesModal.vue";
import BookmarksList from "./BookmarksList.vue";
import ExtensionsList from "./ExtensionsList.vue";
import ProfilesList from "./ProfilesList.vue";
defineProps<{
currentBrowser: BrowserView;
activeSection: ActiveSection;
profileSortKey: ProfileSortKey;
extensionSortKey: ExtensionSortKey;
bookmarkSortKey: BookmarkSortKey;
sortedProfiles: BrowserView["profiles"];
sortedExtensions: BrowserView["extensions"];
sortedBookmarks: BrowserView["bookmarks"];
openProfileError: string;
sectionCount: (section: ActiveSection) => number;
isOpeningProfile: (browserId: string, profileId: string) => boolean;
extensionMonogram: (name: string) => string;
domainFromUrl: (url: string) => string;
associatedProfilesModal: {
title: string;
browserId: string;
profiles: (AssociatedProfileSummary | BookmarkAssociatedProfileSummary)[];
isBookmark: boolean;
} | null;
}>();
const emit = defineEmits<{
"update:activeSection": [value: ActiveSection];
"update:profileSortKey": [value: ProfileSortKey];
"update:extensionSortKey": [value: ExtensionSortKey];
"update:bookmarkSortKey": [value: BookmarkSortKey];
openProfile: [browserId: string, profileId: string];
showExtensionProfiles: [extensionId: string];
showBookmarkProfiles: [url: string];
closeAssociatedProfiles: [];
}>();
</script>
<template>
<section class="section-tabs">
<button
class="section-tab"
:class="{ active: activeSection === 'profiles' }"
type="button"
@click="emit('update:activeSection', 'profiles')"
>
<span>Profiles</span>
<span class="count-pill">{{ sectionCount("profiles") }}</span>
</button>
<button
class="section-tab"
:class="{ active: activeSection === 'extensions' }"
type="button"
@click="emit('update:activeSection', 'extensions')"
>
<span>Extensions</span>
<span class="count-pill">{{ sectionCount("extensions") }}</span>
</button>
<button
class="section-tab"
:class="{ active: activeSection === 'bookmarks' }"
type="button"
@click="emit('update:activeSection', 'bookmarks')"
>
<span>Bookmarks</span>
<span class="count-pill">{{ sectionCount("bookmarks") }}</span>
</button>
</section>
<div class="content-scroll-area">
<ProfilesList
v-if="activeSection === 'profiles'"
:profiles="sortedProfiles"
:sort-key="profileSortKey"
:open-profile-error="openProfileError"
:browser-id="currentBrowser.browserId"
:browser-family-id="currentBrowser.browserFamilyId"
:is-opening-profile="isOpeningProfile"
@update:sort-key="emit('update:profileSortKey', $event)"
@open-profile="(browserId, profileId) => emit('openProfile', browserId, profileId)"
/>
<ExtensionsList
v-else-if="activeSection === 'extensions'"
:extensions="sortedExtensions"
:sort-key="extensionSortKey"
:extension-monogram="extensionMonogram"
@update:sort-key="emit('update:extensionSortKey', $event)"
@show-profiles="emit('showExtensionProfiles', $event)"
/>
<BookmarksList
v-else
:bookmarks="sortedBookmarks"
:sort-key="bookmarkSortKey"
@update:sort-key="emit('update:bookmarkSortKey', $event)"
@show-profiles="emit('showBookmarkProfiles', $event)"
/>
</div>
<AssociatedProfilesModal
v-if="associatedProfilesModal"
:title="associatedProfilesModal.title"
:profiles="associatedProfilesModal.profiles"
:browser-id="associatedProfilesModal.browserId"
:browser-family-id="currentBrowser.browserFamilyId"
:is-bookmark="associatedProfilesModal.isBookmark"
:is-opening-profile="isOpeningProfile"
@close="emit('closeAssociatedProfiles')"
@open-profile="(browserId, profileId) => emit('openProfile', browserId, profileId)"
/>
</template>
<style scoped>
.section-tabs {
display: flex;
gap: 10px;
margin-top: 0;
padding: 8px;
flex-shrink: 0;
border: 1px solid var(--panel-border);
border-radius: 22px;
background: var(--panel);
box-shadow: var(--shadow);
}
.section-tab {
display: inline-flex;
align-items: center;
justify-content: space-between;
gap: 12px;
min-width: 0;
flex: 1;
padding: 10px 12px;
border-radius: 15px;
color: var(--muted);
background: rgba(255, 255, 255, 0.58);
cursor: pointer;
transition:
background 160ms ease,
color 160ms ease,
transform 160ms ease,
box-shadow 160ms ease;
}
.section-tab:hover {
transform: translateY(-1px);
}
.section-tab.active {
color: var(--text);
background: linear-gradient(135deg, rgba(255, 255, 255, 0.96), rgba(232, 240, 255, 0.92));
box-shadow: 0 12px 24px rgba(15, 23, 42, 0.08);
}
.content-scroll-area {
display: flex;
}
.content-scroll-area > * {
flex: 1;
min-height: 0;
}
</style>