mirror of
https://github.com/directus/directus.git
synced 2026-04-03 03:00:39 -04:00
Bookmark improvements (#12031)
* add icon & color to bookmarks * update current bookmark title on edit * clean up edit bookmark dialog on cancel * remove unused bookmark-edit component * interaction improvements * sort based on scope and alphabetically * prevent hover when locked & use tooltip * Reduce size of right hand icon in bookmark Co-authored-by: rijkvanzanten <rijkvanzanten@me.com>
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
import { Knex } from 'knex';
|
||||
|
||||
export async function up(knex: Knex): Promise<void> {
|
||||
await knex.schema.alterTable('directus_presets', (table) => {
|
||||
table.string('icon', 30).notNullable().defaultTo('bookmark_outline');
|
||||
table.string('color').nullable();
|
||||
});
|
||||
}
|
||||
|
||||
export async function down(knex: Knex): Promise<void> {
|
||||
await knex.schema.alterTable('directus_presets', (table) => {
|
||||
table.dropColumn('icon');
|
||||
table.dropColumn('color');
|
||||
});
|
||||
}
|
||||
@@ -33,6 +33,12 @@ fields:
|
||||
- field: bookmark
|
||||
width: half
|
||||
|
||||
- field: icon
|
||||
width: half
|
||||
|
||||
- field: color
|
||||
width: half
|
||||
|
||||
- field: search
|
||||
width: half
|
||||
|
||||
|
||||
@@ -90,6 +90,11 @@ export function usePreset(
|
||||
initLocalPreset();
|
||||
});
|
||||
|
||||
// update current bookmark title when it is edited in navigation-bookmark
|
||||
presetsStore.$subscribe(() => {
|
||||
initLocalPreset();
|
||||
});
|
||||
|
||||
const layoutOptions = computed<Record<string, any>>({
|
||||
get() {
|
||||
return localPreset.value.layout_options?.[layout.value] || null;
|
||||
|
||||
@@ -92,11 +92,13 @@ delete_folder: Delete Folder
|
||||
prefix: Prefix
|
||||
suffix: Suffix
|
||||
reset_bookmark: Reset Bookmark
|
||||
rename_bookmark: Rename Bookmark
|
||||
update_bookmark: Update Bookmark
|
||||
delete_bookmark: Delete Bookmark
|
||||
delete_bookmark_copy: >-
|
||||
Are you sure you want to delete the "{bookmark}" bookmark? This action cannot be undone.
|
||||
delete_personal_bookmark: Delete Personal Bookmark
|
||||
delete_role_bookmark: Delete Role Bookmark
|
||||
delete_global_bookmark: Delete Global Bookmark
|
||||
logoutReason:
|
||||
SIGN_OUT: Signed out
|
||||
SESSION_EXPIRED: Session expired
|
||||
@@ -569,6 +571,11 @@ value_hashed: Value Securely Hashed
|
||||
bookmark_name: Bookmark name...
|
||||
create_bookmark: Create Bookmark
|
||||
edit_bookmark: Edit Bookmark
|
||||
edit_personal_bookmark: Edit Personal Bookmark
|
||||
edit_role_bookmark: Edit Role Bookmark
|
||||
edit_global_bookmark: Edit Global Bookmark
|
||||
cannot_edit_role_bookmarks: Can't Edit Role Bookmarks
|
||||
cannot_edit_global_bookmarks: Can't Edit Global Bookmarks
|
||||
bookmarks: Bookmarks
|
||||
presets: Presets
|
||||
unexpected_error: Unexpected Error
|
||||
|
||||
@@ -1,46 +1,64 @@
|
||||
<template>
|
||||
<v-list-item
|
||||
v-context-menu="'contextMenu'"
|
||||
:to="`/content/${bookmark.collection}?bookmark=${bookmark.id}`"
|
||||
query
|
||||
class="bookmark"
|
||||
clickable
|
||||
@contextmenu.stop=""
|
||||
>
|
||||
<v-list-item-icon><v-icon name="bookmark_outline" /></v-list-item-icon>
|
||||
<v-list-item-icon><v-icon :name="bookmark.icon" :color="bookmark.color" /></v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-text-overflow :text="bookmark.bookmark" />
|
||||
</v-list-item-content>
|
||||
|
||||
<v-menu ref="contextMenu" show-arrow placement="bottom-start">
|
||||
<v-menu placement="bottom-start" show-arrow>
|
||||
<template #activator="{ toggle }">
|
||||
<v-icon
|
||||
v-tooltip.bottom="!hasPermission && t(`cannot_edit_${scope}_bookmarks`)"
|
||||
:name="hasPermission ? 'more_vert' : 'lock'"
|
||||
:clickable="hasPermission"
|
||||
small
|
||||
class="ctx-toggle"
|
||||
@click.prevent="hasPermission ? toggle() : null"
|
||||
/>
|
||||
</template>
|
||||
<v-list>
|
||||
<v-list-item clickable :disabled="isMine === false" @click="renameActive = true">
|
||||
<v-list-item
|
||||
clickable
|
||||
:to="scope !== 'personal' ? `/settings/presets/${bookmark.id}` : undefined"
|
||||
@click="scope === 'personal' ? (editActive = true) : undefined"
|
||||
>
|
||||
<v-list-item-icon>
|
||||
<v-icon name="edit" outline />
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-text-overflow :text="t('rename_bookmark')" />
|
||||
<v-text-overflow :text="t(`edit_${scope}_bookmark`)" />
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<v-list-item clickable class="danger" :disabled="isMine === false" @click="deleteActive = true">
|
||||
<v-list-item clickable class="danger" @click="deleteActive = true">
|
||||
<v-list-item-icon>
|
||||
<v-icon name="delete" outline />
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-text-overflow :text="t('delete_bookmark')" />
|
||||
<v-text-overflow :text="t(`delete_${scope}_bookmark`)" />
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
|
||||
<v-dialog v-model="renameActive" persistent @esc="renameActive = false">
|
||||
<v-dialog v-model="editActive" persistent @esc="editCancel">
|
||||
<v-card>
|
||||
<v-card-title>{{ t('rename_bookmark') }}</v-card-title>
|
||||
<v-card-title>{{ t('edit_personal_bookmark') }}</v-card-title>
|
||||
<v-card-text>
|
||||
<v-input v-model="renameValue" autofocus @keyup.enter="renameSave" />
|
||||
<div class="fields">
|
||||
<v-input v-model="editValue.name" class="full" autofocus @keyup.enter="editSave" />
|
||||
<interface-select-icon width="half" :value="editValue.icon" @input="editValue.icon = $event" />
|
||||
<interface-select-color width="half" :value="editValue.color" @input="editValue.color = $event" />
|
||||
</div>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-button secondary @click="renameActive = false">{{ t('cancel') }}</v-button>
|
||||
<v-button :disabled="renameValue === null" :loading="renameSaving" @click="renameSave">
|
||||
<v-button secondary @click="editCancel">{{ t('cancel') }}</v-button>
|
||||
<v-button :disabled="editValue.name === null" :loading="editSaving" @click="editSave">
|
||||
{{ t('save') }}
|
||||
</v-button>
|
||||
</v-card-actions>
|
||||
@@ -63,7 +81,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { defineComponent, PropType, ref, computed } from 'vue';
|
||||
import { defineComponent, PropType, ref, computed, reactive } from 'vue';
|
||||
import { Preset } from '@directus/shared/types';
|
||||
import { useUserStore, usePresetsStore } from '@/stores';
|
||||
import { unexpectedError } from '@/utils/unexpected-error';
|
||||
@@ -82,58 +100,80 @@ export default defineComponent({
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
const userStore = useUserStore();
|
||||
const { currentUser, isAdmin } = useUserStore();
|
||||
const presetsStore = usePresetsStore();
|
||||
|
||||
const isMine = computed(() => props.bookmark.user === userStore.currentUser!.id);
|
||||
const isMine = computed(() => props.bookmark.user === currentUser!.id);
|
||||
|
||||
const { renameActive, renameValue, renameSave, renameSaving } = useRenameBookmark();
|
||||
const { deleteActive, deleteValue, deleteSave, deleteSaving } = useDeleteBookmark();
|
||||
const hasPermission = computed(() => isMine.value || isAdmin);
|
||||
|
||||
const scope = computed(() => {
|
||||
if (props.bookmark.user && !props.bookmark.role) return 'personal';
|
||||
if (!props.bookmark.user && props.bookmark.role) return 'role';
|
||||
return 'global';
|
||||
});
|
||||
|
||||
const { editActive, editValue, editSave, editSaving, editCancel } = useEditBookmark();
|
||||
const { deleteActive, deleteSave, deleteSaving } = useDeleteBookmark();
|
||||
|
||||
return {
|
||||
t,
|
||||
isMine,
|
||||
renameActive,
|
||||
renameValue,
|
||||
renameSave,
|
||||
renameSaving,
|
||||
hasPermission,
|
||||
scope,
|
||||
editActive,
|
||||
editValue,
|
||||
editSave,
|
||||
editSaving,
|
||||
editCancel,
|
||||
deleteActive,
|
||||
deleteValue,
|
||||
deleteSave,
|
||||
deleteSaving,
|
||||
};
|
||||
|
||||
function useRenameBookmark() {
|
||||
const renameActive = ref(false);
|
||||
const renameValue = ref(props.bookmark.bookmark);
|
||||
const renameSaving = ref(false);
|
||||
function useEditBookmark() {
|
||||
const editActive = ref(false);
|
||||
const editValue = reactive({
|
||||
name: props.bookmark.bookmark,
|
||||
icon: props.bookmark?.icon ?? 'bookmark_outline',
|
||||
color: props.bookmark?.color ?? null,
|
||||
});
|
||||
const editSaving = ref(false);
|
||||
|
||||
return { renameActive, renameValue, renameSave, renameSaving };
|
||||
return { editActive, editValue, editSave, editSaving, editCancel };
|
||||
|
||||
async function renameSave() {
|
||||
renameSaving.value = true;
|
||||
async function editSave() {
|
||||
editSaving.value = true;
|
||||
|
||||
try {
|
||||
await presetsStore.savePreset({
|
||||
...props.bookmark,
|
||||
bookmark: renameValue.value,
|
||||
bookmark: editValue.name,
|
||||
icon: editValue.icon,
|
||||
color: editValue.color,
|
||||
});
|
||||
|
||||
renameActive.value = false;
|
||||
editActive.value = false;
|
||||
} catch (err: any) {
|
||||
unexpectedError(err);
|
||||
} finally {
|
||||
renameSaving.value = false;
|
||||
editSaving.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function editCancel() {
|
||||
editActive.value = false;
|
||||
editValue.name = props.bookmark.bookmark;
|
||||
editValue.icon = props.bookmark?.icon ?? 'bookmark_outline';
|
||||
editValue.color = props.bookmark?.color ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
function useDeleteBookmark() {
|
||||
const deleteActive = ref(false);
|
||||
const deleteValue = ref(props.bookmark.bookmark);
|
||||
const deleteSaving = ref(false);
|
||||
|
||||
return { deleteActive, deleteValue, deleteSave, deleteSaving };
|
||||
return { deleteActive, deleteSave, deleteSaving };
|
||||
|
||||
async function deleteSave() {
|
||||
deleteSaving.value = true;
|
||||
@@ -141,7 +181,7 @@ export default defineComponent({
|
||||
try {
|
||||
let navigateTo: string | null = null;
|
||||
|
||||
if (+route.query?.bookmark === props.bookmark.id) {
|
||||
if (route.query?.bookmark && +route.query.bookmark === props.bookmark.id) {
|
||||
navigateTo = `/content/${props.bookmark.collection}`;
|
||||
}
|
||||
|
||||
@@ -167,4 +207,31 @@ export default defineComponent({
|
||||
--v-list-item-color: var(--danger);
|
||||
--v-list-item-icon-color: var(--danger);
|
||||
}
|
||||
|
||||
.v-list-item {
|
||||
.ctx-toggle {
|
||||
--v-icon-color: var(--foreground-subdued);
|
||||
|
||||
opacity: 0;
|
||||
user-select: none;
|
||||
transition: opacity var(--fast) var(--transition);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.ctx-toggle {
|
||||
opacity: 1;
|
||||
user-select: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fields {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 12px;
|
||||
|
||||
.full {
|
||||
grid-column: 1 / span 2;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -282,7 +282,6 @@ import RefreshSidebarDetail from '@/views/private/components/refresh-sidebar-det
|
||||
import ExportSidebarDetail from '@/views/private/components/export-sidebar-detail.vue';
|
||||
import SearchInput from '@/views/private/components/search-input';
|
||||
import BookmarkAdd from '@/views/private/components/bookmark-add';
|
||||
import BookmarkEdit from '@/views/private/components/bookmark-edit';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { usePermissionsStore, useUserStore } from '@/stores';
|
||||
import DrawerBatch from '@/views/private/components/drawer-batch';
|
||||
@@ -303,7 +302,6 @@ export default defineComponent({
|
||||
LayoutSidebarDetail,
|
||||
SearchInput,
|
||||
BookmarkAdd,
|
||||
BookmarkEdit,
|
||||
DrawerBatch,
|
||||
ArchiveSidebarDetail,
|
||||
RefreshSidebarDetail,
|
||||
@@ -372,7 +370,7 @@ export default defineComponent({
|
||||
batchEditActive,
|
||||
} = useBatch();
|
||||
|
||||
const { bookmarkDialogActive, creatingBookmark, createBookmark, editingBookmark, editBookmark } = useBookmarks();
|
||||
const { bookmarkDialogActive, creatingBookmark, createBookmark } = useBookmarks();
|
||||
|
||||
const currentLayout = computed(() => layouts.value.find((l) => l.id === layout.value));
|
||||
|
||||
@@ -447,8 +445,6 @@ export default defineComponent({
|
||||
creatingBookmark,
|
||||
createBookmark,
|
||||
bookmarkTitle,
|
||||
editingBookmark,
|
||||
editBookmark,
|
||||
breadcrumb,
|
||||
clearFilters,
|
||||
confirmArchive,
|
||||
@@ -583,21 +579,22 @@ export default defineComponent({
|
||||
function useBookmarks() {
|
||||
const bookmarkDialogActive = ref(false);
|
||||
const creatingBookmark = ref(false);
|
||||
const editingBookmark = ref(false);
|
||||
|
||||
return {
|
||||
bookmarkDialogActive,
|
||||
creatingBookmark,
|
||||
createBookmark,
|
||||
editingBookmark,
|
||||
editBookmark,
|
||||
};
|
||||
|
||||
async function createBookmark(name: string) {
|
||||
async function createBookmark(bookmark: any) {
|
||||
creatingBookmark.value = true;
|
||||
|
||||
try {
|
||||
const newBookmark = await saveCurrentAsBookmark({ bookmark: name });
|
||||
const newBookmark = await saveCurrentAsBookmark({
|
||||
bookmark: bookmark.name,
|
||||
icon: bookmark.icon,
|
||||
color: bookmark.color,
|
||||
});
|
||||
router.push(`/content/${newBookmark.collection}?bookmark=${newBookmark.id}`);
|
||||
|
||||
bookmarkDialogActive.value = false;
|
||||
@@ -607,11 +604,6 @@ export default defineComponent({
|
||||
creatingBookmark.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function editBookmark(name: string) {
|
||||
bookmarkTitle.value = name;
|
||||
bookmarkDialogActive.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function clearFilters() {
|
||||
|
||||
@@ -242,6 +242,8 @@ export default defineComponent({
|
||||
|
||||
if (edits.value.name) editsParsed.bookmark = edits.value.name;
|
||||
if (edits.value.name?.length === 0) editsParsed.bookmark = null;
|
||||
if (edits.value.icon) editsParsed.icon = edits.value.icon;
|
||||
if (edits.value.color) editsParsed.color = edits.value.color;
|
||||
if (edits.value.collection) editsParsed.collection = edits.value.collection;
|
||||
if (edits.value.layout) editsParsed.layout = edits.value.layout;
|
||||
if (edits.value.layout_query) editsParsed.layout_query = edits.value.layout_query;
|
||||
@@ -332,6 +334,8 @@ export default defineComponent({
|
||||
collection: preset.value.collection,
|
||||
layout: preset.value.layout,
|
||||
name: preset.value.bookmark,
|
||||
icon: preset.value.icon,
|
||||
color: preset.value.color,
|
||||
search: preset.value.search,
|
||||
scope: scope,
|
||||
layout_query: preset.value.layout_query,
|
||||
@@ -517,6 +521,27 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'icon',
|
||||
name: '$t:icon',
|
||||
type: 'string',
|
||||
meta: {
|
||||
interface: 'select-icon',
|
||||
width: 'half',
|
||||
},
|
||||
schema: {
|
||||
default_value: 'bookmark_outline',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'color',
|
||||
name: '$t:color',
|
||||
type: 'string',
|
||||
meta: {
|
||||
interface: 'select-color',
|
||||
width: 'half',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'search',
|
||||
name: t('search'),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import api from '@/api';
|
||||
import { useUserStore } from '@/stores/';
|
||||
import { Preset } from '@directus/shared/types';
|
||||
import { cloneDeep, merge } from 'lodash';
|
||||
import { cloneDeep, merge, orderBy } from 'lodash';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
@@ -122,7 +122,14 @@ export const usePresetsStore = defineStore({
|
||||
}),
|
||||
getters: {
|
||||
bookmarks(): Preset[] {
|
||||
return this.collectionPresets.filter((preset) => preset.bookmark !== null);
|
||||
return orderBy(
|
||||
this.collectionPresets.filter((preset) => preset.bookmark !== null),
|
||||
[
|
||||
(preset) => preset.user === null && preset.role === null,
|
||||
(preset) => preset.user === null && preset.role !== null,
|
||||
'bookmark',
|
||||
]
|
||||
);
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
|
||||
@@ -8,23 +8,25 @@
|
||||
<v-card-title>{{ t('create_bookmark') }}</v-card-title>
|
||||
|
||||
<v-card-text>
|
||||
<v-input
|
||||
v-model="bookmarkName"
|
||||
autofocus
|
||||
:placeholder="t('bookmark_name')"
|
||||
@keyup.enter="$emit('save', bookmarkName)"
|
||||
/>
|
||||
<div class="fields">
|
||||
<v-input
|
||||
v-model="bookmarkValue.name"
|
||||
class="full"
|
||||
autofocus
|
||||
trim
|
||||
:placeholder="t('bookmark_name')"
|
||||
@keyup.enter="$emit('save', bookmarkValue)"
|
||||
/>
|
||||
<interface-select-icon width="half" :value="bookmarkValue.icon" @input="setIcon" />
|
||||
<interface-select-color width="half" :value="bookmarkValue.color" @input="setColor" />
|
||||
</div>
|
||||
</v-card-text>
|
||||
|
||||
<v-card-actions>
|
||||
<v-button secondary @click="cancel">
|
||||
{{ t('cancel') }}
|
||||
</v-button>
|
||||
<v-button
|
||||
:disabled="bookmarkName === null || bookmarkName.length === 0"
|
||||
:loading="saving"
|
||||
@click="$emit('save', bookmarkName)"
|
||||
>
|
||||
<v-button :disabled="bookmarkValue.name === null" :loading="saving" @click="$emit('save', bookmarkValue)">
|
||||
{{ t('save') }}
|
||||
</v-button>
|
||||
</v-card-actions>
|
||||
@@ -34,7 +36,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import { defineComponent, reactive } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
@@ -51,14 +53,40 @@ export default defineComponent({
|
||||
setup(props, { emit }) {
|
||||
const { t } = useI18n();
|
||||
|
||||
const bookmarkName = ref(null);
|
||||
const bookmarkValue = reactive({
|
||||
name: null,
|
||||
icon: 'bookmark_outline',
|
||||
color: null,
|
||||
});
|
||||
|
||||
return { t, bookmarkName, cancel };
|
||||
return { t, bookmarkValue, setIcon, setColor, cancel };
|
||||
|
||||
function setIcon(icon: any) {
|
||||
bookmarkValue.icon = icon;
|
||||
}
|
||||
|
||||
function setColor(color: any) {
|
||||
bookmarkValue.color = color;
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
bookmarkName.value = null;
|
||||
bookmarkValue.name = null;
|
||||
bookmarkValue.icon = 'bookmark_outline';
|
||||
bookmarkValue.color = null;
|
||||
emit('update:modelValue', false);
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.fields {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 12px;
|
||||
|
||||
.full {
|
||||
grid-column: 1 / span 2;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
<template>
|
||||
<v-dialog :model-value="modelValue" persistent @update:model-value="$emit('update:modelValue', $event)" @esc="cancel">
|
||||
<template #activator="slotBinding">
|
||||
<slot name="activator" v-bind="slotBinding" />
|
||||
</template>
|
||||
|
||||
<v-card>
|
||||
<v-card-title>{{ t('edit_bookmark') }}</v-card-title>
|
||||
|
||||
<v-card-text>
|
||||
<v-input
|
||||
v-model="bookmarkName"
|
||||
autofocus
|
||||
:placeholder="t('bookmark_name')"
|
||||
@keyup.enter="$emit('save', bookmarkName)"
|
||||
/>
|
||||
</v-card-text>
|
||||
|
||||
<v-card-actions>
|
||||
<v-button secondary @click="cancel">
|
||||
{{ t('cancel') }}
|
||||
</v-button>
|
||||
<v-button
|
||||
:disabled="bookmarkName === null || bookmarkName.length === 0"
|
||||
:loading="saving"
|
||||
@click="$emit('save', bookmarkName)"
|
||||
>
|
||||
{{ t('save') }}
|
||||
</v-button>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { defineComponent, ref, watch } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
saving: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
emits: ['save', 'update:modelValue'],
|
||||
setup(props, { emit }) {
|
||||
const { t } = useI18n();
|
||||
|
||||
const bookmarkName = ref(props.name);
|
||||
|
||||
watch(
|
||||
() => props.name,
|
||||
(newName: string) => (bookmarkName.value = newName)
|
||||
);
|
||||
|
||||
return { t, bookmarkName, cancel };
|
||||
|
||||
function cancel() {
|
||||
emit('update:modelValue', false);
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@@ -1,4 +0,0 @@
|
||||
import BookmarkEdit from './bookmark-edit.vue';
|
||||
|
||||
export { BookmarkEdit };
|
||||
export default BookmarkEdit;
|
||||
@@ -3,6 +3,8 @@ import { Filter } from './filter';
|
||||
export type Preset = {
|
||||
id?: number;
|
||||
bookmark: string | null;
|
||||
icon: string;
|
||||
color?: string | null;
|
||||
user: string | null;
|
||||
role: string | null;
|
||||
collection: string;
|
||||
|
||||
Reference in New Issue
Block a user