UI
Baked introduces a metadata generation template which can be used to transform the business domain to UI metadata to be used in dynamic UI applications.
app.Layers.AddUi();
UiLayer provides IComponentDescriptor, IComponentSchema, IData types for
building UI page metadata. A page metadata will have a component descriptor
(represented by a ComponentDescriptorAttribute instance) at the top in the
hierarchy containing Type, Schema, Name and Data properties.
The generated UI metadata files will be saved to
Uifolder at$(OutDir)of your project, you can add below properties to your.csprojfile to copy generated files to given directory<PropertyGroup> <CopyComponentDescriptors>true</CopyComponentDescriptors> <UiAppDir>$(ProjectDir)..\admin</UiAppDir> </PropertyGroup>
Configuration Targets
This layer provides AppDescriptor, ComponentExports, LayerDescriptors
and PageDescriptors configuration target for registering pages using
ComponentDescriptor instances.
AppDescriptor
This target is provided in GenerateCode phase. To configure it in a feature;
configurator.ConfigureAppDescriptor(app =>
{
...
});
ComponentExports
This target is provided in GenerateCode phase. To configure it in a feature;
configurator.ConfigureComponentExports(exports =>
{
...
});
LayoutDescriptors
This target is provided in GenerateCode phase. To configure it in a feature;
configurator.ConfigureLayoutDescriptors(layouts =>
{
...
});
PageDescriptors
This target is provided in GenerateCode phase. To configure it in a feature;
configurator.ConfigurePageDescriptors(pages =>
{
...
});
To access the localization function from a feature use below extension method.
configurator.UsingLocalization(l => { // use this function to add that key to UI project; // l("A localized message") ... });Each call to this function will result
UiLayerto bring that value of given key for every language to the UI project under.baked/folder, e.g.,.baked/locale.en.jsonfile.
To access which keys are going to be brought to UI project from a feature, you can use
UsingLocaleTemplatefunction.configurator.UsingLocaleTemplate(localeTemplate => { ... });
Descriptor Builder System
To generate a page descriptor from a domain model, we provide a descriptor builder system that is added through domain model conventions. There are two builder attributes for this purpose;
ComponentDescriptorBuilderAttribute<TComponentSchema>DescriptorBuilderAttribute<TSchema>
The page generator starts with a Page component path to render a domain model
into a ComponentDescriptor<TComponentSchema> instance. To add a component to a
domain model, for instance to a type, use the AddTypeComponent extension of
IDomainModelConventionCollection;
configurator.ConfigureDomainModelBuilder(builder =>
{
builder.Conventions.AddTypeComponent(
when: c => c.Type...,
where: cc => cc.Path.EndsWith("Page"),
component: (c, cc) => ...
);
});
when:is a predicate function that takesTypeModelMetadataContext cas a parameter and serves as a query to filter typeswhere:is a predicate funtion that takesComponentContext ccas a parameter and is a selector that determines at which component path this convention should be appliedcomponent:is a builder function that takesTypeModelMetadataContext candComponentContext ccas parameters, and is expected to return aComponentDescriptor<TComponentSchema>instance, such asComponentDescriptor<TabbedPage>
AddPropertyComponent, AddMethodComponent and AddParameterComponent
extensions works the same way.
Once you add a component for a domain model at a specific component path, it
will return that component instance when asked at that component path. You may
use GetComponent extension to ask for a component during a component build.
For example, below call asks for a component at ../title path for the type;
type.GetComponent(cc.Drill("Title"))
ComponentContexthas aDrill(...)method that enables you to navigate deeper into component paths.
GetRequiredComponentis also provided to ensure that a component exists at the speficied path for the domain model. Otherwise, it will cause a generation error during post-build phase ofdotnet build.
For non-component schemas, similar extensions are provided for domain models;
AddTypeSchemaAddPropertySchemaAddMethodSchemaAddParameterSchema
Use these extensions to associate domain models with non-component schemas such
as Tab or Input. Once you add a schema for a domain model, you can access it
using GetSchema<TSchema> or GetSchemas<TSchema> extension methods.
GetRequiredSchema<TSchema>is also provided to ensure that a schema exists at that path for that domain model. Otherwise, it will cause a generation error during post-build phase ofdotnet build.
Configuring Existing Schemas
To add a convention that configures an existing schema, there are
Add...ComponentConfiguration<TComponentSchema> and
Add...SchemaConfiguration<TSchema> helpers. Configuration conventions works
exactly the same way add conventions. In addition, to make sure there is a
schema to configure, configuration conventions automatically filter out the
domain models that don't have the given TComponentSchema or TSchema at the
expected component path.
configurator.ConfigureDomainModelBuilder(builder =>
{
// This convention will automatically apply only to the types that have a
// `SimplePage` component
builder.Conventions.AddTypeComponentConfiguration<SimplePage>(
component: sp =>
{
sp.Title = ...;
}
);
});
Bake.vue
Bake.vue is the core utility component that interprets a component descriptor
and sets up the defined component so that it integrates with the rest of the
page.
Data System
Data system allows Bake.vue to fetch data and pass it to the component. Use
Baked.Ui.Datas builder class to create different types of data for a
component. Below you can find some example data usages.
using static Baked.Ui.Datas; // static using is handy for builder classes
...
// inline a static value
Inline("a string");
Inline(new { an: "object" });
// set a dynamic value that is fetched from an api endpoint
Remote("some/endpoint", options: rd => ...);
// set a dynamic value fetched using a composable, `useRoute` in this case
Computed.UseRoute("query");
// set a context value, model in this case
Context.Model();
...
Action System
Action system allows Bake.vue to execute actions upon model change or submit
event of the component. Use Baked.Ui.Actions builder class to create different
types of actions for a component. Below you can find some example action usages.
using static Baked.Ui.Actions;
...
// publishes a page-wide event
Publish.Event("my-button-clicked");
// sets value to a page-wide context with given key
Publish.PageContextValue("my-value");
// redirects app to given route
Local.UseRedirect("/return-page");
// sends configured request to a remote endpoint
Remote("some/endpoint",
// goes to a page after remote action
postAction: Local.UseRedirect("/return-page"),
options: ra => ...
);
...
Reaction System
Reaction system allows Bake.vue to react to publish actions, either event or
page context value. Available reactions are Reload and Show. Below you can
find some example action usages.
using static Baked.Ui.Constraints;
// reacts on an event
component.ReloadOn("my-button-clicked");
// reacts when a page context value changes
component.ReloadWhen("my-value");
// shows/hides component depending on the constraint
component.ShowOn("input-changed", Is("show"));
// shows when `selection` value is valid using a custom validator composable
// `useMyCustomValidator`
component.ShowWhen("selection", Composable.Use("MyCustomValidator"));