Added project links to project edit page

This commit is contained in:
Asaf Gartner 2021-12-26 12:03:25 +02:00
parent 80f0e3b176
commit eb32b04437
5 changed files with 112 additions and 34 deletions

View File

@ -137,6 +137,19 @@
<div class="c--dim f7">Plaintext only. No links or markdown.</div>
</div>
</div>
<div class="edit-form-row">
<div class="pt-input-ns">Project links:</div>
<div>
<textarea class="links" name="links" id="links" maxlength="2048" data-max-chars="2048">
{{- .ProjectSettings.LinksText -}}
</textarea>
<div class="c--dim f7">
<div>Relevant links to put on the project page.</div>
<div>Format: url [Title] (e.g. <code>http://example.com/ Example Site</code>)</div>
<div>(1 per line, 10 max)</div>
</div>
</div>
</div>
<div class="edit-form-row">
<div class="pt-input-ns">Full description:</div>
<div>

View File

@ -146,6 +146,7 @@ type ProjectSettings struct {
Blurb string
Description string
LinksText string
Owners []User
LightLogo string

View File

@ -0,0 +1,40 @@
package website
import (
"fmt"
"strings"
"git.handmade.network/hmn/hmn/src/models"
)
type ParsedLink struct {
Name string
Url string
}
func ParseLinks(text string) []ParsedLink {
lines := strings.Split(text, "\n")
res := make([]ParsedLink, 0, len(lines))
for _, line := range lines {
linkParts := strings.SplitN(line, " ", 2)
url := strings.TrimSpace(linkParts[0])
name := ""
if len(linkParts) > 1 {
name = strings.TrimSpace(linkParts[1])
}
if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
continue
}
res = append(res, ParsedLink{Name: name, Url: url})
}
return res
}
func LinksToText(links []interface{}) string {
linksText := ""
for _, l := range links {
link := l.(*models.Link)
linksText += fmt.Sprintf("%s %s\n", link.URL, link.Name)
}
return linksText
}

View File

@ -496,6 +496,24 @@ func ProjectEdit(c *RequestContext) ResponseData {
if err != nil {
return c.ErrorResponse(http.StatusInternalServerError, err)
}
c.Perf.StartBlock("SQL", "Fetching project links")
projectLinkResult, err := db.Query(c.Context(), c.Conn, models.Link{},
`
SELECT $columns
FROM
handmade_links as link
WHERE
link.project_id = $1
ORDER BY link.ordering ASC
`,
p.Project.ID,
)
if err != nil {
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch project links"))
}
c.Perf.EndBlock()
projectSettings := templates.ProjectToProjectSettings(
&p.Project,
p.Owners,
@ -504,6 +522,8 @@ func ProjectEdit(c *RequestContext) ResponseData {
c.Theme,
)
projectSettings.LinksText = LinksToText(projectLinkResult)
var res ResponseData
res.MustWriteTemplate("project_edit.html", ProjectEditData{
BaseData: getBaseDataAutocrumb(c, "Edit Project"),
@ -558,6 +578,7 @@ type ProjectPayload struct {
ProjectID int
Name string
Blurb string
Links []ParsedLink
Description string
ParsedDescription string
Lifecycle models.ProjectLifecycle
@ -600,6 +621,7 @@ func ParseProjectEditForm(c *RequestContext) ProjectEditFormResult {
res.RejectionReason = "Projects must have a short description"
return res
}
links := ParseLinks(c.Req.Form.Get("links"))
description := c.Req.Form.Get("description")
parsedDescription := parsing.ParseMarkdown(description, parsing.ForumRealMarkdown)
@ -650,6 +672,7 @@ func ParseProjectEditForm(c *RequestContext) ProjectEditFormResult {
res.Payload = ProjectPayload{
Name: projectName,
Blurb: shortDesc,
Links: links,
Description: description,
ParsedDescription: parsedDescription,
Lifecycle: lifecycle,
@ -714,28 +737,23 @@ func updateProject(ctx context.Context, tx pgx.Tx, user *models.User, payload *P
payload.OwnerUsernames = append(payload.OwnerUsernames, selfUsername)
}
var qb db.QueryBuilder
qb.Add(
_, err := tx.Exec(ctx,
`
UPDATE handmade_project SET
name = $?,
blurb = $?,
description = $?,
descparsed = $?,
lifecycle = $?
name = $2,
blurb = $3,
description = $4,
descparsed = $5,
lifecycle = $6
WHERE id = $1
`,
payload.ProjectID,
payload.Name,
payload.Blurb,
payload.Description,
payload.ParsedDescription,
payload.Lifecycle,
)
if user.IsStaff {
qb.Add(`, hidden = $?`, payload.Hidden)
}
qb.Add(`WHERE id = $?`, payload.ProjectID)
_, err := tx.Exec(ctx, qb.String(), qb.Args()...)
if err != nil {
return oops.New(err, "Failed to update project")
}
@ -748,7 +766,8 @@ func updateProject(ctx context.Context, tx pgx.Tx, user *models.User, payload *P
UPDATE handmade_project SET
slug = $2,
featured = $3,
personal = $4
personal = $4,
hidden = $5
WHERE
id = $1
`,
@ -756,6 +775,7 @@ func updateProject(ctx context.Context, tx pgx.Tx, user *models.User, payload *P
payload.Slug,
payload.Featured,
payload.Personal,
payload.Hidden,
)
if err != nil {
return oops.New(err, "Failed to update project with admin fields")
@ -835,6 +855,26 @@ func updateProject(ctx context.Context, tx pgx.Tx, user *models.User, payload *P
}
}
_, err = tx.Exec(ctx, `DELETE FROM handmade_links WHERE project_id = $1`, payload.ProjectID)
if err != nil {
return oops.New(err, "Failed to delete project links")
}
for i, link := range payload.Links {
_, err = tx.Exec(ctx,
`
INSERT INTO handmade_links (name, url, ordering, project_id)
VALUES ($1, $2, $3, $4)
`,
link.Name,
link.Url,
i,
payload.ProjectID,
)
if err != nil {
return oops.New(err, "Failed to insert new project link")
}
}
return nil
}

View File

@ -235,11 +235,7 @@ func UserSettings(c *RequestContext) ResponseData {
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch user links"))
}
linksText := ""
for _, ilink := range links {
link := ilink.(*models.Link)
linksText += fmt.Sprintf("%s %s\n", link.URL, link.Name)
}
linksText := LinksToText(links)
var tduser *templates.DiscordUser
var numUnsavedMessages int
@ -365,31 +361,19 @@ func UserSettingsSave(c *RequestContext) ResponseData {
// Process links
linksText := form.Get("links")
links := strings.Split(linksText, "\n")
links := ParseLinks(linksText)
_, err = tx.Exec(c.Context(), `DELETE FROM handmade_links WHERE user_id = $1`, c.CurrentUser.ID)
if err != nil {
c.Logger.Warn().Err(err).Msg("failed to delete old links")
} else {
for i, link := range links {
link = strings.TrimSpace(link)
linkParts := strings.SplitN(link, " ", 2)
url := strings.TrimSpace(linkParts[0])
name := ""
if len(linkParts) > 1 {
name = strings.TrimSpace(linkParts[1])
}
if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
continue
}
_, err := tx.Exec(c.Context(),
`
INSERT INTO handmade_links (name, url, ordering, user_id)
VALUES ($1, $2, $3, $4)
`,
name,
url,
link.Name,
link.Url,
i,
c.CurrentUser.ID,
)