diff --git a/framework/core/js/src/admin/routes.js b/framework/core/js/src/admin/routes.ts similarity index 90% rename from framework/core/js/src/admin/routes.js rename to framework/core/js/src/admin/routes.ts index 9c3468fde..6cdda32f3 100644 --- a/framework/core/js/src/admin/routes.js +++ b/framework/core/js/src/admin/routes.ts @@ -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 }, diff --git a/framework/core/js/src/common/Application.tsx b/framework/core/js/src/common/Application.tsx index 461b25952..6bd72e227 100644 --- a/framework/core/js/src/common/Application.tsx +++ b/framework/core/js/src/common/Application.tsx @@ -34,11 +34,7 @@ import type { ComponentAttrs } from './Component'; export type FlarumScreens = 'phone' | 'tablet' | 'desktop' | 'desktop-hd'; -export type FlarumGenericRoute = RouteItem< - Record, - Component<{ routeName: string; [key: string]: unknown }>, - Record ->; +export type FlarumGenericRoute = RouteItem; export interface FlarumRequestOptions extends Omit, '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 }; + resolverClass?: new (component: new () => Comp, routeName: string) => DefaultResolver; } | { /** diff --git a/framework/core/js/src/common/resolvers/DefaultResolver.ts b/framework/core/js/src/common/resolvers/DefaultResolver.ts index 68db9be78..a5473c31a 100644 --- a/framework/core/js/src/common/resolvers/DefaultResolver.ts +++ b/framework/core/js/src/common/resolvers/DefaultResolver.ts @@ -15,10 +15,10 @@ export default class DefaultResolver< RouteArgs extends Record = {} > implements RouteResolver { - 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; } diff --git a/framework/core/js/src/forum/ForumApplication.ts b/framework/core/js/src/forum/ForumApplication.ts index 6f20d8ff5..f6ae27541 100644 --- a/framework/core/js/src/forum/ForumApplication.ts +++ b/framework/core/js/src/forum/ForumApplication.ts @@ -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; + constructor() { super(); routes(this); + + this.route = Object.assign({}, (Object.getPrototypeOf(Object.getPrototypeOf(this)) as Application).route.bind(this), makeRouteHelpers(this)); } /** diff --git a/framework/core/js/src/forum/routes.js b/framework/core/js/src/forum/routes.ts similarity index 55% rename from framework/core/js/src/forum/routes.js rename to framework/core/js/src/forum/routes.ts index 6f10c27c5..90dd90fc1 100644 --- a/framework/core/js/src/forum/routes.js +++ b/framework/core/js/src/forum/routes.ts @@ -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(), + }); + }, }; }