project categories

This commit is contained in:
Jake Potrebic 2021-01-22 11:20:03 -08:00
parent f8b90a8c9b
commit a28ab56199
No known key found for this signature in database
GPG Key ID: 7C58557EC9C421F8
8 changed files with 117 additions and 20 deletions

View File

@ -5,7 +5,7 @@ import { ApiSessionType } from '~/types/enums';
export default ({ store, app: { $cookies }, $auth, redirect }: Context) => {
if ($cookies.get('returnRoute')) {
// is returning from login
const returnRoute: string = $cookies.get<string>('returnRoute');
const returnRoute = $cookies.get<string>('returnRoute');
return $auth.processLogin().then(() => {
$cookies.remove('returnRoute', {
path: '/',

View File

@ -18,11 +18,11 @@ export default class ProjectPage extends Vue {
};
}
async asyncData({ $api, params, error }: Context): Promise<{ project: Project }> {
async asyncData({ $api, params, error }: Context): Promise<{ project: Project } | void> {
return await $api
.request<Project>(`projects/${params.author}/${params.slug}`)
.then((project) => {
return { project };
return Promise.resolve({ project });
})
.catch((err: AxiosError) => {
const hangarError: ApiError = err.response?.data as ApiError;

View File

@ -32,12 +32,12 @@
<v-list dense>
<v-subheader>Categories</v-subheader>
<v-list-item-group>
<v-list-item v-for="(cat, i) in categories" :key="i">
<v-list-item v-for="cat in $store.state.projectCategories.values()" :key="cat.apiName">
<v-list-item-icon>
<v-icon v-text="cat.icon" />
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title v-text="cat.text"></v-list-item-title>
<v-list-item-title v-text="cat.title"></v-list-item-title>
</v-list-item-content> </v-list-item
></v-list-item-group>
</v-list>
@ -65,11 +65,6 @@ import { Context } from '@nuxt/types';
import { PaginatedResult, Project } from 'hangar-api';
// TODO move somewhere else
interface Category {
icon: string;
text: string;
}
interface Platform {
icon: string;
text: string;
@ -80,13 +75,6 @@ export default class Home extends Vue {
projects?: PaginatedResult<Project>;
totalProjects: Number = 1337;
projectFilter: String | null = null;
// TODO get categories from server
categories: Category[] = [
{
icon: 'mdi-home',
text: 'Test',
},
];
// TODO get platforms from server
platforms: Platform[] = [
@ -102,8 +90,8 @@ export default class Home extends Vue {
};
}
async asyncData({ $api }: Context): Promise<{ projects: PaginatedProjectList }> {
return { projects: await $api.request<PaginatedProjectList>('projects', 'get', { limit: 25, offset: 0 }) };
async asyncData({ $api, store }: Context): Promise<{ projects: PaginatedResult<Project> }> {
return { projects: await $api.request<PaginatedResult<Project>>('projects', 'get', { limit: 25, offset: 0 }) };
}
}
</script>

View File

@ -10,7 +10,7 @@ const createAuth = ({ app: { $cookies }, store, $api }: Context) => {
maxAge: 120,
secure: true,
});
location.replace(`/login?returnUrl=http://localhost:3000/${redirect}`);
location.replace(`/login?returnUrl=http://localhost:3000${redirect}`);
}
processLogin(): Promise<void> {

39
frontend/store/index.ts Normal file
View File

@ -0,0 +1,39 @@
import { ActionTree, MutationTree } from 'vuex';
import { Context } from '@nuxt/types';
import { IProjectCategory } from 'hangar-api';
import { ProjectCategory } from '~/types/enums';
export const state = () => ({
projectCategories: (null as unknown) as Map<ProjectCategory, IProjectCategory>,
});
export type RootState = ReturnType<typeof state>;
export const mutations: MutationTree<RootState> = {
SET_PROJECT_CATEGORIES: (state, payload: Map<ProjectCategory, IProjectCategory>) => {
state.projectCategories = payload;
},
};
export const actions: ActionTree<RootState, RootState> = {
async nuxtServerInit({ commit }, { $api }: Context) {
try {
const categoryResult = await $api.requestInternal<IProjectCategory[]>('data/categories');
commit(
'SET_PROJECT_CATEGORIES',
convertToMap<ProjectCategory, IProjectCategory>(categoryResult, (value) => value.apiName)
);
// others
} catch (e) {
console.error(e);
}
},
};
function convertToMap<E, T>(values: T[], toStringFunc: (value: T) => string): Map<E, T> {
const map = new Map<E, T>();
for (const value of values) {
map.set((toStringFunc(value) as unknown) as E, value);
}
return map;
}

View File

@ -129,4 +129,12 @@ declare module 'hangar-api' {
text: String;
color: String;
}
// Data interfaces
interface IProjectCategory {
title: string;
icon: string;
apiName: string;
visible: boolean;
}
}

View File

@ -0,0 +1,58 @@
package io.papermc.hangar.controller.internal;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.papermc.hangar.model.Category;
import org.apache.commons.lang3.NotImplementedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.lang.annotation.Annotation;
@Controller
@Secured("ROLE_USER")
@RequestMapping(path = "/api/internal/data", produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.GET)
public class BackendDataController {
private final ObjectMapper mapper;
@Autowired
public BackendDataController(ObjectMapper mapper) {
this.mapper = mapper.copy();
this.mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
@Override
protected <A extends Annotation> A _findAnnotation(Annotated annotated, Class<A> annoClass) {
if (!annotated.hasAnnotation(JsonValue.class)) {
return super._findAnnotation(annotated, annoClass);
}
return null;
}
});
}
@GetMapping("/categories")
public ResponseEntity<ArrayNode> getCategories() {
return ResponseEntity.ok(mapper.valueToTree(Category.VALUES));
}
@GetMapping("/platforms")
public ResponseEntity<ObjectNode> getPlatforms() {
throw new NotImplementedException("NOT IMPLEMENTED");
}
@GetMapping("/colors")
public ResponseEntity<ObjectNode> getColors() {
throw new NotImplementedException("NOT IMPLEMENTED");
}
}

View File

@ -1,6 +1,8 @@
package io.papermc.hangar.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonValue;
import java.util.ArrayList;
@ -9,6 +11,7 @@ import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum Category {
ADMIN_TOOLS(0, "Admin Tools", "fa-server", "admin_tools"),
CHAT(1, "Chat", "fa-comment", "chat"),
@ -42,6 +45,7 @@ public enum Category {
this.isVisible = isVisible;
}
@JsonIgnore
public int getValue() {
return value;
}