mirror of
https://github.com/moghtech/komodo.git
synced 2026-05-04 11:32:28 -05:00
setup jotai and restructure a bit
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
"dependencies": {
|
||||
"ink": "^3.2.0",
|
||||
"ink-text-input": "^4.0.3",
|
||||
"jotai": "^1.6.1",
|
||||
"meow": "^10.1.2",
|
||||
"mongoose": "^6.2.7",
|
||||
"react": "^17.0.2"
|
||||
|
||||
+12
-19
@@ -1,48 +1,41 @@
|
||||
import React, { ReactNode, useEffect, useState } from "react";
|
||||
import React, { ReactNode, useState } from "react";
|
||||
import { Newline, render, Text, useInput, Box } from "ink";
|
||||
import { isDockerInstalled } from "./helpers/docker";
|
||||
import { useConfig, useSequence } from "./hooks";
|
||||
import { Config } from "./types";
|
||||
import init from "./util/init";
|
||||
import Intro from "./components/Intro";
|
||||
import Docker from "./components/docker/Docker";
|
||||
import Periphery from "./components/Periphery";
|
||||
import Confirm from "./components/Confirm";
|
||||
import getFlags from "./flags";
|
||||
import { createUseConfig, createUseSequence } from "./util/state";
|
||||
import { Config } from "./types";
|
||||
|
||||
getFlags().then((flags) => {
|
||||
export const useMainSequence = createUseSequence();
|
||||
export const useConfig = createUseConfig<Config>({});
|
||||
|
||||
init().then(({ flags, dockerInstalled }) => {
|
||||
const App = () => {
|
||||
const [current, next, prev] = useSequence();
|
||||
const [dockerInstalled, setDockerInstalled] = useState<boolean>();
|
||||
const { current, next, prev } = useMainSequence();
|
||||
const [periphery, setPeriphery] = useState<boolean | undefined>(
|
||||
flags.core ? true : flags.periphery ? false : undefined
|
||||
);
|
||||
const [installing, setInstalling] = useState(false);
|
||||
const [config, setConfig] = useConfig<Config>({});
|
||||
|
||||
useEffect(() => {
|
||||
isDockerInstalled().then((res) => setDockerInstalled(res));
|
||||
}, []);
|
||||
|
||||
useInput((_, key) => {
|
||||
if (!installing && key.escape) prev();
|
||||
});
|
||||
|
||||
if (dockerInstalled === undefined) return null;
|
||||
|
||||
const corePages: ReactNode[] = periphery === false ? [] : [];
|
||||
|
||||
const peripheryPages: ReactNode[] = periphery ? [] : [];
|
||||
|
||||
const pages: ReactNode[] = [
|
||||
<Intro next={next} />,
|
||||
...(dockerInstalled ? [] : [<Docker next={next} />]),
|
||||
<Intro />,
|
||||
...(dockerInstalled ? [] : [<Docker />]),
|
||||
...(!flags.core && !flags.periphery
|
||||
? [<Periphery setPeriphery={setPeriphery} next={next} />]
|
||||
? [<Periphery setPeriphery={setPeriphery} />]
|
||||
: []),
|
||||
...(periphery === true ? peripheryPages : []),
|
||||
...(periphery === false ? corePages : []),
|
||||
<Confirm
|
||||
config={config}
|
||||
next={() => {
|
||||
setInstalling(true);
|
||||
next();
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import React from "react";
|
||||
import { Box, Text } from "ink";
|
||||
import { Config, Next } from "../types";
|
||||
import { useEnter } from "../hooks";
|
||||
import { useEnter } from "../util/hooks";
|
||||
import { useConfig } from "../cli";
|
||||
|
||||
const Confirm = ({ config, next }: { config: Config; next: Next }) => {
|
||||
const Confirm = ({ next }: { next: () => void }) => {
|
||||
const { config } = useConfig();
|
||||
useEnter(next);
|
||||
return <Box><Text>confirm</Text></Box>;
|
||||
};
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import React from "react";
|
||||
import { Box, Newline, Text } from "ink";
|
||||
import EnterToContinue from "./util/EnterToContinue";
|
||||
import { useMainSequence } from "../cli";
|
||||
|
||||
const Intro = ({ next }: { next: () => void }) => {
|
||||
const Intro = () => {
|
||||
const { next } = useMainSequence();
|
||||
return (
|
||||
<Box flexDirection="column">
|
||||
<Text>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import React from "react";
|
||||
import { Box } from "ink";
|
||||
import { Config, SetConfig } from "../types";
|
||||
|
||||
const Mongo = ({}: { config: Config; setConfig: SetConfig; }) => {
|
||||
return (
|
||||
<Box>
|
||||
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default Mongo;
|
||||
@@ -1,15 +1,14 @@
|
||||
import React from "react";
|
||||
import { Text } from "ink";
|
||||
import { Next } from "../types";
|
||||
import LabelledSelector from "./util/LabelledSelector";
|
||||
import { useMainSequence } from "../cli";
|
||||
|
||||
const Periphery = ({
|
||||
setPeriphery,
|
||||
next,
|
||||
}: {
|
||||
setPeriphery: (periphery: boolean) => void;
|
||||
next: Next;
|
||||
}) => {
|
||||
const { next } = useMainSequence();
|
||||
return (
|
||||
<LabelledSelector
|
||||
label={
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from "react";
|
||||
import { Box } from "ink";
|
||||
|
||||
const Registry = ({}: {}) => {
|
||||
return (
|
||||
<Box>
|
||||
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default Registry;
|
||||
@@ -1,10 +1,11 @@
|
||||
import React, { Fragment, useEffect, useState } from "react";
|
||||
import { Newline, Text } from "ink";
|
||||
import { Next } from "../../types";
|
||||
import YesNo from "../util/YesNo";
|
||||
import InstallDocker from "./InstallDocker";
|
||||
import { useMainSequence } from "../../cli";
|
||||
|
||||
const Docker = ({ next }: { next: Next }) => {
|
||||
const Docker = () => {
|
||||
const { next } = useMainSequence();
|
||||
const [installDocker, setInstallDocker] = useState<boolean>();
|
||||
useEffect(() => {
|
||||
if (installDocker === false) {
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { Fragment, useState } from "react";
|
||||
import { Box, Newline, Text, useInput } from "ink";
|
||||
import { Next } from "../../types";
|
||||
import YesNo from "../util/YesNo";
|
||||
import { installDockerUbuntu, InstallLog } from "../../helpers/docker";
|
||||
import { installDockerUbuntu, InstallLog } from "../../util/helpers/docker";
|
||||
|
||||
const InstallDocker = ({ next }: { next: Next }) => {
|
||||
const [stage, setStage] = useState<
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from "react";
|
||||
import { Text } from "ink";
|
||||
import { useEnter } from "../../hooks";
|
||||
import { useEnter } from "../../util/hooks";
|
||||
|
||||
const EnterToContinue = ({ onEnter }: { onEnter: () => void }) => {
|
||||
useEnter(onEnter);
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
import { useInput } from "ink";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
export function useSequence(): [
|
||||
current: number,
|
||||
next: () => void,
|
||||
prev: () => void
|
||||
] {
|
||||
const [current, setCurrent] = useState(0);
|
||||
const next = useCallback(() => {
|
||||
setCurrent((current) => current + 1);
|
||||
}, []);
|
||||
const prev = useCallback(() => {
|
||||
setCurrent((current) => Math.max(current - 1, 0));
|
||||
}, []);
|
||||
return [current, next, prev];
|
||||
}
|
||||
|
||||
export function useConfig<T>(
|
||||
init: T
|
||||
): [T, (field: keyof T, val: T[keyof T]) => void] {
|
||||
const [config, setConfig] = useState(init);
|
||||
const set = useCallback((field: keyof T, val: T[keyof T]) => {
|
||||
setConfig((config) => ({ ...config, [field]: val }));
|
||||
}, []);
|
||||
return [config, set];
|
||||
}
|
||||
|
||||
export function useBlinker(interval = 750) {
|
||||
const [on, setOn] = useState(false);
|
||||
useEffect(() => {
|
||||
const int = setInterval(() => {
|
||||
setOn((on) => !on);
|
||||
}, interval);
|
||||
return () => clearInterval(int);
|
||||
}, []);
|
||||
return on;
|
||||
}
|
||||
|
||||
export function useEnter(onEnter: () => void) {
|
||||
useInput((_, key) => {
|
||||
if (key.return) {
|
||||
onEnter();
|
||||
}
|
||||
})
|
||||
}
|
||||
Vendored
+2
-4
@@ -35,7 +35,5 @@ export type StartConfig = {
|
||||
|
||||
export type SetConfig = (
|
||||
field: keyof Config,
|
||||
val: string | number | boolean
|
||||
) => void;
|
||||
|
||||
export type Next = () => void;
|
||||
val: Config[keyof Config]
|
||||
) => void;
|
||||
@@ -0,0 +1,27 @@
|
||||
import { useInput, Key } from "ink";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
export function useBlinker(interval = 750) {
|
||||
const [on, setOn] = useState(false);
|
||||
useEffect(() => {
|
||||
const int = setInterval(() => {
|
||||
setOn((on) => !on);
|
||||
}, interval);
|
||||
return () => clearInterval(int);
|
||||
}, []);
|
||||
return on;
|
||||
}
|
||||
|
||||
export function useKey(key: keyof Key, callback: () => void) {
|
||||
useInput((_, k) => {
|
||||
if (k[key]) callback();
|
||||
});
|
||||
}
|
||||
|
||||
export function useEnter(onEnter: () => void) {
|
||||
useKey("return", onEnter);
|
||||
}
|
||||
|
||||
export function useEsc(onEsc: () => void) {
|
||||
useKey("escape", onEsc);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import getFlags from "./flags";
|
||||
import { isDockerInstalled } from "./helpers/docker";
|
||||
|
||||
// used to load async prerequisites
|
||||
|
||||
async function init() {
|
||||
const flags = await getFlags();
|
||||
const dockerInstalled = await isDockerInstalled();
|
||||
return {
|
||||
flags,
|
||||
dockerInstalled
|
||||
}
|
||||
}
|
||||
|
||||
export default init;
|
||||
@@ -0,0 +1,35 @@
|
||||
import { atom, useAtom } from "jotai";
|
||||
import { useCallback } from "react";
|
||||
|
||||
export function createUseConfig<T>(init: T) {
|
||||
const configAtom = atom<T>(init);
|
||||
|
||||
return () => {
|
||||
const [config, setConfig] = useAtom(configAtom);
|
||||
const set = useCallback((field: keyof T, val: T[keyof T]) => {
|
||||
setConfig((config) => ({ ...config, [field]: val }));
|
||||
}, []);
|
||||
return {
|
||||
config: config as T,
|
||||
set
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function createUseSequence() {
|
||||
const currentAtom = atom(0);
|
||||
return () => {
|
||||
const [current, set] = useAtom(currentAtom);
|
||||
const next = useCallback(() => {
|
||||
set((current) => current + 1);
|
||||
}, []);
|
||||
const prev = useCallback(() => {
|
||||
set((current) => Math.max(current - 1, 0));
|
||||
}, []);
|
||||
return {
|
||||
current,
|
||||
next,
|
||||
prev,
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1699,6 +1699,11 @@ is-what@^4.1.6:
|
||||
resolved "https://registry.yarnpkg.com/is-what/-/is-what-4.1.7.tgz#c41dc1d2d2d6a9285c624c2505f61849c8b1f9cc"
|
||||
integrity sha512-DBVOQNiPKnGMxRMLIYSwERAS5MVY1B7xYiGnpgctsOFvVDz9f9PFXXxMcTOHuoqYp4NK9qFYQaIC1NRRxLMpBQ==
|
||||
|
||||
jotai@^1.6.1:
|
||||
version "1.6.1"
|
||||
resolved "https://registry.yarnpkg.com/jotai/-/jotai-1.6.1.tgz#a6379d7dce159474f24963921d55ae8f6e9e8dd6"
|
||||
integrity sha512-iNKHmpKGN31KXDqxGLsplb4HLTroYtiM7oBEQ9leyoXSEGQGUZKK5IOV4kN6fUmkBSJbwb5WnmInYOYzpjIDOw==
|
||||
|
||||
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
|
||||
Reference in New Issue
Block a user