Class: Plutonium::UI::Kanban::Resource
- Inherits:
-
Component::Base
- Object
- Component::Base
- Plutonium::UI::Kanban::Resource
- Includes:
- Phlex::Rails::Helpers::TurboFrameTag, Phlex::Rails::Helpers::TurboStreamFrom, ColorDot
- Defined in:
- lib/plutonium/ui/kanban/resource.rb
Overview
Board shell — renders one lazy turbo-frame per column.
Each frame id is "kanban-col-
The outer wrapper carries data-controller="kanban" for the Stimulus drag controller wired in Task 11.
Realtime subscription: when board.realtime? is true, render_realtime_subscription is called before the board wrapper. Task 14 implements the broadcaster and fills in that method body.
Instance Attribute Summary collapse
-
#board ⇒ Object
readonly
Returns the value of attribute board.
-
#grouped_data ⇒ Object
readonly
Returns the value of attribute grouped_data.
-
#resource_class ⇒ Object
readonly
Returns the value of attribute resource_class.
-
#resource_definition ⇒ Object
readonly
Returns the value of attribute resource_definition.
-
#resource_fields ⇒ Object
readonly
Returns the value of attribute resource_fields.
-
#scoped_entity ⇒ Object
readonly
Returns the value of attribute scoped_entity.
Class Method Summary collapse
-
.collapse_cookie_name(resource_class) ⇒ Object
Per-board collapse cookie.
- .collapse_cookie_path(request) ⇒ Object
-
.collapse_flips(cookie_value) ⇒ Object
The set of column keys (strings) flipped from their default, parsed from the cookie value.
Instance Method Summary collapse
-
#initialize(board:, grouped_data:, resource_definition:, resource_fields:, resource_class: nil, scoped_entity: nil) ⇒ Resource
constructor
A new instance of Resource.
- #view_template ⇒ Object
Methods included from ColorDot
#color_css_value, #render_color_dot
Methods included from Component::Behaviour
Methods included from Component::Tokens
Methods included from Component::Kit
#BuildActionButton, #BuildActionsDropdown, #BuildAvatar, #BuildBlock, #BuildBreadcrumbs, #BuildBulkActionsToolbar, #BuildColorModeSelector, #BuildDynaFrameContent, #BuildDynaFrameHost, #BuildEmptyCard, #BuildFrameNavigatorPanel, #BuildModalCentered, #BuildModalSlideover, #BuildPageHeader, #BuildPanel, #BuildRowActionsDropdown, #BuildSkeletonTable, #BuildTabList, #BuildTableFilterPills, #BuildTableInfo, #BuildTablePagination, #BuildTableScopesBar, #BuildTableScopesPills, #BuildTableSearchBar, #BuildTableToolbar, #BuildTableViewSwitcher, #method_missing, #respond_to_missing?
Constructor Details
#initialize(board:, grouped_data:, resource_definition:, resource_fields:, resource_class: nil, scoped_entity: nil) ⇒ Resource
Returns a new instance of Resource.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/plutonium/ui/kanban/resource.rb', line 52 def initialize(board:, grouped_data:, resource_definition:, resource_fields:, resource_class: nil, scoped_entity: nil) @board = board @grouped_data = grouped_data @resource_definition = resource_definition # TODO (Tasks 6/10): resource_fields arrives ALREADY resolved — the # column endpoint / index page is responsible for the # `board.card_fields || definition.grid_fields` fallback before # constructing this component. Kanban::Resource (and the Card it # eventually builds) just receives the final field list and renders # it; it does not resolve card_fields itself. @resource_fields = resource_fields # Used by render_realtime_subscription (Task 14) to scope the # ActionCable stream to the correct tenant + resource. @resource_class = resource_class @scoped_entity = scoped_entity end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class Plutonium::UI::Component::Kit
Instance Attribute Details
#board ⇒ Object (readonly)
Returns the value of attribute board.
49 50 51 |
# File 'lib/plutonium/ui/kanban/resource.rb', line 49 def board @board end |
#grouped_data ⇒ Object (readonly)
Returns the value of attribute grouped_data.
49 50 51 |
# File 'lib/plutonium/ui/kanban/resource.rb', line 49 def grouped_data @grouped_data end |
#resource_class ⇒ Object (readonly)
Returns the value of attribute resource_class.
49 50 51 |
# File 'lib/plutonium/ui/kanban/resource.rb', line 49 def resource_class @resource_class end |
#resource_definition ⇒ Object (readonly)
Returns the value of attribute resource_definition.
49 50 51 |
# File 'lib/plutonium/ui/kanban/resource.rb', line 49 def resource_definition @resource_definition end |
#resource_fields ⇒ Object (readonly)
Returns the value of attribute resource_fields.
49 50 51 |
# File 'lib/plutonium/ui/kanban/resource.rb', line 49 def resource_fields @resource_fields end |
#scoped_entity ⇒ Object (readonly)
Returns the value of attribute scoped_entity.
49 50 51 |
# File 'lib/plutonium/ui/kanban/resource.rb', line 49 def scoped_entity @scoped_entity end |
Class Method Details
.collapse_cookie_name(resource_class) ⇒ Object
Per-board collapse cookie. Stores ONLY the column keys whose collapse state differs from the server default (a compact delta): a board sitting at its defaults writes nothing, and toggling a column back to default drops its key — so the cookie can't balloon. Path-scoped to the engine mount so it rides only this board's requests. The server reads it to render each column in the user's state (no client re-apply / FOUC); the kanban controller writes it on toggle.
34 35 36 |
# File 'lib/plutonium/ui/kanban/resource.rb', line 34 def self.(resource_class) "pu_kbc_#{resource_class.name.gsub("::", "_").underscore}" end |
.collapse_cookie_path(request) ⇒ Object
38 39 40 41 |
# File 'lib/plutonium/ui/kanban/resource.rb', line 38 def self.(request) path = request.script_name.to_s path.empty? ? "/" : path end |
.collapse_flips(cookie_value) ⇒ Object
The set of column keys (strings) flipped from their default, parsed from the cookie value. Order/whitespace-tolerant; blanks dropped.
45 46 47 |
# File 'lib/plutonium/ui/kanban/resource.rb', line 45 def self.collapse_flips() .to_s.split(",").filter_map { |k| k.strip.presence } end |
Instance Method Details
#view_template ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/plutonium/ui/kanban/resource.rb', line 70 def view_template render_realtime_subscription if board.realtime? # Wrap in the filter-panel controller so the toolbar's Filter button # can open the slideover — same structure as Grid/Table::Resource, so # the board carries the shared view switcher (Table | Grid | Board), # search, scopes, and filters rather than rendering bare columns. div(data: filter_panel_controller_data) do # Persistent append target for move-rejection toasts. It lives # OUTSIDE the per-column turbo-frames so it survives the frame swaps # a move triggers; toasts are position:fixed, so its location in the # DOM has no layout effect. The move handler appends a flash toast # here via turbo_stream when a drop is rejected (WIP / accepts / # locked) so the snap-back is explained rather than silent. div(id: "kanban-flash") render_scopes_pills div( # `data-turbo-permanent` freezes the loaded board across index # navigations (search / filter / scope all change the URL): Turbo # transplants THIS element instead of re-rendering it as empty lazy # shells, so the columns never blank. The `kanban` controller then # syncs the frozen frames to the new URL (morphing cards in place). # The id MUST be resource-scoped — a shared id would make Turbo # preserve one resource's board when navigating to another's. id: "kanban-board-#{resource_class.model_name.param_key}", class: "pu-kanban-board flex gap-4 overflow-x-auto p-4 min-h-0", data: { turbo_permanent: true, controller: "kanban", # Stimulus value consumed by the drag controller to build the # per-record move URL at drop time. The collection path comes from # request.path so tenant / engine scoping is preserved automatically. # Example: /admin/tasks/__ID__/kanban_move kanban_move_url_template_value: kanban_move_url_template, # Name + path the controller uses to write the collapse cookie — # must match what the server reads (see collapse_cookie_name/path). kanban_collapse_cookie_value: self.class.(resource_class), kanban_collapse_path_value: self.class.(request) } ) do grouped_data.each do |entry| render_column_frame(entry[:column], collapsed: entry[:collapsed]) end end if current_query_object.filter_definitions.present? end end |