aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOscar Najera <hi@oscarnajera.com>2025-01-18 13:38:17 +0100
committerOscar Najera <hi@oscarnajera.com>2025-01-18 13:38:17 +0100
commit089b97cb2f1379ca8981b77edc0a4fc9e7484b66 (patch)
treed8df47992e1a26115a9f8e0940637741d8af6814
parent78130697e5e13ba068df3fc1c45c4b0146bd11c8 (diff)
downloaddotfiles-089b97cb2f1379ca8981b77edc0a4fc9e7484b66.tar.gz
dotfiles-089b97cb2f1379ca8981b77edc0a4fc9e7484b66.tar.bz2
dotfiles-089b97cb2f1379ca8981b77edc0a4fc9e7484b66.zip
[grocy] update to vtable
-rw-r--r--elisp/grocy.el106
1 files changed, 45 insertions, 61 deletions
diff --git a/elisp/grocy.el b/elisp/grocy.el
index c5ec6d6..55998de 100644
--- a/elisp/grocy.el
+++ b/elisp/grocy.el
@@ -21,14 +21,11 @@
(require 'url)
(require 'dash)
+(require 'vtable)
;; Silence byte-compiler.
(defvar url-http-end-of-headers)
-(defvar grocy-units)
-(defvar grocy-locations)
-(defvar grocy-product-groups)
-
(defcustom grocy-server ""
"Grocy main domain."
:type 'string
@@ -39,6 +36,10 @@
:type 'string
:group 'grocy)
+(defvar grocy-units (make-hash-table))
+(defvar grocy-locations (make-hash-table))
+(defvar grocy-product-groups (make-hash-table))
+
(defun grocy--request (endpoint callback &optional method data)
"Do a GET request to api ENDPOINT and call CALLBACK on the resulting buffer.
Set METHOD to other request types and include the already encoded DATA."
@@ -70,7 +71,7 @@ Set METHOD to other request types and include the already encoded DATA."
(grocy-update-info "product_groups" grocy-product-groups "name")
(defun grocy-stock--row (row)
- "Compose ROW into tabulated entry for stock view."
+ "Compose ROW into vtable object for stock view."
(-let* (((&alist 'amount 'amount_opened 'product 'best_before_date) row)
((&alist 'name 'qu_id_stock) product)
(amount
@@ -83,7 +84,7 @@ Set METHOD to other request types and include the already encoded DATA."
(concat " / "
(number-to-string amount_opened)
" open")))))
- (list row (vector best_before_date amount name))))
+ (list best_before_date amount name)))
(defun grocy-stock ()
"Show the grocery stock."
@@ -94,59 +95,45 @@ Set METHOD to other request types and include the already encoded DATA."
(goto-char url-http-end-of-headers)
(let ((result (json-parse-buffer :object-type 'alist)))
(with-current-buffer (get-buffer-create "Grocy stock")
- (tabulated-list-mode)
- (setq tabulated-list-format [("Next due" 12 t)
- ("Amount" 20 t)
- ("Product" 20 t)]
- ;; tabulated-list-padding 2
- tabulated-list-sort-key '("Next due"))
-
- (thread-last
- (cl-map 'list #'grocy-stock--row result)
- (setq tabulated-list-entries))
- (tabulated-list-init-header)
- (tabulated-list-print)
+ (erase-buffer)
+ (make-vtable
+ :columns '((:name "Next due" :primary ascend) "Amount" "Product")
+ :row-colors (list "gray12" "gray6")
+ :objects (cl-map 'list #'grocy-stock--row result))
(display-buffer (current-buffer)))))))
-(defun grocy-products--row (product)
- (-let* (((&hash "name" "location_id" "qu_id_stock"
- "min_stock_amount" "product_group_id") product)
- (prod-group (gethash product_group_id grocy-product-groups)))
- (list product
- (vector name
- (gethash location_id grocy-locations)
- (car (gethash qu_id_stock grocy-units))
- (number-to-string min_stock_amount)
- (if prod-group prod-group "NULL" )))))
-
-(defun grocy-products--refresh ()
+(defun grocy-products ()
+ "Render vtable view of products."
+ (interactive)
(grocy--request
"objects/products"
(lambda (_status)
(goto-char url-http-end-of-headers)
(let ((result (json-parse-buffer)))
(with-current-buffer (get-buffer-create "Grocy products")
- (setq tabulated-list-entries
- (cl-map 'list #'grocy-products--row result))
- (tabulated-list-print 'remember t))))))
-
-(defun grocy-products ()
- "Render tabulated list view of products."
- (interactive)
- (with-current-buffer (get-buffer-create "Grocy products")
- (tabulated-list-mode)
- (setq tabulated-list-format [("Name" 40 t)
- ("Location" 25 t)
- ("Unit" 8 t)
- ("min stock" 5 t)
- ("Group" 10 t)]
- tabulated-list-sort-key '("Name"))
- (local-set-key "e" #'grocy-update-product)
- (local-set-key "a" #'grocy-add-product-shopping-list)
- (add-hook 'tabulated-list-revert-hook #'grocy-products--refresh nil t)
- (run-hooks 'tabulated-list-revert-hook)
- (tabulated-list-init-header)
- (display-buffer (current-buffer))))
+ (erase-buffer)
+ (make-vtable
+ :columns `((:name "Name" :primary ascend
+ :getter ,(apply-partially #'gethash "name"))
+ "Location" "Unit"
+ (:name "min"
+ :getter ,(apply-partially #'gethash "min_stock_amount"))
+ "Group")
+ :actions '("e" grocy-update-product
+ "a" grocy-add-product-shopping-list)
+ :row-colors (list "gray12" "gray6")
+ :objects (seq-into result 'list)
+ :getter
+ (lambda (object column vtable)
+ (pcase (vtable-column vtable column)
+ ("Location" (thread-first (gethash "location_id" object)
+ (gethash grocy-locations)))
+ ("Unit" (thread-first (gethash "qu_id_stock" object)
+ (gethash grocy-units) car))
+ ("Group" (thread-first
+ (gethash "product_group_id" object)
+ (gethash grocy-product-groups "NULL"))))))
+ (display-buffer (current-buffer)))))))
(defun grocy--message-error-reply (status)
"Display `url-retrieve' response buffer and error STATUS."
@@ -168,12 +155,11 @@ Set METHOD to other request types and include the already encoded DATA."
(grocy-buffer-obj->json (current-buffer)))
(kill-buffer)))
-(defun grocy-add-product-shopping-list ()
- "Add selected product to first shopping list."
+(defun grocy-add-product-shopping-list (product)
+ "Add PRODUCT to first shopping list."
(interactive)
- (let* ((product (tabulated-list-get-id))
- (id (gethash "id" product))
- (name (gethash "name" product)))
+ (let ((id (gethash "id" product))
+ (name (gethash "name" product)))
(with-current-buffer (get-buffer-create "* Grocy add product to shopping list *")
(erase-buffer)
(emacs-lisp-mode)
@@ -183,11 +169,9 @@ Set METHOD to other request types and include the already encoded DATA."
(grocy-push-buffer-and-kill-fn "stock/shoppinglist/add-product" "POST"))
(switch-to-buffer (current-buffer)))))
-(defun grocy-update-product ()
- "Update form for currently selected product."
- (interactive)
- (let* ((product (tabulated-list-get-id))
- (id (gethash "id" product)))
+(defun grocy-update-product (product)
+ "Update form for PRODUCT."
+ (let ((id (gethash "id" product)))
(with-current-buffer (get-buffer-create "* Grocy update product *")
(erase-buffer)
(thread-first