✨(frontend) enhance keyboard navigation and upload functionality

Added a check for disabled state in the keyboard navigation hook to
prevent focus when disabled. Updated the upload hook to improve parentId
handling and integrated a new utility for checking child creation
permissions, enhancing the upload process and ensuring better error
handling during file uploads.
This commit is contained in:
Nathan Panchout
2026-02-06 15:39:34 +01:00
committed by Manuel Raynaud
parent 5414f1030d
commit aa6013e99e
2 changed files with 36 additions and 12 deletions
@@ -24,6 +24,10 @@ export const useTableKeyboardNavigation = ({
// the case by default, if we start the area selection from outside the table, the body will be focused instead of the table, making the
// onKeyDown event not being triggered on table)
if (isDisabled) {
return;
}
if (tableRef.current) {
tableRef.current.focus({
preventScroll: true,
@@ -13,6 +13,9 @@ import { addToast } from "@/features/ui/components/toaster/Toaster";
import { FileUploadToast } from "../components/toasts/FileUploadToast";
import { useQueryClient } from "@tanstack/react-query";
import { getEntitlements } from "@/utils/entitlements";
import { useCanCreateChildren } from "@/features/items/utils";
import { getMyFilesQueryKey } from "@/utils/defaultRoutes";
import { useRouter } from "next/router";
type FileUpload = FileWithPath & {
parentId?: string;
@@ -33,6 +36,7 @@ type Upload = {
};
const useUpload = ({ item }: { item: Item }) => {
const router = useRouter();
const createFolder = useMutationCreateFolder();
const queryClient = useQueryClient();
@@ -117,10 +121,11 @@ const useUpload = ({ item }: { item: Item }) => {
// Create the folders and assign each file a parentId.
const createFoldersFromDrop = async (
parentItem: Item,
parentItem: Item | undefined,
folderUploads: FolderUpload[]
) => {
const promises = [];
for (const folder of folderUploads) {
promises.push(
() =>
@@ -128,13 +133,21 @@ const useUpload = ({ item }: { item: Item }) => {
createFolder.mutate(
{
title: folder.item.title!,
parentId: parentItem.id,
parentId: parentItem?.id,
},
{
onSuccess: async (createdFolder) => {
queryClient.invalidateQueries({
queryKey: ["items", parentItem.id],
});
queryClient.invalidateQueries({
queryKey: getMyFilesQueryKey(),
});
if (parentItem) {
queryClient.invalidateQueries({
queryKey: ["items", parentItem.id],
});
}
folder.files.forEach((file) => {
file.parentId = createdFolder.id;
});
@@ -154,9 +167,9 @@ const useUpload = ({ item }: { item: Item }) => {
// Assign each file a parentId and create the folders if it is a folder upload.
const handleHierarchy = async (upload: Upload) => {
upload.folder.files.forEach((file) => {
file.parentId = item!.id;
file.parentId = item?.id;
});
await createFoldersFromDrop(item!, upload.folder.children);
await createFoldersFromDrop(item, upload.folder.children);
};
return {
@@ -187,8 +200,11 @@ const pathNicefy = (path: string) => {
export const useUploadZone = ({ item }: { item: Item }) => {
const { t } = useTranslation();
const createFile = useMutationCreateFile();
const canCreateChildren = useCanCreateChildren(item);
const fileDragToastId = useRef<Id | null>(null);
const fileUploadsToastId = useRef<Id | null>(null);
const [uploadingState, setUploadingState] = useState<UploadingState>({
@@ -199,7 +215,7 @@ export const useUploadZone = ({ item }: { item: Item }) => {
const { filesToUpload, handleHierarchy } = useUpload({ item: item! });
const validateDrop = () => {
const canUpload = item?.abilities?.children_create ?? false;
const canUpload = canCreateChildren;
if (!canUpload) {
return {
code: "no-upload-rights",
@@ -229,7 +245,7 @@ export const useUploadZone = ({ item }: { item: Item }) => {
return;
}
const canUpload = item?.abilities?.children_create ?? false;
const canUpload = canCreateChildren;
fileDragToastId.current = addToast(
<ToasterItem
@@ -265,7 +281,7 @@ export const useUploadZone = ({ item }: { item: Item }) => {
dismissDragToast();
},
onDrop: async (acceptedFiles) => {
if (!(item?.abilities?.children_create ?? false)) {
if (!canCreateChildren) {
dismissDragToast();
return;
}
@@ -357,7 +373,7 @@ export const useUploadZone = ({ item }: { item: Item }) => {
{
filename: file.name,
file,
parentId: file.parentId!,
parentId: file.parentId,
progressHandler: (progress) => {
setUploadingState((prev) => {
const newState = {
@@ -419,7 +435,11 @@ export const useUploadZone = ({ item }: { item: Item }) => {
useEffect(() => {
const unloadCallback = (event: BeforeUnloadEvent) => {
if ([UploadingStep.CREATE_FOLDERS, UploadingStep.UPLOAD_FILES].includes(uploadingState.step)) {
if (
[UploadingStep.CREATE_FOLDERS, UploadingStep.UPLOAD_FILES].includes(
uploadingState.step
)
) {
event.preventDefault();
}
return "";