├── src ├── browser │ ├── less │ │ ├── inc │ │ │ ├── object.less │ │ │ ├── font.less │ │ │ ├── animate │ │ │ │ ├── animate.less │ │ │ │ ├── zoomIn.less │ │ │ │ ├── fadeIn.less │ │ │ │ ├── fadeOut.less │ │ │ │ ├── fadeOutUp.less │ │ │ │ ├── fadeInUp.less │ │ │ │ ├── fadeInDown.less │ │ │ │ └── fadeOutDown.less │ │ │ ├── browser.less │ │ │ ├── base.less │ │ │ ├── buttons.less │ │ │ ├── dropdown.less │ │ │ ├── ie-warning.less │ │ │ ├── alert.less │ │ │ ├── mixin.less │ │ │ ├── generics.less │ │ │ ├── misc.less │ │ │ └── login.less │ │ └── main.less │ ├── js │ │ ├── jest │ │ │ ├── __mocks__ │ │ │ │ ├── jsonRpcMock.js │ │ │ │ └── fileMock.js │ │ │ └── setup.js │ │ ├── dashboardStatus │ │ │ ├── index.js │ │ │ ├── DashboardStatusMainContent.js │ │ │ ├── DashboardStatus.js │ │ │ └── PeriodMenu.js │ │ ├── charts │ │ │ ├── index.js │ │ │ └── BaseTable.js │ │ ├── alertModals │ │ │ ├── actions.js │ │ │ ├── ObjectDeleteModal.js │ │ │ ├── ObjectTransferModal.js │ │ │ ├── reducer.js │ │ │ ├── AbortConfirmModal.js │ │ │ └── AlertModals.js │ │ ├── history.js │ │ ├── browser │ │ │ ├── __tests__ │ │ │ │ ├── Host.test.js │ │ │ │ ├── MainContent.test.js │ │ │ │ ├── Browser.test.js │ │ │ │ ├── MobileHeader.test.js │ │ │ │ ├── StorageInfo.test.js │ │ │ │ ├── AboutModal.test.js │ │ │ │ ├── Header.test.js │ │ │ │ ├── SideBar.test.js │ │ │ │ ├── reducer.test.js │ │ │ │ ├── BrowserDropdown.test.js │ │ │ │ └── actions.test.js │ │ │ ├── Host.js │ │ │ ├── DeviceTable.js │ │ │ ├── Browser.js │ │ │ ├── StorageInfo.js │ │ │ ├── Header.js │ │ │ ├── ConfirmModal.js │ │ │ ├── InputGroup.js │ │ │ ├── MobileHeader.js │ │ │ ├── AboutModal.js │ │ │ ├── DeviceFileModal.js │ │ │ ├── MainContent.js │ │ │ └── reducer.js │ │ ├── __tests__ │ │ │ ├── jsonrpc-test.js │ │ │ └── App.test.js │ │ ├── objects │ │ │ ├── selectors.js │ │ │ ├── __tests__ │ │ │ │ ├── ObjectsSection.test.js │ │ │ │ ├── ObjectsList.test.js │ │ │ │ ├── PrefixContainer.test.js │ │ │ │ ├── DeleteObjectConfirmModal.test.js │ │ │ │ ├── ObjectsListContainer.test.js │ │ │ │ ├── ObjectContainer.test.js │ │ │ │ └── Path.test.js │ │ │ ├── ObjectsSection.js │ │ │ ├── DeleteObjectConfirmModal.js │ │ │ ├── ObjectsList.js │ │ │ ├── PreviewObjectModal.js │ │ │ ├── PrefixContainer.js │ │ │ ├── ObjectContainer.js │ │ │ ├── Path.js │ │ │ └── corsError.js │ │ ├── loader.js │ │ ├── store │ │ │ └── configure-store.js │ │ ├── alert │ │ │ ├── Alert.js │ │ │ ├── __tests___ │ │ │ │ ├── Alert.test.js │ │ │ │ ├── AlertContainer.test.js │ │ │ │ ├── actions.test.js │ │ │ │ └── reducer.test.js │ │ │ ├── reducer.js │ │ │ ├── actions.js │ │ │ └── AlertContainer.js │ │ ├── buckets │ │ │ ├── __tests__ │ │ │ │ ├── BucketSearch.test.js │ │ │ │ ├── selectors.test.js │ │ │ │ ├── Bucket.test.js │ │ │ │ ├── BucketList.test.js │ │ │ │ ├── BucketContainer.test.js │ │ │ │ ├── BucketPolicyModal.test.js │ │ │ │ ├── BucketDropdown.test.js │ │ │ │ └── Policy.test.js │ │ │ ├── BucketContainer.js │ │ │ ├── selectors.js │ │ │ ├── BucketSearch.js │ │ │ ├── Bucket.js │ │ │ └── BucketPolicyModal.js │ │ ├── reducers.js │ │ ├── App.js │ │ ├── constants.js │ │ ├── uploads │ │ │ ├── __tests__ │ │ │ │ ├── Dropzone.test.js │ │ │ │ ├── UploadModal.test.js │ │ │ │ ├── AbortConfirmModal.test.js │ │ │ │ └── reducer.test.js │ │ │ ├── reducer.js │ │ │ ├── AbortConfirmModal.js │ │ │ └── Dropzone.js │ │ └── components │ │ │ └── BrowserUpdate.js │ ├── img │ │ ├── logo.png │ │ ├── arrow.png │ │ ├── more-h.png │ │ ├── favicon.ico │ │ ├── logo-sidebar.png │ │ ├── more-h-light.png │ │ ├── more-h.svg │ │ ├── select-caret.svg │ │ ├── arrow.svg │ │ ├── more-h-light.svg │ │ └── logo-sidebar-small.svg │ ├── fonts │ │ └── lato │ │ │ ├── lato-normal.woff │ │ │ └── lato-normal.woff2 │ ├── simple.js │ ├── index.js │ └── customize-css │ │ └── customize.css └── sdk │ ├── constants.js │ ├── response.js │ ├── aws-sdk-client.js │ ├── s3-endpoints.js │ └── s3client.js ├── default-schemas.json ├── font-awesome ├── fonts │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ └── fontawesome-webfont.woff2 ├── fonts-old │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ └── fontawesome-webfont.woff2 ├── less │ ├── fixed-width.less │ ├── screen-reader.less │ ├── larger.less │ ├── list.less │ ├── core.less │ ├── stacked.less │ ├── font-awesome.less │ ├── bordered-pulled.less │ ├── rotated-flipped.less │ ├── path.less │ ├── animated.less │ └── mixins.less ├── scss │ ├── _fixed-width.scss │ ├── _screen-reader.scss │ ├── _larger.scss │ ├── _list.scss │ ├── _core.scss │ ├── font-awesome.scss │ ├── _stacked.scss │ ├── _bordered-pulled.scss │ ├── _rotated-flipped.scss │ ├── _path.scss │ ├── _animated.scss │ └── _mixins.scss ├── HELP-US-OUT.txt ├── .npmignore └── package.json ├── .gitignore ├── .babelrc ├── simple-editor.js ├── jest.config.js └── Dockerfile /src/browser/less/inc/object.less: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/browser/js/jest/__mocks__/jsonRpcMock.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/browser/js/jest/__mocks__/fileMock.js: -------------------------------------------------------------------------------- 1 | module.exports = 'test-file-stub'; -------------------------------------------------------------------------------- /src/browser/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CSS-Electronics/cancloud/HEAD/src/browser/img/logo.png -------------------------------------------------------------------------------- /src/browser/img/arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CSS-Electronics/cancloud/HEAD/src/browser/img/arrow.png -------------------------------------------------------------------------------- /src/browser/img/more-h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CSS-Electronics/cancloud/HEAD/src/browser/img/more-h.png -------------------------------------------------------------------------------- /default-schemas.json: -------------------------------------------------------------------------------- 1 | { 2 | "endpoint": "", 3 | "schema": "", 4 | "uischema": "", 5 | "config": "" 6 | } 7 | -------------------------------------------------------------------------------- /src/browser/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CSS-Electronics/cancloud/HEAD/src/browser/img/favicon.ico -------------------------------------------------------------------------------- /src/browser/img/logo-sidebar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CSS-Electronics/cancloud/HEAD/src/browser/img/logo-sidebar.png -------------------------------------------------------------------------------- /src/browser/img/more-h-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CSS-Electronics/cancloud/HEAD/src/browser/img/more-h-light.png -------------------------------------------------------------------------------- /src/browser/fonts/lato/lato-normal.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CSS-Electronics/cancloud/HEAD/src/browser/fonts/lato/lato-normal.woff -------------------------------------------------------------------------------- /src/browser/js/dashboardStatus/index.js: -------------------------------------------------------------------------------- 1 | import DashboardStatus from "./DashboardStatus"; 2 | 3 | module.exports = DashboardStatus; 4 | -------------------------------------------------------------------------------- /src/browser/fonts/lato/lato-normal.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CSS-Electronics/cancloud/HEAD/src/browser/fonts/lato/lato-normal.woff2 -------------------------------------------------------------------------------- /font-awesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CSS-Electronics/cancloud/HEAD/font-awesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /font-awesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CSS-Electronics/cancloud/HEAD/font-awesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /font-awesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CSS-Electronics/cancloud/HEAD/font-awesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /font-awesome/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CSS-Electronics/cancloud/HEAD/font-awesome/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /font-awesome/fonts-old/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CSS-Electronics/cancloud/HEAD/font-awesome/fonts-old/fontawesome-webfont.eot -------------------------------------------------------------------------------- /font-awesome/fonts-old/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CSS-Electronics/cancloud/HEAD/font-awesome/fonts-old/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /font-awesome/fonts-old/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CSS-Electronics/cancloud/HEAD/font-awesome/fonts-old/fontawesome-webfont.woff -------------------------------------------------------------------------------- /font-awesome/fonts-old/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CSS-Electronics/cancloud/HEAD/font-awesome/fonts-old/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | 4 | *demo-credentials.json 5 | news.json 6 | 7 | site 8 | 9 | .eslintrc.json 10 | 11 | simple/* 12 | *.bat 13 | -------------------------------------------------------------------------------- /font-awesome/less/fixed-width.less: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .@{fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /font-awesome/less/screen-reader.less: -------------------------------------------------------------------------------- 1 | // Screen Readers 2 | // ------------------------- 3 | 4 | .sr-only { .sr-only(); } 5 | .sr-only-focusable { .sr-only-focusable(); } 6 | -------------------------------------------------------------------------------- /font-awesome/scss/_fixed-width.scss: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .#{$fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "es2015", 4 | "react" 5 | ], 6 | "plugins": [ 7 | "transform-object-rest-spread", 8 | "transform-class-properties" 9 | ] 10 | } -------------------------------------------------------------------------------- /font-awesome/scss/_screen-reader.scss: -------------------------------------------------------------------------------- 1 | // Screen Readers 2 | // ------------------------- 3 | 4 | .sr-only { @include sr-only(); } 5 | .sr-only-focusable { @include sr-only-focusable(); } 6 | -------------------------------------------------------------------------------- /src/browser/less/inc/font.less: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: Lato; 3 | src: url('../../fonts/lato/lato-normal.woff2') format('woff2'), 4 | url('../../fonts/lato/lato-normal.woff') format('woff'); 5 | font-weight: normal; 6 | font-style: normal; 7 | } -------------------------------------------------------------------------------- /src/browser/js/charts/index.js: -------------------------------------------------------------------------------- 1 | // We can add multiple types of charts and export all from the chart component 2 | import BaseChart from "./BaseChart"; 3 | import BaseMap from "./BaseMap"; 4 | import BaseTable from "./BaseTable"; 5 | 6 | 7 | export { BaseChart, BaseMap, BaseTable}; 8 | -------------------------------------------------------------------------------- /src/browser/img/more-h.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/sdk/constants.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Constants for Amazon S3 Compatible Cloud Storage 3 | */ 4 | 5 | export const JSON_RPC_VERSION = '2.0' 6 | export const UI_VERSION = '2018-09-20T05:24:40Z' // We are not dealing with it so make it constant for the time being 7 | export const RESPONSE_ID = 1 -------------------------------------------------------------------------------- /src/browser/less/inc/animate/animate.less: -------------------------------------------------------------------------------- 1 | .animated{ 2 | &.infinite { 3 | .animation-iteration-count(infinite); 4 | } 5 | } 6 | 7 | @import 'fadeIn'; 8 | @import 'fadeInDown'; 9 | @import 'fadeInUp'; 10 | @import 'fadeOut'; 11 | @import 'fadeOutDown'; 12 | @import 'fadeOutUp'; 13 | @import 'zoomIn'; 14 | -------------------------------------------------------------------------------- /font-awesome/HELP-US-OUT.txt: -------------------------------------------------------------------------------- 1 | I hope you love Font Awesome. If you've found it useful, please do me a favor and check out my latest project, 2 | Fort Awesome (https://fortawesome.com). It makes it easy to put the perfect icons on your website. Choose from our awesome, 3 | comprehensive icon sets or copy and paste your own. 4 | 5 | Please. Check it out. 6 | 7 | -Dave Gandy 8 | -------------------------------------------------------------------------------- /font-awesome/less/larger.less: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .@{fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .@{fa-css-prefix}-2x { font-size: 2em; } 11 | .@{fa-css-prefix}-3x { font-size: 3em; } 12 | .@{fa-css-prefix}-4x { font-size: 4em; } 13 | .@{fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /font-awesome/scss/_larger.scss: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .#{$fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .#{$fa-css-prefix}-2x { font-size: 2em; } 11 | .#{$fa-css-prefix}-3x { font-size: 3em; } 12 | .#{$fa-css-prefix}-4x { font-size: 4em; } 13 | .#{$fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /src/browser/less/inc/browser.less: -------------------------------------------------------------------------------- 1 | .meta-image { 2 | width: 180px; 3 | height: 180px; 4 | } 5 | 6 | .table-background { 7 | background-color: rgba(255, 255, 255, 0.7); 8 | } 9 | 10 | .meta-container { 11 | position: relative; 12 | height: 100%; 13 | width: 100%; 14 | } 15 | 16 | .chart-menu { 17 | font-size: 80%; 18 | text-align:right; 19 | } 20 | 21 | .meta-header-height{ 22 | @media (min-width: @screen-md-min) { 23 | height:150px; 24 | } 25 | } -------------------------------------------------------------------------------- /font-awesome/less/list.less: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: @fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .@{fa-css-prefix}-li { 11 | position: absolute; 12 | left: -@fa-li-width; 13 | width: @fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.@{fa-css-prefix}-lg { 17 | left: (-@fa-li-width + (4em / 14)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /font-awesome/scss/_list.scss: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: $fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .#{$fa-css-prefix}-li { 11 | position: absolute; 12 | left: -$fa-li-width; 13 | width: $fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.#{$fa-css-prefix}-lg { 17 | left: -$fa-li-width + (4em / 14); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/browser/less/inc/animate/zoomIn.less: -------------------------------------------------------------------------------- 1 | @-webkit-keyframes zoomIn { 2 | from { 3 | opacity: 0; 4 | -webkit-transform: scale3d(.3, .3, .3); 5 | transform: scale3d(.3, .3, .3); 6 | } 7 | 8 | 50% { 9 | opacity: 1; 10 | } 11 | } 12 | 13 | @keyframes zoomIn { 14 | from { 15 | opacity: 0; 16 | -webkit-transform: scale3d(.3, .3, .3); 17 | transform: scale3d(.3, .3, .3); 18 | } 19 | 20 | 50% { 21 | opacity: 1; 22 | } 23 | } -------------------------------------------------------------------------------- /font-awesome/less/core.less: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix} { 5 | display: inline-block; 6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/browser/less/inc/base.less: -------------------------------------------------------------------------------- 1 | * { 2 | -webkit-font-smoothing: antialiased; 3 | -moz-osx-font-smoothing: grayscale; 4 | 5 | &:focus, 6 | &:active { 7 | outline: 0; 8 | } 9 | } 10 | 11 | html { 12 | font-size: 10px; 13 | -webkit-tap-highlight-color: rgba(0,0,0,0); 14 | } 15 | 16 | html, 17 | body { 18 | min-height: 100%; 19 | } 20 | 21 | a { 22 | .transition(color); 23 | .transition-duration(300ms); 24 | 25 | } 26 | 27 | button { 28 | border: 0; 29 | } 30 | 31 | 32 | -------------------------------------------------------------------------------- /font-awesome/scss/_core.scss: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix} { 5 | display: inline-block; 6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /font-awesome/scss/font-awesome.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables"; 7 | @import "mixins"; 8 | @import "path"; 9 | @import "core"; 10 | @import "larger"; 11 | @import "fixed-width"; 12 | @import "list"; 13 | @import "bordered-pulled"; 14 | @import "animated"; 15 | @import "rotated-flipped"; 16 | @import "stacked"; 17 | @import "icons"; 18 | @import "screen-reader"; 19 | -------------------------------------------------------------------------------- /src/browser/less/inc/animate/fadeIn.less: -------------------------------------------------------------------------------- 1 | @-webkit-keyframes fadeIn { 2 | 0% {opacity: 0;} 3 | 100% {opacity: 1;} 4 | } 5 | 6 | @-moz-keyframes fadeIn { 7 | 0% {opacity: 0;} 8 | 100% {opacity: 1;} 9 | } 10 | 11 | @-o-keyframes fadeIn { 12 | 0% {opacity: 0;} 13 | 100% {opacity: 1;} 14 | } 15 | 16 | @keyframes fadeIn { 17 | 0% {opacity: 0;} 18 | 100% {opacity: 1;} 19 | } 20 | 21 | .fadeIn { 22 | -webkit-animation-name: fadeIn; 23 | -moz-animation-name: fadeIn; 24 | -o-animation-name: fadeIn; 25 | animation-name: fadeIn; 26 | } -------------------------------------------------------------------------------- /src/browser/less/inc/animate/fadeOut.less: -------------------------------------------------------------------------------- 1 | @-webkit-keyframes fadeOut { 2 | 0% {opacity: 1;} 3 | 100% {opacity: 0;} 4 | } 5 | 6 | @-moz-keyframes fadeOut { 7 | 0% {opacity: 1;} 8 | 100% {opacity: 0;} 9 | } 10 | 11 | @-o-keyframes fadeOut { 12 | 0% {opacity: 1;} 13 | 100% {opacity: 0;} 14 | } 15 | 16 | @keyframes fadeOut { 17 | 0% {opacity: 1;} 18 | 100% {opacity: 0;} 19 | } 20 | 21 | .fadeOut { 22 | -webkit-animation-name: fadeOut; 23 | -moz-animation-name: fadeOut; 24 | -o-animation-name: fadeOut; 25 | animation-name: fadeOut; 26 | } -------------------------------------------------------------------------------- /src/browser/js/dashboardStatus/DashboardStatusMainContent.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import MobileHeader from "../browser/MobileHeader"; 4 | import Header from "../browser/Header"; 5 | import web from "../web"; 6 | import DashboardStatusSection from "./DashboardStatusSection"; 7 | 8 | const DashboardStatusMainContent = () => ( 9 |
10 | {web.LoggedIn() && } 11 |
12 | 13 |
14 | ); 15 | 16 | export default DashboardStatusMainContent; 17 | -------------------------------------------------------------------------------- /src/browser/js/dashboardStatus/DashboardStatus.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import SideBar from "../browser/SideBar"; 4 | import AlertContainer from "../alert/AlertContainer"; 5 | import DashboardStatusMainContent from "./DashboardStatusMainContent"; 6 | import DeviceFileModal from "../browser/DeviceFileModal" 7 | 8 | const DashboardStatus = () => ( 9 |
10 | 11 | 12 | 13 | 14 |
15 | ); 16 | 17 | export default DashboardStatus; 18 | -------------------------------------------------------------------------------- /simple-editor.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs-extra"); 2 | const path = require("path"); 3 | 4 | const bundlePath = path.join(__dirname, "/simple/bundle.js"); 5 | const htmlPath = path.join(__dirname, "/simple/index.html"); 6 | try { 7 | const html = fs.openSync(htmlPath, "a"); 8 | const bundle = fs.readFileSync(bundlePath, "utf8"); 9 | fs.appendFileSync(html, ``, "utf8"); 10 | fs.unlinkSync(bundlePath); 11 | console.log("Simple editor build successfully"); 12 | } catch (error) { 13 | console.log(error); 14 | process.exit(0); 15 | } 16 | -------------------------------------------------------------------------------- /font-awesome/less/stacked.less: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; } 21 | -------------------------------------------------------------------------------- /font-awesome/scss/_stacked.scss: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; } 21 | -------------------------------------------------------------------------------- /font-awesome/less/font-awesome.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables.less"; 7 | @import "mixins.less"; 8 | @import "path.less"; 9 | @import "core.less"; 10 | @import "larger.less"; 11 | @import "fixed-width.less"; 12 | @import "list.less"; 13 | @import "bordered-pulled.less"; 14 | @import "animated.less"; 15 | @import "rotated-flipped.less"; 16 | @import "stacked.less"; 17 | @import "icons.less"; 18 | @import "screen-reader.less"; 19 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | const esModules = ['crc'].join('|'); 2 | 3 | module.exports = { 4 | verbose: true, 5 | setupTestFrameworkScriptFile: "/src/browser/js/jest/setup.js", 6 | testMatch: [ 7 | "**/**/__tests__/**/*.(js)" 8 | ], 9 | testURL: "https://localhost:8080", 10 | moduleNameMapper: { 11 | "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "/src/browser/js/jest/__mocks__/fileMock.js", 12 | "\\.(css|scss)$": "identity-obj-proxy" 13 | }, 14 | transformIgnorePatterns: [`/node_modules/(?!${esModules})`] 15 | } -------------------------------------------------------------------------------- /src/browser/img/select-caret.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /font-awesome/.npmignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.egg-info 3 | *.db 4 | *.db.old 5 | *.swp 6 | *.db-journal 7 | 8 | .coverage 9 | .DS_Store 10 | .installed.cfg 11 | _gh_pages/* 12 | 13 | .idea/* 14 | .svn/* 15 | src/website/static/* 16 | src/website/media/* 17 | 18 | bin 19 | cfcache 20 | develop-eggs 21 | dist 22 | downloads 23 | eggs 24 | parts 25 | tmp 26 | .sass-cache 27 | node_modules 28 | 29 | src/website/settingslocal.py 30 | stunnel.log 31 | 32 | .ruby-version 33 | 34 | # don't need these in the npm package. 35 | src/ 36 | _config.yml 37 | bower.json 38 | component.json 39 | composer.json 40 | CONTRIBUTING.md 41 | Gemfile 42 | Gemfile.lock 43 | -------------------------------------------------------------------------------- /src/sdk/response.js: -------------------------------------------------------------------------------- 1 | /** 2 | * StorageResponses receives response from storage API 3 | * and formats it to match the structure required by Browser UI 4 | * e.g response = { 'jsonrpc' : 2.0, result: { FETCHED_RESULT }, id: 1} 5 | */ 6 | 7 | import { JSON_RPC_VERSION, UI_VERSION, RESPONSE_ID } from './constants' 8 | 9 | const storageResponses = { 10 | makeDefaultResponse: (key, result) => { 11 | let response = { 12 | "jsonrpc": JSON_RPC_VERSION, 13 | "result": {}, 14 | "id": RESPONSE_ID 15 | } 16 | 17 | response.result[key] = result 18 | response.result['uiVersion'] = UI_VERSION 19 | return response 20 | } 21 | } 22 | 23 | export default storageResponses 24 | 25 | -------------------------------------------------------------------------------- /font-awesome/less/bordered-pulled.less: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em @fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .@{fa-css-prefix}-pull-left { float: left; } 11 | .@{fa-css-prefix}-pull-right { float: right; } 12 | 13 | .@{fa-css-prefix} { 14 | &.@{fa-css-prefix}-pull-left { margin-right: .3em; } 15 | &.@{fa-css-prefix}-pull-right { margin-left: .3em; } 16 | } 17 | 18 | /* Deprecated as of 4.4.0 */ 19 | .pull-right { float: right; } 20 | .pull-left { float: left; } 21 | 22 | .@{fa-css-prefix} { 23 | &.pull-left { margin-right: .3em; } 24 | &.pull-right { margin-left: .3em; } 25 | } 26 | -------------------------------------------------------------------------------- /font-awesome/scss/_bordered-pulled.scss: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em $fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .#{$fa-css-prefix}-pull-left { float: left; } 11 | .#{$fa-css-prefix}-pull-right { float: right; } 12 | 13 | .#{$fa-css-prefix} { 14 | &.#{$fa-css-prefix}-pull-left { margin-right: .3em; } 15 | &.#{$fa-css-prefix}-pull-right { margin-left: .3em; } 16 | } 17 | 18 | /* Deprecated as of 4.4.0 */ 19 | .pull-right { float: right; } 20 | .pull-left { float: left; } 21 | 22 | .#{$fa-css-prefix} { 23 | &.pull-left { margin-right: .3em; } 24 | &.pull-right { margin-left: .3em; } 25 | } 26 | -------------------------------------------------------------------------------- /font-awesome/less/rotated-flipped.less: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); } 5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); } 6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); } 7 | 8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); } 9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); } 10 | 11 | // Hook for IE8-9 12 | // ------------------------- 13 | 14 | :root .@{fa-css-prefix}-rotate-90, 15 | :root .@{fa-css-prefix}-rotate-180, 16 | :root .@{fa-css-prefix}-rotate-270, 17 | :root .@{fa-css-prefix}-flip-horizontal, 18 | :root .@{fa-css-prefix}-flip-vertical { 19 | filter: none; 20 | } 21 | -------------------------------------------------------------------------------- /font-awesome/scss/_rotated-flipped.scss: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } 5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } 6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } 7 | 8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } 9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } 10 | 11 | // Hook for IE8-9 12 | // ------------------------- 13 | 14 | :root .#{$fa-css-prefix}-rotate-90, 15 | :root .#{$fa-css-prefix}-rotate-180, 16 | :root .#{$fa-css-prefix}-rotate-270, 17 | :root .#{$fa-css-prefix}-flip-horizontal, 18 | :root .#{$fa-css-prefix}-flip-vertical { 19 | filter: none; 20 | } 21 | -------------------------------------------------------------------------------- /src/browser/img/arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/browser/js/alertModals/actions.js: -------------------------------------------------------------------------------- 1 | export const ADD_QUEUE = "alertModals/ADD_QUEUE"; 2 | export const STOP_QUEUE = "alertModals/STOP_QUEUE"; 3 | export const UPDATE_QUEUE = "alertModal/UPDATE_QUEUE"; 4 | export const SHOW_ABORT_MODAL = "alertModal/SHOW_ABORT_MODAL"; 5 | 6 | export const AddQueue = (modal, slug, size, name) => ({ 7 | type: ADD_QUEUE, 8 | modal, 9 | slug, 10 | size, 11 | name 12 | }); 13 | 14 | export const stopQueue = slug => ({ 15 | type: STOP_QUEUE, 16 | slug 17 | }); 18 | 19 | export const updateQueue = (slug, loaded) => ({ 20 | type: UPDATE_QUEUE, 21 | slug, 22 | loaded 23 | }); 24 | 25 | export const showAbortModal = () => ({ 26 | type: SHOW_ABORT_MODAL, 27 | show: true 28 | }); 29 | 30 | export const hideAbortModal = () => ({ 31 | type: SHOW_ABORT_MODAL, 32 | show: false 33 | }); 34 | -------------------------------------------------------------------------------- /font-awesome/less/path.less: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}'); 7 | src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'), 8 | url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'), 9 | url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'), 10 | url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'), 11 | url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg'); 12 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | -------------------------------------------------------------------------------- /src/browser/js/alertModals/ObjectDeleteModal.js: -------------------------------------------------------------------------------- 1 | /** 2 | * CANcloud cloud storage browser 3 | * Progress Modal for Delete objects from the cloud storage 4 | */ 5 | 6 | import React from "react"; 7 | import { ProgressBar } from "react-bootstrap"; 8 | 9 | class ObjectDeleteModal extends React.Component { 10 | render() { 11 | const { progress, roundOffProgress, progressModalText } = this.props; 12 | 13 | return ( 14 |
15 |
16 | {progressModalText} 17 |
18 | 19 |
20 | {roundOffProgress} % 21 |
22 |
23 | ); 24 | } 25 | } 26 | 27 | export default ObjectDeleteModal; 28 | -------------------------------------------------------------------------------- /font-awesome/scss/_path.scss: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}'); 7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'), 8 | url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'), 9 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'), 10 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'), 11 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg'); 12 | // src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | -------------------------------------------------------------------------------- /src/browser/js/jest/setup.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Minio Cloud Storage (C) 2018 Minio, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import "jest-enzyme" 18 | import { configure } from "enzyme" 19 | import Adapter from "enzyme-adapter-react-16" 20 | 21 | configure({ adapter: new Adapter() }) 22 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Use Node.js version 18 on Debian Bullseye 2 | FROM node:18-bullseye 3 | 4 | # The /app directory should act as the main application directory 5 | WORKDIR /app 6 | 7 | # Copy the app package and package-lock.json file 8 | COPY package*.json ./ 9 | 10 | # Install node packages 11 | RUN npm install --ignore-scripts 12 | 13 | # Copy Webpack configuration, Babel configuration, and source files 14 | COPY webpack.config.js .babelrc ./ 15 | COPY ./src ./src 16 | 17 | 18 | # Install the `serve` package globally to run the application 19 | RUN npm install -g serve 20 | 21 | # Set the environment variable to resolve the OpenSSL issue 22 | ENV NODE_OPTIONS=--openssl-legacy-provider 23 | 24 | # Build the app 25 | RUN npm run build 26 | 27 | # Expose the port (example: 3000) 28 | EXPOSE 3000 29 | 30 | # Start the app using the `serve` command 31 | CMD ["serve", "-s", "site"] -------------------------------------------------------------------------------- /font-awesome/less/animated.less: -------------------------------------------------------------------------------- 1 | // Animated Icons 2 | // -------------------------- 3 | 4 | .@{fa-css-prefix}-spin { 5 | -webkit-animation: fa-spin 2s infinite linear; 6 | animation: fa-spin 2s infinite linear; 7 | } 8 | 9 | .@{fa-css-prefix}-pulse { 10 | -webkit-animation: fa-spin 1s infinite steps(8); 11 | animation: fa-spin 1s infinite steps(8); 12 | } 13 | 14 | @-webkit-keyframes fa-spin { 15 | 0% { 16 | -webkit-transform: rotate(0deg); 17 | transform: rotate(0deg); 18 | } 19 | 100% { 20 | -webkit-transform: rotate(359deg); 21 | transform: rotate(359deg); 22 | } 23 | } 24 | 25 | @keyframes fa-spin { 26 | 0% { 27 | -webkit-transform: rotate(0deg); 28 | transform: rotate(0deg); 29 | } 30 | 100% { 31 | -webkit-transform: rotate(359deg); 32 | transform: rotate(359deg); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /font-awesome/scss/_animated.scss: -------------------------------------------------------------------------------- 1 | // Spinning Icons 2 | // -------------------------- 3 | 4 | .#{$fa-css-prefix}-spin { 5 | -webkit-animation: fa-spin 2s infinite linear; 6 | animation: fa-spin 2s infinite linear; 7 | } 8 | 9 | .#{$fa-css-prefix}-pulse { 10 | -webkit-animation: fa-spin 1s infinite steps(8); 11 | animation: fa-spin 1s infinite steps(8); 12 | } 13 | 14 | @-webkit-keyframes fa-spin { 15 | 0% { 16 | -webkit-transform: rotate(0deg); 17 | transform: rotate(0deg); 18 | } 19 | 100% { 20 | -webkit-transform: rotate(359deg); 21 | transform: rotate(359deg); 22 | } 23 | } 24 | 25 | @keyframes fa-spin { 26 | 0% { 27 | -webkit-transform: rotate(0deg); 28 | transform: rotate(0deg); 29 | } 30 | 100% { 31 | -webkit-transform: rotate(359deg); 32 | transform: rotate(359deg); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/browser/img/more-h-light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/browser/js/history.js: -------------------------------------------------------------------------------- 1 | /* 2 | * MinIO Cloud Storage (C) 2016, 2018 MinIO, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import createHistory from "history/createHashHistory"; 18 | import { minioBrowserPrefix } from "./constants"; 19 | 20 | const history = createHistory({ 21 | basename: minioBrowserPrefix 22 | }); 23 | 24 | export default history; 25 | -------------------------------------------------------------------------------- /src/browser/js/browser/__tests__/Host.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * MinIO Cloud Storage (C) 2016, 2018 MinIO, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | import React from "react" 19 | import { shallow } from "enzyme" 20 | import Host from "../Host" 21 | 22 | describe("Host", () => { 23 | it("should render without crashing", () => { 24 | shallow() 25 | }) 26 | }) 27 | -------------------------------------------------------------------------------- /src/browser/js/__tests__/jsonrpc-test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Minio Cloud Storage (C) 2016 Minio, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import JSONrpc from "../jsonrpc" 18 | 19 | describe("jsonrpc", () => { 20 | it("should succeed with valid endpoint", () => { 21 | let jsonRPC = new JSONrpc({ 22 | 23 | }) 24 | expect(jsonRPC.version).toEqual("2.0") 25 | }) 26 | }) 27 | -------------------------------------------------------------------------------- /src/browser/js/browser/__tests__/MainContent.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * MinIO Cloud Storage (C) 2016, 2018 MinIO, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react" 18 | import { shallow } from "enzyme" 19 | import MainContent from "../MainContent" 20 | 21 | describe("MainContent", () => { 22 | it("should render without crashing", () => { 23 | shallow() 24 | }) 25 | }) 26 | -------------------------------------------------------------------------------- /src/browser/js/objects/selectors.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Minio Cloud Storage (C) 2018 Minio, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { createSelector } from "reselect"; 18 | 19 | export const getCurrentPrefix = state => state.objects.currentPrefix; 20 | 21 | export const getCheckedList = state => state.objects.checkedList; 22 | 23 | export const getPrefixWritable = state => state.objects.prefixWritable; 24 | -------------------------------------------------------------------------------- /src/browser/less/inc/animate/fadeOutUp.less: -------------------------------------------------------------------------------- 1 | @-webkit-keyframes fadeOutUp { 2 | 0% { 3 | opacity: 1; 4 | -webkit-transform: translateY(0); 5 | } 6 | 7 | 100% { 8 | opacity: 0; 9 | -webkit-transform: translateY(-20px); 10 | } 11 | } 12 | @-moz-keyframes fadeOutUp { 13 | 0% { 14 | opacity: 1; 15 | -moz-transform: translateY(0); 16 | } 17 | 18 | 100% { 19 | opacity: 0; 20 | -moz-transform: translateY(-20px); 21 | } 22 | } 23 | @-o-keyframes fadeOutUp { 24 | 0% { 25 | opacity: 1; 26 | -o-transform: translateY(0); 27 | } 28 | 29 | 100% { 30 | opacity: 0; 31 | -o-transform: translateY(-20px); 32 | } 33 | } 34 | @keyframes fadeOutUp { 35 | 0% { 36 | opacity: 1; 37 | transform: translateY(0); 38 | } 39 | 40 | 100% { 41 | opacity: 0; 42 | transform: translateY(-20px); 43 | } 44 | } 45 | 46 | .fadeOutUp { 47 | -webkit-animation-name: fadeOutUp; 48 | -moz-animation-name: fadeOutUp; 49 | -o-animation-name: fadeOutUp; 50 | animation-name: fadeOutUp; 51 | } -------------------------------------------------------------------------------- /src/sdk/aws-sdk-client.js: -------------------------------------------------------------------------------- 1 | import AWS from "aws-sdk"; 2 | 3 | class AwsSdk { 4 | constructor(accessKeyId, secretAccessKey, endpoint) { 5 | this.aws3 = new AWS.S3({ 6 | accessKeyId, 7 | secretAccessKey, 8 | endpoint, 9 | s3ForcePathStyle: true 10 | }); 11 | } 12 | 13 | selectObjectContent(params) { 14 | return new Promise((resolve, reject) => { 15 | this.aws3.selectObjectContent(params, (err, data) => { 16 | if (err) { 17 | reject(err); 18 | } else { 19 | let result = ""; 20 | const events = data.Payload; 21 | for (const event of events) { 22 | if (event.Records) { 23 | result = result.concat(event.Records.Payload.toString()); 24 | } else if (event.Stats) { 25 | } else if (event.End) { 26 | resolve(result); 27 | } 28 | } 29 | } 30 | }); 31 | }); 32 | } 33 | } 34 | 35 | export default AwsSdk; 36 | -------------------------------------------------------------------------------- /src/browser/js/objects/__tests__/ObjectsSection.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * MinIO Cloud Storage (C) 2016, 2018 MinIO, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react" 18 | import { shallow } from "enzyme" 19 | import { ObjectsSection } from "../ObjectsSection" 20 | 21 | describe("ObjectsSection", () => { 22 | it("should render without crashing", () => { 23 | shallow() 24 | }) 25 | }) 26 | -------------------------------------------------------------------------------- /src/browser/less/inc/animate/fadeInUp.less: -------------------------------------------------------------------------------- 1 | @-webkit-keyframes fadeInUp { 2 | 0% { 3 | opacity: 0; 4 | -webkit-transform: translateY(20px); 5 | } 6 | 7 | 100% { 8 | opacity: 1; 9 | -webkit-transform: translateY(0); 10 | } 11 | } 12 | 13 | @-moz-keyframes fadeInUp { 14 | 0% { 15 | opacity: 0; 16 | -moz-transform: translateY(20px); 17 | } 18 | 19 | 100% { 20 | opacity: 1; 21 | -moz-transform: translateY(0); 22 | } 23 | } 24 | 25 | @-o-keyframes fadeInUp { 26 | 0% { 27 | opacity: 0; 28 | -o-transform: translateY(20px); 29 | } 30 | 31 | 100% { 32 | opacity: 1; 33 | -o-transform: translateY(0); 34 | } 35 | } 36 | 37 | @keyframes fadeInUp { 38 | 0% { 39 | opacity: 0; 40 | transform: translateY(20px); 41 | } 42 | 43 | 100% { 44 | opacity: 1; 45 | transform: translateY(0); 46 | } 47 | } 48 | 49 | .fadeInUp { 50 | -webkit-animation-name: fadeInUp; 51 | -moz-animation-name: fadeInUp; 52 | -o-animation-name: fadeInUp; 53 | animation-name: fadeInUp; 54 | } -------------------------------------------------------------------------------- /src/browser/less/inc/animate/fadeInDown.less: -------------------------------------------------------------------------------- 1 | @-webkit-keyframes fadeInDown { 2 | 0% { 3 | opacity: 0; 4 | -webkit-transform: translateY(-20px); 5 | } 6 | 7 | 100% { 8 | opacity: 1; 9 | -webkit-transform: translateY(0); 10 | } 11 | } 12 | 13 | @-moz-keyframes fadeInDown { 14 | 0% { 15 | opacity: 0; 16 | -moz-transform: translateY(-20px); 17 | } 18 | 19 | 100% { 20 | opacity: 1; 21 | -moz-transform: translateY(0); 22 | } 23 | } 24 | 25 | @-o-keyframes fadeInDown { 26 | 0% { 27 | opacity: 0; 28 | -ms-transform: translateY(-20px); 29 | } 30 | 31 | 100% { 32 | opacity: 1; 33 | -ms-transform: translateY(0); 34 | } 35 | } 36 | 37 | @keyframes fadeInDown { 38 | 0% { 39 | opacity: 0; 40 | transform: translateY(-20px); 41 | } 42 | 43 | 100% { 44 | opacity: 1; 45 | transform: translateY(0); 46 | } 47 | } 48 | 49 | .fadeInDown { 50 | -webkit-animation-name: fadeInDown; 51 | -moz-animation-name: fadeInDown; 52 | -o-animation-name: fadeInDown; 53 | animation-name: fadeInDown; 54 | } -------------------------------------------------------------------------------- /src/browser/less/inc/animate/fadeOutDown.less: -------------------------------------------------------------------------------- 1 | @-webkit-keyframes fadeOutDown { 2 | 0% { 3 | opacity: 1; 4 | -webkit-transform: translateY(0); 5 | } 6 | 7 | 100% { 8 | opacity: 0; 9 | -webkit-transform: translateY(20px); 10 | } 11 | } 12 | 13 | @-moz-keyframes fadeOutDown { 14 | 0% { 15 | opacity: 1; 16 | -moz-transform: translateY(0); 17 | } 18 | 19 | 100% { 20 | opacity: 0; 21 | -moz-transform: translateY(20px); 22 | } 23 | } 24 | 25 | @-o-keyframes fadeOutDown { 26 | 0% { 27 | opacity: 1; 28 | -o-transform: translateY(0); 29 | } 30 | 31 | 100% { 32 | opacity: 0; 33 | -o-transform: translateY(20px); 34 | } 35 | } 36 | 37 | @keyframes fadeOutDown { 38 | 0% { 39 | opacity: 1; 40 | transform: translateY(0); 41 | } 42 | 43 | 100% { 44 | opacity: 0; 45 | transform: translateY(20px); 46 | } 47 | } 48 | 49 | .fadeOutDown { 50 | -webkit-animation-name: fadeOutDown; 51 | -moz-animation-name: fadeOutDown; 52 | -o-animation-name: fadeOutDown; 53 | animation-name: fadeOutDown; 54 | } -------------------------------------------------------------------------------- /src/browser/js/loader.js: -------------------------------------------------------------------------------- 1 | /* 2 | * MinIO Cloud Storage (C) 2016, 2018 MinIO, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | let delay = [0, 400]; 18 | 19 | function handleLoader(i) { 20 | if (i < 2) { 21 | setTimeout(function() { 22 | document.querySelector(".page-load").classList.add("pl-" + i); 23 | handleLoader(i + 1); 24 | }, delay[i]); 25 | } 26 | } 27 | 28 | const hideLoader = () => handleLoader(0); 29 | 30 | export default hideLoader; 31 | -------------------------------------------------------------------------------- /src/browser/js/browser/Host.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Minio Cloud Storage (C) 2016, 2018 Minio, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react"; 18 | 19 | export const Host = ({ endPoint, bucketName }) => ( 20 |
21 |
22 | {endPoint} 23 |
24 | {bucketName} 25 |
26 |
27 | ); 28 | 29 | export default Host; 30 | -------------------------------------------------------------------------------- /src/browser/js/browser/__tests__/Browser.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * MinIO Cloud Storage (C) 2016, 2018 MinIO, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react" 18 | import { shallow } from "enzyme" 19 | import Browser from "../Browser" 20 | import configureStore from "redux-mock-store" 21 | 22 | const mockStore = configureStore() 23 | 24 | describe("Browser", () => { 25 | it("should render without crashing", () => { 26 | const store = mockStore() 27 | shallow() 28 | }) 29 | }) 30 | -------------------------------------------------------------------------------- /src/browser/js/store/configure-store.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Minio Cloud Storage (C) 2018 Minio, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { createStore, applyMiddleware } from "redux"; 18 | import thunkMiddleware from "redux-thunk"; 19 | import reducers from "../reducers"; 20 | 21 | const createStoreWithMiddleware = applyMiddleware(thunkMiddleware)(createStore); 22 | 23 | export default function configureStore(initialState) { 24 | const store = createStoreWithMiddleware(reducers, initialState); 25 | return store; 26 | } 27 | -------------------------------------------------------------------------------- /src/browser/js/alert/Alert.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Minio Cloud Storage (C) 2018 Minio, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react"; 18 | import AlertComponent from "react-bootstrap/lib/Alert"; 19 | 20 | const Alert = ({ show, type, message, onDismiss }) => ( 21 | 26 |
{message}
27 |
28 | ); 29 | 30 | export default Alert; 31 | -------------------------------------------------------------------------------- /src/browser/js/objects/ObjectsSection.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Minio Cloud Storage (C) 2018 Minio, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react"; 18 | import ObjectsHeader from "./ObjectsHeader"; 19 | import ObjectsListContainer from "./ObjectsListContainer"; 20 | 21 | export class ObjectsSection extends React.Component { 22 | render() { 23 | return ( 24 |
25 | 26 | 27 | 28 | 29 |
30 | ); 31 | } 32 | } 33 | 34 | export default ObjectsSection; 35 | -------------------------------------------------------------------------------- /src/browser/js/buckets/__tests__/BucketSearch.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * MinIO Cloud Storage (C) 2016, 2018 MinIO, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react" 18 | import { shallow } from "enzyme" 19 | import { BucketSearch } from "../BucketSearch" 20 | 21 | describe("BucketSearch", () => { 22 | it("should render without crashing", () => { 23 | shallow() 24 | }) 25 | 26 | it("should call onChange with search text", () => { 27 | const onChange = jest.fn() 28 | const wrapper = shallow() 29 | wrapper.find("input").simulate("change", { target: { value: "test" } }) 30 | expect(onChange).toHaveBeenCalledWith("test") 31 | }) 32 | }) 33 | -------------------------------------------------------------------------------- /src/browser/js/objects/DeleteObjectConfirmModal.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Minio Cloud Storage (C) 2018 Minio, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react"; 18 | import ConfirmModal from "../browser/ConfirmModal"; 19 | 20 | export const DeleteObjectConfirmModal = ({ 21 | deleteObject, 22 | hideDeleteConfirmModal 23 | }) => ( 24 | 34 | ); 35 | 36 | export default DeleteObjectConfirmModal; 37 | -------------------------------------------------------------------------------- /src/browser/js/alert/__tests___/Alert.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Minio Cloud Storage (C) 2018 Minio, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react" 18 | import { shallow, mount } from "enzyme" 19 | import Alert from "../Alert" 20 | 21 | describe("Alert", () => { 22 | it("should render without crashing", () => { 23 | shallow() 24 | }) 25 | 26 | it("should call onDismiss when close button is clicked", () => { 27 | const onDismiss = jest.fn() 28 | const wrapper = mount( 29 | 30 | ) 31 | wrapper.find("button").simulate("click", { preventDefault: jest.fn() }) 32 | expect(onDismiss).toHaveBeenCalled() 33 | }) 34 | }) 35 | -------------------------------------------------------------------------------- /src/browser/js/alert/__tests___/AlertContainer.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Minio Cloud Storage (C) 2018 Minio, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react" 18 | import { shallow, mount } from "enzyme" 19 | import { AlertContainer } from "../AlertContainer" 20 | 21 | describe("Alert", () => { 22 | it("should render without crashing", () => { 23 | shallow( 24 | 25 | ) 26 | }) 27 | 28 | it("should render nothing if message is empty", () => { 29 | const wrapper = shallow( 30 | 31 | ) 32 | expect(wrapper.find("Alert").length).toBe(0) 33 | }) 34 | }) 35 | -------------------------------------------------------------------------------- /src/browser/js/buckets/BucketContainer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Minio Cloud Storage (C) 2018 Minio, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react"; 18 | import { connect } from "react-redux"; 19 | import * as actionsBuckets from "./actions"; 20 | import { getCurrentBucket } from "./selectors"; 21 | import Bucket from "./Bucket"; 22 | 23 | const mapStateToProps = (state, ownProps) => { 24 | return { 25 | isActive: getCurrentBucket(state) === ownProps.bucket 26 | }; 27 | }; 28 | 29 | const mapDispatchToProps = dispatch => { 30 | return { 31 | selectBucket: bucket => dispatch(actionsBuckets.selectBucket(bucket)) 32 | }; 33 | }; 34 | 35 | export default connect( 36 | mapStateToProps, 37 | mapDispatchToProps 38 | )(Bucket); 39 | -------------------------------------------------------------------------------- /src/browser/js/alert/reducer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Minio Cloud Storage (C) 2018 Minio, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import * as actionsAlert from "./actions"; 18 | 19 | const initialState = { 20 | show: false, 21 | type: "danger" 22 | }; 23 | export default (state = initialState, action) => { 24 | switch (action.type) { 25 | case actionsAlert.SET: 26 | return { 27 | show: true, 28 | id: action.alert.id, 29 | type: action.alert.type, 30 | message: action.alert.message 31 | }; 32 | case actionsAlert.CLEAR: 33 | if (action.alert && action.alert.id != state.id) { 34 | return state; 35 | } else { 36 | return initialState; 37 | } 38 | default: 39 | return state; 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /src/browser/js/reducers.js: -------------------------------------------------------------------------------- 1 | /* 2 | * MinIO Cloud Storage (C) 2016, 2018 MinIO, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { combineReducers } from "redux"; 18 | import browser from "./browser/reducer"; 19 | import alert from "./alert/reducer"; 20 | import buckets from "./buckets/reducer"; 21 | import objects from "./objects/reducer"; 22 | import uploads from "./uploads/reducer"; 23 | import {editor} from "config-editor-base" 24 | import alertModals from "./alertModals/reducer"; 25 | import dashboardStatus from "./dashboardStatus/reducer"; 26 | 27 | 28 | const rootReducer = combineReducers({ 29 | browser, 30 | alert, 31 | buckets, 32 | objects, 33 | uploads, 34 | editor, 35 | dashboardStatus, 36 | alertModals 37 | }); 38 | 39 | export default rootReducer; 40 | -------------------------------------------------------------------------------- /src/browser/js/browser/DeviceTable.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { connect } from "react-redux"; 3 | 4 | export class DeviceTable extends React.Component { 5 | createTable = deviceFileContent => { 6 | let table = []; 7 | 8 | for (let i = 0; i < Object.keys(deviceFileContent).length; i++) { 9 | table.push( 10 | 11 | 12 | {JSON.stringify(Object.keys(deviceFileContent)[i]).replace( 13 | /"/g, 14 | "" 15 | )} 16 | 17 | 18 | {JSON.stringify(Object.values(deviceFileContent)[i]).replace( 19 | /"/g, 20 | "" 21 | )} 22 | 23 | 24 | ); 25 | } 26 | return table; 27 | }; 28 | 29 | render() { 30 | console.log(this.props.deviceFileContent) 31 | return ( 32 | 33 | 34 | {this.createTable(this.props.deviceFileContent)} 35 | 36 |
37 | ); 38 | } 39 | } 40 | 41 | function mapStateToProps(state) { 42 | return { 43 | deviceFileContent: state.browser.deviceFileContent 44 | }; 45 | } 46 | 47 | export default connect(mapStateToProps)(DeviceTable); 48 | -------------------------------------------------------------------------------- /src/browser/js/alert/actions.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Minio Cloud Storage (C) 2018 Minio, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export const SET = "alert/SET"; 18 | export const CLEAR = "alert/CLEAR"; 19 | 20 | export let alertId = 0; 21 | 22 | export const set = alert => { 23 | const id = alertId++; 24 | return dispatch => { 25 | if (alert.type !== "danger" || alert.autoClear) { 26 | setTimeout(() => { 27 | dispatch({ 28 | type: CLEAR, 29 | alert: { 30 | id 31 | } 32 | }); 33 | }, 5000); 34 | } 35 | dispatch({ 36 | type: SET, 37 | alert: Object.assign({}, alert, { 38 | id 39 | }) 40 | }); 41 | }; 42 | }; 43 | 44 | export const clear = () => { 45 | return { type: CLEAR }; 46 | }; 47 | -------------------------------------------------------------------------------- /src/browser/js/alertModals/ObjectTransferModal.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { ProgressBar } from "react-bootstrap"; 3 | 4 | import humanize from "humanize"; 5 | 6 | import AbortConfirmModal from "./AbortConfirmModal"; 7 | 8 | class ObjectTransferModal extends React.Component { 9 | render() { 10 | const { 11 | bytesTransfered, 12 | progress, 13 | roundOffProgress, 14 | progressModalText, 15 | isAborted, 16 | abortModal 17 | } = this.props; 18 | 19 | return ( 20 | 21 | {isAborted ? ( 22 | 23 | ) : ( 24 |
25 | 28 |
29 | {progressModalText} 30 |
31 | 32 |
33 | 34 | {humanize.filesize(bytesTransfered)} ({roundOffProgress} %) 35 | 36 |
37 |
38 | )} 39 |
40 | ); 41 | } 42 | } 43 | 44 | export default ObjectTransferModal; 45 | -------------------------------------------------------------------------------- /src/browser/js/App.js: -------------------------------------------------------------------------------- 1 | /* 2 | * MinIO Cloud Storage (C) 2016, 2018 MinIO, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react"; 18 | import { Route, Switch } from "react-router-dom"; 19 | 20 | import Editor from "./editorNew/Editor"; 21 | const Browser = require("./browser/Browser"); 22 | const Login = require("./browser/Login"); 23 | const DashboardStatus = require("./dashboardStatus"); 24 | 25 | export const App = () => { 26 | return ( 27 | 28 | 29 | 30 | 31 | 32 | 33 | ); 34 | }; 35 | 36 | export default App; 37 | -------------------------------------------------------------------------------- /src/browser/js/alert/AlertContainer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Minio Cloud Storage (C) 2018 Minio, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react"; 18 | import { connect } from "react-redux"; 19 | import Alert from "./Alert"; 20 | import * as alertActions from "./actions"; 21 | 22 | export const AlertContainer = ({ alert, clearAlert }) => { 23 | if (!alert.message) { 24 | return ""; 25 | } 26 | return ; 27 | }; 28 | 29 | const mapStateToProps = state => { 30 | return { 31 | alert: state.alert 32 | }; 33 | }; 34 | 35 | const mapDispatchToProps = dispatch => { 36 | return { 37 | clearAlert: () => dispatch(alertActions.clear()) 38 | }; 39 | }; 40 | 41 | export default connect( 42 | mapStateToProps, 43 | mapDispatchToProps 44 | )(AlertContainer); 45 | -------------------------------------------------------------------------------- /src/browser/js/constants.js: -------------------------------------------------------------------------------- 1 | /* 2 | * MinIO Cloud Storage (C) 2016, 2018 MinIO, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // File for all the browser constants. 18 | 19 | // minioBrowserPrefix absolute path. 20 | var p = window.location.pathname; 21 | //export const minioBrowserPrefix = p.slice(0, p.indexOf("/", 1)) 22 | export const minioBrowserPrefix = ""; 23 | export const READ_ONLY = "readonly"; 24 | export const WRITE_ONLY = "writeonly"; 25 | export const READ_WRITE = "readwrite"; 26 | export const NONE = "none"; 27 | export const SECRET_CODE = "cssbrowser"; 28 | export const SHARE_OBJECT_EXPIRY_DAYS = 5; 29 | export const SHARE_OBJECT_EXPIRY_HOURS = 0; 30 | export const SHARE_OBJECT_EXPIRY_MINUTES = 0; 31 | export const UPLOAD = "UPLOAD"; 32 | export const DELETE = "DELETE"; 33 | export const DOWNLOAD = "DOWNLOAD"; 34 | -------------------------------------------------------------------------------- /src/browser/js/alertModals/reducer.js: -------------------------------------------------------------------------------- 1 | import * as actionAlertModals from "./actions"; 2 | 3 | const add = (files, action) => ({ 4 | ...files, 5 | [action.slug]: { 6 | loaded: 0, 7 | size: action.size, 8 | name: action.name 9 | } 10 | }); 11 | 12 | const stop = (files, action) => { 13 | const newFiles = Object.assign({}, files); 14 | delete newFiles[action.slug]; 15 | return {}; 16 | }; 17 | 18 | const update = (files, action) => ({ 19 | ...files, 20 | [action.slug]: { 21 | ...files[action.slug], 22 | loaded: action.loaded 23 | } 24 | }); 25 | 26 | export default ( 27 | state = { 28 | files: {}, 29 | showAbortModal: false 30 | }, 31 | action 32 | ) => { 33 | switch (action.type) { 34 | case actionAlertModals.ADD_QUEUE: 35 | return { 36 | ...state, 37 | files: add(state.files, action), 38 | modal: action.modal 39 | }; 40 | case actionAlertModals.STOP_QUEUE: 41 | return { 42 | ...state, 43 | files: stop(state.files, action) 44 | }; 45 | case actionAlertModals.UPDATE_QUEUE: 46 | return { 47 | ...state, 48 | files: update(state.files, action) 49 | }; 50 | case actionAlertModals.SHOW_ABORT_MODAL: 51 | return { 52 | ...state, 53 | showAbortModal: action.show 54 | }; 55 | default: 56 | return state; 57 | } 58 | }; 59 | -------------------------------------------------------------------------------- /src/browser/js/browser/__tests__/MobileHeader.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * MinIO Cloud Storage (C) 2016, 2018 MinIO, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react" 18 | import { shallow } from "enzyme" 19 | import { MobileHeader } from "../MobileHeader" 20 | 21 | describe("Bucket", () => { 22 | it("should render without crashing", () => { 23 | shallow() 24 | }) 25 | 26 | it("should toggleSidebar when trigger is clicked", () => { 27 | const toggleSidebar = jest.fn() 28 | const wrapper = shallow( 29 | 30 | ) 31 | wrapper 32 | .find("#sidebar-toggle") 33 | .simulate("click", { stopPropagation: jest.fn() }) 34 | expect(toggleSidebar).toHaveBeenCalled() 35 | }) 36 | }) 37 | -------------------------------------------------------------------------------- /src/browser/less/inc/buttons.less: -------------------------------------------------------------------------------- 1 | .btn { 2 | border: 0; 3 | outline: none !important; 4 | padding: 5px 10px; 5 | font-size: 12px; 6 | line-height: 1.5; 7 | border-radius: 2px; 8 | text-align: center; 9 | .transition(all); 10 | .transition-duration(300ms); 11 | 12 | &:hover, 13 | &:focus { 14 | .opacity(0.9); 15 | } 16 | } 17 | 18 | /*----------------------------------- 19 | Button Variants 20 | ------------------------------------*/ 21 | .btn-variant(@bg-color, @color) { 22 | color: @color; 23 | background-color: @bg-color; 24 | 25 | &:hover, 26 | &:focus { 27 | color: @color; 28 | background-color: darken(@bg-color, 6%); 29 | } 30 | 31 | 32 | } 33 | 34 | .btn-block { 35 | display: block; 36 | width: 100%; 37 | } 38 | 39 | .btn-white { 40 | .btn-variant(#fff, darken(@text-color, 20%)); 41 | } 42 | 43 | .btn-link { 44 | .btn-variant(#eee, #545454); 45 | } 46 | 47 | .btn-danger { 48 | .btn-variant(@red, @white); 49 | } 50 | 51 | .btn-primary { 52 | .btn-variant(@blue, @white); 53 | } 54 | 55 | 56 | .btn-dark-gray { 57 | .btn-variant(lighten(@dark-gray,5%), #8e8e8e); 58 | } 59 | 60 | .btn-success { 61 | .btn-variant(@green, @white); 62 | } 63 | 64 | .btn-simple-editor { 65 | .btn-variant(darken(@dark-gray,1%), @text-color); 66 | } 67 | //----------------------------------- -------------------------------------------------------------------------------- /src/browser/js/buckets/__tests__/selectors.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * MinIO Cloud Storage (C) 2016, 2018 MinIO, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { getVisibleBuckets, getCurrentBucket } from "../selectors" 18 | 19 | describe("getVisibleBuckets", () => { 20 | let state 21 | beforeEach(() => { 22 | state = { 23 | buckets: { 24 | list: ["TEST1", "TEST11", "TEST22"] 25 | } 26 | } 27 | }) 28 | 29 | it("should return all buckets if no filter specified", () => { 30 | state.buckets.filter = "" 31 | expect(getVisibleBuckets(state)).toEqual(["TEST1", "TEST11", "TEST22"]) 32 | }) 33 | 34 | it("should return all matching buckets if filter is specified", () => { 35 | state.buckets.filter = "TEST1" 36 | expect(getVisibleBuckets(state)).toEqual(["TEST1", "TEST11"]) 37 | }) 38 | }) 39 | -------------------------------------------------------------------------------- /src/browser/js/uploads/__tests__/Dropzone.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * MinIO Cloud Storage (C) 2016, 2018 MinIO, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react" 18 | import { shallow } from "enzyme" 19 | import { Dropzone } from "../Dropzone" 20 | 21 | describe("Dropzone", () => { 22 | it("should render without crashing", () => { 23 | shallow() 24 | }) 25 | 26 | it("should call uploadFile with files", () => { 27 | const uploadFile = jest.fn() 28 | const wrapper = shallow() 29 | const file1 = new Blob(["file content1"], { type: "text/plain" }) 30 | const file2 = new Blob(["file content2"], { type: "text/plain" }) 31 | wrapper.first().prop("onDrop")([file1, file2]) 32 | expect(uploadFile.mock.calls).toEqual([[file1], [file2]]) 33 | }) 34 | }) 35 | -------------------------------------------------------------------------------- /src/browser/js/browser/Browser.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Minio Cloud Storage (C) 2018 Minio, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react"; 18 | import classNames from "classnames"; 19 | import { connect } from "react-redux"; 20 | import SideBar from "./SideBar"; 21 | import MainContent from "./MainContent"; 22 | import AlertContainer from "../alert/AlertContainer"; 23 | import DeviceFileModal from "./DeviceFileModal"; 24 | 25 | class Browser extends React.Component { 26 | render() { 27 | return ( 28 |
33 | 34 | 35 | 36 | 37 |
38 | ); 39 | } 40 | } 41 | 42 | module.exports = connect(state => state)(Browser); 43 | -------------------------------------------------------------------------------- /src/browser/js/browser/__tests__/StorageInfo.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * MinIO Cloud Storage (C) 2016, 2018 MinIO, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react" 18 | import { shallow } from "enzyme" 19 | import { StorageInfo } from "../StorageInfo" 20 | 21 | describe("StorageInfo", () => { 22 | it("should render without crashing", () => { 23 | shallow( 24 | 28 | ) 29 | }) 30 | 31 | it("should fetchStorageInfo before component is mounted", () => { 32 | const fetchStorageInfo = jest.fn() 33 | shallow( 34 | 38 | ) 39 | expect(fetchStorageInfo).toHaveBeenCalled() 40 | }) 41 | }) 42 | -------------------------------------------------------------------------------- /src/browser/js/browser/__tests__/AboutModal.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * MinIO Cloud Storage (C) 2016, 2018 MinIO, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react" 18 | import { shallow } from "enzyme" 19 | import { AboutModal } from "../AboutModal" 20 | 21 | describe("AboutModal", () => { 22 | const serverInfo = { 23 | version: "test", 24 | memory: "test", 25 | platform: "test", 26 | runtime: "test" 27 | } 28 | 29 | it("should render without crashing", () => { 30 | shallow() 31 | }) 32 | 33 | it("should call hideAbout when close button is clicked", () => { 34 | const hideAbout = jest.fn() 35 | const wrapper = shallow( 36 | 37 | ) 38 | wrapper.find("button").simulate("click") 39 | expect(hideAbout).toHaveBeenCalled() 40 | }) 41 | }) 42 | -------------------------------------------------------------------------------- /src/browser/simple.js: -------------------------------------------------------------------------------- 1 | /* 2 | * MinIO Cloud Storage (C) 2016, 2018 MinIO, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import "babel-polyfill"; 18 | import "./less/main.less"; 19 | import "../../font-awesome/css/font-awesome.css"; 20 | import "material-design-iconic-font/dist/css/material-design-iconic-font.min.css"; 21 | 22 | import React from "react"; 23 | import ReactDOM from "react-dom"; 24 | import { Router } from "react-router-dom"; 25 | import { Provider } from "react-redux"; 26 | 27 | import history from "./js/history"; 28 | import configureStore from "./js/store/configure-store"; 29 | import hideLoader from "./js/loader"; 30 | import App from "./js/App"; 31 | 32 | const store = configureStore(); 33 | 34 | ReactDOM.render( 35 | 36 | 37 | 38 | 39 | , 40 | document.getElementById("root") 41 | ); 42 | 43 | hideLoader(); 44 | -------------------------------------------------------------------------------- /src/browser/js/buckets/selectors.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Minio Cloud Storage (C) 2018 Minio, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { createSelector } from "reselect"; 18 | 19 | const bucketsSelector = state => state.buckets.list; 20 | const bucketsFilterSelector = state => state.buckets.filter; 21 | const bucketsSelectorMeta = state => state.buckets.bucketsMeta; 22 | 23 | export const getVisibleBuckets = createSelector( 24 | bucketsSelector, 25 | bucketsFilterSelector, 26 | (buckets, filter) => 27 | buckets.filter(bucket => bucket.indexOf(filter.toUpperCase()) > -1) 28 | ); 29 | 30 | export const getVisibleBucketsMeta = createSelector( 31 | bucketsSelectorMeta, 32 | bucketsFilterSelector, 33 | (bucketsMeta, filter) => 34 | bucketsMeta.filter( 35 | bucket => bucket.toUpperCase().indexOf(filter.toUpperCase()) > -1 36 | ) 37 | ); 38 | 39 | export const getCurrentBucket = state => state.buckets.currentBucket; 40 | -------------------------------------------------------------------------------- /src/browser/js/buckets/__tests__/Bucket.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * MinIO Cloud Storage (C) 2016, 2018 MinIO, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react" 18 | import { shallow } from "enzyme" 19 | import { Bucket } from "../Bucket" 20 | 21 | describe("Bucket", () => { 22 | it("should render without crashing", () => { 23 | shallow() 24 | }) 25 | 26 | it("should call selectBucket when clicked", () => { 27 | const selectBucket = jest.fn() 28 | const wrapper = shallow( 29 | 30 | ) 31 | wrapper.find("li a").simulate("click", { preventDefault: jest.fn() }) 32 | expect(selectBucket).toHaveBeenCalledWith("test") 33 | }) 34 | 35 | it("should highlight the selected bucket", () => { 36 | const wrapper = shallow() 37 | expect(wrapper.find("li").hasClass("active")).toBeTruthy() 38 | }) 39 | }) 40 | -------------------------------------------------------------------------------- /src/browser/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * MinIO Cloud Storage (C) 2016, 2018 MinIO, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import "babel-polyfill"; 18 | import "./less/main.less"; 19 | import "font-awesome/css/font-awesome.css"; 20 | import "material-design-iconic-font/dist/css/material-design-iconic-font.min.css"; 21 | import "./css/diff2html.min.css" 22 | 23 | import React from "react"; 24 | import ReactDOM from "react-dom"; 25 | import { Router } from "react-router-dom"; 26 | import { Provider } from "react-redux"; 27 | 28 | import history from "./js/history"; 29 | import configureStore from "./js/store/configure-store"; 30 | import hideLoader from "./js/loader"; 31 | import App from "./js/App"; 32 | 33 | const store = configureStore(); 34 | 35 | ReactDOM.render( 36 | 37 | 38 | 39 | 40 | , 41 | document.getElementById("root") 42 | ); 43 | 44 | hideLoader(); 45 | -------------------------------------------------------------------------------- /src/browser/js/objects/__tests__/ObjectsList.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * MinIO Cloud Storage (C) 2016, 2018 MinIO, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react" 18 | import { shallow } from "enzyme" 19 | import { ObjectsList } from "../ObjectsList" 20 | 21 | describe("ObjectsList", () => { 22 | it("should render without crashing", () => { 23 | shallow() 24 | }) 25 | 26 | it("should render ObjectContainer for every object", () => { 27 | const wrapper = shallow( 28 | 29 | ) 30 | expect(wrapper.find("Connect(ObjectContainer)").length).toBe(2) 31 | }) 32 | 33 | it("should render PrefixContainer for every prefix", () => { 34 | const wrapper = shallow( 35 | 36 | ) 37 | expect(wrapper.find("Connect(PrefixContainer)").length).toBe(2) 38 | }) 39 | }) 40 | -------------------------------------------------------------------------------- /src/browser/less/inc/dropdown.less: -------------------------------------------------------------------------------- 1 | .dropdown-menu { 2 | padding: 15px 0; 3 | top: 0; 4 | margin-top: -1px; 5 | 6 | & > li { 7 | & > a { 8 | padding: 8px 20px; 9 | font-size: 15px; 10 | 11 | & > i { 12 | width: 20px; 13 | position: relative; 14 | top: 1px; 15 | } 16 | } 17 | } 18 | } 19 | 20 | #bucket-dropdown { 21 | color: #FFFFFF !important; 22 | } 23 | 24 | .dropdown-menu-right { 25 | background-color:rgba(255,255,255,0.95) !important; 26 | 27 | & > li { 28 | & > a { 29 | text-align: right; 30 | } 31 | } 32 | } 33 | 34 | .meta-info-dropdown { 35 | position: fixed !important; 36 | z-index:9999; 37 | right: 20px; 38 | bottom: 300px; 39 | & .dropdown-toggle { 40 | display: none !important; 41 | } 42 | } 43 | 44 | @media(max-width: @screen-sm-max) { 45 | .meta-info-dropdown{ 46 | display: none !important; 47 | } 48 | } 49 | 50 | .meta-info-dropdown { 51 | & ul { 52 | min-width: 120px !important; 53 | padding: 10px !important; 54 | } 55 | & li { 56 | padding: 0px 15px; 57 | font-size: 15px; 58 | 59 | & .float-right { 60 | float: right; 61 | } 62 | & .float-left { 63 | float: left; 64 | } 65 | } 66 | & td, th { 67 | padding: 5px; 68 | } 69 | & .load-meta-info { 70 | 71 | padding: 15px; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/browser/less/inc/ie-warning.less: -------------------------------------------------------------------------------- 1 | .ie-warning { 2 | background-color: #ff5252; 3 | width: 100%; 4 | height: 100%; 5 | position: fixed; 6 | left: 0; 7 | top: 0; 8 | text-align: center; 9 | 10 | &:before { 11 | width: 1px; 12 | content: ''; 13 | height: 100%; 14 | } 15 | 16 | &:before, 17 | .iw-inner { 18 | display: inline-block; 19 | vertical-align: middle; 20 | } 21 | } 22 | 23 | .iw-inner { 24 | width: 470px; 25 | height: 300px; 26 | background-color: @white; 27 | border-radius: 5px; 28 | padding: 40px; 29 | position: relative; 30 | 31 | ul { 32 | list-style: none; 33 | padding: 0; 34 | margin: 0; 35 | width: 230px; 36 | margin-left: 80px; 37 | margin-top: 16px; 38 | 39 | & > li { 40 | float: left; 41 | 42 | & > a { 43 | display: block; 44 | padding: 10px 15px 7px; 45 | font-size: 14px; 46 | margin: 0 1px; 47 | border-radius: 3px; 48 | 49 | &:hover { 50 | background: #eee; 51 | } 52 | 53 | img { 54 | height: 40px; 55 | margin-bottom: 5px; 56 | } 57 | } 58 | } 59 | } 60 | } 61 | 62 | .iwi-icon { 63 | color: #ff5252; 64 | font-size: 40px; 65 | display: block; 66 | line-height: 100%; 67 | margin-bottom: 15px; 68 | } 69 | 70 | .iwi-skip { 71 | position: absolute; 72 | left: 0; 73 | bottom: -35px; 74 | width: 100%; 75 | color: rgba(255, 255, 255, 0.6); 76 | cursor: pointer; 77 | 78 | &:hover { 79 | color: @white; 80 | } 81 | } -------------------------------------------------------------------------------- /src/browser/js/browser/__tests__/Header.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * MinIO Cloud Storage (C) 2016, 2018 MinIO, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | import React from "react" 19 | import { shallow } from "enzyme" 20 | import Header from "../Header" 21 | 22 | jest.mock("../../web", () => ({ 23 | LoggedIn: jest 24 | .fn(() => true) 25 | .mockReturnValueOnce(true) 26 | .mockReturnValueOnce(false) 27 | })) 28 | describe("Header", () => { 29 | it("should render without crashing", () => { 30 | shallow(
) 31 | }) 32 | 33 | it("should render Login button when the user has not LoggedIn", () => { 34 | const wrapper = shallow(
) 35 | expect(wrapper.find("a").text()).toBe("Login") 36 | }) 37 | 38 | it("should render StorageInfo and BrowserDropdown when the user has LoggedIn", () => { 39 | const wrapper = shallow(
) 40 | expect(wrapper.find("Connect(BrowserDropdown)").length).toBe(1) 41 | expect(wrapper.find("Connect(StorageInfo)").length).toBe(1) 42 | }) 43 | }) 44 | -------------------------------------------------------------------------------- /src/browser/js/browser/__tests__/SideBar.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * MinIO Cloud Storage (C) 2016, 2018 MinIO, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react" 18 | import { shallow } from "enzyme" 19 | import { SideBar } from "../SideBar" 20 | 21 | jest.mock("../../web", () => ({ 22 | LoggedIn: jest.fn(() => false).mockReturnValueOnce(true) 23 | })) 24 | 25 | describe("SideBar", () => { 26 | it("should render without crashing", () => { 27 | shallow() 28 | }) 29 | 30 | it("should not render BucketSearch for non LoggedIn users", () => { 31 | const wrapper = shallow() 32 | expect(wrapper.find("Connect(BucketSearch)").length).toBe(0) 33 | }) 34 | 35 | it("should call clickOutside when the user clicks outside the sidebar", () => { 36 | const clickOutside = jest.fn() 37 | const wrapper = shallow() 38 | wrapper.simulate("clickOut", { preventDefault: jest.fn() }) 39 | expect(clickOutside).toHaveBeenCalled() 40 | }) 41 | }) 42 | -------------------------------------------------------------------------------- /src/browser/js/buckets/__tests__/BucketList.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * MinIO Cloud Storage (C) 2016, 2018 MinIO, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react" 18 | import { shallow } from "enzyme" 19 | import history from "../../history" 20 | import { BucketList } from "../BucketList" 21 | 22 | jest.mock("../../web", () => ({ 23 | LoggedIn: jest 24 | .fn(() => false) 25 | .mockReturnValueOnce(true) 26 | .mockReturnValueOnce(true) 27 | })) 28 | 29 | describe("BucketList", () => { 30 | it("should render without crashing", () => { 31 | const fetchBuckets = jest.fn() 32 | shallow() 33 | }) 34 | 35 | it("should call fetchBuckets before component is mounted", () => { 36 | const fetchBuckets = jest.fn() 37 | const wrapper = shallow( 38 | 39 | ) 40 | expect(fetchBuckets).toHaveBeenCalled() 41 | }) 42 | }) 43 | -------------------------------------------------------------------------------- /src/browser/less/inc/alert.less: -------------------------------------------------------------------------------- 1 | .alert { 2 | border: 0; 3 | position: fixed; 4 | max-width: 500px; 5 | margin: 0; 6 | box-shadow: 0 4px 5px rgba(0, 0, 0, 0.1); 7 | color: @white; 8 | width: 100%; 9 | right: 20px; 10 | border-radius: 3px; 11 | padding: 17px 50px 17px 17px; 12 | z-index: 10010; 13 | .animation-duration(800ms); 14 | .animation-fill-mode(both); 15 | 16 | &:not(.progress) { 17 | top: 20px; 18 | 19 | @media(min-width: (@screen-sm-min)) { 20 | left: 50%; 21 | margin-left: -250px; 22 | } 23 | } 24 | 25 | &.progress { 26 | bottom: 20px; 27 | right: 20px; 28 | } 29 | 30 | &.alert-danger { 31 | background: @red; 32 | } 33 | 34 | &.alert-warning { 35 | background: @orange; 36 | } 37 | 38 | &.alert-success { 39 | background: @green; 40 | } 41 | 42 | &.alert-info { 43 | background: @blue; 44 | } 45 | 46 | @media(max-width: (@screen-xs-max)) { 47 | left: 20px; 48 | width: ~"calc(100% - 40px)"; 49 | max-width: 100%; 50 | } 51 | 52 | .progress { 53 | margin: 10px 10px 8px 0; 54 | height: 5px; 55 | box-shadow: none; 56 | border-radius: 1px; 57 | background-color: @blue; 58 | border-radius: 2px; 59 | overflow: hidden; 60 | } 61 | 62 | .progress-bar { 63 | box-shadow: none; 64 | background-color: @white; 65 | height: 100%; 66 | } 67 | 68 | .close { 69 | position: absolute; 70 | top: 15px; 71 | } 72 | } -------------------------------------------------------------------------------- /src/sdk/s3-endpoints.js: -------------------------------------------------------------------------------- 1 | import { isString } from './helpers.js' 2 | 3 | // List of currently supported endpoints. 4 | let awsS3Endpoint = { 5 | 'us-east-1': 's3.amazonaws.com', 6 | 'us-east-2': 's3-us-east-2.amazonaws.com', 7 | 'us-west-1': 's3-us-west-1.amazonaws.com', 8 | 'us-west-2': 's3-us-west-2.amazonaws.com', 9 | 'ca-central-1': 's3.ca-central-1.amazonaws.com', 10 | 'eu-west-1': 's3-eu-west-1.amazonaws.com', 11 | 'eu-west-2': 's3-eu-west-2.amazonaws.com', 12 | 'sa-east-1': 's3-sa-east-1.amazonaws.com', 13 | 'eu-central-1': 's3-eu-central-1.amazonaws.com', 14 | 'ap-south-1': 's3-ap-south-1.amazonaws.com', 15 | 'ap-southeast-1': 's3-ap-southeast-1.amazonaws.com', 16 | 'ap-southeast-2': 's3-ap-southeast-2.amazonaws.com', 17 | 'ap-northeast-1': 's3-ap-northeast-1.amazonaws.com', 18 | 'cn-north-1': 's3.cn-north-1.amazonaws.com.cn', 19 | 'eu-north-1' : 's3-eu-north-1.amazonaws.com', 20 | 'eu-west-3' : 's3-eu-west-3.amazonaws.com', 21 | 'me-south-1' : 's3-me-south-1.amazonaws.com', 22 | 'eu-south-1' : 's3-eu-south-1.amazonaws.com', 23 | 'ap-northeast-2' : 's3-ap-northeast-2.amazonaws.com', 24 | 'ap-northeast-3' : 's3-ap-northeast-3.amazonaws.com', 25 | 'ap-east-1' : 's3-ap-east-1.amazonaws.com', 26 | 'af-south-1' : 's3-af-south-1.amazonaws.com' 27 | // Add new endpoints here. 28 | } 29 | 30 | // getS3Endpoint get relevant endpoint for the region. 31 | export function getS3Endpoint(region) { 32 | if (!isString(region)) { 33 | throw new TypeError(`Invalid region: ${region}`) 34 | } 35 | var endpoint = awsS3Endpoint[region] 36 | if (endpoint) { 37 | return endpoint 38 | } 39 | return 's3.amazonaws.com' 40 | } 41 | -------------------------------------------------------------------------------- /src/browser/js/browser/StorageInfo.js: -------------------------------------------------------------------------------- 1 | /* 2 | * MinIO Cloud Storage (C) 2016, 2018 MinIO, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react"; 18 | import { connect } from "react-redux"; 19 | import humanize from "humanize"; 20 | import * as actionsCommon from "./actions"; 21 | 22 | export class StorageInfo extends React.Component { 23 | componentWillMount() { 24 | const { fetchStorageInfo } = this.props; 25 | fetchStorageInfo(); 26 | } 27 | render() { 28 | const { used } = 0; 29 | return ( 30 |
31 | {/*
32 |
33 |
*/} 34 |
35 | ); 36 | } 37 | } 38 | 39 | const mapStateToProps = state => { 40 | return { 41 | storageInfo: state.browser.storageInfo 42 | }; 43 | }; 44 | 45 | const mapDispatchToProps = dispatch => { 46 | return { 47 | fetchStorageInfo: () => dispatch(actionsCommon.fetchStorageInfo()) 48 | }; 49 | }; 50 | 51 | export default connect( 52 | mapStateToProps, 53 | mapDispatchToProps 54 | )(StorageInfo); 55 | -------------------------------------------------------------------------------- /src/sdk/s3client.js: -------------------------------------------------------------------------------- 1 | /* 2 | * CANCloud cloud storage browser 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | const StorageClient = require('./storage') 18 | import { endPointSchema } from './helpers' 19 | 20 | export function S3Client(endPoint, accessKey, secretKey, region = '') { 21 | let useSSL = false 22 | const parsedEndPoint = endPointSchema(endPoint) 23 | 24 | switch (parsedEndPoint.protocol) { 25 | case 'http:': { 26 | useSSL = false 27 | break 28 | } 29 | case 'https:': { 30 | useSSL = true 31 | break 32 | } 33 | default: { 34 | useSSL = false 35 | } 36 | } 37 | if (parseInt(parsedEndPoint.port)) { 38 | return new StorageClient.Client({ 39 | endPoint: parsedEndPoint.hostname, 40 | port: parseInt(parsedEndPoint.port) || 80, 41 | useSSL: useSSL, 42 | accessKey: accessKey, 43 | secretKey: secretKey, 44 | region:region 45 | }) 46 | } else { 47 | return new StorageClient.Client({ 48 | endPoint: parsedEndPoint.hostname, 49 | accessKey: accessKey, 50 | secretKey: secretKey, 51 | region:region 52 | }) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/browser/customize-css/customize.css: -------------------------------------------------------------------------------- 1 | /* You can edit the below classes to customize the color scheme of the sidebar. 2 | Similarly, you can add your own favicon.ico, logo.png and logo-sidebar.png to the images folder */ 3 | 4 | 5 | /* Sidebar background color */ 6 | /* .sb-custom { 7 | background-color: #32393F !important; 8 | } */ 9 | 10 | /* Sidebar selected device background color */ 11 | /* .sb-custom-select { 12 | background-color: #e28c2f !important; 13 | } */ 14 | 15 | /*Color of search bar icon*/ 16 | /* .sb-custom-search-icon { 17 | color: rgba(255, 255, 255, 0.58) !important; 18 | } */ 19 | 20 | /*Color of search field placeholder text*/ 21 | /* .sb-custom-search-text::placeholder { 22 | color: rgba(255, 255, 255, 0.58) !important; 23 | } */ 24 | 25 | /*Color of non-selected device text*/ 26 | /* .sb-custom a { 27 | color: rgba(255, 255, 255, 0.58) !important; 28 | } */ 29 | 30 | /*Color of selected device text*/ 31 | /* .sb-custom-select a { 32 | color: #ffffff !important; 33 | } */ 34 | 35 | /*Color of device dropdown text*/ 36 | /* .sb-custom .dropdown-menu-right a { 37 | color: #8e8e8e !important; 38 | } */ 39 | 40 | /*Color version text in the sidebar*/ 41 | /* .sb-custom-version { 42 | color: rgba(255, 255, 255, 0.58) !important; 43 | } */ 44 | 45 | /*Background color of login screen*/ 46 | /* .login-custom { 47 | background-color: rgb(50, 57, 63) !important; 48 | } */ 49 | 50 | /*Host text*/ 51 | /* #sb-host-text { 52 | color: #32393F !important; 53 | } */ 54 | 55 | /*Host globe icon*/ 56 | /* #sb-globe { 57 | color: #32393F !important; 58 | } */ 59 | 60 | /*Change background color of mobile header*/ 61 | /* .mobile-header-custom { 62 | background-color: #303030 !important; 63 | } */ 64 | -------------------------------------------------------------------------------- /src/browser/js/components/BrowserUpdate.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Minio Cloud Storage (C) 2016 Minio, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import React from "react"; 18 | import connect from "react-redux/lib/components/connect"; 19 | 20 | import Tooltip from "react-bootstrap/lib/Tooltip"; 21 | import OverlayTrigger from "react-bootstrap/lib/OverlayTrigger"; 22 | 23 | let BrowserUpdate = ({ latestUiVersion }) => { 24 | // Don't show an update if we're already updated! 25 | if (latestUiVersion === currentUiVersion) return