Skip to content

Commit

Permalink
Add 404 screen (hashicorp-forge#76)
Browse files Browse the repository at this point in the history
* Draft of 404

* Update design

* Fix transitionTo; Add test; MockDate resets

* Revert out-of-scope changes

* Fix merge error
  • Loading branch information
jeffdaley authored Mar 20, 2023
1 parent fe71d4e commit 6b807fb
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 1 deletion.
8 changes: 8 additions & 0 deletions web/app/controllers/404.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Controller from "@ember/controller";
import parseDate from "hermes/utils/parse-date";

export default class Error404Controller extends Controller {
get currentDate() {
return parseDate(new Date(), "long");
}
}
1 change: 1 addition & 0 deletions web/app/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ Router.map(function () {
});
});
this.route("authenticate");
this.route('404', { path: '/*path' })
});
3 changes: 3 additions & 0 deletions web/app/routes/404.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Route from "@ember/routing/route";

export default class Error404Route extends Route {}
13 changes: 12 additions & 1 deletion web/app/routes/authenticated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,18 @@ export default class AuthenticatedRoute extends Route {
) {
// ember-simple-auth uses this value to set cookies when fastboot is enabled: https://github.com/mainmatter/ember-simple-auth/blob/a7e583cf4d04d6ebc96b198a8fa6dde7445abf0e/packages/ember-simple-auth/addon/-internals/routing.js#L12

window.sessionStorage.setItem(SESSION_STORAGE_KEY, transition.intent.url);
/**
* We expect a `transition.intent.url`, but in rare cases, it's undefined,
* e.g., when clicking the "view dashboard" button from the 404 route.
* When this happens, we fall back to `transition.to.name`.
*
* For reference:
* `transition.intent.url` e.g., 'documents/1'
* `transition.to.name` e.g., 'authenticated.documents'
*/
let transitionTo = transition.intent.url ?? transition.to.name;

window.sessionStorage.setItem(SESSION_STORAGE_KEY, transitionTo);
}
}
}
1 change: 1 addition & 0 deletions web/app/styles/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
@use "./ember-power-select-theme";

@use "@hashicorp/design-system-components";
@use "./error-404";
@use "./hds-overrides";

@use "tailwindcss/base";
Expand Down
35 changes: 35 additions & 0 deletions web/app/styles/error-404.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
.error-404 {
@apply bg-color-page-faint;

.title {
@apply text-[3.5rem] mb-5 mr-20;
}

.doc-page {
@apply mt-16 bg-white shadow-2xl border border-color-border-primary rounded-t-xl;
}

.meta-information {
@apply grid grid-cols-2 gap-8;

> div {
@apply space-y-1;
}
}

.divider {
@apply h-[4px] bg-color-foreground-strong w-full;
}

p {
@apply text-display-300 text-color-foreground-strong;
}

.summary {
@apply mb-6 text-display-400 pr-20;
}

.gradient-overlay {
@apply fixed w-full h-56 bottom-0 pointer-events-none bg-gradient-to-t from-color-surface-strong to-transparent;
}
}
54 changes: 54 additions & 0 deletions web/app/templates/404.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{{page-title "Page not found"}}
{{set-body-class "error-404"}}

<div class="flex w-full min-h-screen px-16">
<div class="x-container doc-page">
<div class="p-16">
<header class="flex items-center justify-between mb-16">
<LinkTo @route="authenticated.dashboard" class="no-underline">
<HermesLogo />
</LinkTo>
<Hds::Button
@text="View dashboard"
@icon="arrow-right"
@iconPosition="trailing"
@route="authenticated.dashboard"
/>
</header>
<div class="divider mb-6"></div>
<h1 class="title">[E-404] Page not found</h1>
<p class="summary">
<strong class="mr-1">Summary:</strong>The address may be expired or the
page may have moved. We apologize for any inconvenience.
</p>
<div class="meta-information">
<div>
<p><strong>Status:</strong>
Loading | Success |
<strong>Error</strong></p>
<p><strong>Type:</strong> Four hundred four</p>
</div>
<div>
<p data-test-404-logged-time>
<strong>Logged:</strong>
{{this.currentDate}}</p>
<p><strong>Assignee:</strong> Admin</p>
</div>
</div>
<div class="divider mt-10 mb-14"></div>
<p class="mb-40">
<strong class="uppercase">Note:</strong>
If you think this is a mistake,
<Hds::Link::Inline
@isHrefExternal={{true}}
@href="https://github.com/hashicorp-forge/hermes/issues"
@icon="external-link"
class="hover:no-underline"
>
please create an issue on GitHub
</Hds::Link::Inline>
</p>
</div>
</div>
<div class="gradient-overlay"></div>
</div>
1 change: 1 addition & 0 deletions web/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ module.exports = {
"color-surface-interactive-hover":
"var(--token-color-surface-interactive-hover)",
"color-surface-primary": "var(--token-color-surface-primary)",
"color-surface-strong": "var(--token-color-surface-strong)",
"color-surface-warning": "var(--token-color-surface-warning)",

// Border
Expand Down
22 changes: 22 additions & 0 deletions web/tests/acceptance/404-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { visit } from "@ember/test-helpers";
import { setupApplicationTest } from "ember-qunit";
import { module, test } from "qunit";
import { getPageTitle } from "ember-page-title/test-support";
import MockDate from "mockdate";

module("Acceptance | 404", function (hooks) {
setupApplicationTest(hooks);

test("unknown URLs get the 404 treatment", async function (assert) {
MockDate.set("2000-01-01T06:00:00.000-07:00");

await visit("/not_real_url");

assert.equal(getPageTitle(), "Page not found | Hermes");

assert.dom("h1").hasText("[E-404] Page not found");
assert.dom("[data-test-404-logged-time]").hasText("Logged: 1 January 2000");

MockDate.reset();
});
});

0 comments on commit 6b807fb

Please sign in to comment.