/** * Copyright (c) HashiCorp, Inc. * SPDX-License-Identifier: MPL-2.0 */ import { assign, createMachine, send } from 'xstate'; // Docs on using statecharts: https://xstate.js.org/docs/packages/xstate-fsm/#api export default createMachine( { id: 'evaluations_ui', context: { evaluation: null }, type: 'parallel', states: { table: { initial: 'unknown', on: { NEXT: { actions: ['requestNextPage', send('MODAL_CLOSE')], }, PREV: { actions: ['requestPrevPage', send('MODAL_CLOSE')], }, CHANGE_PAGES_SIZE: { actions: ['changePageSize', send('MODAL_CLOSE')], }, MODEL_UPDATED: '#unknown', }, states: { unknown: { id: 'unknown', always: [{ target: 'data', cond: 'hasData' }, { target: 'empty' }], }, data: {}, empty: {}, }, }, sidebar: { initial: 'unknown', states: { unknown: { always: [ { target: 'open', cond: 'sidebarIsOpen' }, { target: 'close' }, ], }, open: { initial: 'busy', exit: ['removeCurrentEvaluationQueryParameter'], states: { busy: { invoke: { src: 'loadEvaluation', onDone: 'success', onError: 'error', }, }, success: { entry: assign({ evaluation: (context, event) => { return event.data; }, }), on: { LOAD_EVALUATION: { target: 'busy', actions: ['updateEvaluationQueryParameter'], }, }, }, error: { entry: assign({ error: (_ctx, event) => event.data }), on: { RETRY: 'busy', }, }, }, on: { MODAL_CLOSE: 'close', CHANGE_EVAL: [{ target: 'close', cond: 'hasNoCurrentEval' }], }, }, close: { on: { LOAD_EVALUATION: { target: 'open', actions: ['updateEvaluationQueryParameter'], }, CHANGE_EVAL: [ { target: 'open', cond: 'hasCurrentEval', }, ], }, }, }, }, }, }, { services: { // Overridden in the controller async loadEvaluations() {}, async loadEvaluation() {}, }, guards: { sidebarIsOpen() { return false; }, hasData() { return true; }, hasNoCurrentEval(_ctx, { evaluation }) { return !evaluation; }, hasCurrentEval(_ctx, { evaluation }) { return evaluation; }, notBusy(_ctx, _event, meta) { return !meta.state.matches({ sidebar: { open: 'busy' } }); }, }, actions: { updateEvaluationQueryParameter() {}, removeCurrentEvaluationQueryParameter() {}, }, } );