* 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>for-closed-social
@ -0,0 +1 @@ | |||||
<svg viewBox="0 0 48 48" class="svg gitea-git" width="16" height="16" aria-hidden="true"><path fill="#F4511E" d="M42.2 22.1L25.9 5.8c-.5-.5-1.2-.8-1.9-.8s-1.4.3-1.9.8l-3.5 3.5 4.1 4.1c.4-.2.8-.3 1.3-.3 1.7 0 3 1.3 3 3 0 .5-.1.9-.3 1.3l4 4c.4-.2.8-.3 1.3-.3 1.7 0 3 1.3 3 3s-1.3 3-3 3-3-1.3-3-3c0-.5.1-.9.3-1.3l-4-4c-.1 0-.2.1-.3.1v10.4c1.2.4 2 1.5 2 2.8 0 1.7-1.3 3-3 3s-3-1.3-3-3c0-1.3.8-2.4 2-2.8V18.8c-1.2-.4-2-1.5-2-2.8 0-.5.1-.9.3-1.3l-4.1-4.1L5.8 22.1c-.5.5-.8 1.2-.8 1.9s.3 1.4.8 1.9l16.3 16.3c.5.5 1.2.8 1.9.8s1.4-.3 1.9-.8l16.3-16.3c.5-.5.8-1.2.8-1.9s-.3-1.4-.8-1.9z"/></svg> |
@ -0,0 +1 @@ | |||||
<svg viewBox="0 0 64 64" class="svg gitea-github" width="16" height="16" aria-hidden="true"><linearGradient id="a" x1="30.999" x2="30.999" y1="16" y2="55.342" gradientUnits="userSpaceOnUse" spreadMethod="reflect"><stop offset="0" stop-color="#6dc7ff"/><stop offset="1" stop-color="#e6abff"/></linearGradient><path fill="url(#a)" d="M25.008 56.007c-.003-.368-.006-1.962-.009-3.454l-.003-1.55c-6.729.915-8.358-3.78-8.376-3.83-.934-2.368-2.211-3.045-2.266-3.073l-.124-.072c-.463-.316-1.691-1.157-1.342-2.263.315-.997 1.536-1.1 2.091-1.082 3.074.215 4.63 2.978 4.694 3.095 1.569 2.689 3.964 2.411 5.509 1.844.144-.688.367-1.32.659-1.878-4.956-.879-10.571-3.515-10.571-13.104 0-2.633.82-4.96 2.441-6.929-.362-1.206-.774-3.666.446-6.765l.174-.442.452-.144c.416-.137 2.688-.624 7.359 2.433a24.959 24.959 0 016.074-.759c2.115.01 4.158.265 6.09.759 4.667-3.058 6.934-2.565 7.351-2.433l.451.145.174.44c1.225 3.098.813 5.559.451 6.766 1.618 1.963 2.438 4.291 2.438 6.929 0 9.591-5.621 12.219-10.588 13.087.563 1.065.868 2.402.868 3.878 0 1.683-.007 7.204-.015 8.402l-2-.014c.008-1.196.015-6.708.015-8.389 0-2.442-.943-3.522-1.35-3.874l-1.73-1.497 2.274-.253c5.205-.578 10.525-2.379 10.525-11.341 0-2.33-.777-4.361-2.31-6.036l-.43-.469.242-.587c.166-.401.894-2.442-.043-5.291-.758.045-2.568.402-5.584 2.447l-.384.259-.445-.123c-1.863-.518-3.938-.796-6.001-.806-2.052.01-4.124.288-5.984.806l-.445.123-.383-.259c-3.019-2.044-4.833-2.404-5.594-2.449-.935 2.851-.206 4.892-.04 5.293l.242.587-.429.469c-1.536 1.681-2.314 3.712-2.314 6.036 0 8.958 5.31 10.77 10.504 11.361l2.252.256-1.708 1.49c-.372.325-1.03 1.112-1.254 2.727l-.075.549-.506.227c-1.321.592-5.839 2.162-8.548-2.485-.015-.025-.544-.945-1.502-1.557.646.639 1.433 1.673 2.068 3.287.066.19 1.357 3.622 7.28 2.339l1.206-.262.012 3.978c.003 1.487.006 3.076.009 3.444l-1.998.014z"/><linearGradient id="b" x1="32" x2="32" y1="5" y2="59.167" gradientUnits="userSpaceOnUse" spreadMethod="reflect"><stop offset="0" stop-color="#1a6dff"/><stop offset="1" stop-color="#c822ff"/></linearGradient><path fill="url(#b)" d="M32 58C17.663 58 6 46.337 6 32S17.663 6 32 6s26 11.663 26 26-11.663 26-26 26zm0-50C18.767 8 8 18.767 8 32s10.767 24 24 24 24-10.767 24-24S45.233 8 32 8z"/></svg> |
@ -0,0 +1 @@ | |||||
<svg viewBox="0 0 48 48" class="svg gitea-gitlab" width="16" height="16" aria-hidden="true"><path fill="#e53935" d="M24 43l-8-23h16z"/><path fill="#ff7043" d="M24 43l18-23H32z"/><path fill="#e53935" d="M37 5l5 15H32z"/><path fill="#ffa726" d="M24 43l18-23 3 8z"/><path fill="#ff7043" d="M24 43L6 20h10z"/><path fill="#e53935" d="M11 5L6 20h10z"/><path fill="#ffa726" d="M24 43L6 20l-3 8z"/></svg> |
@ -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" .}} |
@ -0,0 +1 @@ | |||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="64px" height="64px"><path fill="#F4511E" d="M42.2,22.1L25.9,5.8C25.4,5.3,24.7,5,24,5c0,0,0,0,0,0c-0.7,0-1.4,0.3-1.9,0.8l-3.5,3.5l4.1,4.1c0.4-0.2,0.8-0.3,1.3-0.3c1.7,0,3,1.3,3,3c0,0.5-0.1,0.9-0.3,1.3l4,4c0.4-0.2,0.8-0.3,1.3-0.3c1.7,0,3,1.3,3,3s-1.3,3-3,3c-1.7,0-3-1.3-3-3c0-0.5,0.1-0.9,0.3-1.3l-4-4c-0.1,0-0.2,0.1-0.3,0.1v10.4c1.2,0.4,2,1.5,2,2.8c0,1.7-1.3,3-3,3s-3-1.3-3-3c0-1.3,0.8-2.4,2-2.8V18.8c-1.2-0.4-2-1.5-2-2.8c0-0.5,0.1-0.9,0.3-1.3l-4.1-4.1L5.8,22.1C5.3,22.6,5,23.3,5,24c0,0.7,0.3,1.4,0.8,1.9l16.3,16.3c0,0,0,0,0,0c0.5,0.5,1.2,0.8,1.9,0.8s1.4-0.3,1.9-0.8l16.3-16.3c0.5-0.5,0.8-1.2,0.8-1.9C43,23.3,42.7,22.6,42.2,22.1z"/></svg> |
@ -0,0 +1 @@ | |||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64px" height="64px"><linearGradient id="KpzH_ttTMIjq8dhx1zD2pa" x1="30.999" x2="30.999" y1="16" y2="55.342" gradientUnits="userSpaceOnUse" spreadMethod="reflect"><stop offset="0" stop-color="#6dc7ff"/><stop offset="1" stop-color="#e6abff"/></linearGradient><path fill="url(#KpzH_ttTMIjq8dhx1zD2pa)" d="M25.008,56.007c-0.003-0.368-0.006-1.962-0.009-3.454l-0.003-1.55 c-6.729,0.915-8.358-3.78-8.376-3.83c-0.934-2.368-2.211-3.045-2.266-3.073l-0.124-0.072c-0.463-0.316-1.691-1.157-1.342-2.263 c0.315-0.997,1.536-1.1,2.091-1.082c3.074,0.215,4.63,2.978,4.694,3.095c1.569,2.689,3.964,2.411,5.509,1.844 c0.144-0.688,0.367-1.32,0.659-1.878C20.885,42.865,15.27,40.229,15.27,30.64c0-2.633,0.82-4.96,2.441-6.929 c-0.362-1.206-0.774-3.666,0.446-6.765l0.174-0.442l0.452-0.144c0.416-0.137,2.688-0.624,7.359,2.433 c1.928-0.494,3.969-0.749,6.074-0.759c2.115,0.01,4.158,0.265,6.09,0.759c4.667-3.058,6.934-2.565,7.351-2.433l0.451,0.145 l0.174,0.44c1.225,3.098,0.813,5.559,0.451,6.766c1.618,1.963,2.438,4.291,2.438,6.929c0,9.591-5.621,12.219-10.588,13.087 c0.563,1.065,0.868,2.402,0.868,3.878c0,1.683-0.007,7.204-0.015,8.402l-2-0.014c0.008-1.196,0.015-6.708,0.015-8.389 c0-2.442-0.943-3.522-1.35-3.874l-1.73-1.497l2.274-0.253c5.205-0.578,10.525-2.379,10.525-11.341c0-2.33-0.777-4.361-2.31-6.036 l-0.43-0.469l0.242-0.587c0.166-0.401,0.894-2.442-0.043-5.291c-0.758,0.045-2.568,0.402-5.584,2.447l-0.384,0.259l-0.445-0.123 c-1.863-0.518-3.938-0.796-6.001-0.806c-2.052,0.01-4.124,0.288-5.984,0.806l-0.445,0.123l-0.383-0.259 c-3.019-2.044-4.833-2.404-5.594-2.449c-0.935,2.851-0.206,4.892-0.04,5.293l0.242,0.587l-0.429,0.469 c-1.536,1.681-2.314,3.712-2.314,6.036c0,8.958,5.31,10.77,10.504,11.361l2.252,0.256l-1.708,1.49 c-0.372,0.325-1.03,1.112-1.254,2.727l-0.075,0.549l-0.506,0.227c-1.321,0.592-5.839,2.162-8.548-2.485 c-0.015-0.025-0.544-0.945-1.502-1.557c0.646,0.639,1.433,1.673,2.068,3.287c0.066,0.19,1.357,3.622,7.28,2.339l1.206-0.262 l0.012,3.978c0.003,1.487,0.006,3.076,0.009,3.444L25.008,56.007z"/><linearGradient id="KpzH_ttTMIjq8dhx1zD2pb" x1="32" x2="32" y1="5" y2="59.167" gradientUnits="userSpaceOnUse" spreadMethod="reflect"><stop offset="0" stop-color="#1a6dff"/><stop offset="1" stop-color="#c822ff"/></linearGradient><path fill="url(#KpzH_ttTMIjq8dhx1zD2pb)" d="M32,58C17.663,58,6,46.337,6,32S17.663,6,32,6s26,11.663,26,26S46.337,58,32,58z M32,8 C18.767,8,8,18.767,8,32s10.767,24,24,24s24-10.767,24-24S45.233,8,32,8z"/></svg> |
@ -0,0 +1 @@ | |||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="64px" height="64px"><path fill="#e53935" d="M24 43L16 20 32 20z"/><path fill="#ff7043" d="M24 43L42 20 32 20z"/><path fill="#e53935" d="M37 5L42 20 32 20z"/><path fill="#ffa726" d="M24 43L42 20 45 28z"/><path fill="#ff7043" d="M24 43L6 20 16 20z"/><path fill="#e53935" d="M11 5L6 20 16 20z"/><path fill="#ffa726" d="M24 43L6 20 3 28z"/></svg> |