Tags
+ID | +Content | +Delete | +
---|
diff --git a/app/http/endpoints/api/tagcreate.go b/app/http/endpoints/api/tagcreate.go new file mode 100644 index 0000000..a716653 --- /dev/null +++ b/app/http/endpoints/api/tagcreate.go @@ -0,0 +1,59 @@ +package api + +import ( + "github.com/TicketsBot/GoPanel/database/table" + "github.com/gin-gonic/gin" +) + +type tag struct { + Id string `json:"id"` + Content string `json:"content"` +} + +func CreateTag(ctx *gin.Context) { + guildId := ctx.Keys["guildid"].(uint64) + var data tag + + if err := ctx.BindJSON(&data); err != nil { + ctx.AbortWithStatusJSON(400, gin.H{ + "success": false, + "error": err.Error(), + }) + return + } + + if !data.verifyIdLength() { + ctx.AbortWithStatusJSON(400, gin.H{ + "success": false, + "error": "Tag ID must be 1 - 16 characters in length", + }) + return + } + + if !data.verifyContentLength() { + ctx.AbortWithStatusJSON(400, gin.H{ + "success": false, + "error": "Tag content must be 1 - 2000 characters in length", + }) + return + } + + if err := table.AddTag(guildId, data.Id, data.Content); err != nil { + ctx.AbortWithStatusJSON(500, gin.H{ + "success": false, + "error": err.Error(), + }) + } else { + ctx.JSON(200, gin.H{ + "success": true, + }) + } +} + +func (t *tag) verifyIdLength() bool { + return len(t.Id) > 0 && len(t.Id) <= 16 +} + +func (t *tag) verifyContentLength() bool { + return len(t.Content) > 0 && len(t.Content) <= 2000 +} diff --git a/app/http/endpoints/api/tagdelete.go b/app/http/endpoints/api/tagdelete.go new file mode 100644 index 0000000..cb480a8 --- /dev/null +++ b/app/http/endpoints/api/tagdelete.go @@ -0,0 +1,30 @@ +package api + +import ( + "github.com/TicketsBot/GoPanel/database/table" + "github.com/gin-gonic/gin" +) + +func DeleteTag(ctx *gin.Context) { + guildId := ctx.Keys["guildid"].(uint64) + tagId := ctx.Param("tag") + + if tagId == "" || len(tagId) > 16 { + ctx.JSON(400, gin.H{ + "success": false, + "error": "Invalid tag", + }) + return + } + + if err := table.DeleteTag(guildId, tagId); err != nil { + ctx.JSON(500, gin.H{ + "success": false, + "error": err.Error(), + }) + } else { + ctx.JSON(200, gin.H{ + "success": true, + }) + } +} diff --git a/app/http/endpoints/api/tagslist.go b/app/http/endpoints/api/tagslist.go new file mode 100644 index 0000000..ea30876 --- /dev/null +++ b/app/http/endpoints/api/tagslist.go @@ -0,0 +1,23 @@ +package api + +import ( + "github.com/TicketsBot/GoPanel/database/table" + "github.com/gin-gonic/gin" +) + +func TagsListHandler(ctx *gin.Context) { + guildId := ctx.Keys["guildid"].(uint64) + + wrapped := make([]tag, 0) + + tags := make(chan []table.Tag) + go table.GetTags(guildId, tags) + for _, t := range <-tags { + wrapped = append(wrapped, tag{ + Id: t.Id, + Content: t.Content, + }) + } + + ctx.JSON(200, wrapped) +} diff --git a/app/http/endpoints/manage/tags.go b/app/http/endpoints/manage/tags.go new file mode 100644 index 0000000..d2a4f13 --- /dev/null +++ b/app/http/endpoints/manage/tags.go @@ -0,0 +1,19 @@ +package manage + +import ( + "github.com/TicketsBot/GoPanel/config" + "github.com/gin-gonic/contrib/sessions" + "github.com/gin-gonic/gin" +) + +func TagsHandler(ctx *gin.Context) { + store := sessions.Default(ctx) + guildId := ctx.Keys["guildid"].(uint64) + + ctx.HTML(200, "manage/tags", gin.H{ + "name": store.Get("name").(string), + "guildId": guildId, + "avatar": store.Get("avatar").(string), + "baseUrl": config.Conf.Server.BaseUrl, + }) +} diff --git a/app/http/server.go b/app/http/server.go index 6034190..6cce309 100644 --- a/app/http/server.go +++ b/app/http/server.go @@ -63,6 +63,7 @@ func StartServer() { authenticateGuild.GET("/manage/:id/logs/modmail", manage.ModmailLogsHandler) authenticateGuild.GET("/manage/:id/blacklist", manage.BlacklistHandler) authenticateGuild.GET("/manage/:id/panels", manage.PanelHandler) + authenticateGuild.GET("/manage/:id/tags", manage.TagsHandler) authenticateGuild.GET("/manage/:id/tickets", manage.TicketListHandler) authenticateGuild.GET("/manage/:id/tickets/view/:uuid", manage.TicketViewHandler) @@ -96,6 +97,10 @@ func StartServer() { guildAuthApi.GET("/:id/tickets/:uuid", api.GetTicket) guildAuthApi.POST("/:id/tickets/:uuid", api.SendMessage) guildAuthApi.DELETE("/:id/tickets/:uuid", api.CloseTicket) + + guildAuthApi.GET("/:id/tags", api.TagsListHandler) + guildAuthApi.PUT("/:id/tags", api.CreateTag) + guildAuthApi.DELETE("/:id/tags/:tag", api.DeleteTag) } userGroup := router.Group("/user", middleware.AuthenticateToken) @@ -120,6 +125,7 @@ func createRenderer() multitemplate.Renderer { r = addManageTemplate(r, "ticketlist") r = addManageTemplate(r, "ticketview") r = addManageTemplate(r, "panels") + r = addManageTemplate(r, "tags") return r } diff --git a/database/table/tags.go b/database/table/tags.go new file mode 100644 index 0000000..43ac2a3 --- /dev/null +++ b/database/table/tags.go @@ -0,0 +1,42 @@ +package table + +import ( + "github.com/TicketsBot/GoPanel/database" + uuid "github.com/satori/go.uuid" +) + +type Tag struct { + Uuid string `gorm:"column:UUID;type:varchar(36);unique;primary_key"` + Id string `gorm:"column:ID;type:varchar(16)"` + Guild uint64 `gorm:"column:GUILDID"` + Content string `gorm:"column:TEXT;type:TEXT"` +} + +func (Tag) TableName() string { + return "cannedresponses" +} + +func GetTag(guild uint64, id string, ch chan string) { + var node Tag + database.Database.Where(Tag{Id: id, Guild: guild}).Take(&node) + ch <- node.Content +} + +func GetTags(guild uint64, ch chan []Tag) { + var rows []Tag + database.Database.Where(Tag{Guild: guild}).Find(&rows) + ch <- rows +} + +func AddTag(guild uint64, id string, content string) error { + return database.Database.Create(&Tag{ + Uuid: uuid.NewV4().String(), + Id: id, + Guild: guild, + Content: content, + }).Error +} + +func DeleteTag(guild uint64, id string) error { + return database.Database.Where(Tag{Id: id, Guild: guild}).Delete(&Tag{}).Error +} diff --git a/go.mod b/go.mod index 1035b21..15833c9 100644 --- a/go.mod +++ b/go.mod @@ -22,6 +22,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/robfig/go-cache v0.0.0-20130306151617-9fc39e0dbf62 github.com/rxdn/gdl v0.0.0-20200421193445-f200b9f466d7 + github.com/satori/go.uuid v1.2.0 github.com/ulule/limiter/v3 v3.5.0 golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a ) diff --git a/public/static/css/style.css b/public/static/css/style.css index cd06d91..98cd0e5 100644 --- a/public/static/css/style.css +++ b/public/static/css/style.css @@ -111,3 +111,9 @@ body { #premium-ad { display: none; } + +.tag-content { + min-width: 300px; + max-width: 300px; + word-wrap: break-word; +} diff --git a/public/templates/includes/head.tmpl b/public/templates/includes/head.tmpl index edb190d..475f7f2 100644 --- a/public/templates/includes/head.tmpl +++ b/public/templates/includes/head.tmpl @@ -122,6 +122,7 @@ td.appendChild(document.createTextNode(content)); td.classList.add('white'); tr.appendChild(td); + return td } function appendButton(tr, content, onclick) { diff --git a/public/templates/includes/navbar.tmpl b/public/templates/includes/navbar.tmpl index 2adaf2b..7eea7c0 100644 --- a/public/templates/includes/navbar.tmpl +++ b/public/templates/includes/navbar.tmpl @@ -19,6 +19,9 @@