diff --git a/docs/content/administration/email-setup.en-us.md b/docs/content/administration/email-setup.en-us.md index 10058d828..645a7a3f4 100644 --- a/docs/content/administration/email-setup.en-us.md +++ b/docs/content/administration/email-setup.en-us.md @@ -79,8 +79,7 @@ SMTP_PORT = 465 FROM = example.user@gmail.com USER = example.user PASSWD = `***` -PROTOCOL = smtp -IS_TLS_ENABLED = true +PROTOCOL = smtps ``` Note that you'll need to create and use an [App password](https://support.google.com/accounts/answer/185833?hl=en) by enabling 2FA on your Google diff --git a/go.mod b/go.mod index 5ccf962e1..b1e31c3fa 100644 --- a/go.mod +++ b/go.mod @@ -107,7 +107,7 @@ require ( github.com/yuin/goldmark-meta v1.1.0 golang.org/x/crypto v0.11.0 golang.org/x/image v0.9.0 - golang.org/x/net v0.12.0 + golang.org/x/net v0.13.0 golang.org/x/oauth2 v0.10.0 golang.org/x/sys v0.10.0 golang.org/x/text v0.11.0 diff --git a/go.sum b/go.sum index 67c73cb71..5e942457a 100644 --- a/go.sum +++ b/go.sum @@ -1216,8 +1216,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= diff --git a/models/issues/review.go b/models/issues/review.go index b2736044f..cae3ef1d3 100644 --- a/models/issues/review.go +++ b/models/issues/review.go @@ -192,6 +192,9 @@ func (r *Review) LoadAttributes(ctx context.Context) (err error) { func (r *Review) HTMLTypeColorName() string { switch r.Type { case ReviewTypeApprove: + if r.Stale { + return "yellow" + } return "green" case ReviewTypeComment: return "grey" diff --git a/models/repo/topic.go b/models/repo/topic.go index ec3de869d..71302388b 100644 --- a/models/repo/topic.go +++ b/models/repo/topic.go @@ -22,7 +22,7 @@ func init() { db.RegisterModel(new(RepoTopic)) } -var topicPattern = regexp.MustCompile(`^[a-z0-9][a-z0-9-]*$`) +var topicPattern = regexp.MustCompile(`^[a-z0-9][-.a-z0-9]*$`) // Topic represents a topic of repositories type Topic struct { diff --git a/models/repo/topic_test.go b/models/repo/topic_test.go index 8a8728168..aaed91bdd 100644 --- a/models/repo/topic_test.go +++ b/models/repo/topic_test.go @@ -69,6 +69,7 @@ func TestAddTopic(t *testing.T) { func TestTopicValidator(t *testing.T) { assert.True(t, repo_model.ValidateTopic("12345")) assert.True(t, repo_model.ValidateTopic("2-test")) + assert.True(t, repo_model.ValidateTopic("foo.bar")) assert.True(t, repo_model.ValidateTopic("test-3")) assert.True(t, repo_model.ValidateTopic("first")) assert.True(t, repo_model.ValidateTopic("second-test-topic")) @@ -77,4 +78,5 @@ func TestTopicValidator(t *testing.T) { assert.False(t, repo_model.ValidateTopic("$fourth-test,topic")) assert.False(t, repo_model.ValidateTopic("-fifth-test-topic")) assert.False(t, repo_model.ValidateTopic("sixth-go-project-topic-with-excess-length")) + assert.False(t, repo_model.ValidateTopic(".foo")) } diff --git a/modules/git/repo_compare.go b/modules/git/repo_compare.go index e70627585..aad725fa9 100644 --- a/modules/git/repo_compare.go +++ b/modules/git/repo_compare.go @@ -280,8 +280,16 @@ func (repo *Repository) GetPatch(base, head string, w io.Writer) error { } // GetFilesChangedBetween returns a list of all files that have been changed between the given commits +// If base is undefined empty SHA (zeros), it only returns the files changed in the head commit +// If base is the SHA of an empty tree (EmptyTreeSHA), it returns the files changes from the initial commit to the head commit func (repo *Repository) GetFilesChangedBetween(base, head string) ([]string, error) { - stdout, _, err := NewCommand(repo.Ctx, "diff", "--name-only", "-z").AddDynamicArguments(base + ".." + head).RunStdString(&RunOpts{Dir: repo.Path}) + cmd := NewCommand(repo.Ctx, "diff-tree", "--name-only", "--root", "--no-commit-id", "-r", "-z") + if base == EmptySHA { + cmd.AddDynamicArguments(head) + } else { + cmd.AddDynamicArguments(base, head) + } + stdout, _, err := cmd.RunStdString(&RunOpts{Dir: repo.Path}) if err != nil { return nil, err } diff --git a/modules/git/repo_compare_test.go b/modules/git/repo_compare_test.go index 5b50bc82a..603aabde4 100644 --- a/modules/git/repo_compare_test.go +++ b/modules/git/repo_compare_test.go @@ -119,3 +119,42 @@ func TestReadWritePullHead(t *testing.T) { err = repo.RemoveReference(PullPrefix + "1/head") assert.NoError(t, err) } + +func TestGetCommitFilesChanged(t *testing.T) { + bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") + repo, err := openRepositoryWithDefaultContext(bareRepo1Path) + assert.NoError(t, err) + defer repo.Close() + + testCases := []struct { + base, head string + files []string + }{ + { + EmptySHA, + "95bb4d39648ee7e325106df01a621c530863a653", + []string{"file1.txt"}, + }, + { + EmptySHA, + "8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2", + []string{"file2.txt"}, + }, + { + "95bb4d39648ee7e325106df01a621c530863a653", + "8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2", + []string{"file2.txt"}, + }, + { + EmptyTreeSHA, + "8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2", + []string{"file1.txt", "file2.txt"}, + }, + } + + for _, tc := range testCases { + changedFiles, err := repo.GetFilesChangedBetween(tc.base, tc.head) + assert.NoError(t, err) + assert.ElementsMatch(t, tc.files, changedFiles) + } +} diff --git a/modules/git/sha1.go b/modules/git/sha1.go index 7d9d9776d..8d6403e86 100644 --- a/modules/git/sha1.go +++ b/modules/git/sha1.go @@ -11,10 +11,10 @@ import ( "strings" ) -// EmptySHA defines empty git SHA +// EmptySHA defines empty git SHA (undefined, non-existent) const EmptySHA = "0000000000000000000000000000000000000000" -// EmptyTreeSHA is the SHA of an empty tree +// EmptyTreeSHA is the SHA of an empty tree, the root of all git repositories const EmptyTreeSHA = "4b825dc642cb6eb9a060e54bf8d69288fbee4904" // SHAFullLength is the full length of a git SHA diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index ea0996469..b089b9001 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -753,7 +753,7 @@ ssh_token_required=Du musst eine Signatur für den Token unten angeben ssh_token=Token ssh_token_help=Du kannst eine Signatur wie folgt generieren: ssh_token_signature=SSH Textsignatur (armored signature) -key_signature_ssh_placeholder=Beginnt mit „-----BEGIN PGP SIGNATURE-----“ +key_signature_ssh_placeholder=Beginnt mit „-----BEGIN SSH SIGNATURE-----“ verify_ssh_key_success=SSH-Key "%s" wurde verifiziert. subkeys=Unterschlüssel key_id=Schlüssel-ID @@ -908,7 +908,7 @@ owner=Besitzer owner_helper=Einige Organisationen könnten in der Dropdown-Liste nicht angezeigt werden, da die Anzahl an Repositories begrenzt ist. repo_name=Repository-Name repo_name_helper=Ein guter Repository-Name besteht normalerweise aus kurzen, unvergesslichen und einzigartigen Schlagwörtern. -repo_size=Repository Größe +repo_size=Repository-Größe template=Template template_select=Vorlage auswählen template_helper=Repository zu einem Template machen @@ -1672,7 +1672,7 @@ pulls.is_ancestor=Dieser Branch ist bereits im Zielbranch enthalten. Es gibt nic pulls.is_empty=Die Änderungen an diesem Branch sind bereits auf dem Zielbranch. Dies wird ein leerer Commit sein. pulls.required_status_check_failed=Einige erforderliche Prüfungen waren nicht erfolgreich. pulls.required_status_check_missing=Einige erforderliche Prüfungen fehlen. -pulls.required_status_check_administrator=Als Administrator kannst du diesen Pull-Request weiterhin zusammenführen. +pulls.required_status_check_administrator=Als Administrator kannst du diesen Pull-Request weiterhin mergen. pulls.blocked_by_approvals=Dieser Pull-Request hat noch nicht genügend Zustimmungen. %d von %d Zustimmungen erteilt. pulls.blocked_by_rejection=Dieser Pull-Request hat Änderungen, die von einem offiziellen Reviewer angefragt wurden. pulls.blocked_by_official_review_requests=Dieser Pull Request hat offizielle Review-Anfragen. @@ -1706,12 +1706,12 @@ pulls.merge_commit_id=Der Mergecommit ID pulls.require_signed_wont_sign=Der Branch erfordert einen signierten Commit, aber dieser Merge wird nicht signiert pulls.invalid_merge_option=Du kannst diese Mergeoption auf diesen Pull-Request nicht anwenden. -pulls.merge_conflict=Zusammenführen fehlgeschlagen: Beim Zusammenführen gab es einen Konflikt. Hinweis: Probiere eine andere Strategie +pulls.merge_conflict=Merge fehlgeschlagen: Beim Mergen gab es einen Konflikt. Hinweis: Probiere eine andere Strategie pulls.merge_conflict_summary=Fehlermeldung -pulls.rebase_conflict=Zusammenführen fehlgeschlagen: Es gab einen Konflikt beim Rebasing des Commits: %[1]s. Hinweis: Versuche eine andere Strategie +pulls.rebase_conflict=Merge fehlgeschlagen: Es gab einen Konflikt beim Rebasen des Commits: %[1]s. Hinweis: Versuche eine andere Strategie pulls.rebase_conflict_summary=Fehlermeldung -pulls.unrelated_histories=Zusammenführung fehlgeschlagen: Der Head der Zusammenführung und die Basis haben keinen gemeinsamen Verlauf. Hinweis: Versuche eine andere Strategie -pulls.merge_out_of_date=Zusammenführung fehlgeschlagen: Während der Zusammenführung wurde die Basis aktualisiert. Hinweis: Versuche es erneut. +pulls.unrelated_histories=Merge fehlgeschlagen: Der Head des Merges und die Basis haben keinen gemeinsamen Verlauf. Hinweis: Versuche eine andere Strategie +pulls.merge_out_of_date=Merge fehlgeschlagen: Während des Mergens wurde die Basis aktualisiert. Hinweis: Versuche es erneut. pulls.head_out_of_date=Mergen fehlgeschlagen: Der Head wurde aktualisiert während der Merge erstellt wurde. Tipp: Versuche es erneut. pulls.push_rejected=Mergen fehlgeschlagen: Der Push wurde abgelehnt. Überprüfe die Git Hooks für dieses Repository. pulls.push_rejected_summary=Vollständige Ablehnungsmeldung @@ -1872,7 +1872,7 @@ activity.title.releases_n=%d Releases activity.title.releases_published_by=%s von %s veröffentlicht activity.published_release_label=Veröffentlicht activity.no_git_activity=In diesem Zeitraum sind keine Commit-Aktivität vorhanden. -activity.git_stats_exclude_merges=Zusammenführungen ausgenommen, +activity.git_stats_exclude_merges=Merges ausgenommen, activity.git_stats_author_1=%d Autor activity.git_stats_author_n=%d Autoren activity.git_stats_pushed_1=hat @@ -2254,7 +2254,7 @@ settings.block_on_official_review_requests_desc=Mergen ist nicht möglich wenn o settings.block_outdated_branch=Merge blockieren, wenn der Pull-Request veraltet ist settings.block_outdated_branch_desc=Mergen ist nicht möglich, wenn der Head-Branch hinter dem Basis-Branch ist. settings.default_branch_desc=Wähle einen Standardbranch für Pull-Requests und Code-Commits: -settings.merge_style_desc=Styles zusammenführen +settings.merge_style_desc=Merge-Styles settings.default_merge_style_desc=Standard Mergeverhalten für Pull Requests: settings.choose_branch=Wähle einen Branch … settings.no_protected_branch=Es gibt keine geschützten Branches. @@ -3124,13 +3124,13 @@ notices.delete_success=Diese Systemmeldung wurde gelöscht. create_repo=hat das Repository %s erstellt rename_repo=hat das Repository von %[1]s zu %[3]s umbenannt commit_repo=hat %[3]s auf %[4]s gepusht -create_issue=`hat Ticket %[3]s#%[2]s geöffnet` -close_issue=`Ticket %[3]s#%[2]s geschlossen` -reopen_issue=`Ticket %[3]s#%[2]s wiedereröffnet` +create_issue=`hat das Issue %[3]s#%[2]s geöffnet` +close_issue=`hat das Issue %[3]s#%[2]s geschlossen` +reopen_issue=`hat das Issue %[3]s#%[2]s wiedereröffnet` create_pull_request=`hat den Pull-Request %[3]s#%[2]s erstellt` close_pull_request=`Pull-Request %[3]s#%[2]s wurde geschlossen` reopen_pull_request=`Pull-Request %[3]s#%[2]s wurde wiedereröffnet` -comment_issue=`Ticket %[3]s#%[2]s wurde kommentiert` +comment_issue=`hat das Issue %[3]s#%[2]s kommentiert` comment_pull=`Pull-Request %[3]s#%[2]s wurde kommentiert` merge_pull_request=`Pull-Request %[3]s#%[2]s wurde zusammengeführt` auto_merge_pull_request=`Pull-Request %[3]s#%[2]s wurde automatisch zusammengeführt` diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 6cb830b6d..b2eeab617 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -80,6 +80,7 @@ milestones = Milestones ok = OK cancel = Cancel +retry = Retry rerun = Re-run rerun_all = Re-run all jobs save = Save @@ -1150,10 +1151,10 @@ file_view_rendered = View Rendered file_view_raw = View Raw file_permalink = Permalink file_too_large = The file is too large to be shown. -invisible_runes_header = `This file contains invisible Unicode characters!` -invisible_runes_description = `This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.` -ambiguous_runes_header = `This file contains ambiguous Unicode characters!` -ambiguous_runes_description = `This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.` +invisible_runes_header = `This file contains invisible Unicode characters` +invisible_runes_description = `This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.` +ambiguous_runes_header = `This file contains ambiguous Unicode characters` +ambiguous_runes_description = `This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.` invisible_runes_line = `This line has invisible unicode characters` ambiguous_runes_line = `This line has ambiguous unicode characters` ambiguous_character = `%[1]c [U+%04[1]X] can be confused with %[2]c [U+%04[2]X]` @@ -1784,6 +1785,8 @@ pulls.delete.text = Do you really want to delete this pull request? (This will p pulls.recently_pushed_new_branches = You pushed on branch %[1]s %[2]s +pull.deleted_branch = (deleted):%s + milestones.new = New Milestone milestones.closed = Closed %s milestones.update_ago = Updated %s @@ -2507,7 +2510,7 @@ tag.create_success = Tag "%s" has been created. topic.manage_topics = Manage Topics topic.done = Done topic.count_prompt = You cannot select more than 25 topics -topic.format_prompt = Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long. +topic.format_prompt = Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase. find_file.go_to_file = Go to file find_file.no_matching = No matching file found diff --git a/routers/web/repo/migrate.go b/routers/web/repo/migrate.go index b918650d1..a6125a1a5 100644 --- a/routers/web/repo/migrate.go +++ b/routers/web/repo/migrate.go @@ -259,6 +259,15 @@ func setMigrationContextData(ctx *context.Context, serviceType structs.GitServic ctx.Data["service"] = serviceType } +func MigrateRetryPost(ctx *context.Context) { + if err := task.RetryMigrateTask(ctx.Repo.Repository.ID); err != nil { + log.Error("Retry task failed: %v", err) + ctx.ServerError("task.RetryMigrateTask", err) + return + } + ctx.JSONOK() +} + func MigrateCancelPost(ctx *context.Context) { migratingTask, err := admin_model.GetMigratingTask(ctx.Repo.Repository.ID) if err != nil { diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index d76e90bf2..0be8bede7 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -610,7 +610,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C if pull.IsSameRepo() { ctx.Data["HeadTarget"] = pull.HeadBranch } else if pull.HeadRepo == nil { - ctx.Data["HeadTarget"] = ":" + pull.HeadBranch + ctx.Data["HeadTarget"] = ctx.Locale.Tr("repo.pull.deleted_branch", pull.HeadBranch) } else { ctx.Data["HeadTarget"] = pull.HeadRepo.OwnerName + ":" + pull.HeadBranch } @@ -654,7 +654,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C if pull.IsSameRepo() { ctx.Data["HeadTarget"] = pull.HeadBranch } else if pull.HeadRepo == nil { - ctx.Data["HeadTarget"] = ":" + pull.HeadBranch + ctx.Data["HeadTarget"] = ctx.Locale.Tr("repo.pull.deleted_branch", pull.HeadBranch) } else { ctx.Data["HeadTarget"] = pull.HeadRepo.OwnerName + ":" + pull.HeadBranch } diff --git a/routers/web/web.go b/routers/web/web.go index ca75bd596..aa3d830f9 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -953,7 +953,11 @@ func registerRoutes(m *web.Route) { addSettingsSecretsRoutes() addSettingVariablesRoutes() }, actions.MustEnableActions) - m.Post("/migrate/cancel", repo.MigrateCancelPost) // this handler must be under "settings", otherwise this incomplete repo can't be accessed + // the follow handler must be under "settings", otherwise this incomplete repo can't be accessed + m.Group("/migrate", func() { + m.Post("/retry", repo.MigrateRetryPost) + m.Post("/cancel", repo.MigrateCancelPost) + }) }, ctxDataSet("PageIsRepoSettings", true, "LFSStartServer", setting.LFS.StartServer)) }, reqSignIn, context.RepoAssignment, context.UnitTypes(), reqRepoAdmin, context.RepoRef()) diff --git a/services/task/task.go b/services/task/task.go index 11a47a68b..db5c1dd3f 100644 --- a/services/task/task.go +++ b/services/task/task.go @@ -126,3 +126,27 @@ func CreateMigrateTask(doer, u *user_model.User, opts base.MigrateOptions) (*adm return task, nil } + +// RetryMigrateTask retry a migrate task +func RetryMigrateTask(repoID int64) error { + migratingTask, err := admin_model.GetMigratingTask(repoID) + if err != nil { + log.Error("GetMigratingTask: %v", err) + return err + } + if migratingTask.Status == structs.TaskStatusQueued || migratingTask.Status == structs.TaskStatusRunning { + return nil + } + + // TODO Need to removing the storage/database garbage brought by the failed task + + // Reset task status and messages + migratingTask.Status = structs.TaskStatusQueued + migratingTask.Message = "" + if err = migratingTask.UpdateCols("status", "message"); err != nil { + log.Error("task.UpdateCols failed: %v", err) + return err + } + + return taskQueue.Push(migratingTask) +} diff --git a/templates/repo/issue/view_content/pull.tmpl b/templates/repo/issue/view_content/pull.tmpl index 214d77a12..a2e727c40 100644 --- a/templates/repo/issue/view_content/pull.tmpl +++ b/templates/repo/issue/view_content/pull.tmpl @@ -2,7 +2,7 @@ {{/* Then the merge box will not be displayed because this page already contains enough information */}} {{else}}
- {{svg "octicon-git-merge" 40}} + {{- else}}red{{end}}">{{svg "octicon-git-merge" 40}}
{{template "repo/pulls/status" .}} {{$showGeneralMergeForm := false}} diff --git a/templates/repo/migrate/migrating.tmpl b/templates/repo/migrate/migrating.tmpl index 50bff0a93..d1bdc5a90 100644 --- a/templates/repo/migrate/migrating.tmpl +++ b/templates/repo/migrate/migrating.tmpl @@ -36,10 +36,11 @@
{{if .Failed}} - + {{else}} - + {{end}} +
{{end}}
diff --git a/templates/repo/unicode_escape_prompt.tmpl b/templates/repo/unicode_escape_prompt.tmpl index 961e2370a..66e00f6a9 100644 --- a/templates/repo/unicode_escape_prompt.tmpl +++ b/templates/repo/unicode_escape_prompt.tmpl @@ -1,6 +1,6 @@ {{if .EscapeStatus}} {{if .EscapeStatus.HasInvisible}} -
+
{{$.root.locale.Tr "repo.invisible_runes_header"}} diff --git a/web_src/js/features/repo-home.js b/web_src/js/features/repo-home.js index 55a277105..70c225b4b 100644 --- a/web_src/js/features/repo-home.js +++ b/web_src/js/features/repo-home.js @@ -166,7 +166,7 @@ export function initRepoTopicBar() { rules: [ { type: 'validateTopic', - value: /^[a-z0-9][a-z0-9-]{0,35}$/, + value: /^\s*[a-z0-9][-.a-z0-9]{0,35}\s*$/, prompt: topicPrompts.formatPrompt }, { diff --git a/web_src/js/features/repo-migrate.js b/web_src/js/features/repo-migrate.js index e57348d31..de9f7b023 100644 --- a/web_src/js/features/repo-migrate.js +++ b/web_src/js/features/repo-migrate.js @@ -1,12 +1,14 @@ import $ from 'jquery'; import {hideElem, showElem} from '../utils/dom.js'; -const {appSubUrl} = window.config; +const {appSubUrl, csrfToken} = window.config; export function initRepoMigrationStatusChecker() { const $repoMigrating = $('#repo_migrating'); if (!$repoMigrating.length) return; + $('#repo_migrating_retry').on('click', doMigrationRetry); + const task = $repoMigrating.attr('data-migrating-task-id'); // returns true if the refresh still need to be called after a while @@ -31,6 +33,7 @@ export function initRepoMigrationStatusChecker() { if (data.status === 3) { hideElem('#repo_migrating_progress'); hideElem('#repo_migrating'); + showElem('#repo_migrating_retry'); showElem('#repo_migrating_failed'); showElem('#repo_migrating_failed_image'); $('#repo_migrating_failed_error').text(data.message); @@ -53,3 +56,14 @@ export function initRepoMigrationStatusChecker() { syncTaskStatus(); // no await } + +async function doMigrationRetry(e) { + await fetch($(e.target).attr('data-migrating-task-retry-url'), { + method: 'post', + headers: { + 'X-Csrf-Token': csrfToken, + 'Content-Type': 'application/json', + }, + }); + window.location.reload(); +}