All files / ext.wikilambda.edit/store/modules errors.js

100% Statements 27/27
100% Branches 14/14
100% Functions 11/11
100% Lines 27/27

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185              17x                                                                                             2x 2x 2x   2x                                   120x 120x 90x   30x 2x     56x                               7x                   57x                 12x                 2x 2x                             9x 1x   9x 8x   9x         9x                   286x 17x                   14x 11x 7x            
/*!
 * WikiLambda Vue editor: Store module for frontend error-related state, actions, mutations and getters
 *
 * @copyright 2020– Abstract Wikipedia team; see AUTHORS.txt
 * @license MIT
 */
 
module.exports = exports = {
	state: {
		/**
		 * Collection of errors by rowId.
		 *
		 * The rowId is an internal integer identifier that
		 * uniquely points at a sub-zObject represented by a
		 * component. The root rowId (0) identifies the whole
		 * object.
		 *
		 * This permits that different app granularity levels
		 * present errors in different ways. For example, a
		 * text field that represents a terminal ZString object
		 * can have an error state. This will be saved in the
		 * error module with the unique internal rowId that
		 * idetifies that sub-object. The component will use
		 * that rowId to grab all the errors associated to
		 * that field.
		 *
		 * Similarly, there can be a number of errors that are
		 * general and page-wide. These errors will be saved
		 * in the state using the root rowId (0) and can be
		 * presented in a top-level component such as the
		 * Publish dialog window.
		 *
		 * The error object will have this shape:
		 *
		 * errors: {
		 *  0: [
		 *    { message: "some error message", code: undefined, type: "error" },
		 *    { message: undefined, code: "wikilambda-unknown-warning", type: "warning" },
		 *    ...
		 *  ],
		 *  1: [],
		 *  ...
		 * }
		 */
		errors: {}
	},
	getters: {
		/**
		 * Returns all the stored errors, flattened into an array.
		 *
		 * @param {Object} state
		 * @return {Object}
		 */
		getAllErrors: function ( state ) {
			let allErrors = [];
			for ( const rowId in state.errors ) {
				allErrors = allErrors.concat( state.errors[ rowId ] );
			}
			return allErrors;
		},
 
		/**
		 * Returns all the errors for a given rowId.
		 * If error type is passed as second parameter, returns only
		 * the errors of the  type ("error" or "warning").
		 *
		 * @param {Object} state
		 * @return {Function}
		 */
		getErrors: function ( state ) {
			/**
			 * @param {number} rowId
			 * @param {string|undefined} type
			 * @return {Array}
			 */
			function getErrorsByRowId( rowId, type = undefined ) {
				const allErrors = state.errors[ rowId ];
				if ( !allErrors ) {
					return [];
				}
				return type ?
					allErrors.filter( ( error ) => error.type === type ) :
					allErrors;
			}
			return getErrorsByRowId;
		}
	},
	actions: {
		/**
		 * Set an error for a given rowId or a generic page-wide error.
		 * Any error that's set to rowId = 0 is considered page-wide.
		 *
		 * @param {Object} context
		 * @param {Object} payload
		 * @param {number} payload.rowId
		 * @param {string} payload.errorMessage
		 * @param {string} payload.errorCode
		 * @param {string} payload.errorType literal string: "error" or "warning"
		 */
		setError: function ( context, payload ) {
			context.commit( 'setError', payload );
		},
 
		/**
		 * Clears all errors given a rowId
		 *
		 * @param {Object} context
		 * @param {number} rowId
		 */
		clearErrors: function ( context, rowId = 0 ) {
			context.commit( 'clearErrorsForId', rowId );
		},
 
		/**
		 * Clears all validation errors
		 *
		 * @param {Object} context
		 */
		clearValidationErrors: function ( context ) {
			context.commit( 'clearValidationErrors' );
		},
 
		/**
		 * Clears all errors.
		 *
		 * @param {Object} context
		 */
		clearAllErrors: function ( context ) {
			context.commit( 'clearValidationErrors' );
			context.commit( 'clearErrorsForId', 0 );
		}
	},
	mutations: {
		/**
		 * Pushes a new error data into the store
		 *
		 * @param {Object} state
		 * @param {Object} payload
		 * @param {number} payload.rowId
		 * @param {string} payload.errorMessage
		 * @param {string} payload.errorCode
		 * @param {string} payload.errorType literal string: "error" or "warning"
		 */
		setError: function ( state, payload ) {
			if ( payload.rowId === undefined ) {
				payload.rowId = 0;
			}
			if ( !( payload.rowId in state.errors ) ) {
				state.errors[ payload.rowId ] = [];
			}
			const errorPayload = {
				message: payload.errorMessage,
				code: payload.errorCode,
				type: payload.errorType
			};
			state.errors[ payload.rowId ].push( errorPayload );
		},
 
		/**
		 * Sets all errors states to false for a given rowId.
		 *
		 * @param {Object} state
		 * @param {number} rowId
		 */
		clearErrorsForId: function ( state, rowId ) {
			if ( rowId in state.errors ) {
				state.errors[ rowId ] = [];
			}
		},
 
		/**
		 * Clears all errors from validating concrete fields
		 *
		 * @param {Object} state
		 */
		clearValidationErrors: function ( state ) {
			for ( const rowId in state.errors ) {
				if ( rowId > 0 ) {
					state.errors[ rowId ] = [];
				}
			}
		}
	}
};