Skip to content

Commit

Permalink
refactor(frontend): move hooks into their own files
Browse files Browse the repository at this point in the history
Cleans up FileViewPage.tsx by moving general-purpose hooks into their own files.
  • Loading branch information
LordTermor committed May 29, 2024
1 parent 372bae2 commit d2da191
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 143 deletions.
52 changes: 52 additions & 0 deletions frontend/src/hooks/BxtHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
import { useCallback, useEffect, useState } from "react";
import axios from "axios";
import { toast } from "react-toastify";

export interface IUpdateSections {
(): void;
Expand Down Expand Up @@ -91,3 +92,54 @@ export const useCompareResults = (): [

return [results, updateResults, () => setResults(undefined)];
};

export const usePushCommitsHandler = (
commits: ICommit[],
reload: () => void
) => {
return useCallback(
async (e: any) => {
let formData = new FormData();

let packages = commits.flatMap((value) => value.packages);
packages.forEach((pkg, index) => {
const missingFields = [];
if (!pkg.file) missingFields.push("package file");
if (!pkg.signatureFile) missingFields.push("signature file");
if (!pkg.section.branch) missingFields.push("branch");
if (!pkg.section.repository) missingFields.push("repository");
if (!pkg.section.architecture)
missingFields.push("architecture");

if (missingFields.length === 0) {
formData.append(`package${index + 1}.filepath`, pkg.file);
formData.append(
`package${index + 1}.signature`,
pkg.signatureFile
);
formData.append(
`package${index + 1}.section`,
JSON.stringify(pkg.section)
);
} else {
toast.error(
`Missing package fields for ${
pkg.name
}: ${missingFields.join(", ")}`
);
}
});

const result = await axios.post(
`${process.env.PUBLIC_URL}/api/packages/commit`,
formData
);

if (result.data["status"] == "ok") {
toast.done("Pushed!");
reload();
}
},
[commits, reload]
);
};
51 changes: 51 additions & 0 deletions frontend/src/hooks/DragNDropHooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* === This file is part of bxt ===
*
* SPDX-FileCopyrightText: 2024 Artem Grinev <agrinev@manjaro.org>
* SPDX-License-Identifier: AGPL-3.0-or-later
*
*/

import { useCallback } from "react";

export const usePackageDropHandler = (
path: string[],
setCommit: (commits: ICommit) => void
) => {
return useCallback(
(acceptedFiles: File[]) => {
const section: ISection = {
branch: path[1],
repository: path[2],
architecture: path[3]
};
const packages: {
[key: string]: Partial<IPackageUpload>;
} = {};
for (const file of acceptedFiles) {
if (file.name.endsWith(".sig")) {
const name = file.name.replace(".sig", "");
if (!packages[name]) {
packages[name] = {};
}
packages[name].signatureFile = file;
continue;
}

packages[file.name] = {
name: file.name,
section,
file: file,
...packages[file.name]
};
}

setCommit({
section,
packages: Object.values(packages)
.filter((partial) => partial as IPackageUpload)
.map((partial) => partial as IPackageUpload)
});
},
[path, setCommit]
);
};
96 changes: 96 additions & 0 deletions frontend/src/hooks/FileManagementHooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/* === This file is part of bxt ===
*
* SPDX-FileCopyrightText: 2024 Artem Grinev <agrinev@manjaro.org>
* SPDX-License-Identifier: AGPL-3.0-or-later
*
*/

import {
FileArray,
ChonkyFileActionData,
ChonkyActions,
FileHelper,
FileData
} from "chonky";
import { OpenFilesPayload } from "chonky/dist/types/action-payloads.types";
import _ from "lodash";
import { useCallback } from "react";
import { SnapshotActionPayload } from "../components/SnapshotAction";

export const useFolderChainForPath = (path: string[]): FileArray => {
const result: FileArray = [];

result.push({
id: "root",
name: "root",
isDir: true
});

for (let i = 1; i < path.length; i++) {
result.push({
id: `${result[i - 1]!.id}/${path[i]}`,
name: path[i],
isDir: true
});
}

return result;
};

export const packageFromFilePath = (filePath: string, packages: IPackage[]) => {
const parts = filePath.split("/");
if (parts.length != 5) return;
const section: ISection = {
branch: parts[1],
repository: parts[2],
architecture: parts[3]
};
const packageName = parts[4];

return packages.find((value) => {
return _.isEqual(value.section, section) && value.name == packageName;
});
};

export const useFileActionHandler = (
setPath: (path: string[]) => void,
setSnapshotModalBranches: (
sourceBranch?: string,
targetBranch?: string
) => void,
setPackage: (pkg?: IPackage) => void,
packages: IPackage[]
) => {
return useCallback(
(data: ChonkyFileActionData) => {
switch (data.id as string) {
case ChonkyActions.OpenFiles.id:
const { targetFile, files } =
data.payload as OpenFilesPayload;
const fileToOpen = targetFile ?? files[0];
if (fileToOpen && FileHelper.isDirectory(fileToOpen)) {
const pathToOpen = fileToOpen.id.split("/");

setPath(pathToOpen);
} else if (
fileToOpen &&
!FileHelper.isDirectory(fileToOpen)
) {
setPackage(
packageFromFilePath(
(fileToOpen as FileData).id,
packages
)
);
}
break;
case "snap":
const { sourceBranch, targetBranch } =
data.payload as SnapshotActionPayload;

setSnapshotModalBranches(sourceBranch, targetBranch);
}
},
[setPath, setSnapshotModalBranches, setPackage, packages]
);
};
151 changes: 8 additions & 143 deletions frontend/src/pages/FileViewPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,10 @@
*
*/

import {
FullFileBrowser,
FileArray,
setChonkyDefaults,
ChonkyFileActionData,
ChonkyActions,
FileHelper,
FileData
} from "chonky";
import { FullFileBrowser, setChonkyDefaults } from "chonky";
import { ChonkyIconFA } from "chonky-icon-fontawesome";
import { useCallback, useEffect, useRef, useState } from "react";
import { useSections } from "../hooks/BxtHooks";
import { usePushCommitsHandler, useSections } from "../hooks/BxtHooks";
import Dropzone from "react-dropzone";
import CommitModal from "../components/CommitModal";
import { Button, Drawer, Menu } from "react-daisyui";
Expand All @@ -27,96 +19,17 @@ import { toast } from "react-toastify";
import SnapshotModal, {
ISnapshotModalProps
} from "../components/SnapshotModal";
import {
SnapshotAction,
SnapshotActionPayload,
SnapToAction
} from "../components/SnapshotAction";
import { OpenFilesPayload } from "chonky/dist/types/action-payloads.types";
import axios from "axios";
import { SnapshotAction, SnapToAction } from "../components/SnapshotAction";
import PackageModal, { PackageModalProps } from "../components/PackageModal";
import _ from "lodash";
import {
useFileActionHandler,
useFolderChainForPath
} from "../hooks/FileManagementHooks";
import { usePackageDropHandler } from "../hooks/DragNDropHooks";

setChonkyDefaults({ iconComponent: ChonkyIconFA });

const useFolderChainForPath = (path: string[]): FileArray => {
const result: FileArray = [];

result.push({
id: "root",
name: "root",
isDir: true
});

for (let i = 1; i < path.length; i++) {
result.push({
id: `${result[i - 1]!.id}/${path[i]}`,
name: path[i],
isDir: true
});
}

return result;
};

const packageFromFilePath = (filePath: string, packages: IPackage[]) => {
const parts = filePath.split("/");
if (parts.length != 5) return;
const section: ISection = {
branch: parts[1],
repository: parts[2],
architecture: parts[3]
};
const packageName = parts[4];

return packages.find((value) => {
return _.isEqual(value.section, section) && value.name == packageName;
});
};

export const useFileActionHandler = (
setPath: (path: string[]) => void,
setSnapshotModalBranches: (
sourceBranch?: string,
targetBranch?: string
) => void,
setPackage: (pkg?: IPackage) => void,
packages: IPackage[]
) => {
return useCallback(
(data: ChonkyFileActionData) => {
switch (data.id as string) {
case ChonkyActions.OpenFiles.id:
const { targetFile, files } =
data.payload as OpenFilesPayload;
const fileToOpen = targetFile ?? files[0];
if (fileToOpen && FileHelper.isDirectory(fileToOpen)) {
const pathToOpen = fileToOpen.id.split("/");

setPath(pathToOpen);
} else if (
fileToOpen &&
!FileHelper.isDirectory(fileToOpen)
) {
setPackage(
packageFromFilePath(
(fileToOpen as FileData).id,
packages
)
);
}
break;
case "snap":
const { sourceBranch, targetBranch } =
data.payload as SnapshotActionPayload;

setSnapshotModalBranches(sourceBranch, targetBranch);
}
},
[setPath, setSnapshotModalBranches, setPackage, packages]
);
};

const usePackageDropHandler = (
path: string[],
setCommit: (commits: ICommit) => void
Expand Down Expand Up @@ -163,54 +76,6 @@ const usePackageDropHandler = (
);
};

const usePushCommitsHandler = (commits: ICommit[], reload: () => void) => {
return useCallback(
async (e: any) => {
let formData = new FormData();

let packages = commits.flatMap((value) => value.packages);
packages.forEach((pkg, index) => {
const missingFields = [];
if (!pkg.file) missingFields.push("package file");
if (!pkg.signatureFile) missingFields.push("signature file");
if (!pkg.section.branch) missingFields.push("branch");
if (!pkg.section.repository) missingFields.push("repository");
if (!pkg.section.architecture)
missingFields.push("architecture");

if (missingFields.length === 0) {
formData.append(`package${index + 1}.filepath`, pkg.file);
formData.append(
`package${index + 1}.signature`,
pkg.signatureFile
);
formData.append(
`package${index + 1}.section`,
JSON.stringify(pkg.section)
);
} else {
toast.error(
`Missing package fields for ${
pkg.name
}: ${missingFields.join(", ")}`
);
}
});

const result = await axios.post(
`${process.env.PUBLIC_URL}/api/packages/commit`,
formData
);

if (result.data["status"] == "ok") {
toast.done("Pushed!");
reload();
}
},
[commits, reload]
);
};

export default (props: any) => {
const [sections, updateSections] = useSections();

Expand Down

0 comments on commit d2da191

Please sign in to comment.