Skip to content

Commit

Permalink
Adapt the client to the server changes for getting the list of posts
Browse files Browse the repository at this point in the history
  • Loading branch information
floscher committed Jun 21, 2024
1 parent ab1501a commit 3a7bfa1
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 37 deletions.
31 changes: 11 additions & 20 deletions client/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@
<li class="nav-item">
<RouterLink to="/posts" class="nav-link">{{ t("nav.posts") }}</RouterLink>
</li>
<li v-if="isAdmin()" class="nav-item">
<li v-if="loggedInUserInfo?.permissions?.canEditUserRoles ?? false" class="nav-item">
<RouterLink to="/administration" class="nav-link">{{ t("nav.administration") }}</RouterLink>
</li>
</ul>
<div class="username">
<login-button v-if="!loggedInUser"></login-button>
<user-name v-else :user="loggedInUser" @logout="logoutUser($event)"></user-name>
<login-button v-if="!loggedInUserInfo"></login-button>
<user-name v-else :user="loggedInUserInfo.user" @logout="logoutUser($event)"></user-name>
</div>

<light-dark-toggler @theme-changed="cssTheme = $event" style="margin-right: 2.5rem"></light-dark-toggler>
Expand All @@ -49,7 +49,7 @@
</div>
</nav>

<RouterView :userPermissions="userPermissions" />
<RouterView :userPermissions="loggedInUserInfo?.permissions" />
</div>
<footer class="page-footer">
<div class="container">
Expand Down Expand Up @@ -114,8 +114,7 @@ import { AuthEndpoints } from "@client/util/api-client.js";
import { saveIdToken } from "@client/util/storage.js";
import { faGithub } from "@fortawesome/free-brands-svg-icons";
import { faExternalLink } from "@fortawesome/free-solid-svg-icons";
import type { AppSettingsDto, User, UserRolePermissionsType } from "@fumix/fu-blog-common";
import { permissionsForUser } from "@fumix/fu-blog-common";
import type { AppSettingsDto, LoggedInUserInfo } from "@fumix/fu-blog-common";
import { onMounted, ref, watch } from "vue";
import { useI18n } from "vue-i18n";
import { useRoute, useRouter } from "vue-router";
Expand All @@ -124,8 +123,7 @@ const { t } = useI18n();
const route = useRoute();
const searchQuery = ref<string>("");
const router = useRouter();
const loggedInUser = ref<User | null>(null);
const userPermissions = ref<UserRolePermissionsType | null>(null);
const loggedInUserInfo = ref<LoggedInUserInfo | undefined>(undefined);
const cssTheme = ref<string | null>(null);
const appData: AppSettingsDto = (JSON.parse(document.getElementById("app-data")?.textContent ?? "{}") as AppSettingsDto) ?? {
Expand All @@ -150,13 +148,11 @@ const setOperator = (operator: string) => {
const setLoginUserAndPermissions = async () => {
AuthEndpoints.getLoggedInUser()
.then((oauthAccount) => {
loggedInUser.value = oauthAccount.user;
userPermissions.value = permissionsForUser(oauthAccount.user);
.then((userInfo: LoggedInUserInfo) => {
loggedInUserInfo.value = userInfo;
})
.catch(() => {
loggedInUser.value = null;
userPermissions.value = null;
loggedInUserInfo.value = undefined;
});
};
Expand All @@ -172,7 +168,7 @@ watch(route, async (value) => {
onMounted(() => {
// listen for token-changed event to gracefully handle login/logout
window.addEventListener("token-changed", (event) => {
if (!loggedInUser.value) {
if (!loggedInUserInfo.value) {
setLoginUserAndPermissions();
}
});
Expand All @@ -190,14 +186,9 @@ const startSearch = (search: string, operator: string = "and") => {
}
};
const isAdmin = () => {
return loggedInUser.value?.roles.includes("ADMIN");
};
const logoutUser = (event: Event) => {
saveIdToken(null); // clear localStorage
loggedInUser.value = null;
userPermissions.value = null;
loggedInUserInfo.value = undefined;
router.push(`/`);
};
</script>
17 changes: 14 additions & 3 deletions client/src/util/api-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import type {
DraftResponseDto,
EditPostRequestDto,
JsonMimeType,
LoggedInUserInfo,
NewPostRequestDto,
OAuthAccount,
Post,
SupportedImageMimeType,
} from "@fumix/fu-blog-common";
import { HttpHeader, imageBytesToDataUrl } from "@fumix/fu-blog-common";
Expand Down Expand Up @@ -86,10 +87,10 @@ function toFormData<T>(payload: ApiRequestJsonPayloadWithFiles<T> | null): FormD
}

export class AuthEndpoints {
static async getLoggedInUser(): Promise<OAuthAccount> {
static async getLoggedInUser(): Promise<LoggedInUserInfo> {
const token = loadIdToken();
if (token) {
return callServer<null, JsonMimeType, OAuthAccount>("/api/auth/loggedInUser/", "POST", "application/json");
return callServer<null, JsonMimeType, LoggedInUserInfo>("/api/auth/loggedInUser/", "POST", "application/json");
}
return Promise.reject();
}
Expand Down Expand Up @@ -138,4 +139,14 @@ export class PostEndpoints {
static async deletePost(id: number): Promise<{ affected: number }> {
return callServer<void, JsonMimeType, { affected: number }>(`/api/posts/delete/${id}`, "POST", "application/json");
}

static async findPosts(pageIndex: number, itemsPerPage = 12, search: string | undefined = undefined, operator: "and" | "or" = "and") {
return callServer<void, JsonMimeType, { data: [Post[], number | null] }>(
`/api/posts/page/${pageIndex}/count/${itemsPerPage}${search ? `/search/${encodeURIComponent(search)}/operator/${operator}` : ""}###`,
"GET",
"application/json",
null,
true,
);
}
}
25 changes: 11 additions & 14 deletions client/src/views/PostsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,10 @@ import ConfirmDialog from "@client/components/ConfirmDialog.vue";
import LoadingSpinner from "@client/components/LoadingSpinner.vue";
import PostPreview from "@client/components/PostPreview.vue";
import WordCloud from "@client/components/WordCloud.vue";
import { PostEndpoints } from "@client/util/api-client";
import { faSadTear } from "@fortawesome/free-regular-svg-icons";
import { faAdd } from "@fortawesome/free-solid-svg-icons";
import type { ConfirmDialogData, Post, UserRolePermissionsType } from "@fumix/fu-blog-common";
import { asSearchOperator, type ConfirmDialogData, type Post, type UserRolePermissionsType } from "@fumix/fu-blog-common";
import type { PropType } from "vue";
import { onMounted, ref, watch } from "vue";
import { useI18n } from "vue-i18n";
Expand Down Expand Up @@ -104,15 +105,11 @@ const props = defineProps({
},
});
const loadPostsWithPagination = async (pageIndex: number, search: string, operator: string) => {
const loadPostsWithPagination = async (pageIndex: number, search: string, operator: "and" | "or") => {
try {
let link = !search
? `/api/posts/page/${pageIndex}/count/${itemsPerPage}`
: `/api/posts/page/${pageIndex}/count/${itemsPerPage}/search/${encodeURIComponent(search)}/operator/${encodeURIComponent(operator)}`;
const res = await fetch(link);
const response = await res.json();
posts.value = response.data[0];
totalPages.value = Math.ceil((await response.data[1]) / itemsPerPage);
const [postResult, count] = await PostEndpoints.findPosts(pageIndex, 12, search, operator).then((it) => it.data);
posts.value = postResult;
totalPages.value = Math.ceil((count ?? 0) / itemsPerPage);
loading.value = false;
} catch (e) {
console.log("ERROR: ", e);
Expand All @@ -122,22 +119,22 @@ const loadPostsWithPagination = async (pageIndex: number, search: string, operat
const onPaginate = (page: number) => {
const searchValue = (route.query?.search || "") as string;
const operator = (route.query?.operator || "and") as string;
const operator = asSearchOperator(route.query?.operator?.toString());
loadPostsWithPagination(page, searchValue, operator);
};
watch(
() => route.query,
(query) => {
const searchValue = (query?.search || "") as string;
const operator = (route.query?.operator || "and") as string;
const searchValue = (query?.search ?? "") as string;
const operator = asSearchOperator(route.query?.operator?.toString());
loadPostsWithPagination(1, searchValue, operator);
},
);
onMounted(() => {
const searchValue = (route.query?.search || "") as string;
const operator = (route.query?.operator || "and") as string;
const operator = asSearchOperator(route.query?.operator?.toString());
blogTitle.value = "fumiX Blog";
blogShortDescription.value = "Alle Beiträge auf einen Blick";
Expand All @@ -150,7 +147,7 @@ const deletePost = async (post: Post) => {
const res = await fetch(`/api/posts/delete/${post.id}`);
await res.json();
const searchValue = (route.query?.search || "") as string;
const operator = (route.query?.operator || "and") as string;
const operator = asSearchOperator(route.query?.operator?.toString());
await loadPostsWithPagination(1, searchValue, operator);
} catch (e) {
console.log("ERROR: ", e);
Expand Down

0 comments on commit 3a7bfa1

Please sign in to comment.