From 6d3682305468d3b7b0b909b2facbe3aa5f75e734 Mon Sep 17 00:00:00 2001 From: Jeff Daley Date: Mon, 18 Mar 2024 14:11:21 -0400 Subject: [PATCH 1/3] Add EmberData support to JiraIssues --- web/app/adapters/jira-issue.ts | 19 ++++++++++++ web/app/components/project/index.ts | 7 +++-- web/app/components/project/tile.ts | 16 ++++++---- web/app/models/jira-issue.ts | 48 +++++++++++++++++++++++++++++ web/app/serializers/jira-issue.ts | 26 ++++++++++++++++ 5 files changed, 107 insertions(+), 9 deletions(-) create mode 100644 web/app/adapters/jira-issue.ts create mode 100644 web/app/models/jira-issue.ts create mode 100644 web/app/serializers/jira-issue.ts diff --git a/web/app/adapters/jira-issue.ts b/web/app/adapters/jira-issue.ts new file mode 100644 index 000000000..59b67281c --- /dev/null +++ b/web/app/adapters/jira-issue.ts @@ -0,0 +1,19 @@ +import DS from "ember-data"; +import ApplicationAdapter from "./application"; +import RSVP from "rsvp"; +import ModelRegistry from "ember-data/types/registries/model"; + +export default class JiraIssueAdapter extends ApplicationAdapter { + findRecord( + _store: DS.Store, + _type: ModelRegistry[K], + id: string, + _snapshot: DS.Snapshot, + ): RSVP.Promise { + const issue = this.fetchSvc + .fetch(`/api/${this.configSvc.config.api_version}/jira/issues/${id}`) + .then((response) => response?.json()); + + return RSVP.resolve(issue); + } +} diff --git a/web/app/components/project/index.ts b/web/app/components/project/index.ts index c78e2c605..3e87b785b 100644 --- a/web/app/components/project/index.ts +++ b/web/app/components/project/index.ts @@ -28,6 +28,7 @@ import { Resize } from "ember-animated/motions/resize"; import { easeOutExpo, easeOutQuad } from "hermes/utils/ember-animated/easings"; import animateTransform from "hermes/utils/ember-animated/animate-transform"; import RouterService from "@ember/routing/router-service"; +import StoreService from "hermes/services/store"; const animationDuration = Ember.testing ? 0 : 450; @@ -58,6 +59,7 @@ export default class ProjectIndexComponent extends Component { const id = jiraIssueID ?? this.args.project.jiraIssueID; - const issue = await this.fetchSvc - .fetch(`/api/${this.configSvc.config.api_version}/jira/issues/${id}`) - .then((response) => response?.json()); + assert("jiraIssueID must exist", id); + const issue = await this.store.findRecord("jira-issue", id); this.jiraIssue = issue; }); diff --git a/web/app/components/project/tile.ts b/web/app/components/project/tile.ts index a68530a3f..3d4220b17 100644 --- a/web/app/components/project/tile.ts +++ b/web/app/components/project/tile.ts @@ -1,9 +1,11 @@ +import { assert } from "@ember/debug"; import { inject as service } from "@ember/service"; import Component from "@glimmer/component"; import { tracked } from "@glimmer/tracking"; import { task } from "ember-concurrency"; import ConfigService from "hermes/services/config"; import FetchService from "hermes/services/fetch"; +import StoreService from "hermes/services/store"; import { HermesProject, HermesProjectHit, @@ -27,6 +29,7 @@ interface ProjectTileComponentSignature { export default class ProjectTileComponent extends Component { @service("fetch") declare fetchSvc: FetchService; @service("config") declare configSvc: ConfigService; + @service declare store: StoreService; constructor(owner: unknown, args: ProjectTileComponentSignature["Args"]) { super(owner, args); @@ -96,13 +99,14 @@ export default class ProjectTileComponent extends Component { - const jiraIssue = await this.fetchSvc - .fetch( - `/api/${this.configSvc.config.api_version}/jira/issues/${this.args.project.jiraIssueID}`, - ) - .then((resp) => resp?.json()); + assert("jiraIssueID must exist", this.args.project.jiraIssueID); - this.jiraIssue = jiraIssue as JiraIssue; + const jiraIssue = await this.store.findRecord( + "jira-issue", + this.args.project.jiraIssueID, + ); + + this.jiraIssue = jiraIssue; }); } diff --git a/web/app/models/jira-issue.ts b/web/app/models/jira-issue.ts new file mode 100644 index 000000000..35466278e --- /dev/null +++ b/web/app/models/jira-issue.ts @@ -0,0 +1,48 @@ +import Model, { attr } from "@ember-data/model"; + +export default class JiraIssueModel extends Model { + /** + * + */ + @attr declare key: string; + + /** + * + */ + @attr declare summary: string; + + /** + * + */ + @attr declare url: string; + + /** + * + */ + @attr declare status: string; + + /** + * + */ + @attr declare assignee: string; + + /** + * + */ + @attr declare issueType: string; + + /** + * + */ + @attr declare issueTypeImage: string; + + /** + * + */ + @attr declare priority: string; + + /** + * + */ + @attr declare priorityImage: string; +} diff --git a/web/app/serializers/jira-issue.ts b/web/app/serializers/jira-issue.ts new file mode 100644 index 000000000..ebd9bbba9 --- /dev/null +++ b/web/app/serializers/jira-issue.ts @@ -0,0 +1,26 @@ +import JSONSerializer from "@ember-data/serializer/json"; +import DS from "ember-data"; +import JiraIssueModel from "hermes/models/jira-issue"; + +export default class JiraIssueSerializer extends JSONSerializer { + /** + * The serializer for the `person` model. + * Handles `query` and `queryRecord` requests to the EmberData store. + * Formats the response to match the JSON spec. + */ + normalizeResponse( + _store: DS.Store, + _primaryModelClass: any, + payload: JiraIssueModel, + _id: string | number, + _requestType: string, + ) { + return { + data: { + id: payload.key, + type: "jira-issue", + attributes: payload, + }, + }; + } +} From 0efc68a27a1db11b2c7d8334dd47b396e25f338a Mon Sep 17 00:00:00 2001 From: Jeff Daley Date: Mon, 18 Mar 2024 14:13:15 -0400 Subject: [PATCH 2/3] Remove`fade-in` animation --- web/app/components/project/tile.hbs | 3 +-- web/app/styles/animations.scss | 4 ---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/web/app/components/project/tile.hbs b/web/app/components/project/tile.hbs index 16a332171..7385fca6e 100644 --- a/web/app/components/project/tile.hbs +++ b/web/app/components/project/tile.hbs @@ -33,8 +33,7 @@
diff --git a/web/app/styles/animations.scss b/web/app/styles/animations.scss index d5f8c9446..6f717b5a5 100644 --- a/web/app/styles/animations.scss +++ b/web/app/styles/animations.scss @@ -7,10 +7,6 @@ } } -.fade-in-forwards { - animation: fadeIn 450ms forwards; -} - @keyframes fadeOut { from { opacity: 1; From fdd75178a23553bde76b04b8e332b00c03ec074b Mon Sep 17 00:00:00 2001 From: Jeff Daley Date: Mon, 18 Mar 2024 14:23:46 -0400 Subject: [PATCH 3/3] Update types and descriptions --- web/app/adapters/jira-issue.ts | 3 +- web/app/components/project/jira-widget.ts | 5 ++-- web/app/components/project/tile.ts | 9 ++---- web/app/models/jira-issue.ts | 29 ++++++++++--------- web/app/serializers/jira-issue.ts | 5 ++-- web/app/types/project.d.ts | 15 ++-------- .../components/project/jira-widget-test.ts | 5 ++-- 7 files changed, 31 insertions(+), 40 deletions(-) diff --git a/web/app/adapters/jira-issue.ts b/web/app/adapters/jira-issue.ts index 59b67281c..3e2caa740 100644 --- a/web/app/adapters/jira-issue.ts +++ b/web/app/adapters/jira-issue.ts @@ -2,6 +2,7 @@ import DS from "ember-data"; import ApplicationAdapter from "./application"; import RSVP from "rsvp"; import ModelRegistry from "ember-data/types/registries/model"; +import JiraIssueModel from "hermes/models/jira-issue"; export default class JiraIssueAdapter extends ApplicationAdapter { findRecord( @@ -9,7 +10,7 @@ export default class JiraIssueAdapter extends ApplicationAdapter { _type: ModelRegistry[K], id: string, _snapshot: DS.Snapshot, - ): RSVP.Promise { + ): RSVP.Promise { const issue = this.fetchSvc .fetch(`/api/${this.configSvc.config.api_version}/jira/issues/${id}`) .then((response) => response?.json()); diff --git a/web/app/components/project/jira-widget.ts b/web/app/components/project/jira-widget.ts index 62b9e8284..afc9996ba 100644 --- a/web/app/components/project/jira-widget.ts +++ b/web/app/components/project/jira-widget.ts @@ -4,16 +4,17 @@ import { tracked } from "@glimmer/tracking"; import { inject as service } from "@ember/service"; import { restartableTask } from "ember-concurrency"; import FetchService from "hermes/services/fetch"; -import { JiraIssue, JiraPickerResult } from "hermes/types/project"; +import { JiraPickerResult } from "hermes/types/project"; import ConfigService from "hermes/services/config"; import { XDropdownListAnchorAPI } from "../x/dropdown-list"; import { next } from "@ember/runloop"; import { assert } from "@ember/debug"; +import JiraIssueModel from "hermes/models/jira-issue"; interface ProjectJiraWidgetComponentSignature { Element: HTMLDivElement; Args: { - issue?: JiraPickerResult | JiraIssue; + issue?: JiraPickerResult | JiraIssueModel; onIssueSelect?: (issue: any) => void; onIssueRemove?: () => void; isDisabled?: boolean; diff --git a/web/app/components/project/tile.ts b/web/app/components/project/tile.ts index 3d4220b17..3a90c780f 100644 --- a/web/app/components/project/tile.ts +++ b/web/app/components/project/tile.ts @@ -3,14 +3,11 @@ import { inject as service } from "@ember/service"; import Component from "@glimmer/component"; import { tracked } from "@glimmer/tracking"; import { task } from "ember-concurrency"; +import JiraIssueModel from "hermes/models/jira-issue"; import ConfigService from "hermes/services/config"; import FetchService from "hermes/services/fetch"; import StoreService from "hermes/services/store"; -import { - HermesProject, - HermesProjectHit, - JiraIssue, -} from "hermes/types/project"; +import { HermesProject, HermesProjectHit } from "hermes/types/project"; export const PROJECT_TILE_MAX_PRODUCTS = 3; @@ -50,7 +47,7 @@ export default class ProjectTileComponent extends Component void; onIssueRemove: () => void;