Skip to content

Commit

Permalink
Add Project::Tile component (#379)
Browse files Browse the repository at this point in the history
* Fix and expand RelatedHermesDocument type

* Update list-item-test.ts

* Revert out-of-scope changes

* Add more attributes to RelatedHermesDocument

* Add new attrs to Go API

* Revert out-of-scope change

* Start of Project Tile

* Write tests, add factories

* Cleanup
  • Loading branch information
jeffdaley authored Oct 25, 2023
1 parent cb38bd2 commit dca6893
Show file tree
Hide file tree
Showing 11 changed files with 353 additions and 8 deletions.
54 changes: 54 additions & 0 deletions web/app/components/project/tile.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<Hds::Card::Container
data-test-project-tile
@hasBorder={{true}}
@levelHover="mid"
class="project-tile h-48 p-4"
...attributes
>
<div class="relative h-full pb-16">
<h3
data-test-title
class="title text-display-300 font-semibold text-color-foreground-strong"
>
{{@project.title}}
</h3>
{{#if @project.description}}
<p
data-test-description
class="description mt-1 text-body-300 text-color-foreground-faint"
>
{{@project.description}}
</p>
{{/if}}

<div
class="absolute bottom-0 left-0 flex w-full items-center justify-between"
>
{{#if this.productAreas}}
<ul class="flex gap-px">
{{#each this.productAreas as |productArea|}}
<li class="flex items-center" data-test-product>
{{productArea}}
</li>
{{/each}}
</ul>
{{/if}}
{{#if this.jiraObject}}
<div class="flex items-center gap-1.5">
{{#if @project.jiraObject.type}}
<span data-test-jira-type>
{{@project.jiraObject.type}}
</span>
{{/if}}
<span
data-test-jira-key
class="text-body-100 text-color-foreground-faint
{{if (eq this.jiraObject.status 'Done') 'line-through'}}"
>
{{this.jiraObject.key}}
</span>
</div>
{{/if}}
</div>
</div>
</Hds::Card::Container>
29 changes: 29 additions & 0 deletions web/app/components/project/tile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Component from "@glimmer/component";
import { HermesProject } from "hermes/types/project";

interface ProjectTileComponentSignature {
Element: HTMLDivElement;
Args: {
project: HermesProject;
};
}

export default class ProjectTileComponent extends Component<ProjectTileComponentSignature> {
protected get documents() {
return this.args.project.documents;
}

protected get jiraObject() {
return this.args.project.jiraObject;
}

protected get productAreas() {
return this.documents?.map((doc) => doc.product).uniq();
}
}

declare module "@glint/environment-ember-loose/registry" {
export default interface Registry {
"Project::Tile": typeof ProjectTileComponent;
}
}
3 changes: 2 additions & 1 deletion web/app/styles/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
@use "components/doc/tile-list";
@use "components/doc/thumbnail";
@use "components/doc/folder-affordance";
@use "components/doc/tile";
@use "components/doc/tile" as doc-tile;
@use "components/doc/state";
@use "components/table/sortable-header";
@use "components/preview-card";
Expand All @@ -38,6 +38,7 @@
@use "components/document/related-resources";
@use "components/hds-badge";
@use "components/product-badge-link";
@use "components/project/tile" as project-tile;
@use "components/header/facet-dropdown";
@use "components/floating-u-i/content";
@use "components/settings/subscription-list-item";
Expand Down
18 changes: 18 additions & 0 deletions web/app/styles/components/project/tile.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.project-tile {
.title,
.description {
@apply overflow-hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
}

.title {
-webkit-line-clamp: 2;
line-clamp: 2;
}

.description {
-webkit-line-clamp: 3;
line-clamp: 3;
}
}
6 changes: 4 additions & 2 deletions web/app/templates/authenticated/projects/index.hbs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
{{page-title "All Projects"}}

<ol>
<ol class="relative grid grid-cols-3 gap-2">
{{#each-in this.model as |_id project|}}
<li data-test-project>
{{project.title}}
<LinkTo @route="authenticated.projects.project" @model={{project.id}}>
<Project::Tile @project={{project}} />
</LinkTo>
</li>
{{/each-in}}
</ol>
12 changes: 12 additions & 0 deletions web/mirage/factories/jira-object.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Factory } from "miragejs";

export default Factory.extend({
id: (i) => i,
key: (i) => `KEY-00${i}`,
url: "",
priority: "Medium",
status: "Open",
assignee: "Unassigned",
type: "Task",
summary: "This is a Jira object",
});
20 changes: 19 additions & 1 deletion web/mirage/factories/project.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
import { Factory } from "miragejs";
import { Factory, ModelInstance, Server } from "miragejs";
import { HermesProject } from "hermes/types/project";

export default Factory.extend({
id: (i: number) => i,
title: (i: number) => `Test Project ${i}`,
dateCreated: 1,
dateModified: 1,
creator: "[email protected]",

// @ts-ignore - Bug https://github.com/miragejs/miragejs/issues/1052
afterCreate(project: ModelInstance<HermesProject>, server: any): void {
server.createList("related-hermes-document", 1);
server.create("jira-object");

const relatedHermesDocuments = server.schema.relatedHermesDocument
.all()
.models.map((doc: ModelInstance) => doc.attrs);

const jiraObject = server.schema.jiraObjects.first()?.attrs;

project.update({
documents: relatedHermesDocuments,
jiraObject,
});
},
});
5 changes: 5 additions & 0 deletions web/mirage/models/jira-object.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Model } from "miragejs";

export default Model.extend({
// Required for Mirage, even though it's empty
});
59 changes: 56 additions & 3 deletions web/tests/acceptance/authenticated/projects-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ import { getPageTitle } from "ember-page-title/test-support";
import { setupApplicationTest } from "ember-qunit";
import { HermesProject } from "hermes/types/project";

const PROJECT_TILE = "[data-test-project-tile]";
const PROJECT_TITLE = `${PROJECT_TILE} [data-test-title]`;
const PROJECT_DESCRIPTION = `${PROJECT_TILE} [data-test-description]`;
const PROJECT_PRODUCT = `${PROJECT_TILE} [data-test-product]`;
const PROJECT_JIRA_TYPE = `${PROJECT_TILE} [data-test-jira-type]`;
const PROJECT_JIRA_KEY = `${PROJECT_TILE} [data-test-jira-key]`;

interface AuthenticatedProjectsRouteTestContext extends MirageTestContext {}
module("Acceptance | authenticated/projects", function (hooks) {
setupApplicationTest(hooks);
Expand All @@ -27,14 +34,60 @@ module("Acceptance | authenticated/projects", function (hooks) {

assert.dom("[data-test-project]").exists({ count: 3 });

const expectedTitles = this.server.schema.projects
let expectedTitles: string[] = [];
let expectedDescriptions: string[] = [];
let expectedProducts: string[] = [];
let expectedKeys: string[] = [];
let expectedJiraTypes: string[] = [];

this.server.schema.projects
.all()
.models.map((project: HermesProject) => project.title);
.models.forEach((project: HermesProject) => {
expectedTitles.push(project.title);

if (project.description) {
expectedDescriptions.push(project.description);
}

if (project.jiraObject) {
expectedKeys.push(project.jiraObject.key);
if (project.jiraObject.type) {
expectedJiraTypes.push(project.jiraObject.type);
}
}
if (project.documents) {
project.documents.forEach((doc) => {
if (doc.product) {
expectedProducts.push(doc.product);
}
});
}
});

const renderedTitles = findAll(PROJECT_TITLE).map(
(e) => e.textContent?.trim(),
);

const renderedDescriptions = findAll(PROJECT_DESCRIPTION).map(
(e) => e.textContent?.trim(),
);

const renderedProducts = findAll(PROJECT_PRODUCT).map(
(e) => e.textContent?.trim(),
);

const renderedKeys = findAll(PROJECT_JIRA_KEY).map(
(e) => e.textContent?.trim(),
);

const renderedTitles = findAll("[data-test-project]").map(
const renderedJiraTypes = findAll(PROJECT_JIRA_TYPE).map(
(e) => e.textContent?.trim(),
);

assert.deepEqual(renderedTitles, expectedTitles);
assert.deepEqual(renderedDescriptions, expectedDescriptions);
assert.deepEqual(renderedProducts, expectedProducts);
assert.deepEqual(renderedKeys, expectedKeys);
assert.deepEqual(renderedJiraTypes, expectedJiraTypes);
});
});
Loading

0 comments on commit dca6893

Please sign in to comment.