-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
And fix a regression: #30053 (comment) Major changes: * rewrite without jquery * remove the "delete modal", using "link-action" is good enough * merge "new modal" and "edit modal"
- Loading branch information
1 parent
a78a466
commit 96d3a03
Showing
9 changed files
with
97 additions
and
180 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,13 @@ | ||
{{template "org/settings/layout_head" (dict "ctxData" . "pageClass" "organization settings labels")}} | ||
<div class="org-setting-content"> | ||
<div class="tw-flex tw-items-center"> | ||
<div class="tw-flex-1"> | ||
{{ctx.Locale.Tr "org.settings.labels_desc"}} | ||
</div> | ||
<button class="ui small primary new-label button">{{ctx.Locale.Tr "repo.issues.new_label"}}</button> | ||
</div> | ||
<div class="divider"></div> | ||
{{template "repo/issue/labels/label_new" .}} | ||
{{template "repo/issue/labels/label_list" .}} | ||
</div> | ||
{{template "repo/issue/labels/edit_delete_label" .}} | ||
<div class="org-setting-content"> | ||
<div class="tw-flex tw-items-center"> | ||
<div class="tw-flex-1"> | ||
{{ctx.Locale.Tr "org.settings.labels_desc"}} | ||
</div> | ||
<button class="ui small primary new-label button">{{ctx.Locale.Tr "repo.issues.new_label"}}</button> | ||
</div> | ||
<div class="divider"></div> | ||
{{template "repo/issue/labels/label_list" .}} | ||
{{template "repo/issue/labels/label_edit_modal" .}} | ||
</div> | ||
{{template "org/settings/layout_footer" .}} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 8 additions & 17 deletions
25
.../repo/issue/labels/edit_delete_label.tmpl → ...s/repo/issue/labels/label_edit_modal.tmpl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,96 +1,81 @@ | ||
import $ from 'jquery'; | ||
import {toggleElem} from '../../utils/dom.ts'; | ||
import {fomanticQuery} from '../../modules/fomantic/base.ts'; | ||
|
||
function isExclusiveScopeName(name) { | ||
function nameHasScope(name: string): boolean { | ||
return /.*[^/]\/[^/].*/.test(name); | ||
} | ||
|
||
function updateExclusiveLabelEdit(form) { | ||
const nameInput = document.querySelector(`${form} .label-name-input`); | ||
const exclusiveField = document.querySelector(`${form} .label-exclusive-input-field`); | ||
const exclusiveCheckbox = document.querySelector(`${form} .label-exclusive-input`); | ||
const exclusiveWarning = document.querySelector(`${form} .label-exclusive-warning`); | ||
export function initCompLabelEdit(pageSelector: string) { | ||
const pageContent = document.querySelector<HTMLElement>(pageSelector); | ||
if (!pageContent) return; | ||
|
||
if (isExclusiveScopeName(nameInput.value)) { | ||
exclusiveField?.classList.remove('muted'); | ||
exclusiveField?.removeAttribute('aria-disabled'); | ||
if (exclusiveCheckbox.checked && exclusiveCheckbox.getAttribute('data-exclusive-warn')) { | ||
exclusiveWarning?.classList.remove('tw-hidden'); | ||
} else { | ||
exclusiveWarning?.classList.add('tw-hidden'); | ||
} | ||
} else { | ||
exclusiveField?.classList.add('muted'); | ||
exclusiveField?.setAttribute('aria-disabled', 'true'); | ||
exclusiveWarning?.classList.add('tw-hidden'); | ||
} | ||
} | ||
// for guest view, the modal is not available, the "labels" are read-only | ||
const elModal = pageContent.querySelector<HTMLElement>('#issue-label-edit-modal'); | ||
if (!elModal) return; | ||
|
||
export function initCompLabelEdit(selector) { | ||
if (!$(selector).length) return; | ||
const elLabelId = elModal.querySelector<HTMLInputElement>('input[name="id"]'); | ||
const elNameInput = elModal.querySelector<HTMLInputElement>('.label-name-input'); | ||
const elExclusiveField = elModal.querySelector('.label-exclusive-input-field'); | ||
const elExclusiveInput = elModal.querySelector<HTMLInputElement>('.label-exclusive-input'); | ||
const elExclusiveWarning = elModal.querySelector('.label-exclusive-warning'); | ||
const elIsArchivedField = elModal.querySelector('.label-is-archived-input-field'); | ||
const elIsArchivedInput = elModal.querySelector<HTMLInputElement>('.label-is-archived-input'); | ||
const elDescInput = elModal.querySelector<HTMLInputElement>('.label-desc-input'); | ||
const elColorInput = elModal.querySelector<HTMLInputElement>('.js-color-picker-input input'); | ||
|
||
// Create label | ||
$('.new-label.button').on('click', () => { | ||
updateExclusiveLabelEdit('.new-label'); | ||
$('.new-label.modal').modal({ | ||
onApprove() { | ||
const form = document.querySelector('.new-label.form'); | ||
if (!form.checkValidity()) { | ||
form.reportValidity(); | ||
return false; | ||
} | ||
$('.new-label.form').trigger('submit'); | ||
}, | ||
}).modal('show'); | ||
return false; | ||
}); | ||
|
||
// Edit label | ||
$('.edit-label-button').on('click', function () { | ||
$('#label-modal-id').val($(this).data('id')); | ||
|
||
const $nameInput = $('.edit-label .label-name-input'); | ||
$nameInput.val($(this).data('title')); | ||
|
||
const $isArchivedCheckbox = $('.edit-label .label-is-archived-input'); | ||
$isArchivedCheckbox[0].checked = this.hasAttribute('data-is-archived'); | ||
const syncModalUi = () => { | ||
const hasScope = nameHasScope(elNameInput.value); | ||
elExclusiveField.classList.toggle('disabled', !hasScope); | ||
const showExclusiveWarning = hasScope && elExclusiveInput.checked && elModal.hasAttribute('data-need-warn-exclusive'); | ||
toggleElem(elExclusiveWarning, showExclusiveWarning); | ||
if (!hasScope) elExclusiveInput.checked = false; | ||
}; | ||
|
||
const $exclusiveCheckbox = $('.edit-label .label-exclusive-input'); | ||
$exclusiveCheckbox[0].checked = this.hasAttribute('data-exclusive'); | ||
// Warn when label was previously not exclusive and used in issues | ||
$exclusiveCheckbox.data('exclusive-warn', | ||
$(this).data('num-issues') > 0 && | ||
(!this.hasAttribute('data-exclusive') || !isExclusiveScopeName($nameInput.val()))); | ||
updateExclusiveLabelEdit('.edit-label'); | ||
const showLabelEditModal = (btn:HTMLElement) => { | ||
// the "btn" should contain the label's attributes by its `data-label-xxx` attributes | ||
const form = elModal.querySelector<HTMLFormElement>('form'); | ||
elLabelId.value = btn.getAttribute('data-label-id') || ''; | ||
elNameInput.value = btn.getAttribute('data-label-name') || ''; | ||
elIsArchivedInput.checked = btn.getAttribute('data-label-is-archived') === 'true'; | ||
elExclusiveInput.checked = btn.getAttribute('data-label-exclusive') === 'true'; | ||
elDescInput.value = btn.getAttribute('data-label-description') || ''; | ||
elColorInput.value = btn.getAttribute('data-label-color') || ''; | ||
elColorInput.dispatchEvent(new Event('input', {bubbles: true})); // trigger the color picker | ||
|
||
$('.edit-label .label-desc-input').val(this.getAttribute('data-description')); | ||
// if label id exists: "edit label" mode; otherwise: "new label" mode | ||
const isEdit = Boolean(elLabelId.value); | ||
|
||
const colorInput = document.querySelector('.edit-label .js-color-picker-input input'); | ||
colorInput.value = this.getAttribute('data-color'); | ||
colorInput.dispatchEvent(new Event('input', {bubbles: true})); | ||
// if a label was not exclusive but has issues, then it should warn user if it will become exclusive | ||
const numIssues = parseInt(btn.getAttribute('data-label-num-issues') || '0'); | ||
elModal.toggleAttribute('data-need-warn-exclusive', !elExclusiveInput.checked && numIssues > 0); | ||
elModal.querySelector('.header').textContent = isEdit ? elModal.getAttribute('data-text-edit-label') : elModal.getAttribute('data-text-new-label'); | ||
|
||
$('.edit-label.modal').modal({ | ||
const curPageLink = elModal.getAttribute('data-current-page-link'); | ||
form.action = isEdit ? `${curPageLink}/edit` : `${curPageLink}/new`; | ||
toggleElem(elIsArchivedField, isEdit); | ||
syncModalUi(); | ||
fomanticQuery(elModal).modal({ | ||
onApprove() { | ||
const form = document.querySelector('.edit-label.form'); | ||
if (!form.checkValidity()) { | ||
form.reportValidity(); | ||
return false; | ||
} | ||
$('.edit-label.form').trigger('submit'); | ||
form.submit(); | ||
}, | ||
}).modal('show'); | ||
return false; | ||
}); | ||
}; | ||
|
||
$('.new-label .label-name-input').on('input', () => { | ||
updateExclusiveLabelEdit('.new-label'); | ||
}); | ||
$('.new-label .label-exclusive-input').on('change', () => { | ||
updateExclusiveLabelEdit('.new-label'); | ||
}); | ||
$('.edit-label .label-name-input').on('input', () => { | ||
updateExclusiveLabelEdit('.edit-label'); | ||
}); | ||
$('.edit-label .label-exclusive-input').on('change', () => { | ||
updateExclusiveLabelEdit('.edit-label'); | ||
}); | ||
elModal.addEventListener('input', () => syncModalUi()); | ||
|
||
// theoretically, if the modal exists, the "new label" button should also exist, just in case it doesn't, use "?." | ||
const elNewLabel = pageContent.querySelector<HTMLElement>('.ui.button.new-label'); | ||
elNewLabel?.addEventListener('click', () => showLabelEditModal(elNewLabel)); | ||
|
||
const elEditLabelButtons = pageContent.querySelectorAll<HTMLElement>('.edit-label-button'); | ||
for (const btn of elEditLabelButtons) { | ||
btn.addEventListener('click', (e) => { | ||
e.preventDefault(); | ||
showLabelEditModal(btn); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters