Add a migrate service type switch page (#12697)
* Add a migrat service type switch page * Improve translations * remove images * Fix images * remove extra create repo button on dashboard * Follow reviewers' opinions * Fix frontend lint * Remove wrong submit file * Fix tests * Adjust the size of image * Apply suggestions from code review Co-authored-by: 赵智超 <1012112796@qq.com> * Remove username and password from migration of github/gitlab * Improve docs * Improve interface docs Co-authored-by: 赵智超 <1012112796@qq.com> Co-authored-by: techknowlogick <techknowlogick@gitea.io>mj-v1.14.3
parent
6483dbc8ec
commit
e153cf07c3
After Width: | Height: | Size: 584 B |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 396 B |
@ -0,0 +1,173 @@
|
|||||||
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package repo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models"
|
||||||
|
"code.gitea.io/gitea/modules/auth"
|
||||||
|
"code.gitea.io/gitea/modules/base"
|
||||||
|
"code.gitea.io/gitea/modules/context"
|
||||||
|
"code.gitea.io/gitea/modules/migrations"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
"code.gitea.io/gitea/modules/structs"
|
||||||
|
"code.gitea.io/gitea/modules/task"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
tplMigrate base.TplName = "repo/migrate/migrate"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Migrate render migration of repository page
|
||||||
|
func Migrate(ctx *context.Context) {
|
||||||
|
ctx.Data["Services"] = append([]structs.GitServiceType{structs.PlainGitService}, structs.SupportedFullGitService...)
|
||||||
|
serviceType := ctx.QueryInt("service_type")
|
||||||
|
if serviceType == 0 {
|
||||||
|
ctx.HTML(200, tplMigrate)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Data["Title"] = ctx.Tr("new_migrate")
|
||||||
|
ctx.Data["private"] = getRepoPrivate(ctx)
|
||||||
|
ctx.Data["IsForcedPrivate"] = setting.Repository.ForcePrivate
|
||||||
|
ctx.Data["DisableMirrors"] = setting.Repository.DisableMirrors
|
||||||
|
ctx.Data["mirror"] = ctx.Query("mirror") == "1"
|
||||||
|
ctx.Data["wiki"] = ctx.Query("wiki") == "1"
|
||||||
|
ctx.Data["milestones"] = ctx.Query("milestones") == "1"
|
||||||
|
ctx.Data["labels"] = ctx.Query("labels") == "1"
|
||||||
|
ctx.Data["issues"] = ctx.Query("issues") == "1"
|
||||||
|
ctx.Data["pull_requests"] = ctx.Query("pull_requests") == "1"
|
||||||
|
ctx.Data["releases"] = ctx.Query("releases") == "1"
|
||||||
|
ctx.Data["LFSActive"] = setting.LFS.StartServer
|
||||||
|
// Plain git should be first
|
||||||
|
ctx.Data["service"] = structs.GitServiceType(serviceType)
|
||||||
|
|
||||||
|
ctxUser := checkContextUser(ctx, ctx.QueryInt64("org"))
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Data["ContextUser"] = ctxUser
|
||||||
|
|
||||||
|
ctx.HTML(200, base.TplName("repo/migrate/"+structs.GitServiceType(serviceType).Name()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleMigrateError(ctx *context.Context, owner *models.User, err error, name string, tpl base.TplName, form *auth.MigrateRepoForm) {
|
||||||
|
switch {
|
||||||
|
case migrations.IsRateLimitError(err):
|
||||||
|
ctx.RenderWithErr(ctx.Tr("form.visit_rate_limit"), tpl, form)
|
||||||
|
case migrations.IsTwoFactorAuthError(err):
|
||||||
|
ctx.RenderWithErr(ctx.Tr("form.2fa_auth_required"), tpl, form)
|
||||||
|
case models.IsErrReachLimitOfRepo(err):
|
||||||
|
ctx.RenderWithErr(ctx.Tr("repo.form.reach_limit_of_creation", owner.MaxCreationLimit()), tpl, form)
|
||||||
|
case models.IsErrRepoAlreadyExist(err):
|
||||||
|
ctx.Data["Err_RepoName"] = true
|
||||||
|
ctx.RenderWithErr(ctx.Tr("form.repo_name_been_taken"), tpl, form)
|
||||||
|
case models.IsErrNameReserved(err):
|
||||||
|
ctx.Data["Err_RepoName"] = true
|
||||||
|
ctx.RenderWithErr(ctx.Tr("repo.form.name_reserved", err.(models.ErrNameReserved).Name), tpl, form)
|
||||||
|
case models.IsErrNamePatternNotAllowed(err):
|
||||||
|
ctx.Data["Err_RepoName"] = true
|
||||||
|
ctx.RenderWithErr(ctx.Tr("repo.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), tpl, form)
|
||||||
|
default:
|
||||||
|
remoteAddr, _ := form.ParseRemoteAddr(owner)
|
||||||
|
err = util.URLSanitizedError(err, remoteAddr)
|
||||||
|
if strings.Contains(err.Error(), "Authentication failed") ||
|
||||||
|
strings.Contains(err.Error(), "Bad credentials") ||
|
||||||
|
strings.Contains(err.Error(), "could not read Username") {
|
||||||
|
ctx.Data["Err_Auth"] = true
|
||||||
|
ctx.RenderWithErr(ctx.Tr("form.auth_failed", err.Error()), tpl, form)
|
||||||
|
} else if strings.Contains(err.Error(), "fatal:") {
|
||||||
|
ctx.Data["Err_CloneAddr"] = true
|
||||||
|
ctx.RenderWithErr(ctx.Tr("repo.migrate.failed", err.Error()), tpl, form)
|
||||||
|
} else {
|
||||||
|
ctx.ServerError(name, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MigratePost response for migrating from external git repository
|
||||||
|
func MigratePost(ctx *context.Context, form auth.MigrateRepoForm) {
|
||||||
|
ctx.Data["Title"] = ctx.Tr("new_migrate")
|
||||||
|
// Plain git should be first
|
||||||
|
ctx.Data["service"] = form.Service
|
||||||
|
ctx.Data["Services"] = append([]structs.GitServiceType{structs.PlainGitService}, structs.SupportedFullGitService...)
|
||||||
|
|
||||||
|
ctxUser := checkContextUser(ctx, form.UID)
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Data["ContextUser"] = ctxUser
|
||||||
|
|
||||||
|
if ctx.HasError() {
|
||||||
|
ctx.HTML(200, tplMigrate)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
remoteAddr, err := form.ParseRemoteAddr(ctx.User)
|
||||||
|
if err != nil {
|
||||||
|
if models.IsErrInvalidCloneAddr(err) {
|
||||||
|
ctx.Data["Err_CloneAddr"] = true
|
||||||
|
addrErr := err.(models.ErrInvalidCloneAddr)
|
||||||
|
switch {
|
||||||
|
case addrErr.IsURLError:
|
||||||
|
ctx.RenderWithErr(ctx.Tr("form.url_error"), tplMigrate, &form)
|
||||||
|
case addrErr.IsPermissionDenied:
|
||||||
|
ctx.RenderWithErr(ctx.Tr("repo.migrate.permission_denied"), tplMigrate, &form)
|
||||||
|
case addrErr.IsInvalidPath:
|
||||||
|
ctx.RenderWithErr(ctx.Tr("repo.migrate.invalid_local_path"), tplMigrate, &form)
|
||||||
|
default:
|
||||||
|
ctx.ServerError("Unknown error", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ctx.ServerError("ParseRemoteAddr", err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var opts = migrations.MigrateOptions{
|
||||||
|
OriginalURL: form.CloneAddr,
|
||||||
|
GitServiceType: structs.GitServiceType(form.Service),
|
||||||
|
CloneAddr: remoteAddr,
|
||||||
|
RepoName: form.RepoName,
|
||||||
|
Description: form.Description,
|
||||||
|
Private: form.Private || setting.Repository.ForcePrivate,
|
||||||
|
Mirror: form.Mirror && !setting.Repository.DisableMirrors,
|
||||||
|
AuthUsername: form.AuthUsername,
|
||||||
|
AuthPassword: form.AuthPassword,
|
||||||
|
AuthToken: form.AuthToken,
|
||||||
|
Wiki: form.Wiki,
|
||||||
|
Issues: form.Issues,
|
||||||
|
Milestones: form.Milestones,
|
||||||
|
Labels: form.Labels,
|
||||||
|
Comments: form.Issues || form.PullRequests,
|
||||||
|
PullRequests: form.PullRequests,
|
||||||
|
Releases: form.Releases,
|
||||||
|
}
|
||||||
|
if opts.Mirror {
|
||||||
|
opts.Issues = false
|
||||||
|
opts.Milestones = false
|
||||||
|
opts.Labels = false
|
||||||
|
opts.Comments = false
|
||||||
|
opts.PullRequests = false
|
||||||
|
opts.Releases = false
|
||||||
|
}
|
||||||
|
|
||||||
|
err = models.CheckCreateRepository(ctx.User, ctxUser, opts.RepoName)
|
||||||
|
if err != nil {
|
||||||
|
handleMigrateError(ctx, ctxUser, err, "MigratePost", tplMigrate, &form)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = task.MigrateRepository(ctx.User, ctxUser, opts)
|
||||||
|
if err == nil {
|
||||||
|
ctx.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + opts.RepoName)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMigrateError(ctx, ctxUser, err, "MigratePost", tplMigrate, &form)
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
{{template "base/head" .}}
|
||||||
|
<div class="repository new migrate">
|
||||||
|
<div class="ui middle very relaxed page grid">
|
||||||
|
<div class="column">
|
||||||
|
<form class="ui form" action="{{.Link}}" method="post">
|
||||||
|
{{.CsrfTokenHtml}}
|
||||||
|
<h3 class="ui top attached header">
|
||||||
|
{{.i18n.Tr "repo.migrate.migrate" .service.Title}}
|
||||||
|
<input id="service_type" type="hidden" name="service" value="{{.service}}">
|
||||||
|
</h3>
|
||||||
|
<div class="ui attached segment">
|
||||||
|
{{template "base/alert" .}}
|
||||||
|
<div class="inline required field {{if .Err_CloneAddr}}error{{end}}">
|
||||||
|
<label for="clone_addr">{{.i18n.Tr "repo.migrate.clone_address"}}</label>
|
||||||
|
<input id="clone_addr" name="clone_addr" value="{{.clone_addr}}" autofocus required>
|
||||||
|
<span class="help">
|
||||||
|
{{.i18n.Tr "repo.migrate.clone_address_desc"}}{{if .ContextUser.CanImportLocal}} {{.i18n.Tr "repo.migrate.clone_local_path"}}{{end}}
|
||||||
|
{{if .LFSActive}}<br/>{{.i18n.Tr "repo.migrate.lfs_mirror_unsupported"}}{{end}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="inline field {{if .Err_Auth}}error{{end}}">
|
||||||
|
<label for="auth_username">{{.i18n.Tr "username"}}</label>
|
||||||
|
<input id="auth_username" name="auth_username" value="{{.auth_username}}" {{if not .auth_username}}data-need-clear="true"{{end}}>
|
||||||
|
</div>
|
||||||
|
<input class="fake" type="password">
|
||||||
|
<div class="inline field {{if .Err_Auth}}error{{end}}">
|
||||||
|
<label for="auth_password">{{.i18n.Tr "password"}}</label>
|
||||||
|
<input id="auth_password" name="auth_password" type="password" value="{{.auth_password}}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="inline field">
|
||||||
|
<label>{{.i18n.Tr "repo.migrate_options"}}</label>
|
||||||
|
<div class="ui checkbox">
|
||||||
|
{{if .DisableMirrors}}
|
||||||
|
<input id="mirror" name="mirror" type="checkbox" readonly>
|
||||||
|
<label>{{.i18n.Tr "repo.migrate_options_mirror_disabled"}}</label>
|
||||||
|
{{else}}
|
||||||
|
<input id="mirror" name="mirror" type="checkbox" {{if .mirror}}checked{{end}}>
|
||||||
|
<label>{{.i18n.Tr "repo.migrate_options_mirror_helper" | Safe}}</label>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui divider"></div>
|
||||||
|
|
||||||
|
<div class="inline required field {{if .Err_Owner}}error{{end}}">
|
||||||
|
<label>{{.i18n.Tr "repo.owner"}}</label>
|
||||||
|
<div class="ui selection owner dropdown">
|
||||||
|
<input type="hidden" id="uid" name="uid" value="{{.ContextUser.ID}}" required>
|
||||||
|
<span class="text" title="{{.ContextUser.Name}}">
|
||||||
|
<img class="ui mini image" src="{{.ContextUser.RelAvatarLink}}">
|
||||||
|
{{.ContextUser.ShortName 20}}
|
||||||
|
</span>
|
||||||
|
<i class="dropdown icon"></i>
|
||||||
|
<div class="menu" title="{{.SignedUser.Name}}">
|
||||||
|
<div class="item" data-value="{{.SignedUser.ID}}">
|
||||||
|
<img class="ui mini image" src="{{.SignedUser.RelAvatarLink}}">
|
||||||
|
{{.SignedUser.ShortName 20}}
|
||||||
|
</div>
|
||||||
|
{{range .Orgs}}
|
||||||
|
<div class="item" data-value="{{.ID}}" title="{{.Name}}">
|
||||||
|
<img class="ui mini image" src="{{.RelAvatarLink}}">
|
||||||
|
{{.ShortName 20}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="inline required field {{if .Err_RepoName}}error{{end}}">
|
||||||
|
<label for="repo_name">{{.i18n.Tr "repo.repo_name"}}</label>
|
||||||
|
<input id="repo_name" name="repo_name" value="{{.repo_name}}" required>
|
||||||
|
</div>
|
||||||
|
<div class="inline field">
|
||||||
|
<label>{{.i18n.Tr "repo.visibility"}}</label>
|
||||||
|
<div class="ui checkbox">
|
||||||
|
{{if .IsForcedPrivate}}
|
||||||
|
<input name="private" type="checkbox" checked readonly>
|
||||||
|
<label>{{.i18n.Tr "repo.visibility_helper_forced" | Safe}}</label>
|
||||||
|
{{else}}
|
||||||
|
<input name="private" type="checkbox" {{if .private}}checked{{end}}>
|
||||||
|
<label>{{.i18n.Tr "repo.visibility_helper" | Safe}}</label>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="inline field {{if .Err_Description}}error{{end}}">
|
||||||
|
<label for="description">{{.i18n.Tr "repo.repo_desc"}}</label>
|
||||||
|
<textarea id="description" name="description">{{.description}}</textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="inline field">
|
||||||
|
<label></label>
|
||||||
|
<button class="ui green button">
|
||||||
|
{{.i18n.Tr "repo.migrate_repo"}}
|
||||||
|
</button>
|
||||||
|
<a class="ui button" href="{{AppSubUrl}}/">{{.i18n.Tr "cancel"}}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{template "base/footer" .}}
|
@ -0,0 +1,137 @@
|
|||||||
|
{{template "base/head" .}}
|
||||||
|
<div class="repository new migrate">
|
||||||
|
<div class="ui middle very relaxed page grid">
|
||||||
|
<div class="column">
|
||||||
|
<form class="ui form" action="{{.Link}}" method="post">
|
||||||
|
{{.CsrfTokenHtml}}
|
||||||
|
<h3 class="ui top attached header">
|
||||||
|
{{.i18n.Tr "repo.migrate.migrate" .service.Title}}
|
||||||
|
<input id="service_type" type="hidden" name="service" value="{{.service}}">
|
||||||
|
</h3>
|
||||||
|
<div class="ui attached segment">
|
||||||
|
{{template "base/alert" .}}
|
||||||
|
<div class="inline required field {{if .Err_CloneAddr}}error{{end}}">
|
||||||
|
<label for="clone_addr">{{.i18n.Tr "repo.migrate.clone_address"}}</label>
|
||||||
|
<input id="clone_addr" name="clone_addr" value="{{.clone_addr}}" autofocus required>
|
||||||
|
<span class="help">
|
||||||
|
{{.i18n.Tr "repo.migrate.clone_address_desc"}}{{if .ContextUser.CanImportLocal}} {{.i18n.Tr "repo.migrate.clone_local_path"}}{{end}}
|
||||||
|
{{if .LFSActive}}<br/>{{.i18n.Tr "repo.migrate.lfs_mirror_unsupported"}}{{end}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="inline field {{if .Err_Auth}}error{{end}}">
|
||||||
|
<label for="auth_token">{{.i18n.Tr "access_token"}}</label>
|
||||||
|
<input id="auth_token" name="auth_token" value="{{.auth_token}}" {{if not .auth_token}}data-need-clear="true"{{end}}>
|
||||||
|
<a target=”_blank” href="https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html">{{svg "octicon-question" 16}}</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="inline field">
|
||||||
|
<label>{{.i18n.Tr "repo.migrate_options"}}</label>
|
||||||
|
<div class="ui checkbox">
|
||||||
|
{{if .DisableMirrors}}
|
||||||
|
<input id="mirror" name="mirror" type="checkbox" readonly>
|
||||||
|
<label>{{.i18n.Tr "repo.migrate_options_mirror_disabled"}}</label>
|
||||||
|
{{else}}
|
||||||
|
<input id="mirror" name="mirror" type="checkbox" {{if .mirror}}checked{{end}}>
|
||||||
|
<label>{{.i18n.Tr "repo.migrate_options_mirror_helper" | Safe}}</label>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span class="help">{{.i18n.Tr "repo.migrate.migrate_items_options"}}</span>
|
||||||
|
<div id="migrate_items">
|
||||||
|
<div class="inline field">
|
||||||
|
<label>{{.i18n.Tr "repo.migrate_items"}}</label>
|
||||||
|
<div class="ui checkbox">
|
||||||
|
<input name="wiki" type="checkbox" {{if .wiki}}checked{{end}}>
|
||||||
|
<label>{{.i18n.Tr "repo.migrate_items_wiki" | Safe}}</label>
|
||||||
|
</div>
|
||||||
|
<div class="ui checkbox">
|
||||||
|
<input name="milestones" type="checkbox" {{if .milestones}}checked{{end}}>
|
||||||
|
<label>{{.i18n.Tr "repo.migrate_items_milestones" | Safe}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="inline field">
|
||||||
|
<label></label>
|
||||||
|
<div class="ui checkbox">
|
||||||
|
<input name="labels" type="checkbox" {{if .labels}}checked{{end}}>
|
||||||
|
<label>{{.i18n.Tr "repo.migrate_items_labels" | Safe}}</label>
|
||||||
|
</div>
|
||||||
|
<div class="ui checkbox">
|
||||||
|
<input name="issues" type="checkbox" {{if .issues}}checked{{end}}>
|
||||||
|
<label>{{.i18n.Tr "repo.migrate_items_issues" | Safe}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="inline field">
|
||||||
|
<label></label>
|
||||||
|
<div class="ui checkbox">
|
||||||
|
<input name="pull_requests" type="checkbox" {{if .pull_requests}}checked{{end}}>
|
||||||
|
<label>{{.i18n.Tr "repo.migrate_items_merge_requests" | Safe}}</label>
|
||||||
|
</div>
|
||||||
|
<div class="ui checkbox">
|
||||||
|
<input name="releases" type="checkbox" {{if .releases}}checked{{end}}>
|
||||||
|
<label>{{.i18n.Tr "repo.migrate_items_releases" | Safe}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui divider"></div>
|
||||||
|
|
||||||
|
<div class="inline required field {{if .Err_Owner}}error{{end}}">
|
||||||
|
<label>{{.i18n.Tr "repo.owner"}}</label>
|
||||||
|
<div class="ui selection owner dropdown">
|
||||||
|
<input type="hidden" id="uid" name="uid" value="{{.ContextUser.ID}}" required>
|
||||||
|
<span class="text" title="{{.ContextUser.Name}}">
|
||||||
|
<img class="ui mini image" src="{{.ContextUser.RelAvatarLink}}">
|
||||||
|
{{.ContextUser.ShortName 20}}
|
||||||
|
</span>
|
||||||
|
<i class="dropdown icon"></i>
|
||||||
|
<div class="menu" title="{{.SignedUser.Name}}">
|
||||||
|
<div class="item" data-value="{{.SignedUser.ID}}">
|
||||||
|
<img class="ui mini image" src="{{.SignedUser.RelAvatarLink}}">
|
||||||
|
{{.SignedUser.ShortName 20}}
|
||||||
|
</div>
|
||||||
|
{{range .Orgs}}
|
||||||
|
<div class="item" data-value="{{.ID}}" title="{{.Name}}">
|
||||||
|
<img class="ui mini image" src="{{.RelAvatarLink}}">
|
||||||
|
{{.ShortName 20}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="inline required field {{if .Err_RepoName}}error{{end}}">
|
||||||
|
<label for="repo_name">{{.i18n.Tr "repo.repo_name"}}</label>
|
||||||
|
<input id="repo_name" name="repo_name" value="{{.repo_name}}" required>
|
||||||
|
</div>
|
||||||
|
<div class="inline field">
|
||||||
|
<label>{{.i18n.Tr "repo.visibility"}}</label>
|
||||||
|
<div class="ui checkbox">
|
||||||
|
{{if .IsForcedPrivate}}
|
||||||
|
<input name="private" type="checkbox" checked readonly>
|
||||||
|
<label>{{.i18n.Tr "repo.visibility_helper_forced" | Safe}}</label>
|
||||||
|
{{else}}
|
||||||
|
<input name="private" type="checkbox" {{if .private}}checked{{end}}>
|
||||||
|
<label>{{.i18n.Tr "repo.visibility_helper" | Safe}}</label>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="inline field {{if .Err_Description}}error{{end}}">
|
||||||
|
<label for="description">{{.i18n.Tr "repo.repo_desc"}}</label>
|
||||||
|
<textarea id="description" name="description">{{.description}}</textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="inline field">
|
||||||
|
<label></label>
|
||||||
|
<button class="ui green button">
|
||||||
|
{{.i18n.Tr "repo.migrate_repo"}}
|
||||||
|
</button>
|
||||||
|
<a class="ui button" href="{{AppSubUrl}}/">{{.i18n.Tr "cancel"}}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{template "base/footer" .}}
|
@ -0,0 +1,23 @@
|
|||||||
|
{{template "base/head" .}}
|
||||||
|
<div class="repository new migrate">
|
||||||
|
<div class="ui middle very relaxed page grid">
|
||||||
|
<div class="column">
|
||||||
|
<div class="ui three stackable cards">
|
||||||
|
{{range .Services}}
|
||||||
|
<div class="ui card">
|
||||||
|
<a class="image" href="{{AppSubUrl}}/repo/migrate?service_type={{.}}">
|
||||||
|
{{svg (Printf "gitea-%s" .Name) 184}}
|
||||||
|
</a>
|
||||||
|
<div class="content">
|
||||||
|
<a class="header" href="{{AppSubUrl}}/repo/migrate?service_type={{.}}">{{.Title}}</a>
|
||||||
|
<div class="description">
|
||||||
|
{{(Printf "repo.migrate.%s.description" .Name) | $.i18n.Tr }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{template "base/footer" .}}
|
After Width: | Height: | Size: 702 B |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 409 B |
Loading…
Reference in new issue