support delete bookmarks
This commit is contained in:
@@ -43,6 +43,7 @@ const allSelected = computed(
|
||||
sortedProfiles.value.length > 0 &&
|
||||
sortedProfiles.value.every((profile) => selectedProfileIds.value.includes(profile.id)),
|
||||
);
|
||||
const isSelectableMode = computed(() => props.isExtension || props.isBookmark);
|
||||
|
||||
function hasBookmarkPath(profile: ModalProfile): profile is BookmarkAssociatedProfileSummary {
|
||||
return "bookmarkPath" in profile;
|
||||
@@ -67,7 +68,7 @@ function isSelected(profileId: string) {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div v-if="isExtension" class="modal-toolbar">
|
||||
<div v-if="isSelectableMode" class="modal-toolbar">
|
||||
<label class="toolbar-checkbox" :class="{ disabled: !sortedProfiles.length }">
|
||||
<input
|
||||
type="checkbox"
|
||||
@@ -95,10 +96,18 @@ function isSelected(profileId: string) {
|
||||
|
||||
<div class="modal-table">
|
||||
<div class="modal-table-header modal-grid" :class="{ bookmark: isBookmark, extension: isExtension }">
|
||||
<div v-if="isExtension" class="header-cell checkbox-cell">Pick</div>
|
||||
<div v-if="isSelectableMode" class="header-cell checkbox-cell">Pick</div>
|
||||
<div class="header-cell icon-cell">Avatar</div>
|
||||
<button class="header-cell sortable" :class="{ active: sortKey === 'name' }" type="button" @click="sortKey = 'name'">Name</button>
|
||||
<button v-if="!isExtension" class="header-cell sortable" :class="{ active: sortKey === 'id' }" type="button" @click="sortKey = 'id'">Profile ID</button>
|
||||
<button
|
||||
v-if="!isExtension && !isBookmark"
|
||||
class="header-cell sortable"
|
||||
:class="{ active: sortKey === 'id' }"
|
||||
type="button"
|
||||
@click="sortKey = 'id'"
|
||||
>
|
||||
Profile ID
|
||||
</button>
|
||||
<div v-if="isExtension" class="header-cell">Source</div>
|
||||
<div v-if="isBookmark" class="header-cell">Bookmark Path</div>
|
||||
<div class="header-cell actions-cell">Action</div>
|
||||
@@ -110,7 +119,7 @@ function isSelected(profileId: string) {
|
||||
class="modal-table-row modal-grid"
|
||||
:class="{ bookmark: isBookmark, extension: isExtension }"
|
||||
>
|
||||
<div v-if="isExtension" class="row-cell checkbox-cell">
|
||||
<div v-if="isSelectableMode" class="row-cell checkbox-cell">
|
||||
<label class="table-checkbox" :class="{ disabled: deleteBusy }">
|
||||
<input
|
||||
type="checkbox"
|
||||
@@ -136,9 +145,9 @@ function isSelected(profileId: string) {
|
||||
</div>
|
||||
<div class="row-cell primary-cell">
|
||||
<strong>{{ profile.name }}</strong>
|
||||
<span v-if="isExtension" class="subtle-line">{{ profile.id }}</span>
|
||||
<span v-if="isExtension || isBookmark" class="subtle-line">{{ profile.id }}</span>
|
||||
</div>
|
||||
<div v-if="!isExtension" class="row-cell">
|
||||
<div v-if="!isExtension && !isBookmark" class="row-cell">
|
||||
<span class="badge neutral">{{ profile.id }}</span>
|
||||
</div>
|
||||
<div v-if="isExtension && hasInstallSource(profile)" class="row-cell muted-cell">
|
||||
@@ -161,7 +170,7 @@ function isSelected(profileId: string) {
|
||||
{{ isOpeningProfile(browserId, profile.id) ? "Opening..." : "Open" }}
|
||||
</button>
|
||||
<button
|
||||
v-if="isExtension"
|
||||
v-if="isSelectableMode"
|
||||
class="danger-button inline-danger-button"
|
||||
type="button"
|
||||
:disabled="deleteBusy"
|
||||
@@ -234,7 +243,7 @@ function isSelected(profileId: string) {
|
||||
}
|
||||
|
||||
.modal-grid.bookmark {
|
||||
grid-template-columns: 56px minmax(140px, 0.9fr) 120px minmax(180px, 1fr) 110px;
|
||||
grid-template-columns: 52px 56px minmax(180px, 0.78fr) minmax(180px, 1fr) 168px;
|
||||
}
|
||||
|
||||
.modal-table-header.modal-grid.extension,
|
||||
|
||||
151
src/components/browser-data/BookmarkRemovalModal.vue
Normal file
151
src/components/browser-data/BookmarkRemovalModal.vue
Normal file
@@ -0,0 +1,151 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
|
||||
import type { RemoveBookmarkResult } from "../../types/browser";
|
||||
|
||||
const props = defineProps<{
|
||||
mode: "confirm" | "result";
|
||||
title: string;
|
||||
bookmarkCount: number;
|
||||
profileCount: number;
|
||||
results: RemoveBookmarkResult[];
|
||||
busy?: boolean;
|
||||
generalError?: string;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
close: [];
|
||||
confirm: [];
|
||||
}>();
|
||||
|
||||
const resultSummary = computed(() => {
|
||||
const statusByUrl = new Map<string, boolean>();
|
||||
|
||||
for (const result of props.results) {
|
||||
const previous = statusByUrl.get(result.url);
|
||||
const succeeded = !result.error;
|
||||
|
||||
if (previous === undefined) {
|
||||
statusByUrl.set(result.url, succeeded);
|
||||
continue;
|
||||
}
|
||||
|
||||
statusByUrl.set(result.url, previous && succeeded);
|
||||
}
|
||||
|
||||
let successCount = 0;
|
||||
let failedCount = 0;
|
||||
for (const succeeded of statusByUrl.values()) {
|
||||
if (succeeded) {
|
||||
successCount += 1;
|
||||
} else {
|
||||
failedCount += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return { successCount, failedCount };
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="modal-backdrop" @click.self="emit('close')">
|
||||
<section class="modal-card">
|
||||
<div class="modal-header">
|
||||
<h3>{{ title }}</h3>
|
||||
<button class="secondary-button" type="button" @click="emit('close')">Close</button>
|
||||
</div>
|
||||
|
||||
<template v-if="mode === 'confirm'">
|
||||
<p class="modal-copy">
|
||||
This will remove {{ bookmarkCount }} bookmark{{ bookmarkCount === 1 ? "" : "s" }} from
|
||||
{{ profileCount }} profile{{ profileCount === 1 ? "" : "s" }}.
|
||||
</p>
|
||||
|
||||
<div class="modal-actions">
|
||||
<button class="secondary-button" type="button" @click="emit('close')">Cancel</button>
|
||||
<button class="danger-button" type="button" :disabled="busy" @click="emit('confirm')">
|
||||
{{ busy ? "Deleting..." : "Confirm Delete" }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<p v-if="generalError" class="result-banner error">{{ generalError }}</p>
|
||||
<p class="modal-copy">
|
||||
Successfully removed {{ resultSummary.successCount }} bookmark{{
|
||||
resultSummary.successCount === 1 ? "" : "s"
|
||||
}}. Failed to remove {{ resultSummary.failedCount }} bookmark{{
|
||||
resultSummary.failedCount === 1 ? "" : "s"
|
||||
}}.
|
||||
</p>
|
||||
|
||||
<div class="modal-actions">
|
||||
<button class="primary-button" type="button" @click="emit('close')">Close</button>
|
||||
</div>
|
||||
</template>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.modal-backdrop {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 50;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
padding: 24px;
|
||||
background: rgba(15, 23, 42, 0.26);
|
||||
backdrop-filter: blur(6px);
|
||||
-webkit-backdrop-filter: blur(6px);
|
||||
}
|
||||
|
||||
.modal-card {
|
||||
width: min(560px, 100%);
|
||||
max-height: min(72vh, 820px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
padding: 16px;
|
||||
border: 1px solid var(--panel-border);
|
||||
border-radius: 22px;
|
||||
background: rgba(255, 255, 255, 0.96);
|
||||
box-shadow: 0 28px 70px rgba(15, 23, 42, 0.18);
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.modal-header h3,
|
||||
.modal-copy {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.modal-copy {
|
||||
color: var(--muted);
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
.result-banner {
|
||||
margin: 0;
|
||||
padding: 12px 14px;
|
||||
border-radius: 14px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.result-banner.error {
|
||||
background: rgba(254, 242, 242, 0.96);
|
||||
color: #b42318;
|
||||
border: 1px solid rgba(239, 68, 68, 0.18);
|
||||
}
|
||||
|
||||
.modal-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,27 +1,88 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
|
||||
import type { BookmarkSortKey, BookmarkSummary } from "../../types/browser";
|
||||
|
||||
defineProps<{
|
||||
const props = defineProps<{
|
||||
bookmarks: BookmarkSummary[];
|
||||
sortKey: BookmarkSortKey;
|
||||
selectedBookmarkUrls: string[];
|
||||
deleteBusy: boolean;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
"update:sortKey": [value: BookmarkSortKey];
|
||||
showProfiles: [url: string];
|
||||
toggleBookmark: [url: string];
|
||||
toggleAllBookmarks: [];
|
||||
deleteBookmark: [url: string];
|
||||
deleteSelected: [];
|
||||
}>();
|
||||
|
||||
const allSelected = computed(
|
||||
() =>
|
||||
props.bookmarks.length > 0 &&
|
||||
props.bookmarks.every((bookmark) => props.selectedBookmarkUrls.includes(bookmark.url)),
|
||||
);
|
||||
|
||||
function isSelected(url: string) {
|
||||
return props.selectedBookmarkUrls.includes(url);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="table-section">
|
||||
<div class="bookmarks-toolbar">
|
||||
<label class="toolbar-checkbox" :class="{ disabled: !bookmarks.length }">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="native-checkbox"
|
||||
:checked="allSelected"
|
||||
:disabled="!bookmarks.length || deleteBusy"
|
||||
@change="emit('toggleAllBookmarks')"
|
||||
/>
|
||||
<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
|
||||
class="danger-button"
|
||||
type="button"
|
||||
:disabled="!selectedBookmarkUrls.length || deleteBusy"
|
||||
@click="emit('deleteSelected')"
|
||||
>
|
||||
{{ deleteBusy ? "Deleting..." : `Delete Selected (${selectedBookmarkUrls.length})` }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div v-if="bookmarks.length" class="data-table">
|
||||
<div class="data-table-header bookmarks-grid">
|
||||
<div class="header-cell checkbox-cell">Pick</div>
|
||||
<button class="header-cell sortable" :class="{ active: sortKey === 'title' }" type="button" @click="emit('update:sortKey', 'title')">Name</button>
|
||||
<button class="header-cell sortable" :class="{ active: sortKey === 'url' }" type="button" @click="emit('update:sortKey', 'url')">URL</button>
|
||||
<div class="header-cell actions-cell">Profiles</div>
|
||||
<div class="header-cell actions-cell">Actions</div>
|
||||
</div>
|
||||
<div class="data-table-body styled-scrollbar">
|
||||
<article v-for="bookmark in bookmarks" :key="bookmark.url" class="data-table-row bookmarks-grid">
|
||||
<div class="row-cell checkbox-cell">
|
||||
<label class="table-checkbox" :class="{ disabled: deleteBusy }">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="native-checkbox"
|
||||
:checked="isSelected(bookmark.url)"
|
||||
:disabled="deleteBusy"
|
||||
@change="emit('toggleBookmark', bookmark.url)"
|
||||
/>
|
||||
<span class="custom-checkbox" :class="{ checked: isSelected(bookmark.url) }" 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="row-cell primary-cell">
|
||||
<strong :title="bookmark.title">{{ bookmark.title }}</strong>
|
||||
</div>
|
||||
@@ -31,6 +92,14 @@ const emit = defineEmits<{
|
||||
<span>View</span>
|
||||
<span class="badge neutral">{{ bookmark.profileIds.length }}</span>
|
||||
</button>
|
||||
<button
|
||||
class="danger-button inline-danger-button"
|
||||
type="button"
|
||||
:disabled="deleteBusy"
|
||||
@click="emit('deleteBookmark', bookmark.url)"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
@@ -43,11 +112,21 @@ const emit = defineEmits<{
|
||||
|
||||
<style scoped>
|
||||
.table-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.bookmarks-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.data-table {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -68,7 +147,7 @@ const emit = defineEmits<{
|
||||
|
||||
.bookmarks-grid {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(180px, 0.9fr) minmax(260px, 1.2fr) 154px;
|
||||
grid-template-columns: 52px minmax(180px, 0.9fr) minmax(260px, 1.2fr) 250px;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
}
|
||||
@@ -102,6 +181,79 @@ const emit = defineEmits<{
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.toolbar-checkbox {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
color: var(--text);
|
||||
font-size: 0.88rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.toolbar-checkbox.disabled {
|
||||
opacity: 0.55;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.native-checkbox {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.table-checkbox {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.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);
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.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-row {
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.12);
|
||||
@@ -153,20 +305,32 @@ const emit = defineEmits<{
|
||||
.actions-cell {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.checkbox-cell {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.inline-danger-button {
|
||||
padding: 6px 10px;
|
||||
border-radius: 10px;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.bookmarks-grid {
|
||||
grid-template-columns: minmax(160px, 0.9fr) minmax(200px, 1fr) 148px;
|
||||
grid-template-columns: 52px minmax(160px, 0.9fr) minmax(200px, 1fr) 236px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
.bookmarks-grid {
|
||||
grid-template-columns: minmax(0, 1fr) 132px;
|
||||
grid-template-columns: 52px minmax(0, 1fr) 152px;
|
||||
}
|
||||
|
||||
.bookmarks-grid > :nth-child(2) {
|
||||
.bookmarks-grid > :nth-child(3) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,11 +8,13 @@ import type {
|
||||
ExtensionSortKey,
|
||||
CleanupHistoryResult,
|
||||
ExtensionAssociatedProfileSummary,
|
||||
RemoveBookmarkResult,
|
||||
PasswordSiteSortKey,
|
||||
ProfileSortKey,
|
||||
RemoveExtensionResult,
|
||||
} from "../../types/browser";
|
||||
import AssociatedProfilesModal from "./AssociatedProfilesModal.vue";
|
||||
import BookmarkRemovalModal from "./BookmarkRemovalModal.vue";
|
||||
import BookmarksList from "./BookmarksList.vue";
|
||||
import ExtensionRemovalModal from "./ExtensionRemovalModal.vue";
|
||||
import ExtensionsList from "./ExtensionsList.vue";
|
||||
@@ -38,6 +40,14 @@ defineProps<{
|
||||
historyCleanupResultOpen: boolean;
|
||||
cleanupHistoryError: string;
|
||||
cleanupHistoryResults: CleanupHistoryResult[];
|
||||
bookmarkSelectedUrls: string[];
|
||||
bookmarkModalSelectedProfileIds: string[];
|
||||
bookmarkDeleteBusy: boolean;
|
||||
bookmarkRemovalConfirmBookmarkCount: number;
|
||||
bookmarkRemovalConfirmProfileCount: number;
|
||||
bookmarkRemovalResultOpen: boolean;
|
||||
bookmarkRemovalError: string;
|
||||
bookmarkRemovalResults: RemoveBookmarkResult[];
|
||||
extensionSelectedIds: string[];
|
||||
extensionModalSelectedProfileIds: string[];
|
||||
extensionDeleteBusy: boolean;
|
||||
@@ -61,6 +71,7 @@ defineProps<{
|
||||
isBookmark: boolean;
|
||||
isExtension?: boolean;
|
||||
extensionId?: string;
|
||||
bookmarkUrl?: string;
|
||||
} | null;
|
||||
}>();
|
||||
|
||||
@@ -74,6 +85,17 @@ const emit = defineEmits<{
|
||||
showExtensionProfiles: [extensionId: string];
|
||||
showBookmarkProfiles: [url: string];
|
||||
showPasswordSiteProfiles: [url: string];
|
||||
toggleBookmarkSelection: [url: string];
|
||||
toggleAllBookmarks: [];
|
||||
deleteBookmarkFromAllProfiles: [url: string];
|
||||
deleteSelectedBookmarks: [];
|
||||
toggleBookmarkModalProfileSelection: [profileId: string];
|
||||
toggleAllBookmarkModalProfiles: [];
|
||||
deleteBookmarkFromProfile: [profileId: string];
|
||||
deleteSelectedBookmarkProfiles: [];
|
||||
confirmBookmarkRemoval: [];
|
||||
closeBookmarkRemovalConfirm: [];
|
||||
closeBookmarkRemovalResult: [];
|
||||
toggleExtensionSelection: [extensionId: string];
|
||||
toggleAllExtensions: [];
|
||||
deleteExtensionFromAllProfiles: [extensionId: string];
|
||||
@@ -177,8 +199,14 @@ const emit = defineEmits<{
|
||||
v-else-if="activeSection === 'bookmarks'"
|
||||
:bookmarks="sortedBookmarks"
|
||||
:sort-key="bookmarkSortKey"
|
||||
:selected-bookmark-urls="bookmarkSelectedUrls"
|
||||
:delete-busy="bookmarkDeleteBusy"
|
||||
@update:sort-key="emit('update:bookmarkSortKey', $event)"
|
||||
@show-profiles="emit('showBookmarkProfiles', $event)"
|
||||
@toggle-bookmark="emit('toggleBookmarkSelection', $event)"
|
||||
@toggle-all-bookmarks="emit('toggleAllBookmarks')"
|
||||
@delete-bookmark="emit('deleteBookmarkFromAllProfiles', $event)"
|
||||
@delete-selected="emit('deleteSelectedBookmarks')"
|
||||
/>
|
||||
|
||||
<PasswordSitesList
|
||||
@@ -223,6 +251,29 @@ const emit = defineEmits<{
|
||||
@close="emit('closeHistoryCleanupResult')"
|
||||
/>
|
||||
|
||||
<BookmarkRemovalModal
|
||||
v-if="bookmarkRemovalConfirmBookmarkCount > 0"
|
||||
mode="confirm"
|
||||
title="Confirm Bookmark Removal"
|
||||
:bookmark-count="bookmarkRemovalConfirmBookmarkCount"
|
||||
:profile-count="bookmarkRemovalConfirmProfileCount"
|
||||
:results="[]"
|
||||
:busy="bookmarkDeleteBusy"
|
||||
@close="emit('closeBookmarkRemovalConfirm')"
|
||||
@confirm="emit('confirmBookmarkRemoval')"
|
||||
/>
|
||||
|
||||
<BookmarkRemovalModal
|
||||
v-if="bookmarkRemovalResultOpen"
|
||||
mode="result"
|
||||
title="Bookmark Removal Result"
|
||||
:bookmark-count="0"
|
||||
:profile-count="0"
|
||||
:results="bookmarkRemovalResults"
|
||||
:general-error="bookmarkRemovalError"
|
||||
@close="emit('closeBookmarkRemovalResult')"
|
||||
/>
|
||||
|
||||
<ExtensionRemovalModal
|
||||
v-if="extensionRemovalConfirmExtensions.length || extensionRemovalConfirmProfiles.length"
|
||||
mode="confirm"
|
||||
@@ -254,15 +305,35 @@ const emit = defineEmits<{
|
||||
:browser-family-id="currentBrowser.browserFamilyId"
|
||||
:is-bookmark="associatedProfilesModal.isBookmark"
|
||||
:is-extension="associatedProfilesModal.isExtension"
|
||||
:selected-profile-ids="extensionModalSelectedProfileIds"
|
||||
:delete-busy="extensionDeleteBusy"
|
||||
:selected-profile-ids="
|
||||
associatedProfilesModal.isExtension
|
||||
? extensionModalSelectedProfileIds
|
||||
: bookmarkModalSelectedProfileIds
|
||||
"
|
||||
:delete-busy="associatedProfilesModal.isExtension ? extensionDeleteBusy : bookmarkDeleteBusy"
|
||||
:is-opening-profile="isOpeningProfile"
|
||||
@close="emit('closeAssociatedProfiles')"
|
||||
@open-profile="(browserId, profileId) => emit('openProfile', browserId, profileId)"
|
||||
@toggle-profile-selection="emit('toggleExtensionModalProfileSelection', $event)"
|
||||
@toggle-all-profile-selection="emit('toggleAllExtensionModalProfiles')"
|
||||
@delete-profile="emit('deleteExtensionFromProfile', $event)"
|
||||
@delete-selected-profiles="emit('deleteSelectedExtensionProfiles')"
|
||||
@toggle-profile-selection="
|
||||
associatedProfilesModal.isExtension
|
||||
? emit('toggleExtensionModalProfileSelection', $event)
|
||||
: emit('toggleBookmarkModalProfileSelection', $event)
|
||||
"
|
||||
@toggle-all-profile-selection="
|
||||
associatedProfilesModal.isExtension
|
||||
? emit('toggleAllExtensionModalProfiles')
|
||||
: emit('toggleAllBookmarkModalProfiles')
|
||||
"
|
||||
@delete-profile="
|
||||
associatedProfilesModal.isExtension
|
||||
? emit('deleteExtensionFromProfile', $event)
|
||||
: emit('deleteBookmarkFromProfile', $event)
|
||||
"
|
||||
@delete-selected-profiles="
|
||||
associatedProfilesModal.isExtension
|
||||
? emit('deleteSelectedExtensionProfiles')
|
||||
: emit('deleteSelectedBookmarkProfiles')
|
||||
"
|
||||
/>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user