Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.x] Field actions #10352

Merged
merged 49 commits into from
Nov 20, 2024
Merged

[5.x] Field actions #10352

merged 49 commits into from
Nov 20, 2024

Conversation

jacksleight
Copy link
Contributor

@jacksleight jacksleight commented Jun 21, 2024

Summary

This PR adds a new feature called field actions.

Field actions provide a way to extend the functionality of existing fieldtypes without having to extend the whole class/component. They can be accessed via a new menu that appears above the field, which also provides a standard UI for common field features such as expand/collapse all and toggle fullscreen (these are referred to as internal actions).

Any action can be flagged as a quick action, which will make it appear in a simple popup menu on hover (exact UI still TBC).

Field actions are implemented entirely on the frontend in JS and should not be confused with entry/term etc. actions that run on the server. The implementation is currently intentionally very lightweight, but convenience helpers could be added in future (eg. to open a modal and prompt for user input).

Here's how they look:

actions

As well as fields this feature has also been incorporated into replicator and bard sets. While the focus of this PR is adding actions to fields, it's been implemented in a generic way so that the same functionality could be added to other component types in the future.

The actions are also available in fullscreen modes, which are now using a universal header component:

CleanShot 2024-09-19 at 14 46 44
CleanShot 2024-09-19 at 14 46 54
CleanShot 2024-09-19 at 14 47 00

Registering Actions

Field actions can be registered as follows. As a minimum you need to specify a display value and run callback. Quick actions also require an icon:

Statamic.$actions.add('text-fieldtype', {
    title: 'Reverse Text',
    run: ({ value, update }) => {
        update(value.split('').reverse().join(''));
    },
});

Statamic.$actions.add('table-fieldtype', {
    title: 'Import CSV',
    icon: 'add-table',
    quick: true,
    visible: () => {
        // check if visible
    },
    run: () => {
        // do something
    },
});

It's entirely up to you what you do inside the run callback. The callbacks currently receive a payload object as follows:

  • vm: The fieldtype Vue component
  • fieldPathPrefix: The field path prefix
  • handle: The field handle
  • value: The field value
  • config: The field config
  • meta: The field meta
  • update(value): The field update function
  • updateMeta(value): The field updateMeta function

And for Bard/Replicator sets:

  • vm: The set Vue component
  • fieldVm: The fieldtype Vue component
  • fieldPathPrefix: The field path prefix
  • index: The set index
  • values: The set values
  • config: The set config
  • meta: The set meta
  • update(handle, value): The set field update function
  • updateMeta(handle, value): The set field updateMeta function

Internal Actions

Fieldtype components themselves can add internal actions to the new dropdown/quick menus. This is currently used for existing expand/collapse all and toggle fullscreen features. These can be defined by adding an internalActions computed property to a fieldtype component:

computed: {
    internalActions() {
        return [
            {
                title: __('Expand All'),
                icon: 'arrows-horizontal-expand',
                quick: true,
                run: this.expandAll,
            },
            // ....
        ];
    },
},

Notes

  • There are currently three "types" of action: Actions are the ones registered through Statamic.$actions, these could also be considered Custom Actions. Internal Actions are the ones registered by fieldtypes themselves. Quick Actions are a subset of both Actions + Internal Actions and are the actions that appear in the hover-menu.
  • On the publish form the quick actions appear on hover, and they also appear in the dropdown, which makes sense since the dropdown covers up the hover-menu, and this ensures they're always accessible. In the fullscreen header there's space to always display the quick actions, but they also appear in the dropdown. This makes less sense, but I couldn't decide if it was worth filtering them out?
    • Worth pointing out that right now all internal actions are also quick actions, but they don't have to be, and it's possible to register custom quick actions as well.
  • At the moment the fullscreen mode toggle is just another action, but maybe it should have special status? It should really have a different "collapse" icon in fullscreen mode, but currently actions can only have one icon.

@jacksleight jacksleight changed the title [5.x] Field Actions [5.x] Add field actions feature Jun 21, 2024
@jacksleight jacksleight marked this pull request as ready for review September 20, 2024 15:33
@jacksleight
Copy link
Contributor Author

jacksleight commented Sep 20, 2024

This is now ready for review. There are a few implementation details and UI things that I'm still unsure about, but I'm hoping you can help figure out the final details.

@jacksleight jacksleight marked this pull request as draft September 23, 2024 17:19
@jacksleight jacksleight marked this pull request as ready for review September 24, 2024 08:21
Copy link
Member

@jackmcdade jackmcdade left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love this! The UI is so tight. I can't wait to get this merged in.

You're right about the Fullscreen icon though, we definitely need to solve the icon switching issue. Maybe we can have a FullscreenToggleAction that works more like an opt-in feature or mixin on the Fieldtype level, and fields can just say "has fullscreen" or something?

Not 100% sure the right approach, but once we solve it, I'm good on the UI/UX side to merge.

@jackmcdade jackmcdade requested a review from jasonvarga November 5, 2024 18:28
@jacksleight
Copy link
Contributor Author

jacksleight commented Nov 6, 2024

You're right about the Fullscreen icon though, we definitely need to solve the icon switching issue. Maybe we can have a FullscreenToggleAction that works more like an opt-in feature or mixin on the Fieldtype level, and fields can just say "has fullscreen" or something?

As a possible solution I've added the ability for the icon to be resolved via a callback that can check the state of the field. I've updated all the fullscreen toggles to use that (the close icon probably needs to be tweaked). There might be a better approach, but this is an option.

I'm also now wondering if these actions should have handles? Pretty much everything else in Statamic has handles, and giving each action a unique handle could be useful down the road... not sure though. Anyway you and Jason can review and decide.

- Move logic into a dedicated FieldAction class.
- Avoids passing around functions as props and needing to define field action related functions in mixins
- The quick property can now also be a function.
- The run, quick, visible, and icon methods all get the same payload.
@jasonvarga jasonvarga changed the title [5.x] Add field actions feature [5.x] Field actions Nov 20, 2024
@jasonvarga jasonvarga merged commit 63be821 into statamic:5.x Nov 20, 2024
15 checks passed
@sorentv2reg
Copy link

This is so cool Jack - Could the buttons be made reactive, i.e. a small icon above title turns red if some rules are triggered (i.e. a background check against an AI model). Obviously there would also need to be some logic that controls how often the check is triggered (field states, field content, time based, and so on).

@jacksleight
Copy link
Contributor Author

@sorentv2reg In theory yes, the icons can already be reactive based on the field state. But they only appear when you hover the menu so may not be that useful as an indicator.

@geert-salamander
Copy link

@jacksleight there seems to be a small bug when using a replicator inside a group. See screenshot below. The one in the group (above) shows the 3 dots below the description instead of to the right.

Screenshot 2024-11-26 at 16 07 03

@jacksleight
Copy link
Contributor Author

@geert-salamander That's been fixed in #11165, not released yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants