reserved fields

This commit is contained in:
Emma 2023-06-17 11:34:44 -06:00
parent c2357e2706
commit d4999bb2bc
4 changed files with 86 additions and 37 deletions

View File

@ -1,6 +1,9 @@
Start query: ?
- by default, queries search the publication
Query current object: ^
- refers specifically to the object based off of this specific type
Query relative object: $
- refers to the last relative object in the heirarchy
Access child: .
- this also maps over all items in a list and returns a list of the relevant children
- if the parent is a list, it will return a list of just the specified child

View File

@ -1,9 +1,10 @@
import { FC, useCallback, useEffect } from 'react'
import { FC, useCallback, useEffect, useState } from 'react'
import { FieldType, FieldTypes, fieldTypeOptions, fieldTypesWithValues } from '../../types/schema'
import { useObjectStateWrapper } from '../../hooks/useObjectState';
import { ValueField } from './value-field';
import { HelpPopper } from '../Poppables/help';
import { Icon } from '../Icon';
import { RESERVED_FIELDS } from '../../constants/ReservedFields';
interface IProps {
update: (arg: FieldType) => void;
@ -13,50 +14,67 @@ interface IProps {
}
export const FieldEditor: FC<IProps> = ({ update, field, fieldName, deleteField }) => {
const { bindProperty, bindPropertyCheck } = useObjectStateWrapper(field, (e) => update(typeof e === 'function' ? e(field) : e))
const { bindProperty, bindPropertyCheck } = useObjectStateWrapper(field, (e) => update(typeof e === 'function' ? e(field) : e));
const shouldShowValueField = useCallback(() => fieldTypesWithValues.includes(field.type) || field.isConstant, [field.isConstant, field.type]);
const [reserved, setReserved] = useState<FieldType | undefined>(RESERVED_FIELDS[fieldName]);
useEffect(() => {
setReserved(RESERVED_FIELDS[fieldName]);
}, [fieldName])
useEffect(() => {
console.log(field.value);
}, [field])
return (
<li className="odd:bg-black/50">
<p>{fieldName}</p>
<div className=" flex gap-x-4 items-center p-2 w-full">
<label className="w-min">
Field Type:&nbsp;
<select className="capitalize" {...bindProperty('type')}>
{fieldTypeOptions.map(o => (
<option className="capitalize" value={FieldTypes[o]}>{o}</option>
))}
</select>
</label>
{shouldShowValueField() && (
<ValueField type={field.type} bind={bindProperty('value')} />
)}
<span className="flex items-center gap-2">
<label><input type="checkbox" {...bindPropertyCheck('isConstant')} /> Is constant</label>
<div className="flex gap-2 items-center">
<p>{fieldName}</p>
{reserved && (
<HelpPopper>
<p className="text-sm">Constant values can't be overwritten in publications. When a dice field is set to a constant value, it instead rolls a dice of that value whenever this field is displayed (unless exported). This could be useful for a randomly generated scenario or for cards being drawn as the dice value will automatically be determined by the dice roll.</p>
<p className="text-xs">This is a reserved field name, these exist for internal purposes, but are still useful when creating a type, and as such have specific settings that you cannot override. If you need control over the field properties, please use a different field name</p>
</HelpPopper>
</span>
<label className="w-min">
Minimum:
<input className="w-12" type="number" {...bindProperty('minimum')} />
</label>
<label className="w-min">
Limit:
<input className="w-12" type="number" {...bindProperty('limit')} />
</label>
<HelpPopper>
<p className="text-sm">Minimum and Limit apply to the number of entries allowed for this field, not the maximum and minimum value. Set the minimum to 0 to make a field optional. Set the limit to 0 to allow for unlimited entries.</p>
</HelpPopper>
<button className="no-default self-end ml-auto" onClick={() => deleteField(fieldName)}>
<Icon className="svg-red-700 hover:svg-red-500 trash-can w-6 h-6" icon="trash"></Icon>
</button>
)}
</div>
{!reserved && (
<div className=" flex gap-x-4 items-center p-2 w-full">
<label className="w-min">
Field Type:&nbsp;
<select className="capitalize" {...bindProperty('type')} disabled={!!reserved}>
{fieldTypeOptions.map(o => (
<option className="capitalize" value={FieldTypes[o]}>{o}</option>
))}
</select>
</label>
{shouldShowValueField() && (
<ValueField type={field.type} bind={bindProperty('value')} />
)}
<span className="flex items-center gap-2">
<label><input type="checkbox" {...bindPropertyCheck('isConstant')} /> Is constant</label>
<HelpPopper>
<p className="text-sm">Constant values can't be overwritten in publications. When a dice field is set to a constant value, it instead rolls a dice of that value whenever this field is displayed (unless exported). This could be useful for a randomly generated scenario or for cards being drawn as the dice value will automatically be determined by the dice roll.</p>
</HelpPopper>
</span>
<label className="w-min">
Minimum:
<input className="w-12" type="number" {...bindProperty('minimum')} />
</label>
<label className="w-min">
Limit:
<input className="w-12" type="number" {...bindProperty('limit')} />
</label>
<HelpPopper>
<p className="text-sm">Minimum and Limit apply to the number of entries allowed for this field, not the maximum and minimum value. Set the minimum to 0 to make a field optional. Set the limit to 0 to allow for unlimited entries.</p>
</HelpPopper>
<button className="no-default self-end ml-auto" onClick={() => deleteField(fieldName)}>
<Icon className="svg-red-700 hover:svg-red-500 trash-can w-6 h-6" icon="trash"></Icon>
</button>
</div>
)}
</li>
)
}

View File

@ -1,4 +1,4 @@
import { useCallback, useEffect } from 'react'
import { FormEvent, useCallback, useEffect } from 'react'
import { FCC } from '../../types'
import { FieldType, FieldTypes, TypeType } from '../../types/schema'
import { useObjectState } from '../../hooks/useObjectState';
@ -23,7 +23,8 @@ export const TypeEditor: FCC<IProps> = ({ saveType, name, type: passedType }) =>
resetType();
}
const addField = useCallback(() => {
const addField = useCallback((e: FormEvent) => {
e.preventDefault();
updateType({
[propertyName]: {
type: FieldTypes.number,
@ -55,8 +56,10 @@ export const TypeEditor: FCC<IProps> = ({ saveType, name, type: passedType }) =>
return (
<div>
<p className="subheader">{passedType ? 'Editing' : 'Creating'} type "{name}"</p>
<input type="text" {...bindPropertyName} />
<button disabled={!propertyName} onClick={addField}>Add Field</button>
<form onSubmit={addField}>
<input type="text" {...bindPropertyName} />
<button disabled={!propertyName}>Add Field</button>
</form>
<ul className="rounded-lg overflow-hidden">
{Object.entries(type).reverse().filter(([k]) => !constantProperties.includes(k)).map(([key, value]) => (
<FieldEditor field={value} update={updateField(key)} fieldName={key} deleteField={deleteField} />

View File

@ -0,0 +1,25 @@
import { FieldType, FieldTypes } from '../types/schema';
export const RESERVED_FIELDS: Record<string, FieldType> = {
maximum: {
isConstant: false,
limit: 1,
minimum: 1,
type: FieldTypes.number,
value: ''
},
minimum: {
isConstant: false,
limit: 1,
minimum: 1,
type: FieldTypes.number,
value: ''
},
relative: {
isConstant: true,
limit: 1,
minimum: 1,
type: FieldTypes.text,
value: '$'
},
}