package app
import (
"fmt"
"html/template"
"net/http"
"strconv"
)
func getDocumentURL(documentID int64) string {
return fmt.Sprintf("/d/%s", encodeIDToBase36(documentID))
}
func getDocumentEditURL(documentID int64) string {
if documentID == 0 {
return "/d/new"
}
return fmt.Sprintf("/d/%s/edit", encodeIDToBase36(documentID))
}
func getDocumentDeleteURL(documentID int64) string {
return fmt.Sprintf("/d/%s/delete", encodeIDToBase36(documentID))
}
func formSubmitSaveDocument(w http.ResponseWriter, r *http.Request, form *Form) error {
documentID := int64(0)
field := form.GetFieldByName("id")
if field != nil {
documentID, _ = strconv.ParseInt(field.GetStringValue(), 10, 64)
}
document := DocumentRecord{}
if documentID > 0 {
var err error
document, err = fetchDocumentRecordByID(db, documentID)
if err != nil {
return err
}
}
document.CreatedBy = getUserID(r)
field = form.GetFieldByName("title")
if field != nil {
document.Title = field.GetStringValue()
}
field = form.GetFieldByName("content")
if field != nil {
document.Content = field.GetStringValue()
}
if err := updateDocumentsRecord(db, &document); err != nil {
return err
}
http.Redirect(w, r, getDocumentURL(document.ID), http.StatusFound)
return nil
}
func httpHandleEditDocument(w http.ResponseWriter, r *http.Request, documentID int64) {
// fetch existing document record
document := DocumentRecord{}
if documentID > 0 {
var err error
document, err = fetchDocumentRecordByID(db, documentID)
if err != nil {
httpHandleError(w, err)
return
}
}
// no permission to edit
if documentID > 0 && document.CreatedBy != getUserID(r) {
httpHandleError(w, errAuthError)
return
}
// render form
form := Form{
Name: "document",
Title: "Document Editor",
Fields: []*FormField{
{ID: "id", Type: "hidden", Values: []string{fmt.Sprintf("%d", documentID)}},
{ID: "title", Type: "text", Label: "Title", Required: true, Values: []string{document.Title}},
{ID: "content", Type: "textarea", Label: "Content", Description: "Supports Markdown and strategy board codes.", Required: true, Values: []string{document.Content}},
},
SubmitHandlers: []string{"save_document"},
}
if _, err := form.Submit(w, r); err != nil {
httpHandleError(w, err)
return
}
form.Render(w, r)
}
func httpHandleViewDocument(w http.ResponseWriter, r *http.Request, documentID int64) {
// fetch existing document record
document, err := fetchDocumentRecordByID(db, documentID)
if err != nil {
httpHandleError(w, err)
return
}
// inject strategy boards in to document markdown
userID := getUserID(r)
markdown, err := markdownInjectStrategyBoard([]byte(document.Content), userID)
if err != nil {
httpHandleError(w, err)
return
}
// render
recordDetails, err := fetchRecordDetails(DocumentRecord{}, documentID)
if err != nil {
httpHandleError(w, err)
return
}
recordOptions := [][]string{}
if document.CreatedBy == userID {
recordOptions = [][]string{{"Edit", getDocumentEditURL(documentID)}, {"Delete", getDocumentDeleteURL(documentID)}}
}
content := markdownToHTML(markdown)
httpHandleTemplate(w, "document.html", map[string]any{
"title": document.Title,
"content": template.HTML(content),
"canEdit": document.CreatedBy == userID,
"editURL": getDocumentEditURL(document.ID),
"recordDetails": recordDetails,
"recordOptions": recordOptions,
})
}
/* Handle document path. */
func httpBaseHandleDocument(w http.ResponseWriter, r *http.Request, path []string) bool {
if path[0] == "d" || path[0] == "doc" {
if len(path) < 2 {
httpHandleError(w, errHttpNotFound)
return true
}
if path[1] == "new" {
httpHandleEditDocument(w, r, 0)
return true
}
documentID := getIDFromBase36(path[1])
if documentID == 0 {
httpHandleError(w, errHttpNotFound)
return true
}
if len(path) > 2 && path[2] == "edit" {
httpHandleEditDocument(w, r, documentID)
return true
}
if len(path) > 2 && path[2] == "delete" {
httpHandleRecordDelete(w, r, DocumentRecord{}, documentID)
return true
}
httpHandleViewDocument(w, r, documentID)
return true
}
return false
}