diff --git a/src/server/playground/comp/Main.tsx b/src/server/playground/comp/Main.tsx index 7f4ab321..a94bd499 100644 --- a/src/server/playground/comp/Main.tsx +++ b/src/server/playground/comp/Main.tsx @@ -10,6 +10,7 @@ import SuccessIcon from "./icon/SuccessIcon.tsx"; import { JSONViewer } from "./JSONVeiwer.tsx"; import { useLesan } from "./ManagedLesanContext.tsx"; import { Selected } from "./Selected.tsx"; +import MultiSelect from "./MultiSelect.tsx"; const lesanAPI = ({ baseUrl, @@ -46,17 +47,17 @@ export const Main = ({ urlAddress }: { urlAddress: string }) => { value: 0 | 1 | null, keyname: string, getObj: Record, - returnObj: Record, + returnObj: Record ) => { for (const key in getObj) { getObj[key].type === "enums" ? (returnObj[`${keyname}.${key}`] = value) : changeGetValue( - value, - `${keyname}.${key}`, - getObj[key].schema, - returnObj, - ); + value, + `${keyname}.${key}`, + getObj[key].schema, + returnObj + ); } return returnObj; }; @@ -84,6 +85,77 @@ export const Main = ({ urlAddress }: { urlAddress: string }) => { }); }; + const renderPostFields = ({ + key, + field, + isMultiEnum = false, + formData, + }: { + key: string; + field: Record; + isMultiEnum?: boolean; + formData?: any; + }): h.JSX.Element => { + if (field.type === "array") { + return renderPostFields({ + key, + formData, + field: field["schema"], + isMultiEnum: true, + }); + } else if (field["type"] === "enums" && isMultiEnum) { + return ( + ({ + label: schemaKey, + value: field["schema"][schemaKey], + }))} + onChange={(options) => { + const value = options.map((item) => item.value); + setFormData({ + data: { + ...formData, + [`set.${key}`]: value, + }, + index: activeTab, + }); + localStorage.setItem("localTabsData", JSON.stringify(tabsData)); + }} + > + ); + } else if (field["type"] === "enums") { + return ( + { + setFormData({ + data: { + ...formData, + [`set.${key}`]: value, + }, + index: activeTab, + }); + localStorage.setItem("localTabsData", JSON.stringify(tabsData)); + }} + incomeActiveItem={formData[`set.${key}`]} + items={Object.keys(field["schema"])} + /> + ); + } else { + return ( + + ); + } + }; + const renderGetFields = ({ getField, keyName, @@ -100,68 +172,67 @@ export const Main = ({ urlAddress }: { urlAddress: string }) => { >
{keyName}
{Object.keys(getField["schema"]).map((item, index) => - getField["schema"][item].type === "enums" - ? ( -
- -
- { - const copy = { ...tabsData[activeTab].formData }; - delete copy[`get.${keyName}.${item}`]; - setFormData({ data: copy, index: activeTab }); - }} - > - - + +
+ { + const copy = { ...tabsData[activeTab].formData }; + delete copy[`get.${keyName}.${item}`]; + setFormData({ data: copy, index: activeTab }); + }} + > + { - setFormData({ - index: activeTab, - data: { - ...tabsData[activeTab].formData, - [`get.${keyName}.${item}`]: 0, - }, - }); - }} - > - 0 - - { + setFormData({ + index: activeTab, + data: { + ...tabsData[activeTab].formData, + [`get.${keyName}.${item}`]: 0, + }, + }); + }} + > + 0 + + { - setFormData({ - data: { - ...tabsData[activeTab].formData, - [`get.${keyName}.${item}`]: 1, - }, - index: activeTab, - }); - }} - > - 1 - -
+ : "" + } + onClick={() => { + setFormData({ + data: { + ...tabsData[activeTab].formData, + [`get.${keyName}.${item}`]: 1, + }, + index: activeTab, + }); + }} + > + 1 +
- ) - : ( - renderGetFields({ - getField: getField["schema"][item], - keyName: `${keyName}.${item}`, - margin: margin + 1, - }) - ) +
+ ) : ( + renderGetFields({ + getField: getField["schema"][item], + keyName: `${keyName}.${item}`, + margin: margin + 1, + }) + ) )} ); @@ -226,7 +297,8 @@ export const Main = ({ urlAddress }: { urlAddress: string }) => { localStorage.setItem("localTabsData", JSON.stringify(tabsData)); }; - const canShowRequestFields = tabsData[activeTab].service && + const canShowRequestFields = + tabsData[activeTab].service && tabsData[activeTab].schema && tabsData[activeTab].postFields && tabsData[activeTab].getFields && @@ -264,7 +336,7 @@ export const Main = ({ urlAddress }: { urlAddress: string }) => { const onClickItem = ( item: string, - type: "service" | "method" | "schema" | "action", + type: "service" | "method" | "schema" | "action" ) => { if (type === "service") { setService({ @@ -313,9 +385,9 @@ export const Main = ({ urlAddress }: { urlAddress: string }) => { onClickItem(item, "service")} items={Object.keys(actsObj)} - incomeActiveItem={tabsData[activeTab].service - ? tabsData[activeTab].service - : null} + incomeActiveItem={ + tabsData[activeTab].service ? tabsData[activeTab].service : null + } /> @@ -329,12 +401,14 @@ export const Main = ({ urlAddress }: { urlAddress: string }) => { onClickItem(item, "schema")} - items={canShowSchema - ? Object.keys((actsObj as any)[tabsData[activeTab].service]) - : []} - incomeActiveItem={tabsData[activeTab].schema - ? tabsData[activeTab].schema - : null} + items={ + canShowSchema + ? Object.keys((actsObj as any)[tabsData[activeTab].service]) + : [] + } + incomeActiveItem={ + tabsData[activeTab].schema ? tabsData[activeTab].schema : null + } /> @@ -343,16 +417,18 @@ export const Main = ({ urlAddress }: { urlAddress: string }) => { onClickItem(item, "action")} - items={canShowAct - ? Object.keys( - (actsObj as any)[tabsData[activeTab].service][ - tabsData[activeTab].schema - ], - ) - : []} - incomeActiveItem={tabsData[activeTab].act - ? tabsData[activeTab].act - : null} + items={ + canShowAct + ? Object.keys( + (actsObj as any)[tabsData[activeTab].service][ + tabsData[activeTab].schema + ] + ) + : [] + } + incomeActiveItem={ + tabsData[activeTab].act ? tabsData[activeTab].act : null + } /> @@ -367,44 +443,11 @@ export const Main = ({ urlAddress }: { urlAddress: string }) => { {Object.keys(tabsData[activeTab].postFields).map((item) => (
- {tabsData[activeTab].postFields[item]["type"] === "enums" - ? ( - { - setFormData({ - data: { - ...tabsData[activeTab].formData, - [`set.${item}`]: clickedItem, - }, - index: activeTab, - }); - localStorage.setItem( - "localTabsData", - JSON.stringify(tabsData), - ); - }} - incomeActiveItem={tabsData[activeTab] - .formData[`set.${item}`]} - items={Object.keys( - tabsData[activeTab].postFields[item]["schema"], - )} - /> - ) - : ( - - )} + {renderPostFields({ + key: item, + field: tabsData[activeTab].postFields[item], + formData: tabsData[activeTab].formData, + })}
))}
@@ -420,7 +463,7 @@ export const Main = ({ urlAddress }: { urlAddress: string }) => { null, "get", tabsData[activeTab].getFields, - {}, + {} ); setFormData({ @@ -428,15 +471,14 @@ export const Main = ({ urlAddress }: { urlAddress: string }) => { index: activeTab, }); }} - > - + > { const copy = changeGetValue( 0, "get", tabsData[activeTab].getFields, - {}, + {} ); setFormData({ data: { @@ -455,7 +497,7 @@ export const Main = ({ urlAddress }: { urlAddress: string }) => { 1, "get", tabsData[activeTab].getFields, - {}, + {} ); setFormData({ data: { @@ -472,70 +514,69 @@ export const Main = ({ urlAddress }: { urlAddress: string }) => {
{Object.keys(tabsData[activeTab].getFields).map((item) => - tabsData[activeTab].getFields[item].type === "enums" - ? ( -
- -
- { - setFormData({ - data: { - ...tabsData[activeTab].formData, - [`get.${item}`]: null, - }, - index: activeTab, - }); - }} - > - - + +
+ { + setFormData({ + data: { + ...tabsData[activeTab].formData, + [`get.${item}`]: null, + }, + index: activeTab, + }); + }} + > + { - setFormData({ - data: { - ...tabsData[activeTab].formData, - [`get.${item}`]: 0, - }, - index: activeTab, - }); - }} - > - 0 - - { + setFormData({ + data: { + ...tabsData[activeTab].formData, + [`get.${item}`]: 0, + }, + index: activeTab, + }); + }} + > + 0 + + { - setFormData({ - data: { - ...tabsData[activeTab].formData, - [`get.${item}`]: 1, - }, - index: activeTab, - }); - }} - > - 1 - -
+ : "" + } + onClick={() => { + setFormData({ + data: { + ...tabsData[activeTab].formData, + [`get.${item}`]: 1, + }, + index: activeTab, + }); + }} + > + 1 +
- ) - : ( - renderGetFields({ - getField: tabsData[activeTab].getFields[item], - keyName: item, - margin: 0, - }) - ) +
+ ) : ( + renderGetFields({ + getField: tabsData[activeTab].getFields[item], + keyName: item, + margin: 0, + }) + ) )}
)} diff --git a/src/server/playground/comp/MultiSelect.tsx b/src/server/playground/comp/MultiSelect.tsx new file mode 100644 index 00000000..d8554e7f --- /dev/null +++ b/src/server/playground/comp/MultiSelect.tsx @@ -0,0 +1,122 @@ +/** @jsx h */ +import { h, FunctionalComponent, useState } from "../reactDeps.ts"; +import ChevronDownIcon from "./icon/ChevronDownIcon.tsx"; +import { useOutsideClick } from "./hooks/useOutsideClick.ts"; + +export interface IOption { + value: string; + label: string; +} + +interface MultiSelectProps { + options: IOption[]; + onChange: (options: IOption[]) => void; +} + +const MultiSelect: FunctionalComponent = ({ + options, + onChange, +}) => { + const [selectedOptions, setSelectedOptions] = useState([]); + const [unselectedOptions, setUnselectedOptions] = + useState(options); + const [isOpen, setIsOpen] = useState(false); + + const handleOptionChange = (selectedOption: IOption) => { + if (selectedOptions.includes(selectedOption)) { + const filteredSelectedOptions = selectedOptions.filter( + (option) => option.value !== selectedOption.value + ); + setSelectedOptions(filteredSelectedOptions); + setUnselectedOptions([...unselectedOptions, selectedOption]); + onChange(filteredSelectedOptions); + } else { + const filteredUnselectedOptions = unselectedOptions.filter( + (option) => option.value !== selectedOption.value + ); + setSelectedOptions([...selectedOptions, selectedOption]); + setUnselectedOptions(filteredUnselectedOptions); + onChange([...selectedOptions, selectedOption]); + } + }; + + const resetOptions = () => { + setSelectedOptions([]); + onChange([]); + setUnselectedOptions(options); + }; + + const toggleDropdown = () => { + setIsOpen(!isOpen); + }; + + const ref = useOutsideClick(() => { + setIsOpen(false); + }); + + return ( +
+
+
+ {selectedOptions.map((item) => ( +
+
+ {item.label} +
+
{ + e.stopPropagation(); + handleOptionChange(item); + }} + > + x +
+
+ ))} +
+
+ {selectedOptions.length ? ( +
{ + e.stopPropagation(); + resetOptions(); + }} + > + x +
+ ) : null} + +
+ +
+
+
+ {isOpen ? ( +
+ {unselectedOptions.length ? ( + unselectedOptions.map((option) => ( +
{ + e.stopPropagation(); + handleOptionChange(option); + }} + className="multi-select__option" + > +
{option.label}
+
+ )) + ) : ( +
No Options!
+ )} +
+ ) : null} +
+ ); +}; + +export default MultiSelect; diff --git a/src/server/playground/comp/icon/ChevronDownIcon.tsx b/src/server/playground/comp/icon/ChevronDownIcon.tsx index 297f44a2..c7dbf661 100644 --- a/src/server/playground/comp/icon/ChevronDownIcon.tsx +++ b/src/server/playground/comp/icon/ChevronDownIcon.tsx @@ -1,7 +1,11 @@ /** @jsx h */ import { h } from "../../reactDeps.ts"; -export default function ChevronDownIcon() { +export default function ChevronDownIcon({ + className = "", +}: { + className?: string; +}) { return ( input { + cursor: pointer; +}