2022-06-21 23:20:53 +00:00
|
|
|
import type { ReactNode } from 'react';
|
|
|
|
import { useState, createContext, useContext } from 'react';
|
|
|
|
|
2022-07-12 16:34:54 +00:00
|
|
|
import { NodeSwitcherDialog } from '../components/node-switcher-dialog';
|
2022-06-21 23:20:53 +00:00
|
|
|
import { useConfig } from './use-config';
|
|
|
|
import { compileEnvironment } from '../utils/compile-environment';
|
|
|
|
import { validateEnvironment } from '../utils/validate-environment';
|
|
|
|
import type { Environment, RawEnvironment, ConfigStatus } from '../types';
|
|
|
|
|
|
|
|
type EnvironmentProviderProps = {
|
|
|
|
definitions?: Partial<RawEnvironment>;
|
|
|
|
children?: ReactNode;
|
|
|
|
};
|
|
|
|
|
|
|
|
export type EnvironmentState = Environment & {
|
|
|
|
configStatus: ConfigStatus;
|
2022-07-12 16:34:54 +00:00
|
|
|
setNodeSwitcherOpen: () => void;
|
2022-06-21 23:20:53 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const EnvironmentContext = createContext({} as EnvironmentState);
|
|
|
|
|
|
|
|
export const EnvironmentProvider = ({
|
|
|
|
definitions,
|
|
|
|
children,
|
|
|
|
}: EnvironmentProviderProps) => {
|
2022-07-12 16:34:54 +00:00
|
|
|
const [isNodeSwitcherOpen, setNodeSwitcherOpen] = useState(false);
|
2022-06-21 23:20:53 +00:00
|
|
|
const [environment, updateEnvironment] = useState<Environment>(
|
|
|
|
compileEnvironment(definitions)
|
|
|
|
);
|
2022-07-12 16:34:54 +00:00
|
|
|
const { status: configStatus, config } = useConfig(
|
|
|
|
environment,
|
|
|
|
updateEnvironment
|
|
|
|
);
|
2022-06-21 23:20:53 +00:00
|
|
|
|
|
|
|
const errorMessage = validateEnvironment(environment);
|
|
|
|
|
|
|
|
if (errorMessage) {
|
|
|
|
throw new Error(errorMessage);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
2022-07-12 16:34:54 +00:00
|
|
|
<EnvironmentContext.Provider
|
|
|
|
value={{
|
|
|
|
...environment,
|
|
|
|
configStatus,
|
|
|
|
setNodeSwitcherOpen: () => setNodeSwitcherOpen(true),
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
{config && (
|
|
|
|
<NodeSwitcherDialog
|
|
|
|
dialogOpen={isNodeSwitcherOpen}
|
|
|
|
toggleDialogOpen={setNodeSwitcherOpen}
|
|
|
|
config={config}
|
|
|
|
onConnect={(url) =>
|
|
|
|
updateEnvironment((env) => ({ ...env, VEGA_URL: url }))
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
)}
|
2022-06-21 23:20:53 +00:00
|
|
|
{children}
|
|
|
|
</EnvironmentContext.Provider>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export const useEnvironment = () => {
|
|
|
|
const context = useContext(EnvironmentContext);
|
|
|
|
if (context === undefined) {
|
|
|
|
throw new Error(
|
|
|
|
'Error running "useEnvironment". No context found, make sure your component is wrapped in an <EnvironmentProvider />.'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return context;
|
|
|
|
};
|