Просмотр исходного кода

Added a seperate loading spinner for pagination CORWEB-39

Fix issue with reseting search query after no results have been found.
Sergiu Miclea 8 лет назад
Родитель
Сommit
c2ee2484e2

+ 15 - 0
src/components/App/App.scss

@@ -469,6 +469,21 @@ button {
   }
   }
 }
 }
 :global {
 :global {
+  .spinner,
+  .spinner:after {
+    border-radius: 50%;
+    width: 12px;
+    height: 12px;
+  }
+  .spinner {
+    position: relative;
+    border-top: 2px solid $gray;
+    border-right: 2px solid $gray;
+    border-bottom: 2px solid $gray;
+    border-left: 2px solid $blue;
+    transform: translateZ(0);
+    animation: rotate 2s infinite linear;
+  }
   .taskIcon {
   .taskIcon {
     width: 16px;
     width: 16px;
     height: 16px;
     height: 16px;

+ 1 - 1
src/components/SearchBox/SearchBox.js

@@ -65,7 +65,7 @@ class SearchBox extends Component {
   }
   }
 
 
   render() {
   render() {
-    let renderLoading = () => this.props.isLoading ? <div className="taskIcon RUNNING"></div> : null
+    let renderLoading = () => this.props.isLoading ? <div className="spinner"></div> : null
     let hidden = this.props.show ? ' ' : ' hidden'
     let hidden = this.props.show ? ' ' : ' hidden'
 
 
     return (
     return (

+ 3 - 3
src/components/SearchBox/SearchBox.scss

@@ -22,10 +22,10 @@ $searchStrokeColor: $gray-dark;
 
 
 .root {
 .root {
   position: relative;
   position: relative;
-  :global(.taskIcon) {
+  :global(.spinner) {
     position: absolute;
     position: absolute;
-    top: 2px;
-    right: 0px;
+    top: 3px;
+    right: 8px;
   }
   }
 }
 }
 
 

+ 20 - 15
src/components/WizardVms/WizardVms.js

@@ -25,6 +25,7 @@ import LoadingIcon from '../LoadingIcon';
 
 
 const title = 'Select instances to migrate';
 const title = 'Select instances to migrate';
 const vmStatesConst = ["All", "RUNNING", "PAUSED", "STOPPED"]
 const vmStatesConst = ["All", "RUNNING", "PAUSED", "STOPPED"]
+const loadingStates = { IDLE: 0, QUERY: 1, PAGINATION: 2 }
 const searchTimeout = 1000;
 const searchTimeout = 1000;
 
 
 class WizardVms extends Component {
 class WizardVms extends Component {
@@ -55,7 +56,7 @@ class WizardVms extends Component {
     this.state = {
     this.state = {
       valid,
       valid,
       queryText: '',
       queryText: '',
-      searching: false,
+      loadingState: loadingStates.IDLE,
       page: 0,
       page: 0,
       filterStatus: 'All',
       filterStatus: 'All',
       filteredData: this.props.data.instances ? this.props.data.instances.slice(0, itemsPerPage) : [],
       filteredData: this.props.data.instances ? this.props.data.instances.slice(0, itemsPerPage) : [],
@@ -79,16 +80,16 @@ class WizardVms extends Component {
   }
   }
 
 
   processProps(props) {
   processProps(props) {
-    let isSearching = typeof props.data.searching === undefined ? this.state.searching : props.data.searching
-    if (props.data.instances && !isSearching) {
+    let loadingState = typeof props.data.loadingState === undefined ? this.state.loadingState : props.data.loadingState
+    if (props.data.instances && !loadingState) {
       this.setState({
       this.setState({
         filteredData: props.data.instances.slice(
         filteredData: props.data.instances.slice(
           this.state.page * itemsPerPage, this.state.page * itemsPerPage + itemsPerPage),
           this.state.page * itemsPerPage, this.state.page * itemsPerPage + itemsPerPage),
-        searching: isSearching
+        loadingState: loadingState.IDLE
       })
       })
     } else {
     } else {
       this.setState({
       this.setState({
-        searching: isSearching
+        loadingState: loadingState
       })
       })
     }
     }
   }
   }
@@ -131,13 +132,13 @@ class WizardVms extends Component {
     }
     }
 
 
     if (this.state.queryText != queryText) {
     if (this.state.queryText != queryText) {
-      this.props.setWizardState({ searching: true })
+      this.props.setWizardState({ loadingState: loadingStates.QUERY })
 
 
       if (this.timeout != null) {
       if (this.timeout != null) {
         clearTimeout(this.timeout)
         clearTimeout(this.timeout)
       }
       }
       this.timeout = setTimeout(() => {
       this.timeout = setTimeout(() => {
-        this.setState({ queryText: queryText }, () => {
+        this.setState({ queryText: queryText, page: 0 }, () => {
           ConnectionsActions.loadInstances(
           ConnectionsActions.loadInstances(
             { id: this.props.data.sourceCloud.credential.id },
             { id: this.props.data.sourceCloud.credential.id },
             this.state.page,
             this.state.page,
@@ -183,7 +184,7 @@ class WizardVms extends Component {
 
 
   nextPage() {
   nextPage() {
     if (this.state.filteredData && this.state.filteredData.length == itemsPerPage) {
     if (this.state.filteredData && this.state.filteredData.length == itemsPerPage) {
-      this.props.setWizardState({ searching: true })
+      this.props.setWizardState({ loadingState: loadingStates.PAGINATION })
       this.setState({ page: this.state.page + 1 }, () => {
       this.setState({ page: this.state.page + 1 }, () => {
         ConnectionsActions.loadInstances(
         ConnectionsActions.loadInstances(
           { id: this.props.data.sourceCloud.credential.id },
           { id: this.props.data.sourceCloud.credential.id },
@@ -196,7 +197,7 @@ class WizardVms extends Component {
 
 
   previousPage() {
   previousPage() {
     if (this.state.page > 0) {
     if (this.state.page > 0) {
-      this.props.setWizardState({ searching: true })
+      this.props.setWizardState({ loadingState: loadingStates.PAGINATION })
       this.setState({ page: this.state.page - 1 }, () => {
       this.setState({ page: this.state.page - 1 }, () => {
         ConnectionsActions.loadInstances(
         ConnectionsActions.loadInstances(
           { id: this.props.data.sourceCloud.credential.id },
           { id: this.props.data.sourceCloud.credential.id },
@@ -248,7 +249,7 @@ class WizardVms extends Component {
   }
   }
 
 
   renderSearch() {
   renderSearch() {
-    if (this.props.data.instancesLoadState === 'success' || this.state.searching) {
+    if (this.props.data.instancesLoadState === 'success' || this.state.loadingState) {
       return this.renderFilteredItems()
       return this.renderFilteredItems()
     }
     }
 
 
@@ -280,10 +281,11 @@ class WizardVms extends Component {
           <div className={s.topFilters}>
           <div className={s.topFilters}>
             <SearchBox
             <SearchBox
               placeholder="Search VMs"
               placeholder="Search VMs"
-              isLoading={this.state.searching}
+              isLoading={this.state.loadingState === loadingStates.QUERY}
               value={this.state.queryText}
               value={this.state.queryText}
               onChange={(e) => this.searchVm(e)}
               onChange={(e) => this.searchVm(e)}
-              show={(!this.state.filteredData || !!this.state.filteredData.length) || !!this.state.queryText}
+              show={(!this.state.filteredData || !!this.state.filteredData.length)
+                || this.state.loadingState > 0 || !!this.state.queryText}
             />
             />
             <div className="category-filter hidden">
             <div className="category-filter hidden">
               {vmStates}
               {vmStates}
@@ -301,13 +303,16 @@ class WizardVms extends Component {
             (!(this.state.filteredData && this.state.filteredData.length) ? " hidden" : " ")}
             (!(this.state.filteredData && this.state.filteredData.length) ? " hidden" : " ")}
           >
           >
             <span
             <span
-              className={(this.state.page === 0 || this.state.searching ? "disabled " : "") + s.prev}
+              className={(this.state.page === 0 || this.state.loadingState ? "disabled " : "") + s.prev}
               onClick={(e) => this.previousPage(e)}
               onClick={(e) => this.previousPage(e)}
             ></span>
             ></span>
-            <span className={s.currentPage}>{this.state.page + 1}</span>
+            <span className={s.currentPage}>{
+              this.state.loadingState === loadingStates.PAGINATION ?
+                <div className="spinner"></div> : this.state.page + 1
+            }</span>
             <span
             <span
               className={((this.state.filteredData && this.state.filteredData.length == itemsPerPage)
               className={((this.state.filteredData && this.state.filteredData.length == itemsPerPage)
-                && !this.state.searching ? " " : "disabled ") + s.next}
+                && !this.state.loadingState ? " " : "disabled ") + s.next}
               onClick={(e) => this.nextPage(e)}
               onClick={(e) => this.nextPage(e)}
             ></span>
             ></span>
           </div>
           </div>

+ 8 - 1
src/components/WizardVms/WizardVms.scss

@@ -109,12 +109,19 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
     cursor: default;
     cursor: default;
     width: 32px;
     width: 32px;
     height: 32px;
     height: 32px;
-    display: inline-block;
     float: left;
     float: left;
     text-align: center;
     text-align: center;
     line-height: 32px;
     line-height: 32px;
     border-left: 1px solid $gray;
     border-left: 1px solid $gray;
     border-right: 1px solid $gray;
     border-right: 1px solid $gray;
+    :global(.spinner) {
+      top: 8px;
+      left: 8px;
+      border-top-color: $gray;
+      border-right-color: $gray;
+      border-bottom-color: $gray;
+      border-left-color: $gray-lighter;
+    }
   }
   }
   &:after {
   &:after {
     display: block;
     display: block;

+ 3 - 3
src/stores/WizardStore/WizardStore.js

@@ -60,7 +60,7 @@ class WizardStore extends Reflux.Store
   onLoadInstances(endpoint, page = 0, queryText = "", cache = true, clearSelection = false) {
   onLoadInstances(endpoint, page = 0, queryText = "", cache = true, clearSelection = false) {
     this.setState({ instancesLoadState: 'loading' })
     this.setState({ instancesLoadState: 'loading' })
     if (cache && (this.state.instances && this.state.instances[page * itemsPerPage])) {
     if (cache && (this.state.instances && this.state.instances[page * itemsPerPage])) {
-      this.setState({ searching: false, instancesLoadState: 'success' })
+      this.setState({ loadingState: 0, instancesLoadState: 'success' })
       return;
       return;
     }
     }
 
 
@@ -105,11 +105,11 @@ class WizardStore extends Reflux.Store
       instances[(page * itemsPerPage) + index] = instance
       instances[(page * itemsPerPage) + index] = instance
     })
     })
 
 
-    this.setState({ instances: instances, instancesLoadState: 'success', searching: false })
+    this.setState({ instances: instances, instancesLoadState: 'success', loadingState: 0 })
   }
   }
 
 
   onLoadInstancesFailed() {
   onLoadInstancesFailed() {
-    this.setState({ instances: [], instancesLoadState: 'error', searching: false })
+    this.setState({ instances: [], instancesLoadState: 'error', loadingState: 0 })
   }
   }
 
 
   onLoadInstanceDetail(endpoint, instance) {
   onLoadInstanceDetail(endpoint, instance) {