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 DashboardPage from './components/DashboardPage';
import BasicsPage from './components/BasicsPage'; import BasicsPage from './components/BasicsPage';
import PermissionsPage from './components/PermissionsPage'; import PermissionsPage from './components/PermissionsPage';
@ -9,10 +10,8 @@ import ExtensionPageResolver from './resolvers/ExtensionPageResolver';
/** /**
* The `routes` initializer defines the forum app's routes. * The `routes` initializer defines the forum app's routes.
*
* @param {App} app
*/ */
export default function (app) { export default function (app: AdminApplication) {
app.routes = { app.routes = {
dashboard: { path: '/', component: DashboardPage }, dashboard: { path: '/', component: DashboardPage },
basics: { path: '/basics', component: BasicsPage }, 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 FlarumScreens = 'phone' | 'tablet' | 'desktop' | 'desktop-hd';
export type FlarumGenericRoute = RouteItem< export type FlarumGenericRoute = RouteItem<any, any, any>;
Record<string, unknown>,
Component<{ routeName: string; [key: string]: unknown }>,
Record<string, unknown>
>;
export interface FlarumRequestOptions<ResponseType> extends Omit<Mithril.RequestOptions<ResponseType>, 'extract'> { export interface FlarumRequestOptions<ResponseType> extends Omit<Mithril.RequestOptions<ResponseType>, 'extract'> {
errorHandler?: (error: RequestError) => void; errorHandler?: (error: RequestError) => void;
@ -80,14 +76,14 @@ export type RouteItem<
/** /**
* The component to render when this route matches. * The component to render when this route matches.
*/ */
component: { new (): Comp }; component: new () => Comp;
/** /**
* A custom resolver class. * A custom resolver class.
* *
* This should be the class itself, and **not** an instance of the * This should be the class itself, and **not** an instance of the
* class. * 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> = {} RouteArgs extends Record<string, unknown> = {}
> implements RouteResolver<Attrs, Comp, RouteArgs> > implements RouteResolver<Attrs, Comp, RouteArgs>
{ {
component: { new (): Comp }; component: new () => Comp;
routeName: string; routeName: string;
constructor(component: { new (): Comp }, routeName: string) { constructor(component: new () => Comp, routeName: string) {
this.component = component; this.component = component;
this.routeName = routeName; this.routeName = routeName;
} }

View File

@ -10,7 +10,7 @@ import Composer from './components/Composer';
import DiscussionRenamedNotification from './components/DiscussionRenamedNotification'; import DiscussionRenamedNotification from './components/DiscussionRenamedNotification';
import CommentPost from './components/CommentPost'; import CommentPost from './components/CommentPost';
import DiscussionRenamedPost from './components/DiscussionRenamedPost'; import DiscussionRenamedPost from './components/DiscussionRenamedPost';
import routes from './routes'; import routes, { makeRouteHelpers } from './routes';
import alertEmailConfirmation from './utils/alertEmailConfirmation'; import alertEmailConfirmation from './utils/alertEmailConfirmation';
import Application from '../common/Application'; import Application from '../common/Application';
import Navigation from '../common/components/Navigation'; import Navigation from '../common/components/Navigation';
@ -73,10 +73,14 @@ export default class ForumApplication extends Application {
*/ */
discussions: DiscussionListState = new DiscussionListState({}); discussions: DiscussionListState = new DiscussionListState({});
route: typeof Application.prototype.route & ReturnType<typeof makeRouteHelpers>;
constructor() { constructor() {
super(); super();
routes(this); 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 IndexPage from './components/IndexPage';
import DiscussionPage from './components/DiscussionPage'; import DiscussionPage from './components/DiscussionPage';
import PostsUserPage from './components/PostsUserPage'; import PostsUserPage from './components/PostsUserPage';
@ -5,13 +6,14 @@ import DiscussionsUserPage from './components/DiscussionsUserPage';
import SettingsPage from './components/SettingsPage'; import SettingsPage from './components/SettingsPage';
import NotificationsPage from './components/NotificationsPage'; import NotificationsPage from './components/NotificationsPage';
import DiscussionPageResolver from './resolvers/DiscussionPageResolver'; 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. * The `routes` initializer defines the forum app's routes.
*
* @param {App} app
*/ */
export default function (app) { export default function (app: ForumApplication) {
app.routes = { app.routes = {
index: { path: '/all', component: IndexPage }, index: { path: '/all', component: IndexPage },
@ -25,40 +27,34 @@ export default function (app) {
settings: { path: '/settings', component: SettingsPage }, settings: { path: '/settings', component: SettingsPage },
notifications: { path: '/notifications', component: NotificationsPage }, notifications: { path: '/notifications', component: NotificationsPage },
}; };
}
export function makeRouteHelpers(app: ForumApplication) {
return {
/** /**
* Generate a URL to a discussion. * Generate a URL to a discussion.
*
* @param {Discussion} discussion
* @param {Integer} [near]
* @return {String}
*/ */
app.route.discussion = (discussion, near) => { discussion: (discussion: Discussion, near: number) => {
return app.route(near && near !== 1 ? 'discussion.near' : 'discussion', { return app.route(near && near !== 1 ? 'discussion.near' : 'discussion', {
id: discussion.slug(), id: discussion.slug(),
near: near && near !== 1 ? near : undefined, near: near && near !== 1 ? near : undefined,
}); });
}; },
/** /**
* Generate a URL to a post. * Generate a URL to a post.
*
* @param {Post} post
* @return {String}
*/ */
app.route.post = (post) => { post: (post: Post) => {
return app.route.discussion(post.discussion(), post.number()); return app.route.discussion(post.discussion(), post.number());
}; },
/** /**
* Generate a URL to a user. * Generate a URL to a user.
*
* @param {User} user
* @return {String}
*/ */
app.route.user = (user) => { user: (user: User) => {
return app.route('user', { return app.route('user', {
username: user.slug(), username: user.slug(),
}); });
},
}; };
} }