feat: support setting a default story type

Expose a `org-clubhouse-default-story-type` variable that can be set to
`feature`, `bug`, `chore` or `prompt`. If set to `prompt`, the
org-clubhouse `Create new story` flow will prompt for the story type
each time. If set to any of the other values, the `Create new story`
flow will use that value for all new stories until that variable is set
otherwise.

This also exposes a new interactive function called
`org-clubhouse-set-default-story-type` that prompts users to set the
default story type value.
This commit is contained in:
Alex Dao 2018-06-10 01:05:36 -04:00 committed by Griffin Smith
parent bb97402cbe
commit c4096e5dbb

View file

@ -57,6 +57,12 @@ If unset all projects will be synchronized")
(defvar org-clubhouse-workflow-name "Default") (defvar org-clubhouse-workflow-name "Default")
(defvar org-clubhouse-default-story-type nil
"Sets the default story type. If set to 'nil', it will interactively prompt
the user each and every time a new story is created. If set to 'feature',
'bug', or 'chore', that value will be used as the default and the user will
not be prompted")
(defvar org-clubhouse-state-alist (defvar org-clubhouse-state-alist
'(("LATER" . "Unscheduled") '(("LATER" . "Unscheduled")
("[ ]" . "Ready for Development") ("[ ]" . "Ready for Development")
@ -73,6 +79,12 @@ If unset all projects will be synchronized")
("bug" . "Bug") ("bug" . "Bug")
("chore" . "Chore"))) ("chore" . "Chore")))
(defvar org-clubhouse-default-story-types
'(("feature" . "Feature")
("bug" . "Bug")
("chore" . "Chore")
("prompt" . "**Prompt each time (do not set a default story type)**")))
;;; ;;;
;;; Utilities ;;; Utilities
;;; ;;;
@ -111,6 +123,11 @@ If unset all projects will be synchronized")
) )
(defun find-match-in-alist (target alist)
(->> alist
(-find (lambda (key-value)
(string-equal (cdr key-value) target)))
car))
(defun org-clubhouse-collect-headlines (beg end) (defun org-clubhouse-collect-headlines (beg end)
"Collects the headline at point or the headlines in a region. Returns a list." "Collects the headline at point or the headlines in a region. Returns a list."
@ -175,13 +192,13 @@ If unset all projects will be synchronized")
(rx "[[" (one-or-more anything) "]" (rx "[[" (one-or-more anything) "]"
"[" (group (one-or-more digit)) "]]") "[" (group (one-or-more digit)) "]]")
clubhouse-id-link) clubhouse-id-link)
(string-to-int (match-string 1 clubhouse-id-link))) (string-to-number (match-string 1 clubhouse-id-link)))
((string-match-p ((string-match-p
(rx buffer-start (rx buffer-start
(one-or-more digit) (one-or-more digit)
buffer-end) buffer-end)
clubhouse-id-link) clubhouse-id-link)
(string-to-int clubhouse-id-link))))) (string-to-number clubhouse-id-link)))))
(comment (comment
(let ((strn "[[https://app.clubhouse.io/example/story/2330][2330]]")) (let ((strn "[[https://app.clubhouse.io/example/story/2330][2330]]"))
@ -189,7 +206,7 @@ If unset all projects will be synchronized")
(rx "[[" (one-or-more anything) "]" (rx "[[" (one-or-more anything) "]"
"[" (group (one-or-more digit)) "]]") "[" (group (one-or-more digit)) "]]")
strn) strn)
(string-to-int (match-string 1 strn))) (string-to-number (match-string 1 strn)))
) )
@ -373,10 +390,7 @@ If unset all projects will be synchronized")
:history 'org-clubhouse-project-history :history 'org-clubhouse-project-history
:action (lambda (selected) :action (lambda (selected)
(let ((project-id (let ((project-id
(->> (org-clubhouse-projects) (find-match-in-alist selected (org-clubhouse-projects))))
(-find (lambda (proj)
(string-equal (cdr proj) selected)))
car)))
(message "%d" project-id) (message "%d" project-id)
(funcall cb project-id))))) (funcall cb project-id)))))
@ -387,10 +401,7 @@ If unset all projects will be synchronized")
:history 'org-clubhouse-epic-history :history 'org-clubhouse-epic-history
:action (lambda (selected) :action (lambda (selected)
(let ((epic-id (let ((epic-id
(->> (org-clubhouse-epics) (find-match-in-alist selected (org-clubhouse-epics))))
(-find (lambda (proj)
(string-equal (cdr proj) selected)))
car)))
(message "%d" epic-id) (message "%d" epic-id)
(funcall cb epic-id))))) (funcall cb epic-id)))))
@ -402,10 +413,7 @@ If unset all projects will be synchronized")
:history 'org-clubhouse-milestone-history :history 'org-clubhouse-milestone-history
:action (lambda (selected) :action (lambda (selected)
(let ((milestone-id (let ((milestone-id
(->> (org-clubhouse-milestones) (find-match-in-alist selected (org-clubhouse-milestones))))
(-find (lambda (proj)
(string-equal (cdr proj) selected)))
car)))
(message "%d" milestone-id) (message "%d" milestone-id)
(funcall cb milestone-id))))) (funcall cb milestone-id)))))
@ -416,12 +424,22 @@ If unset all projects will be synchronized")
:history 'org-clubhouse-story-history :history 'org-clubhouse-story-history
:action (lambda (selected) :action (lambda (selected)
(let ((story-type (let ((story-type
(->> org-clubhouse-story-types (find-match-in-alist selected org-clubhouse-story-types)))
(-find (lambda (proj)
(string-equal (cdr proj) selected)))
car)))
(funcall cb story-type))))) (funcall cb story-type)))))
(defun org-clubhouse-prompt-for-default-story-type ()
(interactive)
(ivy-read
"Select a default story type: "
(-map #'cdr org-clubhouse-default-story-types)
:history 'org-clubhouse-default-story-history
:action (lambda (selected)
(let ((story-type
(find-match-in-alist selected org-clubhouse-default-story-types)))
(if (string-equal story-type "prompt")
(setq org-clubhouse-default-story-type nil)
(setq org-clubhouse-default-story-type story-type))))))
;;; ;;;
;;; Epic creation ;;; Epic creation
;;; ;;;
@ -529,6 +547,7 @@ If the epics already have a CLUBHOUSE-EPIC-ID, they are filtered and ignored."
(org-todo "TODO")))) (org-todo "TODO"))))
(defun org-clubhouse-create-story (&optional beg end) (defun org-clubhouse-create-story (&optional beg end)
"Creates a clubhouse story using selected headlines. "Creates a clubhouse story using selected headlines.
@ -548,16 +567,19 @@ If the stories already have a CLUBHOUSE-ID, they are filtered and ignored."
(when project-id (when project-id
(org-clubhouse-prompt-for-epic (org-clubhouse-prompt-for-epic
(lambda (epic-id) (lambda (epic-id)
(org-clubhouse-prompt-for-story-type (let ((selected-story-type org-clubhouse-default-story-type))
(lambda (story-type) (if (not selected-story-type)
(-map (lambda (elt) (org-clubhouse-prompt-for-story-type
(let* ((title (plist-get elt :title)) (lambda (story-type)
(story (org-clubhouse-create-story-internal set selected-story-type story-type))
title (-map (lambda (elt)
:project-id project-id (let* ((title (plist-get elt :title))
:epic-id epic-id (story (org-clubhouse-create-story-internal
:story-type story-type))) title
(org-clubhouse-populate-created-story elt story))) new-elts)))))))))) :project-id project-id
:epic-id epic-id
:story-type selected-story-type)))
(org-clubhouse-populate-created-story elt story))) new-elts))))))))))
;;; ;;;
;;; Story updates ;;; Story updates