1
0

feat: add table definition fields

This commit is contained in:
Rokas Puzonas 2022-02-05 20:26:40 +02:00
parent db599fa123
commit cb5cad7de6
4 changed files with 171 additions and 27 deletions

View File

@ -10,12 +10,12 @@
}
.App {
padding: 3em;
background-color: #1E1E1E;
color: #CAD6DC;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 1vmin);
color: white;

View File

@ -1,41 +1,34 @@
import { useState } from 'react';
import './App.css';
import TableDefinitionForm from './TableDefinitionForm';
import TableMethodCodeBlock from './TableMethodCodeBlock';
import { TableDefinition } from './TableMethodGenerator';
import TableRenderer from './TableRenderer';
function App() {
let definition: TableDefinition = {
let [definition, setDefinition] = useState<TableDefinition>({
names: ["Miestas", "Atsakingas", "Vardas", "Adresas", "Metai"],
fields: ["City", "Manager", "Name", "Address", "Year"],
widths: [10, 20, 18, 15, 5],
alignments: ["left", "left", "left", "left", "right"]
}
let data = {
method_name: "PrintLocations",
empty_message: "Nėra",
container_type: "LocationsContainer",
entry_name: "l",
entry_type: "Location",
})
let [data, setData] = useState({
definition
};
});
let test_entries = [
["Alytus", "AlytausMuziejusA", "Jonas Jonaitis", "GatveA", "1999"],
["Alytus", "AlytausMuziejusB", "Ona Onaite", "GatveB", "2018"],
["Kaunas", "KaunasMuziejusC", "Jonas Jonaitis", "GatveC", "2004"],
["Klaipėda", "KlaipėdaMuziejusD", "Ona Onaite", "GatveD", "1988"],
];
const onChange = (e: TableDefinition) => {
definition = e
data.definition = e
setDefinition(e)
setData({...data})
}
return (
<div className="App">
<main>
<TableDefinitionForm value={definition} onChange={onChange} />
<hr />
{TableMethodCodeBlock(data)}
<hr />
<TableRenderer definition={definition} entries={test_entries} />
</main>
</div>
);

151
src/TableDefinitionForm.tsx Normal file
View File

@ -0,0 +1,151 @@
import { ChangeEvent, useState } from "react"
import { Alignment, TableDefinition } from "./TableMethodGenerator"
interface TableDefinitionRowProps {
value: Row
onChange?: { (e: Row): void }
}
function TableDefinitionRow(props: TableDefinitionRowProps) {
let [, setName] = useState(props.value.name)
const onChangeName = (e: ChangeEvent<HTMLInputElement>) => {
props.value.name = e.target.value
setName(props.value.name)
if (props.onChange) {
props.onChange(props.value)
}
}
let [, setField] = useState(props.value.field)
const onChangeField = (e: ChangeEvent<HTMLInputElement>) => {
props.value.field = e.target.value
setField(props.value.field)
if (props.onChange) {
props.onChange(props.value)
}
}
let [, setWidth] = useState(props.value.width)
const onChangeWidth = (e: ChangeEvent<HTMLInputElement>) => {
props.value.width = parseFloat(e.target.value)
setWidth(props.value.width)
if (props.onChange) {
props.onChange(props.value)
}
}
let [, setAlignment] = useState(props.value.alighment)
const onChangeAlignment = (e: ChangeEvent<HTMLSelectElement>) => {
props.value.alighment = e.target.value as Alignment
setAlignment(props.value.alighment)
if (props.onChange) {
props.onChange(props.value)
}
}
return (
<li>
<input type="text" value={props.value.name} onChange={onChangeName} />
<input type="text" value={props.value.field} onChange={onChangeField} />
<input type="number" value={props.value.width || props.value.name.length} onChange={onChangeWidth}/>
<select value={props.value.alighment} onChange={onChangeAlignment}>
<option value="right">Right</option>
<option value="left">Left</option>
</select>
</li>
)
}
interface TableDefinitionProps {
value: TableDefinition
onChange?: { (e: TableDefinition): void }
}
interface Row {
name: string
width?: number
field?: string
alighment?: Alignment
}
function intoRows(definition: TableDefinition): Row[] {
const rows: Row[] = []
if (definition.names !== undefined) {
for (let i = 0; i < definition.names.length; i++) {
rows.push({
name: definition.names[i],
width: (definition.widths || [])[i],
field: (definition.fields || [])[i],
alighment: (definition.alignments || [])[i],
})
}
}
return rows
}
function fromRows(rows: Row[]): TableDefinition {
const definition: TableDefinition = {
names: [],
widths: [],
fields: [],
alignments: []
}
for (const row of rows) {
(definition.names as string[]).push(row.name);
(definition.widths as (number|undefined)[]).push(row.width);
(definition.fields as (string|undefined)[]).push(row.field);
(definition.alignments as (Alignment|undefined)[]).push(row.alighment);
}
return definition
}
function TableDefinitionForm(props: TableDefinitionProps) {
let [currentName, setCurrentName] = useState("")
let [rows, setRows] = useState<Row[]>(intoRows(props.value))
const addRow = () => {
rows.push({ name: currentName })
setCurrentName("")
if (props.onChange !== undefined) {
props.onChange(fromRows(rows))
}
}
const updateRow = (i: number, row: Row) => {
if (row.name === "") {
rows.splice(i, 1)
rows = [...rows]
setRows(rows)
} else {
rows = [...rows]
rows[i] = row
setRows(rows)
}
if (props.onChange !== undefined) {
props.onChange(fromRows(rows))
}
}
return (
<form onSubmit={(e) => e.preventDefault()}>
<label>Column:</label>
<input
type="text"
value={currentName}
onChange={(e) => setCurrentName(e.target.value)}
onKeyPress={(e) => e.key === "Enter" && addRow()}
/>
<ol>
{
rows.map((item, i) =>
<TableDefinitionRow key={i} value={item} onChange={(e) => updateRow(i, e)}/>
)
}
</ol>
</form>
)
}
export default TableDefinitionForm

View File

@ -1,4 +1,4 @@
type Alignment = "left"|"right"
export type Alignment = "left"|"right"
export interface TableDefinition {
names?: string[]
@ -21,7 +21,7 @@ export interface TableMethodGeneratorOptions {
function get_total_width(definition: TableDefinition): number {
let names = definition.names || []
if (names.length == 0) { return 0; }
if (names.length === 0) { return 0; }
let total_width = 0
let widths = definition.widths || []
@ -38,7 +38,7 @@ function get_total_width(definition: TableDefinition): number {
export function generate(options: TableMethodGeneratorOptions): string {
const section_names = options.definition.names || []
const method_name = options.method_name || "PrintTable"
if (section_names.length == 0) {
if (section_names.length === 0) {
return `static void ${method_name}()\n{\n}`;
}
@ -60,7 +60,7 @@ export function generate(options: TableMethodGeneratorOptions): string {
const section = section_names[i]
const width = section_widths[i] || section.length
const alighment = section_alignments[i] || "right"
if (alighment == "left") {
if (alighment === "left") {
row_components.push(`{${i},-${width}}`)
} else {
row_components.push(`{${i},${width}}`)
@ -107,7 +107,7 @@ export function generate(options: TableMethodGeneratorOptions): string {
function render_table_row(definition: TableDefinition, entry: string[]): string {
let names = definition.names || []
if (names.length == 0) { return ""; }
if (names.length === 0) { return ""; }
const columns: string[] = []
const alighments = definition.alignments || []
@ -118,7 +118,7 @@ function render_table_row(definition: TableDefinition, entry: string[]): string
const width = widths[i] || names[i].length
const filler = " ".repeat(Math.max(width - value.length, 0));
if (alighment == "left") {
if (alighment === "left") {
columns.push(value + filler);
} else {
columns.push(filler + value);