Skip to main content

YamlEditor Component Documentation

1. Overview

The YamlEditor is a comprehensive, multi-tabbed interface for creating and managing data model schemas in YAML format. It provides a structured environment for defining different aspects of a model, including its core properties, database schema, table and form presentations, layouts, and printing templates. The editor is divided into logical tab groups:
  • Core Schema: Define the fundamental fields for vue (data model), table, form, view, and db contexts.
  • Layouts: Visually or textually design the layout for forms and views.
  • Printing: Configure document templates, print layouts, and page settings, with a live preview.
  • DB Object Schema: Define database-specific object schemas, including primary keys and field mappings.
It features live previews, synchronization tools, and the ability to load schemas from files or pasted text, making it a powerful tool for rapid application development.

2. Props

The YamlEditor component is configured through a set of props. They are categorized below for clarity.

Data & Configuration Props

These props are used to pass the initial data and configuration to the editor. The component uses the .sync modifier (or v-model in Vue 3) to emit updates back to the parent.
Prop NameTypeRequiredDefaultDescription
fieldConfigObject, Arraytrue-An object defining the available properties and options for each field type in the PropertyEditor (e.g., configuration for ‘text’, ‘select’, ‘number’ fields).
modelNameStringtrue-The name of the model being edited. Used for context, often passed to child components.
yamlDataPropObjecttrue-The main schema object containing keys like vue, table, form, and view. Use .sync for two-way binding.
yamlDbDataPropArray, Objecttrue-The array of fields for the database schema (db tab). Use .sync for two-way binding.
dbObjectSchemaPropObjectfalse{ primary_key: '', fields: {} }The schema for the DB Object editor, defining primary keys and field details. Use .sync for two-way binding.
printSettingPropObjecttrue-An object containing page setup configurations for printing (margins, pagination, etc.). Use .sync for two-way binding.
formLayoutPropStringfalse''The raw YML string for the form layout. Used by the text-based layout editor. Use .sync.
viewLayoutPropStringfalse''The raw YML string for the view layout. Used by the text-based layout editor. Use .sync.
formLayoutYmlPropStringfalse''YML output from the visual form layout editor. Use .sync.
formLayoutHtmlPropStringfalse''HTML output from the visual form layout editor. Use .sync.
formLayoutBladePropStringfalse''Blade template output from the visual form layout editor. Use .sync.
formLayoutMarkdownPropStringfalse''Markdown output from the visual form layout editor. Use .sync.
viewLayoutYmlPropStringfalse''YML output from the visual view layout editor. Use .sync.
viewLayoutHtmlPropStringfalse''HTML output from the visual view layout editor. Use .sync.
viewLayoutBladePropStringfalse''Blade template output from the visual view layout editor. Use .sync.
viewLayoutMarkdownPropStringfalse''Markdown output from the visual view layout editor. Use .sync.

These props manage the content for different sections of the print template. All use the .sync modifier.
Prop NameTypeDefaultDescription
printBodyPropString''The main body content of the print template.
printHeadFirstPagePropString''Special header content only for the first page.
printHeadLeftPropString''Content for the left side of the header.
printHeadRightPropString''Content for the right side of the header.
printFooterFullPropString''Content spanning the full width of the footer.
printFooterLeftPropString''Content for the left side of the footer.
printFooterCenterPropString''Content for the center of the footer.
printFooterRightPropString''Content for the right side of the footer. Note: Not in component template but good to have for consistency.

Tab Visibility Props

These boolean props control which tabs are visible in the editor interface.
Prop NameTypeDefaultDescription
showVueTabBooleantrueToggles visibility of the ‘vue’ schema tab.
showTableTabBooleantrueToggles visibility of the ‘table’ schema tab.
showFormTabBooleantrueToggles visibility of the ‘form’ schema tab.
showViewTabBooleantrueToggles visibility of the ‘view’ schema tab.
showDbTabBooleantrueToggles visibility of the ‘db’ schema tab.
showDbObjectSchemaTabBooleantrueToggles visibility of the ‘db object schema’ tab.
showFormLayoutTabBooleantrueToggles visibility of the form layout tabs.
showViewLayoutTabBooleantrueToggles visibility of the view layout tabs.
showDocumentTemplateTabBooleantrueToggles visibility of the ‘document template’ tab.
showPrintTemplateTabBooleantrueToggles visibility of the ‘print template’ tab.
showPageSetupTabBooleantrueToggles visibility of the ‘print preview’ tab.
showYmlTabBooleantrueToggles visibility of the main ‘yml’ output tab.
showDbYmlTabBooleantrueToggles visibility of the ‘db yml’ output tab.
showPrintYmlTabBooleantrueToggles visibility of the ‘print yml’ output tab.
showPageSetupYmlTabBooleantrueToggles visibility of the ‘page setup yml’ tab.

URL Props

These props define the API endpoints required for certain features to function.
Prop NameTypeRequiredDescription
formPreviewUrlStringtrueURL to fetch the rendered HTML for the form layout preview.
viewPreviewUrlStringtrueURL to fetch the rendered HTML for the view layout preview.
renderPreviewUrlStringtrueURL to render the print preview HTML from template and schema data.
fileTreeUrlStringtrueURL to fetch the directory structure of available YAML files to load.
loadYamlUrlStringtrueURL to load the content of a selected YAML file.

3. Emitted Events (.sync)

The YamlEditor is designed to work with two-way data binding. It emits update:propName events for all data-related props. When using this component, you should use the .sync modifier (Vue 2) or v-model:propName (Vue 3) on the corresponding props to ensure data is updated in the parent component. Example using .sync (Vue 2):
<YamlEditor
  :yaml-data-prop.sync="myYamlData"
  :yaml-db-data-prop.sync="myDbData"
  :print-setting-prop.sync="myPrintSettings"
  ...
/>

4. Usage Example

Here is a complete example of how to integrate the YamlEditor into a parent Vue component.
<!-- ParentComponent.vue -->
<template>
  <div id="app">
    <h1 class="mb-4">Product Schema Manager</h1>
    <YamlEditor
      :model-name="'Product'"
      :field-config="fieldConfig"
      :yaml-data-prop.sync="yamlData"
      :yaml-db-data-prop.sync="yamlDbData"
      :db-object-schema-prop.sync="dbObjectSchema"
      :print-setting-prop.sync="printSettings"
      :print-body-prop.sync="printBody"
      :form-layout-prop.sync="formLayout"
      :view-layout-prop.sync="viewLayout"
      :form-preview-url="'/api/preview/form'"
      :view-preview-url="'/api/preview/view'"
      :render-preview-url="'/api/preview/print'"
      :file-tree-url="'/api/files/tree'"
      :load-yaml-url="'/api/files/load'"
    />

    <div class="mt-5">
      <h4>Live Data in Parent Component:</h4>
      <pre><code>{{ JSON.stringify(yamlData, null, 2) }}</code></pre>
    </div>
  </div>
</template>

<script>
import YamlEditor from './components/YamlEditor.vue';

export default {
  name: 'ParentComponent',
  components: {
    YamlEditor,
  },
  data() {
    return {
      // Configuration for the property editor
      fieldConfig: {
        types: [ 'text', 'number', 'boolean', 'date', 'select' ],
        sections: {
          vue: {
            properties: [ 'model', 'type', 'default', 'label' ]
          },
          table: {
            properties: [ 'name', 'label', 'show', 'sort', 'filter' ]
          },
          form: {
            properties: [ 'model', 'label', 'type', 'create', 'edit' ]
          },
          // ... other sections
        }
      },

      // Initial main schema data
      yamlData: {
        vue: [
          { model: 'product_name', type: 'string', default: '', label: 'Product Name' },
          { model: 'price', type: 'number', default: 0, label: 'Price' }
        ],
        table: [
          { name: 'product_name', label: 'Product Name', show: true, sort: true },
          { name: 'price', label: 'Price', show: true, sort: true }
        ],
        form: [
          { model: 'product_name', label: 'Product Name', type: 'text', create: true, edit: true },
          { model: 'price', label: 'Price', type: 'number', create: true, edit: true }
        ],
        view: [
          { model: 'product_name', label: 'Product Name', type: 'text' },
          { model: 'price', label: 'Price', type: 'text' }
        ]
      },

      // Initial DB schema data
      yamlDbData: [
        { name: 'product_name', type: 'string', nullable: false, api: { show: true } },
        { name: 'price', type: 'decimal', default: 0, api: { show: true } }
      ],

      // Initial DB Object Schema data
      dbObjectSchema: {
        primary_key: 'id',
        fields: {
            id: { type: 'increments', name: 'id' }
        }
      },

      // Initial layout and print data
      formLayout: "rows:\n  - columns:\n      - fields: ['product_name']\n      - fields: ['price']",
      viewLayout: "rows:\n  - columns:\n      - fields: ['product_name', 'price']",
      printSettings: {
        margins: { top: '20mm', bottom: '20mm', left: '10mm', right: '10mm' }
      },
      printBody: "<h1>Product Details</h1><p>Name: {{ product_name }}</p><p>Price: {{ price }}</p>",
    };
  }
};
</script>

<style>
/* Add bootstrap or other global styles if needed */
@import"https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css";
pre {
  background-color: #f4f4f4;
  padding: 1rem;
  border-radius: 5px;
  white-space: pre-wrap;
}
</style>