Convert routes to Typescript (#3177)

This commit is contained in:
Alexander Skvortsov 2021-12-01 11:27:19 -05:00 committed by GitHub
parent a0d52569ca
commit 2ffe0f4b71
5 changed files with 43 additions and 48 deletions

View File

@ -1,3 +1,4 @@
import AdminApplication from './AdminApplication';
import DashboardPage from './components/DashboardPage';
import BasicsPage from './components/BasicsPage';
import PermissionsPage from './components/PermissionsPage';
@ -9,10 +10,8 @@ import ExtensionPageResolver from './resolvers/ExtensionPageResolver';
/**
* The `routes` initializer defines the forum app's routes.
*
* @param {App} app
*/
export default function (app) {
export default function (app: AdminApplication) {
app.routes = {
dashboard: { path: '/', component: DashboardPage },
basics: { path: '/basics', component: BasicsPage },

View File

@ -34,11 +34,7 @@ import type { ComponentAttrs } from './Component';
export type FlarumScreens = 'phone' | 'tablet' | 'desktop' | 'desktop-hd';
export type FlarumGenericRoute = RouteItem<
Record<string, unknown>,
Component<{ routeName: string; [key: string]: unknown }>,
Record<string, unknown>
>;
export type FlarumGenericRoute = RouteItem<any, any, any>;
export interface FlarumRequestOptions<ResponseType> extends Omit<Mithril.RequestOptions<ResponseType>, 'extract'> {
errorHandler?: (error: RequestError) => void;
@ -80,14 +76,14 @@ export type RouteItem<
/**
* The component to render when this route matches.
*/
component: { new (): Comp };
component: new () => Comp;
/**
* A custom resolver class.
*
* This should be the class itself, and **not** an instance of the
* class.
*/
resolverClass?: { new (): DefaultResolver<Attrs, Comp, RouteArgs> };
resolverClass?: new (component: new () => Comp, routeName: string) => DefaultResolver<Attrs, Comp, RouteArgs>;
}
| {
/**

View File

@ -15,10 +15,10 @@ export default class DefaultResolver<
RouteArgs extends Record<string, unknown> = {}
> implements RouteResolver<Attrs, Comp, RouteArgs>
{
component: { new (): Comp };
component: new () => Comp;
routeName: string;
constructor(component: { new (): Comp }, routeName: string) {
constructor(component: new () => Comp, routeName: string) {
this.component = component;
this.routeName = routeName;
}

View File

@ -10,7 +10,7 @@ import Composer from './components/Composer';
import DiscussionRenamedNotification from './components/DiscussionRenamedNotification';
import CommentPost from './components/CommentPost';
import DiscussionRenamedPost from './components/DiscussionRenamedPost';
import routes from './routes';
import routes, { makeRouteHelpers } from './routes';
import alertEmailConfirmation from './utils/alertEmailConfirmation';
import Application from '../common/Application';
import Navigation from '../common/components/Navigation';
@ -73,10 +73,14 @@ export default class ForumApplication extends Application {
*/
discussions: DiscussionListState = new DiscussionListState({});
route: typeof Application.prototype.route & ReturnType<typeof makeRouteHelpers>;
constructor() {
super();
routes(this);
this.route = Object.assign({}, (Object.getPrototypeOf(Object.getPrototypeOf(this)) as Application).route.bind(this), makeRouteHelpers(this));
}
/**

View File

@ -1,3 +1,4 @@
import ForumApplication from './ForumApplication';
import IndexPage from './components/IndexPage';
import DiscussionPage from './components/DiscussionPage';
import PostsUserPage from './components/PostsUserPage';
@ -5,13 +6,14 @@ import DiscussionsUserPage from './components/DiscussionsUserPage';
import SettingsPage from './components/SettingsPage';
import NotificationsPage from './components/NotificationsPage';
import DiscussionPageResolver from './resolvers/DiscussionPageResolver';
import Discussion from '../common/models/Discussion';
import Post from '../common/models/Post';
import User from '../common/models/User';
/**
* The `routes` initializer defines the forum app's routes.
*
* @param {App} app
*/
export default function (app) {
export default function (app: ForumApplication) {
app.routes = {
index: { path: '/all', component: IndexPage },
@ -25,40 +27,34 @@ export default function (app) {
settings: { path: '/settings', component: SettingsPage },
notifications: { path: '/notifications', component: NotificationsPage },
};
}
/**
* Generate a URL to a discussion.
*
* @param {Discussion} discussion
* @param {Integer} [near]
* @return {String}
*/
app.route.discussion = (discussion, near) => {
return app.route(near && near !== 1 ? 'discussion.near' : 'discussion', {
id: discussion.slug(),
near: near && near !== 1 ? near : undefined,
});
};
export function makeRouteHelpers(app: ForumApplication) {
return {
/**
* Generate a URL to a discussion.
*/
discussion: (discussion: Discussion, near: number) => {
return app.route(near && near !== 1 ? 'discussion.near' : 'discussion', {
id: discussion.slug(),
near: near && near !== 1 ? near : undefined,
});
},
/**
* Generate a URL to a post.
*
* @param {Post} post
* @return {String}
*/
app.route.post = (post) => {
return app.route.discussion(post.discussion(), post.number());
};
/**
* Generate a URL to a post.
*/
post: (post: Post) => {
return app.route.discussion(post.discussion(), post.number());
},
/**
* Generate a URL to a user.
*
* @param {User} user
* @return {String}
*/
app.route.user = (user) => {
return app.route('user', {
username: user.slug(),
});
/**
* Generate a URL to a user.
*/
user: (user: User) => {
return app.route('user', {
username: user.slug(),
});
},
};
}