diff --git a/assets/static/js/main.js b/assets/static/js/main.js index e9221b5..e885101 100644 --- a/assets/static/js/main.js +++ b/assets/static/js/main.js @@ -186,7 +186,13 @@ function bm_type_field_undelete(sender, type_field_id) { function bm_element_list_delete(sender, element_name, element_name_remove) { document.getElementById(element_name_remove).value = '1'; sender.hidden = true; - document.getElementById('Undelete-' + element_name).hidden = false; + + let btn = document.getElementById('Undelete-' + element_name); + if(btn !== null) btn.hidden = false; + + btn = document.getElementById('Edit-' + element_name); + if(btn !== null) btn.hidden = true; + let x = document.getElementsByClassName(element_name + "-Col"); for (let i = 0; i < x.length; i++) { x[i].classList.add("field-opaque"); @@ -196,7 +202,13 @@ function bm_element_list_delete(sender, element_name, element_name_remove) { function bm_element_list_undelete(sender, element_name, element_name_remove) { document.getElementById(element_name_remove).value = ''; sender.hidden = true; - document.getElementById('Delete-' + element_name).hidden = false; + + let btn = document.getElementById('Delete-' + element_name); + if(btn !== null) btn.hidden = false; + + btn = document.getElementById('Edit-' + element_name); + if(btn !== null) btn.hidden = false; + let x = document.getElementsByClassName(element_name + "-Col"); for (let i = 0; i < x.length; i++) { x[i].classList.remove("field-opaque"); diff --git a/assets/templates/items/share.tmpl b/assets/templates/items/share.tmpl index f81d4d5..6ffbd96 100644 --- a/assets/templates/items/share.tmpl +++ b/assets/templates/items/share.tmpl @@ -40,12 +40,9 @@

-
- Permissions
-
{{ widget_checkbox "Permission_edit" "Edit" "1" "" }}
-
-
+

{{ widget_checkbox "Permission_edit" "Allow editing" "1" "" }}

+ diff --git a/assets/templates/items/share_edit.tmpl b/assets/templates/items/share_edit.tmpl new file mode 100644 index 0000000..64365eb --- /dev/null +++ b/assets/templates/items/share_edit.tmpl @@ -0,0 +1,52 @@ +{{define "page:content"}} + +
+
Share item
+ +
+
+
+
{{ .itemShare.ItemTitle }}
+
+
+

+ + +

+
+
+

+ + +

+
+
+
+
+

+ +

+ {{ .baseUrl }}/ + +
+

+
+
+
+
+

+ + +

+
+
+
+

{{ widget_checkbox "Permission_edit" "Allow editing" "1" "" }}

+
+ +
+
+
+ {{ end }} \ No newline at end of file diff --git a/assets/templates/items/shares.tmpl b/assets/templates/items/shares.tmpl index cd8cc70..f8e6f21 100644 --- a/assets/templates/items/shares.tmpl +++ b/assets/templates/items/shares.tmpl @@ -19,7 +19,11 @@ - {{ .PermissionEdit }} + {{ if eq .PermissionEdit 1}} + + {{ else }} + + {{ end }} {{ .StartDatetime }} @@ -30,6 +34,7 @@ + {{ end }} diff --git a/cmd/web/items_handlers.go b/cmd/web/items_handlers.go index 1fa9806..f80795d 100644 --- a/cmd/web/items_handlers.go +++ b/cmd/web/items_handlers.go @@ -965,8 +965,8 @@ func (app *application) itemShare(w http.ResponseWriter, r *http.Request) { EndDatetime: itemShareFromForm.EndDatetime, } - itemshareModel := &models.ItemShareModel{DB: app.db} - _, err = itemshareModel.Create(itemShare) + itemShareModel := models.NewItemShareModel(app.db) + _, err = itemShareModel.Create(itemShare) if err != nil { app.badRequest(w, err) return @@ -975,14 +975,77 @@ func (app *application) itemShare(w http.ResponseWriter, r *http.Request) { dataMessage := make(map[string]string) dataMessage["messageType"] = "success" - dataMessage["messageContent"] = "Item shared successfully" + dataMessage["messageContent"] = "Item shared created successfully" err = response.HXFragment(fullBuf, []string{"partials/message.tmpl"}, "message", dataMessage) if err != nil { app.serverError(w, r, err) } w.Header().Add("HX-Reswap", `beforeend`) - w.Header().Add("HX-Trigger-After-Settle", `{"showMessage": "", "closeModalDialog": ""}`) + w.Header().Add("HX-Trigger-After-Swap", `{"showMessage": "", "closeModalDialog": ""}`) + + fullBuf.WriteTo(w) + } +} + +func (app *application) itemShareEdit(w http.ResponseWriter, r *http.Request) { + itemShareModel := models.NewItemShareModel(app.db) + id, _ := strconv.ParseInt(flow.Param(r.Context(), "id"), 10, 64) + itemShare, _, _ := itemShareModel.One(id) + + data := app.newTemplateData(r) + data["itemShare"] = itemShare + data["baseUrl"] = app.config.baseURL + + switch r.Method { + case http.MethodGet: + var fullBuf = new(bytes.Buffer) + + err := response.HXFragment(fullBuf, []string{"items/share_edit.tmpl"}, "page:content", data) + if err != nil { + app.serverError(w, r, err) + } + + w.Header().Add("HX-Trigger-After-Swap", `{"showModalDialog": ""}`) + fullBuf.WriteTo(w) + case http.MethodPost: + var itemShareFromForm itemShareForm + + err := request.DecodePostForm(r, &itemShareFromForm) + if err != nil { + app.serverError(w, r, err) + } + + if !itemShareFromForm.Validate(w, r, app, data) { + return + } + + itemShare := &models.ItemShare{ + Token: itemShareFromForm.Token, + Password: itemShareFromForm.Password, + PermissionEdit: itemShareFromForm.PermissionEdit, + StartDatetime: itemShareFromForm.StartDatetime, + EndDatetime: itemShareFromForm.EndDatetime, + } + itemShare.Id = id + + err = itemShareModel.Update(itemShare) + if err != nil { + app.badRequest(w, err) + return + } + var fullBuf = new(bytes.Buffer) + + dataMessage := make(map[string]string) + dataMessage["messageType"] = "success" + dataMessage["messageContent"] = "Item shared edited successfully" + err = response.HXFragment(fullBuf, []string{"partials/message.tmpl"}, "message", dataMessage) + if err != nil { + app.serverError(w, r, err) + } + + w.Header().Add("HX-Reswap", `beforeend`) + w.Header().Add("HX-Trigger-After-Swap", `{"showMessage": "", "closeModalDialog": ""}`) fullBuf.WriteTo(w) } diff --git a/cmd/web/routes.go b/cmd/web/routes.go index 1f71a47..6f464b4 100644 --- a/cmd/web/routes.go +++ b/cmd/web/routes.go @@ -53,6 +53,7 @@ func (app *application) routes() http.Handler { mux.HandleFunc("/item/update/:item_id", app.itemUpdate, "GET", "POST") mux.HandleFunc("/item/delete/:item_id", app.itemDelete, "DELETE") mux.HandleFunc("/item/share/:item_id", app.itemShare, "GET", "POST") + mux.HandleFunc("/item/share/edit/:id", app.itemShareEdit, "GET", "POST") mux.HandleFunc("/item/add-to-dashboard/:item_id", app.itemAddToDashboard, "POST") mux.HandleFunc("/item/remove-from-dashboard/:item_id", app.itemRemoveFromDashboard, "POST", "DELETE") diff --git a/models/constructors.go b/models/constructors.go index f581078..049e2d4 100644 --- a/models/constructors.go +++ b/models/constructors.go @@ -11,3 +11,7 @@ func NewQuicknoteModel(db *database.DB) *QuicknoteModel { func NewItemModel(db *database.DB) *ItemModel { return &ItemModel{BaseModel: &BaseModel{db}} } + +func NewItemShareModel(db *database.DB) *ItemShareModel { + return &ItemShareModel{BaseModel: &BaseModel{db}} +} diff --git a/models/itemshare.go b/models/itemshare.go index 02a1c74..f2e3c5c 100644 --- a/models/itemshare.go +++ b/models/itemshare.go @@ -7,7 +7,7 @@ import ( ) type ItemShareModel struct { - DB *database.DB + *BaseModel } type ItemShare struct { @@ -18,6 +18,24 @@ type ItemShare struct { StartDatetime string `db:"start_datetime"` EndDatetime string `db:"end_datetime"` Password string `db:"password"` + ItemTitle string `db:"item_title"` +} + +func (model *ItemShareModel) One(id int64) (*ItemShare, bool, error) { + ctx, cancel := database.GetContext() + defer cancel() + + var row ItemShare + + query := `SELECT bmi.title AS item_title, bmis.* FROM bm_item_shares bmis + INNER JOIN bm_item bmi ON bmis.item_id=bmi.id WHERE bmis.id = $1` + + err := model.DB.GetContext(ctx, &row, query, id) + if errors.Is(err, sql.ErrNoRows) { + return nil, false, nil + } + + return &row, true, err } func (model *ItemShareModel) Create(ItemShare *ItemShare) (int64, error) { @@ -39,6 +57,20 @@ func (model *ItemShareModel) Create(ItemShare *ItemShare) (int64, error) { return id, err } +func (model *ItemShareModel) Update(ItemShare *ItemShare) error { + ctx, cancel := database.GetContext() + defer cancel() + + query := `UPDATE bm_item_shares SET token=:token, permission_edit=:permission_edit, start_datetime=:start_datetime, end_datetime=:end_datetime WHERE id = :id` + _, err := model.DB.NamedExecContext(ctx, query, ItemShare) + + if err != nil { + return err + } + + return err +} + func (model *ItemShareModel) Delete(id int) (bool, error) { ctx, cancel := database.GetContext() defer cancel()