mirror of
https://github.com/sysadminsmedia/homebox.git
synced 2025-12-21 13:23:14 +01:00
* feat: improved duplicate * feat: enhance item duplication process with transaction handling and error logging for attachments and fields * feat: add error logging during transaction rollback in item duplication process for better debugging * feat: don't try and rollback is the commit succeeded * feat: add customizable duplication options for items, including prefix and field copying settings in API and UI * fix: simplify duplication checks for custom fields, attachments, and maintenance entries in ItemsRepository duplication method * refactor: import DuplicateSettings type from composables and sort import issues
96 lines
2.9 KiB
TypeScript
96 lines
2.9 KiB
TypeScript
import type { ComputedRef } from "vue";
|
|
import { createContext } from "reka-ui";
|
|
import { useMagicKeys, useActiveElement } from "@vueuse/core";
|
|
import type { BarcodeProduct } from "~~/lib/api/types/data-contracts";
|
|
|
|
export enum DialogID {
|
|
AttachmentEdit = 'attachment-edit',
|
|
ChangePassword = 'changePassword',
|
|
CreateItem = 'create-item',
|
|
CreateLocation = 'create-location',
|
|
CreateLabel = 'create-label',
|
|
CreateNotifier = 'create-notifier',
|
|
DuplicateSettings = 'duplicate-settings',
|
|
DuplicateTemporarySettings = 'duplicate-temporary-settings',
|
|
EditMaintenance = 'edit-maintenance',
|
|
Import = 'import',
|
|
ItemImage = 'item-image',
|
|
ItemTableSettings = 'item-table-settings',
|
|
PrintLabel = 'print-label',
|
|
ProductImport = 'product-import',
|
|
QuickMenu = 'quick-menu',
|
|
Scanner = 'scanner',
|
|
PageQRCode = 'page-qr-code',
|
|
UpdateLabel = 'update-label',
|
|
UpdateLocation = 'update-location',
|
|
}
|
|
|
|
export type DialogParamsMap = {
|
|
[DialogID.CreateItem]: { product?: BarcodeProduct };
|
|
[DialogID.ProductImport]: { barcode?: string };
|
|
};
|
|
|
|
type DialogsWithParams = keyof DialogParamsMap;
|
|
|
|
type OpenDialog = {
|
|
<T extends DialogID>(dialogId: T, params?: T extends DialogsWithParams ? DialogParamsMap[T] : undefined): void;
|
|
};
|
|
|
|
type OpenCallback = {
|
|
<T extends DialogID>(dialogId: T, callback: (params?: T extends keyof DialogParamsMap ? DialogParamsMap[T] : undefined) => void): void;
|
|
}
|
|
|
|
export const [useDialog, provideDialogContext] = createContext<{
|
|
activeDialog: ComputedRef<DialogID | null>;
|
|
activeAlerts: ComputedRef<string[]>;
|
|
registerOpenDialogCallback: OpenCallback;
|
|
openDialog: OpenDialog;
|
|
closeDialog: (dialogId?: DialogID) => void;
|
|
addAlert: (alertId: string) => void;
|
|
removeAlert: (alertId: string) => void;
|
|
}>("DialogProvider");
|
|
|
|
export const useDialogHotkey = (
|
|
dialogId: DialogID,
|
|
key: {
|
|
shift?: boolean;
|
|
ctrl?: boolean;
|
|
code: string;
|
|
}
|
|
) => {
|
|
const { openDialog } = useDialog();
|
|
|
|
const activeElement = useActiveElement();
|
|
|
|
const notUsingInput = computed(
|
|
() => activeElement.value?.tagName !== "INPUT" && activeElement.value?.tagName !== "TEXTAREA"
|
|
);
|
|
|
|
useMagicKeys({
|
|
passive: false,
|
|
onEventFired: event => {
|
|
// console.log({
|
|
// event,
|
|
// notUsingInput: notUsingInput.value,
|
|
// eventType: event.type,
|
|
// keyCode: event.code,
|
|
// matchingKeyCode: key.code === event.code,
|
|
// shift: event.shiftKey,
|
|
// matchingShift: key.shift === undefined || event.shiftKey === key.shift,
|
|
// ctrl: event.ctrlKey,
|
|
// matchingCtrl: key.ctrl === undefined || event.ctrlKey === key.ctrl,
|
|
// });
|
|
if (
|
|
notUsingInput.value &&
|
|
event.type === "keydown" &&
|
|
event.code === key.code &&
|
|
(key.shift === undefined || event.shiftKey === key.shift) &&
|
|
(key.ctrl === undefined || event.ctrlKey === key.ctrl)
|
|
) {
|
|
openDialog(dialogId);
|
|
event.preventDefault();
|
|
}
|
|
},
|
|
});
|
|
};
|