github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/ui/src/redux/queryManager/reducer.ts (about) 1 // Copyright 2018 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 import moment from "moment"; 12 import { Action } from "redux"; 13 14 import nextState from "src/util/nextState"; 15 16 const QUERY_BEGIN = "cockroachui/queries/QUERY_BEGIN"; 17 const QUERY_ERROR = "cockroachui/queries/QUERY_ERROR"; 18 const QUERY_COMPLETE = "cockroachui/queries/QUERY_COMPLETE"; 19 20 interface QueryBeginAction extends Action { 21 type: typeof QUERY_BEGIN; 22 payload: { 23 id: string; 24 }; 25 } 26 27 interface QueryErrorAction extends Action { 28 type: typeof QUERY_ERROR; 29 payload: { 30 id: string; 31 error: Error; 32 timestamp: moment.Moment; 33 }; 34 } 35 36 interface QueryCompleteAction extends Action { 37 type: typeof QUERY_COMPLETE; 38 payload: { 39 id: string; 40 timestamp: moment.Moment; 41 }; 42 } 43 44 type QueryAction = QueryBeginAction | QueryErrorAction | QueryCompleteAction; 45 46 /** 47 * queryBegin is dispatched by the query manager whenever the query with the 48 * given ID has started execution. 49 */ 50 export function queryBegin(id: string): QueryBeginAction { 51 return { 52 type: QUERY_BEGIN, 53 payload: { 54 id, 55 }, 56 }; 57 } 58 59 /** 60 * queryError is dispatched by the query manager whenever the query with the 61 * given ID has stopped due to an error condition. This action contains the 62 * returned error, along with the timestamp when the error was received. 63 */ 64 export function queryError(id: string, error: Error, timestamp: moment.Moment): QueryErrorAction { 65 return { 66 type: QUERY_ERROR, 67 payload: { 68 id, 69 error, 70 timestamp, 71 }, 72 }; 73 } 74 75 /** 76 * queryComplete is dispatched by the query manager whenever the query with the 77 * given ID has completed successfully. It includes the timestamp when the query 78 * was completed. 79 */ 80 export function queryComplete(id: string, timestamp: moment.Moment): QueryCompleteAction { 81 return { 82 type: QUERY_COMPLETE, 83 payload: { 84 id, 85 timestamp, 86 }, 87 }; 88 } 89 90 /** 91 * ManagedQueryState maintains the current state for a single managed query. 92 */ 93 export class ManagedQueryState { 94 // True if this query is currently running asynchronously. 95 isRunning = false; 96 // If the previous attempt to run this query ended with an error, this field 97 // contains that error. 98 lastError: Error = null; 99 // Contains the timestamp when the query last compeleted, regardless of 100 // whether it succeeded or encountered an error. 101 completedAt: moment.Moment = null; 102 } 103 104 /** 105 * managedQueryReducer reduces actions for a single managed query. 106 */ 107 export function managedQueryReducer( 108 state = new ManagedQueryState(), action: QueryAction, 109 ): ManagedQueryState { 110 switch (action.type) { 111 case QUERY_BEGIN: 112 return nextState(state, { 113 isRunning: true, 114 lastError: null, 115 completedAt: null, 116 }); 117 case QUERY_ERROR: 118 return nextState(state, { 119 isRunning: false, 120 lastError: action.payload.error, 121 completedAt: action.payload.timestamp, 122 }); 123 case QUERY_COMPLETE: 124 return nextState(state, { 125 isRunning: false, 126 lastError: null, 127 completedAt: action.payload.timestamp, 128 }); 129 default: 130 return state; 131 } 132 } 133 134 /** 135 * QueryManagerState maintains the state for all queries being managed. 136 */ 137 export interface QueryManagerState { 138 [id: string]: ManagedQueryState; 139 } 140 141 /** 142 * queryManagerReducer reduces actions for a query collection, multiplexing 143 * incoming actions to individual query reducers by ID. 144 */ 145 export function queryManagerReducer( 146 state: QueryManagerState = {}, action: QueryAction, 147 ): QueryManagerState { 148 switch (action.type) { 149 case QUERY_BEGIN: 150 case QUERY_ERROR: 151 case QUERY_COMPLETE: 152 return { 153 ...state, 154 [action.payload.id]: managedQueryReducer(state[action.payload.id], action), 155 }; 156 default: 157 return state; 158 } 159 }