re-structure settings + autoclose
This commit is contained in:
parent
fc2e1a65bd
commit
e07dbed6ca
20
app/http/endpoints/api/getautoclose.go
Normal file
20
app/http/endpoints/api/getautoclose.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TicketsBot/GoPanel/database"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetAutoClose(ctx *gin.Context) {
|
||||||
|
guildId := ctx.Keys["guildid"].(uint64)
|
||||||
|
|
||||||
|
settings, err := database.Client.AutoClose.Get(guildId); if err != nil {
|
||||||
|
ctx.AbortWithStatusJSON(500, gin.H{
|
||||||
|
"success": false,
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.JSON(200, settings)
|
||||||
|
}
|
48
app/http/endpoints/api/postautoclose.go
Normal file
48
app/http/endpoints/api/postautoclose.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
dbclient "github.com/TicketsBot/GoPanel/database"
|
||||||
|
"github.com/TicketsBot/database"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func PostAutoClose(ctx *gin.Context) {
|
||||||
|
guildId := ctx.Keys["guildid"].(uint64)
|
||||||
|
|
||||||
|
var settings database.AutoCloseSettings
|
||||||
|
if err := ctx.BindJSON(&settings); err != nil {
|
||||||
|
ctx.AbortWithStatusJSON(400, gin.H{
|
||||||
|
"success": false,
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if settings.Enabled && (settings.SinceLastMessage == nil || settings.SinceOpenWithNoResponse == nil) {
|
||||||
|
ctx.AbortWithStatusJSON(400, gin.H{
|
||||||
|
"success": false,
|
||||||
|
"error": "No time period provided",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.SinceOpenWithNoResponse != nil && *settings.SinceOpenWithNoResponse < 0) || (settings.SinceLastMessage != nil && *settings.SinceLastMessage < 0) {
|
||||||
|
ctx.AbortWithStatusJSON(400, gin.H{
|
||||||
|
"success": false,
|
||||||
|
"error": "Negative time period provided",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := dbclient.Client.AutoClose.Set(guildId, settings); err != nil {
|
||||||
|
ctx.AbortWithStatusJSON(500, gin.H{
|
||||||
|
"success": false,
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.JSON(200, gin.H{
|
||||||
|
"success": true,
|
||||||
|
})
|
||||||
|
}
|
@ -73,37 +73,40 @@ func StartServer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
apiGroup := router.Group("/api", middleware.AuthenticateToken)
|
apiGroup := router.Group("/api", middleware.AuthenticateToken)
|
||||||
guildAuthApi := apiGroup.Group("/", middleware.AuthenticateGuild(true))
|
guildAuthApi := apiGroup.Group("/:id", middleware.AuthenticateGuild(true))
|
||||||
{
|
{
|
||||||
guildAuthApi.GET("/:id/channels", api.ChannelsHandler)
|
guildAuthApi.GET("/channels", api.ChannelsHandler)
|
||||||
guildAuthApi.GET("/:id/premium", api.PremiumHandler)
|
guildAuthApi.GET("/premium", api.PremiumHandler)
|
||||||
guildAuthApi.GET("/:id/user/:user", api.UserHandler)
|
guildAuthApi.GET("/user/:user", api.UserHandler)
|
||||||
|
|
||||||
guildAuthApi.GET("/:id/settings", api.GetSettingsHandler)
|
guildAuthApi.GET("/settings", api.GetSettingsHandler)
|
||||||
guildAuthApi.POST("/:id/settings", api.UpdateSettingsHandler)
|
guildAuthApi.POST("/settings", api.UpdateSettingsHandler)
|
||||||
|
|
||||||
guildAuthApi.GET("/:id/blacklist", api.GetBlacklistHandler)
|
guildAuthApi.GET("/blacklist", api.GetBlacklistHandler)
|
||||||
guildAuthApi.PUT("/:id/blacklist", api.AddBlacklistHandler)
|
guildAuthApi.PUT("/blacklist", api.AddBlacklistHandler)
|
||||||
guildAuthApi.DELETE("/:id/blacklist/:user", api.RemoveBlacklistHandler)
|
guildAuthApi.DELETE("/blacklist/:user", api.RemoveBlacklistHandler)
|
||||||
|
|
||||||
guildAuthApi.GET("/:id/panels", api.ListPanels)
|
guildAuthApi.GET("/panels", api.ListPanels)
|
||||||
guildAuthApi.PUT("/:id/panels", api.CreatePanel)
|
guildAuthApi.PUT("/panels", api.CreatePanel)
|
||||||
guildAuthApi.DELETE("/:id/panels/:message", api.DeletePanel)
|
guildAuthApi.DELETE("/panels/:message", api.DeletePanel)
|
||||||
|
|
||||||
guildAuthApi.GET("/:id/logs/", api.GetLogs)
|
guildAuthApi.GET("/logs/", api.GetLogs)
|
||||||
guildAuthApi.GET("/:id/modmail/logs/", api.GetModmailLogs)
|
guildAuthApi.GET("/modmail/logs/", api.GetModmailLogs)
|
||||||
|
|
||||||
guildAuthApi.GET("/:id/tickets", api.GetTickets)
|
guildAuthApi.GET("/tickets", api.GetTickets)
|
||||||
guildAuthApi.GET("/:id/tickets/:ticketId", api.GetTicket)
|
guildAuthApi.GET("/tickets/:ticketId", api.GetTicket)
|
||||||
guildAuthApi.POST("/:id/tickets/:ticketId", api.SendMessage)
|
guildAuthApi.POST("/tickets/:ticketId", api.SendMessage)
|
||||||
guildAuthApi.DELETE("/:id/tickets/:ticketId", api.CloseTicket)
|
guildAuthApi.DELETE("/tickets/:ticketId", api.CloseTicket)
|
||||||
|
|
||||||
guildAuthApi.GET("/:id/tags", api.TagsListHandler)
|
guildAuthApi.GET("/tags", api.TagsListHandler)
|
||||||
guildAuthApi.PUT("/:id/tags", api.CreateTag)
|
guildAuthApi.PUT("/tags", api.CreateTag)
|
||||||
guildAuthApi.DELETE("/:id/tags/:tag", api.DeleteTag)
|
guildAuthApi.DELETE("/tags/:tag", api.DeleteTag)
|
||||||
|
|
||||||
guildAuthApi.GET("/:id/claimsettings", api.GetClaimSettings)
|
guildAuthApi.GET("/claimsettings", api.GetClaimSettings)
|
||||||
guildAuthApi.POST("/:id/claimsettings", api.PostClaimSettings)
|
guildAuthApi.POST("/claimsettings", api.PostClaimSettings)
|
||||||
|
|
||||||
|
guildAuthApi.GET("/autoclose", api.GetAutoClose)
|
||||||
|
guildAuthApi.POST("/autoclose", api.PostAutoClose)
|
||||||
}
|
}
|
||||||
|
|
||||||
userGroup := router.Group("/user", middleware.AuthenticateToken)
|
userGroup := router.Group("/user", middleware.AuthenticateToken)
|
||||||
|
2
go.mod
2
go.mod
@ -6,7 +6,7 @@ require (
|
|||||||
github.com/BurntSushi/toml v0.3.1
|
github.com/BurntSushi/toml v0.3.1
|
||||||
github.com/TicketsBot/archiverclient v0.0.0-20200425115930-0ca198cc8306
|
github.com/TicketsBot/archiverclient v0.0.0-20200425115930-0ca198cc8306
|
||||||
github.com/TicketsBot/common v0.0.0-20200529141045-7426ad13f1a4
|
github.com/TicketsBot/common v0.0.0-20200529141045-7426ad13f1a4
|
||||||
github.com/TicketsBot/database v0.0.0-20200530221201-9ed09caec466
|
github.com/TicketsBot/database v0.0.0-20200603195715-ce3003c9764c
|
||||||
github.com/apex/log v1.1.2
|
github.com/apex/log v1.1.2
|
||||||
github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff // indirect
|
github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff // indirect
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-8">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h4 class="card-title">Settings</h4>
|
<h4 class="card-title">Settings</h4>
|
||||||
@ -19,12 +19,23 @@
|
|||||||
|
|
||||||
<div class="col-md-1 px-1">
|
<div class="col-md-1 px-1">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Ticket Limit (1-10)</label>
|
<label>Ticket Limit</label>
|
||||||
<input name="ticketlimit" type="text" class="form-control" placeholder="5" id="ticket_limit">
|
<select class="custom-select mr-sm-2" id="ticket_limit" name="ticketlimit">
|
||||||
|
<option value="1">1</option>
|
||||||
|
<option value="2">2</option>
|
||||||
|
<option value="3">3</option>
|
||||||
|
<option value="4">4</option>
|
||||||
|
<option value="5">5</option>
|
||||||
|
<option value="6">6</option>
|
||||||
|
<option value="7">7</option>
|
||||||
|
<option value="8">8</option>
|
||||||
|
<option value="9">9</option>
|
||||||
|
<option value="10">10</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-2 px-1">
|
<div class="col-md-3 px-1">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Ping @everyone on ticket open</label>
|
<label>Ping @everyone on ticket open</label>
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
@ -110,11 +121,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Claim settings -->
|
<!-- Claim settings -->
|
||||||
<div class="row">
|
<div class="col-md-4">
|
||||||
<div class="col-md-12">
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h4 class="card-title">Claim Settings</h4>
|
<h4 class="card-title">Claim Settings</h4>
|
||||||
@ -122,7 +131,7 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form onsubmit="updateClaimSettings(); return false;">
|
<form onsubmit="updateClaimSettings(); return false;">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-2 pr-1">
|
<div class="col-md-6 pr-1">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Support Reps Can View Claimed Tickets</label>
|
<label>Support Reps Can View Claimed Tickets</label>
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
@ -130,7 +139,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-2 pr-1">
|
<div class="col-md-6 pr-1">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Support Reps Can Type In Claimed Tickets</label>
|
<label>Support Reps Can Type In Claimed Tickets</label>
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
@ -140,6 +149,96 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row" style="padding-top: 20px">
|
||||||
|
<div class="col-md-12 pr-1">
|
||||||
|
<div class="form-group">
|
||||||
|
<button class="btn btn-primary btn-fill" type="submit"><i class="fas fa-paper-plane"></i>
|
||||||
|
Submit
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div aria-live="polite" aria-atomic="true" style="position: relative;">
|
||||||
|
<div style="position: absolute; right: 10px" id="toast-container">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<!-- Autoclose settings -->
|
||||||
|
<div class="col-md-8">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h4 class="card-title">Auto-Close</h4>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<form onsubmit="updateAutoCloseSettings(); return false;">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-2 pr-1">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Enabled</label>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" name="enabled" value="on" id="autoclose_enabled" style="width:30px;height:30px;">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-5">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Time since open with no message</label>
|
||||||
|
<div class="row">
|
||||||
|
<div class="input-group col-md-4">
|
||||||
|
<input type="text" class="form-control" id="sinceopen_days">
|
||||||
|
<div class="input-group-append">
|
||||||
|
<div class="input-group-text">d</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group col-md-4">
|
||||||
|
<input type="text" class="form-control" id="sinceopen_hours">
|
||||||
|
<div class="input-group-append">
|
||||||
|
<div class="input-group-text">h</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group col-md-4">
|
||||||
|
<input type="text" class="form-control" id="sinceopen_minutes">
|
||||||
|
<div class="input-group-append">
|
||||||
|
<div class="input-group-text">m</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-5">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Time since last message</label>
|
||||||
|
<div class="row">
|
||||||
|
<div class="input-group col-md-4">
|
||||||
|
<input type="text" class="form-control" id="sincelast_days">
|
||||||
|
<div class="input-group-append">
|
||||||
|
<div class="input-group-text">d</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group col-md-4">
|
||||||
|
<input type="text" class="form-control" id="sincelast_hours">
|
||||||
|
<div class="input-group-append">
|
||||||
|
<div class="input-group-text">h</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group col-md-4">
|
||||||
|
<input type="text" class="form-control" id="sincelast_minutes">
|
||||||
|
<div class="input-group-append">
|
||||||
|
<div class="input-group-text">m</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row" style="padding-top: 20px">
|
<div class="row" style="padding-top: 20px">
|
||||||
<div class="col-md-2 pr-1">
|
<div class="col-md-2 pr-1">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@ -156,11 +255,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div aria-live="polite" aria-atomic="true" style="position: relative;">
|
|
||||||
<div style="position: absolute; right: 10px" id="toast-container">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
async function getSettings() {
|
async function getSettings() {
|
||||||
const res = await axios.get('/api/{{.guildId}}/settings');
|
const res = await axios.get('/api/{{.guildId}}/settings');
|
||||||
@ -207,9 +301,13 @@
|
|||||||
|
|
||||||
async function loadData() {
|
async function loadData() {
|
||||||
const settings = await getSettings();
|
const settings = await getSettings();
|
||||||
|
if (settings.ticket_limit < 1) {
|
||||||
|
settings.ticket_limit = 5;
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementById("prefix").value = settings.prefix;
|
document.getElementById("prefix").value = settings.prefix;
|
||||||
document.getElementById("welcome_message").value = settings.welcome_message;
|
document.getElementById("welcome_message").value = settings.welcome_message;
|
||||||
document.getElementById("ticket_limit").value = settings.ticket_limit;
|
document.getElementById("ticket_limit").selectedIndex = settings.ticket_limit - 1;
|
||||||
document.getElementById("ping_everyone").checked = settings.ping_everyone;
|
document.getElementById("ping_everyone").checked = settings.ping_everyone;
|
||||||
document.getElementById("users_can_close").checked = settings.users_can_close;
|
document.getElementById("users_can_close").checked = settings.users_can_close;
|
||||||
document.getElementById("close_confirmation").checked = settings.close_confirmation;
|
document.getElementById("close_confirmation").checked = settings.close_confirmation;
|
||||||
@ -267,12 +365,69 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const minuteNanos = 60 * 1000 * 1000 * 1000;
|
||||||
|
const hourNanos = 60 * minuteNanos;
|
||||||
|
const dayNanos = 24 * hourNanos;
|
||||||
|
|
||||||
|
function fromNanoSeconds(nanoseconds) {
|
||||||
|
const days = Math.floor(nanoseconds / dayNanos);
|
||||||
|
nanoseconds -= (days * dayNanos);
|
||||||
|
|
||||||
|
const hours = Math.floor(nanoseconds / hourNanos);
|
||||||
|
nanoseconds -= (hours * hourNanos);
|
||||||
|
|
||||||
|
const minutes = Math.floor(nanoseconds / minuteNanos);
|
||||||
|
|
||||||
|
return [days, hours, minutes];
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadAutoClaimSettings() {
|
||||||
|
const res = await axios.get('/api/{{.guildId}}/autoclose');
|
||||||
|
const settings = res.data;
|
||||||
|
|
||||||
|
document.getElementById('autoclose_enabled').checked = settings.enabled;
|
||||||
|
|
||||||
|
const sinceOpen = fromNanoSeconds(settings.since_open_with_no_response);
|
||||||
|
document.getElementById('sinceopen_days').value = sinceOpen[0];
|
||||||
|
document.getElementById('sinceopen_hours').value = sinceOpen[1];
|
||||||
|
document.getElementById('sinceopen_minutes').value = sinceOpen[2];
|
||||||
|
|
||||||
|
const sinceLast = fromNanoSeconds(settings.since_last_message);
|
||||||
|
document.getElementById('sincelast_days').value = sinceLast[0];
|
||||||
|
document.getElementById('sincelast_hours').value = sinceLast[1];
|
||||||
|
document.getElementById('sincelast_minutes').value = sinceLast[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
function toNanoSeconds(days, hours, minutes) {
|
||||||
|
return days * dayNanos + hours * hourNanos + minutes * minuteNanos;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updateAutoCloseSettings() {
|
||||||
|
const data = {
|
||||||
|
enabled: document.getElementById('autoclose_enabled').checked,
|
||||||
|
since_open_with_no_response: toNanoSeconds(document.getElementById('sinceopen_days').value, document.getElementById('sinceopen_hours').value, document.getElementById('sinceopen_minutes').value),
|
||||||
|
since_last_message: toNanoSeconds(document.getElementById('sincelast_days').value, document.getElementById('sincelast_hours').value, document.getElementById('sincelast_minutes').value),
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = await axios.post('/api/{{.guildId}}/autoclose', data);
|
||||||
|
if (res.status !== 200 || !res.data.success) {
|
||||||
|
showToast('Error', res.data.error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
showToast('Success', 'Auto close settings updated');
|
||||||
|
}
|
||||||
|
|
||||||
|
loadAutoClaimSettings();
|
||||||
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
async function updateSettings() {
|
async function updateSettings() {
|
||||||
const data = {
|
const data = {
|
||||||
'prefix': document.getElementById('prefix').value,
|
'prefix': document.getElementById('prefix').value,
|
||||||
'welcome_message': document.getElementById("welcome_message").value,
|
'welcome_message': document.getElementById("welcome_message").value,
|
||||||
'ticket_limit': parseInt(document.getElementById('ticket_limit').value),
|
'ticket_limit': parseInt(document.getElementById('ticket_limit').options[document.getElementById('ticket_limit').selectedIndex].value),
|
||||||
'ping_everyone': document.getElementById("ping_everyone").checked,
|
'ping_everyone': document.getElementById("ping_everyone").checked,
|
||||||
'users_can_close': document.getElementById("users_can_close").checked,
|
'users_can_close': document.getElementById("users_can_close").checked,
|
||||||
'close_confirmation': document.getElementById("close_confirmation").checked,
|
'close_confirmation': document.getElementById("close_confirmation").checked,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user