Add frequently used table columns

Most tables in the Syside VS Code Extension need the same handful of columns: an ID, a name, an attribute value, a piece of documentation, a constraint’s text. Each recipe below is one such column, ready to copy into a view and adapt.

The recipes assume you can add a column to a table view, as Build a table view shows. Chains and representations explain the parts each recipe combines.

Show a name

For aspects of the row element itself, no chain is needed. Pick a representation:

view Name :> columnViews {
    attribute :>> featureRepresentation :> ColRep::declaredName;
}

declaredShortName shows the <…> form (for example a requirement ID), qualifiedName the fully qualified name, and documentation all documentation blocks concatenated.

Show and edit an attribute value

Navigate to the attribute by name, render its value:

view Priority :> columnViews {
    :>> columnFeature = NamedUsage(
        baseViewElement,
        "priority",
        NameType::name,
        UsageKind::attributeUsage
    );
    attribute :>> featureRepresentation :> ColRep::featureValue;
}

The cell edits with an editor picked from the attribute’s declared type (see Editable representations). If the row element does not declare the attribute at all, the cell shows defaultValue and typing into it creates the attribute on save.

Show and edit documentation

specificDocumentation selects one documentation block by name. The default name "" selects the unnamed body. If a requirement carries both a named rationale block and an unnamed body, two columns can surface them independently:

requirement def MaxAltitude {
    doc rationale /* Altitude limit set by local air-traffic regulations. */
    doc /* The drone shall not exceed an altitude of 500 m. */
}

view requirementsTable : TVD::TableView {
    expose DroneProject::DroneSystem::*;
    filter hastype SysML::RequirementDefinition;

    view Rationale :> columnViews {
        attribute :>> featureRepresentation :> ColRep::specificDocumentation {
            attribute :>> documentationName = "rationale";
        }
    }
    view Body :> columnViews {
        attribute :>> featureRepresentation :> ColRep::specificDocumentation;
    }
}

Show and edit constraint text

Navigate the chain to the constraint, then render its language-specific body with the 'language' representation. For a requirement’s require / assume constraint, which is typically unnamed and singular, use the RequirementConstraints family:

requirement def MaxAltitude {
    require constraint altitudeLimit {
        language "English"
            /* The drone shall not exceed an altitude of 500 m. */
    }
}

view Constraint :> columnViews {
    :>> columnFeature = RequirementConstraintsFirst(
        baseViewElement,
        RequirementConstraintKindSV::required
    );
    attribute :>> featureRepresentation :> ColRep::'language';
}

A named constraint can be reached by name instead:

view 'English Constraint' :> columnViews {
    :>> columnFeature = NamedUsage(
        baseViewElement,
        "altitudeLimit",
        NameType::name,
        UsageKind::constraintUsage
    );
    attribute :>> featureRepresentation :> ColRep::'language' {
        attribute :>> languageName = "English";
    }
}

Show the owner

view 'Owning Element' :> columnViews {
    :>> columnFeature = Owner(baseViewElement);
    // qualifiedName is the default representation
}

A column named Owner would shadow the step of the same name, hence the header 'Owning Element'.

Show the heritage

Everything the element inherits from, across all levels and excluding standard-library types, in one read-only cell:

view Heritage :> columnViews {
    :>> columnFeature = HeritageList(baseViewElement);
    attribute :>> featureRepresentation :> ColRep::name;
}

Show the value of any named feature

Without a UsageKind argument, NamedUsage matches a feature of any usage kind. Values of non-attribute features render read-only:

view AssignedComponent :> columnViews {
    :>> columnFeature = NamedUsage(
        baseViewElement,
        "assignedComponent",
        NameType::name
    );
    attribute :>> featureRepresentation :> ColRep::featureValue;
}

Show a value from a metadata tag

MetadataUsageTag selects the row element’s metadata tag by the tag definition’s name. A chained NamedUsage then reaches a value bound inside the tag:

metadata def Safety {
    attribute level;
}

part marked {
    @Safety {
        :>> level = 10;
    }
}

view Level :> columnViews {
    :>> columnFeature = NamedUsage(
        MetadataUsageTag(baseViewElement, "Safety", NameType::name),
        "level",
        NameType::name
    );
    attribute :>> featureRepresentation :> ColRep::featureValue;
}

On an untagged row the chain stops at the MetadataUsageTag step, so the cell shows notApplicableValue.

Show the requirement’s subject

view 'Subject Name' :> columnViews {
    :>> columnFeature = Subject(baseViewElement);
    attribute :>> featureRepresentation :> ColRep::name;
}

For a row that is not a requirement, the cell shows notApplicableValue.

Fan each row out into one row per port

A Fan step fans each row out into several rows, one per target. It must be declared once at view level as a named navigation, called an anchor, which columns then navigate from:

view partsTable : TVD::TableView {
    expose DroneProject::DroneSystem::*;
    filter hastype SysML::PartUsage;

    ports = UsageFan(baseViewElement, UsageKind::portUsage);

    view Part :> columnViews {
        attribute :>> featureRepresentation :> ColRep::declaredName;
    }
    view Port :> columnViews {
        :>> columnFeature = ports;
        attribute :>> featureRepresentation :> ColRep::declaredName;
    }
    view 'Port Documentation' :> columnViews {
        :>> columnFeature = ports;
        attribute :>> featureRepresentation :> ColRep::specificDocumentation;
    }
}

Each part row fans out into one row per port. The Part cell is merged across its fanned-out rows. See Fanning a row out.

Check a new column

Open the view from the SysMLv2 Views panel after adding a column. Each row should show the value the recipe describes. A cell showing the column’s notApplicableValue means the chain found no element on that row, which is expected for rows the recipe does not apply to, such as a part in a Subject column (see Cell outcomes).

Continue with Table navigation chains to write chains of your own, or see A column shows an error, not values if a column shows an error instead of values.