PhoenixKit.Modules.Storage.Reorganizer.Action (phoenix_kit v2.32.1)

Copy Markdown View Source

The one action shape PhoenixKit.Modules.Storage.Reorganizer understands.

A Source returns plain maps (so a module can build them without compiling against this module — see Source's moduledoc). new!/1 validates the shape and fills defaults for anything the source left out; the engine works with the normalized result from here on.

Summary

Functions

Validates a plain map from a Source, raising ArgumentError naming the offending key on any problem, and fills defaults for keys the source didn't set.

A :move action is a no-op when the folder it targets already sits at the wanted parent_uuid with the wanted name (or an accepted "name (N)" variant of it — matches the previous run's own suffix-on-collision output, so re-running plan/2 doesn't propose renaming it back and forth). A nil name means "keep the current name", so it always matches.

Types

on_conflict()

@type on_conflict() :: :suffix | :report

op()

@type op() :: :move | :trash | :report

t()

@type t() :: %{
  :source => String.t(),
  :kind => atom(),
  :label => String.t(),
  :op => op(),
  optional(:folder) =>
    %PhoenixKit.Modules.Storage.Folder{
      __meta__: term(),
      children: term(),
      color: term(),
      cover_file_uuid: term(),
      description: term(),
      files: term(),
      folder_links: term(),
      header_show_background: term(),
      header_show_creator: term(),
      header_show_date: term(),
      header_show_description: term(),
      header_show_file_count: term(),
      header_show_icon: term(),
      header_show_title: term(),
      header_size: term(),
      inserted_at: term(),
      logo_file_uuid: term(),
      name: term(),
      parent: term(),
      parent_uuid: term(),
      trashed_at: term(),
      updated_at: term(),
      user: term(),
      user_uuid: term(),
      uuid: term()
    }
    | nil,
  optional(:parent_uuid) => String.t() | nil,
  optional(:name) => String.t() | nil,
  optional(:counts) => {non_neg_integer(), non_neg_integer()} | nil,
  optional(:on_conflict) => on_conflict(),
  optional(:after_move) => (-> :ok | {:ok, term()} | {:error, term()}) | nil,
  optional(:reason) => String.t() | nil,
  optional(:outcome) => atom(),
  optional(:changes) => [:moved | :renamed | :restored],
  optional(:error) => term()
}

Functions

new!(attrs)

@spec new!(map()) :: t()

Validates a plain map from a Source, raising ArgumentError naming the offending key on any problem, and fills defaults for keys the source didn't set.

noop?(action)

@spec noop?(t()) :: boolean()

A :move action is a no-op when the folder it targets already sits at the wanted parent_uuid with the wanted name (or an accepted "name (N)" variant of it — matches the previous run's own suffix-on-collision output, so re-running plan/2 doesn't propose renaming it back and forth). A nil name means "keep the current name", so it always matches.

An action carrying after_move is never a noop, even when the folder is already in place: the folder position matching doesn't mean the pointer back-fill it exists to run has happened — the engine still needs to apply it (see PhoenixKit.Modules.Storage.Reorganizer's move path, which skips update_folder but still runs after_move in that case).

A trashed folder is never a noop either, even when its parent/name already match: restoring it is itself a change the engine must apply (outcome :restored when nothing else about it changes).