Merge branch '28-dropdown-for-eventtypes' into 'development'

Resolve "dropdown for eventtypes"

See merge request htwk-software/htwkalender!7
This commit is contained in:
Elmar Kresse
2024-05-18 23:34:47 +00:00
7 changed files with 124 additions and 7 deletions

View File

@@ -57,6 +57,10 @@ type Event struct {
models.BaseModel
}
type EventType struct {
EventType string `db:"EventType" json:"eventType"`
}
func (e *Event) Equals(event Event) bool {
return e.Day == event.Day &&
e.Week == event.Week &&

View File

@@ -363,7 +363,31 @@ func AddRoutes(app *pocketbase.PocketBase) {
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")
} 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{
@@ -390,7 +414,7 @@ func AddRoutes(app *pocketbase.PocketBase) {
slog.Error("Failed to delete events: ", "error", err)
return c.JSON(http.StatusBadRequest, "Failed to delete events")
} else {
return c.JSON(http.StatusBadRequest, "Events deleted")
return c.JSON(http.StatusOK, "Events deleted")
}
},
Middlewares: []echo.MiddlewareFunc{

View File

@@ -367,6 +367,17 @@ func GetEventsThatStartBeforeAndEndBefore(app *pocketbase.PocketBase, from types
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) {
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)

View File

@@ -198,3 +198,18 @@ func ContainsEvent(events model.Events, event model.Event) bool {
}
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
}

View 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;
}

View File

@@ -30,6 +30,7 @@ import { useDialog } from "primevue/usedialog";
import router from "../router";
import { fetchModule } from "../api/fetchModule.ts";
import { useI18n } from "vue-i18n";
import { fetchEventTypes } from "../api/fetchEvents.ts";
const dialog = useDialog();
const { t } = useI18n({ useScope: "global" });
@@ -39,6 +40,9 @@ if (store.isEmpty()) {
router.replace("/");
}
const eventTypes: Ref<string[]> = ref([]);
const mobilePage = inject("mobilePage") as Ref<boolean>;
const filters = ref({
course: {
@@ -51,7 +55,7 @@ const filters = ref({
},
eventType: {
value: null,
matchMode: FilterMatchMode.CONTAINS,
matchMode: FilterMatchMode.IN,
},
prof: {
value: null,
@@ -63,7 +67,7 @@ const loadedModules: Ref<Module[]> = ref(new Array(10));
const loadingData = ref(true);
onMounted(() => {
onMounted( () => {
fetchAllModules()
.then(
(data) =>
@@ -74,6 +78,10 @@ onMounted(() => {
.finally(() => {
loadingData.value = false;
});
fetchEventTypes().then((data) => {
eventTypes.value = data;
});
});
const ModuleInformation = defineAsyncComponent(
@@ -184,16 +192,20 @@ function unselectModule(event: DataTableRowUnselectEvent) {
</Column>
<Column
field="eventType"
filter-field="eventType"
:filter-menu-style="{ width: '10rem' }"
style="min-width: 10rem"
:header="$t('additionalModules.eventType')"
:show-clear-button="false"
:show-filter-menu="false"
>
<template #filter="{ filterModel, filterCallback }">
<InputText
<MultiSelect
v-model="filterModel.value"
type="text"
:options="eventTypes"
class="p-column-filter max-w-10rem"
@input="filterCallback()"
style="min-width: 10rem"
@change="filterCallback()"
/>
</template>
<template v-if="loadingData" #body>

View File

@@ -196,6 +196,24 @@ http {
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 {
proxy_pass http://htwkalender-backend:8090;
client_max_body_size 20m;