Niedzielski has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/388069 )

Change subject: Chore: refactor page modules
......................................................................

Chore: refactor page modules

- Rename PageModule to PageComponents.
- Add PageModule type that is an ES6 module with a default export of
  type PageComponent.

Bug: T177236
Change-Id: Ib80dc40548bddec1b1fdc36c1e8a68a2350809f5
---
M src/common/pages/about.tsx
M src/common/pages/home.tsx
M src/common/pages/not-found.tsx
M src/common/pages/style-guide.tsx
M src/common/pages/summary.tsx
M src/common/pages/wiki.tsx
M src/common/routers/route.ts
M src/common/routers/router.ts
8 files changed, 300 insertions(+), 269 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/marvin refs/changes/69/388069/1

diff --git a/src/common/pages/about.tsx b/src/common/pages/about.tsx
index a906239..11524b7 100644
--- a/src/common/pages/about.tsx
+++ b/src/common/pages/about.tsx
@@ -12,78 +12,80 @@
   subtitle: string;
 }
 
-export class Component extends PreactComponent<undefined, State> {
-  constructor() {
-    super();
-    this.state = { subtitle: "" };
-  }
+export default {
+  Component: class extends PreactComponent<undefined, State> {
+    constructor() {
+      super();
+      this.state = { subtitle: "" };
+    }
 
-  componentDidMount() {
-    // todo: figure out a common way across entry points for defining
-    // configuration variables that common code could consume. The server has
-    // server specific vars in config.ts and this here for example are used 
only
-    // on DOM capable envs (componentDidMount will only fire on DOM capable
-    // environments). It would be ideal if we had a common place with
-    // configuration for common code. We need to also take into account 
UglifyJS
-    // and the dead code elimination when using DefinePlugin, so that we can
-    // leverage it to remove dev-only code in production builds
-    // (see https://webpack.js.org/guides/tree-shaking/#minify-the-output)
-    //
-    // Fill the subtitle on the DOM-capable env with the information embedded 
in
-    // the assets by webpack#DefinePlugin
-    const env = process.env.NODE_ENV;
-    const subtitle = `Version ${VERSION}; Env: ${env}`;
-    this.setState({ subtitle });
-  }
+    componentDidMount() {
+      // todo: figure out a common way across entry points for defining
+      // configuration variables that common code could consume. The server has
+      // server specific vars in config.ts and this here for example are used
+      // only on DOM capable envs (componentDidMount will only fire on DOM
+      // capable environments). It would be ideal if we had a common place with
+      // configuration for common code. We need to also take into account
+      // UglifyJS and the dead code elimination when using DefinePlugin, so 
that
+      // we can leverage it to remove dev-only code in production builds
+      // (see https://webpack.js.org/guides/tree-shaking/#minify-the-output)
+      //
+      // Fill the subtitle on the DOM-capable env with the information embedded
+      // in the assets by webpack#DefinePlugin
+      const env = process.env.NODE_ENV;
+      const subtitle = `Version ${VERSION}; Env: ${env}`;
+      this.setState({ subtitle });
+    }
 
-  render(_props: void, { subtitle }: State): JSX.Element {
-    const links = [
-      {
-        href: "https://phabricator.wikimedia.org/tag/marvin/";,
-        text: "Task/Bug tracker"
-      },
-      {
-        href: "https://phabricator.wikimedia.org/diffusion/MARV/";,
-        text: "Code repository (Wikimedia Phabricator)"
-      },
-      {
-        href: "https://github.com/wikimedia/marvin";,
-        text: "Github mirror"
-      },
-      {
-        href:
-          
"https://www.mediawiki.org/wiki/Reading/Web/Projects/NewMobileWebsite";,
-        text: "Documentation on MediaWiki.org"
-      },
-      {
-        href: "https://github.com/wikimedia/marvin/tree/master/docs";,
-        text: "Technical documentation on Github.com"
-      }
-    ];
-    return (
-      <App>
-        <Page title="About Marvin" subtitle={subtitle}>
-          <p>
-            Marvin is in early stages of development.<br /> For more 
information
-            see the following links:
-          </p>
-          <ul>
-            {links.map(({ href, text }) => (
-              <li>
-                <Link href={href}>{text}</Link>
-              </li>
-            ))}
-          </ul>
-          <p>
-            If you want to chat, you can find us in{" "}
-            <code>#wikimedia-mobile</code> on freenode. Or you can send an 
email
-            to the{" "}
-            <a href="https://lists.wikimedia.org/mailman/listinfo/mobile-l";>
-              mobile-l mailing list
-            </a>.
-          </p>
-        </Page>
-      </App>
-    );
+    render(_props: void, { subtitle }: State): JSX.Element {
+      const links = [
+        {
+          href: "https://phabricator.wikimedia.org/tag/marvin/";,
+          text: "Task/Bug tracker"
+        },
+        {
+          href: "https://phabricator.wikimedia.org/diffusion/MARV/";,
+          text: "Code repository (Wikimedia Phabricator)"
+        },
+        {
+          href: "https://github.com/wikimedia/marvin";,
+          text: "Github mirror"
+        },
+        {
+          href:
+            
"https://www.mediawiki.org/wiki/Reading/Web/Projects/NewMobileWebsite";,
+          text: "Documentation on MediaWiki.org"
+        },
+        {
+          href: "https://github.com/wikimedia/marvin/tree/master/docs";,
+          text: "Technical documentation on Github.com"
+        }
+      ];
+      return (
+        <App>
+          <Page title="About Marvin" subtitle={subtitle}>
+            <p>
+              Marvin is in early stages of development.<br /> For more
+              information see the following links:
+            </p>
+            <ul>
+              {links.map(({ href, text }) => (
+                <li>
+                  <Link href={href}>{text}</Link>
+                </li>
+              ))}
+            </ul>
+            <p>
+              If you want to chat, you can find us in{" "}
+              <code>#wikimedia-mobile</code> on freenode. Or you can send an
+              email to the{" "}
+              <a href="https://lists.wikimedia.org/mailman/listinfo/mobile-l";>
+                mobile-l mailing list
+              </a>.
+            </p>
+          </Page>
+        </App>
+      );
+    }
   }
-}
+};
diff --git a/src/common/pages/home.tsx b/src/common/pages/home.tsx
index c4657fe..78ac04c 100644
--- a/src/common/pages/home.tsx
+++ b/src/common/pages/home.tsx
@@ -13,106 +13,110 @@
 import { PageTitleID } from "../models/page/title";
 import Link from "../components/link";
 
-export const Component = (): JSX.Element => {
-  const testSummaries = [
-    {
-      title: "Banana",
-      text: "With landscape image"
-    },
-    {
-      title: "Cucumber",
-      text: "With portrait image"
-    },
-    {
-      title: "Plaintext",
-      text: "Without image"
-    },
-    {
-      title: "Bill_&_Ted's_Excellent_Adventure",
-      text: "With two paragraphs, unencoded path, and styled title"
-    }
-  ];
-  const testPages = [
-    {
-      title: "Ice_cream",
-      text: "A normal article"
-    },
-    {
-      title: "Cake_(disambiguation)",
-      text: "Disambiguation"
-    },
-    {
-      title: "Cheese_cake",
-      text: "Redirect"
-    },
-    {
-      title: "Carrot cake",
-      text: "Encoding redirect"
-    },
-    {
-      title: "Ice_cream_cake",
-      revision: "24242119",
-      text: "An arbitrary revision"
-    }
-  ];
-  return (
-    <App>
-      <Page title="Welcome" subtitle="">
-        <p>Hello world!</p>
-        <p>Here are some test links for the time being:</p>
-        <ul>
-          <li>
-            <Link href={home.toPath()}>Home</Link>
-          </li>
-          <li>
-            <Link href={about.toPath()}>About</Link>
-          </li>
-          <li>
-            <Link href={styleGuide.toPath()}>Style Guide</Link>
-          </li>
-          <li>
-            <Link href="/404">404</Link>
-          </li>
-        </ul>
+const testSummaries = [
+  {
+    title: "Banana",
+    text: "With landscape image"
+  },
+  {
+    title: "Cucumber",
+    text: "With portrait image"
+  },
+  {
+    title: "Plaintext",
+    text: "Without image"
+  },
+  {
+    title: "Bill_&_Ted's_Excellent_Adventure",
+    text: "With two paragraphs, unencoded path, and styled title"
+  }
+];
 
-        <h3>Pages</h3>
-        <ul>
-          <li>
-            {/* todo: this should always appear as with the unvisited color or
-                      be a button. */}
-            <Link href={randomWiki.toPath()}>A random page</Link>
-          </li>
-          {testPages.map(
-            ({
-              title,
-              revision,
-              text
-            }: {
-              title: PageTitleID | string;
-              revision?: string;
-              text: string;
-            }) => (
-              <li>
-                <Link href={wiki.toPath({ title, revision })}>{text}</Link>
-              </li>
-            )
-          )}
-        </ul>
+const testPages = [
+  {
+    title: "Ice_cream",
+    text: "A normal article"
+  },
+  {
+    title: "Cake_(disambiguation)",
+    text: "Disambiguation"
+  },
+  {
+    title: "Cheese_cake",
+    text: "Redirect"
+  },
+  {
+    title: "Carrot cake",
+    text: "Encoding redirect"
+  },
+  {
+    title: "Ice_cream_cake",
+    revision: "24242119",
+    text: "An arbitrary revision"
+  }
+];
 
-        <h3>Summaries</h3>
-        <ul>
-          <li>
-            {/* todo: this should always appear as with the unvisited color or
-                      be a button. */}
-            <Link href={randomSummary.toPath()}>A random summary</Link>
-          </li>
-          {testSummaries.map(({ title, text }) => (
+export default {
+  Component(): JSX.Element {
+    return (
+      <App>
+        <Page title="Welcome" subtitle="">
+          <p>Hello world!</p>
+          <p>Here are some test links for the time being:</p>
+          <ul>
             <li>
-              <Link href={summary.toPath({ title })}>{text}</Link>
+              <Link href={home.toPath()}>Home</Link>
             </li>
-          ))}
-        </ul>
-      </Page>
-    </App>
-  );
+            <li>
+              <Link href={about.toPath()}>About</Link>
+            </li>
+            <li>
+              <Link href={styleGuide.toPath()}>Style Guide</Link>
+            </li>
+            <li>
+              <Link href="/404">404</Link>
+            </li>
+          </ul>
+
+          <h3>Pages</h3>
+          <ul>
+            <li>
+              {/* todo: this should always appear as with the unvisited color 
or
+                      be a button. */}
+              <Link href={randomWiki.toPath()}>A random page</Link>
+            </li>
+            {testPages.map(
+              ({
+                title,
+                revision,
+                text
+              }: {
+                title: PageTitleID | string;
+                revision?: string;
+                text: string;
+              }) => (
+                <li>
+                  <Link href={wiki.toPath({ title, revision })}>{text}</Link>
+                </li>
+              )
+            )}
+          </ul>
+
+          <h3>Summaries</h3>
+          <ul>
+            <li>
+              {/* todo: this should always appear as with the unvisited color 
or
+                      be a button. */}
+              <Link href={randomSummary.toPath()}>A random summary</Link>
+            </li>
+            {testSummaries.map(({ title, text }) => (
+              <li>
+                <Link href={summary.toPath({ title })}>{text}</Link>
+              </li>
+            ))}
+          </ul>
+        </Page>
+      </App>
+    );
+  }
 };
diff --git a/src/common/pages/not-found.tsx b/src/common/pages/not-found.tsx
index ba87615..15c599e 100644
--- a/src/common/pages/not-found.tsx
+++ b/src/common/pages/not-found.tsx
@@ -11,10 +11,14 @@
   0: string;
 }
 
-export const status: number = 404;
+export default {
+  status: 404,
 
-export const Component = (): JSX.Element => (
-  <App>
-    <p>Not found</p>
-  </App>
-);
+  Component(): JSX.Element {
+    return (
+      <App>
+        <p>Not found</p>
+      </App>
+    );
+  }
+};
diff --git a/src/common/pages/style-guide.tsx b/src/common/pages/style-guide.tsx
index 6d584af..089f980 100644
--- a/src/common/pages/style-guide.tsx
+++ b/src/common/pages/style-guide.tsx
@@ -11,52 +11,54 @@
   facilis ab suscipit quos deleniti similique officia cumque, dignissimos iusto
   laudantium facere sint fuga vero iste vel asperiores beatae aliquam!`;
 
-export function Component(): JSX.Element {
-  return (
-    <App>
-      <h1 style={{ margin: "var(--double-space)", textAlign: "center" }}>
-        Style guide
-      </h1>
+export default {
+  Component(): JSX.Element {
+    return (
+      <App>
+        <h1 style={{ margin: "var(--double-space)", textAlign: "center" }}>
+          Style guide
+        </h1>
 
-      <Card header={<h3>Header</h3>}>
-        <Header />
-      </Card>
-      <Card header={<h3>Card</h3>}>
-        <p>{lorem}</p>
-      </Card>
-      <Card header={<h3>Card w/ footer</h3>} footer="This, is a footer">
-        <p>{lorem}</p>
-      </Card>
-      <Card header={<h3>Content typography</h3>}>
-        <Content>
-          <h1>Heading 1</h1>
+        <Card header={<h3>Header</h3>}>
+          <Header />
+        </Card>
+        <Card header={<h3>Card</h3>}>
           <p>{lorem}</p>
-          <h2>Heading 2</h2>
+        </Card>
+        <Card header={<h3>Card w/ footer</h3>} footer="This, is a footer">
           <p>{lorem}</p>
-          <h3>Heading 3</h3>
+        </Card>
+        <Card header={<h3>Content typography</h3>}>
+          <Content>
+            <h1>Heading 1</h1>
+            <p>{lorem}</p>
+            <h2>Heading 2</h2>
+            <p>{lorem}</p>
+            <h3>Heading 3</h3>
+            <p>{lorem}</p>
+            <h4>Heading 4</h4>
+            <p>{lorem}</p>
+            <h5>Heading 5</h5>
+            <p>{lorem}</p>
+            <h6>Heading 6</h6>
+            <p>{lorem}</p>
+            <p>{lorem}</p>
+            <blockquote>{lorem}</blockquote>
+            <p>This is a separator:</p>
+            <Separator />
+            <p>The end</p>
+          </Content>
+        </Card>
+        <Page title="Page template" subtitle="This is the subtitle of the 
page">
           <p>{lorem}</p>
-          <h4>Heading 4</h4>
+        </Page>
+        <Page title="Page template, no subtitle">
           <p>{lorem}</p>
-          <h5>Heading 5</h5>
+        </Page>
+        <Page title="Page template, w/ footer" footer="Hello, footer world">
           <p>{lorem}</p>
-          <h6>Heading 6</h6>
-          <p>{lorem}</p>
-          <p>{lorem}</p>
-          <blockquote>{lorem}</blockquote>
-          <p>This is a separator:</p>
-          <Separator />
-          <p>The end</p>
-        </Content>
-      </Card>
-      <Page title="Page template" subtitle="This is the subtitle of the page">
-        <p>{lorem}</p>
-      </Page>
-      <Page title="Page template, no subtitle">
-        <p>{lorem}</p>
-      </Page>
-      <Page title="Page template, w/ footer" footer="Hello, footer world">
-        <p>{lorem}</p>
-      </Page>
-    </App>
-  );
-}
+        </Page>
+      </App>
+    );
+  }
+};
diff --git a/src/common/pages/summary.tsx b/src/common/pages/summary.tsx
index adc5012..a22a766 100644
--- a/src/common/pages/summary.tsx
+++ b/src/common/pages/summary.tsx
@@ -26,24 +26,29 @@
   summary: PageSummaryModel;
 }
 
-export const getInitialProps = (
-  params: Params = {}
-): Promise<HttpResponse<Props>> =>
-  request(
-    params.title === undefined ? { random: true } : { titlePath: params.title }
-  ).then(({ status, data }) => ({
-    status,
-    data: { summary: data }
-  }));
+export default {
+  getInitialProps(params: Params = {}): Promise<HttpResponse<Props>> {
+    return request(
+      params.title === undefined
+        ? { random: true }
+        : { titlePath: params.title }
+    ).then(({ status, data }) => ({
+      status,
+      data: { summary: data }
+    }));
+  },
 
-export const Component = ({ summary }: Props): JSX.Element => (
-  <App>
-    <Page
-      title={<ContentHeader titleHTML={summary.titleHTML} />}
-      subtitle={summary.descriptionText}
-      footer={<ContentFooter lastModified={summary.lastModified} />}
-    >
-      <PageSummary summary={summary} />
-    </Page>
-  </App>
-);
+  Component({ summary }: Props): JSX.Element {
+    return (
+      <App>
+        <Page
+          title={<ContentHeader titleHTML={summary.titleHTML} />}
+          subtitle={summary.descriptionText}
+          footer={<ContentFooter lastModified={summary.lastModified} />}
+        >
+          <PageSummary summary={summary} />
+        </Page>
+      </App>
+    );
+  }
+};
diff --git a/src/common/pages/wiki.tsx b/src/common/pages/wiki.tsx
index 602b18b..934f976 100644
--- a/src/common/pages/wiki.tsx
+++ b/src/common/pages/wiki.tsx
@@ -30,29 +30,32 @@
   page: PageModel;
 }
 
-export const getInitialProps = (
-  params: Params = {}
-): Promise<HttpResponse<Props>> =>
-  requestPage(
-    params.title === undefined
-      ? { random: true }
-      : {
-          titlePath: params.title,
-          revision:
-            params.revision === undefined
-              ? undefined
-              : parseInt(params.revision, 10)
-        }
-  ).then(({ status, data }) => ({ status, data: { page: data } }));
+export default {
+  getInitialProps(params: Params = {}): Promise<HttpResponse<Props>> {
+    return requestPage(
+      params.title === undefined
+        ? { random: true }
+        : {
+            titlePath: params.title,
+            revision:
+              params.revision === undefined
+                ? undefined
+                : parseInt(params.revision, 10)
+          }
+    ).then(({ status, data }) => ({ status, data: { page: data } }));
+  },
 
-export const Component = ({ page }: Props): JSX.Element => (
-  <App>
-    <Page
-      title={<ContentHeader titleHTML={page.titleHTML} />}
-      subtitle={page.descriptionText}
-      footer={<ContentFooter lastModified={page.lastModified} />}
-    >
-      <ContentPage sections={page.sections} />
-    </Page>
-  </App>
-);
+  Component({ page }: Props): JSX.Element {
+    return (
+      <App>
+        <Page
+          title={<ContentHeader titleHTML={page.titleHTML} />}
+          subtitle={page.descriptionText}
+          footer={<ContentFooter lastModified={page.lastModified} />}
+        >
+          <ContentPage sections={page.sections} />
+        </Page>
+      </App>
+    );
+  }
+};
diff --git a/src/common/routers/route.ts b/src/common/routers/route.ts
index 9653621..197aecd 100644
--- a/src/common/routers/route.ts
+++ b/src/common/routers/route.ts
@@ -25,7 +25,7 @@
  * pages/ subdirectory should implicitly implement this interface or typing 
will
  * fail in routers/api.
  */
-export type PageModule<
+export type PageComponent<
   Params extends RouteParams | undefined = undefined,
   Props = undefined
 > =
@@ -54,6 +54,13 @@
       Component: AnyComponent<undefined, any>;
     };
 
+export interface PageModule<
+  Params extends RouteParams | undefined = undefined,
+  Props = undefined
+> {
+  default: PageComponent<Params, Props>;
+}
+
 /** A plain configuration used to generate a Route. */
 export interface RouteConfig<
   Params extends RouteParams | undefined = undefined,
diff --git a/src/common/routers/router.ts b/src/common/routers/router.ts
index 79d5b4b..0d40836 100644
--- a/src/common/routers/router.ts
+++ b/src/common/routers/router.ts
@@ -1,6 +1,7 @@
 import { AnyComponent } from "../components/preact-utils";
 import {
   AnyRoute,
+  PageComponent,
   PageModule,
   Route,
   RouteParams
@@ -19,7 +20,7 @@
 }
 
 function getInitialProps<Params extends RouteParams | undefined, Props>(
-  module: PageModule<Params, Props>,
+  module: PageComponent<Params, Props>,
   params: Params
 ): Promise<HttpResponse<Props> | void> {
   return module.getInitialProps
@@ -32,10 +33,13 @@
   params: Params
 ): Promise<RouteResponse<Props>> {
   return route.importModule().then((module: PageModule<Params, Props>) =>
-    getInitialProps(module, params).then((response: HttpResponse<Props>) => ({
+    getInitialProps(
+      module.default,
+      params
+    ).then((response: HttpResponse<Props>) => ({
       chunkName: route.chunkName,
-      status: (response && response.status) || module.status || 200,
-      Component: module.Component as AnyComponent<Props, any>,
+      status: (response && response.status) || module.default.status || 200,
+      Component: module.default.Component as AnyComponent<Props, any>,
       props: response && response.data
     }))
   );

-- 
To view, visit https://gerrit.wikimedia.org/r/388069
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib80dc40548bddec1b1fdc36c1e8a68a2350809f5
Gerrit-PatchSet: 1
Gerrit-Project: marvin
Gerrit-Branch: master
Gerrit-Owner: Niedzielski <[email protected]>
Gerrit-Reviewer: Sniedzielski <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to