From 50588da322d3193bd03d1fc349f5690252626a25 Mon Sep 17 00:00:00 2001 From: ditatompel <ditatompel@gmail.com> Date: Tue, 7 May 2024 23:23:31 +0700 Subject: [PATCH] Edit prober name action --- .../routes/(loggedin)/app/prober/+page.svelte | 42 ++++++++++++++++++- .../(loggedin)/app/prober/api-handler.js | 13 ++++++ handler/response.go | 25 +++++++++++ handler/routes.go | 1 + internal/repo/prober.go | 19 ++++++--- 5 files changed, 92 insertions(+), 8 deletions(-) diff --git a/frontend/src/routes/(loggedin)/app/prober/+page.svelte b/frontend/src/routes/(loggedin)/app/prober/+page.svelte index 791b8df..51567cb 100644 --- a/frontend/src/routes/(loggedin)/app/prober/+page.svelte +++ b/frontend/src/routes/(loggedin)/app/prober/+page.svelte @@ -1,7 +1,7 @@ <script> import { DataHandler } from '@vincjo/datatables/remote'; import { format, formatDistance } from 'date-fns'; - import { loadData, deleteData } from './api-handler'; + import { loadData, deleteData, editProber } from './api-handler'; import { onMount, onDestroy } from 'svelte'; import { getModalStore, getToastStore } from '@skeletonlabs/skeleton'; import { @@ -14,6 +14,40 @@ const modalStore = getModalStore(); const toastStore = getToastStore(); + /** + * @param {string} proberId + * @param {string} proberName + */ + function showEditModal(proberId, proberName) { + /** @type {import('@skeletonlabs/skeleton').ModalSettings} */ + const modal = { + type: 'prompt', + // Data + title: 'Enter Name', + body: 'Enter a new name for the prober', + value: proberName, + valueAttr: { type: 'text', minlength: 3, maxlength: 50, required: true }, + response: (r) => { + editProber(proberId, r) + .then((res) => { + if (res.status !== 'ok') { + toastStore.trigger({ message: 'Failed to edit prober' }); + } else { + toastStore.trigger({ + message: 'Prober edited', + background: 'variant-filled-success' + }); + handler.invalidate(); + } + }) + .catch(() => { + toastStore.trigger({ message: 'Failed to edit prober' }); + }); + } + }; + modalStore.trigger(modal); + } + /** @param {number} id */ const handleDelete = (id) => { modalStore.trigger({ @@ -143,7 +177,11 @@ <td> {row.id} <button - class="variant-filled-error btn btn-sm mr-1" + class="variant-filled-secondary btn btn-sm mr-1" + on:click={() => showEditModal(row.id, row.name)}>Edit</button + > + <button + class="variant-filled-error btn btn-sm" name="delete_{row.id}" on:click={() => { handleDelete(row.id); diff --git a/frontend/src/routes/(loggedin)/app/prober/api-handler.js b/frontend/src/routes/(loggedin)/app/prober/api-handler.js index 4b9b683..bd40b38 100644 --- a/frontend/src/routes/(loggedin)/app/prober/api-handler.js +++ b/frontend/src/routes/(loggedin)/app/prober/api-handler.js @@ -17,6 +17,19 @@ export const deleteData = async (id) => { return json; }; +export const editProber = async (id, name) => { + const response = await fetch(apiUri(`/api/v1/prober/${id}`), { + method: 'PATCH', + credentials: 'include', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ name }) + }); + const json = await response.json(); + return json; +}; + const getParams = ({ pageNumber, rowsPerPage, sort, filters }) => { let params = `page=${pageNumber}&limit=${rowsPerPage}`; diff --git a/handler/response.go b/handler/response.go index 3d4a8df..4b572c2 100644 --- a/handler/response.go +++ b/handler/response.go @@ -104,6 +104,31 @@ func Prober(c *fiber.Ctx) error { "message": "Success", "data": nil, }) + } else if c.Method() == "PATCH" { + payload := repo.Prober{} + if err := c.BodyParser(&payload); err != nil { + return c.Status(fiber.StatusUnprocessableEntity).JSON(fiber.Map{ + "status": "error", + "message": err.Error(), + "data": nil, + }) + } + if payload.Name == "" { + return c.Status(fiber.StatusUnprocessableEntity).JSON(fiber.Map{ + "status": "error", + "message": "Please fill prober name", + "data": nil, + }) + } + id, _ := strconv.Atoi(c.Params("id")) + err := proberRepo.Update(id, payload.Name) + if err != nil { + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "status": "error", + "message": err.Error(), + "data": nil, + }) + } } query := repo.ProbersQueryParams{ diff --git a/handler/routes.go b/handler/routes.go index 3e00302..cfa493f 100644 --- a/handler/routes.go +++ b/handler/routes.go @@ -14,6 +14,7 @@ func V1Api(app *fiber.App) { v1.Get("/prober", Prober) v1.Post("/prober", Prober) + v1.Patch("/prober/:id", CookieProtected, Prober) v1.Delete("/prober/:id", CookieProtected, Prober) v1.Get("/nodes", MoneroNodes) v1.Post("/nodes", AddNode) diff --git a/internal/repo/prober.go b/internal/repo/prober.go index ed2089c..2f07e12 100644 --- a/internal/repo/prober.go +++ b/internal/repo/prober.go @@ -12,6 +12,7 @@ import ( type ProberRepository interface { AddProber(name string) error + Update(id int, name string) error Probers(q ProbersQueryParams) (Probers, error) CheckApi(key string) (Prober, error) Delete(id int) error @@ -59,6 +60,18 @@ func (repo *ProberRepo) AddProber(name string) error { return nil } +func (repo *ProberRepo) Update(id int, name string) error { + query := `UPDATE tbl_prober SET name = ? WHERE id = ?` + _, err := repo.db.Exec(query, name, id) + return err +} + +func (repo *ProberRepo) Delete(id int) error { + query := `DELETE FROM tbl_prober WHERE id = ?` + _, err := repo.db.Exec(query, id) + return err +} + func (repo *ProberRepo) Probers(q ProbersQueryParams) (Probers, error) { queryParams := []interface{}{} whereQueries := []string{} @@ -125,9 +138,3 @@ func (repo *ProberRepo) CheckApi(key string) (Prober, error) { err := repo.db.QueryRow(query, key).Scan(&prober.Id, &prober.Name, &prober.ApiKey, &prober.LastSubmitTs) return prober, err } - -func (repo *ProberRepo) Delete(id int) error { - query := `DELETE FROM tbl_prober WHERE id = ?` - _, err := repo.db.Exec(query, id) - return err -}