Skip to content

Commit

Permalink
Merge pull request #2 from Blackshadow8910/creation-autofill
Browse files Browse the repository at this point in the history
[sysadminsmedia#467] Creation autofill
  • Loading branch information
mcarbonne authored Jan 26, 2025
2 parents 86748ff + 37315f1 commit ce241ff
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 56 deletions.
42 changes: 38 additions & 4 deletions frontend/components/Base/Modal.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
<template>
<div class="z-[999]">
<input :id="modalId" v-model="modal" type="checkbox" class="modal-toggle" />
<div class="modal modal-bottom overflow-visible sm:modal-middle">
<div
class="modal overflow-visible sm:modal-middle"
:class="{ 'modal-bottom': !props.modalTop }"
:modal-top="props.modalTop"
>
<div ref="modalBox" class="modal-box relative overflow-visible">
<button
v-if="props.showCloseButton"
Expand Down Expand Up @@ -41,6 +45,14 @@
type: Boolean,
default: true,
},
clickOutsideToClose: {
type: Boolean,
default: false,
},
modalTop: {
type: Boolean,
default: false,
},
});
const modalBox = ref();
Expand All @@ -51,9 +63,11 @@
}
}
onClickOutside(modalBox, () => {
close();
});
if (props.clickOutsideToClose) {
onClickOutside(modalBox, () => {
close();
});
}
function close() {
if (props.readonly) {
Expand All @@ -74,3 +88,23 @@
}
});
</script>

<style lang="css" scoped>
@media (max-width: 640px) {
.modal[modal-top] {
align-items: start;
}
.modal[modal-top] :where(.modal-box) {
max-width: none;
--tw-translate-y: 2.5rem /* 40px */;
--tw-scale-x: 1;
--tw-scale-y: 1;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
width: 100%;
border-top-left-radius: 0px;
border-top-right-radius: 0px;
}
}
</style>
4 changes: 2 additions & 2 deletions frontend/components/Form/Multiselect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<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 +20,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
22 changes: 15 additions & 7 deletions frontend/components/global/QuickMenu/Input.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<template>
<Combobox v-model="selectedAction">
<Combobox v-model="selectedAction" :nullable="true">
<ComboboxInput
ref="inputBox"
class="input input-bordered mt-2 w-full"
@input="inputValue = $event.target.value"
></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(null);
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
21 changes: 8 additions & 13 deletions frontend/components/global/QuickMenu/Modal.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
<template>
<BaseModal v-model="modal" :show-close-button="false">
<BaseModal
v-model="modal"
:show-close-button="false"
:click-outside-to-close="true"
:modal-top="true"
:class="{ 'self-start': 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 +29,6 @@
});
const modal = useVModel(props, "modelValue");
const selectedAction = ref<QuickMenuAction>();
const inputBox = ref<QuickMenuInputData>({ focused: false, revealActions: () => {} });
Expand All @@ -37,7 +37,6 @@
}, 50).start;
const onModalClose = () => {
selectedAction.value = undefined;
inputBox.value.focused = false;
};
Expand All @@ -51,8 +50,4 @@
modal.value = false;
useTimeoutFn(action.action, 100).start();
}
watch(selectedAction, action => {
if (action) invokeAction(action);
});
</script>
Loading

0 comments on commit ce241ff

Please sign in to comment.