From cdaa596d766d938e3318ca6bdc05e0836f417823 Mon Sep 17 00:00:00 2001 From: Carlos Souza Date: Fri, 24 Nov 2023 21:12:01 -0500 Subject: [PATCH] docs: improve config generator (#696) --- docs/components/clipboardIcon.jsx | 16 ++ docs/components/configuration.jsx | 235 +++++++++++++++++++++--------- 2 files changed, 179 insertions(+), 72 deletions(-) create mode 100644 docs/components/clipboardIcon.jsx diff --git a/docs/components/clipboardIcon.jsx b/docs/components/clipboardIcon.jsx new file mode 100644 index 00000000..49385522 --- /dev/null +++ b/docs/components/clipboardIcon.jsx @@ -0,0 +1,16 @@ +export const clipBoardIcon = () => { + return ( + <> + + + + + + + + + ); + +} \ No newline at end of file diff --git a/docs/components/configuration.jsx b/docs/components/configuration.jsx index ce66e979..9b05ce0e 100644 --- a/docs/components/configuration.jsx +++ b/docs/components/configuration.jsx @@ -1,74 +1,151 @@ -import { useState } from "react"; +import { useState, useReducer } from "react"; import json2toml from "json2toml"; +import { clipBoardIcon } from "./clipboardIcon"; + +function reducer(state, action) { + switch (action.name) { + + case 'add_source': { + const currentStages = state.currentStages; + currentStages.source = action.source; + currentStages.intersect = action.intersect; + + const _tomlContent = json2toml(currentStages, { newlineAfterSection: true }); + const tomlContent = (_tomlContent || "").trim(); + + return { + ...state, + currentStages, + tomlContent, + openedModal: false, + }; + } + + case 'add_filter': { + const currentStages = state.currentStages; + + const hasFilterIndex = currentStages.filters?.findIndex( + (s) => s.type == action.stage.type + ); + + if (hasFilterIndex != undefined && hasFilterIndex != -1) { + currentStages.filters[hasFilterIndex] = action.stage; + } else { + currentStages.filters = currentStages.filters?.concat(action.stage) || [action.stage]; + } + + const _tomlContent = json2toml(currentStages, { newlineAfterSection: true }); + const tomlContent = (_tomlContent || "").trim(); + + return { + ...state, + currentStages, + tomlContent, + openedModal: false + }; + } + + case 'add_sink': { + const currentStages = state.currentStages; + currentStages.sink = action.stage; + + const _tomlContent = json2toml(currentStages, { newlineAfterSection: true }); + const tomlContent = (_tomlContent || "").trim(); + + return { + ...state, + currentStages, + openedModal: false, + tomlContent + }; + } + + case 'open_modal': { + return { + ...state, + openedModal: true, + typeModal: action.type, + optionModal: undefined + }; + }; + + case 'close_modal': { + return { + ...state, + openedModal: false + }; + }; + + case 'set_option_modal': { + return { + ...state, + optionModal: action.value + }; + }; + + case 'reset': { + return { + ...state, + currentStages: {}, + tomlContent: "" + }; + }; + } + throw Error('Unknown action: ' + action.name); +} export function Configuration() { - const [openedModal, setOpenedModal] = useState(false); - const [typeModal, setTypeModal] = useState(); - const [optionModal, setoOptionModal] = useState(undefined); - const [currentStages, setCurrentStages] = useState({}); + const [state, dispatch] = useReducer(reducer, + { + openedModal: false, + typeModal: null, + optionModal: undefined, + currentStages: {}, + tomlContent: "" + } + ); const addSourceStage = ({ source, intersect }) => { - currentStages.source = source; - currentStages.intersect = intersect; - setCurrentStages(currentStages); - setOpenedModal(false); + dispatch({ name: 'add_source', source, intersect }); }; const addFilterStage = (stage) => { - const hasFilterIndex = currentStages.filters?.findIndex( - (s) => s.type == stage.type - ); - - if (hasFilterIndex != undefined && hasFilterIndex != -1) { - currentStages.filters[hasFilterIndex] = stage; - } else { - currentStages.filters = currentStages.filters?.concat(stage) || [stage]; - } - - setCurrentStages(currentStages); - setOpenedModal(false); + dispatch({ name: 'add_filter', stage }); }; const addSinkStage = (stage) => { - currentStages.sink = stage; - setCurrentStages(currentStages); - setOpenedModal(false); + dispatch({ name: 'add_sink', stage }); }; function openModal(type) { - setOpenedModal(true); - setTypeModal(type); - setoOptionModal(undefined); + dispatch({ name: 'open_modal', type }); } - function exportConfig() { - if (!currentStages.source) { - alert("Add a source"); - return; - } + function closeModal() { + dispatch({ name: 'close_modal' }); + } - if (!currentStages.sink) { - alert("Add a sink"); - return; - } + function setOptionModal(value) { + dispatch({ name: 'set_option_modal', value }); + } - var element = document.createElement("a"); - element.setAttribute( - "href", - "data:text/plain;charset=utf-8," + - encodeURIComponent( - json2toml(currentStages, { newlineAfterSection: true }) - ) - ); - element.setAttribute("download", "daemon.toml"); + function reset() { + dispatch({ name: 'reset' }); + } + + function copyToClipboard(button) { - element.style.display = "none"; - document.body.appendChild(element); + const smallCopy = document.getElementById('small-copy'); - element.click(); + navigator.clipboard.writeText(state.tomlContent).then(res => { + const originalSmallCopy = smallCopy.innerHTML; + smallCopy.innerHTML = "Copied!"; - document.body.removeChild(element); + setTimeout(() => { + smallCopy.innerHTML = originalSmallCopy; + }, 1000); + }); } const TYPES = { @@ -109,18 +186,18 @@ export function Configuration() { return (
- {openedModal ? ( + {state.openedModal ? ( <>

- {typeModal} + {state.typeModal}

@@ -131,17 +208,17 @@ export function Configuration() { name="stage" id="stage" className="w-full py-2 px-4 rounded mb-2" - onChange={(e) => setoOptionModal(e.target.value)} - value={optionModal} + onChange={(e) => setOptionModal(e.target.value)} + value={state.optionModal} > - {Object.keys(stages[typeModal]).map((k) => ( + {Object.keys(stages[state.typeModal]).map((k) => ( ))} - {optionModal ? stages[typeModal][optionModal] : null} + {state.optionModal ? stages[state.typeModal][state.optionModal] : null}
@@ -161,18 +238,12 @@ export function Configuration() {
-
@@ -184,11 +255,11 @@ export function Configuration() { add source - {currentStages.source ? ( + {state.currentStages.source ? ( ) : null} @@ -200,7 +271,7 @@ export function Configuration() { > add filter - {currentStages[TYPES.FILTERS]?.map((value, index) => ( + {state.currentStages[TYPES.FILTERS]?.map((value, index) => (
@@ -215,13 +286,33 @@ export function Configuration() { add sink - {currentStages.sink ? ( - + {state.currentStages.sink ? ( + ) : null}
-
+ + {state.tomlContent && state.tomlContent.length > 0 && ( +
+
+ config.toml + + Copy to clipboard + + +
+
+
{state.tomlContent}
+
+
+ ) + } + ); } @@ -1841,4 +1932,4 @@ function StageCard({ value }) { ))} ); -} +} \ No newline at end of file