├── .DS_Store ├── .github └── workflows │ └── main.yml ├── .gitignore ├── LICENSE ├── README.md ├── backend ├── .DS_Store ├── .env.example ├── .nvmrc ├── package-lock.json ├── package.json ├── src │ ├── config │ │ ├── bucket.ts │ │ ├── common.ts │ │ ├── fileStorage.ts │ │ └── lang │ │ │ └── en.json │ ├── controllers │ │ ├── bucketManagerController.ts │ │ ├── errorController.ts │ │ ├── fileManagerController.ts │ │ ├── index.ts │ │ └── s3Controller_notusedts.md │ ├── routes │ │ ├── bucketManager.ts │ │ └── fileManager.ts │ ├── sdk │ │ ├── AbstractFileManager.ts │ │ ├── LocalFileManagerSDK.ts │ │ ├── helpers │ │ │ └── sanitazePath.ts │ │ └── types.ts │ ├── server.ts │ └── utilits │ │ ├── appError.ts │ │ ├── catchAsync.ts │ │ └── filemanager.ts ├── tsconfig.json └── uploads │ ├── 046_danny_rahayu_mnv_1_001_.jpg │ ├── 13258950_1711821409069780_1084411530_n.jpg │ ├── 4621.jpg │ ├── 62276217.jpg │ ├── New Microsoft Excel Worksheet.xlsx │ ├── New Microsoft PowerPoint Presentation.pptx │ ├── New Microsoft Word Document.docx │ ├── Untitled-1.pdf │ ├── Untitled-1.psd │ ├── apple.svg │ ├── articles │ ├── 001.jpg │ ├── 002.jpg │ ├── 003.jpg │ ├── 40-something-man-2-1.jpg │ ├── books │ │ ├── 51DEJigkwTL._SX384_BO1,204,203,200_.jpg │ │ ├── 51DIjhk1BSL._SX388_BO1,204,203,200_.jpg │ │ ├── 51ar9Mhg3VL._SX381_BO1,204,203,200_.jpg │ │ ├── book1.jpg │ │ ├── book2.jpg │ │ └── books3.jpg │ └── teacher5.jpg │ ├── bigl.jpg │ ├── devushka-litso-profil-briunetka.jpg │ ├── images.jpg │ ├── landing_fruits.jpg │ ├── new_file.txt │ ├── photos │ └── portfolio symlink │ ├── portfolio │ ├── paints │ │ ├── 1.jpg │ │ ├── 10_thumb.jpg │ │ ├── 2.jpg │ │ ├── 4.jpg │ │ ├── 5.jpg │ │ ├── 6.jpg │ │ ├── 7_thumb.jpg │ │ ├── 8_thumb.jpg │ │ └── 9_thumb.jpg │ └── websites │ │ ├── 1.jpg │ │ ├── 10_thumb.jpg │ │ ├── 11_thumb.jpg │ │ ├── 12_thumb.jpg │ │ ├── 1_thumb.jpg │ │ ├── 2_thumb.jpg │ │ ├── 3_thumb.jpg │ │ ├── 4_thumb.jpg │ │ ├── 5_thumb.jpg │ │ ├── 6_thumb.jpg │ │ ├── 7_thumb.jpg │ │ ├── 8_thumb.jpg │ │ ├── 9_thumb.jpg │ │ └── thumb.jpg │ ├── rik-i-morti-rick-and-morty-rick-sanchez-rick-sanchez-morty-6.jpg │ ├── store │ └── products │ │ └── product1-big.jpg │ └── user-no-img.jpg └── frontend ├── .env.example ├── .gitignore ├── .nvmrc ├── README.md ├── eslint.config.js ├── index.html ├── package-lock.json ├── package.json ├── public ├── css │ └── demo.css └── img │ └── logos │ ├── darkLogo.svg │ └── lightLogo.svg ├── src ├── App.tsx ├── FileManager │ ├── FileManager.tsx │ ├── FileManagerContainer.tsx │ ├── apiSDKs │ │ ├── Ec2ServerConnection.ts │ │ ├── S3FrontConnection.ts │ │ ├── S3ServerConnection.ts │ │ └── types.ts │ ├── assets │ │ ├── icons │ │ │ ├── Inactive │ │ │ │ ├── add-1.svg │ │ │ │ ├── add-2.svg │ │ │ │ ├── add-user.svg │ │ │ │ ├── alarm.svg │ │ │ │ ├── analytics.svg │ │ │ │ ├── archive.svg │ │ │ │ ├── arroba.svg │ │ │ │ ├── bag.svg │ │ │ │ ├── book.svg │ │ │ │ ├── bug.svg │ │ │ │ ├── calendar-1.svg │ │ │ │ ├── calendar.svg │ │ │ │ ├── cash.svg │ │ │ │ ├── chat.svg │ │ │ │ ├── coding.svg │ │ │ │ ├── crop.svg │ │ │ │ ├── delete.svg │ │ │ │ ├── delivery.svg │ │ │ │ ├── dislike.svg │ │ │ │ ├── document.svg │ │ │ │ ├── double-arrow.svg │ │ │ │ ├── doubt.svg │ │ │ │ ├── down-arrow.svg │ │ │ │ ├── download-1.svg │ │ │ │ ├── download.svg │ │ │ │ ├── email-1.svg │ │ │ │ ├── email.svg │ │ │ │ ├── envelope.svg │ │ │ │ ├── eraser.svg │ │ │ │ ├── export.svg │ │ │ │ ├── facebook.svg │ │ │ │ ├── files-and-folders.svg │ │ │ │ ├── flag.svg │ │ │ │ ├── followers.svg │ │ │ │ ├── forward.svg │ │ │ │ ├── funnel.svg │ │ │ │ ├── github.svg │ │ │ │ ├── graph.svg │ │ │ │ ├── heart.svg │ │ │ │ ├── hide.svg │ │ │ │ ├── home.svg │ │ │ │ ├── icon-748150.svg │ │ │ │ ├── id-card.svg │ │ │ │ ├── image.svg │ │ │ │ ├── inbox.svg │ │ │ │ ├── instagram.svg │ │ │ │ ├── layout.svg │ │ │ │ ├── left-arrow.svg │ │ │ │ ├── like.svg │ │ │ │ ├── line-chart.svg │ │ │ │ ├── link.svg │ │ │ │ ├── linkedin.svg │ │ │ │ ├── list.svg │ │ │ │ ├── lock.svg │ │ │ │ ├── mail.svg │ │ │ │ ├── mailbox.svg │ │ │ │ ├── megaphone.svg │ │ │ │ ├── menu.svg │ │ │ │ ├── message.svg │ │ │ │ ├── minimize.svg │ │ │ │ ├── money-1.svg │ │ │ │ ├── money.svg │ │ │ │ ├── multimedia-option.svg │ │ │ │ ├── networking.svg │ │ │ │ ├── newspaper.svg │ │ │ │ ├── no-entry.svg │ │ │ │ ├── open-box.svg │ │ │ │ ├── open-menu.svg │ │ │ │ ├── paper-plane.svg │ │ │ │ ├── paperclip.svg │ │ │ │ ├── pen.svg │ │ │ │ ├── photo-camera.svg │ │ │ │ ├── picture.svg │ │ │ │ ├── pie-chart.svg │ │ │ │ ├── placeholder.svg │ │ │ │ ├── pointer.svg │ │ │ │ ├── presentation.svg │ │ │ │ ├── print.svg │ │ │ │ ├── pulse.svg │ │ │ │ ├── resize.svg │ │ │ │ ├── route.svg │ │ │ │ ├── server.svg │ │ │ │ ├── share.svg │ │ │ │ ├── shield.svg │ │ │ │ ├── shopping-cart.svg │ │ │ │ ├── signature.svg │ │ │ │ ├── substract.svg │ │ │ │ ├── success.svg │ │ │ │ ├── telephone.svg │ │ │ │ ├── text-1.svg │ │ │ │ ├── three-dots-menu.svg │ │ │ │ ├── thunder.svg │ │ │ │ ├── tick.svg │ │ │ │ ├── translate.svg │ │ │ │ ├── turn-off.svg │ │ │ │ ├── twitter.svg │ │ │ │ ├── ui.svg │ │ │ │ ├── undo.svg │ │ │ │ ├── user-1.svg │ │ │ │ ├── user-2.svg │ │ │ │ ├── user-3.svg │ │ │ │ ├── user.svg │ │ │ │ ├── wall-clock.svg │ │ │ │ ├── warning.svg │ │ │ │ ├── whatsapp.svg │ │ │ │ ├── world.svg │ │ │ │ └── youtube.svg │ │ │ ├── files │ │ │ │ ├── ai.svg │ │ │ │ ├── avi.svg │ │ │ │ ├── css.svg │ │ │ │ ├── csv.svg │ │ │ │ ├── dbf.svg │ │ │ │ ├── doc.svg │ │ │ │ ├── dwg.svg │ │ │ │ ├── exe.svg │ │ │ │ ├── file.svg │ │ │ │ ├── fla.svg │ │ │ │ ├── flash.svg │ │ │ │ ├── folder.svg │ │ │ │ ├── folderfull.svg │ │ │ │ ├── folderopen.svg │ │ │ │ ├── gif.svg │ │ │ │ ├── html.svg │ │ │ │ ├── index.tsx │ │ │ │ ├── iso.svg │ │ │ │ ├── javascript.svg │ │ │ │ ├── jpg.svg │ │ │ │ ├── json-file.svg │ │ │ │ ├── mp3.svg │ │ │ │ ├── mp4.svg │ │ │ │ ├── pdf.svg │ │ │ │ ├── png.svg │ │ │ │ ├── ppt.svg │ │ │ │ ├── psd.svg │ │ │ │ ├── rtf.svg │ │ │ │ ├── search.svg │ │ │ │ ├── svg.svg │ │ │ │ ├── trash.svg │ │ │ │ ├── trashbox.svg │ │ │ │ ├── txt.svg │ │ │ │ ├── xls.svg │ │ │ │ ├── xml.svg │ │ │ │ ├── zip-1.svg │ │ │ │ └── zip.svg │ │ │ └── line │ │ │ │ ├── add.svg │ │ │ │ ├── addFolder.svg │ │ │ │ ├── backward.svg │ │ │ │ ├── ban.svg │ │ │ │ ├── cancel-1.svg │ │ │ │ ├── cancel.svg │ │ │ │ ├── copy.svg │ │ │ │ ├── cursor.svg │ │ │ │ ├── cut.svg │ │ │ │ ├── delete-folder.svg │ │ │ │ ├── download.svg │ │ │ │ ├── exit.svg │ │ │ │ ├── folder.svg │ │ │ │ ├── folderOpen.svg │ │ │ │ ├── forward.svg │ │ │ │ ├── gridView.svg │ │ │ │ ├── index.tsx │ │ │ │ ├── information.svg │ │ │ │ ├── layers.svg │ │ │ │ ├── listView.svg │ │ │ │ ├── loupe.svg │ │ │ │ ├── next.svg │ │ │ │ ├── outbox.svg │ │ │ │ ├── paint-palette.svg │ │ │ │ ├── paste.svg │ │ │ │ ├── pencil.svg │ │ │ │ ├── refresh.svg │ │ │ │ ├── resize.svg │ │ │ │ ├── save.svg │ │ │ │ ├── selectAll.svg │ │ │ │ ├── settingsGear.svg │ │ │ │ ├── settingsLines.svg │ │ │ │ ├── text.svg │ │ │ │ ├── trash.svg │ │ │ │ ├── unZip.svg │ │ │ │ ├── upload.svg │ │ │ │ ├── view.svg │ │ │ │ ├── vol2.svg │ │ │ │ ├── vol3.svg │ │ │ │ ├── volume.svg │ │ │ │ └── zip.svg │ │ ├── translations │ │ │ └── en.ts │ │ └── whiteTheme.ts │ ├── components │ │ ├── elements │ │ │ ├── ButtonGroup.tsx │ │ │ ├── ButtonGroupSimple.tsx │ │ │ ├── ContentIcons.tsx │ │ │ ├── Dropzone.tsx │ │ │ ├── DropzoneFileList.tsx │ │ │ ├── Icon.tsx │ │ │ ├── ImageEditor.tsx │ │ │ ├── ImageEditorComponent.tsx │ │ │ ├── InfoBoxes.tsx │ │ │ ├── InputField.tsx │ │ │ ├── PopupDialog.tsx │ │ │ ├── styled.ts │ │ │ └── styledImageeditor.ts │ │ └── sections │ │ │ ├── filesBar │ │ │ ├── ContextMenu.tsx │ │ │ ├── DropZoneWrapper.tsx │ │ │ ├── FilesListContainer.tsx │ │ │ ├── FilesLoadingOverlay.tsx │ │ │ ├── OverlayBlocks.tsx │ │ │ ├── StatusBar.tsx │ │ │ ├── ToasterMessages.tsx │ │ │ ├── index.tsx │ │ │ └── styled.ts │ │ │ ├── folderBar │ │ │ ├── MenuItem.tsx │ │ │ ├── MenuSubmenu.tsx │ │ │ ├── VolumesList.tsx │ │ │ ├── index.tsx │ │ │ └── styled.ts │ │ │ ├── topBar │ │ │ ├── Searching.tsx │ │ │ ├── TopBarButtonGroups.tsx │ │ │ ├── TopBarRightMenus.tsx │ │ │ ├── index.tsx │ │ │ ├── settingsMenu │ │ │ │ ├── ImageViewOptions.tsx │ │ │ │ ├── SortingOptions.tsx │ │ │ │ ├── ThemeSelection.tsx │ │ │ │ ├── constants.ts │ │ │ │ └── index.tsx │ │ │ └── styled.ts │ │ │ └── viewItems │ │ │ ├── App.css │ │ │ ├── ViewItems.tsx │ │ │ ├── gridLayout │ │ │ ├── DraggedElementsStack.tsx │ │ │ ├── FileItem.tsx │ │ │ ├── FolderItem.tsx │ │ │ ├── GridItemRender.tsx │ │ │ ├── GridView.tsx │ │ │ ├── ItemSelectButton.tsx │ │ │ └── VirtualizedGrid.tsx │ │ │ ├── styled.ts │ │ │ └── tableLayout │ │ │ ├── ListFileItem.tsx │ │ │ ├── ListFolderItem.tsx │ │ │ ├── ListItemRender.tsx │ │ │ └── ListView.tsx │ ├── config.ts │ ├── hooks │ │ ├── useApiController.tsx │ │ ├── useCurrentTheme.tsx │ │ ├── useFileManagerOperations.tsx │ │ ├── useGenerateActionButtons.tsx │ │ └── useTexts.tsx │ ├── index.tsx │ ├── store │ │ ├── FileManagerContext.tsx │ │ └── FileManagerReducer.tsx │ ├── styled.ts │ ├── themes │ │ ├── dark.ts │ │ └── light.ts │ ├── types.ts │ └── utils │ │ ├── helpers.ts │ │ ├── index.ts │ │ └── sanitazePath.ts ├── main.tsx └── vite-env.d.ts ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/.DS_Store -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI Workflow 2 | 3 | on: 4 | push: 5 | paths: 6 | - 'frontend/**' 7 | - 'backend/**' 8 | pull_request: 9 | paths: 10 | - 'frontend/**' 11 | - 'backend/**' 12 | 13 | jobs: 14 | frontend: 15 | runs-on: ubuntu-latest 16 | if: contains(github.event.head_commit.message, 'frontend') || contains(github.event.head_commit.message, 'frontend/**') 17 | steps: 18 | - name: Checkout code 19 | uses: actions/checkout@v3 20 | 21 | - name: Set up Node.js 22 | uses: actions/setup-node@v3 23 | with: 24 | node-version-file: './frontend/.nvmrc' 25 | 26 | - name: Install dependencies 27 | working-directory: frontend 28 | run: npm ci 29 | 30 | # - name: Run React tests 31 | # working-directory: frontend 32 | # run: npm test -- --watchAll=false 33 | 34 | - name: Build Frontend 35 | working-directory: frontend 36 | run: npm run build 37 | 38 | backend: 39 | runs-on: ubuntu-latest 40 | if: contains(github.event.head_commit.message, 'backend') || contains(github.event.head_commit.message, 'backend/**') 41 | steps: 42 | - name: Checkout code 43 | uses: actions/checkout@v3 44 | 45 | - name: Set up Node.js 46 | uses: actions/setup-node@v3 47 | with: 48 | node-version-file: './backend/.nvmrc' 49 | 50 | - name: Install dependencies 51 | working-directory: backend 52 | run: npm ci 53 | 54 | # - name: Run Backend Tests 55 | # working-directory: backend 56 | # run: npm test 57 | 58 | - name: Start Server and Verify 59 | working-directory: backend 60 | run: | 61 | npm start & 62 | sleep 10 63 | curl -I http://localhost:3000 64 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Farhad Aliyev 4 | 5 | Selling this software is prohibited. Any violation of this contract will be prosecuted. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /backend/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/.DS_Store -------------------------------------------------------------------------------- /backend/.env.example: -------------------------------------------------------------------------------- 1 | S3_ACCESS_KEY=your_access_key 2 | S3_SECRET_KEY=your_secret_key 3 | S3_ENDPOINT=http://192.168.1.18:9001 -------------------------------------------------------------------------------- /backend/.nvmrc: -------------------------------------------------------------------------------- 1 | v22 -------------------------------------------------------------------------------- /backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cronus_backend", 3 | "version": "2.0.0", 4 | "description": "", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "tsx watch src/server.ts", 8 | "build": "tsc", 9 | "start": "node dist/server.js" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "dependencies": { 15 | "@aws-sdk/client-s3": "^3.908.0", 16 | "@aws-sdk/lib-storage": "^3.908.0", 17 | "@aws-sdk/s3-request-presigner": "^3.908.0", 18 | "archiver": "^7.0.1", 19 | "body-parser": "^2.2.0", 20 | "cors": "^2.8.5", 21 | "dotenv": "^17.2.3", 22 | "express": "^5.1.0", 23 | "express-rate-limit": "^8.1.0", 24 | "fs-extra": "^11.3.2", 25 | "multer": "^2.0.2", 26 | "node-cron": "^4.2.1", 27 | "unzipper": "^0.12.3" 28 | }, 29 | "devDependencies": { 30 | "@types/archiver": "^6.0.3", 31 | "@types/body-parser": "^1.19.6", 32 | "@types/cors": "^2.8.19", 33 | "@types/express": "^5.0.3", 34 | "@types/express-rate-limit": "^6.0.2", 35 | "@types/fs-extra": "^11.0.4", 36 | "@types/graceful-fs": "^4.1.9", 37 | "@types/multer": "^2.0.0", 38 | "@types/node": "^24.7.2", 39 | "@types/node-cron": "^3.0.11", 40 | "@types/unzipper": "^0.10.11", 41 | "ts-node-dev": "^2.0.0", 42 | "tsx": "^4.20.6", 43 | "typescript": "^5.9.3" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /backend/src/config/bucket.ts: -------------------------------------------------------------------------------- 1 | import { S3ClientConfig } from "@aws-sdk/client-s3"; 2 | 3 | export const s3config: S3ClientConfig = { 4 | region: "us-east-1", 5 | endpoint: process.env.S3_ENDPOINT!, 6 | credentials: { 7 | accessKeyId: process.env.S3_ACCESS_KEY!, 8 | secretAccessKey: process.env.S3_SECRET_KEY!, 9 | }, 10 | }; 11 | 12 | export const bucketName = "cronusfilemanager"; 13 | -------------------------------------------------------------------------------- /backend/src/config/common.ts: -------------------------------------------------------------------------------- 1 | export const MAX_UPLOAD_FILE_AMOUNT = 50; 2 | export const MAX_UPLOAD_FILE_SIZE = 5 * 1024 * 1024; // 5 MB (max file size) -------------------------------------------------------------------------------- /backend/src/config/fileStorage.ts: -------------------------------------------------------------------------------- 1 | import nodePath from "path"; 2 | 3 | export const FILE_STORAGE_MAIN_FOLDER = "uploads"; 4 | export const FILE_STORAGE_TRASH_FOLDER = nodePath.join(FILE_STORAGE_MAIN_FOLDER, "trash"); 5 | export const FILE_STORAGE_TMP_FOLDER = nodePath.join(FILE_STORAGE_MAIN_FOLDER, "tmp"); 6 | export const PROTECTED_FOLDERS = [FILE_STORAGE_TMP_FOLDER, FILE_STORAGE_TRASH_FOLDER, `${FILE_STORAGE_MAIN_FOLDER}`]; 7 | 8 | export const ALLOWED_FILE_EXTENSIONS = [ 9 | ".jpg", 10 | ".png", 11 | ".gif", 12 | ".jpeg", 13 | ".svg", 14 | ".doc", 15 | ".txt", 16 | ".csv", 17 | ".docx", 18 | ".xls", 19 | ".xml", 20 | ".pdf", 21 | ".zip", 22 | ".ppt", 23 | ".mp4", 24 | ".ai", 25 | ".psd", 26 | ".mp3", 27 | ".mp4", 28 | ".avi", 29 | ".heic", 30 | ".webm", 31 | ]; 32 | -------------------------------------------------------------------------------- /backend/src/config/lang/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "messages" : { 3 | "errors": { 4 | "userNotFound": "User with this id not exists" , 5 | "userTokenNotExists": "User with this token not exists", 6 | "userTokenNotSeted": "User token not exists", 7 | "userPassNotEqual": "Passwords are not equal", 8 | "userLoginFields":"Please provide login and password!", 9 | "userLoginWrong":"Incorrect login or password" 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /backend/src/controllers/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @package Cronus File Manager 3 | * @author Farhad Aliyev Kanni 4 | * @copyright Copyright (c) 2011 - 2024, Kannifarhad, Ltd. 5 | * @license https://opensource.org/licenses/GPL-3.0 6 | * @link http://filemanager.kanni.pro 7 | */ 8 | 9 | import fileManagerController from "./fileManagerController"; 10 | import bucketManagerController from "./bucketManagerController"; 11 | 12 | // const bucketManagerController = new S3Controller() 13 | export { fileManagerController, bucketManagerController }; 14 | -------------------------------------------------------------------------------- /backend/src/sdk/types.ts: -------------------------------------------------------------------------------- 1 | export const ENTITY_CONST = { 2 | DIRECTORY: "folder", 3 | FILE: "file", 4 | } as const; 5 | 6 | export type EntityType = (typeof ENTITY_CONST)[keyof typeof ENTITY_CONST]; 7 | 8 | export interface FSItem { 9 | id: string; 10 | name: string; 11 | created: Date; 12 | modified: Date; 13 | path: string; 14 | premissions: FSPermissions; 15 | type: EntityType; 16 | size?: number; 17 | extension?: string; 18 | children?: FSItem[]; 19 | } 20 | 21 | export interface DirectoryTreeOptions { 22 | exclude?: RegExp | RegExp[]; 23 | includeFiles?: boolean; 24 | extensions?: RegExp; 25 | normalizePath?: boolean; 26 | removePath?: string; 27 | attributes?: string[]; 28 | withChildren?: boolean; 29 | childrenDepth?: number 30 | } 31 | 32 | export interface FSPermissions { 33 | owner: string; 34 | group: string; 35 | others: string; 36 | } 37 | -------------------------------------------------------------------------------- /backend/src/utilits/appError.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @package Cronus File Manager 3 | * @author Farhad Aliyev Kanni 4 | * @copyright Copyright (c) 2011 - 2024, Kannifarhad, Ltd. 5 | * @license https://opensource.org/licenses/GPL-3.0 6 | * @link http://filemanager.kanni.pro 7 | */ 8 | 9 | export default class AppError extends Error { 10 | public statusCode: number; 11 | public status: 'fail' | 'error'; 12 | public isOperational: boolean; 13 | public messagetext: string; 14 | 15 | constructor(message: string, statusCode: number) { 16 | super(message); 17 | 18 | this.statusCode = statusCode; 19 | this.messagetext = message; 20 | this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error'; 21 | this.isOperational = true; 22 | 23 | // Maintains proper stack trace for where our error was thrown (only in V8) 24 | if (Error.captureStackTrace) { 25 | Error.captureStackTrace(this, this.constructor); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /backend/src/utilits/catchAsync.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @package Cronus File Manager 3 | * author Farhad Aliyev Kanni 4 | * @copyright Copyright (c) 2011 - 2024, Kannifarhad, Ltd. 5 | * @license https://opensource.org/licenses/GPL-3.0 6 | * @link http://filemanager.kanni.pro 7 | */ 8 | 9 | import { Request, Response, NextFunction } from "express"; 10 | import AppError from "./appError"; 11 | 12 | /** 13 | * Wraps an async Express route handler and forwards rejected promises to next(). 14 | */ 15 | const catchAsync = 16 | (fn: (req: Request, res: Response, next: NextFunction) => Promise) => 17 | (req: Request, res: Response, next: NextFunction): void => { 18 | fn(req, res, next).catch((error: Error) => 19 | next(new AppError(`Error while executing code: ${error?.message}`, 400)) 20 | ); 21 | }; 22 | 23 | export default catchAsync; 24 | -------------------------------------------------------------------------------- /backend/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "ESNext", 5 | "moduleResolution": "node", 6 | "outDir": "dist", 7 | "rootDir": "src", 8 | "strict": true, 9 | "esModuleInterop": true, 10 | "resolveJsonModule": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "skipLibCheck": true, 13 | "sourceMap": true 14 | }, 15 | "include": ["src"], 16 | "exclude": ["node_modules", "dist"] 17 | } -------------------------------------------------------------------------------- /backend/uploads/046_danny_rahayu_mnv_1_001_.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/046_danny_rahayu_mnv_1_001_.jpg -------------------------------------------------------------------------------- /backend/uploads/13258950_1711821409069780_1084411530_n.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/13258950_1711821409069780_1084411530_n.jpg -------------------------------------------------------------------------------- /backend/uploads/4621.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/4621.jpg -------------------------------------------------------------------------------- /backend/uploads/62276217.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/62276217.jpg -------------------------------------------------------------------------------- /backend/uploads/New Microsoft Excel Worksheet.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/New Microsoft Excel Worksheet.xlsx -------------------------------------------------------------------------------- /backend/uploads/New Microsoft PowerPoint Presentation.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/New Microsoft PowerPoint Presentation.pptx -------------------------------------------------------------------------------- /backend/uploads/New Microsoft Word Document.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/New Microsoft Word Document.docx -------------------------------------------------------------------------------- /backend/uploads/Untitled-1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/Untitled-1.pdf -------------------------------------------------------------------------------- /backend/uploads/Untitled-1.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/Untitled-1.psd -------------------------------------------------------------------------------- /backend/uploads/articles/001.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/articles/001.jpg -------------------------------------------------------------------------------- /backend/uploads/articles/002.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/articles/002.jpg -------------------------------------------------------------------------------- /backend/uploads/articles/003.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/articles/003.jpg -------------------------------------------------------------------------------- /backend/uploads/articles/40-something-man-2-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/articles/40-something-man-2-1.jpg -------------------------------------------------------------------------------- /backend/uploads/articles/books/51DEJigkwTL._SX384_BO1,204,203,200_.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/articles/books/51DEJigkwTL._SX384_BO1,204,203,200_.jpg -------------------------------------------------------------------------------- /backend/uploads/articles/books/51DIjhk1BSL._SX388_BO1,204,203,200_.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/articles/books/51DIjhk1BSL._SX388_BO1,204,203,200_.jpg -------------------------------------------------------------------------------- /backend/uploads/articles/books/51ar9Mhg3VL._SX381_BO1,204,203,200_.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/articles/books/51ar9Mhg3VL._SX381_BO1,204,203,200_.jpg -------------------------------------------------------------------------------- /backend/uploads/articles/books/book1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/articles/books/book1.jpg -------------------------------------------------------------------------------- /backend/uploads/articles/books/book2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/articles/books/book2.jpg -------------------------------------------------------------------------------- /backend/uploads/articles/books/books3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/articles/books/books3.jpg -------------------------------------------------------------------------------- /backend/uploads/articles/teacher5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/articles/teacher5.jpg -------------------------------------------------------------------------------- /backend/uploads/bigl.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/bigl.jpg -------------------------------------------------------------------------------- /backend/uploads/devushka-litso-profil-briunetka.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/devushka-litso-profil-briunetka.jpg -------------------------------------------------------------------------------- /backend/uploads/images.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/images.jpg -------------------------------------------------------------------------------- /backend/uploads/landing_fruits.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/landing_fruits.jpg -------------------------------------------------------------------------------- /backend/uploads/new_file.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/new_file.txt -------------------------------------------------------------------------------- /backend/uploads/photos/portfolio symlink: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/photos/portfolio symlink -------------------------------------------------------------------------------- /backend/uploads/portfolio/paints/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/portfolio/paints/1.jpg -------------------------------------------------------------------------------- /backend/uploads/portfolio/paints/10_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/portfolio/paints/10_thumb.jpg -------------------------------------------------------------------------------- /backend/uploads/portfolio/paints/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/portfolio/paints/2.jpg -------------------------------------------------------------------------------- /backend/uploads/portfolio/paints/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/portfolio/paints/4.jpg -------------------------------------------------------------------------------- /backend/uploads/portfolio/paints/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/portfolio/paints/5.jpg -------------------------------------------------------------------------------- /backend/uploads/portfolio/paints/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/portfolio/paints/6.jpg -------------------------------------------------------------------------------- /backend/uploads/portfolio/paints/7_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/portfolio/paints/7_thumb.jpg -------------------------------------------------------------------------------- /backend/uploads/portfolio/paints/8_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/portfolio/paints/8_thumb.jpg -------------------------------------------------------------------------------- /backend/uploads/portfolio/paints/9_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/portfolio/paints/9_thumb.jpg -------------------------------------------------------------------------------- /backend/uploads/portfolio/websites/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/portfolio/websites/1.jpg -------------------------------------------------------------------------------- /backend/uploads/portfolio/websites/10_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/portfolio/websites/10_thumb.jpg -------------------------------------------------------------------------------- /backend/uploads/portfolio/websites/11_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/portfolio/websites/11_thumb.jpg -------------------------------------------------------------------------------- /backend/uploads/portfolio/websites/12_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/portfolio/websites/12_thumb.jpg -------------------------------------------------------------------------------- /backend/uploads/portfolio/websites/1_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/portfolio/websites/1_thumb.jpg -------------------------------------------------------------------------------- /backend/uploads/portfolio/websites/2_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/portfolio/websites/2_thumb.jpg -------------------------------------------------------------------------------- /backend/uploads/portfolio/websites/3_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/portfolio/websites/3_thumb.jpg -------------------------------------------------------------------------------- /backend/uploads/portfolio/websites/4_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/portfolio/websites/4_thumb.jpg -------------------------------------------------------------------------------- /backend/uploads/portfolio/websites/5_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/portfolio/websites/5_thumb.jpg -------------------------------------------------------------------------------- /backend/uploads/portfolio/websites/6_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/portfolio/websites/6_thumb.jpg -------------------------------------------------------------------------------- /backend/uploads/portfolio/websites/7_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/portfolio/websites/7_thumb.jpg -------------------------------------------------------------------------------- /backend/uploads/portfolio/websites/8_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/portfolio/websites/8_thumb.jpg -------------------------------------------------------------------------------- /backend/uploads/portfolio/websites/9_thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/portfolio/websites/9_thumb.jpg -------------------------------------------------------------------------------- /backend/uploads/portfolio/websites/thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/portfolio/websites/thumb.jpg -------------------------------------------------------------------------------- /backend/uploads/rik-i-morti-rick-and-morty-rick-sanchez-rick-sanchez-morty-6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/rik-i-morti-rick-and-morty-rick-sanchez-rick-sanchez-morty-6.jpg -------------------------------------------------------------------------------- /backend/uploads/store/products/product1-big.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/store/products/product1-big.jpg -------------------------------------------------------------------------------- /backend/uploads/user-no-img.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kannifarhad/CronusFileManager/3bca39ca27173880e49022a21a981ec2282954d5/backend/uploads/user-no-img.jpg -------------------------------------------------------------------------------- /frontend/.env.example: -------------------------------------------------------------------------------- 1 | EXTEND_ESLINT=true 2 | VITE_S3_ACCESS_KEY=your_access_key 3 | VITE_S3_SECRET_KEY=your_secret_key 4 | VITE_BACKEND_URL=http://localhost:3131 -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /frontend/.nvmrc: -------------------------------------------------------------------------------- 1 | v22 -------------------------------------------------------------------------------- /frontend/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import reactHooks from 'eslint-plugin-react-hooks' 4 | import reactRefresh from 'eslint-plugin-react-refresh' 5 | import tseslint from 'typescript-eslint' 6 | import { defineConfig, globalIgnores } from 'eslint/config' 7 | 8 | export default defineConfig([ 9 | globalIgnores(['dist']), 10 | { 11 | files: ['**/*.{ts,tsx}'], 12 | extends: [ 13 | js.configs.recommended, 14 | tseslint.configs.recommended, 15 | reactHooks.configs['recommended-latest'], 16 | reactRefresh.configs.vite, 17 | ], 18 | languageOptions: { 19 | ecmaVersion: 2020, 20 | globals: globals.browser, 21 | }, 22 | }, 23 | ]) 24 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cronus-file-manager", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc -b && vite build", 9 | "lint": "eslint .", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "@aws-sdk/client-s3": "^3.651.1", 14 | "@aws-sdk/s3-request-presigner": "^3.651.1", 15 | "@dnd-kit/core": "^6.1.0", 16 | "@emotion/react": "^11.13.3", 17 | "@emotion/styled": "^11.13.0", 18 | "@mui/material": "^6.1.3", 19 | "@mui/system": "^6.1.3", 20 | "axios": "^1.7.2", 21 | "fabric": "^6.0.2", 22 | "react": "^19.1.1", 23 | "react-dom": "^19.1.1", 24 | "react-dropzone": "^14.2.3", 25 | "react-virtualized": "^9.22.6", 26 | "tui-image-editor": "^3.15.3" 27 | }, 28 | "devDependencies": { 29 | "@eslint/js": "^9.36.0", 30 | "@types/node": "^24.6.2", 31 | "@types/react": "^19.1.16", 32 | "@types/react-dom": "^19.1.9", 33 | "@types/react-virtualized": "^9.22.3", 34 | "@vitejs/plugin-react": "^5.0.4", 35 | "babel-plugin-react-compiler": "^19.1.0-rc.3", 36 | "eslint": "^9.36.0", 37 | "eslint-plugin-react-hooks": "^5.2.0", 38 | "eslint-plugin-react-refresh": "^0.4.22", 39 | "globals": "^16.4.0", 40 | "typescript": "~5.9.3", 41 | "typescript-eslint": "^8.45.0", 42 | "vite": "^7.1.7", 43 | "vite-plugin-svgr": "^4.5.0" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /frontend/public/css/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: "Montserrat"; 3 | padding: 0px; 4 | } 5 | #root { 6 | max-width: 1300px; 7 | margin: 0px auto; 8 | } 9 | .demo-content { 10 | max-width: 1200px; 11 | margin: 50px auto 100px auto; 12 | padding: 50px; 13 | border-radius: 5px; 14 | border: 1px solid #ccc; 15 | } 16 | .demo-content pre { 17 | background: #f1f1f1; 18 | border-radius: 7px; 19 | padding: 20px 0px; 20 | color: #666; 21 | font-style: italic; 22 | } 23 | .demo-content img { 24 | margin: 0px auto; 25 | display: block; 26 | } 27 | .demo-content p { 28 | font-size: 14px; 29 | } 30 | .demo-content ul li { 31 | font-size: 14px; 32 | padding: 5px 0px; 33 | } 34 | .demo-content a { 35 | color: #0492f2; 36 | } 37 | .demo-content h1 { 38 | text-align: center; 39 | } 40 | .lisence p { 41 | font-size: 11px; 42 | } 43 | 44 | .MuiTableRow-head th:first-of-type { 45 | -webkit-border-top-left-radius: 5px; 46 | -moz-border-radius-topleft: 5px; 47 | border-top-left-radius: 5px; 48 | } 49 | 50 | .MuiTableRow-head th:last-child { 51 | -webkit-border-top-right-radius: 5px; 52 | -moz-border-radius-topright: 5px; 53 | border-top-right-radius: 5px; 54 | } 55 | -------------------------------------------------------------------------------- /frontend/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import FileManager from "./FileManager/index"; 3 | import { type VolumeListType, VolumeTypes } from "./FileManager/types"; 4 | 5 | const volumesList: VolumeListType = [ 6 | { 7 | id: "1", 8 | type: VolumeTypes.SERVER, 9 | endpoint: import.meta.env.VITE_BACKEND_URL!, 10 | name: "My EC2 server", 11 | }, 12 | { 13 | id: "2", 14 | type: VolumeTypes.S3BUCKET_BACK, 15 | endpoint: import.meta.env.VITE_BACKEND_URL!, 16 | bucket: "cronusfilemanager", 17 | name: "S3 Server Connection", 18 | }, 19 | { 20 | id: "3", 21 | type: VolumeTypes.S3BUCKET_FRONT, 22 | bucket: "cronusfilemanager", 23 | name: "S3 Front Connection", 24 | region: "us-east-1", 25 | endpoint: "http://192.168.1.18:9001", 26 | credentials: { 27 | accessKeyId: import.meta.env.VITE_S3_ACCESS_KEY!, 28 | secretAccessKey: import.meta.env.REACT_APP_S3_SECRET_KEY!, 29 | }, 30 | }, 31 | ]; 32 | 33 | const App: React.FC = () => { 34 | const handleCallBack = (filePath: string) => { 35 | console.log("Image Path Returned", filePath); 36 | }; 37 | 38 | return ( 39 | 44 | ); 45 | }; 46 | 47 | export default App; 48 | -------------------------------------------------------------------------------- /frontend/src/FileManager/FileManager.tsx: -------------------------------------------------------------------------------- 1 | import React, { memo } from "react"; 2 | import { ThemeProvider } from "@mui/system"; 3 | import { FileManagerWrapper } from "./styled"; 4 | import FileManagerContainer from "./FileManagerContainer"; 5 | import PopupDialog from "./components/elements/PopupDialog"; 6 | import ImageEditPopup from "./components/elements/ImageEditor"; 7 | import { useFileManagerState } from "./store/FileManagerContext"; 8 | import useCurrentTheme from "./hooks/useCurrentTheme"; 9 | 10 | const FileManager: React.FC<{ height: number }> = ({ height }) => { 11 | const { fullScreen } = useFileManagerState(); 12 | const theme = useCurrentTheme(); 13 | return ( 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | ); 22 | }; 23 | 24 | export default memo(FileManager); 25 | -------------------------------------------------------------------------------- /frontend/src/FileManager/FileManagerContainer.tsx: -------------------------------------------------------------------------------- 1 | import React, { memo } from "react"; 2 | import { Paper, Grid } from "@mui/material"; 3 | import TopBar from "./components/sections/topBar"; 4 | import FolderBar from "./components/sections/folderBar"; 5 | import FilesBar from "./components/sections/filesBar"; 6 | 7 | const FileManager: React.FC = () => ( 8 | 17 | 18 | 29 | 30 | 31 | 32 | 33 | ); 34 | 35 | export default memo(FileManager); 36 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/add-1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/add-2.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/add-user.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/alarm.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/analytics.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/archive.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/arroba.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/bag.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/book.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/calendar-1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/calendar.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/cash.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/chat.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/coding.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/crop.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/delete.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/dislike.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/document.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/double-arrow.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/doubt.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/down-arrow.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/download-1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/download.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/email-1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/envelope.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/eraser.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/export.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/facebook.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/files-and-folders.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/flag.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/followers.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/forward.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/funnel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/github.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/graph.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/heart.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/hide.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/home.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/icon-748150.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/id-card.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/image.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/instagram.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/layout.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/left-arrow.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/like.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/line-chart.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/link.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/linkedin.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/list.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/lock.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/mailbox.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/megaphone.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/menu.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/message.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/minimize.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/money-1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/money.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/multimedia-option.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/newspaper.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/no-entry.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/open-box.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/open-menu.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/paper-plane.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/paperclip.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/pen.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/photo-camera.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/picture.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/pie-chart.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/placeholder.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/pointer.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/presentation.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/print.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/pulse.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/resize.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/server.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/share.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/shield.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/shopping-cart.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/signature.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/substract.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/success.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/telephone.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/text-1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/three-dots-menu.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/thunder.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/tick.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/translate.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/turn-off.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/ui.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/undo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/user-1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/user-2.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/user-3.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/user.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/wall-clock.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/Inactive/warning.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/files/avi.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/files/file.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/files/flash.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/files/folder.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 10 | 12 | 13 | 15 | 16 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/files/folderfull.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 14 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | 34 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/files/folderopen.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | 11 | 13 | 14 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/files/gif.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 13 | 14 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/files/zip-1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/add.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/addFolder.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/backward.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/ban.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/cancel-1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/cancel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/copy.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/cursor.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/cut.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/delete-folder.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/download.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/exit.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/folder.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/folderOpen.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/forward.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/gridView.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/information.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/layers.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/listView.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/loupe.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/paste.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/pencil.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/refresh.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/resize.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/save.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/selectAll.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/text.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/trash.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/unZip.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/upload.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/view.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/vol2.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 10 | 13 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/vol3.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 10 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/icons/line/zip.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/FileManager/assets/translations/en.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | select: "Choose", 3 | yes: "Yes", 4 | no: "No", 5 | name: "Name", 6 | loading: "Loading", 7 | size: "Size", 8 | accept: "Accept", 9 | created: "Created", 10 | search: "Search...", 11 | noResults: "No results had been found.", 12 | searchLimit: "text should be more than 3 symbol", 13 | everywhere: "Everywhere", 14 | emptyFolder: "The folder is empty!", 15 | onSelectedFolder: "On selected folder", 16 | selectFolderWarn: "Please select folder to view!", 17 | }; 18 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/elements/ButtonGroup.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ButtonGroup from "@mui/material/ButtonGroup"; 3 | import type { ButtonProps } from "@mui/material/Button"; 4 | import { StyledActionButton } from "./styled"; 5 | import Icon, { type IconName } from "./Icon"; 6 | 7 | export interface ButtonItemType extends Omit { 8 | icon: IconName; 9 | label: string; 10 | onClick: (params: any) => void; 11 | } 12 | export type ButtonGroupProps = { buttons: ButtonItemType[] }; 13 | 14 | const CustomButtonGroup: React.FC = ({ buttons }) => { 15 | const buttonComponents = buttons.map((button) => ( 16 | } 20 | > 21 | {button.label} 22 | 23 | )); 24 | 25 | return ( 26 | 27 | {buttonComponents} 28 | 29 | ); 30 | }; 31 | 32 | export default CustomButtonGroup; 33 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/elements/ButtonGroupSimple.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Button from "@mui/material/Button"; 3 | import ButtonGroup from "@mui/material/ButtonGroup"; 4 | 5 | interface ButtonData { 6 | label: string; 7 | onClick: () => void; 8 | disabled?: boolean; 9 | icon?: string; 10 | } 11 | 12 | interface ButtonGroupSimpleProps { 13 | buttons: ButtonData[]; 14 | } 15 | 16 | const ButtonGroupSimple: React.FC = ({ buttons }) => ( 17 |
18 | 19 | {buttons.map((button) => ( 20 | 29 | ))} 30 | 31 |
32 | ); 33 | 34 | export default ButtonGroupSimple; 35 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/elements/ContentIcons.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { imagesMap } from "../../assets/icons/files"; 3 | 4 | export type ContentIconType = keyof typeof imagesMap; 5 | 6 | export interface ContentIconsProps extends React.SVGProps { 7 | name: ContentIconType; 8 | color?: string; 9 | size?: number; 10 | } 11 | 12 | const ContentIcons: React.FC = ({ name, color = "#2a2a2a", size = 15, ...rest }) => { 13 | const SelectedIcon = imagesMap[name]; 14 | 15 | if (!SelectedIcon) { 16 | console.warn(`Icon not found: ${name}`); 17 | return null; 18 | } 19 | 20 | return ; 21 | }; 22 | 23 | export default ContentIcons; 24 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/elements/Icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { iconMap } from "../../assets/icons/line"; 3 | 4 | export type IconName = keyof typeof iconMap; 5 | 6 | export interface IconProps extends React.SVGProps { 7 | name: IconName; 8 | color?: string; 9 | size?: number; 10 | } 11 | 12 | const Icon: React.FC = ({ name, color = "#ccc", size = 15, ...rest }) => { 13 | const SelectedIcon = iconMap[name]; 14 | 15 | if (!SelectedIcon) { 16 | console.warn(`Icon not found: ${name}`); 17 | return null; 18 | } 19 | 20 | return ; 21 | }; 22 | 23 | export default Icon; 24 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/elements/InputField.tsx: -------------------------------------------------------------------------------- 1 | import { type ChangeEvent } from "react"; 2 | import { TextField, type TextFieldProps } from "@mui/material"; 3 | 4 | interface InputFieldProps extends Omit { 5 | onChange: (value: string) => void; 6 | } 7 | 8 | export default function InputField(props: InputFieldProps) { 9 | const { onChange, ...rest } = props; 10 | 11 | const handleChange = (event: ChangeEvent) => { 12 | onChange(event.target.value); 13 | }; 14 | 15 | return ; 16 | } 17 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/sections/filesBar/DropZoneWrapper.tsx: -------------------------------------------------------------------------------- 1 | import { memo, useCallback, useEffect } from "react"; 2 | import Dropzone from "../../elements/Dropzone"; 3 | import { useFileManagerState } from "../../../store/FileManagerContext"; 4 | 5 | function DropZoneWrapper() { 6 | const { 7 | uploadPopup, 8 | operations: { handleToggleUploadPopUp }, 9 | } = useFileManagerState(); 10 | 11 | const handleDragEnter = useCallback(() => { 12 | handleToggleUploadPopUp(true); 13 | }, [handleToggleUploadPopUp]); 14 | 15 | useEffect(() => { 16 | window.addEventListener("dragenter", handleDragEnter); 17 | return () => { 18 | window.removeEventListener("dragenter", handleDragEnter); 19 | }; 20 | }, [handleDragEnter]); 21 | if (!uploadPopup) return null; 22 | 23 | return ; 24 | } 25 | 26 | export default memo(DropZoneWrapper); 27 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/sections/filesBar/FilesListContainer.tsx: -------------------------------------------------------------------------------- 1 | import React, { memo, useCallback, type MouseEvent } from "react"; 2 | import ViewItems from "../viewItems/ViewItems"; 3 | import { StyledFilesListContainer, StyledFilesListWrapper } from "./styled"; 4 | import OverlayBlocks from "./OverlayBlocks"; 5 | import { useFileManagerState } from "../../../store/FileManagerContext"; 6 | import { ContextMenuTypeEnum } from "../../../types"; 7 | import { StyledEmptyFolderContainer } from "../viewItems/styled"; 8 | import useText from "../../../hooks/useTexts"; 9 | 10 | const ContainerBar: React.FC = () => { 11 | const { 12 | operations: { handleContextClick }, 13 | selectedFolder, 14 | search, 15 | } = useFileManagerState(); 16 | const texts = useText(); 17 | 18 | const handleContextMenuClick = useCallback( 19 | (event: MouseEvent) => { 20 | handleContextClick({ 21 | item: null, 22 | event, 23 | menuType: ContextMenuTypeEnum.CONTENT, 24 | }); 25 | }, 26 | [handleContextClick] 27 | ); 28 | 29 | if (!selectedFolder && !search.text) { 30 | return ( 31 | 32 |
{texts.selectFolderWarn}
33 |
34 | ); 35 | } 36 | 37 | return ( 38 | 39 | 40 | 41 | 42 | 43 | 44 | ); 45 | }; 46 | 47 | export default memo(ContainerBar); 48 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/sections/filesBar/FilesLoadingOverlay.tsx: -------------------------------------------------------------------------------- 1 | import { memo, type FC } from "react"; 2 | import { StyledFilesLoadingOverlay } from "./styled"; 3 | import { useFileManagerState } from "../../../store/FileManagerContext"; 4 | import useText from "../../../hooks/useTexts"; 5 | 6 | const FilesLoadingOverlay: FC = () => { 7 | const { loading } = useFileManagerState(); 8 | const texts = useText(); 9 | 10 | if (!loading) return null; 11 | 12 | return ( 13 | 14 |
{texts.loading}
15 |
16 | ); 17 | }; 18 | 19 | export default memo(FilesLoadingOverlay); 20 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/sections/filesBar/OverlayBlocks.tsx: -------------------------------------------------------------------------------- 1 | import { memo, type FC } from "react"; 2 | import DropZoneWrapper from "./DropZoneWrapper"; 3 | import FilesLoadingOverlay from "./FilesLoadingOverlay"; 4 | import ContextMenu from "./ContextMenu"; 5 | import ToasterMessages from "./ToasterMessages"; 6 | 7 | const OverlayBlocks: FC = () => ( 8 | <> 9 | 10 | 11 | 12 | 13 | 14 | ); 15 | 16 | export default memo(OverlayBlocks); 17 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/sections/filesBar/StatusBar.tsx: -------------------------------------------------------------------------------- 1 | import { memo, type FC, type MouseEvent } from "react"; 2 | import { Box, Button, Collapse } from "@mui/material"; 3 | import { useFileManagerState } from "../../../store/FileManagerContext"; 4 | import { ItemMoveActionTypeEnum } from "../../../types"; 5 | 6 | const StatusBar: FC = () => { 7 | const { 8 | operations: { handleClearBuffer }, 9 | bufferedItems, 10 | selectedFiles, 11 | } = useFileManagerState(); 12 | const selectIsActive = selectedFiles.size > 0 || bufferedItems.files.size > 0; 13 | 14 | return ( 15 | 16 | 17 | {selectedFiles.size > 0 && ( 18 | 19 | {selectedFiles.size} item{selectedFiles.size > 1 ? "s are" : " is"} selected 20 | 21 | )} 22 | {bufferedItems.files.size > 0 && ( 23 | 24 | {bufferedItems.files.size} 25 | {bufferedItems.type === ItemMoveActionTypeEnum.CUT ? " cut" : " copied"} item 26 | {selectedFiles.size > 1 ? "s are" : " is"} in buffer 27 | 40 | 41 | )} 42 | 43 | 44 | ); 45 | }; 46 | 47 | export default memo(StatusBar); 48 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/sections/filesBar/ToasterMessages.tsx: -------------------------------------------------------------------------------- 1 | import { memo, type FC } from "react"; 2 | import InfoBoxes from "../../elements/InfoBoxes"; 3 | import { StyledToasterMessages } from "./styled"; 4 | import { useFileManagerState } from "../../../store/FileManagerContext"; 5 | import type { Message } from "../../../types"; 6 | 7 | const ToasterMessages: FC = () => { 8 | const { messages } = useFileManagerState(); 9 | 10 | return ( 11 | 12 | {messages.map((alert: Message) => ( 13 | 14 | ))} 15 | 16 | ); 17 | }; 18 | 19 | export default memo(ToasterMessages); 20 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/sections/filesBar/index.tsx: -------------------------------------------------------------------------------- 1 | import React, { memo } from "react"; 2 | import { StyledFilesBarWrapper } from "./styled"; 3 | import StatusBar from "./StatusBar"; 4 | import FilesListContainer from "./FilesListContainer"; 5 | 6 | const FileBarWrapper: React.FC = () => { 7 | return ( 8 | 9 | 10 | 11 | 12 | ); 13 | }; 14 | 15 | export default memo(FileBarWrapper); 16 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/sections/filesBar/styled.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-empty-pattern */ 2 | import { styled } from "@mui/material/styles"; 3 | import { Grid, Box } from "@mui/material"; 4 | 5 | export const StyledFilesBarWrapper = styled(Grid)(({}) => ({ 6 | position: "relative", 7 | // overflow: "auto", 8 | flex: 1, 9 | height: "100%", 10 | display: "flex", 11 | flexDirection: "column", 12 | // background: "#fff", 13 | "& .infoMessages": { 14 | width: "100%", 15 | height: "40px", 16 | gap:"20px", 17 | display: "flex", 18 | alignItems: "center", 19 | justifyContent: "center", 20 | padding: "0px 15px", 21 | fontSize: "13px", 22 | // background: "#fff", 23 | textAlign: "center", 24 | borderTop: "1px solid #E9eef9", 25 | }, 26 | })); 27 | 28 | export const StyledFilesLoadingOverlay = styled(Box)(({}) => ({ 29 | position: "absolute", 30 | zIndex: "55", 31 | top: "0px", 32 | left: "0px", 33 | width: "100%", 34 | height: "100%", 35 | "& .opaOverlaw": { 36 | opacity: "0.8", 37 | background: "#fff", 38 | position: "absolute", 39 | width: "100%", 40 | height: "100%", 41 | display: "flex", 42 | alignItems: "center", 43 | justifyContent: "center", 44 | fontSize: "25px", 45 | fontWeight: "bold", 46 | }, 47 | })); 48 | 49 | export const StyledToasterMessages = styled(Box)(({}) => ({ 50 | zIndex: "66", 51 | position: "absolute", 52 | top: "20px", 53 | right: "20px", 54 | width: "300px", 55 | float: "right", 56 | })); 57 | 58 | export const StyledFilesListContainer = styled(Box)(({}) => ({ 59 | position: "relative", 60 | overflowY: "hidden", 61 | height: "100%", 62 | width: "100%", 63 | })); 64 | 65 | export const StyledFilesListWrapper = styled(Box)(({}) => ({ 66 | position: "relative", 67 | height: "100%", 68 | })); 69 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/sections/folderBar/MenuSubmenu.tsx: -------------------------------------------------------------------------------- 1 | import { type FC } from "react"; 2 | import { List } from "@mui/material"; 3 | import MenuItem from "./MenuItem"; 4 | import { type FolderList } from "../../../types"; 5 | 6 | interface MenuSubmenuProps { 7 | folderList: FolderList["children"]; 8 | } 9 | 10 | const MenuSubmenu: FC = ({ folderList }) => ( 11 | 12 | {Array.isArray(folderList) && folderList.map((child) => )} 13 | 14 | ); 15 | 16 | export default MenuSubmenu; 17 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/sections/folderBar/index.tsx: -------------------------------------------------------------------------------- 1 | import { memo } from "react"; 2 | import { StyledFolderBar, FileManagerFolderBarGrid, FileManagerFolderBarWrapper } from "./styled"; 3 | import VolumesList from "./VolumesList"; 4 | 5 | function FolderBar() { 6 | return ( 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | ); 15 | } 16 | export default memo(FolderBar); 17 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/sections/topBar/TopBarButtonGroups.tsx: -------------------------------------------------------------------------------- 1 | import React, { memo } from "react"; 2 | import { Tooltip, ButtonGroup, useTheme } from "@mui/material"; 3 | import { StyledButton, StyledButtonGroupWrapper } from "../../elements/styled"; 4 | import { type Button } from "../../../types"; 5 | import Icon from "../../elements/Icon"; 6 | 7 | interface ButtonGroupSimpleProps { 8 | buttons: Button[]; 9 | } 10 | 11 | const ButtonGroupSimple: React.FC = ({ buttons }) => { 12 | const theme = useTheme(); 13 | 14 | return ( 15 | 16 | 17 | {buttons.map((button) => ( 18 | 23 | 24 | 29 | 37 | 38 | 39 | 40 | ))} 41 | 42 | 43 | ); 44 | }; 45 | 46 | export default memo(ButtonGroupSimple); 47 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/sections/topBar/settingsMenu/ImageViewOptions.tsx: -------------------------------------------------------------------------------- 1 | import { memo } from "react"; 2 | import { Radio, FormControlLabel, Grid2 as Grid, FormLabel, Box } from "@mui/material"; 3 | import { StyledTopBarMenuItem } from "../styled"; 4 | import { imageViewOptions } from "./constants"; 5 | import { useFileManagerState } from "../../../../store/FileManagerContext"; 6 | 7 | const ImageViewOptions = () => { 8 | const { 9 | settings, 10 | operations: { handleSetThumbView }, 11 | } = useFileManagerState(); 12 | 13 | return ( 14 | 15 | Images on files list 16 | 17 | {imageViewOptions.map((option) => ( 18 | 19 | handleSetThumbView(option.value)} 22 | > 23 | 27 | } 28 | label={option.name} 29 | /> 30 | 31 | 32 | ))} 33 | 34 | 35 | ); 36 | }; 37 | 38 | export default memo(ImageViewOptions); 39 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/sections/topBar/settingsMenu/ThemeSelection.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-explicit-any */ 2 | import { memo } from "react"; 3 | import { Grid2 as Grid, FormLabel, Box } from "@mui/material"; 4 | import { SettingsSelect, SettingsSelectOption } from "../styled"; 5 | import { themeList } from "../../../../hooks/useCurrentTheme"; 6 | import { useFileManagerState } from "../../../../store/FileManagerContext"; 7 | 8 | const ThemeSelection = () => { 9 | const { 10 | settings, 11 | operations: { handleSelectTheme }, 12 | } = useFileManagerState(); 13 | 14 | return ( 15 | 16 | Theme 17 | 18 | { 24 | if (event.target.dataset.value) { 25 | handleSelectTheme(event.target.dataset.value); 26 | } 27 | }} 28 | > 29 | {themeList.map((option) => ( 30 | 31 | {option.name} 32 | 33 | ))} 34 | 35 | 36 | 37 | ); 38 | }; 39 | 40 | export default memo(ThemeSelection); 41 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/sections/topBar/settingsMenu/constants.ts: -------------------------------------------------------------------------------- 1 | import { ImagesThumbTypeEnum, OrderByFieldEnum, SortByFieldEnum } from "../../../../types"; 2 | 3 | export enum SettingsMenuEnum { 4 | SETTINGS = "SETTINGS", 5 | SEARCH = "SEARCH", 6 | SORTING = "SORTING", 7 | } 8 | 9 | export const orderOptions = [ 10 | { name: "By Name", value: OrderByFieldEnum.NAME }, 11 | { name: "By Size", value: OrderByFieldEnum.SIZE }, 12 | { name: "By Create Date", value: OrderByFieldEnum.DATE }, 13 | ]; 14 | 15 | export const sortOptions = [ 16 | { name: "Ascending", value: SortByFieldEnum.ASC }, 17 | { name: "Descending", value: SortByFieldEnum.DESC }, 18 | ]; 19 | 20 | export const imageViewOptions = [ 21 | { name: "Show Icons", value: ImagesThumbTypeEnum.ICONS }, 22 | { name: "Show Thumbs", value: ImagesThumbTypeEnum.THUMB }, 23 | ]; 24 | 25 | export interface SettingsPopoverMenuProps { 26 | anchorEl: HTMLElement | null; 27 | open: SettingsMenuEnum; 28 | onClose: () => void; 29 | } 30 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/sections/topBar/settingsMenu/index.tsx: -------------------------------------------------------------------------------- 1 | import { memo } from "react"; 2 | import ImageViewOptions from "./ImageViewOptions"; 3 | import SortingOptions from "./SortingOptions"; 4 | import ThemeSelection from "./ThemeSelection"; 5 | 6 | const Settings = () => ( 7 | <> 8 | 9 | 10 | 11 | 12 | ); 13 | 14 | export default memo(Settings); 15 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/sections/topBar/styled.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-empty-pattern */ 2 | import { styled } from "@mui/material/styles"; 3 | import { Grid2 as Grid, MenuItem, Popover, Select } from "@mui/material"; 4 | 5 | export const TopBarWrapper = styled(Grid)(({ theme }) => ({ 6 | padding: "5px", 7 | borderBottom: `1px solid ${theme.cronus.topBar.borderColor}`, 8 | background: theme.cronus.topBar.background, 9 | flex: "none", 10 | overflow: "hidden", 11 | })); 12 | 13 | export const StyledTopBarMenuItem = styled(MenuItem)(({}) => ({ 14 | padding: "0px", 15 | fontSize: "13px", 16 | borderRadius: "5px", 17 | display: "block", 18 | "& span": { 19 | fontSize: "13px", 20 | }, 21 | "& label": { 22 | margin: "0px", 23 | }, 24 | "& svg": { 25 | width: "15px", 26 | }, 27 | })); 28 | 29 | export const SettingsPopover = styled(Popover)(({}) => ({ 30 | padding: "0px", 31 | "&>div": { 32 | // padding: "10px", 33 | }, 34 | })); 35 | export const SettingsSelectOption = styled(MenuItem)(({}) => ({ 36 | fontSize: "13px", 37 | })); 38 | export const SettingsSelect = styled(Select)(({}) => ({ 39 | fontSize: "13px", 40 | ".MuiSelect-root": { 41 | // fontSize: "12px", 42 | }, 43 | ".MuiSelect-select": { 44 | // fontSize: "12px", 45 | }, 46 | })); 47 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/sections/viewItems/App.css: -------------------------------------------------------------------------------- 1 | .grid-container { 2 | display: grid; 3 | grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); 4 | gap: 10px; 5 | } 6 | 7 | .item { 8 | background-color: lightgray; 9 | padding: 20px; 10 | text-align: center; 11 | border: 1px solid #ccc; 12 | cursor: pointer; 13 | transition: opacity 0.2s ease; 14 | } 15 | 16 | .item.file { 17 | background-color: lightcoral; 18 | } 19 | 20 | .item.folder { 21 | background-color: lightseagreen; 22 | } 23 | 24 | .item.selected { 25 | border: 2px solid blue; 26 | } 27 | 28 | .item.dragging { 29 | opacity: 0.5; 30 | } 31 | 32 | .dropzone { 33 | border: 2px dashed lightblue; 34 | min-height: 100px; 35 | padding: 10px; 36 | } 37 | 38 | .dropzone.over { 39 | border-color: lightgreen; 40 | } 41 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/sections/viewItems/ViewItems.tsx: -------------------------------------------------------------------------------- 1 | import React, { memo } from "react"; 2 | import GridView from "./gridLayout/GridView"; 3 | import ListView from "./tableLayout/ListView"; 4 | import { ViewTypeEnum } from "../../../types"; 5 | import { useFileManagerState } from "../../../store/FileManagerContext"; 6 | import { Box } from "@mui/system"; 7 | 8 | const ViewItems: React.FC = () => { 9 | const { settings } = useFileManagerState(); 10 | return settings.itemsViewType === ViewTypeEnum.GRID ? ( 11 | 12 | 13 | 14 | ) : ( 15 | 16 | ); 17 | }; 18 | 19 | export default memo(ViewItems); 20 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/sections/viewItems/gridLayout/DraggedElementsStack.tsx: -------------------------------------------------------------------------------- 1 | import { memo } from "react"; 2 | import { Box } from "@mui/material"; 3 | import type { Items, ItemsList } from "../../../../types"; 4 | import GridItemRender from "./GridItemRender"; 5 | import { ITEM_SIZE } from "./GridView"; 6 | 7 | const getRandomRotation = () => { 8 | return Math.floor(Math.random() * 30) - 15; 9 | }; 10 | 11 | const DraggedElementsStack = ({ filesList }: { filesList: Items[] }) => { 12 | const limitedFilesList: ItemsList = filesList.slice(0, 5); 13 | 14 | return ( 15 | 23 | {limitedFilesList.map((file, index) => ( 24 | 39 | 40 | 41 | ))} 42 | 43 | ); 44 | }; 45 | 46 | export default memo(DraggedElementsStack); 47 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/sections/viewItems/gridLayout/GridItemRender.tsx: -------------------------------------------------------------------------------- 1 | import { memo, type CSSProperties } from "react"; 2 | import { Box } from "@mui/material"; 3 | import FolderItem from "./FolderItem"; 4 | import FileItem from "./FileItem"; 5 | import { type Items, ItemType } from "../../../../types"; 6 | 7 | const GridItemRender = ({ item, ...rest }: { item: Items; style?: CSSProperties }) => ( 8 | 9 | {item.type === ItemType.FOLDER ? ( 10 | 11 | ) : item.type === ItemType.FILE ? ( 12 | 13 | ) : null} 14 | 15 | ); 16 | 17 | export default memo(GridItemRender); 18 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/sections/viewItems/gridLayout/ItemSelectButton.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-explicit-any */ 2 | import { memo, useCallback } from "react"; 3 | import { StyledSelectCheckbox, StyledPrivateIcon } from "../styled"; 4 | import { useFileManagerState } from "../../../../store/FileManagerContext"; 5 | import { type Items } from "../../../../types"; 6 | import { wasMultiSelectKeyUsed } from "../../../../utils"; 7 | 8 | function ItemSelectButton({ item }: { item: Items }) { 9 | const { 10 | operations: { handleAddSelected }, 11 | selectedFiles, 12 | } = useFileManagerState(); 13 | const isSelected = selectedFiles?.has(item); 14 | 15 | // Using onClick as it will be correctly 16 | // preventing if there was a drag 17 | const handleClick = useCallback( 18 | (event: any) => { 19 | if (event.defaultPrevented) { 20 | return; 21 | } 22 | // marking the event as used 23 | event.preventDefault(); 24 | handleAddSelected(item, wasMultiSelectKeyUsed(event)); 25 | }, 26 | [item, handleAddSelected] 27 | ); 28 | 29 | if (item.private) return ; 30 | 31 | return ; 32 | } 33 | 34 | export default memo(ItemSelectButton); 35 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/sections/viewItems/gridLayout/VirtualizedGrid.tsx: -------------------------------------------------------------------------------- 1 | import { memo } from "react"; 2 | import { AutoSizer, Grid, type GridCellRenderer, type GridProps } from "react-virtualized"; 3 | import { type ItemsList } from "../../../../types"; 4 | import GridItemRender from "./GridItemRender"; 5 | import { ITEM_SIZE } from "./GridView"; 6 | 7 | const VirtualizedGrid = ({ items }: { items: ItemsList }) => { 8 | const cellRenderer: GridCellRenderer = ({ columnIndex, key, rowIndex, style, parent }) => { 9 | // Type assertion for parent to include columnCount 10 | const { columnCount } = parent.props as GridProps; 11 | 12 | const itemIndex = rowIndex * columnCount + columnIndex; 13 | if (itemIndex >= items.length) return null; // Skip rendering empty cells 14 | 15 | const item = items[itemIndex]; 16 | return ; 17 | }; 18 | 19 | return ( 20 | 21 | {({ width, height }) => { 22 | const columnCount = Math.floor(width / ITEM_SIZE); 23 | const rowCount = Math.ceil(items.length / columnCount); 24 | 25 | return ( 26 | 35 | ); 36 | }} 37 | 38 | ); 39 | }; 40 | 41 | export default memo(VirtualizedGrid); 42 | -------------------------------------------------------------------------------- /frontend/src/FileManager/components/sections/viewItems/tableLayout/ListItemRender.tsx: -------------------------------------------------------------------------------- 1 | import { memo, type CSSProperties } from "react"; 2 | import FolderItem from "./ListFolderItem"; 3 | import FileItem from "./ListFileItem"; 4 | import { type Items, ItemType } from "../../../../types"; 5 | 6 | const ListItemRender = ({ item, style = {} }: { item: Items; style?: CSSProperties }) => 7 | item.type === ItemType.FOLDER ? ( 8 | 9 | ) : item.type === ItemType.FILE ? ( 10 | 11 | ) : null; 12 | 13 | export default memo(ListItemRender); 14 | -------------------------------------------------------------------------------- /frontend/src/FileManager/config.ts: -------------------------------------------------------------------------------- 1 | export const LOCASTORAGE_SETTINGS_KEY = "CRONUS_SETTINGS"; 2 | export const VOLUME_SETTINGS_LIST = ""; 3 | 4 | export const FILE_EXTENSION_MAP = { 5 | icons: { 6 | ".png": "png", 7 | ".jpg": "jpg", 8 | ".jpeg": "jpeg", 9 | ".doc": "doc", 10 | ".docx": "doc", 11 | ".xls": "xls", 12 | ".xlsx": "xls", 13 | ".pdf": "pdf", 14 | ".ppt": "ppt", 15 | ".pptx": "ppt", 16 | ".svg": "svg", 17 | ".xml": "xml", 18 | ".psd": "psd", 19 | ".ai": "ai", 20 | ".mp4": "mp4", 21 | ".txt": "txt", 22 | ".csv": "csv", 23 | ".zip": "zip", 24 | ".gif": "gif", 25 | ".rar": "zip-1", 26 | ".tar.gz": "zip-1", 27 | broken: "search", 28 | folder: "folder", 29 | folderopen: "folderopen", 30 | folderfull: "folderfull", 31 | }, 32 | textFiles: [".txt"], 33 | imageFiles: [".jpg", ".jpeg", ".png", ".svg", ".gif", ".webm"], 34 | archiveFiles: [".zip", ".tar.gz"], 35 | }; 36 | -------------------------------------------------------------------------------- /frontend/src/FileManager/hooks/useApiController.tsx: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import { type FileManagerState, VolumeTypes } from "../types"; 3 | import Ec2ServerConnection from "../apiSDKs/Ec2ServerConnection"; 4 | import S3FrontConnection from "../apiSDKs/S3FrontConnection"; 5 | import S3ServerConnection from "../apiSDKs/S3ServerConnection"; 6 | 7 | export const useApiController = ( 8 | selectedVolume: FileManagerState["selectedVolume"] 9 | ) => { 10 | const connection = useMemo(() => { 11 | if (!selectedVolume) return null; 12 | 13 | switch (selectedVolume.type) { 14 | case VolumeTypes.SERVER: { 15 | return new Ec2ServerConnection(selectedVolume.endpoint); 16 | } 17 | case VolumeTypes.S3BUCKET_BACK: { 18 | return new S3ServerConnection( 19 | selectedVolume.endpoint, 20 | selectedVolume.bucket 21 | ); 22 | } 23 | case VolumeTypes.S3BUCKET_FRONT: { 24 | return new S3FrontConnection(selectedVolume); 25 | } 26 | 27 | default: 28 | return null; 29 | } 30 | }, [selectedVolume]); 31 | return connection; 32 | }; 33 | 34 | export default useApiController; 35 | -------------------------------------------------------------------------------- /frontend/src/FileManager/hooks/useCurrentTheme.tsx: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import dark from "../themes/dark"; 3 | import light from "../themes/light"; 4 | import { useFileManagerState } from "../store/FileManagerContext"; 5 | import { type ThemeItemList } from "../types"; 6 | 7 | export const themeList: ThemeItemList = [ 8 | { 9 | id: "darkTheme", 10 | name: "Dark", 11 | theme: dark, 12 | }, 13 | { 14 | id: "lightTheme", 15 | name: "Light", 16 | theme: light, 17 | }, 18 | ]; 19 | 20 | export const useCurrentTheme = () => { 21 | const { settings } = useFileManagerState(); 22 | const currentTheme = useMemo( 23 | () => 24 | themeList.find((theme) => theme.id === settings.selectedTheme)?.theme ?? 25 | themeList[1].theme, 26 | [settings.selectedTheme] 27 | ); 28 | return currentTheme; 29 | }; 30 | 31 | export default useCurrentTheme; 32 | -------------------------------------------------------------------------------- /frontend/src/FileManager/hooks/useTexts.tsx: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import en from "../assets/translations/en"; 3 | 4 | const lang = "en"; 5 | export const useText = () => { 6 | const allTexts = useMemo(() => { 7 | switch (lang) { 8 | case "en": 9 | return en; 10 | default: 11 | return en; 12 | } 13 | }, []); 14 | return allTexts; 15 | }; 16 | 17 | export default useText; 18 | -------------------------------------------------------------------------------- /frontend/src/FileManager/index.tsx: -------------------------------------------------------------------------------- 1 | import React, { memo, forwardRef, useImperativeHandle } from "react"; 2 | import type { FileManagerProps } from "./types"; 3 | import { FileManagerProvider } from "./store/FileManagerContext"; 4 | import FileManager from "./FileManager"; 5 | 6 | const FileManagerWithProvider: React.FC = forwardRef( 7 | ({ selectItemCallback, height, volumesList }, ref) => { 8 | useImperativeHandle(ref, () => ({ 9 | refresh: () => { 10 | console.log("refresh requested"); 11 | }, 12 | })); 13 | 14 | return ( 15 | 16 | 17 | 18 | ); 19 | } 20 | ); 21 | 22 | export default memo(FileManagerWithProvider); 23 | -------------------------------------------------------------------------------- /frontend/src/FileManager/styled.ts: -------------------------------------------------------------------------------- 1 | import { styled } from "@mui/material/styles"; 2 | import { Box, type BoxProps } from "@mui/material"; 3 | 4 | export interface FileManagerWrapperProps extends BoxProps { 5 | expanded: boolean; 6 | } 7 | export const FileManagerWrapper = styled(Box, { 8 | shouldForwardProp: (prop: string) => !["expanded"].includes(prop), 9 | })(({ expanded, height }) => { 10 | if (expanded) { 11 | return { 12 | position: "fixed", 13 | top: "0", 14 | left: "0", 15 | height: "100%", 16 | width: "100%", 17 | zIndex: "999", 18 | padding: "20px", 19 | background: "rgba(255, 255, 255, 0.7)", 20 | }; 21 | } 22 | return { 23 | height: `${height}px`, 24 | display: "flex", 25 | alignItems: "stretch", 26 | width: "100%", 27 | }; 28 | }); 29 | -------------------------------------------------------------------------------- /frontend/src/FileManager/themes/light.ts: -------------------------------------------------------------------------------- 1 | import { createTheme } from "@mui/material/styles"; 2 | 3 | const theme = createTheme({ 4 | status: { 5 | danger: "#ff0000", 6 | }, 7 | cronus: { 8 | iconButton: { 9 | background: "#fff", 10 | backgroundEnabled: "#fff", 11 | disabledColor: "#ccc", 12 | activeColor: "#556cd6", 13 | borderColor: "#bcc7fd", 14 | borderActiveColor: "#ccc", 15 | }, 16 | topBar: { 17 | background: "#f6f7fd", 18 | borderColor: "#868DAA", 19 | }, 20 | folderBar: { 21 | background: "#f6f7fd", 22 | borderColor: "#E9eef9", 23 | iconColor: "#cccc", 24 | activeFolderBackground: "#30ccff57", 25 | volumeIconBack: "#556cd6", 26 | volumeActiveBackColor: "#fff", 27 | }, 28 | fileItems: { 29 | background: { 30 | hover: "#f7f7f7", 31 | selected: "#e0f0fb", 32 | selectMode: "#f7f7f7", 33 | }, 34 | title: { 35 | color: "", 36 | }, 37 | extension: { 38 | background: "#dadadaff", 39 | color: "#000000ff", 40 | }, 41 | cuted: "", 42 | }, 43 | dropzone: { 44 | background: "#f9fafc", 45 | droppablearea: { 46 | background: "#fff", 47 | color: "#bdbdbd", 48 | borderColor: "#ccc", 49 | }, 50 | boxShadow: "0px 2px 4px #bababa", 51 | borderColor: "#ccc", 52 | }, 53 | }, 54 | palette: { 55 | mode: "light", 56 | primary: { 57 | main: "#556cd6", 58 | }, 59 | secondary: { 60 | main: "#19857b", 61 | }, 62 | error: { 63 | main: "#f00", 64 | }, 65 | background: { 66 | default: "#fff", 67 | }, 68 | }, 69 | }); 70 | 71 | export default theme; 72 | -------------------------------------------------------------------------------- /frontend/src/FileManager/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./sanitazePath"; 2 | export * from "./helpers"; 3 | -------------------------------------------------------------------------------- /frontend/src/main.tsx: -------------------------------------------------------------------------------- 1 | // import { StrictMode } from 'react' 2 | import { createRoot } from 'react-dom/client' 3 | import App from './App.tsx' 4 | 5 | createRoot(document.getElementById('root')!).render( 6 | // 7 | 8 | // , 9 | ) 10 | -------------------------------------------------------------------------------- /frontend/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module "*.svg?react" { 4 | import * as React from "react"; 5 | const ReactComponent: React.FunctionComponent & { title?: string }>; 6 | export default ReactComponent; 7 | } 8 | // declare module "*.svg" { 9 | // import * as React from "react"; 10 | // export const ReactComponent: React.FunctionComponent< 11 | // React.SVGProps & { title?: string } 12 | // >; 13 | // export default ReactComponent; 14 | // } 15 | -------------------------------------------------------------------------------- /frontend/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 4 | "target": "ES2022", 5 | "useDefineForClassFields": true, 6 | "lib": ["ES2022", "DOM", "DOM.Iterable"], 7 | "module": "ESNext", 8 | "types": ["vite/client", "node"], 9 | "skipLibCheck": true, 10 | 11 | /* Bundler mode */ 12 | "moduleResolution": "bundler", 13 | "allowImportingTsExtensions": true, 14 | "verbatimModuleSyntax": true, 15 | "moduleDetection": "force", 16 | "noEmit": true, 17 | "jsx": "react-jsx", 18 | 19 | /* Linting */ 20 | "strict": true, 21 | "noUnusedLocals": true, 22 | "noUnusedParameters": true, 23 | "erasableSyntaxOnly": false, 24 | "noFallthroughCasesInSwitch": true, 25 | "noUncheckedSideEffectImports": true 26 | }, 27 | "include": ["src"] 28 | } 29 | -------------------------------------------------------------------------------- /frontend/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "./tsconfig.app.json" }, 5 | { "path": "./tsconfig.node.json" } 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /frontend/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 4 | "target": "ES2023", 5 | "lib": ["ES2023"], 6 | "module": "ESNext", 7 | "types": ["node"], 8 | "skipLibCheck": true, 9 | 10 | /* Bundler mode */ 11 | "moduleResolution": "bundler", 12 | "allowImportingTsExtensions": true, 13 | "verbatimModuleSyntax": true, 14 | "moduleDetection": "force", 15 | "noEmit": true, 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "erasableSyntaxOnly": false, 22 | "noFallthroughCasesInSwitch": true, 23 | "noUncheckedSideEffectImports": true 24 | }, 25 | "include": ["vite.config.ts"] 26 | } 27 | -------------------------------------------------------------------------------- /frontend/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import react from "@vitejs/plugin-react"; 3 | import svgr from "vite-plugin-svgr"; 4 | 5 | // https://vite.dev/config/ 6 | export default defineConfig({ 7 | plugins: [ 8 | react({ 9 | babel: { 10 | plugins: [["babel-plugin-react-compiler"]], 11 | }, 12 | }), 13 | svgr({ 14 | svgrOptions: { 15 | icon: true, 16 | }, 17 | }), 18 | ], 19 | server: { 20 | open: true, // Opens the browser on start 21 | port: 3000, // Default Vite port 22 | fs: { 23 | strict: false, // Allow history-based routing 24 | }, 25 | }, 26 | }); 27 | --------------------------------------------------------------------------------