Skip to content

Commit

Permalink
Merge branch 'main' into 112-documentation-general-documentation
Browse files Browse the repository at this point in the history
# Conflicts:
#	anzeigen-frontend/src/components/AdNavBar.vue
  • Loading branch information
jannik.lange committed Jan 24, 2025
2 parents 2b801ee + 39b7f3a commit 998c217
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 1 deletion.
7 changes: 7 additions & 0 deletions anzeigen-frontend/src/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ export const API_ERROR_MSG =
export const CREATE_AD_SUCCESS = "Die Anzeige wurde erfolgreich erstellt.";
export const UPDATE_AD_SUCCESS = "Die Anzeige wurde erfolgreich aktualisiert.";
export const DELETE_AD_SUCCESS = "Die Anzeige wurde erfolgreich gelöscht.";
export const FILE_SIZE_TO_BIG = (size: string) =>
"Die ausgewählte(n) Datei(n) ist / sind zu groß. Maximal " + size + "MB.";
export const TOO_MANY_FILES = (amount: string) =>
"Die Anzahl der Dateien ist überschritten. Maximal " + amount + " Stück.";

/**
* Injection Keys
Expand All @@ -38,6 +42,9 @@ export const IK_IS_MYBOARD: InjectionKey<Readonly<Ref<boolean>>> = Symbol(
/**
* Other constants
*/
export const ALLOWED_FILE_TYPES =
"image/png, image/jpeg, image/jpg, application/pdf";
export const ALLOWED_IMAGE_TYPES = "image/png, image/jpeg, image/jpg";
export const AD_MAX_TITLE_LENGTH = 40;
export const DATE_DISPLAY_FORMAT = "DD.MM.YYYY"; // use this in conjunction with useDateFormat
export const DEFAULT_BOARD_QUERIES = {
Expand Down
35 changes: 35 additions & 0 deletions anzeigen-frontend/src/components/Ad/Edit/AdFilesUpload.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
:disabled="disabled"
class="mb-4"
multiple
:accept="ALLOWED_FILE_TYPES"
hide-details
:clearable="false"
variant="outlined"
Expand Down Expand Up @@ -37,6 +38,23 @@ import type { SwbFileTO } from "@/api/swbrett";
import { computed } from "vue";
import { VFileUploadItem } from "vuetify/labs/VFileUpload";
import { Levels } from "@/api/error.ts";
import { useSnackbar } from "@/composables/useSnackbar.ts";
import {
ALLOWED_FILE_TYPES,
FILE_SIZE_TO_BIG,
TOO_MANY_FILES,
} from "@/Constants.ts";
import { useSettingStore } from "@/stores/settings.ts";
const settingStore = useSettingStore();
const snackbar = useSnackbar();
const maxFileSize =
settingStore.getSetting("MAX_SWB_FILE_SIZE")?.numberValue || 1;
const maxFileNumber =
settingStore.getSetting("MAX_SWB_FILES_LENGTH")?.numberValue || 5;
const { modelValue } = defineProps<{
modelValue?: SwbFileTO[];
disabled?: boolean;
Expand Down Expand Up @@ -102,6 +120,23 @@ const uploadedFile = async (uploads: File[] | File) => {
uploads = [uploads];
}
if (uploads.length + toReturn.length > maxFileNumber) {
snackbar.sendMessage({
level: Levels.WARNING,
message: TOO_MANY_FILES(maxFileSize.toString()),
});
return;
}
const aggregatedFileSize = uploads.reduce((acc, file) => acc + file.size, 0);
if (aggregatedFileSize > maxFileSize * 1024 * 1024) {
snackbar.sendMessage({
level: Levels.WARNING,
message: FILE_SIZE_TO_BIG(maxFileSize.toString()),
});
return;
}
for (const file of uploads) {
if (
toReturn.some(
Expand Down
20 changes: 20 additions & 0 deletions anzeigen-frontend/src/components/Ad/Edit/AdTitelPicture.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
variant="outlined"
density="compact"
hide-details
:accept="ALLOWED_IMAGE_TYPES"
:disabled="disabled"
prepend-icon="mdi-panorama-outline"
:model-value="computedPicture"
Expand All @@ -17,6 +18,17 @@ import type { SwbImageTO } from "@/api/swbrett";
import { computed } from "vue";
import { Levels } from "@/api/error.ts";
import { useSnackbar } from "@/composables/useSnackbar.ts";
import { ALLOWED_IMAGE_TYPES, FILE_SIZE_TO_BIG } from "@/Constants.ts";
import { useSettingStore } from "@/stores/settings.ts";
const settingStore = useSettingStore();
const maxImageSize =
settingStore.getSetting("MAX_SWB_IMAGE_SIZE")?.numberValue || 1;
const snackbar = useSnackbar();
const { modelValue } = defineProps<{
modelValue: SwbImageTO | undefined;
disabled?: boolean;
Expand Down Expand Up @@ -52,6 +64,14 @@ const uploadPicture = async (files: File[] | File) => {
return;
}
if (file.size > maxImageSize * 1024 * 1024) {
snackbar.sendMessage({
level: Levels.WARNING,
message: FILE_SIZE_TO_BIG(maxImageSize.toString()),
});
return;
}
const reader = new FileReader();
reader.onloadend = function () {
const result = (reader.result as string).split(",")[1];
Expand Down
38 changes: 37 additions & 1 deletion anzeigen-frontend/src/components/AdNavBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
</template>

<script setup lang="ts">
import type { SettingTO } from "@/api/swbrett";
import { useRouteQuery } from "@vueuse/router";
import { computed, onMounted } from "vue";
import { useRoute } from "vue-router";
Expand All @@ -32,6 +34,7 @@ import FilterAdCategory from "@/components/Filter/FilterAdCategory.vue";
import FilterAdType from "@/components/Filter/FilterAdType.vue";
import SortAdSelection from "@/components/Filter/SortAdSelection.vue";
import UserFilter from "@/components/Filter/UserFilter.vue";
import { useGetSettings } from "@/composables/api/useSettingsApi.ts";
import {
useCreateUser,
useFindUser,
Expand All @@ -48,10 +51,12 @@ import {
ROUTES_MYBOARD,
} from "@/Constants";
import router from "@/plugins/router";
import { useSettingStore } from "@/stores/settings.ts";
import { useUserStore } from "@/stores/user";
const dialogBus = useDialogEventBus();
const userStore = useUserStore();
const settingStore = useSettingStore();
const snackbar = useSnackbar();
const userQuery = useRouteQuery(QUERY_NAME_USERID);
Expand Down Expand Up @@ -79,13 +84,23 @@ const {
loading: createUserLoading,
} = useCreateUser();
const {
call: getSettings,
data: settingsData,
loading: settingsLoading,
error: settingsError,
} = useGetSettings();
const triggerDialog = () => {
dialogBus.emit(AdTOFromJSONTyped(AdTOToJSONTyped(EMPTY_ADTO_OBJECT), false));
};
const loading = computed(
() =>
userInfoLoading.value || findUserLoading.value || createUserLoading.value
userInfoLoading.value ||
findUserLoading.value ||
createUserLoading.value ||
settingsLoading.value
);
const currentUser = computed(() => findUserData.value || createUserData.value);
Expand All @@ -112,11 +127,32 @@ const resetUserQuery = () => {
* Loads the user upon loading if not set.
*/
onMounted(() => {
if (!settingStore.isLoaded) {
loadSettings();
}
if (!userStore.userID) {
loadUser();
}
});
/**
* Loads settings and stores them in the settings store.
*/
const loadSettings = async () => {
await getSettings();
if (settingsError.value) {
snackbar.sendMessage({
level: Levels.ERROR,
message: API_ERROR_MSG,
});
return;
}
settingStore.setSettings(settingsData.value as SettingTO[]);
};
/**
* Loads current user. Therefore, requests all parameters from the sso endpoint and matches those with the backend.
* If no user exists a new one will be created.
Expand Down
23 changes: 23 additions & 0 deletions anzeigen-frontend/src/composables/api/useSettingsApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { GetSettingRequest, SettingTO } from "@/api/swbrett";

import { inject } from "vue";

import { useApiCall } from "@/composables/api/useApiCall.ts";
import { DEFAULT_API_KEY } from "@/composables/useApi.ts";

export const useGetSettings = () => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const api = inject(DEFAULT_API_KEY)!;

// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
return useApiCall<void, SettingTO[]>(() => api.getSettings());
};

export const useGetSetting = () => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const api = inject(DEFAULT_API_KEY)!;

return useApiCall<GetSettingRequest, SettingTO>((params) =>
api.getSetting(params)
);
};
24 changes: 24 additions & 0 deletions anzeigen-frontend/src/stores/settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { SettingTO, SettingTOSettingNameEnum } from "@/api/swbrett";

import { defineStore } from "pinia";
import { computed, ref } from "vue";

export const useSettingStore = defineStore("settings", () => {
const settings = ref<SettingTO[]>([]);

const isLoaded = computed(() => settings.value && settings.value.length > 0);

const setSettings = (payload: SettingTO[]) => {
settings.value = payload;
};

const getSetting = (settingName: SettingTOSettingNameEnum) =>
settings.value.find((setting) => setting.settingName === settingName);

return {
settings,
isLoaded,
setSettings,
getSetting,
};
});

0 comments on commit 998c217

Please sign in to comment.