Configuration

Setting up a view

The first step to building an Airplane view is to write its configuration. This contains the core metadata of the view, like the view name and environment variables. It includes all information aside from the actual code that is executed when the view is run.
View configuration was previously accomplished using a yaml-based view definition. This new, inline view configuration allows tasks to be configured and developed in the same file.
To define a view, the JavaScript SDK provides a function airplane.view(...), which takes two parameters: the view configuration and the view component. The result of airplane.view must be the default export of the file.
tsx
Copied
1
// my_view.airplane.tsx
2
import { Title } from "@airplane/views";
3
import airplane from "airplane";
4
const MyView = () => {
5
return <Title>Hello World!</Title>;
6
};
7
export default airplane.view(
8
// View configuration
9
{
10
slug: "my_view",
11
name: "My View",
12
description: "This is my view!",
13
},
14
// View component
15
MyView,
16
);
Airplane will only discover views that are the default export of files ending in .airplane.tsx, .airplane.jsx, .view.tsx, or .view.jsx.

Reference

View configuration

slug
REQUIRED
string
A unique identifier that ties this configuration to a view in Airplane. This cannot be changed (a different slug will end up creating a new view). Slugs must:
  • Be fewer than 50 characters long.
  • Use only lowercase letters, numbers and underscores.
  • Start with a lowercase later.
name
Default
same value as slug
string

A user-facing name for the view. This can be changed.

description
string

A user-facing description for the view. Supports markdown.

envVars
Record<string, string> | Record<string, {config: string}> | Record<string, {value: string}>
Environment variables that will be passed into the view. For values that are shared across multiple tasks, environment variables can load their value from config variables.
permissions
"team_access" | ViewExplicitPermissions
Configure who has access to the view. Permissions can either be omitted to manage permissions in the UI, set to "team_access" to allow full access to everyone on the team, or defined with explicit granular permissions. For more information, see Views permissions.

Permissions configuration

Configure who has access to the view. Permissions can either be omitted to manage permissions in the UI, set to "team_access" to allow full access to everyone on the team, or defined with explicit granular permissions.
You can assign granular viewer or admin access to groups or users. Groups are referenced by slug, and users are referenced by email. For more information, see View permissions.
type ViewExplicitPermissions
viewers
optional
{ users?: string[], groups?: string[] }

Groups and users who can access a view.

admins
optional
{ users?: string[], groups?: string[] }

Groups and users who have full access to the view, and can change view permissions.

Using TypeScript

All views components and libraries are built with TypeScript and have type support out of the box.
By default, Airplane Views are initialized using TypeScript (.tsx). Running airplane init will:
  • Search for a tsconfig.json file in your current directory. If it does not exist, we will generate a default tsconfig.json for you in your current directory. You can change the configuration to suit your needs.
  • Search your package.json for the typescript dependency. If TypeScript is not installed, we will install the latest version.
While we provide a tsconfig.json file to enable TypeScript code editor support, we currently do not run tsc when building your view. This means that type errors will not stop your view from being deployed.
Views supports a number of recommended TypeScript patterns to improve type safety.

Component state

We recommend using Generics to keep the component state type-safe.
In the following example, we tell useComponentState that the component it is registered with is a table. This automatically types state fields such as selectedRow while erroring out on fields that don't exist on the table state such as value.
tsx
Copied
1
const { id, selectedRow } = useComponentState<TableState>();
2
// The following line would error since `value` does not exist on `TableState`.
3
// const { id, value } = useComponentState<TableState>();
4
return (
5
<Stack>
6
<Table id={id} columns={columns} data={data} rowSelection="single" />
7
{selectedRow && <Text>{`Selected ${selectedRow.name}`}</Text>}
8
</Stack>
9
);
Most of our examples do not use types for brevity, but we strongly recommend using types throughout your view!

Task backed components

All Task backed components take Generics that type the parameters and output of the task.
In the following example, we've typed the parameters and output of the task list_animals that backs the Select component.
tsx
Copied
1
{/* The task `list_cat_breeds` has parameters of type `{ filter: string }` and output of type string[] */}
2
<Select<{ filter: string }, string[]>
3
id={searchAnimals.id}
4
task={{
5
slug: "list_cat_breeds",
6
params: { filter: "" },
7
// This would cause a type error.
8
// params: { key: "value" },
9
}}
10
// `cats` is of type string[]
11
outputTransform={(cats) => cats.map((cat) => cat.toUpperCase())}
12
placeholder="Select a cat breed"
13
/>