Skip to content

Custom actions

Example of custom actions in Kottster

Kottster provides default actions for working with records (view, edit, delete), but you can add custom actions for specific workflows. There are three ways to add custom actions:

  • Client-side actions - For simple UI interactions that don't need server processing
  • Auto-calling server procedures - For server operations that run automatically when clicked
  • Manually calling server procedures - For server operations where you need custom logic before/after the call

Client-side actions

Use client-side actions for simple interactions like showing alerts, opening modals, or navigating to other pages.

Add the customActions prop to the TablePage component. This prop accepts an array of objects, each representing a custom action.

app/pages/users/index.jsx
jsx
import { TablePage } from '@kottster/react';

export default () => (
  <TablePage
    customActions={[
      {
        label: 'View Profile',
        color: 'blue',
        onClick: (record) => {
          // Simple client-side logic
          window.open(`https://example.com/profile/${record.id}`, '_blank');
        },
      },
    ]}
  />
);

Auto-calling server procedures

Use this approach when you need server-side processing (like sending emails or updating data) and want the procedure to run automatically when the button is clicked.

In the customActions prop of the TablePage component, specify the procedure property with the name of the server procedure to call. You can also handle the result using the onResult callback.

app/pages/users/index.jsx
jsx
import { TablePage } from '@kottster/react';
import { notifications } from '@mantine/notifications';

export default () => (
  <TablePage
    customActions={[
      {
        label: 'Send Welcome Email',
        procedure: 'sendWelcomeEmail', // What server procedure to call
        onResult: (result) => {
          if (result.success) {
            notifications.show({
              title: 'Success',
              message: `Welcome email sent to ${result.sentTo}`,
              color: 'green',
            });
          }
        },
      },
    ]}
  />
);

On the server side, add the procedure name to your table controller. Define the server procedure that will be called automatically:

app/pages/users/api.server.js
js
import { app } from '../../_server/app';
import postgresDataSource from '../../_server/data-sources/postgres_db';

// Get Knex client to interact with the database
const knex = postgresDataSource.getClient();

const controller = app.defineTableController({}, {
  sendWelcomeEmail: async (record) => {
    // Get user email from the database
    const user = await knex('users').where({ id: record.id }).first();
    if (!user) {
      throw new Error('User not found');
    }

    // Send email logic here...
    console.log(`[server] Sending welcome email to ${user.email}`);

    return { 
      success: true, 
      sentTo: user.email 
    };
  }
});

export default controller;

Manually calling server procedures

Use this approach when you need custom logic before or after calling the server procedure, such as showing confirmation dialogs, validating data, custom error handling, or chaining multiple operations.

app/pages/users/index.jsx
jsx
import { TablePage, useCallProcedure } from '@kottster/react';
import { notifications } from '@mantine/notifications';

export default () => {
  const callProcedure = useCallProcedure();

  const handleSendEmail = (record) => {
    const confirmed = confirm(`Send welcome email to ${record.email}?`);
    if (confirmed) {
      // Manually call the same server procedure
      const result = await callProcedure('sendWelcomeEmail', record);
      
      if (result.success) {
        notifications.show({
          title: 'Success',
          message: 'Email sent successfully!',
          color: 'green',
        });
      }
    }
  };

  return (
    <TablePage
      customActions={[
        {
          label: 'Send Welcome Email',
          onClick: handleSendEmail,
        },
      ]}
    />
  );
};

When to use each approach

  • Client-side actions: Navigation, showing/hiding UI elements, client-side data filtering
  • Auto-calling procedures: Simple server operations like sending emails, generating reports, or updating status
  • Manual procedure calls: When you need confirmation dialogs, data validation, or complex workflows before or after the server call