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 | 124x 124x 124x 51x 46x 3x 124x 1x 1x 1x 1x 1x 1x | /* * Copyright 2021 Harness Inc. All rights reserved. * Use of this source code is governed by the PolyForm Shield 1.0.0 license * that can be found in the licenses directory at the root of this repository, also available at * https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt. */ import React, { useState } from 'react' import type { FormikProps, FormikErrors } from 'formik' import { clone, merge } from 'lodash-es' interface DeployStageErrorState { errors: FormikErrors<unknown> forms: { [key: string]: React.MutableRefObject<FormikProps<unknown> | null>[] } } interface FormProps { tab: string form: React.MutableRefObject<FormikProps<unknown> | null> } export interface StageErrorContextInterface { state: DeployStageErrorState subscribeForm: (formData: FormProps) => void unSubscribeForm: (formData: FormProps) => void submitFormsForTab: (tab: string) => void checkErrorsForTab: (tab: string) => Promise<void> } export const StageErrorContext = React.createContext<StageErrorContextInterface>({ state: { errors: {}, forms: {} }, subscribeForm: () => undefined, unSubscribeForm: () => undefined, submitFormsForTab: () => undefined, checkErrorsForTab: () => new Promise<void>(() => undefined) }) export interface DeployStageErrorProviderProps { children: React.ReactNode } export function DeployStageErrorProvider(props: DeployStageErrorProviderProps): React.ReactElement { const [state, setState] = useState<DeployStageErrorState>({ errors: {}, forms: {} }) const subscribeForm = React.useCallback((formData: FormProps): void => { setState(prevState => { const forms = clone(prevState).forms const existingForms = forms[formData.tab] if (existingForms) { existingForms.push(formData.form) } else { forms[formData.tab] = [formData.form] } return { ...prevState, forms } }) }, []) const unSubscribeForm = React.useCallback((formData: FormProps) => { setState(prevState => { const forms = clone(prevState).forms const existingForms = forms[formData.tab] if (existingForms) { const index = existingForms.findIndex(form => form === formData.form) existingForms.splice(index, 1) if (existingForms.length === 0) delete forms[formData.tab] return { ...prevState, forms } } return { ...prevState } }) }, []) const submitFormsForTab = (tab: string) => { const forms = state.forms[tab] if (!forms) return const promises = [] for (const form of forms) { form.current?.submitForm() promises.push(form.current?.validateForm()) } Promise.all(promises).then(values => { let errors = {} values.forEach(value => { errors = merge(errors, value) }) setState({ ...state, errors }) }) } const checkErrorsForTab = (tab: string): Promise<void> => { return new Promise((resolve, reject) => { const forms = state.forms[tab] if (!forms) resolve() const promises = [] for (const form of forms) { form.current?.submitForm() promises.push(form.current?.validateForm()) } Promise.all(promises).then(values => { let errors = {} let errorsCount = 0 values.forEach(value => { errorsCount += Object.keys(value ?? {}).length errors = merge(errors, value) }) setState({ ...state, errors }) if (errorsCount === 0) resolve() reject() }) }) } return ( <StageErrorContext.Provider value={{ state, subscribeForm, unSubscribeForm, checkErrorsForTab, submitFormsForTab }}> {props.children} </StageErrorContext.Provider> ) } |