Skip to content

Instantly share code, notes, and snippets.

@couhajjou
Last active January 10, 2024 00:22
Show Gist options
  • Save couhajjou/abe2c01ea24d5d48db52ec84c0eed987 to your computer and use it in GitHub Desktop.
Save couhajjou/abe2c01ea24d5d48db52ec84c0eed987 to your computer and use it in GitHub Desktop.
A specification for Pyro Actions

Pyro Actions - Specs Proposal 0.0.1

Disclaimer: This is heavily based on Odoo. A lot of copy-pasting of the action docs, I changed the language and some of the design to adapt it to Ach. This document was requested by Zach.

Versions:

  • 0.0.0: Quick draft (4 hours of work, copy-pasting and adaptation) - @couhajjou
  • 0.0.1: gpt4 corrections - @couhajjou
  • 0.1.0: added "Previous Art Section"

Previous art summary: Odoo

Actions in Odoo

In Odoo, an "Action" is an object that represents a user's request to perform an operation. It defines what should happen when a user triggers a button, menu item, or any other interactive element. There are several types of actions, each serving a distinct purpose:

Window Action:

Represents the opening of a new window in the user interface. Used for actions like opening a specific form view, tree view, or other UI components.

Report Action:

Defines the generation and presentation of reports. Associated with actions that produce printable documents or reports.

Server Action:

Represents a server-side operation or workflow. Typically used for more complex business logic and automation.

Client Action:

Defines actions that occur on the client-side, often written in JavaScript. Used for dynamic and responsive user interactions without server requests.

URL Action:

Represents actions that open a specific URL. Useful for integrating external resources or linking to external websites. Actions are linked to various elements in Odoo, such as buttons, menu items, or triggers within the system. By defining actions, developers can customize and control the behavior of the Odoo application to meet specific business requirements.

Views is Odoo

Form View:

Purpose: Displays a single record with input fields for editing. Structure: Contains various field widgets (text, date, selection, etc.) arranged in a structured layout. Usage: Primary view for creating, editing, and displaying detailed information about a specific record.

Tree View:

Purpose: Presents a list of records in a tabular format. Structure: Displays selected fields in columns, allowing quick scanning and editing of multiple records. Usage: Ideal for managing and manipulating datasets with multiple records.

Search View:

Purpose: Facilitates the search and filtering of records based on specified criteria. Structure: Provides a search bar and filters for refining data retrieval. Usage: Helps users locate specific records quickly by applying various search criteria.

Calendar View:

Purpose: Represents records in a calendar format. Structure: Displays records chronologically, often in a monthly, weekly, or daily view. Usage: Useful for managing time-based data, such as events, appointments, or deadlines.

Graph View:

Purpose: Displays data in graphical formats like bar charts or line graphs. Structure: Presents a visual representation of data trends and patterns. Usage: Offers insights into numeric data, aiding in the analysis of trends and comparisons.

Pivot View:

Purpose: Enables users to analyze and summarize data through pivot tables. Structure: Allows users to drag and drop fields for dynamic data analysis. Usage: Useful for aggregating and presenting data in a structured manner, offering flexibility in data exploration.

Introduction

UI Actions (or Pyro Actions) define the behavior of the system in response to user actions: login, action button, selection of an invoice, ...

UI Actions can have a code_interface section that creates elixir and/or JS hooks so that it can be triggered from elixir (and Iex) and/or with Phoenix.LiveView.JS.

The are 6 type of Pyro Actions:

Parameters

All UI actions share two mandatory parameters:

  • type: the category of the current action, determines which parameters may be used and how the action is interpreted
  • name: short user-readable description of the action, may be displayed in the client's interface

Optional parameters

Aside from their two mandatory parameters, all actions also share optional parameters used to present an action in an arbitrary resource's contextual menu:

  • resource_contextual_menu: specifies on which resource we can see the UI action. ex: if we set this to :customer, the UI action will show on the contextual menu of customer.
  • contextual_menu_type: which contextual menu the action will appear under, it can be one of:
    • :action_contextual_menu (default): Specifies that the action will appear in the Action contextual menu of the bound resource.
    • :report_contextual_menu: Specifies that the action will appear in the Print contextual menu of the bound resource.
  • view_types: a list of view types for which the action appears in the contextual menu, mostly "list" and / or "form". Defaults to [:list, :form] (both list and form)

View Actions

The most common action type, used to present visualizations of a resource through views: a view action defines a set of view types (and possibly specific views) for a resource (and possibly specific record of the resource).

Its fields are:

  • resource: resource to present views for
  • views: a list of (view_type, view_name) pairs. The first element of each pair is the category of the view (list, form, calendar, cards, map, ...). If no view_name is provided, then Pyro should fetch the default view of the specified type for the requested resource
  • record_id (optional): if the default view is form, specifies the record to load (otherwise a new record should be created)
  • target (optional): whether the views should be open in the main content area (current_area), in full-screen mode (fullscreen) or in a dialog/popup (new). Use main instead of current to clear the breadcrumbs. Defaults to current.
  • context (optional): additional context data to pass to the views
  • filter (optional): filter to implicitly add to all view search queries
  • limit (optional): the number of records to display in lists by default. Defaults to 80 in the web client
  • search_view_id (optional - chak> I will elaborate on this later)

For instance, to open customers (user with the customer flag set) with list and form views:

ui_actions
  ui_action
    type: :view_action
    resource: :user
    views: [tree: false, form: false]
    filter: expr(:user.customer, "=", true) # chak> Zach how to do this properly?
  end
end

Or to open the form view of a specific product (obtained separately) in a new dialog:

ui_actions
  ui_action
    type: :view_action
    resource: :product
    views: [tree: false, form: false]
    record_id: filter(:product.name, "=", "Ash Coffee Mug")
    target: :new  # this will open a dialog, other options are :fullscreen and :current_area
  end
end

URL Actions (:url_action)

Allow opening a URL (website/web page). Can be customized via two fields:

  • url: the address to open when activating the action
  • target (default= new): the available values are:
    • new: opens the URL in a new window/page
    • self: opens the URL in the current window/page (replaces the actual content)
    • download: redirects to a download URL

Example:

ui_actions
  ui_action
    type: :url_action
    url: "https://ash-hq.com"
    target: :self
  end
end

This will replace the current content section with the Ash home page.

Api Actions (:api_action)

Allow triggering a call to a method defined in an Ash API

  • api: the API we are calling
  • resource: resource linked to the action, the resource should be referenced in the API
# demo.ex
defmodule Kech.Demo do
  use Ash.Api, extensions: [AshAdmin.Api]

  resources do
    resource Kech.Demo.Customer
    resource Kech.Demo.Order
  end
end
ui_actions
  ui_action do
    type: :api_action
    api: :demo
    resource: :customer
    # ...
    # ...
  end
end
  • code (code - chak> this is rough): Specify a piece of elixir code to execute when the action is called
ui_actions
    ui_action
    type: :api_action
    resource: :customer
    code do
        # chak> this is not clear yet. it's gonna be either:
        # - arbitrary elixir code
        # - or some DSL for a limited type of code based on usage patterns
        # chab> what variables will be available here implicitly (evaluation context, see below)?

        # elixir code here
        # elixir code here
    end
end

Evaluation context

A number of keys are available in the evaluation context of or surrounding server actions:

  • resource: resource linked to the action via resource_id
  • record/records: record/recordset on which the action is triggered, can be void.
  • env: Phoenix Environment
  • datetime, dateutil, time, timezone: corresponding Python modules
  • log: log(message, level='info'): logging function to record debug information in the logging table
  • Warning: constructor for the Warning exception

Report Actions (:report_action)

Triggers the printing of a report.

  • name (mandatory): used as the filename if print_report_name is not specified. Otherwise, only useful as a mnemonic/description of the report when

looking for one in a list of some sort

  • resource (mandatory): the resource your report will be about
  • report_type (default=qweb-pdf): either qweb-pdf for PDF reports or qweb-html for HTML
  • report_name (mandatory): the name (:term:external id) of the qweb template used to render the report
  • print_report_name: a Python expression defining the name of the report.
  • groups_id: the groups allowed to view/use the current report
  • multi: if set to True, the action will not be displayed on a form view.
  • paperformat_id: field to the paper format you wish to use for this report (if not specified, the company format will be used)
  • attachment_use: if set to True, the report is only generated once the first time it is requested and re-printed from the stored report afterward instead of being re-generated every time. Can be used for reports that must only be generated once (e.g., for legal reasons)
  • attachment: an expression that defines the name of the report; the record is accessible as the variable object

Client Actions (:client_action)

Triggers an action implemented entirely in the client (the front end).

  • tag: the client-side identifier of the action, an arbitrary string that the client should know how to react to
  • params (optional): a dictionary of additional data to send to the client, alongside the client action tag
  • target (optional): whether the client action should be open in the main content area (current), in full-screen mode (fullscreen), or in a dialog/popup (new). Use main instead of current to clear the breadcrumbs. Defaults to current.

TODO - Chak:

  • Add Example

Cron Actions (:cron_action)

Actions triggered automatically on a predefined frequency.

  • name: Name of the automated action (Mainly used in log display)
  • interval_number: Number of interval_type uom between two executions of the action
  • interval_type: Unit of measure of frequency interval (minutes, hours, days, weeks, months)
  • numbercall: Number of times this action has to be run. If the action is expected to run indefinitely, set to -1.
  • doall: Boolean specifying whether the missed actions have to be executed in case of server restarts.
  • resource_id: resource on which this action will be called
  • code: Code content of the action. Can be a simple call to the resource's method:
# Code block example
  • nextcall: Next planned execution date of this action (date/time format)

TODO - Chak

  • Add Example
@couhajjou
Copy link
Author

couhajjou commented Jan 10, 2024

Yeah, I know Zach. Thanks for you time and your support. it's been great so far and above my expectations.
So it's encouraging me to give back.

I'll strive to stay coherent and within the spirit of Ash.
I can go with triggers or ui_triggers instead of 'ui_actions' for now and rename thinks later when we merge the naming.
At least for now, we that we will not confuse people.
I will be mainly seeking support about SparkDSL from Discord.

Solo can go fast, and it's a good thing. But I am listening to whoever want to participate in this effort.

@couhajjou
Copy link
Author

new document version

  • 0.1.0: added "Previous Art Section" where I provide a summary of Odoo actions and views

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment