🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
Bootcamp:Chapter 16
This page was created by Hans.karlsen on 2023-03-19. Last edited by Wikiadmin on 2026-07-29.

You will reorganize the application menu and build a factory-focused workflow where a factory creates cars for its selected brand.

This chapter continues from Chapter 15. It assumes that the Turnkey application is running and that creating a car assigns a registration number, including the Realtime improvement completed in the previous chapter.

What you will build

A car follows a lifecycle: a CarFactory creates it, and a dealer can later sell it. In this chapter, you will:

  • organize global actions into Views and Admin menu groups;
  • remove the general-purpose New Car action from the car seeker;
  • create a CarFactorySeeker and a document view for one factory;
  • create cars from the selected factory, so that the factory becomes the car owner;
  • associate each factory with one car brand and copy that brand to every car it creates;
  • remove sales-oriented UI from the factory view.

Clean up the main menu

Use the Actions Editor to make the global menu describe what each action is for.

  1. Delete the yellow note in the model.
  2. Open the Actions Editor.
  3. Move these actions to the Views menu group:
    • CarSeeker
    • ShowCarsAndBrands
    • ShowCarsAndBrandsSVG
    • PersonSeekerIAmInControl
  4. Move BrandSeeker to the Admin menu group.
  5. Delete the duplicate PersonSeekerAgain action.
  6. Save the model.

Upload and verify the menu

  1. Open the cloud connection dialog and confirm that the servers are running.
  2. Check whether an upload has pending changes. If no changes are detected, return to MDriven Designer and save the model again.
  3. Select Upload Model so that the Turnkey server receives the changed menu definition.
  4. Open the application and verify that the actions appear in their intended menu groups.

Review action access and deep links

Inspect why CarSeeker requires a login by locating the access group reference on the action.

An access group on an action controls whether the user can launch that action. An access group on a ViewModel controls access to the view itself. Consider both locations when a view can be reached through a deep link: restricting only the launch action does not replace reviewing access to the destination view.

Test the current car workflow by creating and saving a car. Confirm that a registration number is assigned soon after save, as configured in Chapter 15.

Create a seeker for factories

A seeker is a ViewModel that lists objects and lets the user select one. Create a seeker for CarFactory objects.

  1. Create a new ViewModel named CarFactorySeeker.
  2. Set its class to CarFactory.
  3. Select UI-First, then select Copy Seeker Autoform. This creates an initial seeker layout and a corresponding global action.
  4. In the seeker result, remove the columns for:
    • AsString
    • ChangeTime
    • CreateTime
    • Guid
  5. Keep Name.
  6. Locate the global action created by Copy Seeker Autoform and assign it to the Views menu group.
  7. Save the model.

Add Create Factory

Create a ViewModel action named CreateFactory. Set its execute expression to create a factory and give it a recognizable name:

let f=CarFactory.Create in
(
  f.Name:='NewFactory'
)

Save and upload the model. Open CarFactorySeeker, select Create Factory, and save. Verify that a factory named NewFactory appears in the result.

Create the factory document view

A document ViewModel displays one selected object. Create one for a specific factory.

  1. In the ViewModel Editor, add a class action named ShowFactory for CarFactory.
  2. Create a ViewModel named CarFactoryView.
  3. Set its class to CarFactory and select Requires Root. The view needs a root object because it will show one factory.
  4. Return to ShowFactory and set Bring Up ViewModel to CarFactoryView.
  5. Set ViewModel RootObject to self so the selected factory is supplied as the root object.
  6. Save.
  7. Open CarFactoryView, select UI-First, and choose Copy Document Auto Form.
  8. Remove unwanted generated widgets and columns from the document layout.

You can remove unwanted UI at different levels: remove a ViewModel column when the field should not be part of the ViewModel, or remove or reposition its widget when you want to change only the presentation. Keep the layout focused on factory data and the factory's cars.

Remove New Car from the car seeker

The general car seeker should no longer create cars. Open CarSeeker, inspect its actions, and delete its NewCar action.

In CarFactoryView, add a ViewModel action named NewCar. Its execute expression must create a car and assign the current factory as its owner:

let c=Car.Create in
(
  c.CarOwner:=vCurrent_CarFactoryView
)

In the CurrentlyOwnedCars grid, remove these columns:

  • AsString
  • ChangeTime
  • CreateTime
  • Guid

Keep RegistrationNumber and State.

Save and upload the model. In the application, select a factory from CarFactorySeeker and verify that it opens CarFactoryView. Use New Car, save, and verify that the new car receives a registration number.

Associate a factory with a brand

A factory produces one brand, while a brand can have many factories. Add an association in the main class diagram between CarFactory and BrandOfCar:

Association end Cardinality Meaning
CarFactory → BrandOfCar 0..1 A factory produces zero or one selected brand.
BrandOfCar → CarFactories 0..* One brand can have many factories.

For example, several factories can produce BMW cars, but an individual BMW factory has one selected brand.

After adding the association, right-click Car and use Changed by – Cross Reference to locate the dependency on VMAction:CarFactoryView:NewCar. This helps you find the action that must be updated when the factory's brand is added to the car-creation workflow.

Set the car brand when creating a car

Amend the NewCar action in CarFactoryView. In addition to setting CarOwner, assign the new car's BrandOfCar from the current factory:

let c=Car.Create in
(
  c.CarOwner:=vCurrent_CarFactoryView;
  c.BrandOfCar:=vCurrent_CarFactoryView.BrandOfCar
)

Save the action.

Let the user select the factory brand

In CarFactoryView, add a ComboBox for the BrandOfCar association:

  1. Right-click in the view and add a ComboBox (Singlelinks with setter).
  2. Configure it to list BrandOfCar objects and assign the selected object to the CarFactory single association.
  3. Drag the BrandOfCar widget to the appropriate position in the grid.
  4. Save the model.

The new association changes the database schema. Open the cloud connection dialog and select Changes. Confirm that the schema update includes a foreign-key column in CarFactory for the selected BrandOfCar. Select Upload Model, then use Check Server Status to confirm that the database evolution completed.

Show the brand in the factory car list

Add the created car's brand to the CurrentlyOwnedCars grid:

  1. Open CarFactoryView in the ViewModel Editor.
  2. Scroll to CurrentlyOwnedCars.
  3. Right-click the grid and select Add column.
  4. Select BrandOfCar, then select BrandOfCar.Name : String.
  5. Change the display name to Brand.
  6. Save and test the application.

Select a brand on a factory, create a car from that factory, save, and verify that the car row shows the selected brand.

Make destructive actions unambiguous

In a factory document, the default Delete This action deletes the factory, not a car in the car list. Rename it so the scope is clear:

  1. In CarFactoryView, double-click the Delete This action.
  2. Rename it to Delete This Factory.
  3. Save and upload the model.
  4. Refresh the web application and verify the changed label.

If the label does not change in the application after saving, upload the model through the cloud connection dialog. Saving the local model does not by itself update the running Turnkey application.

Remove actions and UI that do not belong in the factory workflow

Review the ShowFactory action on CarFactoryView. In this location it does not add value because the user is already viewing the selected factory. Use the action's opt-out setting in this position to remove the unnecessary option while retaining the action where it is needed elsewhere.

Create and save several cars, for example five, from a factory. Verify that each saved car receives a unique registration number.

A factory creates cars; it does not purchase them. Remove the DocumentForSales grid and the controls that belong to it from CarFactoryView. Save and upload the model.

InitiateSale is not available in this factory workflow at this point. The sales flow requires the relevant sales context rather than a factory that owns newly created cars.

Completion checklist

  • Global actions are organized under Views and Admin.
  • CarFactorySeeker lists factories by name and provides Create Factory.
  • Selecting a factory opens CarFactoryView.
  • New Car is available from the factory view, not from CarSeeker.
  • A factory can have one selected brand.
  • Creating a car from a factory sets both its owner and its brand from that factory.
  • The factory's car list shows registration number, state, and brand.
  • The factory delete action is explicitly named Delete This Factory.
  • Sales-specific UI has been removed from the factory view.

See also