mirror of
https://gitlab.dit.htwk-leipzig.de/htwk-software/htwkalender.git
synced 2025-08-09 21:27:45 +02:00
Merge branch '28-dropdown-for-eventtypes' into 'development'
Resolve "dropdown for eventtypes" See merge request htwk-software/htwkalender!7
This commit is contained in:
@@ -57,6 +57,10 @@ type Event struct {
|
|||||||
models.BaseModel
|
models.BaseModel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EventType struct {
|
||||||
|
EventType string `db:"EventType" json:"eventType"`
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Event) Equals(event Event) bool {
|
func (e *Event) Equals(event Event) bool {
|
||||||
return e.Day == event.Day &&
|
return e.Day == event.Day &&
|
||||||
e.Week == event.Week &&
|
e.Week == event.Week &&
|
||||||
|
@@ -363,7 +363,31 @@ func AddRoutes(app *pocketbase.PocketBase) {
|
|||||||
slog.Error("Failed to get courses for semester with events: ", "error", err)
|
slog.Error("Failed to get courses for semester with events: ", "error", err)
|
||||||
return c.JSON(http.StatusBadRequest, "Failed to get courses for semester with events")
|
return c.JSON(http.StatusBadRequest, "Failed to get courses for semester with events")
|
||||||
} else {
|
} else {
|
||||||
return c.JSON(200, courses)
|
return c.JSON(http.StatusOK, courses)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Middlewares: []echo.MiddlewareFunc{
|
||||||
|
apis.ActivityLogger(app),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
// API Endpoint to get all eventTypes from the database distinct
|
||||||
|
app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
|
||||||
|
_, err := e.Router.AddRoute(echo.Route{
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/api/events/types",
|
||||||
|
Handler: func(c echo.Context) error {
|
||||||
|
eventTypes, err := events.GetEventTypes(app)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("Failed to get event types", "error", err)
|
||||||
|
return c.JSON(http.StatusBadRequest, "Failed to get event types")
|
||||||
|
} else {
|
||||||
|
return c.JSON(http.StatusOK, eventTypes)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Middlewares: []echo.MiddlewareFunc{
|
Middlewares: []echo.MiddlewareFunc{
|
||||||
@@ -390,7 +414,7 @@ func AddRoutes(app *pocketbase.PocketBase) {
|
|||||||
slog.Error("Failed to delete events: ", "error", err)
|
slog.Error("Failed to delete events: ", "error", err)
|
||||||
return c.JSON(http.StatusBadRequest, "Failed to delete events")
|
return c.JSON(http.StatusBadRequest, "Failed to delete events")
|
||||||
} else {
|
} else {
|
||||||
return c.JSON(http.StatusBadRequest, "Events deleted")
|
return c.JSON(http.StatusOK, "Events deleted")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Middlewares: []echo.MiddlewareFunc{
|
Middlewares: []echo.MiddlewareFunc{
|
||||||
|
@@ -367,6 +367,17 @@ func GetEventsThatStartBeforeAndEndBefore(app *pocketbase.PocketBase, from types
|
|||||||
return events, nil
|
return events, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetAllEventTypes(app *pocketbase.PocketBase) ([]model.EventType, error) {
|
||||||
|
var eventTypes []model.EventType
|
||||||
|
|
||||||
|
err := app.Dao().DB().Select("EventType").From("events").GroupBy("EventType").Distinct(true).All(&eventTypes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return eventTypes, nil
|
||||||
|
}
|
||||||
|
|
||||||
func GetEventsThatStartAfterAndEndAfter(app *pocketbase.PocketBase, from types.DateTime, to types.DateTime) (model.Events, error) {
|
func GetEventsThatStartAfterAndEndAfter(app *pocketbase.PocketBase, from types.DateTime, to types.DateTime) (model.Events, error) {
|
||||||
var events model.Events
|
var events model.Events
|
||||||
err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp("Start >= {:startDate} AND End >= {:endDate} AND Start <= {:endDate} AND End >= {:startDate}", dbx.Params{"startDate": from, "endDate": to})).All(&events)
|
err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp("Start >= {:startDate} AND End >= {:endDate} AND Start <= {:endDate} AND End >= {:startDate}", dbx.Params{"startDate": from, "endDate": to})).All(&events)
|
||||||
|
@@ -198,3 +198,18 @@ func ContainsEvent(events model.Events, event model.Event) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetEventTypes(app *pocketbase.PocketBase) ([]string, error) {
|
||||||
|
dbEventTypes, err := db.GetAllEventTypes(app)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the []model.EventType to []string
|
||||||
|
var eventTypes []string
|
||||||
|
for _, eventType := range dbEventTypes {
|
||||||
|
eventTypes = append(eventTypes, eventType.EventType)
|
||||||
|
}
|
||||||
|
|
||||||
|
return eventTypes, nil
|
||||||
|
}
|
||||||
|
33
frontend/src/api/fetchEvents.ts
Normal file
33
frontend/src/api/fetchEvents.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
//Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format.
|
||||||
|
//Copyright (C) 2024 HTWKalender support@htwkalender.de
|
||||||
|
|
||||||
|
//This program is free software: you can redistribute it and/or modify
|
||||||
|
//it under the terms of the GNU Affero General Public License as published by
|
||||||
|
//the Free Software Foundation, either version 3 of the License, or
|
||||||
|
//(at your option) any later version.
|
||||||
|
|
||||||
|
//This program is distributed in the hope that it will be useful,
|
||||||
|
//but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
//GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
//You should have received a copy of the GNU Affero General Public License
|
||||||
|
//along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// function to fetch course data from the API
|
||||||
|
|
||||||
|
export async function fetchEventTypes(): Promise<string[]> {
|
||||||
|
const eventTypes: string[] = [];
|
||||||
|
await fetch("/api/events/types")
|
||||||
|
.then((response) => {
|
||||||
|
return response.json() as Promise<string[]>;
|
||||||
|
})
|
||||||
|
.then((responseModules: string[]) => {
|
||||||
|
responseModules.forEach((eventType: string) => {
|
||||||
|
eventTypes.push(
|
||||||
|
eventType,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return eventTypes;
|
||||||
|
}
|
@@ -30,6 +30,7 @@ import { useDialog } from "primevue/usedialog";
|
|||||||
import router from "../router";
|
import router from "../router";
|
||||||
import { fetchModule } from "../api/fetchModule.ts";
|
import { fetchModule } from "../api/fetchModule.ts";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
|
import { fetchEventTypes } from "../api/fetchEvents.ts";
|
||||||
|
|
||||||
const dialog = useDialog();
|
const dialog = useDialog();
|
||||||
const { t } = useI18n({ useScope: "global" });
|
const { t } = useI18n({ useScope: "global" });
|
||||||
@@ -39,6 +40,9 @@ if (store.isEmpty()) {
|
|||||||
router.replace("/");
|
router.replace("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const eventTypes: Ref<string[]> = ref([]);
|
||||||
|
|
||||||
|
|
||||||
const mobilePage = inject("mobilePage") as Ref<boolean>;
|
const mobilePage = inject("mobilePage") as Ref<boolean>;
|
||||||
const filters = ref({
|
const filters = ref({
|
||||||
course: {
|
course: {
|
||||||
@@ -51,7 +55,7 @@ const filters = ref({
|
|||||||
},
|
},
|
||||||
eventType: {
|
eventType: {
|
||||||
value: null,
|
value: null,
|
||||||
matchMode: FilterMatchMode.CONTAINS,
|
matchMode: FilterMatchMode.IN,
|
||||||
},
|
},
|
||||||
prof: {
|
prof: {
|
||||||
value: null,
|
value: null,
|
||||||
@@ -74,6 +78,10 @@ onMounted(() => {
|
|||||||
.finally(() => {
|
.finally(() => {
|
||||||
loadingData.value = false;
|
loadingData.value = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
fetchEventTypes().then((data) => {
|
||||||
|
eventTypes.value = data;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const ModuleInformation = defineAsyncComponent(
|
const ModuleInformation = defineAsyncComponent(
|
||||||
@@ -184,16 +192,20 @@ function unselectModule(event: DataTableRowUnselectEvent) {
|
|||||||
</Column>
|
</Column>
|
||||||
<Column
|
<Column
|
||||||
field="eventType"
|
field="eventType"
|
||||||
|
filter-field="eventType"
|
||||||
|
:filter-menu-style="{ width: '10rem' }"
|
||||||
|
style="min-width: 10rem"
|
||||||
:header="$t('additionalModules.eventType')"
|
:header="$t('additionalModules.eventType')"
|
||||||
:show-clear-button="false"
|
:show-clear-button="false"
|
||||||
:show-filter-menu="false"
|
:show-filter-menu="false"
|
||||||
>
|
>
|
||||||
<template #filter="{ filterModel, filterCallback }">
|
<template #filter="{ filterModel, filterCallback }">
|
||||||
<InputText
|
<MultiSelect
|
||||||
v-model="filterModel.value"
|
v-model="filterModel.value"
|
||||||
type="text"
|
:options="eventTypes"
|
||||||
class="p-column-filter max-w-10rem"
|
class="p-column-filter max-w-10rem"
|
||||||
@input="filterCallback()"
|
style="min-width: 10rem"
|
||||||
|
@change="filterCallback()"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="loadingData" #body>
|
<template v-if="loadingData" #body>
|
||||||
|
@@ -196,6 +196,24 @@ http {
|
|||||||
limit_req zone=modules burst=5 nodelay;
|
limit_req zone=modules burst=5 nodelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
location /api/events/types {
|
||||||
|
proxy_pass http://htwkalender-backend:8090;
|
||||||
|
client_max_body_size 20m;
|
||||||
|
proxy_connect_timeout 600s;
|
||||||
|
proxy_read_timeout 600s;
|
||||||
|
proxy_send_timeout 600s;
|
||||||
|
send_timeout 600s;
|
||||||
|
proxy_cache_bypass 0;
|
||||||
|
proxy_no_cache 0;
|
||||||
|
proxy_cache mcache; # mcache=RAM
|
||||||
|
proxy_cache_valid 200 301 302 10m;
|
||||||
|
proxy_cache_valid 403 404 5m;
|
||||||
|
proxy_cache_lock on;
|
||||||
|
proxy_cache_use_stale timeout updating;
|
||||||
|
add_header X-Proxy-Cache $upstream_cache_status;
|
||||||
|
limit_req zone=modules burst=10 nodelay;
|
||||||
|
}
|
||||||
|
|
||||||
location /api/rooms {
|
location /api/rooms {
|
||||||
proxy_pass http://htwkalender-backend:8090;
|
proxy_pass http://htwkalender-backend:8090;
|
||||||
client_max_body_size 20m;
|
client_max_body_size 20m;
|
||||||
|
Reference in New Issue
Block a user