Migrate grid views

Syside v1 changes how grid views collect their rows and what an editable matrix writes, in the VS Code Extension and in syside grid export alike. Views written for Syside v0.11 keep working in compatibility mode until you move them to the 1.0 notation. This guide moves them one kind of change at a time.

Before you start:

  • If you don’t have Syside v0.11 table exports, make them now in compatibility mode, as Check the result describes.

  • Fix the model errors Syside v1 reports on its own, which make every view read-only whatever library it uses; a syntax error blocks the views entirely. Migrate SysML models covers them. syside grid export refuses to export a model with errors unless you pass --allow-errors, and it also counts validation errors in Sysand dependencies, which syside check doesn’t report.

  • Views written for a version before Syside v0.11 have to be migrated with Syside v0.11 first. Syside v1 shows an error for them instead of the views (see “This workspace’s views are written for a pre-0.11 version of Syside”).

Know what compatibility mode keeps

A workspace whose SysideViews.sysml is the Syside v0.11 library runs in compatibility mode, whether the copy sits in the workspace or comes from a Sysand dependency or a syside.toml include. Its views render as they did in Syside v0.11 and stay editable unless the model has errors, and no file is rewritten. In the VS Code Extension, a banner in each view says so. Support for compatibility mode will eventually be discontinued, so treat it as time to migrate rather than as a way to stay on 0.11.

Keep one copy of the library per folder you load: two copies in one load each report a global-namespace-distinguishability warning, and in the VS Code Extension they disable the table and matrix views.

A few things differ from Syside v0.11 even in compatibility mode:

  • Elements from files a syside.toml include brings in, and from Sysand dependencies, are read-only in every grid view.

  • A hierarchical table that exposes several roots shows them side by side instead of reporting an error.

  • A matrix whose cellView exposes more than one element opens read-only instead of failing.

  • A usage typed by an abstract definition can be edited.

  • A hierarchical table no longer expands flows, bindings and successions. With includeReferenceElements = true, Syside v0.11 showed rows for their ends.

  • Add Sibling and Add Sub on a row that a single requirement definition doesn’t type create a usage only.

  • columnOrder now also sets the order of the columns in an exported CSV file, and leaves out the columns it doesn’t list. The Syside v0.11 CSV export ignored it and kept the order the columns are declared in, so update anything that reads the CSV by column position.

  • syside grid export exits 4 when any view has nothing to export, after writing the others. Syside v0.11 exited 0.

A workspace with no copy of the library never runs in compatibility mode, and its views list as General views. The SysMLv2 Views panel then offers Add SysideViews.sysml, which adds the 1.0 library. Once it is added, skip the library switch and start at replacing what 1.0 removed.

Switch to the 1.0 library

Run Syside: Update the SysideViews library to 1.0 from the Command Palette, or click Update the SysideViews library to 1.0… on the compatibility-mode banner, and confirm the warning. The update overwrites SysideViews.sysml only, and cannot be undone in the editor: restore the backup or commit to go back. Without the extension, delete the 0.11 SysideViews.sysml and add the 1.0 library from the Sysand index (see Add command). If the folder isn’t a Sysand project yet, run syside project init first (Init command):

syside project add sensmetry/syside-views --version-constraint 1.0.0

The views now load against the 1.0 library. Each name a view uses that 1.0 removed is reported as an error, and every view stays read-only until all of them are replaced.

If the 0.11 copy comes from an installed Sysand package or from a file outside the workspace, the update is refused. Update the library where it is maintained.

Replace what 1.0 removed

Search the workspace for each of these names. Each one no longer resolves, and like any model error it makes every view read-only until it is replaced. A removed name can also raise a second error, such as invocation-expression-instantiated-type or view-usage-types, whose rule text suggests a different fix. The replacement name clears both.

Editable matrix subtypes

EditableMatrixView, ConnectionMatrixView, AllocationMatrixView and RequirementMatrixView are gone. Type the matrix by MatrixView, set isEditable = true, and give the cellView a filter that admits the one kind the subtype created:

// Before
occurrence def Tables {
    view Alloc : MVD::AllocationMatrixView {
        view :>> rowView    { expose Hierarchy::**; }
        view :>> columnView { expose Hierarchy::**; }
        view :>> cellView   { expose Hierarchy; }
    }
}

// After
occurrence def Tables {
    view Alloc : MVD::MatrixView {
        attribute :>> isEditable = true;
        view :>> rowView {
            expose Hierarchy::**;
            filter hastype SysML::PartUsage;
        }
        view :>> columnView {
            expose Hierarchy::**;
            filter hastype SysML::PartUsage;
        }
        view :>> cellView {
            expose Hierarchy;
            filter hastype SysML::AllocationUsage;
        }
    }
}

ConnectionMatrixView becomes the connection usage filter, AllocationMatrixView the allocation usage filter, and RequirementMatrixView the derivation usage filter, all listed in Relationship kinds. A derivation filter names both the #derivation metadata and the usage kind:

view :>> cellView {
    expose Hierarchy;
    filter (
        @ RequirementDerivation::derivation and
        as SysML::ConnectionUsage hastype SysML::ConnectionUsage
    );
}

The metadata alone admits two kinds, and the matrix stays read-only. syside check passes and the export is the same either way, so only the editor shows the difference. A custom subtype of EditableMatrixView takes the filter for whichever kind it was meant to create.

The subtypes also restricted the rows and columns to definitions. In 1.0 an axis is whatever its expose and filter select, so give each axis a kind filter, as above. To keep definition names in the headers, see definitions collected from a tree.

The features and heritage attribute

exposeFeaturesAndHeritage is gone. Its successor, recursiveFeatureExpose, is not a rename: it defaults to true and applies only to recursive exposes (see Table attributes). Replace each occurrence by where it sits.

When the line sits in a view definition, the model reports it there, but the exposes to change are in every view typed by that definition. Find those views and change their exposes too, or the model has no errors and the views show the wrong rows.

Where

= true

= false

Flat table, matrix rowView or columnView

Delete the line and make the expose recursive: expose Cars; becomes expose Cars::**;. The supertypes and typing definitions the flag also listed are no longer rows. Show them in a HeritageList column (see Heritage).

Delete the line. Under expose X::**, the table now also shows features inherited below the first level. Narrow it with a kind filter.

Read-only matrix cellView

Delete the line and make the expose recursive. A non-recursive expose marks no cells.

Delete the line and make the expose recursive. A non-recursive expose marks no cells.

Hierarchical table

Delete the line, and make the expose recursive as described in Hierarchical table exposes.

Delete the line, and make the expose recursive as described in Hierarchical table exposes.

Editable matrix cellView

Delete the line, and keep the expose as it is. A recursive expose makes the matrix read-only.

Delete the line, and keep the expose as it is.

Deleting exposeFeaturesAndHeritage = false takes the 1.0 rows. To keep the 0.11 rows under a recursive expose, replace it with recursiveFeatureExpose = false instead.

A view that set the flag next to a definition-kind filter used it to collect the definitions used in a tree. A recursive expose in 1.0 shows the usages in the tree, not their definitions, so on a matrix axis keep the usages and label them by their definitions:

// Before: definition columns collected from the Vehicle tree
view :>> columnView {
    expose Vehicle;
    attribute :>> exposeFeaturesAndHeritage = true;
    filter istype SysML::Definition;
}

// After: the usages of the Vehicle tree, labeled by their definitions
view :>> columnView {
    expose Vehicle::**;
    attribute :>> representDefinition = true;
    filter hastype SysML::PartUsage;
}

Two usages of one definition are now two columns with the same label. In a flat table that listed definitions this way, expose the definitions directly, such as expose Pkg::*; with a definition-kind filter, or keep the usage rows and add a column with DefinitionsFirst(baseViewElement).

The usage step

The UsageHTV step is gone, because a hierarchical table row is now the usage itself. Replace each call with its argument, and each name that only stood for UsageHTV(…) with baseViewElement:

// Before
ref aNodeUsage = UsageHTV(baseViewElement);
view 'Failure Type' subsets columnViews {
    :>> columnFeature default NamedUsage(aNodeUsage, "failureType", NameType::name);
}

// After
view 'Failure Type' subsets columnViews {
    :>> columnFeature default NamedUsage(baseViewElement, "failureType", NameType::name);
}

A tree column that was redefined only to show UsageHTV(baseViewElement) needs no columnFeature at all.

Hierarchical table exposes

A hierarchical table now shows what its one expose shows (see Expose). Rewrite each 0.11 form:

0.11 view

Shows in 1.0

Rewrite

expose Car;

Car alone, without its tree

expose Car::*::**; for the 0.11 look, or expose Car::**; to add Car as the top row

expose Fleet::*; or expose Fleet::**;, with a filter that kept only Car

One level of Fleet, or nothing

expose Fleet::Car::*::**;

Several exposes

An error

Keep one. For several trees, expose a definition that holds them, as in Build a hierarchical table view.

expose Car; is the form to look for first: it was the usual way to write a hierarchical table, and it still loads without an error. Check the view’s filter at the same time, since a filter that names only definition kinds now keeps only the top row (see Hierarchical tables).

Check what each view shows

The model now loads without errors. These changes leave a view loading but showing something different, so open each one and check that it still shows what it is for.

Hierarchical tables

Rows are features now, not the definitions typing them (see Hierarchical tables):

  • Columns show the usage. A column without a columnFeature, the tree column included, now shows the usage inner, by its qualified name by default, rather than Widget for part inner : Widget. To keep a definition column, navigate with DefinitionsFirst(baseViewElement). Under expose X::** the top row is a definition, so that column shows N/A there. Route every column that reads the definition through DefinitionsFirst, including the steps that start from it, such as HeritageList and NamedUsage. A column left out still reads the usage. A column you redeclare from an inherited table view comes just after the tree column, as in Syside v0.11, so set columnOrder to keep the order. List every column in it: a column it doesn’t list is left out.

  • A column that finds a renamed reserved feature by name finds nothing. If you moved a feature’s name to its short name (see Fix model warnings), a NamedUsage with NameType::name has to use NameType::shortName instead.

  • The filter has to admit every kind on the path. It judges every row and removes a failing row with everything below it. A filter that names only definition kinds now keeps the top row and nothing else, so add the usage kinds of the rows to show:

    // Before
    filter (as SysML::PartDefinition) hastype SysML::PartDefinition
        or (as SysML::ActionDefinition) hastype SysML::ActionDefinition;
    // After: the top row's kind, and the usage kind of every row below it
    filter (as SysML::PartDefinition) hastype SysML::PartDefinition
        or (as SysML::PartUsage) hastype SysML::PartUsage
        or (as SysML::ActionUsage) hastype SysML::ActionUsage;
    

    A filter that names only usage kinds removes the top row under expose X::**, and the whole tree with it. Add the top row’s kind, or expose X::*::**.

  • A tree without a filter shows more. Items, untyped parts and connectors are rows now. Attributes and ports stay hidden, because includeReferenceElements defaults to false. Add a kind filter for what the tree is for.

  • An abstract or reference top row is removed. Set includeAbstractElements or includeReferenceElements to true, or expose X::*::** so the top element is not a row.

  • Wrapper definitions still give a filled top row. A definition that existed only to make the real subject appear as the top row keeps that role. Expose its members, so that the wrapper itself is not a row and its part is the top row:

    // Before
    part def context {
        part top : ElectricVehicle;
    }
    occurrence def Tables {
        view Tree : TVD::HierarchicalTableView { expose context; }
    }
    
    // After
    occurrence def Tables {
        view Tree : TVD::HierarchicalTableView { expose context::*::**; }
    }
    

    The top row is then the usage top, so a DefinitionsFirst(baseViewElement) column shows ElectricVehicle there, as in 0.11. Without the wrapper, expose ElectricVehicle::** makes the definition the top row, where such a column shows N/A, and expose ElectricVehicle::*::** has no top row at all. Delete the wrapper only if no column navigates to the definition.

  • Filters on metadata may stop matching. Every filter term is now evaluated on the usage, so a term such as @Safety where the metadata is applied to the definition may no longer match. Check such views, and move the metadata to the usages or test the definition with hastype if rows are missing.

  • Exported rows gain a level. With a top row, the hierarchical CSV export starts with a 0 line for it and every other level moves down by one. Scripts that read the export need to allow for it.

Flat tables

  • Recursive exposes gain rows. expose X::** now walks every feature, owned and inherited, at every depth, and connectors are rows. Narrow the table with a kind filter.

  • The include flags hide whole branches. A reference or abstract element now hides everything below it, not only itself. See Include flags in grid views.

Matrices

  • Axes can mix kinds. An axis with expose X::** and no filter shows definitions and the usages beneath them. Give each axis a kind filter.

  • Definition axes are no longer marked by connections between usages. A connection between engine and transmission does not mark the Engine × Transmission cell. Switch the axes to the usages with representDefinition = true, or model the relationship as a definition. See Usage and definition traceability.

  • A reference end needs its axis widened. When an end is a reference, such as rSys in allocate a to rSys; with ref part rSys : MySystem; in part def Mission, expose that axis at the reference and set includeReferenceElements = true on it. A usage declared directly in a package counts as a reference too.

    package Deployment {
        private import SysideViews::*;
        part def MySystem;
        part def Mission {
            action a;
            ref part rSys : MySystem;
            allocate a to rSys;
        }
        occurrence def Tables {
            view AllocationMatrix : MVD::MatrixView {
                view :>> rowView    { expose Mission::a; }
                view :>> columnView {
                    expose Mission::rSys::**;
                    attribute :>> includeReferenceElements = true;
                    filter hastype SysML::PartUsage;
                }
                view :>> cellView {
                    expose Mission::*;
                    filter hastype SysML::AllocationUsage;
                }
            }
        }
    }
    

    If a view definition binds includeReferenceElements with =, change it to default there, or the view’s own value is an error (see Check editing).

  • Ports fold onto the path. With portsAreTransparent, a port end now counts as the element the connection reaches it through (a.p1 counts as a), so marks move from definition rows to usage rows. See Port transparency.

  • Weak marks appear in more cells. showWeakTraceability now also follows the path that names an end, and specialization for definitions. See Weak marks.

  • A read-only matrix shows every kind its filter admits. Without a filter, its cells now include connection definitions in scope as well.

Check editing

  • An attribute bound with = in a definition is read-only from usage rows. SysML does not allow a subtype to override a bound value. If it should be editable from usages, change = to default in the definition. This changes the model: the value becomes one that usages can override.

  • Usage rows are editable, and shared rows are locked. An edit on a usage row now writes to that usage, not to its definition. A feature that a definition passes to several usages appears under each of them, and those rows are locked. Edit it in the definition instead. When only one usage shows the feature, its row is not locked, and an edit there writes into the definition, which every other use of that definition then shares.

  • Editable matrices explain what they refuse. Add Traceability appears on an empty cell and Remove Traceability on a marked one. Each is disabled, with the reason on hover, when the cell cannot be written. There is no submenu for choosing the kind of relationship. See What an editable matrix writes.

Check the result

Open each view from the SysMLv2 Views panel. It should open without a compatibility-mode banner or an error banner, which confirms it runs on the 1.0 library.

Then compare the exports from before and after the migration, as described in Compare the exports. Rows that were added or removed should come from changes you made on purpose, such as a new top row or a narrower filter.

Continue with Include flags in grid views for how 1.0 selects rows, or see Troubleshoot grid views if a view still does not load.