aboutsummaryrefslogtreecommitdiff
path: root/pearl.el
diff options
context:
space:
mode:
Diffstat (limited to 'pearl.el')
-rw-r--r--pearl.el54
1 files changed, 54 insertions, 0 deletions
diff --git a/pearl.el b/pearl.el
index 593cf47..662d7b9 100644
--- a/pearl.el
+++ b/pearl.el
@@ -4498,6 +4498,60 @@ view's server order is honored); every other source uses `:sort'/`:order'."
(cons (plist-get source :client-sort) (plist-get source :client-order))
(cons (plist-get source :sort) (plist-get source :order))))
+(defconst pearl--grouping-choices
+ '(("status" . "workflowState")
+ ("project" . "project")
+ ("assignee" . "assignee")
+ ("priority" . "priority")
+ ("none" . nil))
+ "Interactive grouping dimensions: (DISPLAY . `issueGrouping' VALUE).
+DISPLAY is what `pearl-set-grouping' completes; VALUE is the Linear
+`issueGrouping' the render path speaks, or nil for \"none\" (ungroup). `cycle'
+is intentionally absent: it isn't rendered into the issue drawer (see
+`pearl--format-issue-as-org-entry'), so an offline client-side regroup can't
+read it -- deferred until cycle drawer fields land.")
+
+(defun pearl--grouping-display-to-value (display)
+ "Coerce a DISPLAY grouping label to its `issueGrouping' value (or nil).
+Signals a `user-error' for a label outside `pearl--grouping-choices'."
+ (let ((cell (assoc display pearl--grouping-choices)))
+ (unless cell
+ (user-error "Unknown grouping %s; use one of %s"
+ display (mapconcat #'car pearl--grouping-choices "/")))
+ (cdr cell)))
+
+(defun pearl--check-grouping (value)
+ "Validate a grouping VALUE; signal a `user-error' on an unknown one.
+Returns t when VALUE is nil (none) or one of the interactive grouping values
+\(`pearl--grouping-choices'). `cycle' and any other unsupported value are
+rejected -- the render path treats them as flat, but the interactive command
+refuses them before writing the header."
+ (let ((allowed (delq nil (mapcar #'cdr pearl--grouping-choices))))
+ (when (and value (not (member value allowed)))
+ (user-error "Unknown grouping %s; use %s or none"
+ value (mapconcat #'car (butlast pearl--grouping-choices) "/"))))
+ t)
+
+(defun pearl--source-with-grouping (source value)
+ "Return SOURCE with grouping VALUE recorded under `:client-group'.
+VALUE is an `issueGrouping' string for all source types (uniform key); a view's
+own server `:group' is left intact so clearing the override restores it. A nil
+VALUE (none) removes `:client-group' entirely, so `pearl--effective-grouping'
+falls back to the server `:group' (a view) or to flat (a filter)."
+ (if value
+ (plist-put (copy-sequence source) :client-group value)
+ (cl-loop for (k v) on source by #'cddr
+ unless (eq k :client-group) append (list k v))))
+
+(defun pearl--effective-grouping (source)
+ "Return the `issueGrouping' value SOURCE should render by, or nil for flat.
+An interactive `:client-group' overrides a view's server `:group'; with no
+override, a view uses its `:group' and a filter is flat. Every grouping
+consumer (render, merge, append, refresh) reads through this so a refresh
+reproduces the layout on screen rather than the server grouping."
+ (or (plist-get source :client-group)
+ (plist-get source :group)))
+
;;; Sentinel infrastructure for filter / pick-one prompts
;;
;; These sentinel constants and helpers back the prompt UX shared by