Skip to content

Commit

Permalink
Merge pull request #1424 from CMSgov/EASI-1499/backend-connected-book…
Browse files Browse the repository at this point in the history
…mark-components

[EASI-1499] Fully connected the bookmarking frontend components to the backend
  • Loading branch information
jstrang-oddball committed Jan 19, 2022
2 parents 638cf7d + 5f573a7 commit c8837bd
Show file tree
Hide file tree
Showing 20 changed files with 429 additions and 202 deletions.
13 changes: 5 additions & 8 deletions pkg/storage/cedar_system_bookmark.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,14 @@ func (s *Store) FetchCedarSystemBookmarks(ctx context.Context) ([]*models.CedarS

// DeleteCedarSystemBookmark deletes an existing cedar system bookmark object in the database
func (s *Store) DeleteCedarSystemBookmark(ctx context.Context, cedarSystemBookmark *models.CedarSystemBookmark) (*models.CedarSystemBookmark, error) {
euaUserID := appcontext.Principal(ctx).ID()

const deleteCedarSystemBookmarkSQL = `
DELETE FROM cedar_system_bookmarks
WHERE eua_user_id.id = :id
AND cedar_system_id = :
RETURNING *`
WHERE eua_user_id = $1
AND cedar_system_id = $2;`

_, err := s.db.NamedExecContext(
ctx,
deleteCedarSystemBookmarkSQL,
cedarSystemBookmark,
)
_, err := s.db.Exec(deleteCedarSystemBookmarkSQL, euaUserID, cedarSystemBookmark.CedarSystemID)

if err != nil {
appcontext.ZLogger(ctx).Error("Failed to delete cedar system bookmark with error %s", zap.Error(err))
Expand Down
81 changes: 56 additions & 25 deletions src/components/BookmarkCard/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,40 @@
import React from 'react';
import { MemoryRouter } from 'react-router-dom';
import { MockedProvider } from '@apollo/client/testing';
import { render } from '@testing-library/react';

import GetCedarSystemsAndBookmarksQuery from 'queries/GetCedarSystemsAndBookmarksQuery';
import { mapCedarStatusToIcon } from 'types/iconStatus';
import { mockSystemInfo } from 'views/Sandbox/mockSystemData';

import BookmarkCard from './index';

describe('BookmarkCard', () => {
const mocks = [
{
request: {
query: GetCedarSystemsAndBookmarksQuery
},
result: {
data: {
cedarSystems: [],
cedarSystemBookmarks: []
}
}
}
];

it('matches the snapshot', () => {
const { asFragment } = render(
<MemoryRouter>
<BookmarkCard
type="systemProfile"
statusIcon={mapCedarStatusToIcon(mockSystemInfo[0].status)}
{...mockSystemInfo[0]}
/>
<MockedProvider mocks={mocks}>
<BookmarkCard
type="systemProfile"
statusIcon={mapCedarStatusToIcon(mockSystemInfo[0].status)}
refetch={() => {}}
{...mockSystemInfo[0]}
/>
</MockedProvider>
</MemoryRouter>
);
expect(asFragment()).toMatchSnapshot();
Expand All @@ -24,11 +43,14 @@ describe('BookmarkCard', () => {
it('renders translated headings', () => {
const { getByText } = render(
<MemoryRouter>
<BookmarkCard
type="systemProfile"
statusIcon={mapCedarStatusToIcon(mockSystemInfo[0].status)}
{...mockSystemInfo[0]}
/>
<MockedProvider mocks={mocks}>
<BookmarkCard
type="systemProfile"
statusIcon={mapCedarStatusToIcon(mockSystemInfo[0].status)}
refetch={() => {}}
{...mockSystemInfo[0]}
/>
</MockedProvider>
</MemoryRouter>
);

Expand All @@ -41,11 +63,14 @@ describe('BookmarkCard', () => {
it('renders corresponding success health icon for status', () => {
const { getByTestId } = render(
<MemoryRouter>
<BookmarkCard
type="systemProfile"
statusIcon={mapCedarStatusToIcon(mockSystemInfo[0].status)}
{...mockSystemInfo[0]}
/>
<MockedProvider mocks={mocks}>
<BookmarkCard
type="systemProfile"
statusIcon={mapCedarStatusToIcon(mockSystemInfo[0].status)}
refetch={() => {}}
{...mockSystemInfo[0]}
/>
</MockedProvider>
</MemoryRouter>
);

Expand All @@ -57,11 +82,14 @@ describe('BookmarkCard', () => {
it('renders corresponding warning health icon for status', () => {
const { getByTestId } = render(
<MemoryRouter>
<BookmarkCard
type="systemProfile"
statusIcon={mapCedarStatusToIcon(mockSystemInfo[1].status)}
{...mockSystemInfo[1]}
/>
<MockedProvider mocks={mocks}>
<BookmarkCard
type="systemProfile"
statusIcon={mapCedarStatusToIcon(mockSystemInfo[1].status)}
refetch={() => {}}
{...mockSystemInfo[1]}
/>
</MockedProvider>
</MemoryRouter>
);

Expand All @@ -73,11 +101,14 @@ describe('BookmarkCard', () => {
it('renders corresponding fail health icon for status', () => {
const { getByTestId } = render(
<MemoryRouter>
<BookmarkCard
type="systemProfile"
statusIcon={mapCedarStatusToIcon(mockSystemInfo[2].status)}
{...mockSystemInfo[2]}
/>
<MockedProvider mocks={mocks}>
<BookmarkCard
type="systemProfile"
statusIcon={mapCedarStatusToIcon(mockSystemInfo[2].status)}
refetch={() => {}}
{...mockSystemInfo[2]}
/>
</MockedProvider>
</MemoryRouter>
);

Expand Down
24 changes: 22 additions & 2 deletions src/components/BookmarkCard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useMutation } from '@apollo/client';
import { Card } from '@trussworks/react-uswds';
import classnames from 'classnames';

import UswdsReactLink from 'components/LinkWrapper';
import Divider from 'components/shared/Divider';
import SystemHealthIcon from 'components/SystemHealthIcon';
import DeleteCedarSystemBookmarkQuery from 'queries/DeleteCedarSystemBookmarkQuery';
import { GetCedarSystems_cedarSystems as CedarSystemProps } from 'queries/types/GetCedarSystems';
import { IconStatus } from 'types/iconStatus';

Expand All @@ -17,6 +19,7 @@ type BookmarkCardProps = {
className?: string;
statusIcon: IconStatus;
type: 'systemProfile'; // Built in for future iterations/varations of bookmarked datasets that ingest i18n translations for headers.
refetch: () => any | undefined;
};

const BookmarkCard = ({
Expand All @@ -28,9 +31,23 @@ const BookmarkCard = ({
acronym,
status,
statusIcon,
businessOwnerOrg
businessOwnerOrg,
refetch
}: BookmarkCardProps & CedarSystemProps) => {
const { t } = useTranslation();

const [deleteMutate] = useMutation(DeleteCedarSystemBookmarkQuery);

const handleDeleteBookmark = (cedarSystemId: string) => {
deleteMutate({
variables: {
input: {
cedarSystemId
}
}
}).then(refetch);
};

return (
<Card
data-testid="single-bookmark-card"
Expand All @@ -47,7 +64,10 @@ const BookmarkCard = ({
<h2 className="bookmark__title margin-top-0 margin-bottom-1">
<UswdsReactLink to={`/systems/${id}`}>{name}</UswdsReactLink>
</h2>
<BookmarkCardIcon size="md" />
<BookmarkCardIcon
size="md"
onClick={() => handleDeleteBookmark(id)}
/>
</div>
<p className="margin-0">{acronym}</p>
<p className="bookmark__body-text line-height-body-4">{description}</p>
Expand Down
11 changes: 11 additions & 0 deletions src/queries/CreateCedarSystemBookmarkQuery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { gql } from '@apollo/client';

export default gql`
mutation CreateCedarSystemBookmark($input: CreateCedarSystemBookmarkInput!) {
createCedarSystemBookmark(input: $input) {
cedarSystemBookmark {
cedarSystemId
}
}
}
`;
9 changes: 9 additions & 0 deletions src/queries/DeleteCedarSystemBookmarkQuery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { gql } from '@apollo/client';

export default gql`
mutation DeleteCedarSystemBookmark($input: CreateCedarSystemBookmarkInput!) {
deleteCedarSystemBookmark(input: $input) {
cedarSystemId
}
}
`;
10 changes: 10 additions & 0 deletions src/queries/GetCedarSystemBookmarksQuery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { gql } from '@apollo/client';

export default gql`
query GetCedarSystemBookmarks {
cedarSystemBookmarks {
euaUserId
cedarSystemId
}
}
`;
21 changes: 21 additions & 0 deletions src/queries/GetCedarSystemsAndBookmarksQuery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { gql } from '@apollo/client';

export default gql`
query GetCedarSystemsAndBookmarks {
cedarSystemBookmarks {
euaUserId
cedarSystemId
}
cedarSystems {
id
name
description
acronym
status
businessOwnerOrg
businessOwnerOrgComp
systemMaintainerOrg
systemMaintainerOrgComp
}
}
`;
28 changes: 28 additions & 0 deletions src/queries/types/CreateCedarSystemBookmark.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* tslint:disable */
/* eslint-disable */
// @generated
// This file was automatically generated and should not be edited.

import { CreateCedarSystemBookmarkInput } from "./../../types/graphql-global-types";

// ====================================================
// GraphQL mutation operation: CreateCedarSystemBookmark
// ====================================================

export interface CreateCedarSystemBookmark_createCedarSystemBookmark_cedarSystemBookmark {
__typename: "CedarSystemBookmark";
cedarSystemId: string;
}

export interface CreateCedarSystemBookmark_createCedarSystemBookmark {
__typename: "CreateCedarSystemBookmarkPayload";
cedarSystemBookmark: CreateCedarSystemBookmark_createCedarSystemBookmark_cedarSystemBookmark | null;
}

export interface CreateCedarSystemBookmark {
createCedarSystemBookmark: CreateCedarSystemBookmark_createCedarSystemBookmark | null;
}

export interface CreateCedarSystemBookmarkVariables {
input: CreateCedarSystemBookmarkInput;
}
23 changes: 23 additions & 0 deletions src/queries/types/DeleteCedarSystemBookmark.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/* tslint:disable */
/* eslint-disable */
// @generated
// This file was automatically generated and should not be edited.

import { CreateCedarSystemBookmarkInput } from "./../../types/graphql-global-types";

// ====================================================
// GraphQL mutation operation: DeleteCedarSystemBookmark
// ====================================================

export interface DeleteCedarSystemBookmark_deleteCedarSystemBookmark {
__typename: "DeleteCedarSystemBookmarkPayload";
cedarSystemId: string;
}

export interface DeleteCedarSystemBookmark {
deleteCedarSystemBookmark: DeleteCedarSystemBookmark_deleteCedarSystemBookmark | null;
}

export interface DeleteCedarSystemBookmarkVariables {
input: CreateCedarSystemBookmarkInput;
}
18 changes: 18 additions & 0 deletions src/queries/types/GetCedarSystemBookmarks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* tslint:disable */
/* eslint-disable */
// @generated
// This file was automatically generated and should not be edited.

// ====================================================
// GraphQL query operation: GetCedarSystemBookmarks
// ====================================================

export interface GetCedarSystemBookmarks_cedarSystemBookmarks {
__typename: "CedarSystemBookmark";
euaUserId: string;
cedarSystemId: string;
}

export interface GetCedarSystemBookmarks {
cedarSystemBookmarks: GetCedarSystemBookmarks_cedarSystemBookmarks[];
}
32 changes: 32 additions & 0 deletions src/queries/types/GetCedarSystemsAndBookmarks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* tslint:disable */
/* eslint-disable */
// @generated
// This file was automatically generated and should not be edited.

// ====================================================
// GraphQL query operation: GetCedarSystemsAndBookmarks
// ====================================================

export interface GetCedarSystemsAndBookmarks_cedarSystemBookmarks {
__typename: "CedarSystemBookmark";
euaUserId: string;
cedarSystemId: string;
}

export interface GetCedarSystemsAndBookmarks_cedarSystems {
__typename: "CedarSystem";
id: string;
name: string;
description: string | null;
acronym: string | null;
status: string | null;
businessOwnerOrg: string | null;
businessOwnerOrgComp: string | null;
systemMaintainerOrg: string | null;
systemMaintainerOrgComp: string | null;
}

export interface GetCedarSystemsAndBookmarks {
cedarSystemBookmarks: GetCedarSystemsAndBookmarks_cedarSystemBookmarks[];
cedarSystems: (GetCedarSystemsAndBookmarks_cedarSystems | null)[] | null;
}
7 changes: 7 additions & 0 deletions src/types/graphql-global-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,13 @@ export interface CreateAccessibilityRequestNoteInput {
shouldSendEmail: boolean;
}

/**
* The data needed to bookmark a cedar system
*/
export interface CreateCedarSystemBookmarkInput {
cedarSystemId: string;
}

/**
* Input data for extending a system request's lifecycle ID
*/
Expand Down
2 changes: 1 addition & 1 deletion src/views/FlagsWrapper/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const UserTargetingWrapper = ({ children }: WrapperProps) => {
downgrade508User: false,
downgrade508Tester: false,
help: false,
systemProfile: false
systemProfile: true
}
});

Expand Down

0 comments on commit c8837bd

Please sign in to comment.