Merge branch 'main' into add-file-tree-to-file-view-page

This commit is contained in:
Kerwin Bryant authored and GitHub committed 2025-01-03 13:52:57 +08:00
commit b1b24282ae
266 files changed
+4462 -3471

No files matched your search

+3 -23
View File
@@ -742,15 +742,10 @@ input:-webkit-autofill:active,
font-family: var(--fonts-monospace);
font-size: 13px;
font-weight: var(--font-weight-normal);
margin: 0 6px;
padding: 5px 10px;
padding: 3px 5px;
flex-shrink: 0;
}
.ui .sha.label .shortsha {
display: inline-block; /* not sure whether it is still needed */
}
.ui .button.truncate {
display: inline-block;
max-width: 100%;
@@ -933,7 +928,8 @@ strong.attention-caution, svg.attention-caution {
color: var(--color-red-dark-1);
}
.center:not(.popup) {
/* FIXME: this is a longstanding dirty patch since 2015, it only makes the pages more messy and shouldn't be used */
.center {
text-align: center;
}
@@ -989,22 +985,6 @@ overflow-menu .ui.label {
margin-top: 3em !important;
}
/* multiple radio or checkboxes as inline element */
.inline-grouped-list {
display: inline-block;
vertical-align: top;
}
.inline-grouped-list > .ui {
display: block;
margin-top: 5px;
margin-bottom: 10px;
}
.inline-grouped-list > .ui:first-child {
margin-top: 1px;
}
.lines-blame-btn {
padding: 0 0 0 5px;
display: flex;
+1 -19
View File
@@ -1,13 +1,4 @@
.explore .secondary-nav {
border-width: 1px !important;
}
.explore .secondary-nav .svg {
width: 16px;
text-align: center;
margin-right: 5px;
}
/* FIXME: need to refactor the repo branches list page and move these styles to proper place */
.ui.repository.branches .info {
font-size: 12px;
color: var(--color-text-light);
@@ -20,12 +11,3 @@
overflow: hidden;
text-overflow: ellipsis;
}
.ui.repository.branches .overflow-visible {
overflow: visible;
}
/* fix alignment of PR popup in branches table */
.ui.repository.branches table .ui.popup {
text-align: left;
}
+6 -11
View File
@@ -57,6 +57,12 @@
white-space: nowrap;
display: flex;
align-items: center;
gap: 0.25em;
}
#git-graph-container li .ui.label.commit-id-short {
padding-top: 2px;
padding-bottom: 2px;
}
#git-graph-container li .node-relation {
@@ -112,17 +118,6 @@
text-overflow: ellipsis;
}
#git-graph-container #rev-list .sha.label {
padding-top: 5px;
padding-bottom: 3px;
}
#git-graph-container #rev-list .sha.label .ui.detail.icon.button {
padding-top: 3px;
margin-top: -5px;
padding-bottom: 1px;
}
#git-graph-container #graph-raw-list {
margin: 0;
}
+27 -329
View File
@@ -38,11 +38,6 @@ textarea,
color: var(--color-input-text);
}
/* fix fomantic small dropdown having inconsistent padding with input */
.ui.small.selection.dropdown {
padding: .67857143em 1.6em .67857143em 1em;
}
input:hover,
textarea:hover,
.ui.input input:hover,
@@ -109,9 +104,8 @@ textarea:focus,
color: var(--color-input-text);
}
/* match <select> padding to <input> */
.ui.form select {
padding: 0.67857143em 1em;
.ui.form .field > .selection.dropdown {
min-width: 14em; /* matches the default min width */
}
.form .help {
@@ -120,47 +114,6 @@ textarea:focus,
display: inline-block;
}
#create-page-form form {
margin: auto;
}
#create-page-form form .ui.message {
text-align: center;
}
@media (min-width: 768px) {
#create-page-form form {
width: 800px !important;
}
#create-page-form form .header {
padding-left: 280px !important;
}
#create-page-form form .inline.field > label {
text-align: right;
width: 250px !important;
word-wrap: break-word;
}
#create-page-form form .help {
margin-left: 265px !important;
}
#create-page-form form .optional .title {
margin-left: 250px !important;
}
#create-page-form form .inline.field > input,
#create-page-form form .inline.field > textarea {
width: 50%;
}
}
@media (max-width: 767.98px) {
#create-page-form form .optional .title {
margin-left: 15px;
}
#create-page-form form .inline.field > label {
display: block;
}
}
.m-captcha-style {
width: 100%;
height: 5em;
@@ -187,7 +140,7 @@ textarea:focus,
}
@media (max-height: 575px) {
#rc-imageselect,
#rc-imageselect, /* google recaptcha */
.g-recaptcha-style,
.h-captcha-style {
transform: scale(0.77);
@@ -195,295 +148,40 @@ textarea:focus,
}
}
.user.forgot.password form,
.user.reset.password form,
.user.signup form {
margin: auto;
width: 700px !important;
}
.user.activate form .ui.message,
.user.forgot.password form .ui.message,
.user.reset.password form .ui.message,
.user.link-account form .ui.message,
.user.signin form .ui.message,
.user.signup form .ui.message {
text-align: center;
}
@media (min-width: 768px) {
.user.activate form,
.user.forgot.password form,
.user.reset.password form,
.user.link-account form,
.user.signin form,
.user.signup form {
width: 800px !important;
}
.user.activate form .header,
.user.forgot.password form .header,
.user.reset.password form .header,
.user.link-account form .header,
.user.signin form .header,
.user.signup form .header {
padding-left: 280px !important;
}
.user.activate form .inline.field > label {
text-align: right;
width: 250px !important;
word-wrap: break-word;
}
.user.activate form .help,
.user.forgot.password form .help,
.user.reset.password form .help,
.user.link-account form .help,
.user.signin form .help,
.user.signup form .help {
margin-left: 265px !important;
}
.user.activate form .optional .title,
.user.forgot.password form .optional .title,
.user.reset.password form .optional .title,
.user.link-account form .optional .title,
.user.signin form .optional .title,
.user.signup form .optional .title {
margin-left: 250px !important;
}
}
@media (max-width: 767.98px) {
.user.activate form .optional .title,
.user.forgot.password form .optional .title,
.user.reset.password form .optional .title,
.user.link-account form .optional .title,
.user.signin form .optional .title,
.user.signup form .optional .title {
margin-left: 15px;
}
.user.activate form .inline.field > label,
.user.forgot.password form .inline.field > label,
.user.reset.password form .inline.field > label,
.user.link-account form .inline.field > label,
.user.signin form .inline.field > label,
.user.signup form .inline.field > label {
display: block;
}
}
.user.activate form .header,
.user.forgot.password form .header,
.user.reset.password form .header,
.user.link-account form .header,
.user.signin form .header,
.user.signup form .header {
padding-left: 0 !important;
text-align: center;
}
.user.activate form .inline.field > label,
.user.forgot.password form .inline.field > label,
.user.reset.password form .inline.field > label,
.user.link-account form .inline.field > label,
.user.signin form .inline.field > label,
.user.signup form .inline.field > label {
width: 200px;
}
@media (max-width: 767.98px) {
.user.activate form .inline.field > label,
.user.forgot.password form .inline.field > label,
.user.reset.password form .inline.field > label,
.user.link-account form .inline.field > label,
.user.signin form .inline.field > label,
.user.signup form .inline.field > label {
width: 100% !important;
}
}
.user.activate form input[type="number"],
.user.forgot.password form input[type="number"],
.user.reset.password form input[type="number"],
.user.link-account form input[type="number"],
.user.signin form input[type="number"],
.user.signup form input[type="number"] {
-moz-appearance: textfield;
}
.user.activate form input::-webkit-outer-spin-button,
.user.forgot.password form input::-webkit-outer-spin-button,
.user.reset.password form input::-webkit-outer-spin-button,
.user.link-account form input::-webkit-outer-spin-button,
.user.signin form input::-webkit-outer-spin-button,
.user.signup form input::-webkit-outer-spin-button,
.user.activate form input::-webkit-inner-spin-button,
.user.forgot.password form input::-webkit-inner-spin-button,
.user.reset.password form input::-webkit-inner-spin-button,
.user.link-account form input::-webkit-inner-spin-button,
.user.signin form input::-webkit-inner-spin-button,
.user.signup form input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
.repository.new.repo form,
.repository.new.migrate form,
.repository.new.fork form {
margin: auto;
}
.repository.new.repo form .ui.message,
.repository.new.migrate form .ui.message,
.repository.new.fork form .ui.message {
text-align: center;
}
@media (min-width: 768px) {
.repository.new.repo form,
.repository.new.migrate form,
.repository.new.fork form {
width: 800px !important;
}
.repository.new.repo form .header,
.repository.new.migrate form .header,
.repository.new.fork form .header {
padding-left: 280px !important;
}
.repository.new.repo form .inline.field > label,
.repository.new.migrate form .inline.field > label,
.repository.new.fork form .inline.field > label {
text-align: right;
width: 250px !important;
word-wrap: break-word;
}
.repository.new.repo form .help,
.repository.new.migrate form .help,
.repository.new.fork form .help {
margin-left: 265px !important;
}
.repository.new.repo form .optional .title,
.repository.new.migrate form .optional .title,
.repository.new.fork form .optional .title {
margin-left: 250px !important;
}
.repository.new.repo form .inline.field > input,
.repository.new.migrate form .inline.field > input,
.repository.new.fork form .inline.field > input,
.repository.new.repo form .inline.field > textarea,
.repository.new.migrate form .inline.field > textarea,
.repository.new.fork form .inline.field > textarea {
width: 50%;
}
}
@media (max-width: 767.98px) {
.repository.new.repo form .optional .title,
.repository.new.migrate form .optional .title,
.repository.new.fork form .optional .title {
margin-left: 15px;
}
.repository.new.repo form .inline.field > label,
.repository.new.migrate form .inline.field > label,
.repository.new.fork form .inline.field > label {
display: block;
}
}
.repository.new.repo form .dropdown .text,
.repository.new.migrate form .dropdown .text,
.repository.new.fork form .dropdown .text {
margin-right: 0 !important;
}
.repository.new.repo form .header,
.repository.new.migrate form .header,
.repository.new.fork form .header {
padding-left: 0 !important;
text-align: center;
}
.repository.new.repo form .selection.dropdown,
.repository.new.migrate form .selection.dropdown,
.repository.new.fork form .selection.dropdown,
.repository.new.fork form .field a {
vertical-align: middle;
width: 50% !important;
}
@media (max-width: 767.98px) {
.repository.new.repo form label,
.repository.new.migrate form label,
.repository.new.fork form label,
.repository.new.repo form .inline.field > input,
.repository.new.migrate form .inline.field > input,
.repository.new.fork form .inline.field > input,
.repository.new.fork form .field a,
.repository.new.repo form .selection.dropdown,
.repository.new.migrate form .selection.dropdown,
.repository.new.fork form .selection.dropdown {
width: 100% !important;
}
.repository.new.repo form .field button,
.repository.new.migrate form .field button,
.repository.new.fork form .field button,
.repository.new.repo form .field a,
.repository.new.migrate form .field a {
margin-bottom: 1em;
width: 100%;
}
}
@media (min-width: 768px) {
.repository.new.repo .ui.form #auto-init {
margin-left: 265px !important;
}
}
.repository.new.repo .ui.form .selection.dropdown:not(.owner) {
width: 50% !important;
}
@media (max-width: 767.98px) {
.repository.new.repo .ui.form .selection.dropdown:not(.owner) {
width: 100% !important;
}
}
/* form fields with additional content besides their label, used on login form
* use like <div class="field"><label/><a/><input/></div> */
.form-field-content-aside-label {
display: grid;
grid-template-columns: 1fr 1fr;
}
.form-field-content-aside-label > *:nth-child(2) {
.ui.form.left-right-form .inline.field > label {
text-align: right;
}
.form-field-content-aside-label input {
grid-column: span 2;
width: 250px;
margin-right: 10px;
}
.ui.form .field > .selection.dropdown {
min-width: 14em; /* matches the default min width */
.ui.form.left-right-form .inline.field > .help {
margin-left: calc(250px + 15px);
}
.new.webhook form .help {
margin-left: 25px;
.ui.form.left-right-form .inline.field input:not([type="checkbox"], [type="radio"]),
.ui.form.left-right-form .inline.field .ui.dropdown,
.ui.form.left-right-form .inline.field textarea {
width: 50%;
}
.new.webhook .events.fields .column {
padding-left: 40px;
}
.githook textarea {
font-family: var(--fonts-monospace);
.ui.form.left-right-form .inline.field .inline-right {
display: inline-flex;
flex-direction: column;
gap: 0.5em;
}
@media (max-width: 767.98px) {
.new.org .ui.form .field button,
.new.org .ui.form .field a {
margin-bottom: 1em;
.ui.form.left-right-form .inline.field > label {
width: 100%;
margin: 0;
text-align: left;
}
.ui.form.left-right-form .inline.field > .help {
margin: 0;
}
.ui.form.left-right-form .inline.field input:not([type="checkbox"], [type="radio"]),
.ui.form.left-right-form .inline.field .ui.dropdown,
.ui.form.left-right-form .inline.field textarea {
width: 100%;
}
.new.org .ui.form .field input {
width: 100% !important;
}
}
+2 -1
View File
@@ -82,5 +82,6 @@
@import "./review.css";
@import "./actions.css";
@tailwind utilities;
@import "./helpers.css";
@tailwind utilities;
+2 -2
View File
@@ -103,11 +103,11 @@
#navbar .ui.dropdown .navbar-profile-admin {
display: block;
position: absolute;
font-size: 10px;
font-size: 9px;
font-weight: var(--font-weight-bold);
color: var(--color-nav-bg);
background: var(--color-primary);
padding: 2px 4px;
padding: 2px 3px;
border-radius: 10px;
top: -1px;
left: 18px;
-87
View File
@@ -1,94 +1,7 @@
#create-page-form form {
margin: auto;
}
#create-page-form form .ui.message {
text-align: center;
}
@media (min-width: 768px) {
#create-page-form form {
width: 800px !important;
}
#create-page-form form .header {
padding-left: 280px !important;
}
#create-page-form form .inline.field > label {
text-align: right;
width: 250px !important;
word-wrap: break-word;
}
#create-page-form form .help {
margin-left: 265px !important;
}
#create-page-form form .optional .title {
margin-left: 250px !important;
}
#create-page-form form .inline.field > input,
#create-page-form form .inline.field > textarea {
width: 50%;
}
}
@media (max-width: 767.98px) {
#create-page-form form .optional .title {
margin-left: 15px;
}
#create-page-form form .inline.field > label {
display: block;
}
}
.organization .head .ui.header .ui.right {
margin-top: 5px;
}
.organization.new.org form {
margin: auto;
}
.organization.new.org form .ui.message {
text-align: center;
}
@media (min-width: 768px) {
.organization.new.org form {
width: 800px !important;
}
.organization.new.org form .header {
padding-left: 280px !important;
}
.organization.new.org form .inline.field > label {
text-align: right;
width: 250px !important;
word-wrap: break-word;
}
.organization.new.org form .help {
margin-left: 265px !important;
}
.organization.new.org form .optional .title {
margin-left: 250px !important;
}
.organization.new.org form .inline.field > input,
.organization.new.org form .inline.field > textarea {
width: 50%;
}
}
@media (max-width: 767.98px) {
.organization.new.org form .optional .title {
margin-left: 15px;
}
.organization.new.org form .inline.field > label {
display: block;
}
}
.organization.new.org form .header {
padding-left: 0 !important;
text-align: center;
}
.page-content.organization .org-avatar {
margin-right: 15px;
}
+7 -49
View File
@@ -120,15 +120,13 @@ td .commit-summary {
align-items: center;
overflow: hidden;
text-overflow: ellipsis;
gap: 0.25em;
}
@media (max-width: 767.98px) {
.latest-commit .sha {
.latest-commit .commit-id-short {
display: none;
}
.latest-commit .commit-summary {
margin-left: 8px;
}
}
.repo-path {
@@ -605,15 +603,6 @@ td .commit-summary {
margin-right: 0.25em;
}
.singular-commit {
display: flex;
align-items: center;
}
.singular-commit .badge {
height: 30px !important;
}
.repository.view.issue .comment-list .timeline-item.event > .commit-status-link {
float: right;
margin-right: 8px;
@@ -836,10 +825,6 @@ td .commit-summary {
height: 10px;
}
.repository.compare.pull .show-form-container {
text-align: left;
}
.repository .choose.branch {
display: flex;
align-items: center;
@@ -877,11 +862,6 @@ td .commit-summary {
margin-top: -8px;
}
.repository.compare.pull .pullrequest-form {
margin-top: 16px;
margin-bottom: 16px;
}
.repository.compare.pull .markup {
font-size: 14px;
}
@@ -936,14 +916,6 @@ td .commit-summary {
width: 200px;
}
.repository #commits-table thead .shatd {
text-align: center;
}
.repository #commits-table td.sha .sha.label {
margin: 0;
}
.repository #commits-table.ui.basic.striped.table tbody tr:nth-child(2n) {
background-color: var(--color-light) !important;
}
@@ -1440,12 +1412,6 @@ td .commit-summary {
padding-top: 15px;
}
.commit-header-row {
min-height: 50px !important;
padding-top: 0 !important;
padding-bottom: 0 !important;
}
.commit-header-buttons {
display: flex;
gap: 4px;
@@ -1622,7 +1588,7 @@ td .commit-summary {
align-items: center;
}
.labels-list .label {
.labels-list .label, .scope-parent > .label {
padding: 0 6px;
min-height: 20px;
line-height: 1.3; /* there is a `font-size: 1.25em` for inside emoji, so here the line-height needs to be larger slightly */
@@ -1701,6 +1667,10 @@ tbody.commit-list {
white-space: nowrap;
}
.latest-commit .message-wrapper {
max-width: calc(100% - 2.5rem);
}
/* in the commit list, messages can wrap so we can use inline */
.commit-list .message-wrapper {
display: inline;
@@ -2128,18 +2098,6 @@ tbody.commit-list {
.repository.view.issue .comment-list .timeline .comment-header-right .role-label {
display: none;
}
.commit-header-row .ui.horizontal.list {
width: 100%;
overflow-x: auto;
margin-top: 2px;
}
.commit-header-row .ui.horizontal.list .item {
align-items: center;
display: flex;
}
.commit-header-row .author {
padding: 3px 0;
}
.commit-header h3 {
flex-basis: auto !important;
margin-bottom: 0.5rem !important;
+36 -248
View File
@@ -1,272 +1,60 @@
.repository .ui.attached.isSigned.isWarning {
border-left: 1px solid var(--color-error-border);
border-right: 1px solid var(--color-error-border);
}
.repository .ui.attached.isSigned.isWarning.top,
.repository .ui.attached.isSigned.isWarning.message {
border-top: 1px solid var(--color-error-border);
}
.repository .ui.attached.isSigned.isWarning.message {
box-shadow: none;
background-color: var(--color-error-bg);
color: var(--color-error-text);
}
.repository .ui.attached.isSigned.isWarning.message .ui.text {
color: var(--color-error-text);
}
.repository .ui.attached.isSigned.isWarning:last-child,
.repository .ui.attached.isSigned.isWarning.bottom {
border-bottom: 1px solid var(--color-error-border);
}
.repository .ui.attached.isSigned.isVerified {
border-left: 1px solid var(--color-success-border);
border-right: 1px solid var(--color-success-border);
}
.repository .ui.attached.isSigned.isVerified.top,
.repository .ui.attached.isSigned.isVerified.message {
border-top: 1px solid var(--color-success-border);
}
.repository .ui.attached.isSigned.isVerified.message {
box-shadow: none;
background-color: var(--color-success-bg);
color: var(--color-success-text);
}
.repository .ui.attached.isSigned.isVerified.message .pull-right {
color: var(--color-text);
}
.repository .ui.attached.isSigned.isVerified.message .ui.text {
color: var(--color-success-text);
}
.repository .ui.attached.isSigned.isVerified:last-child,
.repository .ui.attached.isSigned.isVerified.bottom {
border-bottom: 1px solid var(--color-success-border);
}
.repository .ui.attached.isSigned.isVerifiedUntrusted,
.repository .ui.attached.isSigned.isVerifiedUnmatched {
border-left: 1px solid var(--color-warning-border);
border-right: 1px solid var(--color-warning-border);
}
.repository .ui.attached.isSigned.isVerifiedUntrusted.top,
.repository .ui.attached.isSigned.isVerifiedUnmatched.top,
.repository .ui.attached.isSigned.isVerifiedUntrusted.message,
.repository .ui.attached.isSigned.isVerifiedUnmatched.message {
border-top: 1px solid var(--color-warning-border);
}
.repository .ui.attached.isSigned.isVerifiedUntrusted.message,
.repository .ui.attached.isSigned.isVerifiedUnmatched.message {
box-shadow: none;
background-color: var(--color-warning-bg);
color: var(--color-warning-text);
}
.repository .ui.attached.isSigned.isVerifiedUntrusted.message .ui.text,
.repository .ui.attached.isSigned.isVerifiedUnmatched.message .ui.text {
color: var(--color-warning-text);
}
.repository .ui.attached.isSigned.isVerifiedUntrusted:last-child,
.repository .ui.attached.isSigned.isVerifiedUnmatched:last-child,
.repository .ui.attached.isSigned.isVerifiedUntrusted.bottom,
.repository .ui.attached.isSigned.isVerifiedUnmatched.bottom {
border-bottom: 1px solid var(--color-warning-border);
}
.repository #commits-table td.sha .sha.label,
.repository #repo-files-table .sha.label,
.repository #repo-file-commit-box .sha.label,
.repository #rev-list .sha.label,
.repository .timeline-item.commits-list .singular-commit .sha.label {
.ui.label.commit-id-short,
.ui.label.commit-sign-badge {
border: 1px solid var(--color-light-border);
font-size: 13px;
font-weight: var(--font-weight-normal);
padding: 3px 5px;
flex-shrink: 0;
}
.repository #commits-table td.sha .sha.label .detail.icon,
.repository #repo-files-table .sha.label .detail.icon,
.repository #repo-file-commit-box .sha.label .detail.icon,
.repository #rev-list .sha.label .detail.icon,
.repository .timeline-item.commits-list .singular-commit .sha.label .detail.icon {
background: var(--color-light);
margin: -6px -10px -4px 0;
padding: 5px 4px 5px 6px;
border-left: 1px solid var(--color-light-border);
border-top: 0;
border-right: 0;
border-bottom: 0;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
.ui.label.commit-id-short {
font-family: var(--fonts-monospace);
}
.repository #commits-table td.sha .sha.label .detail.icon .svg,
.repository #repo-files-table .sha.label .detail.icon .svg,
.repository #repo-file-commit-box .sha.label .detail.icon .svg,
.repository #rev-list .sha.label .detail.icon .svg,
.repository .timeline-item.commits-list .singular-commit .sha.label .detail.icon .svg {
margin: 0 0.25em 0 0;
}
.repository #commits-table td.sha .sha.label .detail.icon > div,
.repository #repo-files-table .sha.label .detail.icon > div,
.repository #repo-file-commit-box .sha.label .detail.icon > div,
.repository #rev-list .sha.label .detail.icon > div,
.repository .timeline-item.commits-list .singular-commit .sha.label .detail.icon > div {
display: flex;
align-items: center;
}
.repository #commits-table td.sha .sha.label.isSigned.isWarning,
.repository #repo-files-table .sha.label.isSigned.isWarning,
.repository #repo-file-commit-box .sha.label.isSigned.isWarning,
.repository #rev-list .sha.label.isSigned.isWarning,
.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isWarning {
border: 1px solid var(--color-red-badge);
background: var(--color-red-badge-bg);
}
.repository #commits-table td.sha .sha.label.isSigned.isWarning .detail.icon,
.repository #repo-files-table .sha.label.isSigned.isWarning .detail.icon,
.repository #repo-file-commit-box .sha.label.isSigned.isWarning .detail.icon,
.repository #rev-list .sha.label.isSigned.isWarning .detail.icon,
.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isWarning .detail.icon {
border-left: 1px solid var(--color-red-badge);
color: var(--color-red-badge);
}
.repository #commits-table td.sha .sha.label.isSigned.isWarning:hover,
.repository #repo-files-table .sha.label.isSigned.isWarning:hover,
.repository #repo-file-commit-box .sha.label.isSigned.isWarning:hover,
.repository #rev-list .sha.label.isSigned.isWarning:hover,
.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isWarning:hover {
background: var(--color-red-badge-hover-bg) !important;
}
.repository #commits-table td.sha .sha.label.isSigned.isVerified,
.repository #repo-files-table .sha.label.isSigned.isVerified,
.repository #repo-file-commit-box .sha.label.isSigned.isVerified,
.repository #rev-list .sha.label.isSigned.isVerified,
.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerified {
border: 1px solid var(--color-green-badge);
background: var(--color-green-badge-bg);
}
.repository #commits-table td.sha .sha.label.isSigned.isVerified .detail.icon,
.repository #repo-files-table .sha.label.isSigned.isVerified .detail.icon,
.repository #repo-file-commit-box .sha.label.isSigned.isVerified .detail.icon,
.repository #rev-list .sha.label.isSigned.isVerified .detail.icon,
.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerified .detail.icon {
border-left: 1px solid var(--color-green-badge);
color: var(--color-green-badge);
}
.repository #commits-table td.sha .sha.label.isSigned.isVerified:hover,
.repository #repo-files-table .sha.label.isSigned.isVerified:hover,
.repository #repo-file-commit-box .sha.label.isSigned.isVerified:hover,
.repository #rev-list .sha.label.isSigned.isVerified:hover,
.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerified:hover {
background: var(--color-green-badge-hover-bg) !important;
}
.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUntrusted,
.repository #repo-files-table .sha.label.isSigned.isVerifiedUntrusted,
.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUntrusted,
.repository #rev-list .sha.label.isSigned.isVerifiedUntrusted,
.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUntrusted {
border: 1px solid var(--color-yellow-badge);
background: var(--color-yellow-badge-bg);
}
.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUntrusted .detail.icon,
.repository #repo-files-table .sha.label.isSigned.isVerifiedUntrusted .detail.icon,
.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUntrusted .detail.icon,
.repository #rev-list .sha.label.isSigned.isVerifiedUntrusted .detail.icon,
.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUntrusted .detail.icon {
border-left: 1px solid var(--color-yellow-badge);
color: var(--color-yellow-badge);
}
.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUntrusted:hover,
.repository #repo-files-table .sha.label.isSigned.isVerifiedUntrusted:hover,
.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUntrusted:hover,
.repository #rev-list .sha.label.isSigned.isVerifiedUntrusted:hover,
.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUntrusted:hover {
background: var(--color-yellow-badge-hover-bg) !important;
}
.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUnmatched,
.repository #repo-files-table .sha.label.isSigned.isVerifiedUnmatched,
.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUnmatched,
.repository #rev-list .sha.label.isSigned.isVerifiedUnmatched,
.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUnmatched {
border: 1px solid var(--color-orange-badge);
background: var(--color-orange-badge-bg);
}
.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUnmatched .detail.icon,
.repository #repo-files-table .sha.label.isSigned.isVerifiedUnmatched .detail.icon,
.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUnmatched .detail.icon,
.repository #rev-list .sha.label.isSigned.isVerifiedUnmatched .detail.icon,
.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUnmatched .detail.icon {
border-left: 1px solid var(--color-orange-badge);
color: var(--color-orange-badge);
}
.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUnmatched:hover,
.repository #repo-files-table .sha.label.isSigned.isVerifiedUnmatched:hover,
.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUnmatched:hover,
.repository #rev-list .sha.label.isSigned.isVerifiedUnmatched:hover,
.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUnmatched:hover {
background: var(--color-orange-badge-hover-bg) !important;
}
.singular-commit .shabox .sha.label {
.ui.label.commit-id-short > .commit-sign-badge {
margin: 0;
border: 1px solid var(--color-light-border);
padding: 0;
border: 0 !important;
border-radius: 0;
background: transparent;
}
.singular-commit .shabox .sha.label.isSigned.isWarning {
border: 1px solid var(--color-red-badge);
background: var(--color-red-badge-bg);
.ui.label.commit-id-short > .commit-sign-badge:hover {
background: transparent !important;
}
.singular-commit .shabox .sha.label.isSigned.isWarning:hover {
background: var(--color-red-badge-hover-bg) !important;
.commit-is-signed.sign-trusted {
border: 1px solid var(--color-green-badge) !important;
background: var(--color-green-badge-bg) !important;
}
.singular-commit .shabox .sha.label.isSigned.isVerified {
border: 1px solid var(--color-green-badge);
background: var(--color-green-badge-bg);
}
.singular-commit .shabox .sha.label.isSigned.isVerified:hover {
.commit-is-signed.sign-trusted:hover {
background: var(--color-green-badge-hover-bg) !important;
}
.singular-commit .shabox .sha.label.isSigned.isVerifiedUntrusted {
border: 1px solid var(--color-yellow-badge);
background: var(--color-yellow-badge-bg);
.commit-is-signed.sign-untrusted {
border: 1px solid var(--color-yellow-badge) !important;
background: var(--color-yellow-badge-bg) !important;
}
.singular-commit .shabox .sha.label.isSigned.isVerifiedUntrusted:hover {
.commit-is-signed.sign-untrusted:hover {
background: var(--color-yellow-badge-hover-bg) !important;
}
.singular-commit .shabox .sha.label.isSigned.isVerifiedUnmatched {
border: 1px solid var(--color-orange-badge);
background: var(--color-orange-badge-bg);
.commit-is-signed.sign-unmatched {
border: 1px solid var(--color-orange-badge) !important;
background: var(--color-orange-badge-bg) !important;
}
.singular-commit .shabox .sha.label.isSigned.isVerifiedUnmatched:hover {
.commit-is-signed.sign-unmatched:hover {
background: var(--color-orange-badge-hover-bg) !important;
}
.commit-is-signed.sign-warning {
border: 1px solid var(--color-red-badge) !important;
background: var(--color-red-badge-bg) !important;
}
.commit-is-signed.sign-warning:hover {
background: var(--color-red-badge-hover-bg) !important;
}
@@ -147,7 +147,7 @@ function clearMergeMessage() {
</template>
</span>
</button>
<div class="ui dropdown icon button" @click.stop="showMergeStyleMenu = !showMergeStyleMenu" v-if="mergeStyleAllowedCount>1">
<div class="ui dropdown icon button" @click.stop="showMergeStyleMenu = !showMergeStyleMenu">
<svg-icon name="octicon-triangle-down" :size="14"/>
<div class="menu" :class="{'show':showMergeStyleMenu}">
<template v-for="msd in mergeForm.mergeStyles">
+2
View File
@@ -38,6 +38,8 @@ function initRepoDiffFileViewToggle() {
}
function initRepoDiffConversationForm() {
// FIXME: there could be various different form in a conversation-holder (for example: reply form, edit form).
// This listener is for "reply form" only, it should clearly distinguish different forms in the future.
addDelegatedEventListener<HTMLFormElement, SubmitEvent>(document, 'submit', '.conversation-holder form', async (form, e) => {
e.preventDefault();
const textArea = form.querySelector<HTMLTextAreaElement>('textarea');
+36 -33
View File
@@ -1,20 +1,17 @@
import $ from 'jquery';
import {svg} from '../svg.ts';
import {showErrorToast} from '../modules/toast.ts';
import {GET, POST} from '../modules/fetch.ts';
import {showElem} from '../utils/dom.ts';
import {createElementFromHTML, showElem} from '../utils/dom.ts';
import {parseIssuePageInfo} from '../utils.ts';
import {fomanticQuery} from '../modules/fomantic/base.ts';
let i18nTextEdited;
let i18nTextOptions;
let i18nTextDeleteFromHistory;
let i18nTextDeleteFromHistoryConfirm;
let i18nTextEdited: string;
let i18nTextOptions: string;
let i18nTextDeleteFromHistory: string;
let i18nTextDeleteFromHistoryConfirm: string;
function showContentHistoryDetail(issueBaseUrl, commentId, historyId, itemTitleHtml) {
let $dialog = $('.content-history-detail-dialog');
if ($dialog.length) return;
$dialog = $(`
function showContentHistoryDetail(issueBaseUrl: string, commentId: string, historyId: string, itemTitleHtml: string) {
const elDetailDialog = createElementFromHTML(`
<div class="ui modal content-history-detail-dialog">
${svg('octicon-x', 16, 'close icon inside')}
<div class="header tw-flex tw-items-center tw-justify-between">
@@ -29,8 +26,11 @@ function showContentHistoryDetail(issueBaseUrl, commentId, historyId, itemTitleH
</div>
<div class="comment-diff-data is-loading"></div>
</div>`);
$dialog.appendTo($('body'));
$dialog.find('.dialog-header-options').dropdown({
document.body.append(elDetailDialog);
const elOptionsDropdown = elDetailDialog.querySelector('.ui.dropdown.dialog-header-options');
const $fomanticDialog = fomanticQuery(elDetailDialog);
const $fomanticDropdownOptions = fomanticQuery(elOptionsDropdown);
$fomanticDropdownOptions.dropdown({
showOnFocus: false,
allowReselection: true,
async onChange(_value, _text, $item) {
@@ -46,7 +46,7 @@ function showContentHistoryDetail(issueBaseUrl, commentId, historyId, itemTitleH
const resp = await response.json();
if (resp.ok) {
$dialog.modal('hide');
$fomanticDialog.modal('hide');
} else {
showErrorToast(resp.message);
}
@@ -60,10 +60,10 @@ function showContentHistoryDetail(issueBaseUrl, commentId, historyId, itemTitleH
}
},
onHide() {
$(this).dropdown('clear', true);
$fomanticDropdownOptions.dropdown('clear', true);
},
});
$dialog.modal({
$fomanticDialog.modal({
async onShow() {
try {
const params = new URLSearchParams();
@@ -74,25 +74,25 @@ function showContentHistoryDetail(issueBaseUrl, commentId, historyId, itemTitleH
const response = await GET(url);
const resp = await response.json();
const commentDiffData = $dialog.find('.comment-diff-data')[0];
commentDiffData?.classList.remove('is-loading');
const commentDiffData = elDetailDialog.querySelector('.comment-diff-data');
commentDiffData.classList.remove('is-loading');
commentDiffData.innerHTML = resp.diffHtml;
// there is only one option "item[data-option-item=delete]", so the dropdown can be entirely shown/hidden.
if (resp.canSoftDelete) {
showElem($dialog.find('.dialog-header-options'));
showElem(elOptionsDropdown);
}
} catch (error) {
console.error('Error:', error);
}
},
onHidden() {
$dialog.remove();
$fomanticDialog.remove();
},
}).modal('show');
}
function showContentHistoryMenu(issueBaseUrl, $item, commentId) {
const $headerLeft = $item.find('.comment-header-left');
function showContentHistoryMenu(issueBaseUrl: string, elCommentItem: Element, commentId: string) {
const elHeaderLeft = elCommentItem.querySelector('.comment-header-left');
const menuHtml = `
<div class="ui dropdown interact-fg content-history-menu" data-comment-id="${commentId}">
&bull; ${i18nTextEdited}${svg('octicon-triangle-down', 14, 'dropdown icon')}
@@ -100,9 +100,12 @@ function showContentHistoryMenu(issueBaseUrl, $item, commentId) {
</div>
</div>`;
$headerLeft.find(`.content-history-menu`).remove();
$headerLeft.append($(menuHtml));
$headerLeft.find('.dropdown').dropdown({
elHeaderLeft.querySelector(`.ui.dropdown.content-history-menu`)?.remove(); // remove the old one if exists
elHeaderLeft.append(createElementFromHTML(menuHtml));
const elDropdown = elHeaderLeft.querySelector('.ui.dropdown.content-history-menu');
const $fomanticDropdown = fomanticQuery(elDropdown);
$fomanticDropdown.dropdown({
action: 'hide',
apiSettings: {
cache: false,
@@ -110,7 +113,7 @@ function showContentHistoryMenu(issueBaseUrl, $item, commentId) {
},
saveRemoteData: false,
onHide() {
$(this).dropdown('change values', null);
$fomanticDropdown.dropdown('change values', null);
},
onChange(value, itemHtml, $item) {
if (value && !$item.find('[data-history-is-deleted=1]').length) {
@@ -124,9 +127,9 @@ export async function initRepoIssueContentHistory() {
const issuePageInfo = parseIssuePageInfo();
if (!issuePageInfo.issueNumber) return;
const $itemIssue = $('.repository.issue .timeline-item.comment.first'); // issue(PR) main content
const $comments = $('.repository.issue .comment-list .comment'); // includes: issue(PR) comments, review comments, code comments
if (!$itemIssue.length && !$comments.length) return;
const elIssueDescription = document.querySelector('.repository.issue .timeline-item.comment.first'); // issue(PR) main content
const elComments = document.querySelectorAll('.repository.issue .comment-list .comment'); // includes: issue(PR) comments, review comments, code comments
if (!elIssueDescription && !elComments.length) return;
const issueBaseUrl = `${issuePageInfo.repoLink}/issues/${issuePageInfo.issueNumber}`;
@@ -139,13 +142,13 @@ export async function initRepoIssueContentHistory() {
i18nTextDeleteFromHistoryConfirm = resp.i18n.textDeleteFromHistoryConfirm;
i18nTextOptions = resp.i18n.textOptions;
if (resp.editedHistoryCountMap[0] && $itemIssue.length) {
showContentHistoryMenu(issueBaseUrl, $itemIssue, '0');
if (resp.editedHistoryCountMap[0] && elIssueDescription) {
showContentHistoryMenu(issueBaseUrl, elIssueDescription, '0');
}
for (const [commentId, _editedCount] of Object.entries(resp.editedHistoryCountMap)) {
if (commentId === '0') continue;
const $itemComment = $(`#issuecomment-${commentId}`);
showContentHistoryMenu(issueBaseUrl, $itemComment, commentId);
const elIssueComment = document.querySelector(`#issuecomment-${commentId}`);
if (elIssueComment) showContentHistoryMenu(issueBaseUrl, elIssueComment, commentId);
}
} catch (error) {
console.error('Error:', error);
+3
View File
@@ -30,6 +30,9 @@ async function tryOnEditContent(e) {
const saveAndRefresh = async (e) => {
e.preventDefault();
// we are already in a form, do not bubble up to the document otherwise there will be other "form submit handlers"
// at the moment, the form submit event conflicts with initRepoDiffConversationForm (global '.conversation-holder form' event handler)
e.stopPropagation();
renderContent.classList.add('is-loading');
showElem(renderContent);
hideElem(editContentZone);
+1 -1
View File
@@ -5,7 +5,7 @@ import {initIssueSidebarComboList} from './repo-issue-sidebar-combolist.ts';
function initBranchSelector() {
// TODO: RemoveIssueRef: see "repo/issue/branch_selector_field.tmpl"
const elSelectBranch = document.querySelector('.ui.dropdown.select-branch');
const elSelectBranch = document.querySelector('.ui.dropdown.select-branch.branch-selector-dropdown');
if (!elSelectBranch) return;
const urlUpdateIssueRef = elSelectBranch.getAttribute('data-url-update-issueref');
+13 -61
View File
@@ -1,4 +1,3 @@
import $ from 'jquery';
import {
initRepoCommentFormAndSidebar,
initRepoIssueBranchSelect, initRepoIssueCodeCommentCancel, initRepoIssueCommentDelete,
@@ -15,7 +14,7 @@ import {initCompReactionSelector} from './comp/ReactionSelector.ts';
import {initRepoSettings} from './repo-settings.ts';
import {initRepoPullRequestMergeForm} from './repo-issue-pr-form.ts';
import {initRepoPullRequestCommitStatus} from './repo-issue-pr-status.ts';
import {hideElem, queryElemChildren, showElem} from '../utils/dom.ts';
import {hideElem, queryElemChildren, queryElems, showElem} from '../utils/dom.ts';
import {initRepoIssueCommentEdit} from './repo-issue-edit.ts';
import {initRepoMilestone} from './repo-milestone.ts';
import {initRepoNew} from './repo-new.ts';
@@ -29,47 +28,20 @@ function initRepoBranchTagSelector(selector: string) {
}
export function initBranchSelectorTabs() {
const elSelectBranch = document.querySelector('.ui.dropdown.select-branch');
if (!elSelectBranch) return;
$(elSelectBranch).find('.reference.column').on('click', function () {
hideElem($(elSelectBranch).find('.scrolling.reference-list-menu'));
showElem(this.getAttribute('data-target'));
queryElemChildren(this.parentNode, '.branch-tag-item', (el) => el.classList.remove('active'));
this.classList.add('active');
return false;
});
}
function initRepoCommonBranchOrTagDropdown(selector: string) {
$(selector).each(function () {
const $dropdown = $(this);
$dropdown.find('.reference.column').on('click', function () {
hideElem($dropdown.find('.scrolling.reference-list-menu'));
showElem($($(this).data('target')));
return false;
});
});
}
function initRepoCommonFilterSearchDropdown(selector: string) {
const $dropdown = $(selector);
if (!$dropdown.length) return;
$dropdown.dropdown({
fullTextSearch: 'exact',
selectOnKeydown: false,
onChange(_text, _value, $choice) {
if ($choice[0].getAttribute('data-url')) {
window.location.href = $choice[0].getAttribute('data-url');
}
},
message: {noResults: $dropdown[0].getAttribute('data-no-results')},
});
const elSelectBranches = document.querySelectorAll('.ui.dropdown.select-branch');
for (const elSelectBranch of elSelectBranches) {
queryElems(elSelectBranch, '.reference.column', (el) => el.addEventListener('click', () => {
hideElem(elSelectBranch.querySelectorAll('.scrolling.reference-list-menu'));
showElem(el.getAttribute('data-target'));
queryElemChildren(el.parentNode, '.branch-tag-item', (el) => el.classList.remove('active'));
el.classList.add('active');
}));
}
}
export function initRepository() {
if (!$('.page-content.repository').length) return;
const pageContent = document.querySelector('.page-content.repository');
if (!pageContent) return;
initRepoBranchTagSelector('.js-branch-tag-selector');
initRepoCommentFormAndSidebar();
@@ -79,19 +51,12 @@ export function initRepository() {
initRepoMilestone();
initRepoNew();
// Compare or pull request
const $repoDiff = $('.repository.diff');
if ($repoDiff.length) {
initRepoCommonBranchOrTagDropdown('.choose.branch .dropdown');
initRepoCommonFilterSearchDropdown('.choose.branch .dropdown');
}
initRepoCloneButtons();
initCitationFileCopyContent();
initRepoSettings();
// Issues
if ($('.repository.view.issue').length > 0) {
if (pageContent.matches('.page-content.repository.view.issue')) {
initRepoIssueCommentEdit();
initRepoIssueBranchSelect();
@@ -112,18 +77,5 @@ export function initRepository() {
initRepoPullRequestCommitStatus();
}
// Pull request
const $repoComparePull = $('.repository.compare.pull');
if ($repoComparePull.length > 0) {
// show pull request form
$repoComparePull.find('button.show-form').on('click', function (e) {
e.preventDefault();
hideElem($(this).parent());
const $form = $repoComparePull.find('.pullrequest-form');
showElem($form);
});
}
initUnicodeEscapeButton();
}
+77 -11
View File
@@ -1,14 +1,80 @@
import $ from 'jquery';
import {hideElem, showElem, toggleElem} from '../utils/dom.ts';
import {htmlEscape} from 'escape-goat';
import {fomanticQuery} from '../modules/fomantic/base.ts';
const {appSubUrl} = window.config;
function initRepoNewTemplateSearch(form: HTMLFormElement) {
const inputRepoOwnerUid = form.querySelector<HTMLInputElement>('#uid');
const elRepoTemplateDropdown = form.querySelector<HTMLInputElement>('#repo_template_search');
const inputRepoTemplate = form.querySelector<HTMLInputElement>('#repo_template');
const elTemplateUnits = form.querySelector('#template_units');
const elNonTemplate = form.querySelector('#non_template');
const checkTemplate = function () {
const hasSelectedTemplate = inputRepoTemplate.value !== '' && inputRepoTemplate.value !== '0';
toggleElem(elTemplateUnits, hasSelectedTemplate);
toggleElem(elNonTemplate, !hasSelectedTemplate);
};
inputRepoTemplate.addEventListener('change', checkTemplate);
checkTemplate();
const $dropdown = fomanticQuery(elRepoTemplateDropdown);
const onChangeOwner = function () {
$dropdown.dropdown('setting', {
apiSettings: {
url: `${appSubUrl}/repo/search?q={query}&template=true&priority_owner_id=${inputRepoOwnerUid.value}`,
onResponse(response) {
const results = [];
results.push({name: '', value: ''}); // empty item means not using template
for (const tmplRepo of response.data) {
results.push({
name: htmlEscape(tmplRepo.repository.full_name),
value: String(tmplRepo.repository.id),
});
}
$dropdown.fomanticExt.onResponseKeepSelectedItem($dropdown, inputRepoTemplate.value);
return {results};
},
cache: false,
},
});
};
inputRepoOwnerUid.addEventListener('change', onChangeOwner);
onChangeOwner();
}
export function initRepoNew() {
// Repo Creation
if ($('.repository.new.repo').length > 0) {
$('input[name="gitignores"], input[name="license"]').on('change', () => {
const gitignores = $('input[name="gitignores"]').val();
const license = $('input[name="license"]').val();
if (gitignores || license) {
document.querySelector<HTMLInputElement>('input[name="auto_init"]').checked = true;
}
});
}
const pageContent = document.querySelector('.page-content.repository.new-repo');
if (!pageContent) return;
const form = document.querySelector<HTMLFormElement>('.new-repo-form');
const inputGitIgnores = form.querySelector<HTMLInputElement>('input[name="gitignores"]');
const inputLicense = form.querySelector<HTMLInputElement>('input[name="license"]');
const inputAutoInit = form.querySelector<HTMLInputElement>('input[name="auto_init"]');
const updateUiAutoInit = () => {
inputAutoInit.checked = Boolean(inputGitIgnores.value || inputLicense.value);
};
inputGitIgnores.addEventListener('change', updateUiAutoInit);
inputLicense.addEventListener('change', updateUiAutoInit);
updateUiAutoInit();
const inputRepoName = form.querySelector<HTMLInputElement>('input[name="repo_name"]');
const inputPrivate = form.querySelector<HTMLInputElement>('input[name="private"]');
const updateUiRepoName = () => {
const helps = form.querySelectorAll(`.help[data-help-for-repo-name]`);
hideElem(helps);
let help = form.querySelector(`.help[data-help-for-repo-name="${CSS.escape(inputRepoName.value)}"]`);
if (!help) help = form.querySelector(`.help[data-help-for-repo-name=""]`);
showElem(help);
const repoNamePreferPrivate = {'.profile': false, '.profile-private': true};
const preferPrivate = repoNamePreferPrivate[inputRepoName.value];
// inputPrivate might be disabled because site admin "force private"
if (preferPrivate !== undefined && !inputPrivate.closest('.disabled, [disabled]')) {
inputPrivate.checked = preferPrivate;
}
};
inputRepoName.addEventListener('input', updateUiRepoName);
updateUiRepoName();
initRepoNewTemplateSearch(form);
}
-51
View File
@@ -1,51 +0,0 @@
import $ from 'jquery';
import {htmlEscape} from 'escape-goat';
import {hideElem, showElem} from '../utils/dom.ts';
const {appSubUrl} = window.config;
export function initRepoTemplateSearch() {
const $repoTemplate = $('#repo_template');
const checkTemplate = function () {
const $templateUnits = $('#template_units');
const $nonTemplate = $('#non_template');
if ($repoTemplate.val() !== '' && $repoTemplate.val() !== '0') {
showElem($templateUnits);
hideElem($nonTemplate);
} else {
hideElem($templateUnits);
showElem($nonTemplate);
}
};
$repoTemplate.on('change', checkTemplate);
checkTemplate();
const changeOwner = function () {
$('#repo_template_search')
.dropdown({
apiSettings: {
url: `${appSubUrl}/repo/search?q={query}&template=true&priority_owner_id=${$('#uid').val()}`,
onResponse(response) {
const filteredResponse = {success: true, results: []};
filteredResponse.results.push({
name: '',
value: '',
});
// Parse the response from the api to work with our dropdown
$.each(response.data, (_r, repo) => {
filteredResponse.results.push({
name: htmlEscape(repo.repository.full_name),
value: repo.repository.id,
});
});
return filteredResponse;
},
cache: false,
},
fullTextSearch: true,
});
};
$('#uid').on('change', changeOwner);
changeOwner();
}
+2 -1
View File
@@ -36,8 +36,9 @@ declare module 'swagger-ui-dist/swagger-ui-es-bundle.js' {
}
interface JQuery {
api: any, // fomantic
areYouSure: any, // jquery.are-you-sure
fomanticExt: any; // fomantic extension
api: any, // fomantic
dimmer: any, // fomantic
dropdown: any; // fomantic
modal: any; // fomantic
-2
View File
@@ -35,7 +35,6 @@ import {initRepoEllipsisButton, initCommitStatuses} from './features/repo-commit
import {initRepoTopicBar} from './features/repo-home.ts';
import {initViewFileTreeSidebar} from './features/repo-view-file-tree-sidebar.ts';
import {initAdminCommon} from './features/admin/common.ts';
import {initRepoTemplateSearch} from './features/repo-template.ts';
import {initRepoCodeView} from './features/repo-code.ts';
import {initSshKeyFormParser} from './features/sshkey-helper.ts';
import {initUserSettings} from './features/user-settings.ts';
@@ -194,7 +193,6 @@ onDomReady(() => {
initRepoPullRequestReview,
initRepoRelease,
initRepoReleaseNew,
initRepoTemplateSearch,
initRepoTopicBar,
initViewFileTreeSidebar,
initRepoWikiForm,
+2 -1
View File
@@ -11,9 +11,10 @@ import {svg} from '../svg.ts';
export const fomanticMobileScreen = window.matchMedia('only screen and (max-width: 767.98px)');
export function initGiteaFomantic() {
// our extensions
$.fn.fomanticExt = {};
// Silence fomantic's error logging when tabs are used without a target content element
$.fn.tab.settings.silent = true;
// By default, use "exact match" for full text search
$.fn.dropdown.settings.fullTextSearch = 'exact';
// Do not use "cursor: pointer" for dropdown labels
+18
View File
@@ -1,6 +1,7 @@
import $ from 'jquery';
import {generateAriaId} from './base.ts';
import type {FomanticInitFunction} from '../../types.ts';
import {queryElems} from '../../utils/dom.ts';
const ariaPatchKey = '_giteaAriaPatchDropdown';
const fomanticDropdownFn = $.fn.dropdown;
@@ -9,6 +10,7 @@ const fomanticDropdownFn = $.fn.dropdown;
export function initAriaDropdownPatch() {
if ($.fn.dropdown === ariaDropdownFn) throw new Error('initAriaDropdownPatch could only be called once');
$.fn.dropdown = ariaDropdownFn;
$.fn.fomanticExt.onResponseKeepSelectedItem = onResponseKeepSelectedItem;
(ariaDropdownFn as FomanticInitFunction).settings = fomanticDropdownFn.settings;
}
@@ -351,3 +353,19 @@ export function hideScopedEmptyDividers(container: Element) {
if (item.nextElementSibling?.matches('.divider')) hideDivider(item);
}
}
function onResponseKeepSelectedItem(dropdown: typeof $|HTMLElement, selectedValue: string) {
// There is a bug in fomantic dropdown when using "apiSettings" to fetch data
// * when there is a selected item, the dropdown insists on hiding the selected one from the list:
// * in the "filter" function: ('[data-value="'+value+'"]').addClass(className.filtered)
//
// When user selects one item, and click the dropdown again,
// then the dropdown only shows other items and will select another (wrong) one.
// It can't be easily fix by using setTimeout(patch, 0) in `onResponse` because the `onResponse` is called before another `setTimeout(..., timeLeft)`
// Fortunately, the "timeLeft" is controlled by "loadingDuration" which is always zero at the moment, so we can use `setTimeout(..., 10)`
const elDropdown = (dropdown instanceof HTMLElement) ? dropdown : dropdown[0];
setTimeout(() => {
queryElems(elDropdown, `.menu .item[data-value="${CSS.escape(selectedValue)}"].filtered`, (el) => el.classList.remove('filtered'));
$(elDropdown).dropdown('set selected', selectedValue ?? '');
}, 10);
}
+1
View File
@@ -49,6 +49,7 @@ test('parseIssueNewHref', () => {
expect(parseIssueNewHref('/owner/repo/issues/new')).toEqual({ownerName: 'owner', repoName: 'repo', pathType: 'issues'});
expect(parseIssueNewHref('/owner/repo/issues/new?query')).toEqual({ownerName: 'owner', repoName: 'repo', pathType: 'issues'});
expect(parseIssueNewHref('/sub/owner/repo/issues/new#hash')).toEqual({ownerName: 'owner', repoName: 'repo', pathType: 'issues'});
expect(parseIssueNewHref('/sub/owner/repo/compare/feature/branch-1...fix/branch-2')).toEqual({ownerName: 'owner', repoName: 'repo', pathType: 'pulls'});
});
test('parseUrl', () => {
+3 -2
View File
@@ -39,8 +39,9 @@ export function parseIssueHref(href: string): IssuePathInfo {
export function parseIssueNewHref(href: string): IssuePathInfo {
const path = (href || '').replace(/[#?].*$/, '');
const [_, ownerName, repoName, pathType, indexString] = /([^/]+)\/([^/]+)\/(issues|pulls)\/new/.exec(path) || [];
return {ownerName, repoName, pathType, indexString};
const [_, ownerName, repoName, pathTypeField] = /([^/]+)\/([^/]+)\/(issues\/new|compare\/.+\.\.\.)/.exec(path) || [];
const pathType = pathTypeField.startsWith('issues/new') ? 'issues' : 'pulls';
return {ownerName, repoName, pathType};
}
export function parseIssuePageInfo(): IssuePageInfo {