From bb0adea4947d7bd1f62f366857d68be467b233d1 Mon Sep 17 00:00:00 2001 From: Kanagaraj M Date: Thu, 22 Feb 2018 07:30:00 +0530 Subject: [PATCH] Refactor browser dropdown links and components (#5562) * refactor browser links and about modal Moved about modal to separate component and added unit tests. * refactor change password modal component * added unit tests for ChangePasswordModal * fix logout function in browser dropdown * remove older unused BrowserDropdown component * remove unused variables from BrowserDropdown component * show BrowserDropdown and StorageInfo only for LoggedIn users Non-loggedIn users will see a 'Login' button --- browser/app/js/browser/AboutModal.js | 64 ++++++ browser/app/js/browser/BrowserDropdown.js | 156 ++++++++++++++ browser/app/js/browser/ChangePasswordModal.js | 201 +++++++++++++++++ browser/app/js/browser/Header.js | 27 ++- browser/app/js/browser/InputGroup.js | 70 ++++++ browser/app/js/browser/Login.js | 2 +- .../js/browser/__tests__/AboutModal.test.js | 41 ++++ .../browser/__tests__/BrowserDropdown.test.js | 63 ++++++ .../__tests__/ChangePasswordModal.test.js | 109 ++++++++++ .../app/js/browser/__tests__/Header.test.js | 17 ++ .../app/js/browser/__tests__/actions.test.js | 29 +++ .../app/js/browser/__tests__/reducer.test.js | 24 ++- browser/app/js/browser/actions.js | 21 ++ browser/app/js/browser/reducer.js | 8 +- browser/app/js/components/BrowserDropdown.js | 56 ----- browser/app/js/components/InputGroup.js | 49 ----- browser/app/js/components/SettingsModal.js | 204 ------------------ 17 files changed, 823 insertions(+), 318 deletions(-) create mode 100644 browser/app/js/browser/AboutModal.js create mode 100644 browser/app/js/browser/BrowserDropdown.js create mode 100644 browser/app/js/browser/ChangePasswordModal.js create mode 100644 browser/app/js/browser/InputGroup.js create mode 100644 browser/app/js/browser/__tests__/AboutModal.test.js create mode 100644 browser/app/js/browser/__tests__/BrowserDropdown.test.js create mode 100644 browser/app/js/browser/__tests__/ChangePasswordModal.test.js delete mode 100644 browser/app/js/components/BrowserDropdown.js delete mode 100644 browser/app/js/components/InputGroup.js delete mode 100644 browser/app/js/components/SettingsModal.js diff --git a/browser/app/js/browser/AboutModal.js b/browser/app/js/browser/AboutModal.js new file mode 100644 index 000000000..054526097 --- /dev/null +++ b/browser/app/js/browser/AboutModal.js @@ -0,0 +1,64 @@ +/* + * Minio Cloud Storage (C) 2018 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from "react" +import { Modal } from "react-bootstrap" +import logo from "../../img/logo.svg" + +export const AboutModal = ({ serverInfo, hideAbout }) => { + const { version, memory, platform, runtime } = serverInfo + return ( + + +
+
+ + + +
+
+
    +
  • +
    Version
    + {version} +
  • +
  • +
    Memory
    + {memory} +
  • +
  • +
    Platform
    + {platform} +
  • +
  • +
    Runtime
    + {runtime} +
  • +
+
+
+
+ ) +} + +export default AboutModal diff --git a/browser/app/js/browser/BrowserDropdown.js b/browser/app/js/browser/BrowserDropdown.js new file mode 100644 index 000000000..0b762949d --- /dev/null +++ b/browser/app/js/browser/BrowserDropdown.js @@ -0,0 +1,156 @@ +/* + * Minio Cloud Storage (C) 2016, 2017, 2018 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from "react" +import { connect } from "react-redux" +import { Dropdown } from "react-bootstrap" +import * as browserActions from "./actions" +import web from "../web" +import history from "../history" +import AboutModal from "./AboutModal" +import ChangePasswordModal from "./ChangePasswordModal" + +export class BrowserDropdown extends React.Component { + constructor(props) { + super(props) + this.state = { + showAboutModal: false, + showChangePasswordModal: false + } + } + showAbout(e) { + e.preventDefault() + this.setState({ + showAboutModal: true + }) + } + hideAbout() { + this.setState({ + showAboutModal: false + }) + } + showChangePassword(e) { + e.preventDefault() + this.setState({ + showChangePasswordModal: true + }) + } + hideChangePassword() { + this.setState({ + showChangePasswordModal: false + }) + } + componentDidMount() { + const { fetchServerInfo } = this.props + fetchServerInfo() + } + fullScreen(e) { + e.preventDefault() + let el = document.documentElement + if (el.requestFullscreen) { + el.requestFullscreen() + } + if (el.mozRequestFullScreen) { + el.mozRequestFullScreen() + } + if (el.webkitRequestFullscreen) { + el.webkitRequestFullscreen() + } + if (el.msRequestFullscreen) { + el.msRequestFullscreen() + } + } + logout(e) { + e.preventDefault() + web.Logout() + history.replace("/login") + } + render() { + const { serverInfo } = this.props + return ( +
  • + + + + + +
  • + + Github + +
  • +
  • + + Fullscreen + +
  • +
  • + + Documentation + +
  • +
  • + + Ask for help + +
  • +
  • + + About + + {this.state.showAboutModal && ( + + )} +
  • +
  • + + Change Password + + {this.state.showChangePasswordModal && ( + + )} +
  • +
  • + + Sign Out + +
  • + + + + ) + } +} + +const mapStateToProps = state => { + return { + serverInfo: state.browser.serverInfo + } +} + +const mapDispatchToProps = dispatch => { + return { + fetchServerInfo: () => dispatch(browserActions.fetchServerInfo()) + } +} + +export default connect(mapStateToProps, mapDispatchToProps)(BrowserDropdown) diff --git a/browser/app/js/browser/ChangePasswordModal.js b/browser/app/js/browser/ChangePasswordModal.js new file mode 100644 index 000000000..9266451b7 --- /dev/null +++ b/browser/app/js/browser/ChangePasswordModal.js @@ -0,0 +1,201 @@ +/* + * Minio Cloud Storage (C) 2016, 2018 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from "react" +import { connect } from "react-redux" +import web from "../web" +import * as alertActions from "../alert/actions" + +import { + Tooltip, + Modal, + ModalBody, + ModalHeader, + OverlayTrigger +} from "react-bootstrap" +import InputGroup from "./InputGroup" + +export class ChangePasswordModal extends React.Component { + constructor(props) { + super(props) + this.state = { + accessKey: "", + secretKey: "", + keysReadOnly: false + } + } + // When its shown, it loads the access key and secret key. + componentWillMount() { + const { serverInfo } = this.props + + // Check environment variables first. + if (serverInfo.info.isEnvCreds) { + this.setState({ + accessKey: "xxxxxxxxx", + secretKey: "xxxxxxxxx", + keysReadOnly: true + }) + } else { + web.GetAuth().then(data => { + this.setState({ + accessKey: data.accessKey, + secretKey: data.secretKey + }) + }) + } + } + + // Handle field changes from inside the modal. + accessKeyChange(e) { + this.setState({ + accessKey: e.target.value + }) + } + + secretKeyChange(e) { + this.setState({ + secretKey: e.target.value + }) + } + + secretKeyVisible(secretKeyVisible) { + this.setState({ + secretKeyVisible + }) + } + + // Save the auth params and set them. + setAuth(e) { + const { showAlert } = this.props + const accessKey = this.state.accessKey + const secretKey = this.state.secretKey + web + .SetAuth({ + accessKey, + secretKey + }) + .then(data => { + showAlert({ + type: "success", + message: "Changed credentials" + }) + }) + .catch(err => { + showAlert({ + type: "danger", + message: err.message + }) + }) + } + + generateAuth(e) { + web.GenerateAuth().then(data => { + this.setState({ + accessKey: data.accessKey, + secretKey: data.secretKey, + secretKeyVisible: true + }) + }) + } + + render() { + const { hideChangePassword } = this.props + return ( + + Change Password + + + + + +
    + + + +
    +
    + ) + } +} + +const mapStateToProps = state => { + return { + serverInfo: state.browser.serverInfo + } +} + +const mapDispatchToProps = dispatch => { + return { + showAlert: alert => dispatch(alertActions.set(alert)) + } +} + +export default connect(mapStateToProps, mapDispatchToProps)(ChangePasswordModal) diff --git a/browser/app/js/browser/Header.js b/browser/app/js/browser/Header.js index 138f9ad33..716873df8 100644 --- a/browser/app/js/browser/Header.js +++ b/browser/app/js/browser/Header.js @@ -17,12 +17,27 @@ import React from "react" import Path from "../objects/Path" import StorageInfo from "./StorageInfo" +import BrowserDropdown from "./BrowserDropdown" +import web from "../web" +import { minioBrowserPrefix } from "../constants" -export const Header = () => ( -
    - - -
    -) +export const Header = () => { + const loggedIn = web.LoggedIn() + return ( +
    + + {loggedIn && } + +
    + ) +} export default Header diff --git a/browser/app/js/browser/InputGroup.js b/browser/app/js/browser/InputGroup.js new file mode 100644 index 000000000..dd49482d9 --- /dev/null +++ b/browser/app/js/browser/InputGroup.js @@ -0,0 +1,70 @@ +/* + * Minio Cloud Storage (C) 2016, 2018 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from "react" + +let InputGroup = ({ + label, + id, + name, + value, + onChange, + type, + spellCheck, + required, + readonly, + autoComplete, + align, + className +}) => { + var input = ( + + ) + if (readonly) + input = ( + + ) + return ( +
    + {input} + + +
    + ) +} + +export default InputGroup diff --git a/browser/app/js/browser/Login.js b/browser/app/js/browser/Login.js index 063e9cabb..f2c003fea 100644 --- a/browser/app/js/browser/Login.js +++ b/browser/app/js/browser/Login.js @@ -20,7 +20,7 @@ import classNames from "classnames" import logo from "../../img/logo.svg" import Alert from "../alert/Alert" import * as actionsAlert from "../alert/actions" -import InputGroup from "../components/InputGroup" +import InputGroup from "./InputGroup" import { minioBrowserPrefix } from "../constants" import web from "../web" import { Redirect } from "react-router-dom" diff --git a/browser/app/js/browser/__tests__/AboutModal.test.js b/browser/app/js/browser/__tests__/AboutModal.test.js new file mode 100644 index 000000000..dd5690987 --- /dev/null +++ b/browser/app/js/browser/__tests__/AboutModal.test.js @@ -0,0 +1,41 @@ +/* + * Minio Cloud Storage (C) 2018 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from "react" +import { shallow } from "enzyme" +import { AboutModal } from "../AboutModal" + +describe("AboutModal", () => { + const serverInfo = { + version: "test", + memory: "test", + platform: "test", + runtime: "test" + } + + it("should render without crashing", () => { + shallow() + }) + + it("should call hideAbout when close button is clicked", () => { + const hideAbout = jest.fn() + const wrapper = shallow( + + ) + wrapper.find("button").simulate("click") + expect(hideAbout).toHaveBeenCalled() + }) +}) diff --git a/browser/app/js/browser/__tests__/BrowserDropdown.test.js b/browser/app/js/browser/__tests__/BrowserDropdown.test.js new file mode 100644 index 000000000..c388bab5f --- /dev/null +++ b/browser/app/js/browser/__tests__/BrowserDropdown.test.js @@ -0,0 +1,63 @@ +/* + * Minio Cloud Storage (C) 2018 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from "react" +import { shallow } from "enzyme" +import { BrowserDropdown } from "../BrowserDropdown" + +describe("BrowserDropdown", () => { + const serverInfo = { + version: "test", + memory: "test", + platform: "test", + runtime: "test" + } + + it("should render without crashing", () => { + shallow( + + ) + }) + + it("should call fetchServerInfo after its mounted", () => { + const fetchServerInfo = jest.fn() + const wrapper = shallow( + + ) + expect(fetchServerInfo).toHaveBeenCalled() + }) + + it("should show AboutModal when About link is clicked", () => { + const wrapper = shallow( + + ) + wrapper.find("#show-about").simulate("click", { preventDefault: jest.fn() }) + wrapper.update() + expect(wrapper.state("showAboutModal")).toBeTruthy() + expect(wrapper.find("AboutModal").length).toBe(1) + }) + + it("should logout and redirect to /login when logout is clicked", () => { + const wrapper = shallow( + + ) + wrapper.find("#logout").simulate("click", { preventDefault: jest.fn() }) + expect(window.location.pathname.endsWith("/login")).toBeTruthy() + }) +}) diff --git a/browser/app/js/browser/__tests__/ChangePasswordModal.test.js b/browser/app/js/browser/__tests__/ChangePasswordModal.test.js new file mode 100644 index 000000000..411cc938b --- /dev/null +++ b/browser/app/js/browser/__tests__/ChangePasswordModal.test.js @@ -0,0 +1,109 @@ +/* + * Minio Cloud Storage (C) 2018 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from "react" +import { shallow, mount } from "enzyme" +import { ChangePasswordModal } from "../ChangePasswordModal" + +jest.mock("../../web", () => ({ + GetAuth: jest.fn(() => { + return Promise.resolve({ accessKey: "test1", secretKey: "test2" }) + }), + GenerateAuth: jest.fn(() => { + return Promise.resolve({ accessKey: "gen1", secretKey: "gen2" }) + }), + SetAuth: jest.fn(({ accessKey, secretKey }) => { + if (accessKey == "test3" && secretKey == "test4") { + return Promise.resolve({}) + } else { + return Promise.reject({ message: "Error" }) + } + }) +})) + +describe("ChangePasswordModal", () => { + const serverInfo = { + version: "test", + memory: "test", + platform: "test", + runtime: "test", + info: { isEnvCreds: false } + } + + it("should render without crashing", () => { + shallow() + }) + + it("should get the keys when its rendered", () => { + const wrapper = shallow() + setImmediate(() => { + expect(wrapper.state("accessKey")).toBe("test1") + expect(wrapper.state("secretKey")).toBe("test2") + }) + }) + + it("should show readonly keys when isEnvCreds is true", () => { + const newServerInfo = { ...serverInfo, info: { isEnvCreds: true } } + const wrapper = shallow() + expect(wrapper.state("accessKey")).toBe("xxxxxxxxx") + expect(wrapper.state("secretKey")).toBe("xxxxxxxxx") + expect(wrapper.find("#accessKey").prop("readonly")).toBeTruthy() + expect(wrapper.find("#secretKey").prop("readonly")).toBeTruthy() + expect(wrapper.find("#generate-keys").hasClass("hidden")).toBeTruthy() + expect(wrapper.find("#update-keys").hasClass("hidden")).toBeTruthy() + }) + + it("should generate accessKey and secretKey when Generate buttons is clicked", () => { + const wrapper = shallow() + wrapper.find("#generate-keys").simulate("click") + setImmediate(() => { + expect(wrapper.state("accessKey")).toBe("gen1") + expect(wrapper.state("secretKey")).toBe("gen2") + }) + }) + + it("should update accessKey and secretKey when Update button is clicked", () => { + const showAlert = jest.fn() + const wrapper = shallow( + + ) + wrapper + .find("#accessKey") + .simulate("change", { target: { value: "test3" } }) + wrapper + .find("#secretKey") + .simulate("change", { target: { value: "test4" } }) + wrapper.find("#update-keys").simulate("click") + setImmediate(() => { + expect(showAlert).toHaveBeenCalledWith({ + type: "success", + message: "Changed credentials" + }) + }) + }) + + it("should call hideChangePassword when Cancel button is clicked", () => { + const hideChangePassword = jest.fn() + const wrapper = shallow( + + ) + wrapper.find("#cancel-change-password").simulate("click") + expect(hideChangePassword).toHaveBeenCalled() + }) +}) diff --git a/browser/app/js/browser/__tests__/Header.test.js b/browser/app/js/browser/__tests__/Header.test.js index a48357361..7f9042e3a 100644 --- a/browser/app/js/browser/__tests__/Header.test.js +++ b/browser/app/js/browser/__tests__/Header.test.js @@ -18,8 +18,25 @@ import React from "react" import { shallow } from "enzyme" import Header from "../Header" +jest.mock("../../web", () => ({ + LoggedIn: jest + .fn(() => true) + .mockReturnValueOnce(true) + .mockReturnValueOnce(false) +})) describe("Header", () => { it("should render without crashing", () => { shallow(
    ) }) + + it("should render Login button when the user has not LoggedIn", () => { + const wrapper = shallow(
    ) + expect(wrapper.find("a").text()).toBe("Login") + }) + + it("should render StorageInfo and BrowserDropdown when the user has LoggedIn", () => { + const wrapper = shallow(
    ) + expect(wrapper.find("Connect(BrowserDropdown)").length).toBe(1) + expect(wrapper.find("Connect(StorageInfo)").length).toBe(1) + }) }) diff --git a/browser/app/js/browser/__tests__/actions.test.js b/browser/app/js/browser/__tests__/actions.test.js index d89ee5873..012d7031f 100644 --- a/browser/app/js/browser/__tests__/actions.test.js +++ b/browser/app/js/browser/__tests__/actions.test.js @@ -21,6 +21,15 @@ import * as actionsCommon from "../actions" jest.mock("../../web", () => ({ StorageInfo: jest.fn(() => { return Promise.resolve({ storageInfo: { Total: 100, Free: 60 } }) + }), + ServerInfo: jest.fn(() => { + return Promise.resolve({ + MinioVersion: "test", + MinioMemory: "test", + MinioPlatform: "test", + MinioRuntime: "test", + MinioGlobalInfo: "test" + }) }) })) @@ -38,4 +47,24 @@ describe("Common actions", () => { expect(actions).toEqual(expectedActions) }) }) + + it("creates common/SET_SERVER_INFO after fetching the server details", () => { + const store = mockStore() + const expectedActions = [ + { + type: "common/SET_SERVER_INFO", + serverInfo: { + version: "test", + memory: "test", + platform: "test", + runtime: "test", + info: "test" + } + } + ] + return store.dispatch(actionsCommon.fetchServerInfo()).then(() => { + const actions = store.getActions() + expect(actions).toEqual(expectedActions) + }) + }) }) diff --git a/browser/app/js/browser/__tests__/reducer.test.js b/browser/app/js/browser/__tests__/reducer.test.js index d7dee346f..968f60e8e 100644 --- a/browser/app/js/browser/__tests__/reducer.test.js +++ b/browser/app/js/browser/__tests__/reducer.test.js @@ -24,7 +24,8 @@ describe("common reducer", () => { storageInfo: { total: 0, free: 0 - } + }, + serverInfo: {} }) }) @@ -67,4 +68,25 @@ describe("common reducer", () => { storageInfo: { total: 100, free: 40 } }) }) + + it("should handle SET_SERVER_INFO", () => { + expect( + reducer(undefined, { + type: actionsCommon.SET_SERVER_INFO, + serverInfo: { + version: "test", + memory: "test", + platform: "test", + runtime: "test", + info: "test" + } + }).serverInfo + ).toEqual({ + version: "test", + memory: "test", + platform: "test", + runtime: "test", + info: "test" + }) + }) }) diff --git a/browser/app/js/browser/actions.js b/browser/app/js/browser/actions.js index 0164f7573..f82d03b4f 100644 --- a/browser/app/js/browser/actions.js +++ b/browser/app/js/browser/actions.js @@ -19,6 +19,7 @@ import web from "../web" export const TOGGLE_SIDEBAR = "common/TOGGLE_SIDEBAR" export const CLOSE_SIDEBAR = "common/CLOSE_SIDEBAR" export const SET_STORAGE_INFO = "common/SET_STORAGE_INFO" +export const SET_SERVER_INFO = "common/SET_SERVER_INFO" export const toggleSidebar = () => ({ type: TOGGLE_SIDEBAR @@ -44,3 +45,23 @@ export const setStorageInfo = storageInfo => ({ type: SET_STORAGE_INFO, storageInfo }) + +export const fetchServerInfo = () => { + return function(dispatch) { + return web.ServerInfo().then(res => { + const serverInfo = { + version: res.MinioVersion, + memory: res.MinioMemory, + platform: res.MinioPlatform, + runtime: res.MinioRuntime, + info: res.MinioGlobalInfo + } + dispatch(setServerInfo(serverInfo)) + }) + } +} + +export const setServerInfo = serverInfo => ({ + type: SET_SERVER_INFO, + serverInfo +}) diff --git a/browser/app/js/browser/reducer.js b/browser/app/js/browser/reducer.js index 3ee036534..1e1789aef 100644 --- a/browser/app/js/browser/reducer.js +++ b/browser/app/js/browser/reducer.js @@ -17,7 +17,11 @@ import * as actionsCommon from "./actions" export default ( - state = { sidebarOpen: false, storageInfo: { total: 0, free: 0 } }, + state = { + sidebarOpen: false, + storageInfo: { total: 0, free: 0 }, + serverInfo: {} + }, action ) => { switch (action.type) { @@ -33,6 +37,8 @@ export default ( return Object.assign({}, state, { storageInfo: action.storageInfo }) + case actionsCommon.SET_SERVER_INFO: + return { ...state, serverInfo: action.serverInfo } default: return state } diff --git a/browser/app/js/components/BrowserDropdown.js b/browser/app/js/components/BrowserDropdown.js deleted file mode 100644 index b242c3dd5..000000000 --- a/browser/app/js/components/BrowserDropdown.js +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Minio Cloud Storage (C) 2016, 2017 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react' -import connect from 'react-redux/lib/components/connect' -import Dropdown from 'react-bootstrap/lib/Dropdown' - -let BrowserDropdown = ({fullScreenFunc, aboutFunc, settingsFunc, logoutFunc}) => { - return ( -
  • - - - - - -
  • - Github -
  • -
  • - Fullscreen -
  • -
  • - Documentation -
  • -
  • - Ask for help -
  • -
  • - About -
  • -
  • - Change Password -
  • -
  • - Sign Out -
  • - - - - ) -} - -export default connect(state => state)(BrowserDropdown) diff --git a/browser/app/js/components/InputGroup.js b/browser/app/js/components/InputGroup.js deleted file mode 100644 index 9aee63f4c..000000000 --- a/browser/app/js/components/InputGroup.js +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Minio Cloud Storage (C) 2016 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react' - -let InputGroup = ({label, id, name, value, onChange, type, spellCheck, required, readonly, autoComplete, align, className}) => { - var input = - if (readonly) - input = - return
    - { input } - - -
    -} - -export default InputGroup diff --git a/browser/app/js/components/SettingsModal.js b/browser/app/js/components/SettingsModal.js deleted file mode 100644 index 189a2b9f8..000000000 --- a/browser/app/js/components/SettingsModal.js +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Minio Cloud Storage (C) 2016 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react' -import connect from 'react-redux/lib/components/connect' -import * as actions from '../actions' - -import Tooltip from 'react-bootstrap/lib/Tooltip' -import Modal from 'react-bootstrap/lib/Modal' -import ModalBody from 'react-bootstrap/lib/ModalBody' -import ModalHeader from 'react-bootstrap/lib/ModalHeader' -import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger' -import InputGroup from './InputGroup' - -class SettingsModal extends React.Component { - - // When the settings are shown, it loads the access key and secret key. - componentWillMount() { - const {web, dispatch} = this.props - const {serverInfo} = this.props - - let accessKeyEnv = '' - let secretKeyEnv = '' - // Check environment variables first. - if (serverInfo.info.isEnvCreds) { - dispatch(actions.setSettings({ - accessKey: 'xxxxxxxxx', - secretKey: 'xxxxxxxxx', - keysReadOnly: true - })) - } else { - web.GetAuth() - .then(data => { - dispatch(actions.setSettings({ - accessKey: data.accessKey, - secretKey: data.secretKey - })) - }) - } - } - - // When they are re-hidden, the keys are unloaded from memory. - componentWillUnmount() { - const {dispatch} = this.props - - dispatch(actions.setSettings({ - accessKey: '', - secretKey: '', - secretKeyVisible: false - })) - dispatch(actions.hideSettings()) - } - - // Handle field changes from inside the modal. - accessKeyChange(e) { - const {dispatch} = this.props - dispatch(actions.setSettings({ - accessKey: e.target.value - })) - } - - secretKeyChange(e) { - const {dispatch} = this.props - dispatch(actions.setSettings({ - secretKey: e.target.value - })) - } - - secretKeyVisible(secretKeyVisible) { - const {dispatch} = this.props - dispatch(actions.setSettings({ - secretKeyVisible - })) - } - - // Save the auth params and set them. - setAuth(e) { - e.preventDefault() - const {web, dispatch} = this.props - - let accessKey = document.getElementById('accessKey').value - let secretKey = document.getElementById('secretKey').value - web.SetAuth({ - accessKey, - secretKey - }) - .then(data => { - dispatch(actions.setSettings({ - accessKey: '', - secretKey: '', - secretKeyVisible: false - })) - dispatch(actions.hideSettings()) - dispatch(actions.showAlert({ - type: 'success', - message: 'Changed credentials' - })) - }) - .catch(err => { - dispatch(actions.setSettings({ - accessKey: '', - secretKey: '', - secretKeyVisible: false - })) - dispatch(actions.hideSettings()) - dispatch(actions.showAlert({ - type: 'danger', - message: err.message - })) - }) - } - - generateAuth(e) { - e.preventDefault() - const {dispatch} = this.props - - web.GenerateAuth() - .then(data => { - dispatch(actions.setSettings({ - secretKeyVisible: true - })) - dispatch(actions.setSettings({ - accessKey: data.accessKey, - secretKey: data.secretKey - })) - }) - } - - hideSettings(e) { - e.preventDefault() - - const {dispatch} = this.props - dispatch(actions.hideSettings()) - } - - render() { - let {settings} = this.props - - return ( - - - Change Password - - - - - - -
    - - - -
    -
    - ) - } -} - -export default connect(state => { - return { - web: state.web, - settings: state.settings, - serverInfo: state.serverInfo - } -})(SettingsModal)