diff --git a/docs/developers/building-an-extension/backend-integration.md b/docs/developers/building-an-extension/backend-integration.md new file mode 100644 index 0000000..c27189a --- /dev/null +++ b/docs/developers/building-an-extension/backend-integration.md @@ -0,0 +1,8 @@ +--- +sidebar_position: 6 +slug: /developers/building-an-extension/backend-integration +toc_min_heading_level: 2 +toc_max_heading_level: 5 +--- + +# Backend Integration \ No newline at end of file diff --git a/docs/developers/building-an-extension/basic-setup.md b/docs/developers/building-an-extension/basic-setup.md new file mode 100644 index 0000000..87fe827 --- /dev/null +++ b/docs/developers/building-an-extension/basic-setup.md @@ -0,0 +1,216 @@ +--- +sidebar_position: 3 +slug: /developers/building-an-extension/basic-setup +toc_min_heading_level: 2 +toc_max_heading_level: 5 +--- + +# Basic Extension Setup + +After scaffolding your extension, you need to configure both the Ember Engine and the Laravel package. This setup involves initializing the frontend code for the Ember Engine and setting up the API code for the Laravel package. + +## Overview + +- **Ember Engine**: Located in the `/addon` directory, this is where all your frontend code will reside. +- **Laravel Package**: Located in the `/server` directory, this is where you'll handle your API code. + +## Setting Up the Ember Engine + +Your Ember Engine configuration begins in `addon/engine.js`. This file includes the `setupExtension` function, which is called during initialization to configure your extension’s integration with Fleetbase. + +Here is a basic example of `engine.js`: + +```js +import Engine from '@ember/engine'; +import loadInitializers from 'ember-load-initializers'; +import Resolver from 'ember-resolver'; +import config from './config/environment'; +import services from '@fleetbase/ember-core/exports/services'; + +const { modulePrefix } = config; +const externalRoutes = ['console', 'extensions']; + +export default class StarterEngine extends Engine { + modulePrefix = modulePrefix; + Resolver = Resolver; + dependencies = { + services, + externalRoutes, + }; + + setupExtension = function (app, engine, universe) { + // Register menu item in the header + universe.registerHeaderMenuItem('Starter', 'console.starter', { icon: 'layer-group', priority: 5 }); + }; +} + +loadInitializers(StarterEngine, modulePrefix); +``` + +### Adding Dependencies + +If your extension depends on other extensions, such as FleetOps, declare these dependencies in `engine.js`: + +```js +export default class StarterEngine extends Engine { + engineDependencies = ['@fleetbase/fleetops-engine']; + + setupExtension = function (app, engine, universe) { + // Your setup code + }; +} +``` + +### `setupExtension` Arguments + +The `setupExtension` function receives three arguments: +- **App Instance (`app`)**: Represents the entire Fleetbase Console application. +- **Engine Instance (`engine`)**: Represents the instance of your engine. +- **Universe Service (`universe`)**: Essential service for integrating with Fleetbase Console and other extensions. + +### Registering in the Navbar + +To add your extension to the Fleetbase Console navbar, use the `universe.registerHeaderMenuItem()` function. This function requires: +- **Name**: The display name for the navbar item. +- **Route**: The route for your extension, as defined in the `fleetbase.route` key of your `package.json`. +- **Options**: Optional parameters such as `icon` and `priority`. + +Because routes are statically set at build time the route prefix can only be defined in the extensions `package.json` under the `fleetbase` key, which is shown in the example below. In the example the route prefix is set as `starter` this means your extension will sit at the `console.starter` route and the URL will be `/starter` in the Fleetbase Console. + +You can change the `route` option to change the route and URL of your extension. + +For example, your `package.json` might include: + +```json +{ + "name": "@fleetbase/starter-engine", + "version": "0.0.1", + "description": "Starter Extension for Fleetbase", + "fleetbase": { + "route": "starter" + } +} +``` + +This configuration means the route location of the extension will be `console.starter`. To register this with the navbar: + +```js +universe.registerHeaderMenuItem('Starter', 'console.starter'); +``` + +#### Custom Icons + +You can use Font Awesome icons or custom icons for your extension. To use a Font Awesome icon: + +```js +universe.registerHeaderMenuItem('Starter', 'console.starter', { icon: 'warehouse' }); +``` + +For a custom icon, you will need to create a component using `ember-cli`: + +Make sure you have `ember-cli` installed globally via `npm i -g ember-cli`. Now, from your extension directory run the ember generate command. + +```bash +ember g component starter-brand-icon -gc +``` + +This will generate a new glimmer component at `addon/components/start-brand-icon` which will include a `js` file for the code and `hbs` (handlesbars) for the template. You can read more about Ember and Glimmer Components on the [official Ember.js docs](https://guides.emberjs.com/release/upgrading/current-edition/glimmer-components/). + +Define the glimmer component with an `options` argument which contains a `width` and `height` property: + +```js +import Component from '@glimmer/component'; +import { tracked } from '@glimmer/tracking'; + +export default class StarterBrandIconComponent extends Component { + @tracked width = 19; + @tracked height = 19; + + constructor(owner, { options: { width = 19, height = 19 } }) { + super(...arguments); + this.width = width; + this.height = height; + } +} +``` + +Render the icon in the component’s template. For example, using SVG: + +```hbs + + + + + +``` + +You can also use a PNG, JPEG, or even a GIF like so using the Fleetbase `` component or the native HTML `` element. In the example below we use the Fleetbase `` component. + +```hbs + +``` + +Then, register the custom icon with `registerHeaderMenuItem`, first you must import the icon component to your `engine.js` then set it in the `iconComponent` option. + +Additionally the `iconComponentOptions` property can take any other custom options you might require and they will be available to your component in the `options` argument. + +```js +import StarterBrandIconComponent from './components/starter-brand-icon'; + +export default class StarterEngine extends Engine { + setupExtension = function (app, engine, universe) { + universe.registerHeaderMenuItem('Starter', 'console.starter', { + iconComponent: StarterBrandIconComponent, + iconComponentOptions: { width: 19, height: 19 }, + priority: 5 + }); + } +} +``` + +#### `priority` Option + +The `priority` option determines the position of your extension link in the navbar. + +- **Higher Priority Values**: Extension links with higher priority values are rendered later in the navbar. For example, if you set a priority of `10`, it will appear towards the end of the navbar, after items with lower priority values. +- **Lower Priority Values**: Extension links with lower priority values are rendered earlier in the navbar. For example, if you set a priority of `1`, it will appear before items with higher priority values. + +By setting different priority values, you can control the order of your extension links relative to other items in the navbar. For example, a priority of `5` will place the link between items with priorities of `4` and `6`. + + +## Getting Started with Service Providers + +The Service Provider in Laravel handles the setup of your extension's API. You can find this in `server/src/Providers/StarterServiceProvider.php`. If you used the CLI to scaffold your Service Provider name and backend namespace will be based on the name of your extension. + +In your service provider ensure that the `fleetbase/core-api` is registered: + +```php +app->register(CoreServiceProvider::class); + } + + public function boot() + { + // Register commands, observers, views, routes, and configs + $this->mergeConfigFrom(__DIR__ . '/../../config/starter.php', 'starter'); + } +} +``` + +In future pages, we will cover: +- Setting up the API and using the Core API. +- Handling authentication and developing features. +- Creating integrations with other services. diff --git a/docs/developers/building-an-extension/developing-the-frontend.md b/docs/developers/building-an-extension/developing-the-frontend.md new file mode 100644 index 0000000..f2df9d8 --- /dev/null +++ b/docs/developers/building-an-extension/developing-the-frontend.md @@ -0,0 +1,492 @@ +--- +sidebar_position: 4 +slug: /developers/building-an-extension/developing-the-frontend +toc_min_heading_level: 2 +toc_max_heading_level: 5 +--- + +# Developing the Frontend + +Now that you have the basic setup for your extension, you will need to develop a frontend for the extension. If your extension is a sole integration this document will cover adding integrations to other extensions and the Fleetbase console. If your extension is a full module we will cover developing a UI for the module as well as cover the basics of controllers, routes, and components. + + +## Developing an Extension UI + +If you are developing a full module extension you will need to build the overall UI which includes the sidebar for navigation, and the main and section view where the application UI and content will render to. + +### Generate the Application Route + +First start by generating an application route, this is the first route and template which will be loaded when users enter your extension. You can do this simply using `ember-cli` from your extension directory: + +```bash +ember g application +``` + +This will generate two files: +- **`addon/routes/application.js`**: The initial route of your extension. +- **`addon/templates/application.hbs`**: The initial template of your extension, this will work as the "layout". + +### Creating Application Layout + +Inside your `application.hbs` we can create the initial UI using components from the `@fleetbase/ember-ui` package: + +```hbs + + Home + + + + {{outlet}} + +``` + +- **``**: This is a component which can be used to register components or template inside of another element. Since the sidebar is persistent throughout Fleetbase and is rendered from the console application template you will need to "wormhole" your navigation items to the sidebar like the above example. +- **``**: This is a Fleetbase provided UI component which creates a standard container for rendering your extension UI. +- **`{{outlet}}`**: This is a standard Ember.js provided template helper which is used to render route and sub route content. For example when I click the "home link" it will render the template contents of the `console.starter.home` route into this `{{outlet}}`. + +To add navigation panels which group menu items you can use the `` component as shown below: + +```hbs + + + Audits + Reports + + +``` + +You can add as many panels or sidebar items as your extension needs, each route will be loaded and rendered into the `{{outlet}}`. + +### Setup for Integrations in Layout + +If your extension is integratable, meaning other extensions can integrate and add views and components then you will first need to create a registry via the `UniverseService` for other extensions to register to, then inside your UI you can render these integrations into your extension. + +#### Creating Integration Registries + +For example, let's say another extension enables additional functionality to our extension and we will allow additional menu items to our UI. Inside our `addon/engine.js` we will create a registry for this like so: + +```js +export default class StarterEngine extends Engine { + setupExtension = function (app, engine, universe) { + // create all registries necessary + universe.createRegistries([ + 'engine:starter', + 'starter:component:map', + 'starter:component:global-search', + 'starter:component:audit-report-panel', + ]); + } +} +``` + +The above function `universe.createRegistries` will have created these registries for your extension which can be referenced in your application, in the example we created 4 registries each uniquely namespaced for their individual component or purpose. + +#### Using Registries from Integrations + +Now let's say we want to use the `engine:starter` registry a registry for menu items to our extension then in our template we can use the Fleetbase provided `` component. + +The integrating extension would need to register a menu item from their own `engine.js` like so: + +```js +import IntegrationControlPanel from './components/integration-control-panel'; + +export default class IntegratingEngine extends Engine { + setupExtension = function (app, engine, universe) { + // Register a menu item inside Starter extension + universe.registerMenuItem('engine:starter', 'Integration Controls', { + component: IntegrationControlPanel, + registerComponentToEngine: '@org/starter-engine', + icon: 'cog', + slug: 'integration-controls', + }); + } +} +``` + +The above `universe.registerMenuItem` function takes 3 arguments: + +- **`registryName`**: This is the registry where the intended menu item will be registered to. +- **`title`**: This is the title of the menu item. +- **`options`**: These are options which add additional configuration for the menu item. +- **`options.component`**: This is the component which will be rendered when the menu item is clicked. +- **`options.registerComponentToEngine`**: This tells universe to register the above component into the engine being integrated to. +- **`options.icon`**: The icon for the menu item. +- **`options.slug`**: This is the url slug for the view rendered when the item is clicked. + +#### Rendering from Registries + +The above coverse integrating into another extension, but for this bit the focus is on handling integrations. So assuming all the above is done by another engine we can then render the menu items into our extension using the `RegistryYield` component mentioned previously. Here is how it would look: + +```hbs + + Home + + {{menuItem.title}} + + +``` + +Alternatively you can also programatically get menu items from the `UniverseService` instance anywhere throughout your extension codebase. For example we can get the items as an array from a controller like so: + +```js +import Controller from '@ember/controller'; +import { inject as service } from '@ember/service'; + +export default class SomeController extends Controller { + @service universe; + + get registryMenuItems() { + return this.universe.getMenuItemsFromRegistry('engine:starter'); + } +} +``` + +## Adding Routes + +Routes are URL's within your extension which allow a user to navigate to different parts of your extension. Routes can optionally have controllers which bind to the template allowing you to add functions or other properties. In Ember.js the route is responsible for loading data from the API if there is any, handling transitions, and controller setup if there is any. + +Ember.js routes have very useful hooks which give you further control over each stage of the transition lifecycle. More about routes and it's API can be found on the [official Ember.js guide about routing](https://guides.emberjs.com/release/routing/). + +To create a new route in your extension start by using the `ember-cli` generate command to generate a route like so: + +```bash +ember g route home +``` + +### Nested Routes + +Nested routing is also capable which takes advantage of the `{{outlet}}` template helper to render nested route templates from a parent route. Nested routes can also be generated like so: + + +```bash +ember g home/index +ember g home/analytics +ember g home/analytics/view +``` + +In the above example we have generated 3 nested routes, an `index` route which in Ember.js will always be loaded first and within the parent route, then another nested route `home/analytics` and a further nested route `home/analytics/view`. This is a great if your `home/analytics` route displays a list of items and you need to easily display specific details about an item within the same template via the `home/analytics/view` route. + +Additionally the URL mapping will be persistent so that when the user refreshed on the view route it will still load and render those specific analytic details. + +### Define Routes + +Routes will not work unless they are explicitly defined in your extensions `addon/routes.js` - you will need to manually define your newly generated routes here for them to work like so: + +```js +import buildRoutes from 'ember-engines/routes'; + +export default buildRoutes(function () { + this.route('home'); +}); +``` + +For defining nested routes it would look like this: + +```js +import buildRoutes from 'ember-engines/routes'; + +export default buildRoutes(function () { + this.route('home', function () { + this.route('index'); + this.route('analytics', function () { + this.route('view', { path: '/details/:id' }); + }); + }); +}); +``` + +The above example shows you can use the `path` option to customize the URL of the route and also dynamic parameters. + +### Loading Data in Route + +The Ember.js way is to load a routes data from the route itself, it provides a convenient hook called `model()` which the resolved data becomes available to both the template and controller as either `@model` from the template, or `this.model` in the controller. + +Here is an example of loading data in a route using the Fleetbase provided `FetchService`: + +```js +import Route from '@ember/routing/route'; +import { inject as service } from '@ember/service'; + +export default class MyRoute extends Route { + @service fetch; + + beforeModel(transition) {} + + model({ id }) { + return this.fetch.get('analytics', { id }); + } + + afterModel(model) {} + + setupController(controller, model) { + super.setupController(...arguments); + } +} +``` + +In the above example we use the `FetchService` to load data from the api. The model first argument receives URL params or dynamic parameters which are set in the Router map. In this example included useful Route hooks as well which we will breakdown below, but further documentation on available hooks like `willTransition`, `didTransition`, `loading`, `activate` can be found on the [official Ember.js Route API documentation](https://api.emberjs.com/ember/release/classes/route/). + +- **`beforeModel`**: Is a method which is called before the model is loaded, you can use this to do checks and then use the `Transition` [transition](https://api.emberjs.com/ember/release/classes/Transition) object to redirect or abort if needed. +- **`model`**: This method must return a promise which would then be resolved and passed to template and controller. +- **`afterModel`**: This method allows further functionality to be done from the route once the model is resolved. +- **`setupController`**: This method is called once the controller is initialized and mounted and the model has been resolved. Here you can do even more with the model and the controller if necessary. + +## Using UI Components + +Fleetbase extensions are built with `@fleetbase/ember-ui` package which is a Ember component library that provides convenient and common UI components, template helpers, modifiers and styling for your extension. We will cover the basic components which can be used to quiclky build a UI for your Fleetbase extension. + +[Continue reading about provided user interface components](/developers/building-an-extension/user-interface-library) + +## Using Core Services + +Fleetbase extensions are built with the `@fleetbase/ember-core` package which provides critical core services and useful utilities to make developing extensions faster and easier. By now, you should already be familiar with the `UniverseService` which is used for integrations and functionality between the console and other extensions. + +Fleetbase extensions are able to easily inject these core services throughout the codebase (controllers, routes, components) using the Ember.js provided `inject` function like so: + +```js +import Component from '@glimmer/component'; +import { inject as service } from '@ember/service'; + +export default class MyComponent extends Component { + @service fetch; + @service universe; +} +``` + +Below are the core services Fleetbase exposes to extensions: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ServiceDescription
`AppCacheService` +

This is a service which allows you to easily store and retrieve cache data from browser local storage.

+ Example Usage
+ ```js + this.appCache.set(key, value); + const value = this.appCache.get(key); + ``` +
`ChatService` +

This is a service which allows you to easily store and retrieve cache data from browser local storage.

+ Example Usage
+ ```js + @action async startChat() { + const chatChannel = await this.chat.createChatChannel('Chat Channel 1'); + const chatParticipant = await this.chat.addParticipant(chatChannel, this.currentUser.user); + const message = await this.chat.sendMessage(chatChannel, chartParticipant, 'Hello Chat!'); + } + ``` +
`CrudService` +

This is a convenient service for performing interactive CRUD operations on models. In the example below it will create a delete confirmation prompt.

+ Example Usage
+ ```js + @action deleteVehicle(vehicleModel) { + this.crud.delete(vehicleModel); + } + ``` +
`CurrentUser` +

This service allows you to load the currently authenticated user model and access properties for a current user. It can also be used to set user specifi local storage data. Since the current user is loaded already at the start of a session you should always be able to access the user from this service.

+ Example Usage
+ ```js + @action async getUser() { + try { + const user = await this.currentUser.promiseUser(); + console.log(`${this.currentUser.name} loaded!`); + this.currentUser.setOption('some-preference', 1); + } catch (error) { + console.error(error.message); + } + } + + @action async doSomethingWithUser() { + const preferences = await this.fetch.get(`user-preferences/${this.currentUser.id}`); + } + ``` +
`FetchService` +

This is a very convenient native fetch wrapper service which allows you to make authenticated request to the API, as well as handle uploads and downloads.

+ Example Usage
+ ```js + this.fetch.get(); + this.fetch.post(); + this.fetch.put(); + this.fetch.delete(); + this.fetch.download(); + this.fetch.uploadFile.perform(file); + ``` +
`NotificationsService` +

This service is used to trigger notifications.

+ Example Usage
+ ```js + this.notifications.info(); + this.notifications.success(); + this.notifications.warning(); + this.notifications.error(); + try { + this.fetch.get(); + } catch (error) { + this.notifications.serverError(error); + } + ``` +
`SocketService` +

This service is a convenient wrapper around the socketcluster client which can be used to easily listen to socket channel events.

+ Example Usage
+ ```js + this.socket.listen(channelId, (event) => { + console.log('New incoming real-time event', event); + }); + ``` +
`UniverseService` +

This service is crucial for developing extensions as it handles functionality and integration with the Fleetbase console and other extensions.

+ Example Usage
+ ```js + this.universe.registerUserMenuItem('Starter Analytics'); + ``` +
+ +## Building an Integration Only + +Some extensions do not require a full navigatable UI, instead an integration for example which adds a component to the Fleet-Ops order form will be much simpler. This is where the `UniverseService` becomes powerful in the ability to add UI functionality to other extensions, espescially core extensions. + +In the following example will demonstrate adding an additional form box to the Fleet-Ops order form. + +### The Engine.js + +Let's say you want to create an extension for container haulage, typically these kinds of orders will require vessel and port details about the container. We can easily create a new form which renders into the Fleet Ops order form when a `type: haulage` order is being created. Let's call this extension "Haulage". + +First generate the component which will be used to render a vessel details form into the Fleet Ops new order form. + +```bash +ember g component vessel-details-form -gc +``` + +Next prepare your `addon/engine.js`: + +```js +import Engine from '@ember/engine'; +import loadInitializers from 'ember-load-initializers'; +import Resolver from 'ember-resolver'; +import config from './config/environment'; +import services from '@fleetbase/ember-core/exports/services'; +import VesselDetailsFormComponent from './components/vessel-details-form'; + +const { modulePrefix } = config; +const externalRoutes = ['console', 'extensions']; + +export default class HaulageEngine extends Engine { + modulePrefix = modulePrefix; + Resolver = Resolver; + dependencies = { + services, + externalRoutes, + }; + engineDependencies = ['@fleetbase/fleetops-engine']; + setupExtension = function (app, engine, universe) { + // Register the Vessel Details form component + universe.registerRenderableComponent('@fleetbase/fleetops-engine', 'fleet-ops:template:operations:orders:new', VesselDetailsFormComponent); + }; +} + +loadInitializers(HaulageEngine, modulePrefix); +``` + +### The Component + +Now head to your newly generated component and let's prepare it. Fleet-Ops order form registry will provide the `OrderModel` and the `Controller` for context which allows you to update the order and use the controller functions available. + +```js +import Component from '@glimmer/component'; +import { tracked } from '@glimmer/tracking'; + +export default class VesselDetailsFormComponent extends Component { + @tracked order; + constructor(owner, { order }) { + super(...arguments); + this.order = order; + } + + @action updateVesselDetail(event, key) { + const metaField = this.order.meta.find((_metaField) => metaField.key === key); + if (metaField) { + metaField.value = event.target.value; + } else { + this.order.meta.pushObject({ + key, + value: event.target.value + }); + } + } +} +``` + +This component now has the Fleet Ops `OrderModel` instance as `this.order` available. We can store additional information about a Fleet Ops order using the `meta` property. + +```hbs +{{#if (eq this.order.type "haulage")}} + +
+ + + +
+
+{{/if}} +``` + +Now when a haulage order type is selected the Fleet Ops order form will render you component allowing the user to key in vessel details to the order `meta` data which will be serialized and available as `get(order, 'vessel-name')` or on the backend as `$order->getMeta('vessel-name');`. + +## Putting it Together + +This covers the basics for developing the frontend for a Fleetbase extension, now let's put it all together in an example where we render a table of records with pagination. + +### The Route + +### The Controller + +### The Template + + + + + diff --git a/docs/developers/building-an-extension/getting-started.md b/docs/developers/building-an-extension/getting-started.md index 7b49410..6e3abd4 100644 --- a/docs/developers/building-an-extension/getting-started.md +++ b/docs/developers/building-an-extension/getting-started.md @@ -1,6 +1,92 @@ --- -sidebar_position: 1 -slug: /developers/building-an-extension +sidebar_position: 2 +slug: /developers/building-an-extension/getting-started +toc_min_heading_level: 2 +toc_max_heading_level: 5 --- # Getting Started + +This section guides you through the initial setup and scaffolding of a Fleetbase Extension using the Fleetbase CLI. For developers new to Fleetbase, we also offer an alternative method using the [starter extension repo](https://github.com/fleetbase/starter-extension). + +## Installation of Fleetbase CLI + +Begin by installing the Fleetbase CLI with npm: + +```bash +npm i -g @fleetbase/cli +``` + +## Choosing the Scaffold Location + +It's recommended to scaffold extensions directly within the `packages` directory of your Fleetbase installation. This approach ensures that your extensions are neatly organized and easily accessible within the Fleetbase ecosystem. + + +## Scaffolding a New Extension + +Once the CLI is installed, you can scaffold a new extension by running: + +```bash +flb scaffold --path packages/your-extension +``` + +You will be prompted to provide details about your extension, including: + +- `-p, --path`: Specify the directory where the extension should be created. +- `-n, --name`: Name of your extension. +- `-d, --description`: A brief description of what your extension does. +- `-a, --author`: Name of the extension author. +- `-e, --email`: Contact email of the author. +- `-k, --keywords`: Relevant keywords for the extension. +- `-n, --namespace`: PHP Namespace for your extension. +- `-r, --repo`: Repository URL where the extension will be hosted. + +## Using the Starter Extension Repository + +Alternatively, if you prefer a more manual setup, clone the starter extension repository: + +```bash +git clone git@github.com:fleetbase/starter-extension.git packages/your-extension +``` + +This method creates a basic template in your specified directory, ready for further development. + +## Setting Up Fleetbase for Development + +After scaffolding or cloning your extension, you need to set up your development environment. Follow the [setup instructions for Fleetbase development](/getting-started/install/for-development) to prepare your system. + +## Linking Your Extension + +### Link the Engine + +Link your extension to the Fleetbase console by modifying `console/package.json`: + +```json +// package.json +{ + "dependencies": { + "@author/your-extension": "link:../packages/your-extension" + } +} +``` + +Make sure to run `pnpm install` from the `./console` directory. + +### Link the API + +Ensure the API is aware of your new extension by updating `api/composer.json`: + +```json +{ + "repositories": [ + { + "type": "path", + "url": "../packages/your-extension" + } + ] +} +``` + +Make sure to run `composer install` from the `./api` directory. + +This setup integrates your extension into the Fleetbase environment, allowing for seamless development and testing. diff --git a/docs/developers/building-an-extension/introduction.md b/docs/developers/building-an-extension/introduction.md new file mode 100644 index 0000000..c240a4f --- /dev/null +++ b/docs/developers/building-an-extension/introduction.md @@ -0,0 +1,41 @@ +--- +sidebar_position: 1 +slug: /developers/building-an-extension +toc_min_heading_level: 2 +toc_max_heading_level: 5 +--- + +# Introduction + +Welcome to the Fleetbase Extension Development Guide! In this document, we'll explore how to enhance the capabilities of the Fleetbase platform by creating extensions. Extensions are modular packages that enable new features, integrations, or complete modules, seamlessly expanding the functionality the Fleetbase OS. + +An extension in Fleetbase is a combination of an [Ember Engine](https://ember-engines.com/), which handles frontend interactions, and a [Laravel package](https://laravel.com/docs/11.x/packages) that serves as the API backend. This dual structure allows for robust and scalable development. + +To streamline your development process, you can use the Fleetbase CLI to scaffold new extensions. This tool helps you quickly set up the basic structure of your extension, allowing you to focus on customizing and extending its functionality. + +By the end of this guide, you will learn the necessary steps to create, test, and deploy your own extensions, enhancing the Fleetbase ecosystem to meet your specific business needs. For detailed instructions on setting up and using the Fleetbase CLI, refer to our [CLI documentation](/extensions/cli). + +## API Core Framework + +Developing an extension with Fleetbase is facilitated by the Fleetbase Core API, which is essential for any extension. This API serves as the backbone of your extension, providing the necessary infrastructure for feature integration and extension scalability. + +By leveraging the Core API, developers can: + +- **Register and schedule commands**: Automate tasks and processes within your extension. +- **Create expansions**: These are classes which allow you to extend functions on any other class in Fleetbase. +- **Manage middleware and notifications**: Enhance the functionality and responsiveness of your extension. +- **Set up routes and views**: Define the navigational structure and user interface of your extension. +- **Utilize core data models and utility functions**: These are designed to streamline the development process and ensure consistency across extensions. +- **Build resource APIs**: Use the composable REST API framework to rapidly develop resource-oriented services. + +The Core API not only simplifies the creation of robust extensions but also ensures they integrate smoothly with the broader Fleetbase ecosystem. For more details on using the Core API, refer to [Fleetbase Core API documentation](https://github.com/fleetbase/core-api). + +## Ember Core Framework + +For the frontend, Fleetbase equips extension developers with two essential libraries: `fleetbase/ember-core` and `fleetbase/ember-ui`. These libraries are integral to initiating and running your Ember Engine for extensions. + +- **`fleetbase/ember-core`**: Provides the foundational services, adapters, and utilities necessary for initializing and managing your extension's frontend. This includes integration capabilities with other extensions, ensuring a cohesive operation within the Fleetbase environment. +- **`fleetbase/ember-ui`**: Offers a suite of standardized UI components and styles, making it straightforward to develop attractive and user-friendly interfaces. This library ensures that the visual elements of your extension maintain consistency with the overall Fleetbase aesthetic, promoting a seamless user experience. + +Together, these libraries form the core of the Ember framework within Fleetbase, enabling developers to efficiently create and deploy visually consistent and functionally robust frontend applications. + diff --git a/docs/developers/building-an-extension/user-interface-library.md b/docs/developers/building-an-extension/user-interface-library.md new file mode 100644 index 0000000..a723667 --- /dev/null +++ b/docs/developers/building-an-extension/user-interface-library.md @@ -0,0 +1,554 @@ +--- +sidebar_position: 5 +slug: /developers/building-an-extension/user-interface-library +toc_min_heading_level: 2 +toc_max_heading_level: 5 +--- + +# User Interface Library + +Here you can find the most useful and commonly used UI components exposed by `@fleetbase/ember-ui` library. These components can be used to build composable and clean user interfaces for Fleetbase Extensions. + +### `