From 737ba0c3310a64c68b788e52f9bc548e6640f555 Mon Sep 17 00:00:00 2001 From: Han Yu Date: Wed, 12 Jun 2019 12:28:30 -0400 Subject: [PATCH] web: show button to trigger update [ch2697] (#1738) --- web/package.json | 1 + web/src/Sidebar.tsx | 10 +- web/src/SidebarTriggerButton.scss | 23 +++++ web/src/SidebarTriggerButton.test.tsx | 33 +++++++ web/src/SidebarTriggerButton.tsx | 45 +++++++++ web/src/__snapshots__/Sidebar.test.tsx.snap | 104 ++++++++++++++++++++ web/src/assets/svg/trigger.svg | 2 +- web/src/setupTests.ts | 5 + web/yarn.lock | 31 ++++++ 9 files changed, 252 insertions(+), 2 deletions(-) create mode 100644 web/src/SidebarTriggerButton.scss create mode 100644 web/src/SidebarTriggerButton.test.tsx create mode 100644 web/src/SidebarTriggerButton.tsx diff --git a/web/package.json b/web/package.json index ad6e042579..9de0535980 100644 --- a/web/package.json +++ b/web/package.json @@ -50,6 +50,7 @@ "enzyme": "^3.9.0", "enzyme-adapter-react-16": "^1.11.2", "enzyme-to-json": "^3.3.5", + "jest-fetch-mock": "^2.1.2", "prettier": "1.16.4" }, "engines": { diff --git a/web/src/Sidebar.tsx b/web/src/Sidebar.tsx index 71c8d19ca5..7002a5637c 100644 --- a/web/src/Sidebar.tsx +++ b/web/src/Sidebar.tsx @@ -10,6 +10,8 @@ import PathBuilder from "./PathBuilder" import { timeAgoFormatter } from "./timeFormatters" import { AlertResource } from "./AlertPane" import SidebarIcon from "./SidebarIcon" +import SidebarTriggerButton from "./SidebarTriggerButton" +import { ReactComponent as triggerButton } from "./assets/svg/trigger.svg" class SidebarItem { name: string @@ -96,13 +98,14 @@ class Sidebar extends PureComponent { let hasBuilt = !isZeroTime(item.lastDeployTime) let building = !isZeroTime(item.currentBuildStartTime) let timeAgo = + let isSelected = this.props.selected === item.name let classes = "resLink" if (building) { classes += " resLink--building" } - if (this.props.selected === item.name) { + if (isSelected) { classes += " is-selected" } return ( @@ -115,6 +118,11 @@ class Sidebar extends PureComponent { hasWarning={item.hasWarnings} isBuilding={building} /> + {item.name} {item.numberOfAlerts() > 0 ? ( diff --git a/web/src/SidebarTriggerButton.scss b/web/src/SidebarTriggerButton.scss new file mode 100644 index 0000000000..a9bc7ae175 --- /dev/null +++ b/web/src/SidebarTriggerButton.scss @@ -0,0 +1,23 @@ +@import "constants"; + +.SidebarTriggerButton { + position: absolute; + background-color: transparent; + border: 0 none; + height: $sidebar-item; + width: $sidebar-item; + display: flex; + align-items: center; + justify-content: center; + fill: $color-white; + opacity: $translucent-ish; + cursor: pointer; +} + +.SidebarTriggerButton.isSelected { + fill: $color-gray-dark; +} + +.SidebarTriggerButton:hover { + opacity: 1; +} diff --git a/web/src/SidebarTriggerButton.test.tsx b/web/src/SidebarTriggerButton.test.tsx new file mode 100644 index 0000000000..24a923bba2 --- /dev/null +++ b/web/src/SidebarTriggerButton.test.tsx @@ -0,0 +1,33 @@ +import React from "react" +import { mount } from "enzyme" +import SidebarTriggerButton from "./SidebarTriggerButton" +import { TriggerMode } from "./types" + +describe("SidebarTriggerButtoon", () => { + beforeEach(() => { + fetchMock.resetMocks() + }) + + it("POSTs to endpoint when clicked", () => { + fetchMock.mockResponse(JSON.stringify({})) + + const root = mount( + + ) + + let element = root.find(".SidebarTriggerButton") + expect(element).toHaveLength(1) + element.simulate("click") + + expect(fetchMock.mock.calls.length).toEqual(1) + expect(fetchMock.mock.calls[0][0]).toEqual("//localhost/api/trigger") + expect(fetchMock.mock.calls[0][1].method).toEqual("post") + expect(fetchMock.mock.calls[0][1].body).toEqual( + JSON.stringify({ manifest_names: ["doggos"] }) + ) + }) +}) diff --git a/web/src/SidebarTriggerButton.tsx b/web/src/SidebarTriggerButton.tsx new file mode 100644 index 0000000000..6e044697c8 --- /dev/null +++ b/web/src/SidebarTriggerButton.tsx @@ -0,0 +1,45 @@ +import React, { PureComponent } from "react" +import { TriggerMode } from "./types" +import { ReactComponent as TriggerSvg } from "./assets/svg/trigger.svg" +import "./SidebarTriggerButton.scss" + +type SidebarTriggerButtonProps = { + resourceName: string + triggerMode: TriggerMode + isSelected: boolean +} + +const triggerUpdate = (name: string): void => { + let url = `//${window.location.host}/api/trigger` + + fetch(url, { + method: "post", + body: JSON.stringify({ manifest_names: [name] }), + }).then(response => { + if (!response.ok) { + console.log(response) + } + }) +} + +export default class SidebarTriggerButton extends PureComponent< + SidebarTriggerButtonProps +> { + render() { + let props = this.props + if (props.triggerMode === TriggerMode.TriggerModeAuto) { + return null + } + + return ( + + ) + } +} diff --git a/web/src/__snapshots__/Sidebar.test.tsx.snap b/web/src/__snapshots__/Sidebar.test.tsx.snap index 2d1912f04d..6d4d398903 100644 --- a/web/src/__snapshots__/Sidebar.test.tsx.snap +++ b/web/src/__snapshots__/Sidebar.test.tsx.snap @@ -48,6 +48,14 @@ exports[`sidebar abbreviates durations under a minute 1`] = ` > indicator-auto-building.svg + indicator-auto-building.svg + indicator-auto-building.svg + indicator-auto-building.svg + indicator-auto-building.svg + indicator-auto-building.svg + indicator-auto-building.svg + indicator-auto-building.svg + indicator-auto-building.svg + indicator-auto-building.svg + indicator-auto-building.svg + indicator-manual-building.svg + indicator-manual-building.svg + \ No newline at end of file + \ No newline at end of file diff --git a/web/src/setupTests.ts b/web/src/setupTests.ts index 4cda5b382e..4251d0ab30 100644 --- a/web/src/setupTests.ts +++ b/web/src/setupTests.ts @@ -1,4 +1,9 @@ import { configure } from "enzyme" import Adapter from "enzyme-adapter-react-16" +import { GlobalWithFetchMock } from "jest-fetch-mock" configure({ adapter: new Adapter() }) + +const customGlobal: GlobalWithFetchMock = global as GlobalWithFetchMock +customGlobal.fetch = require("jest-fetch-mock") +customGlobal.fetchMock = customGlobal.fetch diff --git a/web/yarn.lock b/web/yarn.lock index 091ad50797..7f8cb7778d 100644 --- a/web/yarn.lock +++ b/web/yarn.lock @@ -3078,6 +3078,14 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: safe-buffer "^5.0.1" sha.js "^2.4.8" +cross-fetch@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.3.tgz#e8a0b3c54598136e037f8650f8e823ccdfac198e" + integrity sha512-PrWWNH3yL2NYIb/7WF/5vFG3DCQiXDOVf8k3ijatbrtnwNuhMWLC7YF7uqf53tbTFDzHIUD8oITw4Bxt8ST3Nw== + dependencies: + node-fetch "2.1.2" + whatwg-fetch "2.0.4" + cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -5815,6 +5823,14 @@ jest-environment-node@^24.7.1: jest-mock "^24.7.0" jest-util "^24.7.1" +jest-fetch-mock@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/jest-fetch-mock/-/jest-fetch-mock-2.1.2.tgz#1260b347918e3931c4ec743ceaf60433da661bd0" + integrity sha512-tcSR4Lh2bWLe1+0w/IwvNxeDocMI/6yIA2bijZ0fyWxC4kQ18lckQ1n7Yd40NKuisGmcGBRFPandRXrW/ti/Bw== + dependencies: + cross-fetch "^2.2.2" + promise-polyfill "^7.1.1" + jest-get-type@^24.3.0: version "24.3.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.3.0.tgz#582cfd1a4f91b5cdad1d43d2932f816d543c65da" @@ -6929,6 +6945,11 @@ no-case@^2.2.0: dependencies: lower-case "^1.1.1" +node-fetch@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" + integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= + node-forge@0.7.5: version "0.7.5" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df" @@ -8411,6 +8432,11 @@ promise-inflight@^1.0.1: resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= +promise-polyfill@^7.1.1: + version "7.1.2" + resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-7.1.2.tgz#ab05301d8c28536301622d69227632269a70ca3b" + integrity sha512-FuEc12/eKqqoRYIGBrUptCBRhobL19PS2U31vMNTfyck1FxPyMfgsXyW4Mav85y/ZN1hop3hOwRlUDok23oYfQ== + promise@8.0.2: version "8.0.2" resolved "https://registry.yarnpkg.com/promise/-/promise-8.0.2.tgz#9dcd0672192c589477d56891271bdc27547ae9f0" @@ -10764,6 +10790,11 @@ whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3, whatwg-encoding@^1.0.5: dependencies: iconv-lite "0.4.24" +whatwg-fetch@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" + integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== + whatwg-fetch@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb"