Skip to content

Commit

Permalink
Merge branch 'main' into jeffdaley/products-route
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffdaley committed Oct 20, 2023
2 parents 5071235 + b00e6a2 commit 70a85c6
Show file tree
Hide file tree
Showing 24 changed files with 865 additions and 204 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
node_modules
/web/.pnp.*
/web/.yarn/*
/web/.eslintcache
/web/dist

# Terraform related
Expand Down
18 changes: 13 additions & 5 deletions internal/api/documents_related_resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,15 @@ type externalLinkRelatedResourceGetResponse struct {
}

type hermesDocumentRelatedResourceGetResponse struct {
GoogleFileID string `json:"googleFileID"`
Title string `json:"title"`
DocumentType string `json:"documentType"`
DocumentNumber string `json:"documentNumber"`
SortOrder int `json:"sortOrder"`
GoogleFileID string `json:"googleFileID"`
Title string `json:"title"`
DocumentType string `json:"documentType"`
DocumentNumber string `json:"documentNumber"`
SortOrder int `json:"sortOrder"`
Status string `json:"status"`
Owners []string `json:"owners"`
OwnerPhotos []string `json:"ownerPhotos"`
Product string `json:"product"`
}

func documentsResourceRelatedResourcesHandler(
Expand Down Expand Up @@ -153,6 +157,10 @@ func documentsResourceRelatedResourcesHandler(
DocumentType: doc.DocType,
DocumentNumber: doc.DocNumber,
SortOrder: hdrr.RelatedResource.SortOrder,
Status: doc.Status,
Owners: doc.Owners,
OwnerPhotos: doc.OwnerPhotos,
Product: doc.Product,
})
}

Expand Down
44 changes: 44 additions & 0 deletions web/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
module.exports = {
plugins: ["ember", "@typescript-eslint"],
parser: "@typescript-eslint/parser",
parserOptions: {
project: "./tsconfig.json",
},
ignorePatterns: ["*.js", "/mirage/**/*", "/node_modules/**/*", "/dist/**/*"],
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking",
],

rules: {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unsafe-member-access": "off",
"@typescript-eslint/no-unsafe-call": "off",
"@typescript-eslint/no-unsafe-assignment": "off",
"@typescript-eslint/no-unsafe-argument": "off",
"@typescript-eslint/no-unsafe-return": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/no-redundant-type-constituents": "off",
"@typescript-eslint/require-await": "off",
"@typescript-eslint/no-floating-promises": "off",
"@typescript-eslint/unbound-method": "off",
"@typescript-eslint/no-misused-promises": "off",
"@typescript-eslint/restrict-template-expressions": "off",
"@typescript-eslint/no-misused-new": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/restrict-plus-operands": "off",
"@typescript-eslint/await-thenable": "off",
"@typescript-eslint/no-unsafe-enum-comparison": "off",
"@typescript-eslint/no-unnecessary-type-assertion": "off",
"no-case-declarations": "off",
"no-fallthrough": "off",
"prefer-const": "off",
"no-empty-pattern": "off",
"no-control-regex": "off",
"no-self-assign": "off",
"prefer-rest-params": "off",
"no-empty": "off",
},
};
12 changes: 11 additions & 1 deletion web/app/components/editable-field.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { action } from "@ember/object";
import { next, schedule, scheduleOnce } from "@ember/runloop";
import { schedule, scheduleOnce } from "@ember/runloop";
import { assert } from "@ember/debug";
import { guidFor } from "@ember/object/internals";
import { HermesDocument, HermesUser } from "hermes/types/document";
import blinkElement from "hermes/utils/blink-element";

export const FOCUSABLE =
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
Expand Down Expand Up @@ -185,6 +186,7 @@ export default class EditableFieldComponent extends Component<EditableFieldCompo
*/
@action protected disableEditing() {
this.editingIsEnabled = false;
this.emptyValueErrorIsShown = false;
}

/**
Expand Down Expand Up @@ -255,9 +257,17 @@ export default class EditableFieldComponent extends Component<EditableFieldCompo
(newValue instanceof Array && newValue.length === 0)
) {
if (this.args.isRequired) {
if (this.emptyValueErrorIsShown) {
const error =
this.editingContainer?.querySelector(".hds-form-error");
blinkElement(error);
return;
}

this.emptyValueErrorIsShown = true;
return;
}

/**
* We don't consider an empty value to be a change
* if the initial value is undefined.
Expand Down
6 changes: 1 addition & 5 deletions web/app/components/hermes-logo.hbs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
{{! @glint-nocheck: not typesafe yet }}
<div
class="hermes-logo"
...attributes
>
<div class="hermes-logo" ...attributes>
<FlightIcon @name="hashicorp" @size="24" />
<div class="hermes-logo-divider"></div>
<div class="hermes-logo-text">
Expand Down
7 changes: 6 additions & 1 deletion web/app/components/hermes-logo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import Component from "@glimmer/component";

interface HermesLogoComponentSignature {
Element: HTMLDivElement;
Args: {};
}

export default class HermesLogoComponent extends Component<HermesLogoComponentSignature> {}

declare module "@glint/environment-ember-loose/registry" {
export default interface Registry {
HermesLogo: typeof HermesLogoComponent;
}
}
1 change: 1 addition & 0 deletions web/app/components/inputs/product-select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import ProductAreasService, {
ProductArea,
} from "hermes/services/product-areas";
import getProductId from "hermes/utils/get-product-id";
import { MatchAnchorWidthOptions } from "../floating-u-i/content";

interface InputsProductSelectSignature {
Element: HTMLDivElement;
Expand Down
49 changes: 49 additions & 0 deletions web/app/components/new/project-form.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<form
data-test-project-form
{{on "submit" this.maybeSubmitForm}}
class="mx-auto mb-10 max-w-xl"
>
<div class="space-y-4">
<h1>Start a project</h1>
</div>
<div class="mt-7 grid gap-7">
<Hds::Form::Textarea::Field
{{on "keydown" this.onKeydown}}
{{auto-height-textarea}}
{{autofocus}}
data-test-title
@value={{this.title}}
name="title"
placeholder="Enter a project title"
as |F|
>
<F.Label>Title</F.Label>
{{#if this.errorIsShown}}
<F.Error data-test-title-error>
Title is required.
</F.Error>
{{/if}}
</Hds::Form::Textarea::Field>

<Hds::Form::Textarea::Field
data-test-description
{{on "keydown" this.onKeydown}}
@value={{this.description}}
rows="2"
placeholder="A short summary of your project"
name="description"
as |F|
>
<F.Label>Description</F.Label>
</Hds::Form::Textarea::Field>

{{! TODO: Add Jira integration }}

</div>
<Hds::Button
data-test-submit
@text="Create project"
@isFullWidth={{true}}
type="submit"
/>
</form>
88 changes: 88 additions & 0 deletions web/app/components/new/project-form.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { action } from "@ember/object";
import RouterService from "@ember/routing/router-service";
import { next } from "@ember/runloop";
import { inject as service } from "@ember/service";
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import FlashMessageService from "ember-cli-flash/services/flash-messages";
import { task } from "ember-concurrency";
import FetchService from "hermes/services/fetch";
import cleanString from "hermes/utils/clean-string";

interface NewProjectFormComponentSignature {
Args: {};
}

export default class NewProjectFormComponent extends Component<NewProjectFormComponentSignature> {
@service("fetch") declare fetchSvc: FetchService;
@service declare router: RouterService;
@service declare flashMessages: FlashMessageService;

@tracked protected title: string = "";
@tracked protected description: string = "";

@tracked protected formIsValid = false;
@tracked protected errorIsShown = false;

@action maybeSubmitForm(event?: SubmitEvent) {
if (event) {
event.preventDefault();
}

this.validateForm();

if (this.formIsValid) {
this.createProject.perform();
}
}

private validateForm() {
this.errorIsShown = this.title.length === 0;
this.formIsValid = this.title.length > 0;
}

@action protected onKeydown(e: KeyboardEvent) {
if (e.key === "Enter") {
// Replace newline function with submit action
e.preventDefault();
this.maybeSubmitForm();
}
if (this.errorIsShown) {
// Validate once the input value are captured
next("afterRender", () => {
this.validateForm();
});
}
}

private createProject = task(async () => {
try {
const project = await this.fetchSvc
.fetch("/api/v1/projects", {
method: "POST",
body: JSON.stringify({
title: cleanString(this.title),
description: cleanString(this.description),
}),
})
.then((response) => response?.json());
this.router.transitionTo("authenticated.projects.project", project.id);
} catch (error: unknown) {
const typedError = error as Error;

this.flashMessages.add({
title: "Error creating project",
message: typedError.message,
type: "critical",
timeout: 6000,
extendedTimeout: 1000,
});
}
});
}

declare module "@glint/environment-ember-loose/registry" {
export default interface Registry {
"New::ProjectForm": typeof NewProjectFormComponent;
}
}
4 changes: 4 additions & 0 deletions web/app/components/related-resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ export interface RelatedHermesDocument {
documentType: string;
documentNumber: string;
sortOrder: number;
status: string;
owners?: string[];
ownerPhotos?: string[];
product?: string;
}

export enum RelatedResourcesScope {
Expand Down
3 changes: 3 additions & 0 deletions web/app/components/related-resources/add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,9 @@ export default class RelatedResourcesAddComponent extends Component<RelatedResou
title: attrs.title,
documentType: attrs.docType,
documentNumber: attrs.docNumber,
owners: attrs.owners,
ownerPhotos: attrs.ownerPhotos,
product: attrs.product,
sortOrder: 1,
} as RelatedHermesDocument;

Expand Down
8 changes: 7 additions & 1 deletion web/app/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ export default class Router extends EmberRouter {
rootURL = config.rootURL;
}

const showProjectRoutes =
config.environment === "development" || config.environment === "test";

Router.map(function () {
this.route("authenticated", { path: "/" }, function () {
this.route("product-area", { path: "/product-area/:product_area_id" });
Expand All @@ -19,9 +22,12 @@ Router.map(function () {
this.route("settings");
this.route("new", function () {
this.route("doc");
if (showProjectRoutes) {
this.route("project");
}
});

if (config.environment === "development" || config.environment === "test") {
if (showProjectRoutes) {
this.route("projects", function () {
this.route("project", { path: "/:project_id" });
});
Expand Down
10 changes: 9 additions & 1 deletion web/app/routes/authenticated/new/doc.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
import Route from "@ember/routing/route";
import { inject as service } from "@ember/service";
import ProductAreasService from "hermes/services/product-areas";

interface AuthenticatedNewDocRouteParams {
docType: string;
}

export default class AuthenticatedNewDocRoute extends Route {
@service declare productAreas: ProductAreasService;

queryParams = {
docType: {
refreshModel: true,
},
};

model(params: AuthenticatedNewDocRouteParams) {
async model(params: AuthenticatedNewDocRouteParams) {
if (!this.productAreas.index) {
await this.productAreas.fetch.perform();
}

return params.docType;
}
}
3 changes: 3 additions & 0 deletions web/app/routes/authenticated/new/project.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Route from "@ember/routing/route";

export default class AuthenticatedNewProjectRoute extends Route {}
3 changes: 3 additions & 0 deletions web/app/templates/authenticated/new/project.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{{page-title "Start a project"}}

<New::ProjectForm />
Loading

0 comments on commit 70a85c6

Please sign in to comment.