Skip to main content

vizier 0.1.0 copy "vizier: ^0.1.0" to clipboard
vizier: ^0.1.0 copied to clipboard

Resource-driven server-rendered admin panels for Maat applications.

Vizier #

Resource-driven, server-rendered admin panels for Maat applications. Describe a model once as an AdminResource and Vizier renders the list, create, edit and show pages, enforces your authorization hooks on every request, and serves the whole panel behind Anubis web sessions. No JavaScript build step: the assets ship inside the package and vizier:install publishes them into your application.

class SlotAdminResource extends AdminResource<Slot> {
  @override
  ModelDefinition<Slot> get model => Slot.def;

  @override
  String get slug => 'slots';

  @override
  String get singularLabel => 'Slot';

  @override
  String get pluralLabel => 'Slots';

  @override
  String get titleAttribute => 'starts_at';

  @override
  AdminForm form(AdminForm form) => form.fields([
    NumberField('resource_id', label: 'Resource id').integer().required(),
    DateTimeField('starts_at').required(),
    DateTimeField('ends_at').required(),
  ]);

  @override
  AdminTable<Slot> table(AdminTable<Slot> table) => table
      .columns([
        DateTimeColumn<Slot>('starts_at').sortable(),
        DateTimeColumn<Slot>('ends_at'),
      ])
      .defaultSort('starts_at');

  @override
  bool canCreate(Request request) => request.user<User>()?.isAdmin ?? false;
}

Installation #

dependencies:
  vizier: ^0.1.0

Vizier needs the packages it builds on: anubis for web sessions and CSRF, khnum_maat for views, and seshat_maat for models.

Register the service provider and the console commands, then publish the views and assets once:

providers: [VizierServiceProvider.new, AdminServiceProvider.new],
commands: [...vizierCommands()],
dart run bin/maat.dart vizier:install

A normal install never overwrites files your application already published; pass --force after reviewing the differences to take newer defaults.

Defining a panel #

A panel is registered from a service provider that boots after VizierServiceProvider, because the panel resolves the anubis.session middleware by alias at registration time.

class AdminServiceProvider extends ServiceProvider {
  AdminServiceProvider(super.app);

  @override
  void boot() {
    Anubis.provider('users', (id) => User.query().find(int.parse(id)));

    Vizier.panel(
      Panel(
        title: 'Booking Admin',
        userProvider: 'users',
        authenticate: (email, password) async {
          final user = await User.query().where('email', email).first();
          final valid = await Hash.checkAsync(password, user?.authPassword ?? '');
          return user != null && valid && user.isStaff ? user : null;
        },
        resources: [BookingAdminResource(), SlotAdminResource()],
      ),
    );
  }
}

authenticate returns the user to sign in, or null to reject. The panel mounts at /admin by default; pass path to move it.

Resources #

Every AdminResource<T> describes one model:

Member Purpose
model, slug, singularLabel, pluralLabel, titleAttribute Identity and how a record is named.
form(AdminForm) Fields for create and edit.
table(AdminTable<T>) Columns, sorting, search and filters for the index page.
navigationIcon, navigationOrder Placement in the sidebar.
query() The base query; override to scope what the panel can see.
beforeCreate, afterCreate, beforeUpdate, afterUpdate Hooks around writes.

Fields: TextField, EmailField, PasswordField, TextareaField, NumberField, BooleanField, SelectField, DateField, DateTimeField, HiddenField.

Columns: TextColumn, BooleanColumn, DateColumn, DateTimeColumn, and ComputedColumn for values derived from the record.

Authorization #

Nothing is writable by default. Each hook receives the current Request, so the same rule that guards your API guards the panel:

@override
bool canViewAny(Request request) => true;

@override
bool canCreate(Request request) => _isAdmin(request);

@override
bool canUpdate(Request request, Slot record) => _isAdmin(request);

@override
bool canDelete(Request request, Slot record) => _isAdmin(request);

Actions #

Row and bulk actions run your own code and report back to the page:

@override
List<AdminAction<Booking>> actions() => [
  AdminAction(
    name: 'mark-no-show',
    label: 'Mark no-show',
    bulk: true,
    icon: VizierIcon.check,
    requiresConfirmation: true,
    handler: (request, records, values) async {
      for (final record in records) {
        await bookings.markNoShow(record);
      }
      return ActionResult(message: '${records.length} bookings updated.');
    },
  ),
];

@override
bool canRunAction(Request request, AdminAction<Booking> action, Booking record) =>
    _isStaff(request);

An action may take a form to collect input before it runs; the values arrive in values.

Pages, widgets and extensions #

  • VizierPage renders a custom view at its own slug and appears in the sidebar; dashboard replaces the default DashboardPage.
  • VizierWidget renders a view inside the dashboard.
  • VizierExtension bundles resources, pages, dashboard widgets and translations under a package name, so a third-party package can plug a whole section into a panel with one entry in extensions.

Localization #

Panels ship English and Arabic catalogs, and Arabic renders right-to-left. defaultLocale, supportedLocales, rtlLocales, localeResolver and translations on Panel control the rest; resources and actions accept per-locale labels through singularLabelFor, pluralLabelFor and localizedLabels.

Customizing the templates #

vizier:install publishes the Khnum templates to resources/views/vendor/vizier/ and the CSS and JavaScript to public/vendor/vizier/. Edit them freely; your application's copies win over the package defaults.

Documentation #

The full guide lives in the Maat documentation.

0
likes
0
points
147
downloads

Publisher

verified publishergaitco.com

Weekly Downloads

Resource-driven server-rendered admin panels for Maat applications.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

anubis, khnum_maat, maat, path, seshat_maat

More

Packages that depend on vizier