74 lines
3.0 KiB
TypeScript
74 lines
3.0 KiB
TypeScript
import { FC, useCallback } from 'react'
|
|
import { FieldType, FieldTypes, Schema, TypeType, fieldTypesWithValues } from '../../types/schema'
|
|
import { Truncate } from '../Poppables/truncation';
|
|
import { Accordion, AccordionContent } from '../../lib/accordion';
|
|
|
|
interface IProps {
|
|
schema: Schema;
|
|
onTypeClick?: (arg: string, arg1: TypeType) => void;
|
|
}
|
|
|
|
export const SchemaViewer: FC<IProps> = ({ schema, onTypeClick }) => {
|
|
|
|
const createValueLable = useCallback((field: FieldType) => {
|
|
if (field.isConstant) {
|
|
if (field.type === FieldTypes.dice) return 'Auto-rolled'
|
|
return 'Constant value:'
|
|
}
|
|
switch (field.type) {
|
|
case FieldTypes.type: return 'Type:'
|
|
case FieldTypes.dice: return 'Dice:'
|
|
case FieldTypes.select: return 'Options:'
|
|
default: return '';
|
|
}
|
|
}, [])
|
|
|
|
return (
|
|
<>
|
|
{/* <div className="whitespace-pre-wrap">{JSON.stringify(schema, null, 2)}</div> */}
|
|
<div>
|
|
<p className="font-bold text-lg">{schema.name}</p>
|
|
<hr />
|
|
<p className="font-bold italic">Templates</p>
|
|
<ul>
|
|
{Object.entries(schema.templates).map(([templateKey, template]) => (
|
|
<li>
|
|
<p className="font-bold">{templateKey}</p>
|
|
<p className="font-thin text-xs">{template.type}</p>
|
|
{template.publishable && <p className="font-thin text-xs">This template can create publications</p>}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
<hr />
|
|
<p className="font-bold italic">Types</p>
|
|
<ul className="rounded-lg overflow-hidden grid">
|
|
{Object.entries(schema.types).map(([typeKey, type]) => (
|
|
<li
|
|
key={'type viewer' + typeKey}
|
|
// onClick={() => onTypeClick && onTypeClick(typeKey, type)}
|
|
data-clickable={!!onTypeClick}
|
|
className="odd:bg-black/50 p-2 group overflow-hidden"
|
|
>
|
|
<Accordion
|
|
title={<p className="group-data-[expanded]/controlled:mb-2 transition-all font-bold">{typeKey}</p>}
|
|
>
|
|
<AccordionContent>
|
|
<div className="grid grid-cols-2 gap-2">
|
|
{Object.entries(type).map(([fieldKey, field]) => (
|
|
<div key={'field viewer' + fieldKey} className="rounded-lg border border-olive-drab p-2">
|
|
<p className="font-bold">{fieldKey}</p>
|
|
<p className="font-thin capitalize text-xs">{field.type}</p>
|
|
<p className="font-thin capitalize text-xs">Maximum entries: {field.limit === 0 ? 'unlimited ' : field.limit}</p>
|
|
{(field.isConstant || fieldTypesWithValues.includes(field.type)) && <p className="font-thin capitalize text-xs">{createValueLable(field)} <Truncate>{field.value}</Truncate></p>}
|
|
</div>
|
|
))}
|
|
</div>
|
|
</AccordionContent>
|
|
</Accordion>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
</>
|
|
)
|
|
} |