/metatonic

A dynamic data entry platform/framework

Primary LanguageTypeScriptOtherNOASSERTION

metatonic-platform

Build Status Maintainability Test Coverage

Metatonic is a set of libraries and tools for writing large data entry applications extremely quickly.

App Builder

Code of Conduct

Documentation

Name Coverage/Status NPM
metatonic-core 96% core:npm version
metatonic-react 22% react:npm version
metatonic-redux 46% react:npm version
metatonic-react-redux 0% react:npm version
apps/app-builder Mostly Working
apps/frontend-only Mostly Working
apps/server-rendered-with-database Early Dev
metatonic-server Early Dev
metatonic-metatstore Brainstorming

Everything is still a work in progress. I'd love your help as long as your down with the Code of Conduct

Some things we care about

  • We care about helping you write least code possible, hopefully no code sometimes
  • We care deeply about data entry. Good data is the backbone of so many jobs that matter.
  • We care about you being to create what ever you want. We provide a way to make creating data entry and display parts of your app very quickly. We believe in Configuration and convention.
  • We care about you being to write in the UI framework of your choice. Right now we support React but it's coded to be able to have plugins later for Angular, Vue, Knockout whatever floats your boat. As long as it works well with one way bindings and state managment like redux you should be good.

Examples

Record Editor

@editorFor("record", FieldSet, {isDefault: true})
export class RecordEditor extends BaseEditorModel<{[key:string]:any}, RecordSchemaType, BaseEditorModel<RecordSchemaType>, void> {
    render() {
        let recordType = this.props.field.typeParameters.typeParams as SchemaRecordType;
        let fields = recordType.fields;
        return (<>{
            fields.map(field =>
                <FieldEditor value={this.props.value[field.name]} field={field} context={createContext(field, this.props.context)}/>
            )}
        </>)
    }
}

Input Editor

@editorFor("numeric", InputBoxLabelContainer, { isDefault: true })
export class NumericEditor extends BaseEditor<Numeric, NumericTypeInfo, BaseEditorModel<Numeric>, void> {
    render() {
        return (
            <input type="number"
                   id={this.uniqueId()}
                   value={this.value().toEditorString()}
                   required={this.field().required}
                   max={this.props.field.max || undefined}
                   min={this.props.field.min || undefined}
                   step={1}
                   onChange={this.notifyChanged}
            />
        );
    }
}

Schema from TypeScript class

@model
export class Field {
    @field("text", "Name", SchemaEntryType.entry, { required: true })
    name: string;

    @field("text", "Label", SchemaEntryType.entry, { required: true })
    label: string;
    
    @field("code", "Type", SchemaEntryType.selection, { required: true })
    typeName: string;

    @field("code", "Type", SchemaEntryType.selection, { required: true })
    entryType?: SchemaEntryType;

    @field("boolean", "Multiple", SchemaEntryType.entry, { required: true })
    multiple: boolean;

    @field("boolean", "Required", SchemaEntryType.entry, { required: true })
    required: boolean;

    @field("numeric", "Max Length", SchemaEntryType.entry, { required: false })
    maxLength?: Maybe<number>;

    @field("numeric", "Max", SchemaEntryType.entry, { required: false })
    max?: Maybe<number>;

    @field("numeric", "Min", SchemaEntryType.entry, { required: false })
    min?: Maybe<number>;

    @field("boolean", "Can Add", SchemaEntryType.entry, { required: false })
    canAdd?: boolean;

    @field("boolean", "Can Add", SchemaEntryType.entry, { required: false })
    canEditSelection?: boolean;

    @field("text", "UI Preference", SchemaEntryType.entry, { required: false })
    uiControlPreference?: string;
}