// import dependencies
import { TabContext, TabList, TabPanel } from '@mui/lab';
import React, { useRef, useState, useEffect } from 'react';
import { Modal, Icon, Query, Color, View, Box, Tab, FormGroup, FormControlLabel, Switch, Stack, Button, TextField } from '../';
// colors
import colors from '../colors';
// let context
let DashupContext = null;
// global timer
let timer;
// global debounce
const debounce = (func, timeout = 1000) => {
// return debounced
return (...args) => {
// clear timeout previously
clearTimeout(timer);
// create new timeout
timer = setTimeout(() => func(...args), timeout);
};
};
// create menu component
const DashupUIFormConfig = (props = {}) => {
// get struct
const struct = props.getFieldStruct(props.field?.type);
// tabs
const [named] = useState(!!(props.field.name || '').length);
const [tab, setTab] = useState('config');
const [field, setData] = useState(props.field);
const [color, setColor] = useState(false);
const [loading, setLoading] = useState(!props.value && !!field?.default && struct?.data?.actions?.includes('sanitise'));
const [defaultValue, setDefaultValue] = useState(struct?.data?.actions?.includes('sanitise') ? null : field?.default);
// use ref
const colorRef = useRef(null);
const labelRef = useRef(null);
// to label
const toName = (text) => {
// return cammelcase
return text
.replace(/[\W_]+/g, ' ') // remove non alpha numeric
.replace(/^[0-9]+/g, '') // remove leadingnumbers
.replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => {
// uppercase words
return index === 0 ? word.toLowerCase() : word.toUpperCase();
})
.replace(/\s+/g, '') // remove spaces
};
// set field
const setField = (field, key, value) => {
// check object
let obj = {[key]:value};
// check type
if (typeof key === 'object') obj = key;
// set values
Object.keys(obj).forEach((key) => {
field[key] = obj[key];
});
// save
setData({ ...field });
// save
debounce(props.setField, 200)(field, field);
};
// on label
const onLabel = (e) => {
// opts
const opts = {
label : e.target.value,
};
// name
const name = toName(e.target.value);
// if name includes
if (!field.name || !named) {
opts.name = name;
}
// set field
setField(field, opts);
};
// on default
const onDefault = async (val) => {
// set default
setDefaultValue(val);
// check submit
if (struct?.data?.actions?.includes('submit')) {
// set value
const { value } = await props.dashup.action({
type : 'field',
page : props.page.get('_id'),
struct : struct?.type,
}, 'submit', field, val);
// set val
val = value;
}
// set field
setField(field, 'default', val);
};
// check default value
useEffect(() => {
// check struct actions
if (typeof field?.default === 'undefined') return setLoading(false);
if (!struct?.data?.actions?.includes('sanitise')) return setLoading(false);
// loading
setLoading(true);
// load value
props.dashup.action({
type : 'field',
page : props.page.get('_id'),
struct : struct?.type,
}, 'sanitise', field, field?.default).then((data) => {
// check data
if (!data || !data.sanitised) return setLoading(false);
// set value
setDefaultValue(data.sanitised);
// loading default
setLoading(false);
});
}, [field?.type, field?.uuid]);
// use effect
useEffect(() => {
// use effect
labelRef.current?.focus();
}, []);
// tabs
const tabs = struct?.data?.tabs || ['config'];
// return modal
return !!(field && struct) && (
<>
onLabel(e) }
fullWidth
/>
setField(field, 'name', toName(e.target.value), true) }
fullWidth
/>
setField(field, 'placeholder', e.target.value, true) }
/>
setField(field, 'help', e.target.value, true) }
/>
setTab(v.toLowerCase()) }>
{ tabs.map((t, i) => {
// return jsx
return ;
}) }
{ tabs.map((t, i) => {
// return jsx
return (
{ `${t}`.toLowerCase() === 'display' && (
<>
setField(field, 'readOnly', val) }
getFieldStruct={ props.getFieldStruct }
/>
setField(field, 'viewOnly', val) }
getFieldStruct={ props.getFieldStruct }
/>
>
) }
{ `${t}`.toLowerCase() === 'config' && (
<>
{ !!struct?.data?.multiple && (
setField(field, 'multiple', e.target.checked, true) } /> } label="Allow Multiple" />
) }
{ !!struct?.data?.default && !loading && (
onDefault(val),
} }
/>
) }
>
) }
);
}) }
{ !!color && setColor(false) } onChange={ (hex) => setField(field, 'color', hex.hex === 'transparent' ? null : hex) } /> }
>
);
};
// consumer wrapper
const DashupUIFormConfigWrap = (props = {}) => {
// return JSX
return (
{ (data) => (
) }
);
};
// export default page menu
export default (ctx) => {
// use context
DashupContext = ctx;
// return actual component
return DashupUIFormConfigWrap;
};