diff --git a/backend/service/addRoute.go b/backend/service/addRoute.go index 82c33de..3697e46 100644 --- a/backend/service/addRoute.go +++ b/backend/service/addRoute.go @@ -1,6 +1,7 @@ package service import ( + "htwkalender/service/db" "htwkalender/service/events" v1 "htwkalender/service/fetch/v1" v2 "htwkalender/service/fetch/v2" @@ -170,6 +171,29 @@ func AddRoutes(app *pocketbase.PocketBase) { return nil }) + app.OnBeforeServe().Add(func(e *core.ServeEvent) error { + _, err := e.Router.AddRoute(echo.Route{ + Method: http.MethodDelete, + Path: "/api/feed", + Handler: func(c echo.Context) error { + token := c.QueryParam("token") + err := db.DeleteFeed(app.Dao(), token) + if err != nil { + return c.JSON(http.StatusNotFound, err) + } else { + return c.JSON(http.StatusOK, "Feed deleted") + } + }, + Middlewares: []echo.MiddlewareFunc{ + apis.ActivityLogger(app), + }, + }) + if err != nil { + return err + } + return nil + }) + app.OnBeforeServe().Add(func(e *core.ServeEvent) error { _, err := e.Router.AddRoute(echo.Route{ Method: http.MethodGet, diff --git a/backend/service/db/dbFeeds.go b/backend/service/db/dbFeeds.go index 408d763..07e4a1f 100644 --- a/backend/service/db/dbFeeds.go +++ b/backend/service/db/dbFeeds.go @@ -1,6 +1,8 @@ package db import ( + "errors" + "github.com/pocketbase/dbx" "github.com/pocketbase/pocketbase" "github.com/pocketbase/pocketbase/daos" "github.com/pocketbase/pocketbase/models" @@ -39,6 +41,25 @@ func FindFeedByToken(token string, app *pocketbase.PocketBase) (*model.Feed, err return &feed, err } +func DeleteFeed(db *daos.Dao, feedId string) error { + + sqlResult, err := db.DB().Delete("feeds", dbx.NewExp("id = {:id}", dbx.Params{"id": feedId})).Execute() + var deletedRows int64 + if sqlResult != nil { + deletedRows, _ = sqlResult.RowsAffected() + } + + if err != nil { + return err + } else { + if deletedRows == 0 { + return errors.New("No feed with id " + feedId + " found") + } else { + return nil + } + } +} + func GetAllFeeds(db *daos.Dao) ([]model.Feed, error) { var feeds []model.Feed err := db.DB().Select("*").From("feeds").All(&feeds) diff --git a/backend/service/db/dbFeeds_test.go b/backend/service/db/dbFeeds_test.go new file mode 100644 index 0000000..33ea2fd --- /dev/null +++ b/backend/service/db/dbFeeds_test.go @@ -0,0 +1,55 @@ +package db + +import ( + "github.com/pocketbase/pocketbase/daos" + "github.com/pocketbase/pocketbase/tests" + "testing" +) + +const testDataDir = "./mockData" + +func TestDeleteFeed(t *testing.T) { + + setupTestApp := func(t *testing.T) *daos.Dao { + testApp, err := tests.NewTestApp(testDataDir) + if err != nil { + t.Fatal(err) + } + dao := daos.New(testApp.Dao().DB()) + return dao + } + + type args struct { + db *daos.Dao + feedId string + } + testsCases := []struct { + name string + args args + wantErr bool + }{ + { + name: "TestDeleteFeed", + args: args{ + db: setupTestApp(t), + feedId: "fkoqti06ohlnsb8", + }, + wantErr: false, + }, + { + name: "TestDeleteFeedNotExisting", + args: args{ + db: setupTestApp(t), + feedId: "test324", + }, + wantErr: true, + }, + } + for _, tt := range testsCases { + t.Run(tt.name, func(t *testing.T) { + if err := DeleteFeed(tt.args.db, tt.args.feedId); (err != nil) != tt.wantErr { + t.Errorf("DeleteFeed() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/backend/service/db/mockData/data.db b/backend/service/db/mockData/data.db new file mode 100644 index 0000000..acca65d Binary files /dev/null and b/backend/service/db/mockData/data.db differ diff --git a/backend/service/db/mockData/logs.db b/backend/service/db/mockData/logs.db new file mode 100644 index 0000000..1391d96 Binary files /dev/null and b/backend/service/db/mockData/logs.db differ diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 6d84655..6c8130d 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -19,6 +19,7 @@ const isDisabled = (routeName: RouteRecordName | null | undefined) => { + diff --git a/frontend/src/api/createFeed.ts b/frontend/src/api/createFeed.ts index da95ab0..bafb019 100644 --- a/frontend/src/api/createFeed.ts +++ b/frontend/src/api/createFeed.ts @@ -38,3 +38,18 @@ export async function saveIndividualFeed( }); return token; } + +export async function deleteIndividualFeed(token: string): Promise { + await fetch("/api/feed?token=" + token, { + method: "DELETE", + }).then ((response) => { + if (response.ok) { + return Promise.resolve(response); + } else { + return Promise.reject(response); + } + }).catch((error) => { + return Promise.reject(error); + }); + +} diff --git a/frontend/src/components/CalendarLink.vue b/frontend/src/components/CalendarLink.vue index 2507ca8..7b7e771 100644 --- a/frontend/src/components/CalendarLink.vue +++ b/frontend/src/components/CalendarLink.vue @@ -79,7 +79,7 @@ const actions = [ diff --git a/frontend/src/i18n/translations/de.json b/frontend/src/i18n/translations/de.json index a96dcdc..7d3694c 100644 --- a/frontend/src/i18n/translations/de.json +++ b/frontend/src/i18n/translations/de.json @@ -52,7 +52,21 @@ "headline": "Bearbeite deinen HTWKalender", "subTitle": "Füge deinen Link oder Token ein um den Kalender zu bearbeiten", "loadCalendar": "Kalender laden", - "noCalendarFound": "Keinen Kalender gefunden" + "noCalendarFound": "Keinen Kalender gefunden", + "save": "Speichern", + "delete": "Löschen", + "addModules": "Module hinzufügen", + "dialog": { + "headline": "Kalender löschen", + "subTitle": "Sind Sie sicher, dass Sie Ihren Kalender löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden.\nBitte entfernen Sie den Kalender anschließend aus Ihrer Kalender-App.", + "delete": "Löschen" + }, + "toast": { + "success": "Erfolg", + "error": "Fehler", + "successDetail": "Kalender erfolgreich gelöscht", + "errorDetail": "Fehler beim Löschen des Kalenders" + } }, "additionalModules": { "subTitle": "Füge weitere Module hinzu die nicht in deinem Studiengang enthalten sind.", diff --git a/frontend/src/i18n/translations/en.json b/frontend/src/i18n/translations/en.json index e68bc81..64a3d09 100644 --- a/frontend/src/i18n/translations/en.json +++ b/frontend/src/i18n/translations/en.json @@ -52,7 +52,21 @@ "headline": "edit your HTWKalender", "subTitle": "please enter your link or calendar token", "loadCalendar": "load calendar", - "noCalendarFound": "no calendar found" + "noCalendarFound": "no calendar found", + "save": "save", + "delete": "delete", + "addModules": "add modules", + "dialog": { + "headline": "delete calendar", + "subTitle": "Are you sure you want to delete your calendar? This action cannot be undone.\nPlease remove the calendar afterwords from your calendar app.", + "delete": "delete" + }, + "toast": { + "success": "Success", + "error": "Error", + "successDetail": "Calendar successfully deleted", + "errorDetail": "Calendar could not be deleted" + } }, "additionalModules": { "subTitle": "Select additional modules that are not listed in the regular semester for your course", diff --git a/frontend/src/main.ts b/frontend/src/main.ts index c2b5e96..93be59b 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -12,7 +12,7 @@ import Card from "primevue/card"; import DataView from "primevue/dataview"; import Dialog from "primevue/dialog"; import ToggleButton from "primevue/togglebutton"; -import "primevue/resources/themes/viva-dark/theme.css"; +import "primevue/resources/themes/tailwind-light/theme.css"; import "primeicons/primeicons.css"; import "primeflex/primeflex.css"; import router from "./router"; diff --git a/frontend/src/view/EditCalendarView.vue b/frontend/src/view/EditCalendarView.vue index 2952cb7..9ee6a2c 100644 --- a/frontend/src/view/EditCalendarView.vue +++ b/frontend/src/view/EditCalendarView.vue @@ -52,7 +52,7 @@ function loadCalendar(): void { moduleStore().addModule(module); }); modules.value = moduleStore().modules; - router.push("/edit-additional-modules"); + router.push("/edit-calendar"); } else { toast.add({ severity: "error", @@ -66,7 +66,6 @@ function loadCalendar(): void {