Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
mcarbonne committed Jan 20, 2025
1 parent 295ba0a commit a6d8318
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 51 deletions.
12 changes: 9 additions & 3 deletions frontend/components/Base/Modal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@
type: Boolean,
default: true,
},
clickOutsideToClose: {
type: Boolean,
default: false,
},
});
const modalBox = ref();
Expand All @@ -51,9 +55,11 @@
}
}
onClickOutside(modalBox, () => {
close();
});
if (props.clickOutsideToClose) {
onClickOutside(modalBox, () => {
close();
});
}
function close() {
if (props.readonly) {
Expand Down
7 changes: 5 additions & 2 deletions frontend/components/Form/Multiselect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
<span class="label-text">{{ label }}</span>
</label>
<div class="dropdown dropdown-top sm:dropdown-end">
<div tabindex="0" class="flex min-h-[48px] w-full flex-wrap gap-2 rounded-lg border border-gray-400 p-4">
<div
tabindex="0"
class="flex min-h-[48px] w-full flex-wrap gap-2 rounded-lg border border-base-content/20 p-4"
>
<span v-for="itm in value" :key="itm.id" class="badge">
{{ itm.name }}
</span>
Expand All @@ -20,7 +23,7 @@
<div
tabindex="0"
style="display: inline"
class="dropdown-content menu z-[9999] mb-1 w-full rounded border border-gray-400 bg-base-100 shadow"
class="dropdown-content menu z-[9999] mb-1 w-full rounded border border-base-content/20 bg-base-100 shadow"
>
<div class="m-2">
<input v-model="search" placeholder="Search…" class="input input-bordered input-sm w-full" />
Expand Down
28 changes: 17 additions & 11 deletions frontend/components/Item/CreateModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -141,20 +141,26 @@
}
}
whenever(
watch(
() => modal.value,
() => {
focused.value = true;
if (locationId.value) {
const found = locations.value.find(l => l.id === locationId.value);
if (found) {
form.location = found;
open => {
if (open) {
useTimeoutFn(() => {
focused.value = true;
}, 50);
if (locationId.value) {
const found = locations.value.find(l => l.id === locationId.value);
if (found) {
form.location = found;
}
}
}
if (labelId.value) {
form.labels = labels.value.filter(l => l.id === labelId.value);
if (labelId.value) {
form.labels = labels.value.filter(l => l.id === labelId.value);
}
} else {
focused.value = false;
}
}
);
Expand Down
10 changes: 7 additions & 3 deletions frontend/components/Label/CreateModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,14 @@
loading.value = false;
}
whenever(
watch(
() => modal.value,
() => {
focused.value = true;
open => {
if (open)
useTimeoutFn(() => {
focused.value = true;
}, 50);
else focused.value = false;
}
);
Expand Down
33 changes: 29 additions & 4 deletions frontend/components/Location/CreateModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<BaseModal v-model="modal">
<template #title>{{ $t("components.location.create_modal.title") }}</template>
<form @submit.prevent="create()">
<LocationSelector v-model="form.parent" />
<FormTextField
ref="locationNameRef"
v-model="form.name"
Expand All @@ -17,7 +18,6 @@
:label="$t('components.location.create_modal.location_description')"
:max-length="1000"
/>
<LocationSelector v-model="form.parent" />
<div class="modal-action">
<div class="flex justify-center">
<BaseButton class="rounded-r-none" type="submit" :loading="loading">{{ $t("global.create") }}</BaseButton>
Expand Down Expand Up @@ -59,10 +59,23 @@
parent: null as LocationSummary | null,
});
whenever(
watch(
() => modal.value,
() => {
focused.value = true;
open => {
if (open) {
useTimeoutFn(() => {
focused.value = true;
}, 50);
if (locationId.value) {
const found = locations.value.find(l => l.id === locationId.value);
if (found) {
form.parent = found;
}
}
} else {
focused.value = false;
}
}
);
Expand All @@ -77,8 +90,20 @@
const api = useUserApi();
const toast = useNotifier();
const locationsStore = useLocationStore();
const locations = computed(() => locationsStore.allLocations);
const route = useRoute();
const { shift } = useMagicKeys();
const locationId = computed(() => {
if (route.fullPath.includes("/location/")) {
return route.params.id;
}
return null;
});
async function create(close = true) {
if (loading.value) {
toast.error("Already creating a location");
Expand Down
20 changes: 14 additions & 6 deletions frontend/components/global/QuickMenu/Input.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
></ComboboxInput>
<ComboboxOptions
class="card dropdown-content absolute max-h-48 w-full overflow-y-scroll rounded-lg border border-base-300 bg-base-100"
:unmount="false"
>
<ComboboxOption
v-for="(action, idx) in filteredActions"
Expand Down Expand Up @@ -68,33 +69,40 @@
},
});
const selectedAction = useVModel(props, "modelValue");
const emit = defineEmits(["update:modelValue", "actionSelected"]);
const selectedAction = ref();
const inputValue = ref("");
const inputBox = ref();
const inputBoxButton = ref();
const { focused: inputBoxFocused } = useFocus(inputBox);
const emit = defineEmits(["update:modelValue", "quickSelect"]);
const revealActions = () => {
unrefElement(inputBoxButton).click();
};
watch(inputBoxFocused, () => {
if (inputBoxFocused.value) revealActions();
watch(inputBoxFocused, val => {
if (val) revealActions();
else inputValue.value = "";
});
watch(inputValue, (val, oldVal) => {
if (!oldVal) {
const action = props.actions?.find(v => v.shortcut === val);
if (action) {
emit("quickSelect", action);
emit("actionSelected", action);
inputBoxFocused.value = false;
}
}
});
watch(selectedAction, val => {
if (val) {
emit("actionSelected", val);
selectedAction.value = null;
}
});
const filteredActions = computed(() => {
const searchTerm = inputValue.value.toLowerCase();
return (props.actions || []).filter(action => {
Expand Down
15 changes: 2 additions & 13 deletions frontend/components/global/QuickMenu/Modal.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
<template>
<BaseModal v-model="modal" :show-close-button="false">
<BaseModal v-model="modal" :show-close-button="false" :click-outside-to-close="true">
<div class="relative">
<span class="text-neutral-400">{{ $t("components.quick_menu.shortcut_hint") }}</span>
<QuickMenuInput
ref="inputBox"
v-model="selectedAction"
:actions="props.actions || []"
@quick-select="invokeAction"
></QuickMenuInput>
<QuickMenuInput ref="inputBox" :actions="props.actions || []" @action-selected="invokeAction"></QuickMenuInput>
</div>
</BaseModal>
</template>
Expand All @@ -28,7 +23,6 @@
});
const modal = useVModel(props, "modelValue");
const selectedAction = ref<QuickMenuAction>();
const inputBox = ref<QuickMenuInputData>({ focused: false, revealActions: () => {} });
Expand All @@ -37,7 +31,6 @@
}, 50).start;
const onModalClose = () => {
selectedAction.value = undefined;
inputBox.value.focused = false;
};
Expand All @@ -51,8 +44,4 @@
modal.value = false;
useTimeoutFn(action.action, 100).start();
}
watch(selectedAction, action => {
if (action) invokeAction(action);
});
</script>
28 changes: 19 additions & 9 deletions frontend/layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,11 @@
<button class="group" @click="btn.action">
{{ btn.name.value }}

<kbd v-if="btn.shortcut" class="ml-auto hidden text-neutral-400 group-hover:inline">{{
btn.shortcut
}}</kbd>
<kbd
v-if="btn.shortcut"
class="kbd kbd-sm ml-auto hidden text-neutral-400 group-hover:inline"
>{{ btn.shortcut }}</kbd
>
</button>
</li>
</ul>
Expand Down Expand Up @@ -145,9 +147,14 @@
const displayOutdatedWarning = computed(() => !isDev && !hasHiddenLatest.value && isOutdated.value);
const activeElement = useActiveElement();
const keys = useMagicKeys({
aliasMap: {
"": "control_",
"Shift+": "ShiftLeft_",
"!": "ShiftLeft_digit1",
"@": "ShiftLeft_digit2",
"#": "ShiftLeft_digit3",
},
});
Expand All @@ -173,33 +180,36 @@
{
id: 0,
name: computed(() => t("menu.create_item")),
shortcut: "⌃1",
shortcut: "!",
action: () => {
modals.item = true;
},
},
{
id: 1,
name: computed(() => t("menu.create_location")),
shortcut: "⌃2",
shortcut: "@",
action: () => {
modals.location = true;
},
},
{
id: 2,
name: computed(() => t("menu.create_label")),
shortcut: "⌃3",
shortcut: "#",
action: () => {
modals.label = true;
},
},
];
dropdown.forEach(option => {
if (option.shortcut) {
whenever(keys[option.shortcut], () => {
option.action();
if (option?.shortcut) {
const shortcutKeycode = option.shortcut.replace(/([0-9])/, "digit$&");
whenever(keys[shortcutKeycode], () => {
if (activeElement.value?.tagName !== "INPUT") {
option.action();
}
});
}
});
Expand Down

0 comments on commit a6d8318

Please sign in to comment.