1
1
mirror of https://github.com/go-gitea/gitea synced 2024-12-22 16:44:26 +00:00

new webhooks list UI

This commit is contained in:
Unknwon 2015-08-26 21:45:51 +08:00
parent 1cb03135b7
commit 2881456421
28 changed files with 329 additions and 180 deletions

View File

@ -303,6 +303,7 @@ func runWeb(ctx *cli.Context) {
adminReq := middleware.Toggle(&middleware.ToggleOptions{SignInRequire: true, AdminRequire: true})
// ***** START: Admin *****
m.Group("/admin", func() {
m.Get("", adminReq, admin.Dashboard)
m.Get("/config", admin.Config)
@ -339,6 +340,7 @@ func runWeb(ctx *cli.Context) {
m.Get("/:id:int/delete", admin.DeleteNotice)
})
}, adminReq)
// ***** END: Admin *****
m.Group("", func() {
m.Get("/:username", user.Profile)
@ -377,7 +379,7 @@ func runWeb(ctx *cli.Context) {
reqRepoAdmin := middleware.RequireRepoAdmin()
// Organization.
// ***** START: Organization *****
m.Group("/org", func() {
m.Get("/create", org.Create)
m.Post("/create", bindIgnErr(auth.CreateOrgForm{}), org.CreatePost)
@ -403,9 +405,14 @@ func runWeb(ctx *cli.Context) {
m.Post("/teams/:team/delete", org.DeleteTeam)
m.Group("/settings", func() {
m.Get("", org.Settings)
m.Post("", bindIgnErr(auth.UpdateOrgSettingForm{}), org.SettingsPost)
m.Get("/hooks", org.SettingsHooks)
m.Combo("").Get(org.Settings).
Post(bindIgnErr(auth.UpdateOrgSettingForm{}), org.SettingsPost)
m.Group("/hooks", func() {
m.Get("", org.Webhooks)
m.Post("/delete", org.DeleteWebhook)
})
m.Get("/hooks/new", repo.WebHooksNew)
m.Post("/hooks/gogs/new", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksNewPost)
m.Post("/hooks/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost)
@ -421,8 +428,9 @@ func runWeb(ctx *cli.Context) {
m.Group("/org", func() {
m.Get("/:org", org.Home)
}, ignSignIn, middleware.OrgAssignment(true))
// ***** END: Organization *****
// Repository.
// ***** START: Repository *****
m.Group("/repo", func() {
m.Get("/create", repo.Create)
m.Post("/create", bindIgnErr(auth.CreateRepoForm{}), repo.CreatePost)
@ -433,11 +441,15 @@ func runWeb(ctx *cli.Context) {
}, reqSignIn)
m.Group("/:username/:reponame", func() {
m.Get("/settings", repo.Settings)
m.Post("/settings", bindIgnErr(auth.RepoSettingForm{}), repo.SettingsPost)
m.Group("/settings", func() {
m.Route("/collaboration", "GET,POST", repo.SettingsCollaboration)
m.Get("/hooks", repo.Webhooks)
m.Combo("").Get(repo.Settings).
Post(bindIgnErr(auth.RepoSettingForm{}), repo.SettingsPost)
m.Route("/collaboration", "GET,POST", repo.Collaboration)
m.Group("/hooks", func() {
m.Get("", repo.Webhooks)
m.Post("/delete", repo.DeleteWebhook)
})
m.Get("/hooks/new", repo.WebHooksNew)
m.Post("/hooks/gogs/new", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksNewPost)
m.Post("/hooks/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost)
@ -446,14 +458,14 @@ func runWeb(ctx *cli.Context) {
m.Post("/hooks/slack/:id", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost)
m.Group("/hooks/git", func() {
m.Get("", repo.SettingsGitHooks)
m.Combo("/:name").Get(repo.SettingsGitHooksEdit).
Post(repo.SettingsGitHooksEditPost)
m.Get("", repo.GitHooks)
m.Combo("/:name").Get(repo.GitHooksEdit).
Post(repo.GitHooksEditPost)
}, middleware.GitHookService())
m.Group("/keys", func() {
m.Combo("").Get(repo.SettingsDeployKeys).
Post(bindIgnErr(auth.AddSSHKeyForm{}), repo.SettingsDeployKeysPost)
m.Combo("").Get(repo.DeployKeys).
Post(bindIgnErr(auth.AddSSHKeyForm{}), repo.DeployKeysPost)
m.Post("/delete", repo.DeleteDeployKey)
})
@ -536,6 +548,7 @@ func runWeb(ctx *cli.Context) {
m.Head("/hooks/trigger", repo.TriggerHook)
})
})
// ***** END: Repository *****
// robots.txt
m.Get("/robots.txt", func(ctx *middleware.Context) {

View File

@ -510,12 +510,14 @@ settings.remove_collaborator_success = Collaborator has been removed.
settings.user_is_org_member = User is organization member who cannot be added as a collaborator.
settings.add_webhook = Add Webhook
settings.hooks_desc = Webhooks are much like basic HTTP POST event triggers. Whenever something occurs in Gogs, we will handle the notification to the target host you specify. Learn more in this <a target="_blank" href="%s">Webhooks Guide</a>.
settings.webhook_deletion = Delete Webhook
settings.webhook_deletion_desc = Delete this webhook will remove its information and all delivery history. Do you want to continue?
settings.webhook_deletion_success = Webhook has been deleted successfully!
settings.githooks_desc = Git Hooks are powered by Git itself, you can edit files of supported hooks in the list below to perform custom operations.
settings.githook_edit_desc = If the hook is inactive, sample content will be presented. Leaving content to an empty value will disable this hook.
settings.githook_name = Hook Name
settings.githook_content = Hook Content
settings.update_githook = Update Hook
settings.remove_hook_success = Webhook has been removed.
settings.add_webhook_desc = Gogs will send a <code>POST</code> request to the URL you specify, along with regarding the event that occured. You can also specify what kind of data format you'd like to get upon triggering the hook (JSON, x-www-form-urlencoded, XML, etc). More information can be found in our <a target="_blank" href="%s">Webhooks Guide</a>.
settings.payload_url = Payload URL
settings.content_type = Content Type

View File

@ -395,6 +395,26 @@
"strictMath": 0,
"strictUnits": 0
},
"\/public\/less\/_organization.less": {
"allowInsecureImports": 0,
"createSourceMap": 0,
"disableJavascript": 0,
"fileType": 1,
"ieCompatibility": 1,
"ignore": 1,
"ignoreWasSetByUser": 0,
"inputAbbreviatedPath": "\/public\/less\/_organization.less",
"outputAbbreviatedPath": "\/public\/css\/_organization.css",
"outputPathIsOutsideProject": 0,
"outputPathIsSetByUser": 0,
"outputStyle": 0,
"relativeURLS": 0,
"shouldRunAutoprefixer": 0,
"shouldRunBless": 0,
"strictImports": 0,
"strictMath": 0,
"strictUnits": 0
},
"\/public\/less\/_repository.less": {
"allowInsecureImports": 0,
"createSourceMap": 0,

View File

@ -445,13 +445,13 @@ func CommitRepoAction(userID, repoUserID int64, userName, actEmail string,
if err = CreateHookTask(&HookTask{
RepoID: repo.ID,
HookID: w.Id,
HookID: w.ID,
Type: w.HookTaskType,
Url: w.Url,
Url: w.URL,
BasePayload: payload,
ContentType: w.ContentType,
EventType: HOOK_EVENT_PUSH,
IsSsl: w.IsSsl,
IsSsl: w.IsSSL,
}); err != nil {
return fmt.Errorf("CreateHookTask: %v", err)
}

View File

@ -111,8 +111,11 @@ func (u *User) DashboardLink() string {
return setting.AppSubUrl + "/"
}
// HomeLink returns the user home page link.
// HomeLink returns the user or organization home page link.
func (u *User) HomeLink() string {
if u.IsOrganization() {
return setting.AppSubUrl + "/org/" + u.Name
}
return setting.AppSubUrl + "/" + u.Name
}
@ -162,6 +165,15 @@ func (u *User) AvatarLink() string {
return setting.GravatarSource + u.Avatar
}
// DisplayName returns full name if it's not empty,
// returns username otherwise.
func (u *User) DisplayName() string {
if len(u.FullName) > 0 {
return u.FullName
}
return u.Name
}
// NewGitSig generates and returns the signature of given user.
func (u *User) NewGitSig() *git.Signature {
return &git.Signature{

View File

@ -60,36 +60,45 @@ type HookEvent struct {
PushOnly bool `json:"push_only"`
}
type HookStatus int
const (
HOOK_STATUS_NONE = iota
HOOK_STATUS_SUCCEED
HOOK_STATUS_FAILED
)
// Webhook represents a web hook object.
type Webhook struct {
Id int64
RepoId int64
Url string `xorm:"TEXT"`
ID int64 `xorm:"pk autoincr"`
RepoID int64
OrgID int64
URL string `xorm:"url TEXT"`
ContentType HookContentType
Secret string `xorm:"TEXT"`
Events string `xorm:"TEXT"`
*HookEvent `xorm:"-"`
IsSsl bool
IsSSL bool `xorm:"is_ssl"`
IsActive bool
HookTaskType HookTaskType
Meta string `xorm:"TEXT"` // store hook-specific attributes
OrgId int64
Created time.Time `xorm:"CREATED"`
Updated time.Time `xorm:"UPDATED"`
Meta string `xorm:"TEXT"` // store hook-specific attributes
LastStatus HookStatus // Last delivery status
Created time.Time `xorm:"CREATED"`
Updated time.Time `xorm:"UPDATED"`
}
// GetEvent handles conversion from Events to HookEvent.
func (w *Webhook) GetEvent() {
w.HookEvent = &HookEvent{}
if err := json.Unmarshal([]byte(w.Events), w.HookEvent); err != nil {
log.Error(4, "webhook.GetEvent(%d): %v", w.Id, err)
log.Error(4, "webhook.GetEvent(%d): %v", w.ID, err)
}
}
func (w *Webhook) GetSlackHook() *Slack {
s := &Slack{}
if err := json.Unmarshal([]byte(w.Meta), s); err != nil {
log.Error(4, "webhook.GetSlackHook(%d): %v", w.Id, err)
log.Error(4, "webhook.GetSlackHook(%d): %v", w.ID, err)
}
return s
}
@ -117,7 +126,7 @@ func CreateWebhook(w *Webhook) error {
// GetWebhookById returns webhook by given ID.
func GetWebhookById(hookId int64) (*Webhook, error) {
w := &Webhook{Id: hookId}
w := &Webhook{ID: hookId}
has, err := x.Get(w)
if err != nil {
return nil, err
@ -134,26 +143,37 @@ func GetActiveWebhooksByRepoId(repoId int64) (ws []*Webhook, err error) {
}
// GetWebhooksByRepoId returns all webhooks of repository.
func GetWebhooksByRepoId(repoId int64) (ws []*Webhook, err error) {
err = x.Find(&ws, &Webhook{RepoId: repoId})
func GetWebhooksByRepoId(repoID int64) (ws []*Webhook, err error) {
err = x.Find(&ws, &Webhook{RepoID: repoID})
return ws, err
}
// UpdateWebhook updates information of webhook.
func UpdateWebhook(w *Webhook) error {
_, err := x.Id(w.Id).AllCols().Update(w)
_, err := x.Id(w.ID).AllCols().Update(w)
return err
}
// DeleteWebhook deletes webhook of repository.
func DeleteWebhook(hookId int64) error {
_, err := x.Delete(&Webhook{Id: hookId})
return err
func DeleteWebhook(id int64) (err error) {
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err
}
if _, err = sess.Delete(&Webhook{ID: id}); err != nil {
return err
} else if _, err = sess.Delete(&HookTask{HookID: id}); err != nil {
return err
}
return sess.Commit()
}
// GetWebhooksByOrgId returns all webhooks for an organization.
func GetWebhooksByOrgId(orgId int64) (ws []*Webhook, err error) {
err = x.Find(&ws, &Webhook{OrgId: orgId})
func GetWebhooksByOrgId(orgID int64) (ws []*Webhook, err error) {
err = x.Find(&ws, &Webhook{OrgID: orgID})
return ws, err
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -73,9 +73,21 @@ img {
.text {
&.red {
color: #d95c5c!important;
a {
color: #d95c5c!important;
&:hover {
color: #E67777!important;
}
}
}
&.blue {
color: #428bca!important;
a {
color: #15c!important;
&:hover {
color: #428bca!important;
}
}
}
&.grey {
color: #767676!important;
@ -105,6 +117,10 @@ img {
white-space: nowrap;
display: inline-block;
}
&.thin {
font-weight: normal;
}
}
.message {

View File

@ -59,7 +59,7 @@
}
}
}
.repository.edit.hook {
.repository.edit.githook {
form {
@input-padding: 25%!important;
.inline.field > label {
@ -73,7 +73,7 @@
}
}
}
.repository.edit.hook {
.repository.edit.githook {
form {
textarea {
width: 70%!important;

View File

@ -0,0 +1,17 @@
.organization {
padding-top: 15px;
padding-bottom: @footer-margin * 2;
.head {
.ui.header {
.text {
vertical-align: middle;
font-size: 1.6rem;
margin-left: 15px;
}
.ui.right {
margin-top: 5px;
}
}
}
}

View File

@ -629,8 +629,9 @@
}
.item {
padding: 10px 20px;
i {
margin-right: 5px;
.octicon,
.fa {
width: 20px;
}
}
}

View File

@ -5,6 +5,7 @@
@import "_install";
@import "_form";
@import "_repository";
@import "_organization";
@import "_user";
@import "_dashboard";
@import "_admin";

View File

@ -26,7 +26,7 @@ func ListRepoHooks(ctx *middleware.Context) {
apiHooks := make([]*api.Hook, len(hooks))
for i := range hooks {
h := &api.Hook{
Id: hooks[i].Id,
ID: hooks[i].ID,
Type: hooks[i].HookTaskType.Name(),
Active: hooks[i].IsActive,
Config: make(map[string]string),
@ -35,7 +35,7 @@ func ListRepoHooks(ctx *middleware.Context) {
// Currently, onle have push event.
h.Events = []string{"push"}
h.Config["url"] = hooks[i].Url
h.Config["url"] = hooks[i].URL
h.Config["content_type"] = hooks[i].ContentType.Name()
if hooks[i].HookTaskType == models.SLACK {
s := hooks[i].GetSlackHook()
@ -67,8 +67,8 @@ func CreateRepoHook(ctx *middleware.Context, form api.CreateHookOption) {
}
w := &models.Webhook{
RepoId: ctx.Repo.Repository.ID,
Url: form.Config["url"],
RepoID: ctx.Repo.Repository.ID,
URL: form.Config["url"],
ContentType: models.ToHookContentType(form.Config["content_type"]),
Secret: form.Config["secret"],
HookEvent: &models.HookEvent{
@ -102,12 +102,12 @@ func CreateRepoHook(ctx *middleware.Context, form api.CreateHookOption) {
}
apiHook := &api.Hook{
Id: w.Id,
ID: w.ID,
Type: w.HookTaskType.Name(),
Events: []string{"push"},
Active: w.IsActive,
Config: map[string]string{
"url": w.Url,
"url": w.URL,
"content_type": w.ContentType.Name(),
},
}
@ -129,7 +129,7 @@ func EditRepoHook(ctx *middleware.Context, form api.EditHookOption) {
if form.Config != nil {
if url, ok := form.Config["url"]; ok {
w.Url = url
w.URL = url
}
if ct, ok := form.Config["content_type"]; ok {
if !models.IsValidHookContentType(ct) {

View File

@ -105,9 +105,11 @@ func SettingsDelete(ctx *middleware.Context) {
ctx.HTML(200, SETTINGS_DELETE)
}
func SettingsHooks(ctx *middleware.Context) {
func Webhooks(ctx *middleware.Context) {
ctx.Data["Title"] = ctx.Tr("org.settings")
ctx.Data["PageIsSettingsHooks"] = true
ctx.Data["BaseLink"] = ctx.Org.OrgLink
ctx.Data["Description"] = ctx.Tr("org.settings.hooks_desc")
// Delete web hook.
remove := com.StrTo(ctx.Query("remove")).MustInt64()
@ -130,3 +132,15 @@ func SettingsHooks(ctx *middleware.Context) {
ctx.Data["Webhooks"] = ws
ctx.HTML(200, SETTINGS_HOOKS)
}
func DeleteWebhook(ctx *middleware.Context) {
if err := models.DeleteWebhook(ctx.QueryInt64("id")); err != nil {
ctx.Flash.Error("DeleteWebhook: " + err.Error())
} else {
ctx.Flash.Success(ctx.Tr("repo.settings.webhook_deletion_success"))
}
ctx.JSON(200, map[string]interface{}{
"redirect": ctx.Org.OrgLink + "/settings/hooks",
})
}

View File

@ -173,7 +173,7 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) {
}
}
func SettingsCollaboration(ctx *middleware.Context) {
func Collaboration(ctx *middleware.Context) {
ctx.Data["Title"] = ctx.Tr("repo.settings")
ctx.Data["PageIsSettingsCollaboration"] = true
@ -249,26 +249,16 @@ func SettingsCollaboration(ctx *middleware.Context) {
func Webhooks(ctx *middleware.Context) {
ctx.Data["Title"] = ctx.Tr("repo.settings")
ctx.Data["PageIsSettingsHooks"] = true
// Delete web hook.
remove := com.StrTo(ctx.Query("remove")).MustInt64()
if remove > 0 {
if err := models.DeleteWebhook(remove); err != nil {
ctx.Handle(500, "DeleteWebhook", err)
return
}
ctx.Flash.Success(ctx.Tr("repo.settings.remove_hook_success"))
ctx.Redirect(ctx.Repo.RepoLink + "/settings/hooks")
return
}
ctx.Data["BaseLink"] = ctx.Repo.RepoLink
ctx.Data["Description"] = ctx.Tr("repo.settings.hooks_desc", "http://gogs.io/docs/features/webhook.html")
ws, err := models.GetWebhooksByRepoId(ctx.Repo.Repository.ID)
if err != nil {
ctx.Handle(500, "GetWebhooksByRepoId", err)
return
}
ctx.Data["Webhooks"] = ws
ctx.HTML(200, HOOKS)
}
@ -318,8 +308,8 @@ func WebHooksNewPost(ctx *middleware.Context, form auth.NewWebhookForm) {
}
w := &models.Webhook{
RepoId: orCtx.RepoId,
Url: form.PayloadUrl,
RepoID: orCtx.RepoId,
URL: form.PayloadUrl,
ContentType: ct,
Secret: form.Secret,
HookEvent: &models.HookEvent{
@ -328,7 +318,7 @@ func WebHooksNewPost(ctx *middleware.Context, form auth.NewWebhookForm) {
IsActive: form.Active,
HookTaskType: models.GOGS,
Meta: "",
OrgId: orCtx.OrgId,
OrgID: orCtx.OrgId,
}
if err := w.UpdateEvent(); err != nil {
@ -429,7 +419,7 @@ func WebHooksEditPost(ctx *middleware.Context, form auth.NewWebhookForm) {
ct = models.FORM
}
w.Url = form.PayloadUrl
w.URL = form.PayloadUrl
w.ContentType = ct
w.Secret = form.Secret
w.HookEvent = &models.HookEvent{
@ -474,8 +464,8 @@ func SlackHooksNewPost(ctx *middleware.Context, form auth.NewSlackHookForm) {
}
w := &models.Webhook{
RepoId: orCtx.RepoId,
Url: form.PayloadUrl,
RepoID: orCtx.RepoId,
URL: form.PayloadUrl,
ContentType: models.JSON,
Secret: "",
HookEvent: &models.HookEvent{
@ -484,7 +474,7 @@ func SlackHooksNewPost(ctx *middleware.Context, form auth.NewSlackHookForm) {
IsActive: form.Active,
HookTaskType: models.SLACK,
Meta: string(meta),
OrgId: orCtx.OrgId,
OrgID: orCtx.OrgId,
}
if err := w.UpdateEvent(); err != nil {
ctx.Handle(500, "UpdateEvent", err)
@ -539,7 +529,7 @@ func SlackHooksEditPost(ctx *middleware.Context, form auth.NewSlackHookForm) {
return
}
w.Url = form.PayloadUrl
w.URL = form.PayloadUrl
w.Meta = string(meta)
w.HookEvent = &models.HookEvent{
PushOnly: form.PushOnly,
@ -557,6 +547,18 @@ func SlackHooksEditPost(ctx *middleware.Context, form auth.NewSlackHookForm) {
ctx.Redirect(fmt.Sprintf("%s/settings/hooks/%d", orCtx.Link, hookId))
}
func DeleteWebhook(ctx *middleware.Context) {
if err := models.DeleteWebhook(ctx.QueryInt64("id")); err != nil {
ctx.Flash.Error("DeleteWebhook: " + err.Error())
} else {
ctx.Flash.Success(ctx.Tr("repo.settings.webhook_deletion_success"))
}
ctx.JSON(200, map[string]interface{}{
"redirect": ctx.Repo.RepoLink + "/settings/hooks",
})
}
type OrgRepoCtx struct {
OrgId int64
RepoId int64
@ -608,7 +610,7 @@ func TriggerHook(ctx *middleware.Context) {
models.HookQueue.AddRepoID(repo.ID)
}
func SettingsGitHooks(ctx *middleware.Context) {
func GitHooks(ctx *middleware.Context) {
ctx.Data["Title"] = ctx.Tr("repo.settings")
ctx.Data["PageIsSettingsGitHooks"] = true
@ -622,7 +624,7 @@ func SettingsGitHooks(ctx *middleware.Context) {
ctx.HTML(200, GITHOOKS)
}
func SettingsGitHooksEdit(ctx *middleware.Context) {
func GitHooksEdit(ctx *middleware.Context) {
ctx.Data["Title"] = ctx.Tr("repo.settings")
ctx.Data["PageIsSettingsGitHooks"] = true
@ -640,7 +642,7 @@ func SettingsGitHooksEdit(ctx *middleware.Context) {
ctx.HTML(200, GITHOOK_EDIT)
}
func SettingsGitHooksEditPost(ctx *middleware.Context) {
func GitHooksEditPost(ctx *middleware.Context) {
name := ctx.Params(":name")
hook, err := ctx.Repo.GitRepo.GetHook(name)
if err != nil {
@ -659,7 +661,7 @@ func SettingsGitHooksEditPost(ctx *middleware.Context) {
ctx.Redirect(ctx.Repo.RepoLink + "/settings/hooks/git")
}
func SettingsDeployKeys(ctx *middleware.Context) {
func DeployKeys(ctx *middleware.Context) {
ctx.Data["Title"] = ctx.Tr("repo.settings")
ctx.Data["PageIsSettingsKeys"] = true
@ -673,7 +675,7 @@ func SettingsDeployKeys(ctx *middleware.Context) {
ctx.HTML(200, DEPLOY_KEYS)
}
func SettingsDeployKeysPost(ctx *middleware.Context, form auth.AddSSHKeyForm) {
func DeployKeysPost(ctx *middleware.Context, form auth.AddSSHKeyForm) {
ctx.Data["Title"] = ctx.Tr("repo.settings")
ctx.Data["PageIsSettingsKeys"] = true

26
templates/org/header.tmpl Normal file
View File

@ -0,0 +1,26 @@
{{with .Org}}
<div class="ui container">
<div class="ui vertically grid head">
<div class="column">
<div class="ui header">
<img class="ui image" src="{{.AvatarLink}}?s=100">
<span class="text thin grey"><a href="{{AppSubUrl}}/org/{{.Name}}">{{.DisplayName}}</a></span>
<div class="ui right">
<div class="ui menu">
<a class="{{if $.PageIsOrgTeams}}active{{end}} item" href="{{$.OrgLink}}/teams">
<i class="octicon octicon-jersey"></i>&nbsp;{{$.i18n.Tr "org.teams"}}
<div class="floating ui black label">{{.NumTeams}}</div>
</a>
<a class="{{if $.PageIsOrgMembers}}active{{end}} item" href="{{$.OrgLink}}/members">
<i class="octicon octicon-organization"></i>&nbsp;{{$.i18n.Tr "org.people"}}
<div class="floating ui black label">{{.NumMembers}}</div>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="ui divider"></div>
{{end}}

View File

@ -1,38 +1,11 @@
{{template "ng/base/head" .}}
{{template "ng/base/header" .}}
{{template "org/base/header" .}}
<div id="setting-wrapper" class="main-wrapper">
<div id="org-setting" class="container clear">
{{template "org/settings/nav" .}}
<div class="grid-4-5 left">
<div class="setting-content">
{{template "ng/base/alert" .}}
<div id="setting-content">
<div id="repo-hooks-panel" class="panel panel-radius">
<div class="panel-header">
<a class="btn btn-small btn-black btn-header btn-radius right" href="{{.OrgLink}}/settings/hooks/new">{{.i18n.Tr "repo.settings.add_webhook"}}</a>
<strong>{{.i18n.Tr "repo.settings.hooks"}}</strong>
</div>
<ul class="panel-body setting-list">
<li>{{.i18n.Tr "org.settings.hooks_desc" | Str2html}}</li>
{{range .Webhooks}}
<li>
{{if .IsActive}}
<span class="left text-success"><i class="octicon octicon-check"></i></span>
{{else}}
<span class="left text-grey"><i class="octicon octicon-primitive-dot"></i></span>
{{end}}
<a class="link" href="{{$.OrgLink}}/settings/hooks/{{.Id}}">{{.Url}}</a>
<a href="{{$.OrgLink}}/settings/hooks?remove={{.Id}}" class="text-red right"><i class="fa fa-times"></i></a>
<a href="{{$.OrgLink}}/settings/hooks/{{.Id}}" class="text-blue right"><i class="fa fa-pencil"></i></a>
</li>
{{end}}
</ul>
</div>
</div>
</div>
</div>
</div>
{{template "base/head" .}}
<div class="organization settings webhooks">
{{template "org/header" .}}
<div class="ui container">
<div class="ui grid">
{{template "org/settings/navbar" .}}
{{template "repo/settings/hook_list" .}}
</div>
</div>
</div>
{{template "ng/base/footer" .}}
{{template "base/footer" .}}

View File

@ -4,9 +4,9 @@
</div>
<div class="panel-body">
<ul class="menu menu-vertical switching-list grid-1-5 left">
<li {{if .PageIsSettingsOptions}}class="current"{{end}}><a href="{{AppSubUrl}}/org/{{.Org.Name}}/settings">{{.i18n.Tr "org.settings.options"}}</a></li>
<li {{if .PageIsSettingsHooks}}class="current"{{end}}><a href="{{AppSubUrl}}/org/{{.Org.Name}}/settings/hooks">{{.i18n.Tr "repo.settings.hooks"}}</a></li>
<li {{if .PageIsSettingsDelete}}class="current"{{end}}><a href="{{AppSubUrl}}/org/{{.Org.Name}}/settings/delete">{{.i18n.Tr "org.settings.delete"}}</a></li>
<li {{if .PageIsSettingsOptions}}class="current"{{end}}><a href="{{.Org.HomeLink}}/settings">{{.i18n.Tr "org.settings.options"}}</a></li>
<li {{if .PageIsSettingsHooks}}class="current"{{end}}><a href="{{.Org.HomeLink}}/settings/hooks">{{.i18n.Tr "repo.settings.hooks"}}</a></li>
<li {{if .PageIsSettingsDelete}}class="current"{{end}}><a href="{{.Org.HomeLink}}/settings/delete">{{.i18n.Tr "org.settings.delete"}}</a></li>
</ul>
</div>
</div>

View File

@ -0,0 +1,14 @@
<div class="four wide column">
<div class="ui vertical menu">
<div class="header item">{{.i18n.Tr "org.settings"}}</div>
<a class="{{if .PageIsSettingsOptions}}active{{end}} item" href="{{.Org.HomeLink}}/settings">
{{.i18n.Tr "org.settings.options"}}
</a>
<a class="{{if .PageIsSettingsHooks}}active{{end}} item" href="{{.Org.HomeLink}}/settings/hooks">
{{.i18n.Tr "repo.settings.hooks"}}
</a>
<a class="{{if .PageIsSettingsDelete}}active{{end}} item" href="{{.Org.HomeLink}}/settings/delete">
{{.i18n.Tr "org.settings.delete"}}
</a>
</div>
</div>

View File

@ -1,6 +1,6 @@
{{with .Repository}}
<div class="ui container"><!-- start container -->
<div id="repoheader" class="ui vertically padded grid head"><!-- start grid -->
<div class="ui vertically padded grid head"><!-- start grid -->
<div class="column"><!-- start column -->
<div class="ui black small compact menu floated right count labelled">
<a class="item{{if $.IsRepositoryOwner}} poping up{{end}}"{{if not $.IsRepositoryOwner}} href="{{AppSubUrl}}/repo/fork/{{.ID}}"{{else}} data-content="{{$.i18n.Tr "repo.fork_from_self"}}" data-position="top center" data-variation="tiny"{{end}}>
@ -27,19 +27,17 @@
</div>
<div class="ui header">
<div class="ui huge breadcrumb">
<i class="mega-octicon octicon-{{if .IsPrivate}}lock{{else if .IsMirror}}repo-clone{{else if .IsFork}}repo-forked{{else}}repo{{end}}"></i>
<a href="{{AppSubUrl}}/{{.Owner.Name}}">{{.Owner.Name}}</a>
<div class="divider"> / </div>
<a href="{{$.RepoLink}}">{{.Name}}</a>
{{if .IsMirror}}<div class="ui label">{{$.i18n.Tr "mirror"}}</div>{{end}}
{{if .IsFork}}<div class="fork-flag">{{$.i18n.Tr "repo.forked_from"}} <a href="{{.BaseRepo.RepoLink}}">{{SubStr .BaseRepo.RepoLink 1 -1}}</a></div>{{end}}
<div class="ui huge breadcrumb">
<i class="mega-octicon octicon-{{if .IsPrivate}}lock{{else if .IsMirror}}repo-clone{{else if .IsFork}}repo-forked{{else}}repo{{end}}"></i>
<a href="{{AppSubUrl}}/{{.Owner.Name}}">{{.Owner.Name}}</a>
<div class="divider"> / </div>
<a href="{{$.RepoLink}}">{{.Name}}</a>
{{if .IsMirror}}<div class="ui label">{{$.i18n.Tr "mirror"}}</div>{{end}}
{{if .IsFork}}<div class="fork-flag">{{$.i18n.Tr "repo.forked_from"}} <a href="{{.BaseRepo.RepoLink}}">{{SubStr .BaseRepo.RepoLink 1 -1}}</a></div>{{end}}
</div>
</div>
</div>
</div><!-- end column -->
</div><!-- end grid -->
</div><!-- end container -->
<div class="ui divider"></div>
{{end}}

View File

@ -1,5 +1,5 @@
{{template "base/head" .}}
<div class="repository settings edit hook">
<div class="repository settings edit githook">
{{template "repo/header" .}}
<div class="ui container">
<div class="ui grid">

View File

@ -1,5 +1,5 @@
{{template "base/head" .}}
<div class="repository settings hooks">
<div class="repository settings githooks">
{{template "repo/header" .}}
<div class="ui container">
<div class="ui grid">
@ -16,13 +16,9 @@
</div>
{{range .Hooks}}
<div class="item">
{{if .IsActive}}
<span class="text success"><i class="octicon octicon-check"></i></span>
{{else}}
<span class="text grey"><i class="octicon octicon-primitive-dot"></i></span>
{{end}}
<span class="text {{if .IsActive}}green{{else}}grey{{end}}"><i class="octicon octicon-primitive-dot"></i></span>
<span>{{.Name}}</span>
<a href="{{$.RepoLink}}/settings/hooks/git/{{.Name}}" class="text blue ui right"><i class="fa fa-pencil"></i></a>
<a class="text blue ui right" href="{{$.RepoLink}}/settings/hooks/git/{{.Name}}"><i class="fa fa-pencil"></i></a>
</div>
{{end}}
</div>

View File

@ -1,11 +1,11 @@
<div id="gogs" class="{{if (and .PageIsSettingsHooksEdit (not (eq .HookType "Gogs")))}}hidden{{end}}">
<form class="form form-align panel-body repo-setting-form" id="repo-setting-form-gogs" action="{{if .RepoLink}}{{.RepoLink}}{{else if .OrgLink}}{{.OrgLink}}{{end}}/settings/hooks/gogs/{{if .PageIsSettingsHooksNew}}new{{else}}{{.Webhook.Id}}{{end}}" method="post">
<form class="form form-align panel-body repo-setting-form" id="repo-setting-form-gogs" action="{{if .RepoLink}}{{.RepoLink}}{{else if .OrgLink}}{{.OrgLink}}{{end}}/settings/hooks/gogs/{{if .PageIsSettingsHooksNew}}new{{else}}{{.Webhook.ID}}{{end}}" method="post">
{{.CsrfTokenHtml}}
<input type="hidden" name="hook_type" value="gogs">
<div class="text-center panel-desc">{{.i18n.Tr "repo.settings.add_webhook_desc" "http://gogs.io/docs/features/webhook.html" | Str2html}}</div>
<div class="field">
<label class="req" for="payload-url">{{.i18n.Tr "repo.settings.payload_url"}}</label>
<input class="ipt ipt-large ipt-radius {{if .Err_UserName}}ipt-error{{end}}" id="payload-url" name="payload_url" type="url" value="{{.Webhook.Url}}" required />
<input class="ipt ipt-large ipt-radius {{if .Err_UserName}}ipt-error{{end}}" id="payload-url" name="payload_url" type="url" value="{{.Webhook.URL}}" required />
</div>
<div class="field">
<label class="req">{{.i18n.Tr "repo.settings.content_type"}}</label>

View File

@ -0,0 +1,52 @@
<div class="twelve wide column content">
{{template "base/alert" .}}
<h4 class="ui top attached header">
{{.i18n.Tr "repo.settings.hooks"}}
<div class="ui right">
<a class="ui blue tiny button" href="{{.BaseLink}}/settings/hooks/new">{{.i18n.Tr "repo.settings.add_webhook"}}</a>
</div>
</h4>
<div class="ui attached table segment">
<div class="ui hook list">
<div class="item">
{{.Description | Str2html}}
</div>
{{range .Webhooks}}
<div class="item">
{{if eq .LastStatus 1}}
<span class="text green"><i class="octicon octicon-check"></i></span>
{{else if eq .LastStatus 2}}
<span class="text red"><i class="octicon octicon-alert"></i></span>
{{else}}
<span class="text grey"><i class="octicon octicon-primitive-dot"></i></span>
{{end}}
<a href="{{$.BaseLink}}/settings/hooks/{{.ID}}">{{.URL}}</a>
<div class="ui right">
<span class="text blue"><a href="{{$.BaseLink}}/settings/hooks/{{.ID}}"><i class="fa fa-pencil"></i></a></span>
<span class="text red"><a class="delete-button" data-url="{{$.Link}}/delete" data-id="{{.ID}}"><i class="fa fa-times"></i></a></span>
</div>
</div>
{{end}}
</div>
</div>
</div>
<div class="ui small basic delete modal">
<div class="ui icon header">
<i class="trash icon"></i>
{{.i18n.Tr "repo.settings.webhook_deletion"}}
</div>
<div class="content">
<p>{{.i18n.Tr "repo.settings.webhook_deletion_desc"}}</p>
</div>
<div class="actions">
<div class="ui red basic inverted cancel button">
<i class="remove icon"></i>
{{.i18n.Tr "modal.no"}}
</div>
<div class="ui green basic inverted ok button">
<i class="checkmark icon"></i>
{{.i18n.Tr "modal.yes"}}
</div>
</div>
</div>

View File

@ -11,5 +11,5 @@
<div class="field">
<label></label>
<button class="btn btn-green btn-large btn-radius">{{if .PageIsSettingsHooksNew}}{{.i18n.Tr "repo.settings.add_webhook"}}{{else}}{{.i18n.Tr "repo.settings.update_webhook"}}{{end}}</button>
{{if .PageIsSettingsHooksEdit}}<a class="btn btn-red btn-large btn-link btn-radius" href="{{.RepoLink}}/settings/hooks?remove={{.Webhook.Id}}"><strong>{{.i18n.Tr "repo.settings.delete_webhook"}}</strong></a>{{end}}
{{if .PageIsSettingsHooksEdit}}<a class="btn btn-red btn-large btn-link btn-radius" href="{{.RepoLink}}/settings/hooks?remove={{.Webhook.ID}}"><strong>{{.i18n.Tr "repo.settings.delete_webhook"}}</strong></a>{{end}}
</div>

View File

@ -1,11 +1,11 @@
<div id="slack" class="{{if or .PageIsSettingsHooksNew (and .PageIsSettingsHooksEdit (not (eq .HookType "Slack")))}}hidden{{end}}">
<form class="form form-align panel-body repo-setting-form" id="repo-setting-form-slack" action="{{if .RepoLink}}{{.RepoLink}}{{else if .OrgLink}}{{.OrgLink}}{{end}}/settings/hooks/slack/{{if .PageIsSettingsHooksNew}}new{{else}}{{.Webhook.Id}}{{end}}" method="post">
<form class="form form-align panel-body repo-setting-form" id="repo-setting-form-slack" action="{{if .RepoLink}}{{.RepoLink}}{{else if .OrgLink}}{{.OrgLink}}{{end}}/settings/hooks/slack/{{if .PageIsSettingsHooksNew}}new{{else}}{{.Webhook.ID}}{{end}}" method="post">
{{.CsrfTokenHtml}}
<input type="hidden" name="hook_type" value="slack">
<div class="text-center panel-desc">{{.i18n.Tr "repo.settings.add_slack_hook_desc" "http://slack.com" | Str2html}}</div>
<div class="field">
<label class="req" for="payload-url">{{.i18n.Tr "repo.settings.payload_url"}}</label>
<input class="ipt ipt-large ipt-radius {{if .Err_UserName}}ipt-error{{end}}" id="payload-url" name="payload_url" type="url" value="{{.Webhook.Url}}" required />
<input class="ipt ipt-large ipt-radius {{if .Err_UserName}}ipt-error{{end}}" id="payload-url" name="payload_url" type="url" value="{{.Webhook.URL}}" required />
</div>
<div class="field">
<label class="req" for="channel">{{.i18n.Tr "repo.settings.slack_channel"}}</label>

View File

@ -1,39 +1,11 @@
{{template "ng/base/head" .}}
{{template "ng/base/header" .}}
<div id="repo-wrapper">
{{template "repo/header_old" .}}
<div id="setting-wrapper" class="main-wrapper">
<div id="repo-setting" class="container clear">
{{template "repo/settings/nav" .}}
<div class="grid-4-5 left">
<div class="setting-content">
{{template "ng/base/alert" .}}
<div id="setting-content">
<div id="repo-hooks-panel" class="panel panel-radius">
<div class="panel-header">
<a class="btn btn-small btn-black btn-header btn-radius right" href="{{.RepoLink}}/settings/hooks/new">{{.i18n.Tr "repo.settings.add_webhook"}}</a>
<strong>{{.i18n.Tr "repo.settings.hooks"}}</strong>
</div>
<ul class="panel-body setting-list">
<li>{{.i18n.Tr "repo.settings.hooks_desc" "http://gogs.io/docs/features/webhook.html" | Str2html}}</li>
{{range .Webhooks}}
<li>
{{if .IsActive}}
<span class="left text-success"><i class="octicon octicon-check"></i></span>
{{else}}
<span class="left text-grey"><i class="octicon octicon-primitive-dot"></i></span>
{{end}}
<a class="link" href="{{$.RepoLink}}/settings/hooks/{{.Id}}">{{.Url}}</a>
<a href="{{$.RepoLink}}/settings/hooks?remove={{.Id}}" class="text-red right"><i class="fa fa-times"></i></a>
<a href="{{$.RepoLink}}/settings/hooks/{{.Id}}" class="text-blue right"><i class="fa fa-pencil"></i></a>
</li>
{{end}}
</ul>
</div>
</div>
</div>
</div>
</div>
{{template "base/head" .}}
<div class="repository settings webhooks">
{{template "repo/header" .}}
<div class="ui container">
<div class="ui grid">
{{template "repo/settings/navbar" .}}
{{template "repo/settings/hook_list" .}}
</div>
</div>
</div>
{{template "ng/base/footer" .}}
{{template "base/footer" .}}