Refactor of components (#5499)
parent
9ab6a8035f
commit
feb726dd98
@ -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 configureStore from "redux-mock-store" |
||||||
|
import thunk from "redux-thunk" |
||||||
|
import * as actionsCommon from "../common" |
||||||
|
|
||||||
|
jest.mock("../../web", () => ({ |
||||||
|
StorageInfo: jest.fn(() => { |
||||||
|
return Promise.resolve({ storageInfo: { Total: 100, Free: 60 } }) |
||||||
|
}) |
||||||
|
})) |
||||||
|
|
||||||
|
const middlewares = [thunk] |
||||||
|
const mockStore = configureStore(middlewares) |
||||||
|
|
||||||
|
describe("Common actions", () => { |
||||||
|
it("creates common/SET_STORAGE_INFO after fetching the storage details ", () => { |
||||||
|
const store = mockStore() |
||||||
|
const expectedActions = [ |
||||||
|
{ type: "common/SET_STORAGE_INFO", storageInfo: { total: 100, free: 60 } } |
||||||
|
] |
||||||
|
return store.dispatch(actionsCommon.fetchStorageInfo()).then(() => { |
||||||
|
const actions = store.getActions() |
||||||
|
expect(actions).toEqual(expectedActions) |
||||||
|
}) |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,171 @@ |
|||||||
|
/* |
||||||
|
* 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 configureStore from "redux-mock-store" |
||||||
|
import thunk from "redux-thunk" |
||||||
|
import * as actionsObjects from "../objects" |
||||||
|
|
||||||
|
jest.mock("../../web", () => ({ |
||||||
|
ListObjects: jest.fn(() => { |
||||||
|
return Promise.resolve({ |
||||||
|
objects: [{ name: "test1" }, { name: "test2" }], |
||||||
|
istruncated: false, |
||||||
|
nextmarker: "test2" |
||||||
|
}) |
||||||
|
}) |
||||||
|
})) |
||||||
|
|
||||||
|
const middlewares = [thunk] |
||||||
|
const mockStore = configureStore(middlewares) |
||||||
|
|
||||||
|
describe("Objects actions", () => { |
||||||
|
it("creates objects/SET_LIST action", () => { |
||||||
|
const store = mockStore() |
||||||
|
const expectedActions = [ |
||||||
|
{ |
||||||
|
type: "objects/SET_LIST", |
||||||
|
objects: [{ name: "test1" }, { name: "test2" }], |
||||||
|
isTruncated: false, |
||||||
|
marker: "test2" |
||||||
|
} |
||||||
|
] |
||||||
|
store.dispatch( |
||||||
|
actionsObjects.setList( |
||||||
|
[{ name: "test1" }, { name: "test2" }], |
||||||
|
"test2", |
||||||
|
false |
||||||
|
) |
||||||
|
) |
||||||
|
const actions = store.getActions() |
||||||
|
expect(actions).toEqual(expectedActions) |
||||||
|
}) |
||||||
|
|
||||||
|
it("creates objects/SET_SORT_BY action", () => { |
||||||
|
const store = mockStore() |
||||||
|
const expectedActions = [ |
||||||
|
{ |
||||||
|
type: "objects/SET_SORT_BY", |
||||||
|
sortBy: "name" |
||||||
|
} |
||||||
|
] |
||||||
|
store.dispatch(actionsObjects.setSortBy("name")) |
||||||
|
const actions = store.getActions() |
||||||
|
expect(actions).toEqual(expectedActions) |
||||||
|
}) |
||||||
|
|
||||||
|
it("creates objects/SET_SORT_ORDER action", () => { |
||||||
|
const store = mockStore() |
||||||
|
const expectedActions = [ |
||||||
|
{ |
||||||
|
type: "objects/SET_SORT_ORDER", |
||||||
|
sortOrder: true |
||||||
|
} |
||||||
|
] |
||||||
|
store.dispatch(actionsObjects.setSortOrder(true)) |
||||||
|
const actions = store.getActions() |
||||||
|
expect(actions).toEqual(expectedActions) |
||||||
|
}) |
||||||
|
|
||||||
|
it("creates objects/SET_LIST after fetching the objects", () => { |
||||||
|
const store = mockStore({ |
||||||
|
buckets: { currentBucket: "bk1" }, |
||||||
|
objects: { currentPrefix: "" } |
||||||
|
}) |
||||||
|
const expectedActions = [ |
||||||
|
{ |
||||||
|
type: "objects/SET_LIST", |
||||||
|
objects: [{ name: "test1" }, { name: "test2" }], |
||||||
|
marker: "test2", |
||||||
|
isTruncated: false |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "objects/SET_SORT_BY", |
||||||
|
sortBy: "" |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "objects/SET_SORT_ORDER", |
||||||
|
sortOrder: false |
||||||
|
} |
||||||
|
] |
||||||
|
return store.dispatch(actionsObjects.fetchObjects()).then(() => { |
||||||
|
const actions = store.getActions() |
||||||
|
expect(actions).toEqual(expectedActions) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it("creates objects/APPEND_LIST after fetching more objects", () => { |
||||||
|
const store = mockStore({ |
||||||
|
buckets: { currentBucket: "bk1" }, |
||||||
|
objects: { currentPrefix: "" } |
||||||
|
}) |
||||||
|
const expectedActions = [ |
||||||
|
{ |
||||||
|
type: "objects/APPEND_LIST", |
||||||
|
objects: [{ name: "test1" }, { name: "test2" }], |
||||||
|
marker: "test2", |
||||||
|
isTruncated: false |
||||||
|
} |
||||||
|
] |
||||||
|
return store.dispatch(actionsObjects.fetchObjects(true)).then(() => { |
||||||
|
const actions = store.getActions() |
||||||
|
expect(actions).toEqual(expectedActions) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it("creates objects/SET_SORT_BY and objects/SET_SORT_ORDER when sortObjects is called", () => { |
||||||
|
const store = mockStore({ |
||||||
|
objects: { |
||||||
|
list: [], |
||||||
|
sortBy: "", |
||||||
|
sortOrder: false, |
||||||
|
isTruncated: false, |
||||||
|
marker: "" |
||||||
|
} |
||||||
|
}) |
||||||
|
const expectedActions = [ |
||||||
|
{ |
||||||
|
type: "objects/SET_SORT_BY", |
||||||
|
sortBy: "name" |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "objects/SET_SORT_ORDER", |
||||||
|
sortOrder: true |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "objects/SET_LIST", |
||||||
|
objects: [], |
||||||
|
isTruncated: false, |
||||||
|
marker: "" |
||||||
|
} |
||||||
|
] |
||||||
|
store.dispatch(actionsObjects.sortObjects("name")) |
||||||
|
const actions = store.getActions() |
||||||
|
expect(actions).toEqual(expectedActions) |
||||||
|
}) |
||||||
|
|
||||||
|
it("should update browser url and creates objects/SET_CURRENT_PREFIX action when selectPrefix is called", () => { |
||||||
|
const store = mockStore({ |
||||||
|
buckets: { currentBucket: "test" } |
||||||
|
}) |
||||||
|
const expectedActions = [ |
||||||
|
{ type: "objects/SET_CURRENT_PREFIX", prefix: "abc/" } |
||||||
|
] |
||||||
|
store.dispatch(actionsObjects.selectPrefix("abc/")) |
||||||
|
const actions = store.getActions() |
||||||
|
expect(actions).toEqual(expectedActions) |
||||||
|
expect(window.location.pathname.endsWith("/test/abc/")).toBeTruthy() |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,46 @@ |
|||||||
|
/* |
||||||
|
* 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 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 toggleSidebar = () => ({ |
||||||
|
type: TOGGLE_SIDEBAR |
||||||
|
}) |
||||||
|
|
||||||
|
export const closeSidebar = () => ({ |
||||||
|
type: CLOSE_SIDEBAR |
||||||
|
}) |
||||||
|
|
||||||
|
export const fetchStorageInfo = () => { |
||||||
|
return function(dispatch) { |
||||||
|
return web.StorageInfo().then(res => { |
||||||
|
const storageInfo = { |
||||||
|
total: res.storageInfo.Total, |
||||||
|
free: res.storageInfo.Free |
||||||
|
} |
||||||
|
dispatch(setStorageInfo(storageInfo)) |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export const setStorageInfo = storageInfo => ({ |
||||||
|
type: SET_STORAGE_INFO, |
||||||
|
storageInfo |
||||||
|
}) |
@ -0,0 +1,126 @@ |
|||||||
|
/* |
||||||
|
* 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 web from "../web" |
||||||
|
import history from "../history" |
||||||
|
import { |
||||||
|
sortObjectsByName, |
||||||
|
sortObjectsBySize, |
||||||
|
sortObjectsByDate |
||||||
|
} from "../utils" |
||||||
|
|
||||||
|
export const SET_LIST = "objects/SET_LIST" |
||||||
|
export const APPEND_LIST = "objects/APPEND_LIST" |
||||||
|
export const SET_SORT_BY = "objects/SET_SORT_BY" |
||||||
|
export const SET_SORT_ORDER = "objects/SET_SORT_ORDER" |
||||||
|
export const SET_CURRENT_PREFIX = "objects/SET_CURRENT_PREFIX" |
||||||
|
|
||||||
|
export const setList = (objects, marker, isTruncated) => ({ |
||||||
|
type: SET_LIST, |
||||||
|
objects, |
||||||
|
marker, |
||||||
|
isTruncated |
||||||
|
}) |
||||||
|
|
||||||
|
export const appendList = (objects, marker, isTruncated) => ({ |
||||||
|
type: APPEND_LIST, |
||||||
|
objects, |
||||||
|
marker, |
||||||
|
isTruncated |
||||||
|
}) |
||||||
|
|
||||||
|
export const fetchObjects = append => { |
||||||
|
return function(dispatch, getState) { |
||||||
|
const { |
||||||
|
buckets: { currentBucket }, |
||||||
|
objects: { currentPrefix, marker } |
||||||
|
} = getState() |
||||||
|
return web |
||||||
|
.ListObjects({ |
||||||
|
bucketName: currentBucket, |
||||||
|
prefix: currentPrefix, |
||||||
|
marker: marker |
||||||
|
}) |
||||||
|
.then(res => { |
||||||
|
let objects = [] |
||||||
|
if (res.objects) { |
||||||
|
objects = res.objects.map(object => { |
||||||
|
return { |
||||||
|
...object, |
||||||
|
name: object.name.replace(currentPrefix, "") |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
if (append) { |
||||||
|
dispatch(appendList(objects, res.nextmarker, res.istruncated)) |
||||||
|
} else { |
||||||
|
dispatch(setList(objects, res.nextmarker, res.istruncated)) |
||||||
|
dispatch(setSortBy("")) |
||||||
|
dispatch(setSortOrder(false)) |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export const sortObjects = sortBy => { |
||||||
|
return function(dispatch, getState) { |
||||||
|
const { objects } = getState() |
||||||
|
const sortOrder = objects.sortBy == sortBy ? !objects.sortOrder : true |
||||||
|
dispatch(setSortBy(sortBy)) |
||||||
|
dispatch(setSortOrder(sortOrder)) |
||||||
|
let list |
||||||
|
switch (sortBy) { |
||||||
|
case "name": |
||||||
|
list = sortObjectsByName(objects.list, sortOrder) |
||||||
|
break |
||||||
|
case "size": |
||||||
|
list = sortObjectsBySize(objects.list, sortOrder) |
||||||
|
break |
||||||
|
case "last-modified": |
||||||
|
list = sortObjectsByDate(objects.list, sortOrder) |
||||||
|
break |
||||||
|
default: |
||||||
|
list = objects.list |
||||||
|
break |
||||||
|
} |
||||||
|
dispatch(setList(list, objects.marker, objects.isTruncated)) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export const setSortBy = sortBy => ({ |
||||||
|
type: SET_SORT_BY, |
||||||
|
sortBy |
||||||
|
}) |
||||||
|
|
||||||
|
export const setSortOrder = sortOrder => ({ |
||||||
|
type: SET_SORT_ORDER, |
||||||
|
sortOrder |
||||||
|
}) |
||||||
|
|
||||||
|
export const selectPrefix = prefix => { |
||||||
|
return function(dispatch, getState) { |
||||||
|
dispatch(setCurrentPrefix(prefix)) |
||||||
|
const currentBucket = getState().buckets.currentBucket |
||||||
|
history.replace(`/${currentBucket}/${prefix}`) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export const setCurrentPrefix = prefix => { |
||||||
|
return { |
||||||
|
type: SET_CURRENT_PREFIX, |
||||||
|
prefix |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
/* |
||||||
|
* 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 Path from "./Path" |
||||||
|
import StorageInfo from "./StorageInfo" |
||||||
|
|
||||||
|
export const Header = () => ( |
||||||
|
<header className="fe-header"> |
||||||
|
<Path /> |
||||||
|
<StorageInfo /> |
||||||
|
</header> |
||||||
|
) |
||||||
|
|
||||||
|
export default Header |
@ -0,0 +1,30 @@ |
|||||||
|
/* |
||||||
|
* 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 MobileHeader from "./MobileHeader" |
||||||
|
import Header from "./Header" |
||||||
|
import ObjectsSection from "./ObjectsSection" |
||||||
|
|
||||||
|
export const MainContent = () => ( |
||||||
|
<div className="fe-body"> |
||||||
|
<MobileHeader /> |
||||||
|
<Header /> |
||||||
|
<ObjectsSection /> |
||||||
|
</div> |
||||||
|
) |
||||||
|
|
||||||
|
export default MainContent |
@ -0,0 +1,60 @@ |
|||||||
|
/* |
||||||
|
* 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 classNames from "classnames" |
||||||
|
import { connect } from "react-redux" |
||||||
|
import logo from "../../img/logo.svg" |
||||||
|
import * as actionsCommon from "../actions/common" |
||||||
|
|
||||||
|
export const MobileHeader = ({ sidebarOpen, toggleSidebar }) => ( |
||||||
|
<header className="fe-header-mobile hidden-lg hidden-md"> |
||||||
|
<div |
||||||
|
id="sidebar-toggle" |
||||||
|
className={ |
||||||
|
"feh-trigger " + |
||||||
|
classNames({ |
||||||
|
"feht-toggled": sidebarOpen |
||||||
|
}) |
||||||
|
} |
||||||
|
onClick={e => { |
||||||
|
e.stopPropagation() |
||||||
|
toggleSidebar() |
||||||
|
}} |
||||||
|
> |
||||||
|
<div className="feht-lines"> |
||||||
|
<div className="top" /> |
||||||
|
<div className="center" /> |
||||||
|
<div className="bottom" /> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<img className="mh-logo" src={logo} alt="" /> |
||||||
|
</header> |
||||||
|
) |
||||||
|
|
||||||
|
const mapStateToProps = state => { |
||||||
|
return { |
||||||
|
sidebarOpen: state.common.sidebarOpen |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => { |
||||||
|
return { |
||||||
|
toggleSidebar: () => dispatch(actionsCommon.toggleSidebar()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(MobileHeader) |
@ -0,0 +1,35 @@ |
|||||||
|
/* |
||||||
|
* 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 humanize from "humanize" |
||||||
|
import Moment from "moment" |
||||||
|
import ObjectItem from "./ObjectItem" |
||||||
|
import * as actionsObjects from "../actions/objects" |
||||||
|
|
||||||
|
export const ObjectContainer = ({ object }) => { |
||||||
|
const actionButtons = [] |
||||||
|
const props = { |
||||||
|
name: object.name, |
||||||
|
contentType: object.contentType, |
||||||
|
size: humanize.filesize(object.size), |
||||||
|
lastModified: Moment(object.lastModified).format("lll"), |
||||||
|
actionButtons: [] |
||||||
|
} |
||||||
|
return <ObjectItem {...props} /> |
||||||
|
} |
||||||
|
|
||||||
|
export default ObjectContainer |
@ -0,0 +1,58 @@ |
|||||||
|
/* |
||||||
|
* 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 { connect } from "react-redux" |
||||||
|
import humanize from "humanize" |
||||||
|
import Moment from "moment" |
||||||
|
import { getDataType } from "../mime" |
||||||
|
|
||||||
|
export const ObjectItem = ({ |
||||||
|
name, |
||||||
|
contentType, |
||||||
|
size, |
||||||
|
lastModified, |
||||||
|
actionButtons, |
||||||
|
onClick |
||||||
|
}) => { |
||||||
|
return ( |
||||||
|
<div className={"fesl-row"} data-type={getDataType(name, contentType)}> |
||||||
|
<div className="fesl-item fesl-item-icon"> |
||||||
|
<div className="fi-select"> |
||||||
|
<input type="checkbox" name={name} checked={false} /> |
||||||
|
<i className="fis-icon" /> |
||||||
|
<i className="fis-helper" /> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className="fesl-item fesl-item-name"> |
||||||
|
<a |
||||||
|
href="#" |
||||||
|
onClick={e => { |
||||||
|
e.preventDefault() |
||||||
|
onClick() |
||||||
|
}} |
||||||
|
> |
||||||
|
{name} |
||||||
|
</a> |
||||||
|
</div> |
||||||
|
<div className="fesl-item fesl-item-size">{size}</div> |
||||||
|
<div className="fesl-item fesl-item-modified">{lastModified}</div> |
||||||
|
<div className="fesl-item fesl-item-actions">{actionButtons}</div> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default ObjectItem |
@ -0,0 +1,99 @@ |
|||||||
|
/* |
||||||
|
* 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 classNames from "classnames" |
||||||
|
import { connect } from "react-redux" |
||||||
|
import * as actionsObjects from "../actions/objects" |
||||||
|
|
||||||
|
export const ObjectsHeader = ({ |
||||||
|
sortNameOrder, |
||||||
|
sortSizeOrder, |
||||||
|
sortLastModifiedOrder, |
||||||
|
sortObjects |
||||||
|
}) => ( |
||||||
|
<div className="feb-container"> |
||||||
|
<header className="fesl-row" data-type="folder"> |
||||||
|
<div className="fesl-item fesl-item-icon" /> |
||||||
|
<div |
||||||
|
className="fesl-item fesl-item-name" |
||||||
|
id="sort-by-name" |
||||||
|
onClick={() => sortObjects("name")} |
||||||
|
data-sort="name" |
||||||
|
> |
||||||
|
Name |
||||||
|
<i |
||||||
|
className={classNames({ |
||||||
|
"fesli-sort": true, |
||||||
|
fa: true, |
||||||
|
"fa-sort-alpha-desc": sortNameOrder, |
||||||
|
"fa-sort-alpha-asc": !sortNameOrder |
||||||
|
})} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
<div |
||||||
|
className="fesl-item fesl-item-size" |
||||||
|
id="sort-by-size" |
||||||
|
onClick={() => sortObjects("size")} |
||||||
|
data-sort="size" |
||||||
|
> |
||||||
|
Size |
||||||
|
<i |
||||||
|
className={classNames({ |
||||||
|
"fesli-sort": true, |
||||||
|
fa: true, |
||||||
|
"fa-sort-amount-desc": sortSizeOrder, |
||||||
|
"fa-sort-amount-asc": !sortSizeOrder |
||||||
|
})} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
<div |
||||||
|
className="fesl-item fesl-item-modified" |
||||||
|
id="sort-by-last-modified" |
||||||
|
onClick={() => sortObjects("last-modified")} |
||||||
|
data-sort="last-modified" |
||||||
|
> |
||||||
|
Last Modified |
||||||
|
<i |
||||||
|
className={classNames({ |
||||||
|
"fesli-sort": true, |
||||||
|
fa: true, |
||||||
|
"fa-sort-numeric-desc": sortLastModifiedOrder, |
||||||
|
"fa-sort-numeric-asc": !sortLastModifiedOrder |
||||||
|
})} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
<div className="fesl-item fesl-item-actions" /> |
||||||
|
</header> |
||||||
|
</div> |
||||||
|
) |
||||||
|
|
||||||
|
const mapStateToProps = state => { |
||||||
|
return { |
||||||
|
sortNameOrder: state.objects.sortBy == "name" && state.objects.sortOrder, |
||||||
|
sortSizeOrder: state.objects.sortBy == "size" && state.objects.sortOrder, |
||||||
|
sortLastModifiedOrder: |
||||||
|
state.objects.sortBy == "last-modified" && state.objects.sortOrder |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => { |
||||||
|
return { |
||||||
|
sortObjects: sortBy => dispatch(actionsObjects.sortObjects(sortBy)) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(ObjectsHeader) |
@ -0,0 +1,75 @@ |
|||||||
|
/* |
||||||
|
* 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 classNames from "classnames" |
||||||
|
import { connect } from "react-redux" |
||||||
|
import InfiniteScroll from "react-infinite-scroller" |
||||||
|
import * as actionsObjects from "../actions/objects" |
||||||
|
import ObjectsList from "./ObjectsList" |
||||||
|
|
||||||
|
export class ObjectsListContainer extends React.Component { |
||||||
|
componentWillReceiveProps(nextProps) { |
||||||
|
const { currentBucket, currentPrefix, loadObjects } = this.props |
||||||
|
if ( |
||||||
|
currentBucket != nextProps.currentBucket || |
||||||
|
currentPrefix != nextProps.currentPrefix |
||||||
|
) { |
||||||
|
loadObjects() |
||||||
|
} |
||||||
|
} |
||||||
|
render() { |
||||||
|
const { objects, isTruncated, currentBucket, loadObjects } = this.props |
||||||
|
return ( |
||||||
|
<div className="feb-container"> |
||||||
|
<InfiniteScroll |
||||||
|
pageStart={0} |
||||||
|
loadMore={() => loadObjects(true)} |
||||||
|
hasMore={isTruncated} |
||||||
|
useWindow={true} |
||||||
|
initialLoad={false} |
||||||
|
> |
||||||
|
<ObjectsList objects={objects} /> |
||||||
|
</InfiniteScroll> |
||||||
|
<div |
||||||
|
className="text-center" |
||||||
|
style={{ display: isTruncated && currentBucket ? "block" : "none" }} |
||||||
|
> |
||||||
|
<span>Loading...</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const mapStateToProps = state => { |
||||||
|
return { |
||||||
|
currentBucket: state.buckets.currentBucket, |
||||||
|
currentPrefix: state.objects.currentPrefix, |
||||||
|
objects: state.objects.list, |
||||||
|
isTruncated: state.objects.isTruncated |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => { |
||||||
|
return { |
||||||
|
loadObjects: append => dispatch(actionsObjects.fetchObjects(append)) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)( |
||||||
|
ObjectsListContainer |
||||||
|
) |
@ -0,0 +1,28 @@ |
|||||||
|
/* |
||||||
|
* 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 ObjectsHeader from "./ObjectsHeader" |
||||||
|
import ObjectsListContainer from "./ObjectsListContainer" |
||||||
|
|
||||||
|
export const ObjectsSection = () => ( |
||||||
|
<div> |
||||||
|
<ObjectsHeader /> |
||||||
|
<ObjectsListContainer /> |
||||||
|
</div> |
||||||
|
) |
||||||
|
|
||||||
|
export default ObjectsSection |
@ -0,0 +1,45 @@ |
|||||||
|
/* |
||||||
|
* 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 { connect } from "react-redux" |
||||||
|
import ObjectItem from "./ObjectItem" |
||||||
|
import * as actionsObjects from "../actions/objects" |
||||||
|
|
||||||
|
export const PrefixContainer = ({ object, currentPrefix, selectPrefix }) => { |
||||||
|
const props = { |
||||||
|
name: object.name, |
||||||
|
contentType: object.contentType, |
||||||
|
onClick: () => selectPrefix(`${currentPrefix}${object.name}`) |
||||||
|
} |
||||||
|
|
||||||
|
return <ObjectItem {...props} /> |
||||||
|
} |
||||||
|
|
||||||
|
const mapStateToProps = (state, ownProps) => { |
||||||
|
return { |
||||||
|
object: ownProps.object, |
||||||
|
currentPrefix: state.objects.currentPrefix |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => { |
||||||
|
return { |
||||||
|
selectPrefix: prefix => dispatch(actionsObjects.selectPrefix(prefix)) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(PrefixContainer) |
@ -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 { connect } from "react-redux" |
||||||
|
import humanize from "humanize" |
||||||
|
import * as actionsCommon from "../actions/common" |
||||||
|
|
||||||
|
export class StorageInfo extends React.Component { |
||||||
|
componentWillMount() { |
||||||
|
const { fetchStorageInfo } = this.props |
||||||
|
fetchStorageInfo() |
||||||
|
} |
||||||
|
render() { |
||||||
|
const { total, free } = this.props.storageInfo |
||||||
|
const used = total - free |
||||||
|
const usedPercent = used / total * 100 + "%" |
||||||
|
const freePercent = free * 100 / total |
||||||
|
return ( |
||||||
|
<div className="feh-usage"> |
||||||
|
<div className="fehu-chart"> |
||||||
|
<div style={{ width: usedPercent }} /> |
||||||
|
</div> |
||||||
|
<ul> |
||||||
|
<li> |
||||||
|
<span>Used: </span> |
||||||
|
{humanize.filesize(total - free)} |
||||||
|
</li> |
||||||
|
<li className="pull-right"> |
||||||
|
<span>Free: </span> |
||||||
|
{humanize.filesize(total - used)} |
||||||
|
</li> |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const mapStateToProps = state => { |
||||||
|
return { |
||||||
|
storageInfo: state.common.storageInfo |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => { |
||||||
|
return { |
||||||
|
fetchStorageInfo: () => dispatch(actionsCommon.fetchStorageInfo()) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(StorageInfo) |
@ -0,0 +1,36 @@ |
|||||||
|
/* |
||||||
|
* 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 { MobileHeader } from "../MobileHeader" |
||||||
|
|
||||||
|
describe("Bucket", () => { |
||||||
|
it("should render without crashing", () => { |
||||||
|
shallow(<MobileHeader sidebarOpen={false} />) |
||||||
|
}) |
||||||
|
|
||||||
|
it("should toggleSidebar when trigger is clicked", () => { |
||||||
|
const toggleSidebar = jest.fn() |
||||||
|
const wrapper = shallow( |
||||||
|
<MobileHeader sidebarOpen={false} toggleSidebar={toggleSidebar} /> |
||||||
|
) |
||||||
|
wrapper |
||||||
|
.find("#sidebar-toggle") |
||||||
|
.simulate("click", { stopPropagation: jest.fn() }) |
||||||
|
expect(toggleSidebar).toHaveBeenCalled() |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,61 @@ |
|||||||
|
/* |
||||||
|
* 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 { ObjectsHeader } from "../ObjectsHeader" |
||||||
|
|
||||||
|
describe("ObjectsHeader", () => { |
||||||
|
it("should render without crashing", () => { |
||||||
|
const sortObjects = jest.fn() |
||||||
|
shallow(<ObjectsHeader sortObjects={sortObjects} />) |
||||||
|
}) |
||||||
|
|
||||||
|
it("should render columns with asc classes by default", () => { |
||||||
|
const sortObjects = jest.fn() |
||||||
|
const wrapper = shallow(<ObjectsHeader sortObjects={sortObjects} />) |
||||||
|
expect( |
||||||
|
wrapper.find("#sort-by-name i").hasClass("fa-sort-alpha-asc") |
||||||
|
).toBeTruthy() |
||||||
|
expect( |
||||||
|
wrapper.find("#sort-by-size i").hasClass("fa-sort-amount-asc") |
||||||
|
).toBeTruthy() |
||||||
|
expect( |
||||||
|
wrapper.find("#sort-by-last-modified i").hasClass("fa-sort-numeric-asc") |
||||||
|
).toBeTruthy() |
||||||
|
}) |
||||||
|
|
||||||
|
it("should render name column with desc class when objects are sorted by name", () => { |
||||||
|
const sortObjects = jest.fn() |
||||||
|
const wrapper = shallow( |
||||||
|
<ObjectsHeader sortObjects={sortObjects} sortNameOrder={true} /> |
||||||
|
) |
||||||
|
expect( |
||||||
|
wrapper.find("#sort-by-name i").hasClass("fa-sort-alpha-desc") |
||||||
|
).toBeTruthy() |
||||||
|
}) |
||||||
|
|
||||||
|
it("should call sortObjects when a column is clicked", () => { |
||||||
|
const sortObjects = jest.fn() |
||||||
|
const wrapper = shallow(<ObjectsHeader sortObjects={sortObjects} />) |
||||||
|
wrapper.find("#sort-by-name").simulate("click") |
||||||
|
expect(sortObjects).toHaveBeenCalledWith("name") |
||||||
|
wrapper.find("#sort-by-size").simulate("click") |
||||||
|
expect(sortObjects).toHaveBeenCalledWith("size") |
||||||
|
wrapper.find("#sort-by-last-modified").simulate("click") |
||||||
|
expect(sortObjects).toHaveBeenCalledWith("last-modified") |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,39 @@ |
|||||||
|
/* |
||||||
|
* 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 { ObjectsList } from "../ObjectsList" |
||||||
|
|
||||||
|
describe("ObjectsList", () => { |
||||||
|
it("should render without crashing", () => { |
||||||
|
shallow(<ObjectsList objects={[]} />) |
||||||
|
}) |
||||||
|
|
||||||
|
it("should render ObjectContainer for every object", () => { |
||||||
|
const wrapper = shallow( |
||||||
|
<ObjectsList objects={[{ name: "test1.jpg" }, { name: "test2.jpg" }]} /> |
||||||
|
) |
||||||
|
expect(wrapper.find("ObjectContainer").length).toBe(2) |
||||||
|
}) |
||||||
|
|
||||||
|
it("should render PrefixContainer for every prefix", () => { |
||||||
|
const wrapper = shallow( |
||||||
|
<ObjectsList objects={[{ name: "abc/" }, { name: "xyz/" }]} /> |
||||||
|
) |
||||||
|
expect(wrapper.find("Connect(PrefixContainer)").length).toBe(2) |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,57 @@ |
|||||||
|
/* |
||||||
|
* 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 { ObjectsListContainer } from "../ObjectsListContainer" |
||||||
|
|
||||||
|
describe("ObjectsList", () => { |
||||||
|
it("should render without crashing", () => { |
||||||
|
shallow(<ObjectsListContainer loadObjects={jest.fn()} />) |
||||||
|
}) |
||||||
|
|
||||||
|
it("should render ObjectsList with objects", () => { |
||||||
|
const wrapper = shallow( |
||||||
|
<ObjectsListContainer |
||||||
|
objects={[{ name: "test1.jpg" }, { name: "test2.jpg" }]} |
||||||
|
loadObjects={jest.fn()} |
||||||
|
/> |
||||||
|
) |
||||||
|
expect(wrapper.find("ObjectsList").length).toBe(1) |
||||||
|
expect(wrapper.find("ObjectsList").prop("objects")).toEqual([ |
||||||
|
{ name: "test1.jpg" }, |
||||||
|
{ name: "test2.jpg" } |
||||||
|
]) |
||||||
|
}) |
||||||
|
|
||||||
|
it("should call loadObjects when currentBucket is changed", () => { |
||||||
|
const loadObjects = jest.fn() |
||||||
|
const wrapper = shallow( |
||||||
|
<ObjectsListContainer currentBucket="test1" loadObjects={loadObjects} /> |
||||||
|
) |
||||||
|
wrapper.setProps({ currentBucket: "test2" }) |
||||||
|
expect(loadObjects).toHaveBeenCalled() |
||||||
|
}) |
||||||
|
|
||||||
|
it("should call loadObjects when currentPrefix is changed", () => { |
||||||
|
const loadObjects = jest.fn() |
||||||
|
const wrapper = shallow( |
||||||
|
<ObjectsListContainer currentPrefix="abc/" loadObjects={loadObjects} /> |
||||||
|
) |
||||||
|
wrapper.setProps({ currentPrefix: "abc/xyz/" }) |
||||||
|
expect(loadObjects).toHaveBeenCalled() |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,37 @@ |
|||||||
|
/* |
||||||
|
* 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 { ObjectItem } from "../ObjectItem" |
||||||
|
|
||||||
|
describe("ObjectItem", () => { |
||||||
|
it("should render without crashing", () => { |
||||||
|
shallow(<ObjectItem name={"test"} />) |
||||||
|
}) |
||||||
|
|
||||||
|
it("should render with content type", () => { |
||||||
|
const wrapper = shallow(<ObjectItem name={"test.jpg"} contentType={""} />) |
||||||
|
expect(wrapper.prop("data-type")).toBe("image") |
||||||
|
}) |
||||||
|
|
||||||
|
it("should call onClick when the object isclicked", () => { |
||||||
|
const onClick = jest.fn() |
||||||
|
const wrapper = shallow(<ObjectItem name={"test"} onClick={onClick} />) |
||||||
|
wrapper.find("a").simulate("click", { preventDefault: jest.fn() }) |
||||||
|
expect(onClick).toHaveBeenCalled() |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,72 @@ |
|||||||
|
/* |
||||||
|
* 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 { Path } from "../Path" |
||||||
|
|
||||||
|
describe("Path", () => { |
||||||
|
it("should render without crashing", () => { |
||||||
|
shallow(<Path currentBucket={"test1"} currentPrefix={"test2"} />) |
||||||
|
}) |
||||||
|
|
||||||
|
it("should render only bucket if there is no prefix", () => { |
||||||
|
const wrapper = shallow(<Path currentBucket={"test1"} currentPrefix={""} />) |
||||||
|
expect(wrapper.find("span").length).toBe(1) |
||||||
|
expect(wrapper.text()).toBe("test1") |
||||||
|
}) |
||||||
|
|
||||||
|
it("should render bucket and prefix", () => { |
||||||
|
const wrapper = shallow( |
||||||
|
<Path currentBucket={"test1"} currentPrefix={"a/b/"} /> |
||||||
|
) |
||||||
|
expect(wrapper.find("span").length).toBe(3) |
||||||
|
expect( |
||||||
|
wrapper |
||||||
|
.find("span") |
||||||
|
.at(0) |
||||||
|
.text() |
||||||
|
).toBe("test1") |
||||||
|
expect( |
||||||
|
wrapper |
||||||
|
.find("span") |
||||||
|
.at(1) |
||||||
|
.text() |
||||||
|
).toBe("a") |
||||||
|
expect( |
||||||
|
wrapper |
||||||
|
.find("span") |
||||||
|
.at(2) |
||||||
|
.text() |
||||||
|
).toBe("b") |
||||||
|
}) |
||||||
|
|
||||||
|
it("should call selectPrefix when a prefix part is clicked", () => { |
||||||
|
const selectPrefix = jest.fn() |
||||||
|
const wrapper = shallow( |
||||||
|
<Path |
||||||
|
currentBucket={"test1"} |
||||||
|
currentPrefix={"a/b/"} |
||||||
|
selectPrefix={selectPrefix} |
||||||
|
/> |
||||||
|
) |
||||||
|
wrapper |
||||||
|
.find("a") |
||||||
|
.at(2) |
||||||
|
.simulate("click", { preventDefault: jest.fn() }) |
||||||
|
expect(selectPrefix).toHaveBeenCalledWith("a/b/") |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,44 @@ |
|||||||
|
/* |
||||||
|
* 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 { PrefixContainer } from "../PrefixContainer" |
||||||
|
|
||||||
|
describe("PrefixContainer", () => { |
||||||
|
it("should render without crashing", () => { |
||||||
|
shallow(<PrefixContainer object={{ name: "abc/" }} />) |
||||||
|
}) |
||||||
|
|
||||||
|
it("should render ObjectItem with props", () => { |
||||||
|
const wrapper = shallow(<PrefixContainer object={{ name: "abc/" }} />) |
||||||
|
expect(wrapper.find("ObjectItem").length).toBe(1) |
||||||
|
expect(wrapper.find("ObjectItem").prop("name")).toBe("abc/") |
||||||
|
}) |
||||||
|
|
||||||
|
it("should call selectPrefix when the prefix is clicked", () => { |
||||||
|
const selectPrefix = jest.fn() |
||||||
|
const wrapper = shallow( |
||||||
|
<PrefixContainer |
||||||
|
object={{ name: "abc/" }} |
||||||
|
currentPrefix={"xyz/"} |
||||||
|
selectPrefix={selectPrefix} |
||||||
|
/> |
||||||
|
) |
||||||
|
wrapper.find("ObjectItem").prop("onClick")() |
||||||
|
expect(selectPrefix).toHaveBeenCalledWith("xyz/abc/") |
||||||
|
}) |
||||||
|
}) |
@ -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 { StorageInfo } from "../StorageInfo" |
||||||
|
|
||||||
|
describe("StorageInfo", () => { |
||||||
|
it("should render without crashing", () => { |
||||||
|
shallow( |
||||||
|
<StorageInfo |
||||||
|
storageInfo={{ total: 100, free: 60 }} |
||||||
|
fetchStorageInfo={jest.fn()} |
||||||
|
/> |
||||||
|
) |
||||||
|
}) |
||||||
|
|
||||||
|
it("should fetchStorageInfo before component is mounted", () => { |
||||||
|
const fetchStorageInfo = jest.fn() |
||||||
|
shallow( |
||||||
|
<StorageInfo |
||||||
|
storageInfo={{ total: 100, free: 60 }} |
||||||
|
fetchStorageInfo={fetchStorageInfo} |
||||||
|
/> |
||||||
|
) |
||||||
|
expect(fetchStorageInfo).toHaveBeenCalled() |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,24 @@ |
|||||||
|
/* |
||||||
|
* 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 createHistory from "history/createBrowserHistory" |
||||||
|
import { minioBrowserPrefix } from "./constants" |
||||||
|
|
||||||
|
const history = createHistory({ |
||||||
|
basename: minioBrowserPrefix |
||||||
|
}) |
||||||
|
|
||||||
|
export default history |
@ -0,0 +1,70 @@ |
|||||||
|
/* |
||||||
|
* 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 reducer from "../common" |
||||||
|
import * as actionsCommon from "../../actions/common" |
||||||
|
|
||||||
|
describe("common reducer", () => { |
||||||
|
it("should return the initial state", () => { |
||||||
|
expect(reducer(undefined, {})).toEqual({ |
||||||
|
sidebarOpen: false, |
||||||
|
storageInfo: { |
||||||
|
total: 0, |
||||||
|
free: 0 |
||||||
|
} |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it("should handle TOGGLE_SIDEBAR", () => { |
||||||
|
expect( |
||||||
|
reducer( |
||||||
|
{ sidebarOpen: false }, |
||||||
|
{ |
||||||
|
type: actionsCommon.TOGGLE_SIDEBAR |
||||||
|
} |
||||||
|
) |
||||||
|
).toEqual({ |
||||||
|
sidebarOpen: true |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it("should handle CLOSE_SIDEBAR", () => { |
||||||
|
expect( |
||||||
|
reducer( |
||||||
|
{ sidebarOpen: true }, |
||||||
|
{ |
||||||
|
type: actionsCommon.CLOSE_SIDEBAR |
||||||
|
} |
||||||
|
) |
||||||
|
).toEqual({ |
||||||
|
sidebarOpen: false |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it("should handle SET_STORAGE_INFO", () => { |
||||||
|
expect( |
||||||
|
reducer( |
||||||
|
{}, |
||||||
|
{ |
||||||
|
type: actionsCommon.SET_STORAGE_INFO, |
||||||
|
storageInfo: { total: 100, free: 40 } |
||||||
|
} |
||||||
|
) |
||||||
|
).toEqual({ |
||||||
|
storageInfo: { total: 100, free: 40 } |
||||||
|
}) |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,97 @@ |
|||||||
|
/* |
||||||
|
* 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 reducer from "../objects" |
||||||
|
import * as actions from "../../actions/objects" |
||||||
|
|
||||||
|
describe("objects reducer", () => { |
||||||
|
it("should return the initial state", () => { |
||||||
|
const initialState = reducer(undefined, {}) |
||||||
|
expect(initialState).toEqual({ |
||||||
|
list: [], |
||||||
|
sortBy: "", |
||||||
|
sortOrder: false, |
||||||
|
currentPrefix: "", |
||||||
|
marker: "", |
||||||
|
isTruncated: false |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
it("should handle SET_LIST", () => { |
||||||
|
const newState = reducer(undefined, { |
||||||
|
type: actions.SET_LIST, |
||||||
|
objects: [{ name: "obj1" }, { name: "obj2" }], |
||||||
|
marker: "obj2", |
||||||
|
isTruncated: false |
||||||
|
}) |
||||||
|
expect(newState.list).toEqual([{ name: "obj1" }, { name: "obj2" }]) |
||||||
|
expect(newState.marker).toBe("obj2") |
||||||
|
expect(newState.isTruncated).toBeFalsy() |
||||||
|
}) |
||||||
|
|
||||||
|
it("should handle APPEND_LIST", () => { |
||||||
|
const newState = reducer( |
||||||
|
{ |
||||||
|
list: [{ name: "obj1" }, { name: "obj2" }], |
||||||
|
marker: "obj2", |
||||||
|
isTruncated: true |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: actions.APPEND_LIST, |
||||||
|
objects: [{ name: "obj3" }, { name: "obj4" }], |
||||||
|
marker: "obj4", |
||||||
|
isTruncated: false |
||||||
|
} |
||||||
|
) |
||||||
|
expect(newState.list).toEqual([ |
||||||
|
{ name: "obj1" }, |
||||||
|
{ name: "obj2" }, |
||||||
|
{ name: "obj3" }, |
||||||
|
{ name: "obj4" } |
||||||
|
]) |
||||||
|
expect(newState.marker).toBe("obj4") |
||||||
|
expect(newState.isTruncated).toBeFalsy() |
||||||
|
}) |
||||||
|
|
||||||
|
it("should handle SET_SORT_BY", () => { |
||||||
|
const newState = reducer(undefined, { |
||||||
|
type: actions.SET_SORT_BY, |
||||||
|
sortBy: "name" |
||||||
|
}) |
||||||
|
expect(newState.sortBy).toEqual("name") |
||||||
|
}) |
||||||
|
|
||||||
|
it("should handle SET_SORT_ORDER", () => { |
||||||
|
const newState = reducer(undefined, { |
||||||
|
type: actions.SET_SORT_ORDER, |
||||||
|
sortOrder: true |
||||||
|
}) |
||||||
|
expect(newState.sortOrder).toEqual(true) |
||||||
|
}) |
||||||
|
|
||||||
|
it("should handle SET_CURRENT_PREFIX", () => { |
||||||
|
const newState = reducer( |
||||||
|
{ currentPrefix: "test1/", marker: "abc", isTruncated: true }, |
||||||
|
{ |
||||||
|
type: actions.SET_CURRENT_PREFIX, |
||||||
|
prefix: "test2/" |
||||||
|
} |
||||||
|
) |
||||||
|
expect(newState.currentPrefix).toEqual("test2/") |
||||||
|
expect(newState.marker).toEqual("") |
||||||
|
expect(newState.isTruncated).toBeFalsy() |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,39 @@ |
|||||||
|
/* |
||||||
|
* 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 * as actionsCommon from "../actions/common" |
||||||
|
|
||||||
|
export default ( |
||||||
|
state = { sidebarOpen: false, storageInfo: { total: 0, free: 0 } }, |
||||||
|
action |
||||||
|
) => { |
||||||
|
switch (action.type) { |
||||||
|
case actionsCommon.TOGGLE_SIDEBAR: |
||||||
|
return Object.assign({}, state, { |
||||||
|
sidebarOpen: !state.sidebarOpen |
||||||
|
}) |
||||||
|
case actionsCommon.CLOSE_SIDEBAR: |
||||||
|
return Object.assign({}, state, { |
||||||
|
sidebarOpen: false |
||||||
|
}) |
||||||
|
case actionsCommon.SET_STORAGE_INFO: |
||||||
|
return Object.assign({}, state, { |
||||||
|
storageInfo: action.storageInfo |
||||||
|
}) |
||||||
|
default: |
||||||
|
return state |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,65 @@ |
|||||||
|
/* |
||||||
|
* 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 * as actionsObjects from "../actions/objects" |
||||||
|
|
||||||
|
export default ( |
||||||
|
state = { |
||||||
|
list: [], |
||||||
|
sortBy: "", |
||||||
|
sortOrder: false, |
||||||
|
currentPrefix: "", |
||||||
|
marker: "", |
||||||
|
isTruncated: false |
||||||
|
}, |
||||||
|
action |
||||||
|
) => { |
||||||
|
switch (action.type) { |
||||||
|
case actionsObjects.SET_LIST: |
||||||
|
return { |
||||||
|
...state, |
||||||
|
list: action.objects, |
||||||
|
marker: action.marker, |
||||||
|
isTruncated: action.isTruncated |
||||||
|
} |
||||||
|
case actionsObjects.APPEND_LIST: |
||||||
|
return { |
||||||
|
...state, |
||||||
|
list: [...state.list, ...action.objects], |
||||||
|
marker: action.marker, |
||||||
|
isTruncated: action.isTruncated |
||||||
|
} |
||||||
|
case actionsObjects.SET_SORT_BY: |
||||||
|
return { |
||||||
|
...state, |
||||||
|
sortBy: action.sortBy |
||||||
|
} |
||||||
|
case actionsObjects.SET_SORT_ORDER: |
||||||
|
return { |
||||||
|
...state, |
||||||
|
sortOrder: action.sortOrder |
||||||
|
} |
||||||
|
case actionsObjects.SET_CURRENT_PREFIX: |
||||||
|
return { |
||||||
|
...state, |
||||||
|
currentPrefix: action.prefix, |
||||||
|
marker: "", |
||||||
|
isTruncated: false |
||||||
|
} |
||||||
|
default: |
||||||
|
return state |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue