Merge pull request #69 from directus/tooltips

Action button tooltips
This commit is contained in:
Rijk van Zanten
2020-08-06 16:07:32 -04:00
committed by GitHub
25 changed files with 82 additions and 65 deletions

View File

@@ -17,6 +17,7 @@ module.exports = {
'@typescript-eslint/no-use-before-define': 0,
'@typescript-eslint/ban-ts-ignore': 0,
'@typescript-eslint/no-explicit-any': 0,
'vue/valid-v-slot': 0,
'comma-dangle': [
'error',
{

View File

@@ -17,7 +17,7 @@ export function useItem(collection: Ref<string>, primaryKey: Ref<string | number
const edits = ref({});
const isNew = computed(() => primaryKey.value === '+');
const isBatch = computed(() => typeof primaryKey.value === 'string' && primaryKey.value.includes(','));
const isSingle = computed(() => !!collectionInfo.value?.system?.single);
const isSingle = computed(() => !!collectionInfo.value?.meta?.single);
const endpoint = computed(() => {
return collection.value.startsWith('directus_')

View File

@@ -4,20 +4,31 @@ import { nanoid } from 'nanoid';
const handlers: Record<string, () => void> = {};
function bind(element: HTMLElement, binding: DirectiveBinding) {
element.dataset.tooltip = nanoid();
handlers[element.dataset.tooltip] = createEnterHandler(element, binding);
element.addEventListener('mouseenter', handlers[element.dataset.tooltip]);
element.addEventListener('mouseleave', onLeaveTooltip);
}
function unbind(element: HTMLElement) {
element.removeEventListener('mouseenter', handlers[element.dataset.tooltip as string]);
element.removeEventListener('mouseleave', onLeaveTooltip);
clearTimeout(tooltipTimer);
const tooltip = getTooltip();
tooltip.classList.remove('visible');
delete handlers[element.dataset.tooltip as string];
}
const Tooltip: DirectiveOptions = {
bind(element, binding) {
element.dataset.tooltip = nanoid();
handlers[element.dataset.tooltip] = createEnterHandler(element, binding);
element.addEventListener('mouseenter', handlers[element.dataset.tooltip]);
element.addEventListener('mouseleave', onLeaveTooltip);
},
unbind(element) {
element.removeEventListener('mouseenter', handlers[element.dataset.tooltip as string]);
element.removeEventListener('mouseleave', onLeaveTooltip);
clearTimeout(tooltipTimer);
const tooltip = getTooltip();
tooltip.classList.remove('visible');
delete handlers[element.dataset.tooltip as string];
bind, unbind,
update(element, binding) {
if (binding.value && !binding.oldValue) {
bind(element, binding);
} else if (!binding.value && binding.oldValue) {
unbind(element);
}
}
};

View File

@@ -361,7 +361,7 @@ export default defineComponent({
function usePreview() {
const displayTemplate = computed(() => {
if (props.template !== null) return props.template;
return collectionInfo.value?.system?.display_template;
return collectionInfo.value?.meta?.display_template;
});
const requiredFields = computed(() => {

View File

@@ -10,6 +10,10 @@
"only_show_the_file_extension": "Only show the file extension",
"textarea": "Textarea",
"add_preset": "Add Preset",
"add_role": "Add Role",
"add_user": "Add User",
"uploaded_by": "Uploaded By",
"hide_field_on_detail": "Hide Field on Detail",
"show_field_on_detail": "Show Field on Detail",

View File

@@ -38,7 +38,7 @@ export default function useNavigation() {
const navItem: NavItem = {
collection: collection,
name: collectionInfo.name,
icon: collectionInfo.system?.icon || 'box',
icon: collectionInfo.meta?.icon || 'box',
to: `/collections/${collection}`,
};
@@ -57,7 +57,7 @@ export default function useNavigation() {
const navItem: NavItem = {
collection: collection.collection,
name: collection.name,
icon: collection.system?.icon || 'box',
icon: collection.meta?.icon || 'box',
to: `/collections/${collection.collection}`,
};

View File

@@ -26,7 +26,7 @@ export default defineComponent({
const isSingle = computed(() => {
const collectionInfo = collectionsStore.getCollection(props.collection);
return !!collectionInfo?.system?.single === true;
return !!collectionInfo?.meta?.single === true;
});
return { component, isSingle };

View File

@@ -48,7 +48,7 @@
<v-dialog v-model="confirmDelete" v-if="selection.length > 0">
<template #activator="{ on }">
<v-button rounded icon class="action-delete" @click="on">
<v-button rounded icon class="action-delete" @click="on" v-tooltip.bottom="$t('delete')">
<v-icon name="delete" />
</v-button>
</template>
@@ -67,11 +67,11 @@
</v-card>
</v-dialog>
<v-button rounded icon class="action-batch" v-if="selection.length > 1" :to="batchLink">
<v-button rounded icon class="action-batch" v-if="selection.length > 1" :to="batchLink" v-tooltip.bottom="$t('edit')">
<v-icon name="edit" />
</v-button>
<v-button rounded icon :to="addNewLink">
<v-button rounded icon :to="addNewLink" v-tooltip.bottom="$t('add_new')">
<v-icon name="add" />
</v-button>
</template>

View File

@@ -105,7 +105,7 @@
<template #append-outer>
<save-options
v-if="collectionInfo.single === false"
v-if="collectionInfo.single !== true"
:disabled="hasEdits === false"
@save-and-stay="saveAndStay"
@save-and-add-new="saveAndAddNew"

View File

@@ -1,7 +1,7 @@
<template>
<v-dialog v-model="dialogActive">
<template #activator="{ on }">
<v-button rounded icon class="add-new" @click="on">
<v-button rounded icon class="add-new" @click="on" v-tooltip.bottom="$t('add_new_folder')">
<v-icon name="create_new_folder" />
</v-button>
</template>

View File

@@ -17,7 +17,7 @@
<v-dialog v-model="moveToDialogActive" v-if="selection.length > 0">
<template #activator="{ on }">
<v-button rounded icon @click="on" class="folder">
<v-button rounded icon @click="on" class="folder" v-tooltip.bottom="$t('move_to_folder')">
<v-icon name="folder_move" />
</v-button>
</template>
@@ -42,7 +42,7 @@
<v-dialog v-model="confirmDelete" v-if="selection.length > 0">
<template #activator="{ on }">
<v-button rounded icon class="action-delete" @click="on">
<v-button rounded icon class="action-delete" @click="on" v-tooltip.bottom="$t('delete')">
<v-icon name="delete" />
</v-button>
</template>
@@ -61,11 +61,11 @@
</v-card>
</v-dialog>
<v-button rounded icon class="action-batch" v-if="selection.length > 1" :to="batchLink">
<v-button rounded icon class="action-batch" v-if="selection.length > 1" :to="batchLink" v-tooltip.bottom="$t('edit')">
<v-icon name="edit" />
</v-button>
<v-button rounded icon class="add-new" to="/files/+">
<v-button rounded icon class="add-new" to="/files/+" v-tooltip.bottom="$t('add_new_file')">
<v-icon name="add" />
</v-button>
</template>

View File

@@ -14,7 +14,7 @@
<template #actions>
<v-dialog v-model="confirmDelete">
<template #activator="{ on }">
<v-button rounded icon class="action-delete" :disabled="item === null" @click="on">
<v-button rounded icon class="action-delete" :disabled="item === null" @click="on" v-tooltip.bottom="$t('delete')">
<v-icon name="delete" />
</v-button>
</template>
@@ -35,7 +35,7 @@
<v-dialog v-model="moveToDialogActive" v-if="isNew === false">
<template #activator="{ on }">
<v-button rounded icon :disabled="item === null" @click="on" class="folder">
<v-button rounded icon :disabled="item === null" @click="on" class="folder" v-tooltip.bottom="$t('move_to_folder')">
<v-icon name="folder_move" />
</v-button>
</template>
@@ -58,11 +58,11 @@
</v-card>
</v-dialog>
<v-button v-if="item && item.type.includes('image')" rounded icon @click="editActive = true" class="edit">
<v-button v-if="item && item.type.includes('image')" rounded icon @click="editActive = true" class="edit" v-tooltip.bottom="$t('edit')">
<v-icon name="tune" />
</v-button>
<v-button rounded icon :loading="saving" :disabled="hasEdits === false" @click="saveAndQuit">
<v-button rounded icon :loading="saving" :disabled="hasEdits === false" @click="saveAndQuit" v-tooltip.bottom="$t('save')">
<v-icon name="check" />
<template #append-outer>

View File

@@ -9,7 +9,7 @@
</template>
<template #actions>
<v-button rounded icon to="/settings/data-model/+">
<v-button rounded icon to="/settings/data-model/+" v-tooltip.bottom="$t('create_collection')">
<v-icon name="add" />
</v-button>
</template>
@@ -41,7 +41,7 @@
class="icon"
:class="{
hidden: item.hidden,
system: item.collection.startsWith('directus_'),
meta: item.collection.startsWith('directus_'),
unmanaged: item.managed === false && item.collection.startsWith('directus_') === false,
}"
:name="item.icon"
@@ -53,7 +53,7 @@
class="collection"
:class="{
hidden: item.hidden,
system: item.collection.startsWith('directus_'),
meta: item.collection.startsWith('directus_'),
unmanaged: item.managed === false && item.collection.startsWith('directus_') === false,
}"
>
@@ -144,7 +144,7 @@ export default defineComponent({
return sortBy(
collectionsStore.state.collections.filter(
(collection) =>
collection.collection.startsWith('directus_') === false && collection.system?.hidden === false
collection.collection.startsWith('directus_') === false && collection.meta?.hidden === false
),
'collection'
);
@@ -155,14 +155,14 @@ export default defineComponent({
collectionsStore.state.collections
.filter(
(collection) =>
collection.collection.startsWith('directus_') === false && collection.system?.hidden === true
collection.collection.startsWith('directus_') === false && collection.meta?.hidden === true
)
.map((collection) => ({ ...collection, icon: 'visibility_off' })),
'collection'
);
});
const system = computed(() => {
const meta = computed(() => {
return sortBy(
collectionsStore.state.collections
.filter((collection) => collection.collection.startsWith('directus_') === true)
@@ -175,7 +175,7 @@ export default defineComponent({
return sortBy(
collectionsStore.state.collections
.filter((collection) => collection.collection.startsWith('directus_') === false)
.filter((collection) => collection.system === null),
.filter((collection) => collection.meta === null),
'collection'
);
});
@@ -195,8 +195,8 @@ export default defineComponent({
items.push(unmanaged.value);
}
if (activeTypes.value.includes('system')) {
items.push(system.value);
if (activeTypes.value.includes('meta')) {
items.push(meta.value);
}
return items.flat();
@@ -217,7 +217,7 @@ export default defineComponent({
color: var(--foreground-subdued);
}
.system {
.meta {
color: var(--primary);
}

View File

@@ -10,7 +10,7 @@
<template #actions>
<v-dialog v-model="confirmDelete">
<template #activator="{ on }">
<v-button rounded icon class="action-delete" :disabled="item === null" @click="on">
<v-button rounded icon class="action-delete" :disabled="item === null" @click="on" v-tooltip.bottom="$t('delete_collection')">
<v-icon name="delete" />
</v-button>
</template>
@@ -29,7 +29,7 @@
</v-card>
</v-dialog>
<v-button rounded icon :loading="saving" :disabled="hasEdits === false" @click="saveAndQuit">
<v-button rounded icon :loading="saving" :disabled="hasEdits === false" @click="saveAndQuit" v-tooltip.bottom="$t('save')">
<v-icon name="check" />
</v-button>
</template>
@@ -52,10 +52,10 @@
<v-form
collection="directus_collections"
:loading="loading"
:initial-values="item && item.system"
:initial-values="item && item.meta"
:batch-mode="isBatch"
:primary-key="collection"
v-model="edits.system"
v-model="edits.meta"
/>
</div>

View File

@@ -11,7 +11,7 @@
<template #actions>
<v-dialog v-model="confirmDelete" v-if="selection.length > 0">
<template #activator="{ on }">
<v-button rounded icon class="action-delete" @click="on">
<v-button rounded icon class="action-delete" @click="on" v-tooltip.bottom="$t('delete')">
<v-icon name="delete" />
</v-button>
</template>
@@ -30,7 +30,7 @@
</v-card>
</v-dialog>
<v-button rounded icon :to="addNewLink">
<v-button rounded icon :to="addNewLink" v-tooltip.bottom="$t('add_preset')">
<v-icon name="add" />
</v-button>
</template>

View File

@@ -14,7 +14,7 @@
<template #actions>
<v-dialog v-model="confirmDelete">
<template #activator="{ on }">
<v-button rounded icon class="action-delete" :disabled="preset === null || id === '+'" @click="on">
<v-button rounded icon class="action-delete" :disabled="preset === null || id === '+'" @click="on" v-tooltip.bottom="$t('delete')">
<v-icon name="delete" />
</v-button>
</template>
@@ -33,7 +33,7 @@
</v-card>
</v-dialog>
<v-button icon rounded :disabled="hasEdits === false" :loading="saving" @click="save">
<v-button icon rounded :disabled="hasEdits === false" :loading="saving" @click="save" v-tooltip.bottom="$t('save')">
<v-icon name="check" />
</v-button>
</template>

View File

@@ -8,7 +8,7 @@
</template>
<template #actions>
<v-button icon rounded :disabled="noEdits" :loading="saving" @click="save">
<v-button icon rounded :disabled="noEdits" :loading="saving" @click="save" v-tooltip.bottom="$t('save')">
<v-icon name="check" />
</v-button>
</template>

View File

@@ -9,7 +9,7 @@
</template>
<template #actions>
<v-button rounded icon :to="addNewLink">
<v-button rounded icon :to="addNewLink" v-tooltip.bottom="$t('add_role')">
<v-icon name="add" />
</v-button>
</template>

View File

@@ -9,7 +9,7 @@
<template #actions>
<v-dialog v-model="confirmDelete" v-if="[1, 2].includes(+primaryKey) === false">
<template #activator="{ on }">
<v-button rounded icon class="action-delete" :disabled="item === null" @click="on">
<v-button rounded icon class="action-delete" :disabled="item === null" @click="on" v-tooltip.bottom="$t('delete')">
<v-icon name="delete" />
</v-button>
</template>
@@ -28,7 +28,7 @@
</v-card>
</v-dialog>
<v-button rounded icon :loading="saving" :disabled="hasEdits === false" @click="saveAndQuit">
<v-button rounded icon :loading="saving" :disabled="hasEdits === false" @click="saveAndQuit" v-tooltip.bottom="$t('save')">
<v-icon name="check" />
<template #append-outer>

View File

@@ -34,11 +34,11 @@
</v-card>
</v-dialog>
<v-button rounded icon class="action-batch" v-if="selection.length > 1" :to="batchLink">
<v-button rounded icon class="action-batch" v-if="selection.length > 1" :to="batchLink" v-tooltip.bottom="$t('edit')">
<v-icon name="edit" />
</v-button>
<v-button rounded icon :to="addNewLink">
<v-button rounded icon :to="addNewLink" v-tooltip.bottom="$t('add_user')">
<v-icon name="add" />
</v-button>
</template>

View File

@@ -13,7 +13,7 @@
<template #actions>
<v-dialog v-model="confirmDelete">
<template #activator="{ on }">
<v-button rounded icon class="action-delete" :disabled="item === null" @click="on">
<v-button rounded icon class="action-delete" :disabled="item === null" @click="on" v-tooltip.bottom="$t('delete')">
<v-icon name="delete" />
</v-button>
</template>
@@ -32,7 +32,7 @@
</v-card>
</v-dialog>
<v-button rounded icon :loading="saving" :disabled="hasEdits === false" @click="saveAndQuit">
<v-button rounded icon :loading="saving" :disabled="hasEdits === false" @click="saveAndQuit" v-tooltip.bottom="$t('save')">
<v-icon name="check" />
<template #append-outer>

View File

@@ -16,7 +16,7 @@ export const useCollectionsStore = createStore({
visibleCollections: (state) => {
return state.collections
.filter(({ collection }) => collection.startsWith('directus_') === false)
.filter(collection => collection.system?.hidden !== true);
.filter(collection => collection.meta?.hidden !== true);
},
},
actions: {
@@ -27,11 +27,11 @@ export const useCollectionsStore = createStore({
this.state.collections = collections.map((collection: CollectionRaw) => {
let name: string | VueI18n.TranslateResult;
const icon = collection.system?.icon || 'box';
const icon = collection.meta?.icon || 'box';
if (collection.system && notEmpty(collection.system.translation)) {
for (let i = 0; i < collection.system.translation.length; i++) {
const { locale, translation } = collection.system.translation[i];
if (collection.meta && notEmpty(collection.meta.translation)) {
for (let i = 0; i < collection.meta.translation.length; i++) {
const { locale, translation } = collection.meta.translation[i];
i18n.mergeLocaleMessage(locale, {
collections: {

View File

@@ -7,7 +7,7 @@ type Translation = {
export interface CollectionRaw {
collection: string;
system: {
meta: {
note: string | null;
hidden: boolean;
single: boolean;
@@ -16,7 +16,7 @@ export interface CollectionRaw {
translation: Translation[] | null;
display_template: string | null;
} | null;
database: Record<string, any>;
schema: Record<string, any>;
}
export interface Collection extends CollectionRaw {

View File

@@ -7,7 +7,7 @@
position: absolute;
top: 0;
left: 0;
z-index: 500;
z-index: 475;
display: none;
max-width: 260px;
padding: 4px 8px;

View File

@@ -4,6 +4,7 @@
:class="{ active, 'has-content': !!value }"
v-click-outside="disable"
@click="active = true"
v-tooltip.bottom="active ? null : $t('search')"
>
<v-icon name="search" />
<input ref="input" :value="value" @input="emitValue" />