0d44e5e6 |
(in-package :mfa-tool)
(defpackage :mfa-tool.stack
(:use :cl)
(:export #:stack-interface
#:format-stack-status))
(in-package :mfa-tool.stack)
(defun dispatch-with-action-creator (action-creator)
(lambda (store data)
(mfa-tool.store:dispatch store
(funcall action-creator data))))
(defmacro with-pp ((pane) &body body)
`(capi:apply-in-pane-process ,pane
(lambda ()
,@body)))
(defun human-readable-stack-status (stack)
(nstring-capitalize
(substitute #\space #\_
(string (daydreamer.aws-result:stack-status stack)))))
(defun format-stack-status (stream stack &optional colon-p at-sign-p)
(declare (ignore colon-p at-sign-p))
(princ (human-readable-stack-status stack)
stream))
(defun get-output-columns (type col1 col2)
|
4dde8453 |
`((:title ,(format nil "~a Name" type)
|
0d44e5e6 |
:adjust :right
:width (character ,(max (+ (length type) 5) col1)))
|
4dde8453 |
(:title "Value"
|
0d44e5e6 |
:adjust :left
:width (character ,(max (+ (length type) 5) col2)))))
|
8a9ff578 |
;; doesn't work, seems to cause segfaults, but would be a cool feature :(
(defun go-to-console (interface stack)
(with-pp (interface)
(mfa-tool::open-url
(format nil "https://us-west-2.console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/stackinfo?stackId=~a"
(quri:url-encode (daydreamer.aws-result:stack-id stack))))))
|
0d44e5e6 |
(capi:define-interface stack-interface (capi:interface mfa-tool.stack-store:stack-store)
()
(:panes
(region-chooser capi:option-pane
:reader region-chooser
;; :external-max-width '(character 35)
|
4dde8453 |
:items (list :|us-east-1| :|us-east-2|
:|us-west-1| :|us-west-2|
:|ca-central-1|
:|eu-central-1|
:|eu-west-1| :|eu-west-2|)
:selected-item (mfa-tool.aws-dispatcher::region capi:interface)
|
0d44e5e6 |
:selection-callback (dispatch-with-action-creator 'mfa-tool.aws-dispatcher::update-region)
:callback-type :interface-data)
(stack-chooser capi:list-panel
:reader stack-chooser
;; :external-max-width '(character 35)
:items ()
:print-function 'daydreamer.aws-result:stack-name
:selection-callback (dispatch-with-action-creator 'mfa-tool.aws-dispatcher:select-stack)
:callback-type :interface-data)
|
81fd0fa2 |
(refresh-status capi:push-button
:text "Refresh"
:callback-type :interface
:callback (lambda (store)
(mfa-tool.store:dispatch store :refresh)))
|
8a9ff578 |
#+(or)
(open-web-console capi:push-button
:text "Open"
:callback-type :interface
:callback (lambda (store)
(go-to-console
(mfa-tool.stack-store:selected-stack store))))
|
0d44e5e6 |
(status-display capi:display-pane
:background :transparent
:reader status-display
:text "")
(outputs-display capi:multi-column-list-panel
:columns (get-output-columns "Output" 10 10)
:header-args (list :selection-callback :sort)
:sort-descriptions (list (capi:make-sorting-description
:type "Output Name"
:key 'car
:sort 'string-lessp
:reverse-sort 'string-greaterp)
(capi:make-sorting-description
:type "Value"
:key 'cadr
:sort 'string-lessp
:reverse-sort 'string-greaterp))
:items nil
:vertical-scroll t
:reader outputs-display
:visible-min-height '(character 10)
:visible-min-width '(character 50))
(parameters-display capi:multi-column-list-panel
:columns (get-output-columns "Parameter" 10 10)
:header-args (list :selection-callback :sort)
:sort-descriptions (list (capi:make-sorting-description
:type "Parameter Name"
:key 'car
:sort 'string-lessp
:reverse-sort 'string-greaterp)
(capi:make-sorting-description
:type "Value"
:key 'cadr
:sort 'string-lessp
:reverse-sort 'string-greaterp))
:items nil
:vertical-scroll t
:reader parameters-display
:visible-min-height '(character 10)
:visible-min-width '(character 50)))
(:layouts
(key-layout capi:column-layout
'(region-chooser
stack-chooser)
:visible-max-width '(character 35))
|
81fd0fa2 |
(status-layout capi:row-layout
'(status-display
nil
#+(or)open-web-console
refresh-status)
:adjust :center)
|
0d44e5e6 |
(attribute-layout capi:column-layout
|
81fd0fa2 |
'(status-layout
|
0d44e5e6 |
parameters-display
outputs-display))
(main-layout capi:row-layout
'(key-layout
attribute-layout)))
(:default-initargs
:layout 'main-layout
:title "Stack Explorer"
:visible-min-width 800))
(defmethod mfa-tool.store:execute :after ((interface stack-interface) (_ mfa-tool.aws-dispatcher:update-stacks))
(with-pp (interface)
(with-accessors ((stack-chooser stack-chooser)) interface
|
81fd0fa2 |
(setf (capi:collection-items stack-chooser) (mfa-tool.stack-store:available-stacks interface)
(capi:choice-selected-item
(stack-chooser interface)) (mfa-tool.stack-store:selected-stack interface)))))
|
0d44e5e6 |
(defun max-widths (cols)
(loop for (col1 col2) in cols
maximizing (length col1) into len1
maximizing (length col2) into len2
finally (return (list len1 len2))))
(defmethod mfa-tool.store:execute :after ((interface stack-interface) (_ mfa-tool.aws-dispatcher:select-stack))
(with-pp (interface)
(with-accessors ((status-display status-display) (selected-stack mfa-tool.stack-store:selected-stack)
(outputs-display outputs-display) (outputs mfa-tool.stack-store:outputs)
(parameters-display parameters-display) (parameters mfa-tool.stack-store:parameters))
interface
(capi:modify-multi-column-list-panel-columns
outputs-display :columns (apply 'get-output-columns "Output" (max-widths outputs)))
(capi:modify-multi-column-list-panel-columns
parameters-display :columns (apply 'get-output-columns "Parameter" (max-widths parameters)))
|
4dde8453 |
|
81fd0fa2 |
(when (not (eq (capi:choice-selected-item (stack-chooser interface))
(mfa-tool.aws-dispatcher:stack _)))
(setf (capi:choice-selected-item (stack-chooser interface)) (mfa-tool.stack-store:selected-stack interface)))
|
0d44e5e6 |
(setf (capi:display-pane-text status-display)
(format nil "~a: ~/mfa-tool.stack:format-stack-status/"
(daydreamer.aws-result:stack-name selected-stack)
selected-stack)
(capi:collection-items parameters-display) parameters
(capi:collection-items outputs-display) outputs))))
|