плоское хранение данных

This commit is contained in:
krokodilka 2022-07-22 23:31:02 +03:00
parent 03cca73e73
commit e6caad37b2
10 changed files with 267 additions and 166 deletions

@ -12,7 +12,6 @@ import type {ElementsOfObject} from "./questionTypes"
//Значения, собираемые для отправки на бэк
interface Values {
title: string;
type: string;
children: string;
description: string;
}
@ -24,7 +23,8 @@ const types = [
{desc:"чекбокс", value:"checkbox"},
{desc:"файл", value:"file"},
{desc:"кнопка", value:"button"},
{desc:"ничего", value:"none"}
{desc: "описание", value: "description"},
{desc:"ничего", value:"none"},
]
export const TextField = (props: any) => {
@ -103,17 +103,34 @@ const getIndexById = (id:number, array:Array<ElementsOfObject>):number => {
export default () => {
const [type, setType] = React.useState<number>(4)
const [stockroom, setStockroom] = React.useState<Array<ElementsOfObject>>([])
const [focus, setFocus] = React.useState<number | undefined>() //Хранит id объекта
// React.useEffect(() => {
// console.log(focus)
// if (focus !== undefined) {
// let elem = document.getElementById(focus + "")
// if (elem !== null) {
// console.log(elem)
// elem.focus()
// }
// }
// },[focus])
//При пересоздании массива для изменения фокуса объекта отменяются фокусы у всех элементов массива
const typeHC = (value:number): void => {
setType(value)
setStockroom([])
saveCondition("type", value)
saveCondition("stockroom", [])
//Изменение типа очищает все поля, кроме фокуса
const typeHC = (type:number): void => {
if (focus !== undefined) {
let index = getIndexById(focus, stockroom)
let newArr = stockroom
newArr[index].type = type
newArr[index].color = ""
newArr[index].text = ""
setStockroom([...newArr])
saveCondition("stockroom", newArr)
}
}
const changeFocus = (id: number): void => {
//Не менять фокус если снова выбрано то же окно
@ -175,7 +192,16 @@ export default () => {
//Говорим стейту с фокусом, что фокус изменился
setFocus(newArr.length - 1)
} else { //фокус есть - добавляем после объекта с фокусом
let index = getIndexById(focus, stockroom)
let current = stockroom[index]
//Объект в фокусе - контейнер. Новый объект создаётся с указанием, что контейнер - родитель
if (current.type === 7) {
obj.parent = current.id
}
newArr.splice(index + 1, 0, obj)
//Говорим стейту с фокусом, что фокус изменился
@ -198,20 +224,20 @@ export default () => {
saveCondition("stockroom", newArr)
}
}
console.log("render")
return(
<>
<Formik
initialValues={{
children: '',
title: '',
type: '',
description:'описание',
}}
onSubmit={(values, actions) => {
console.log(JSON.stringify(values))
// console.log(JSON.stringify(values))
console.log(getCondition())
console.log(focus)
}}
>
{(props: FormikProps<Values>) => (
@ -233,23 +259,22 @@ export default () => {
<VStack>
<WorkSpace
type={type}
stockroom={stockroom}
changeFocus={changeFocus}
/>
</VStack>
<VStack
minWidth="200px"
minWidth="250px"
bgColor="lightgray"
height="98vh"
padding="10px"
overflow="auto"
>
<Settings
types={types}
stockroom={stockroom}
typeHC={typeHC}
type={type}
focus={focus}
changeFocus={changeFocus}
changeBgColor={changeBgColor}

@ -61,7 +61,13 @@ export default ({name}) => {
padding="10px"
width="80%"
ref={visual}
/>
tabIndex={0}
_focus={{
border:"solid 1px red"
}}
>
</Box>
}
</>
)

@ -1,13 +1,3 @@
export function saveCondition (key:string, value:any) {
let ls : any = window.localStorage.getItem("condition")
if (ls !== null) {
ls = JSON.parse(ls)
} else {
ls = {}
}
ls[key] = value
localStorage.setItem("condition", JSON.stringify(ls))
}
export function getCondition () {
let ls : any = window.localStorage.getItem("condition")
if (ls !== null) {
@ -15,4 +5,15 @@ export function getCondition () {
} else {
return null
}
}
export function saveCondition (key:string, value:any) {
let ls : any = getCondition()
if (ls === null) {
ls = {}
}
ls[key] = value
localStorage.setItem("condition", JSON.stringify(ls))
}
export function clearCondition (key:string, value:any) {
localStorage.setItem("condition", "{}")
}

@ -4,16 +4,18 @@ interface ElementsOfObject {
id: number;
isFocus: boolean;
color?: string;
type: number
parent: undefined | number
}
interface QuestionProps {
type: number;
stockroom: Array<ElementsOfObject>;
stockroom: Array<ElementsOfObject> | never[];
focus: number;
changeFocus: (id?: number) => void;
changeBgColor: (text?:string) => void;
changeText: (text?:string) => void;
createObject?: (obj?:ElementsOfObject) => void;
deleteObject: (id?:number) => void;
getIndexById: (id?:number, array?:ElementsOfObject) => number;
changeFocus: (id: number) => void;
changeBgColor: (text:string) => void;
changeText: (text:string) => void;
createObject?: (obj:ElementsOfObject) => void;
deleteObject: (id:number) => void;
getIndexById: (id:number, array?:ElementsOfObject) => number;
}
export type {ElementsOfObject, QuestionProps}

@ -1,14 +1,26 @@
import React from 'react';
import {Box, Button, Checkbox, Container, Select} from "@chakra-ui/react";
import Buttons from "./tools/buttons"
import {Box, Button, Checkbox, Container, Select, Textarea} from "@chakra-ui/react";
import UserElements from "./userElements"
import SunEditor from "suneditor-react";
export default (props: any) => {
let current:any
if (props.focus !== undefined) {
if (props.stockroom !== undefined) {
const index = props.getIndexById(props.focus, props.stockroom)
if (index !== undefined) {
current = props.stockroom[index]
}
}
}
return (
<>
<Select
placeholder='тип вопроса'
value={props.type}
value={current === undefined ? 0 : current.type}
onChange={e => {
props.typeHC(Number(e.target.value))
}}
@ -19,7 +31,7 @@ export default (props: any) => {
))
}
</Select>
<Buttons
<UserElements
stockroom={props.stockroom}
focus={props.focus}
changeFocus={props.changeFocus}
@ -28,8 +40,53 @@ export default (props: any) => {
createObject={props.createObject}
deleteObject={props.deleteObject}
getIndexById={props.getIndexById}
current={current}
/>
<Button type="submit">Создать вопрос</Button>
{current === undefined ?
null
:
current.type === 5 ?
<SunEditor
width="200px"
onChange={(e:any)=> {
let visual = document.getElementById(current.id)
if (visual !== null) {
visual.innerHTML = e
}
props.changeText(e)
}}
// imageUploadHandler={(e:any)=>console.log(e)}
// onImageUpload={(e:any)=>console.log(e)}
// showController={(e:any)=>console.log(e)}
// hideToolbar={false}
defaultValue={current.text}
setOptions={{
buttonList: [
[
'undo', 'redo',
'font', 'fontSize', 'formatBlock',
'paragraphStyle', 'blockquote',
'bold', 'underline', 'italic', 'strike', 'subscript', 'superscript',
'fontColor', 'hiliteColor', 'textStyle',
'removeFormat',
'outdent', 'indent',
'align', 'horizontalRule', 'list', 'lineHeight',
'table', 'link', 'image', 'video',
'fullScreen', 'showBlocks', 'codeView',
'preview', 'print', 'save', 'template',
]
]
}}
/>
:
<Textarea
onChange={(e) => props.changeText(e.target.value)}
placeholder="Текст"
maxWidth="300px"
value={current.text}
/>
}
</>
)
}

@ -1,77 +0,0 @@
import React from 'react';
import { Button, VStack, HStack, Textarea} from "@chakra-ui/react";
import {ChromePicker} from "react-color";
import Viewer from "./viewer";
import { useSnackbar } from 'notistack';
import type {ElementsOfObject, QuestionProps} from "../questionTypes"
export default ({stockroom = [], focus, changeFocus, changeText, changeBgColor, createObject, deleteObject, getIndexById}: any) => {
const { enqueueSnackbar, closeSnackbar } = useSnackbar();
let current
if (focus !== undefined) {
const index = getIndexById(focus, stockroom)
if (index !== undefined) {
current = stockroom[index]
}
}
return(
<>
<ChromePicker
disableAlpha
color={
current === undefined ?
""
:
focus === undefined ?
""
:
current.color
}
onChange={e => {changeBgColor(e.hex)}}
/>
<Button
onClick={() => {
createObject({text: "", color: "", isFocus: true})
}}
>Добавить</Button>
<Textarea
onChange={(e) => changeText(e.target.value)}
placeholder="Текст кнопки"
maxWidth="300px"
value={
current === undefined ?
""
:
focus === undefined ?
""
:
current.text
}
/>
{
stockroom.length === 0 ?
null
:
<VStack style={{
boxShadow:"rgba(0, 0, 0, 0.3) 0px 0px 2px, rgba(0, 0, 0, 0.3) 0px 4px 8px",
padding:"5px",
width:"150px",
borderRadius:"4px",
maxHeight:"30vh",
overflow:"auto",
}}>
<Viewer
stockroom={stockroom}
changeFocus={changeFocus}
deleteObject={deleteObject}
/>
</VStack>
}
</>
)
}

@ -1,57 +1,62 @@
import React from 'react';
import {
Select, Checkbox, Button,
Select, Checkbox, Button, Box
} from '@chakra-ui/react'
import {TextField} from "./createQuestion";
import Description from "./description"
import type {QuestionProps} from "./questionTypes"
export default ({type, stockroom = [], changeFocus} : any) => {
switch(type) {
case 0://Тип вопроса - текст?
return (<TextField name="text" placeholder="текст" type="text" />)
export default ({element, stockroom = [], changeFocus, keyInfo} : any) => {
switch(element.type) {
case 0://Тип элемента вопроса - текст?
return (<TextField name="text" placeholder="текст" type="text" key={keyInfo}/>)
break;
case 1://Тип вопроса - селект?
case 1://Тип элемента вопроса - селект?
return (
<Select>
{
stockroom.map((e: any, i: number) => {
return <option key={i}>{e.text}</option>
})
}
</Select>
// <Select>
// {
// stockroom.map((e: any, i: number) => {
// return <option key={i}>{e.text}</option>
// })
// }
// </Select>
<></>
)
break;
case 2://Тип вопроса - чекбокс?
case 2://Тип элемента вопроса - чекбокс?
return(
<>
{
stockroom.map((e:any, i:number) => {
return <Checkbox key={i}>{e.text}</Checkbox>
})
}
{/*{*/}
{/* stockroom.map((e:any, i:number) => {*/}
{/* return <Checkbox key={i}>{e.text}</Checkbox>*/}
{/* })*/}
{/*}*/}
</>
)
break;
case 3://Тип вопроса - файл?
return (<input type="file"/>)
case 3://Тип элемента вопроса - файл?
return (<input type="file" key={keyInfo}/>)
break;
case 4://Тип вопроса - кнопка?
case 4://Тип элемента вопроса - кнопка?
return(
<>
{
stockroom.map((e:any, i:number) => {
return <Button
backgroundColor={e.color}
key={i}
onClick={(event: any) => {
changeFocus(e.id)
event.target.blur()
}}
>{e.text}</Button>
})
}
</>
<Button
key={keyInfo}
backgroundColor={element.color}
onClick={(event: any) => {
changeFocus(element.id)
event.target.blur()
}}
>{element.text}</Button>
)
break;
case 5://Тип элемента вопроса - описание?
return(
<Box
id={element.id}
border="solid 1px #d2d2d2"
padding="10px"
key={keyInfo}
/>
)
break;
default:

@ -0,0 +1,64 @@
import React from 'react';
import { Button, VStack, HStack, Textarea} from "@chakra-ui/react";
import {ChromePicker} from "react-color";
import Viewer from "./viewer";
import { useSnackbar } from 'notistack';
import type {ElementsOfObject, QuestionProps} from "./questionTypes"
export default (props: any) => {
const { enqueueSnackbar, closeSnackbar } = useSnackbar();
return(
<>
<ChromePicker
disableAlpha
color={
props.current === undefined ?
""
:
props.focus === undefined ?
""
:
props.current.color
}
onChange={e => {props.changeBgColor(e.hex)}}
/>
<Button
onClick={() => {
props.createObject({text: "", color: "", isFocus: true, type: 0, id: -1, parent: undefined})
}}
>добавить</Button>
<Button
onClick={() => {
props.createObject({text: "контейнер", isFocus: true, type: 7, id: -1, parent: undefined})
}}
>контейнер</Button>
{
props.stockroom.length === 0 ?
null
:
<VStack style={{
boxShadow:"rgba(0, 0, 0, 0.3) 0px 0px 2px, rgba(0, 0, 0, 0.3) 0px 4px 8px",
padding:"5px",
width:"150px",
borderRadius:"4px",
maxHeight:"30vh",
minHeight:"50px",
overflow:"auto",
}}>
<Viewer
stockroom={props.stockroom}
changeFocus={props.changeFocus}
deleteObject={props.deleteObject}
/>
</VStack>
}
</>
)
}

@ -8,11 +8,11 @@ export default (props:any) => {
<>
{
props.stockroom.map((e:any, i:number) => {
console.log(e)
return(
<HStack
key={i}
style={{
cursor:"pointer",
width:"100%",
display: "flex",
@ -23,7 +23,13 @@ export default (props:any) => {
props.changeFocus(e.id)
}}
>
<Text>{e.text}</Text>
{
e.type === 5 ?
<Text>Описание</Text>
:
<Text>{e.text}</Text>
}
<Button
rightIcon={<DeleteIcon />}
onClick={(event:any) => {

@ -3,18 +3,30 @@ import Types from "./types"
import {QuestionProps} from "./questionTypes";
import Description from "./description";
import {TextField} from "./createQuestion";
import {Box} from "@chakra-ui/react";
export default ({type, stockroom, changeFocus} : any) => {
//компонент для разворачивания вёрстки из хранилища
return(
<>
<TextField placeholder="Заголовок" name="title" type="text" />
<Description name="description"/>
<Types
type={type}
stockroom={stockroom}
changeFocus={changeFocus}
/>
</>
)
}
export default ({stockroom, changeFocus} : any) => {
if (stockroom.length !== 0) {
// Перед работой проверяем все вложенности. На основе хранилища с плоскими объектами строится хранилище с вложенностями.
let newStorage:any = []
stockroom.forEach((e:any,i:number) => {
if (e.parent === undefined) {
newStorage.push(e)
} else {
newStorage.forEach()
}
})
return(
<Types
element={stockroom[0]} keyInfo={0} changeFocus={changeFocus}
/>
)
} else {
return null
}
}
// if (e.type === 1 || e.type === 7) {
//
// }