From 51d063b0e58ff03af74e11ad5b89b7b52831bd3a Mon Sep 17 00:00:00 2001 From: Jan Szumotalski Date: Fri, 1 May 2026 22:34:26 +0200 Subject: [PATCH] removed file upload dialog removes file upload dialog from frontend, upload from backend along with parsing dependencies --- backend/package-lock.json | 122 +----------------- backend/package.json | 5 +- backend/src/routes/api/admin/menu.ts | 56 -------- .../menu-add/menu-add.component.html | 4 - .../menu-add/menu-add.component.scss | 3 + .../menu-edit/menu-add/menu-add.component.ts | 15 +-- .../menu-edit/menu-edit.component.ts | 10 -- .../menu-upload/menu-upload.component.html | 20 --- .../menu-upload/menu-upload.component.scss | 4 - .../menu-upload/menu-upload.component.spec.ts | 29 ----- .../menu-upload/menu-upload.component.ts | 30 ----- frontend/src/app/app.module.ts | 2 - .../src/app/services/updates.service.spec.ts | 3 +- 13 files changed, 9 insertions(+), 294 deletions(-) delete mode 100644 frontend/src/app/admin-view/menu-edit/menu-upload/menu-upload.component.html delete mode 100644 frontend/src/app/admin-view/menu-edit/menu-upload/menu-upload.component.scss delete mode 100644 frontend/src/app/admin-view/menu-edit/menu-upload/menu-upload.component.spec.ts delete mode 100644 frontend/src/app/admin-view/menu-edit/menu-upload/menu-upload.component.ts diff --git a/backend/package-lock.json b/backend/package-lock.json index 28c465c..99a9d05 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -16,7 +16,6 @@ "cors": "^2.8.5", "express": "^4.18.2", "mongoose": "^7.4.1", - "multer": "^2.0.2", "node-schedule": "^2.1.1", "passport": "^0.6.0", "passport-local": "^1.0.0", @@ -24,8 +23,7 @@ "speakeasy": "^2.0.0", "tx2": "^1.0.5", "underscore": "^1.13.8", - "web-push": "^3.6.7", - "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.1/xlsx-0.20.1.tgz" + "web-push": "^3.6.7" }, "devDependencies": { "@types/bcryptjs": "^2.4.2", @@ -33,7 +31,6 @@ "@types/cors": "^2.8.13", "@types/express": "^4.17.17", "@types/express-session": "^1.17.7", - "@types/multer": "^1.4.11", "@types/node-schedule": "^2.1.7", "@types/passport": "^1.0.12", "@types/passport-local": "^1.0.35", @@ -271,15 +268,6 @@ "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", "dev": true }, - "node_modules/@types/multer": { - "version": "1.4.11", - "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.11.tgz", - "integrity": "sha512-svK240gr6LVWvv3YGyhLlA+6LRRWA4mnGIU7RcNmgjBYFl6665wcXrRfxGp5tEPVHUNm5FMcmq7too9bxCwX/w==", - "dev": true, - "dependencies": { - "@types/express": "*" - } - }, "node_modules/@types/node": { "version": "20.4.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.5.tgz", @@ -787,11 +775,6 @@ "node": ">= 8" } }, - "node_modules/append-field": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", - "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" - }, "node_modules/array-differ": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", @@ -1040,18 +1023,8 @@ "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true }, "node_modules/bytes": { "version": "3.1.2", @@ -1293,21 +1266,6 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "node_modules/concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "engines": [ - "node >= 6.0" - ], - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } - }, "node_modules/connect-history-api-fallback": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", @@ -2951,25 +2909,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/multer": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/multer/-/multer-2.1.0.tgz", - "integrity": "sha512-TBm6j41rxNohqawsxlsWsNNh/VdV4QFXcBvRcPhXaA05EZ79z0qJ2bQFpync6JBoHTeNY5Q1JpG7AlTjdlfAEA==", - "license": "MIT", - "dependencies": { - "append-field": "^1.0.0", - "busboy": "^1.6.0", - "concat-stream": "^2.0.0", - "type-is": "^1.6.18" - }, - "engines": { - "node": ">= 10.16.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/multi-stage-sourcemap": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/multi-stage-sourcemap/-/multi-stage-sourcemap-0.3.1.tgz", @@ -3470,20 +3409,6 @@ "node": ">= 0.8" } }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -3911,23 +3836,6 @@ "node": ">= 0.8" } }, - "node_modules/streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/string-template": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/string-template/-/string-template-1.0.0.tgz", @@ -4182,12 +4090,6 @@ "node": ">= 0.6" } }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "license": "MIT" - }, "node_modules/typescript": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", @@ -4279,12 +4181,6 @@ "which-typed-array": "^1.1.2" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" - }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -4584,18 +4480,6 @@ "node": ">=0.10.0" } }, - "node_modules/xlsx": { - "version": "0.20.1", - "resolved": "https://cdn.sheetjs.com/xlsx-0.20.1/xlsx-0.20.1.tgz", - "integrity": "sha512-hA7SYmn/H3cJ1VGi7kmSKxbEXCEn5UVJlwYFSFXhLe54wPUvW+80TmR5l+TZh4nJCw8G/e0SuZUfvqlTIh40hw==", - "license": "Apache-2.0", - "bin": { - "xlsx": "bin/xlsx.njs" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/backend/package.json b/backend/package.json index cc02306..ffb87d3 100644 --- a/backend/package.json +++ b/backend/package.json @@ -18,7 +18,6 @@ "cors": "^2.8.5", "express": "^4.18.2", "mongoose": "^7.4.1", - "multer": "^2.0.2", "node-schedule": "^2.1.1", "passport": "^0.6.0", "passport-local": "^1.0.0", @@ -26,8 +25,7 @@ "speakeasy": "^2.0.0", "tx2": "^1.0.5", "underscore": "^1.13.8", - "web-push": "^3.6.7", - "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.1/xlsx-0.20.1.tgz" + "web-push": "^3.6.7" }, "devDependencies": { "@types/bcryptjs": "^2.4.2", @@ -35,7 +33,6 @@ "@types/cors": "^2.8.13", "@types/express": "^4.17.17", "@types/express-session": "^1.17.7", - "@types/multer": "^1.4.11", "@types/node-schedule": "^2.1.7", "@types/passport": "^1.0.12", "@types/passport-local": "^1.0.35", diff --git a/backend/src/routes/api/admin/menu.ts b/backend/src/routes/api/admin/menu.ts index 70a8ce2..d21a8a8 100644 --- a/backend/src/routes/api/admin/menu.ts +++ b/backend/src/routes/api/admin/menu.ts @@ -1,24 +1,11 @@ import { Router } from "express" import { Perms, adminPerm, project } from "@/utility" -import multer from "multer" -import * as XLSX from "xlsx" import Menu from "@schemas/Menu" import { editorRouter } from "./editor" import usettings, { Features } from "@/helpers/usettings" const menuRouter = Router() -const storage = multer.memoryStorage() -const upload = multer({storage: storage}) - -interface sheetObject { - day: string; - sn: string; - sn2: string; - ob: string; - kol: string; -} - menuRouter.use(adminPerm(Perms.Menu)) menuRouter.use(usettings.mw(Features.Menu)) @@ -120,49 +107,6 @@ menuRouter.post('/:start/:count', async (req, res) => { } }) -menuRouter.post('/upload', upload.single('menu'), async (req,res)=> { - if (!req.file) { - res.status(400).send("File required") - return - } - var sheet = XLSX.read(req.file.buffer) - var data: sheetObject[] = XLSX.utils.sheet_to_json(sheet.Sheets[sheet.SheetNames[0]], {raw: true, header: ["day", "sn", "sn2", "ob", "kol"], range: 2}) - data = data.map((val, i) => { - var result: any = {} - var dateparts = val.day.match(/(\d{2})\.(\d{2})\.(\d{4})/) - if (dateparts) { - var date = new Date(parseInt(dateparts[3]),parseInt(dateparts[2])-1,parseInt(dateparts[1])) - date.setUTCHours(0,0,0,0) - } else { - res.sendStatus(500) - return - } - result.day = date - result.sn = val.sn.split('\n') - result.sn.push(val.sn2) - - //#region ob - var ob = val.ob - ob = ob.replace(/^\s*\n/gm, "") - ob = ob.replace(/ \/ /gm, "\n") - ob = ob.replace(/:(?!\s)/gm, ": ") - result.ob = ob.split('\n') - //#endregion - - result.kol = val.kol - if (date.getUTCDay() == 5) { - result.kol = null - } - return result - }) - - if (await Menu.insertMany(data)) { - res.status(201).send({status: 201}) - } else { - res.sendStatus(500) - } -}) - menuRouter.put('/:id', async (req, res) => { let menu = await Menu.findById(req.params.id) if (!menu) { diff --git a/frontend/src/app/admin-view/menu-edit/menu-add/menu-add.component.html b/frontend/src/app/admin-view/menu-edit/menu-add/menu-add.component.html index 074c72f..11ba598 100644 --- a/frontend/src/app/admin-view/menu-edit/menu-add/menu-add.component.html +++ b/frontend/src/app/admin-view/menu-edit/menu-add/menu-add.component.html @@ -3,7 +3,6 @@ Dzień Tydzień - Plik
@switch (type) { @@ -21,9 +20,6 @@ } - @case ("file") { - - } }
diff --git a/frontend/src/app/admin-view/menu-edit/menu-add/menu-add.component.scss b/frontend/src/app/admin-view/menu-edit/menu-add/menu-add.component.scss index e69de29..b6ca2af 100644 --- a/frontend/src/app/admin-view/menu-edit/menu-add/menu-add.component.scss +++ b/frontend/src/app/admin-view/menu-edit/menu-add/menu-add.component.scss @@ -0,0 +1,3 @@ +mat-dialog-content { + padding-bottom: 5px !important; +} diff --git a/frontend/src/app/admin-view/menu-edit/menu-add/menu-add.component.ts b/frontend/src/app/admin-view/menu-edit/menu-add/menu-add.component.ts index 4aa97b9..ac759fd 100644 --- a/frontend/src/app/admin-view/menu-edit/menu-add/menu-add.component.ts +++ b/frontend/src/app/admin-view/menu-edit/menu-add/menu-add.component.ts @@ -1,6 +1,5 @@ import { Component, inject, signal } from '@angular/core' -import { MenuUploadComponent } from '../menu-upload/menu-upload.component' -import { MatDialog, MatDialogRef } from '@angular/material/dialog' +import { MatDialogRef } from '@angular/material/dialog' import { FDSelection } from 'src/app/fd.da' import { FormControl, FormGroup } from '@angular/forms' import { MAT_DATE_RANGE_SELECTION_STRATEGY } from '@angular/material/datepicker' @@ -18,7 +17,6 @@ import { weekendFilter } from 'src/app/util' }) export class MenuAddComponent { public dialogRef: MatDialogRef = inject(MatDialogRef) - private dialog = inject(MatDialog) type: string | undefined filter = weekendFilter @@ -45,15 +43,4 @@ export class MenuAddComponent { break } } - - activateUpload() { - this.dialog - .open(MenuUploadComponent) - .afterClosed() - .subscribe(data => { - if (data) { - this.dialogRef.close({ type: 'file', ...data }) - } - }) - } } diff --git a/frontend/src/app/admin-view/menu-edit/menu-edit.component.ts b/frontend/src/app/admin-view/menu-edit/menu-edit.component.ts index 1bfe07c..80d6bdf 100644 --- a/frontend/src/app/admin-view/menu-edit/menu-edit.component.ts +++ b/frontend/src/app/admin-view/menu-edit/menu-edit.component.ts @@ -5,7 +5,6 @@ import { FDSelection } from 'src/app/fd.da' import { Menu } from 'src/app/types/menu' import { MatTableDataSource } from '@angular/material/table' import { MatDialog } from '@angular/material/dialog' -import { MenuUploadComponent } from './menu-upload/menu-upload.component' import { Status } from 'src/app/types/status' import { MatSnackBar } from '@angular/material/snack-bar' import { MenuAddComponent } from './menu-add/menu-add.component' @@ -121,15 +120,6 @@ export class MenuEditComponent implements OnDestroy { if (s.status.toString().match(/2\d\d/)) this.refresh() } - activateUpload() { - this.dialog - .open(MenuUploadComponent) - .afterClosed() - .subscribe(data => { - if (data) this.refresh() - }) - } - editSn(id: string) { this.ac .editSn(id, this.dataSource.data.find(v => v._id == id)!.sn) diff --git a/frontend/src/app/admin-view/menu-edit/menu-upload/menu-upload.component.html b/frontend/src/app/admin-view/menu-edit/menu-upload/menu-upload.component.html deleted file mode 100644 index a75b627..0000000 --- a/frontend/src/app/admin-view/menu-edit/menu-upload/menu-upload.component.html +++ /dev/null @@ -1,20 +0,0 @@ -

Import z pliku

- - - -
-

UWAGA!

-

Przed wysłaniem upewnij się że

-
    -
  • Daty w pliku są prawidłowe i poprawnie sformatowane (DD.MM.RRRR)
  • -
  • Wszystkie pozycje w menu są w osobnych linijkach
  • -
  • Załączony dokument to arkusz w formacie XLSX lub ODS
  • -
-

Nie spełnienie któregokolwiek z tych wymagań może skutkować szkodami w programie!

-

Późniejsza modyfikacja danych jest niemożliwa w tej wersji programu.

-
-
- - - - diff --git a/frontend/src/app/admin-view/menu-edit/menu-upload/menu-upload.component.scss b/frontend/src/app/admin-view/menu-edit/menu-upload/menu-upload.component.scss deleted file mode 100644 index e6f808d..0000000 --- a/frontend/src/app/admin-view/menu-edit/menu-upload/menu-upload.component.scss +++ /dev/null @@ -1,4 +0,0 @@ -:host { - margin: 8pt; - display: block; -} diff --git a/frontend/src/app/admin-view/menu-edit/menu-upload/menu-upload.component.spec.ts b/frontend/src/app/admin-view/menu-edit/menu-upload/menu-upload.component.spec.ts deleted file mode 100644 index 679501f..0000000 --- a/frontend/src/app/admin-view/menu-edit/menu-upload/menu-upload.component.spec.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing' - -import { MenuUploadComponent } from './menu-upload.component' -import { MatDialogModule, MatDialogRef } from '@angular/material/dialog' -import { MenuEditService } from '../menu-edit.service' - -xdescribe('MenuUploadComponent', () => { - let component: MenuUploadComponent - let fixture: ComponentFixture - - beforeEach(() => { - const acMock = jasmine.createSpyObj('AdminCommService') - TestBed.configureTestingModule({ - declarations: [MenuUploadComponent], - providers: [ - { provide: MenuEditService, useValue: acMock }, - { provide: MatDialogRef, useValue: {} }, - ], - imports: [MatDialogModule], - }) - fixture = TestBed.createComponent(MenuUploadComponent) - component = fixture.componentInstance - fixture.detectChanges() - }) - - it('should create', () => { - expect(component).toBeTruthy() - }) -}) diff --git a/frontend/src/app/admin-view/menu-edit/menu-upload/menu-upload.component.ts b/frontend/src/app/admin-view/menu-edit/menu-upload/menu-upload.component.ts deleted file mode 100644 index 64216c1..0000000 --- a/frontend/src/app/admin-view/menu-edit/menu-upload/menu-upload.component.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Component, inject } from '@angular/core' -import { MatDialogRef } from '@angular/material/dialog' -import { MenuEditService } from '../menu-edit.service' - -@Component({ - selector: 'app-upload-edit', - templateUrl: './menu-upload.component.html', - styleUrls: ['./menu-upload.component.scss'], - standalone: false, -}) -export class MenuUploadComponent { - private ac = inject(MenuEditService) - public dialogRef: MatDialogRef = inject(MatDialogRef) - - protected file: File | undefined - onFileChange(event: Event) { - const file: File = (event.target as HTMLInputElement).files![0] - if (file) { - this.file = file - } else { - this.file = undefined - } - } - - submit() { - this.ac.postMenu(this.file!)?.subscribe(value => { - this.dialogRef.close(value) - }) - } -} diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index c1fffe1..778d606 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -26,7 +26,6 @@ import { LogoutConfirmationComponent } from './app-view/personal/logout-confirma import { PersonalComponent } from './app-view/personal/personal.component' import { AppComponent } from './app.component' import { LoginComponent } from './login/login.component' -import { MenuUploadComponent } from './admin-view/menu-edit/menu-upload/menu-upload.component' import { NewsEditComponent } from './admin-view/news-edit/news-edit.component' import { MatSnackBarModule } from '@angular/material/snack-bar' import { NewPostComponent } from './admin-view/news-edit/new-post/edit-post.component' @@ -109,7 +108,6 @@ import { MatTooltipModule } from "@angular/material/tooltip"; LogoutConfirmationComponent, DateSelectorComponent, AdminViewComponent, - MenuUploadComponent, NewsEditComponent, NewPostComponent, AccountMgmtComponent, diff --git a/frontend/src/app/services/updates.service.spec.ts b/frontend/src/app/services/updates.service.spec.ts index e7a5377..2424396 100644 --- a/frontend/src/app/services/updates.service.spec.ts +++ b/frontend/src/app/services/updates.service.spec.ts @@ -10,7 +10,6 @@ import { withInterceptorsFromDi, } from '@angular/common/http' import { environment } from 'src/environments/environment' -import { firstValueFrom } from 'rxjs' describe('UpdatesService', () => { let service: UpdatesService @@ -33,7 +32,7 @@ describe('UpdatesService', () => { }) it('should grab news', () => { - const res = firstValueFrom(service.getNews()) + const res = service.getNews() const req = httpTestingController.expectOne(environment.apiEndpoint+`/app/news`) expect(res).withContext("empty news array").toBeDefined()