enhance(repo): move delete to modal, add files to directory in file view and apply patch ui improvements.

brymut 2025-11-15 11:54:28 +03:00
parent 57782c392a
commit 72d9f96455
No known key found for this signature in database
GPG Key ID: 25AB059F26A42251
9 changed files with 230 additions and 10 deletions

View File

@ -306,5 +306,11 @@ func prepareFileViewEditorButtons(ctx *context.Context) bool {
ctx.Data["EditFileTooltip"] = util.Iif(isLFSLocked, ctx.Tr("repo.editor.this_file_locked"), ctx.Tr("repo.editor.edit_this_file"))
ctx.Data["CanDeleteFile"] = !isLFSLocked
ctx.Data["DeleteFileTooltip"] = util.Iif(isLFSLocked, ctx.Tr("repo.editor.this_file_locked"), ctx.Tr("repo.editor.delete_this_file"))
// Generate unique branch name for delete modal
if ctx.Doer != nil {
ctx.Data["new_branch_name"] = getUniquePatchBranchName(ctx, ctx.Doer.LowerName, ctx.Repo.Repository)
}
return true
}

View File

@ -11,6 +11,5 @@
<span class="section"><a href="{{$.BranchLink}}/{{index $.TreePaths $i | PathEscapeSegments}}">{{$v}}</a></span>
{{end}}
{{end}}
<span>{{ctx.Locale.Tr "repo.editor.or"}} <a href="{{or .ReturnURI (print $.BranchLink "/" (PathEscapeSegments .TreePath))}}">{{ctx.Locale.Tr "repo.editor.cancel_lower"}}</a></span>
<input type="hidden" id="tree_path" name="tree_path" value="{{.TreePath}}">
</div>

View File

@ -22,11 +22,8 @@
{{svg "octicon-sidebar-collapse"}}
</button>
<div class="breadcrumb">
{{ctx.Locale.Tr "repo.editor.patching"}}
<a class="section" href="{{$.RepoLink}}">{{.Repository.FullName}}</a>
<div class="breadcrumb-divider">:</div>
<span>{{ctx.Locale.Tr "repo.editor.patching"}}</span>
<a class="section" href="{{$.BranchLink}}">{{.BranchName}}</a>
<span>{{ctx.Locale.Tr "repo.editor.or"}} <a href="{{$.BranchLink}}">{{ctx.Locale.Tr "repo.editor.cancel_lower"}}</a></span>
<input type="hidden" name="tree_path" value="__dummy_for_EditRepoFileForm.TreePath(Required)__">
<input id="file-name" type="hidden" value="diff.patch">
</div>

View File

@ -66,24 +66,33 @@
</div>
<div class="repo-button-row-right">
{{if and .RefFullName.IsBranch (not .IsViewFile)}}
{{if .RefFullName.IsBranch}}
{{$addFilePath := .TreePath}}
{{if .IsViewFile}}
{{if gt (len .TreeNames) 1}}
{{$addFilePath = StringUtils.Join (slice .TreeNames 0 (Eval (len .TreeNames) "-" 1)) "/"}}
{{else}}
{{$addFilePath = ""}}
{{end}}
{{end}}
<button class="ui dropdown basic compact jump button repo-add-file" {{if not .Repository.CanEnableEditor}}disabled{{end}}>
{{ctx.Locale.Tr "repo.editor.add_file"}}
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
<div class="menu">
<a class="item" href="{{.RepoLink}}/_new/{{.BranchName | PathEscapeSegments}}/{{.TreePath | PathEscapeSegments}}">
<a class="item" href="{{.RepoLink}}/_new/{{.BranchName | PathEscapeSegments}}/{{$addFilePath | PathEscapeSegments}}">
{{svg "octicon-file-added" 16 "tw-mr-2"}}{{ctx.Locale.Tr "repo.editor.new_file"}}
</a>
{{if .RepositoryUploadEnabled}}
<a class="item" href="{{.RepoLink}}/_upload/{{.BranchName | PathEscapeSegments}}/{{.TreePath | PathEscapeSegments}}">
<a class="item" href="{{.RepoLink}}/_upload/{{.BranchName | PathEscapeSegments}}/{{$addFilePath | PathEscapeSegments}}">
{{svg "octicon-upload" 16 "tw-mr-2"}}{{ctx.Locale.Tr "repo.editor.upload_file"}}
</a>
{{end}}
<a class="item" href="{{.RepoLink}}/_diffpatch/{{.BranchName | PathEscapeSegments}}/{{.TreePath | PathEscapeSegments}}">
<a class="item" href="{{.RepoLink}}/_diffpatch/{{.BranchName | PathEscapeSegments}}/{{$addFilePath | PathEscapeSegments}}">
{{svg "octicon-diff" 16 "tw-mr-2"}}{{ctx.Locale.Tr "repo.editor.patch"}}
</a>
</div>
</button>
{{if not .IsViewFile}}
<button class="ui dropdown basic compact jump button icon repo-file-actions-dropdown" data-tooltip-content="{{ctx.Locale.Tr "repo.more_operations"}}">
{{svg "octicon-kebab-horizontal"}}
<div class="menu">
@ -101,6 +110,7 @@
{{end}}
</div>
</button>
{{end}}
{{end}}
<!-- Only show clone panel in repository home page -->
{{if $isTreePathRoot}}

View File

@ -74,7 +74,7 @@
<span class="btn-octicon disabled" data-tooltip-content="{{.EditFileTooltip}}">{{svg "octicon-pencil"}}</span>
{{end}}
{{if .CanDeleteFile}}
<a class="btn-octicon btn-octicon-danger" data-tooltip-content="{{.DeleteFileTooltip}}" href="{{.RepoLink}}/_delete/{{PathEscapeSegments .BranchName}}/{{PathEscapeSegments .TreePath}}">{{svg "octicon-trash"}}</a>
<a type="button" class="btn-octicon btn-octicon-danger" data-tooltip-content="{{.DeleteFileTooltip}}" id="delete-file-button">{{svg "octicon-trash"}}</a>
{{else}}
<span class="btn-octicon disabled" data-tooltip-content="{{.DeleteFileTooltip}}">{{svg "octicon-trash"}}</span>
{{end}}
@ -148,4 +148,75 @@
<a class="item copy-line-permalink" role="menuitem" data-url="{{.Repository.Link}}/src/commit/{{PathEscape .CommitID}}/{{PathEscapeSegments .TreePath}}{{if $.HasSourceRenderedToggle}}?display=source{{end}}">{{ctx.Locale.Tr "repo.file_copy_permalink"}}</a>
</div>
</div>
{{/* Delete File Modal */}}
{{if .CanDeleteFile}}
<div class="ui modal" id="delete-file-modal">
<i class="close icon"></i>
<div class="content">
<form id="delete-file-form" class="ui form form-fetch-action" method="post" action="{{.RepoLink}}/_delete/{{.BranchName | PathEscapeSegments}}/{{.TreePath | PathEscapeSegments}}">
{{.CsrfTokenHtml}}
<input type="hidden" name="last_commit" value="{{.CommitID}}">
<input type="hidden" name="tree_path" value="{{.TreePath}}">
<div class="commit-form-wrapper">
{{ctx.AvatarUtils.Avatar .SignedUser 40 "commit-avatar"}}
<div class="commit-form avatar-content-left-arrow">
<h3>
<span>{{svg "octicon-unlock" 24}}</span>
{{ctx.Locale.Tr "repo.editor.commit_changes"}}
</h3>
<div class="field">
<input name="commit_summary" maxlength="100" placeholder="Delete {{.TreePath}}" value="Delete {{.TreePath}}" autofocus>
</div>
<div class="field">
<textarea name="commit_message" placeholder="{{ctx.Locale.Tr "repo.editor.commit_message_desc"}}" rows="5"></textarea>
</div>
<div class="inline field">
<div class="ui checkbox">
<input name="signoff" type="checkbox">
<label>{{ctx.Locale.Tr "repo.editor.signoff_desc"}}</label>
</div>
</div>
<div class="quick-pull-choice">
<div class="field">
<div class="ui radio checkbox">
<input type="radio" name="commit_choice" value="direct" checked>
<label>
{{svg "octicon-git-commit"}}
{{ctx.Locale.Tr "repo.editor.commit_directly_to_this_branch" .BranchName}}
</label>
</div>
</div>
{{if not .Repository.IsEmpty}}
<div class="field">
<div class="ui radio checkbox">
<input type="radio" name="commit_choice" value="commit-to-new-branch">
<label>
{{svg "octicon-git-pull-request"}}
{{ctx.Locale.Tr "repo.editor.create_new_branch_np"}}
</label>
</div>
</div>
<div class="quick-pull-branch-name tw-hidden">
<div class="new-branch-name-input field">
{{svg "octicon-git-branch"}}
<input type="text" name="new_branch_name" maxlength="100" value="{{.new_branch_name}}" class="input-contrast tw-mr-1" placeholder="{{ctx.Locale.Tr "repo.editor.new_branch_name_desc"}}" title="{{ctx.Locale.Tr "repo.editor.new_branch_name"}}">
<span class="text-muted"></span>
</div>
</div>
{{end}}
</div>
</div>
</div>
<div class="tw-text-right tw-mt-4">
<button type="button" class="ui button" onclick="$('#delete-file-modal').modal('hide')">{{ctx.Locale.Tr "cancel"}}</button>
<button type="submit" class="ui red button">
{{svg "octicon-trash" 16}}
{{ctx.Locale.Tr "repo.editor.delete_this_file"}}
</button>
</div>
</form>
</div>
</div>
{{end}}
</div>

View File

@ -65,6 +65,7 @@
@import "./repo/file-view.css";
@import "./repo/file-actions.css";
@import "./repo/editor-commit.css";
@import "./repo/delete-file.css";
@import "./repo/wiki.css";
@import "./repo/header.css";
@import "./repo/home.css";

View File

@ -0,0 +1,92 @@
/* Delete file modal styling */
#delete-file-modal {
max-width: 680px;
}
#delete-file-modal .content {
padding: 1.5rem;
}
#delete-file-modal .commit-form-wrapper {
padding-left: 48px;
position: relative;
}
#delete-file-modal .commit-form-wrapper .commit-avatar {
float: left;
margin-left: -48px;
}
#delete-file-modal .commit-form-wrapper .commit-form {
position: relative;
padding: 15px;
border: 1px solid var(--color-secondary);
border-radius: var(--border-radius);
background-color: var(--color-box-body);
}
#delete-file-modal .commit-form h3 {
margin-top: 0;
margin-bottom: 1rem;
}
#delete-file-modal .commit-form .field {
margin-bottom: 1rem;
}
#delete-file-modal .commit-form input[name="commit_summary"] {
width: 100%;
padding: 10px 12px;
font-size: 14px;
}
#delete-file-modal .commit-form textarea[name="commit_message"] {
width: 100%;
padding: 10px 12px;
font-size: 14px;
}
#delete-file-modal .quick-pull-choice .field {
margin-bottom: 0.75rem;
}
#delete-file-modal .commit-form-wrapper .commit-form .quick-pull-choice .new-branch-name-input {
position: relative;
margin-left: 25px;
}
#delete-file-modal .commit-form-wrapper .commit-form .quick-pull-choice .new-branch-name-input input {
width: 240px !important;
padding-left: 26px !important;
}
#delete-file-modal .commit-form-wrapper .commit-form .quick-pull-choice .octicon-git-branch {
position: absolute;
top: 9px;
left: 8px;
}
/* Arrow pointing to avatar */
#delete-file-modal .avatar-content-left-arrow::before,
#delete-file-modal .avatar-content-left-arrow::after {
right: 100%;
top: 20px;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
#delete-file-modal .avatar-content-left-arrow::before {
border-right-color: var(--color-secondary);
border-width: 9px;
margin-top: -9px;
}
#delete-file-modal .avatar-content-left-arrow::after {
border-right-color: var(--color-box-body);
border-width: 8px;
margin-top: -8px;
}

View File

@ -0,0 +1,42 @@
import $ from 'jquery';
export function initRepoDeleteFile() {
const deleteButton = document.querySelector('#delete-file-button');
const deleteModal = document.querySelector('#delete-file-modal');
const deleteForm = document.querySelector<HTMLFormElement>('#delete-file-form');
if (!deleteButton || !deleteModal || !deleteForm) {
return;
}
deleteButton.addEventListener('click', (e) => {
e.preventDefault();
$(deleteModal).modal('show');
});
// Handle form submission
deleteForm.addEventListener('submit', () => {
$(deleteModal).modal('hide');
});
// Handle commit choice radio buttons
const commitChoiceRadios = deleteForm.querySelectorAll<HTMLInputElement>('input[name="commit_choice"]');
const newBranchNameContainer = deleteForm.querySelector('.quick-pull-branch-name');
const newBranchNameInput = deleteForm.querySelector<HTMLInputElement>('input[name="new_branch_name"]');
for (const radio of commitChoiceRadios) {
radio.addEventListener('change', () => {
if (radio.value === 'commit-to-new-branch') {
newBranchNameContainer?.classList.remove('tw-hidden');
if (newBranchNameInput) {
newBranchNameInput.required = true;
}
} else {
newBranchNameContainer?.classList.add('tw-hidden');
if (newBranchNameInput) {
newBranchNameInput.required = false;
}
}
});
}
}

View File

@ -35,6 +35,7 @@ import {initUserAuthWebAuthn, initUserAuthWebAuthnRegister} from './features/use
import {initRepoRelease, initRepoReleaseNew} from './features/repo-release.ts';
import {initRepoEditor} from './features/repo-editor.ts';
import {initRepoEditorCommit} from './features/repo-editor-commit.ts';
import {initRepoDeleteFile} from './features/repo-delete-file.ts';
import {initCompSearchUserBox} from './features/comp/SearchUserBox.ts';
import {initInstall} from './features/install.ts';
import {initCompWebHookEditor} from './features/comp/WebHookEditor.ts';
@ -125,6 +126,7 @@ const initPerformanceTracer = callInitFunctions([
initRepoDiffCommitBranchesAndTags,
initRepoEditor,
initRepoEditorCommit,
initRepoDeleteFile,
initRepoGraphGit,
initRepoIssueContentHistory,
initRepoIssueList,