Quickstart

This guide will get you up and running with Xams and covers the following:

  • Creating a Xams Api project
  • Creating a Xams NextJS \ React project
  • Creating tables
  • Displaying and creating records from a datatable
  • Writing service logic
  • Creating forms

Prerequisites

Install EF Core Tools

Ensure you have version 8+ of the Entity Framework Core tools installed.

Terminal

dotnet tool install --global dotnet-ef

Install Xams CLI

Install the Xams CLI if you haven't installed it yet.

Terminal

dotnet tool install --global Xams.Cli --version 1.0.3

Create Api Project

  1. Create the directory you want your project to live in.
  2. Open the command prompt or terminal in the directory.
  3. Execute the Xams CLI. Choose Create Api Project.

Terminal

xams-cli
  1. Enter your email address. A project key will be sent.
  2. Enter the project key.
  3. Enter the name of your project. All of the c# project will be prefixed with this name.
  4. Open the solution in your IDE of choice. The projects contained in this solution are:
  • Project.Common: Classes shared across projects including Entities
  • Project.Data: Entity Framework migrations as well as the DbContext
  • Project.Services: All service layer logic
  • Project.Web: The api endpoints
  1. The project is configured to use SQLite by default. Run the following commands in the Project.Data folder to create the first migration and update the database.

Terminal - / Project.Data

dotnet ef migrations add migration01
dotnet ef database update
  1. Run the project using HTTPS. The project will launch the Admin Dashboard automatically. It may take a moment to start.

Create NextJS Project

  1. Open the command prompt or terminal in the directory to create the React \ NextJS project.
  2. Execute the Xams CLI. Choose Create React \ NextJS Project.

Terminal

xams-cli
  1. Enter your email address. A project key will be sent.
  2. Enter the project key.
  3. Enter the name of your web app. A folder with the name of your web app will be created and includes all of the web app files.
  4. Open the folder in your code editor of choice.
  5. In the directory of the web app execute the following code.

Terminal

npm install && npm run dev
  1. With the Api running, open the NextJS project in the browser (http://localhost:3000?userid=f8a43b04-4752-4fda-a89f-62bebcd8240c)

Create an Entity

  1. In the "Common" project create a new class file in the Entities folder and name it "Widget.cs"
  2. Paste the below code in the file.

Project.Common / Entities / Widget.cs

[Table("Widget")]
public class Widget
{
public Guid WidgetId { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
  1. Add the Widget class to the DataContext class.

Project.Data / DataContext.cs

public class DataContext : BaseDbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<Permission> Permissions { get; set; }
public DbSet<RolePermission> RolePermissions { get; set; }
public DbSet<Team> Teams { get; set; }
public DbSet<TeamUser> TeamUsers { get; set; }
public DbSet<TeamRole> TeamRoles { get; set; }
public DbSet<UserRole> UserRoles { get; set; }
public DbSet<Option> Options { get; set; }
public DbSet<Setting> Settings { get; set; }
public DbSet<Common.Entities.System> Systems { get; set; }
public DbSet<Job> Jobs { get; set; }
public DbSet<JobHistory> JobHistories { get; set; }
public DbSet<Audit> Audits { get; set; }
public DbSet<AuditField> AuditFields { get; set; }
public DbSet<AuditHistory> AuditHistories { get; set; }
public DbSet<AuditHistoryDetail> AuditHistoryDetails { get; set; }
public DbSet<Widget> Widgets { get; set; } // <-- Add this
}
  1. In the Project.Data directory execute the code below to create a migration and update the database.

Terminal

dotnet ef migrations add migration02
dotnet ef database update
  1. Start the project

Create a Datatable

  1. Paste the following code in index.tsx

src / pages / index.tsx

import { DataTable } from '@ixeta/xams'
import React from 'react'
const Index = () => {
return (
<div className="h-96 w-[500px] p-10">
<DataTable tableName="Widget"></DataTable>
</div>
)
}
export default Index

This will create the following table.

If you click the "Add" button on the table, a form will open where a new record can be created.

Add Service Logic

We can have the service layer automatically set a price for the Widget based on the number of Widgets in the database.

  1. Create a new class file in the Project.Services/ServiceLogic folder. Name it "WidgetService.cs"
  2. Replace the class in the file with the code below.

Project.Services / ServiceLogic / WidgetService.cs

// Execute on Create or Update of the Widget entity before the Save to the database.
[ServiceLogic(nameof(Widget), DataOperation.Create | DataOperation.Update, LogicStage.PreOperation)]
public class WidgetService : IServiceLogic
{
public async Task<Response<object?>> Execute(ServiceContext context)
{
var db = context.GetDbContext<DataContext>();
// Get the entity being saved
Widget widget = context.GetEntity<Widget>();
var countWidgets = await db.Widgets.CountAsync();
// Only set on create
if (context.DataOperation is DataOperation.Create)
{
// Because this is a PreOperation (before save), the Price will
// eventually get saved to the database
widget.Price = countWidgets * 10.5M;
}
return ServiceResult.Success();
}
}

Create a Record

  1. Replace the code in index.tsx with the following.

src / pages / index.tsx

import { useAuthRequest } from '@ixeta/xams'
import { Button } from '@mantine/core'
import React from 'react'
const Index = () => {
const authRequest = useAuthRequest()
const onClick = async () => {
const resp = await authRequest.create('Widget', {
Name: 'My Widget',
Price: 9.99,
})
if (!resp.succeeded) {
return
}
}
return <Button onClick={onClick}>Create Widget</Button>
}
export default Index

When the button is clicked, a Widget record will be created with the provided data.

Create a Form

  1. Replace the code in index.tsx with the following.

src / pages / index.tsx

import { Field, FormContainer, SaveButton, useFormBuilder } from '@ixeta/xams'
import { Grid } from '@mantine/core'
import React from 'react'
const Index = () => {
// Use the useFormBuilder hook to specify the table we're creating the form for
const formBuilder = useFormBuilder({
tableName: 'Widget',
})
return (
<div className="h-full w-full max-w-md p-6">
{/* Create a form container for this table's fields */}
<FormContainer formBuilder={formBuilder}>
<div className="flex flex-col gap-4">
<Grid>
<Grid.Col span={6}>
{/* Define the table fields to bind to */}
<Field name="Name" />
</Grid.Col>
<Grid.Col span={6}>
<Field name="Price" />
</Grid.Col>
</Grid>
<SaveButton />
</div>
</FormContainer>
</div>
)
}
export default Index

This will create the below form:

Was this page helpful?