gitea源码

LabelEdit.ts 4.6KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import {toggleElem} from '../../utils/dom.ts';
  2. import {fomanticQuery} from '../../modules/fomantic/base.ts';
  3. import {submitFormFetchAction} from '../common-fetch-action.ts';
  4. function nameHasScope(name: string): boolean {
  5. return /.*[^/]\/[^/].*/.test(name);
  6. }
  7. export function initCompLabelEdit(pageSelector: string) {
  8. const pageContent = document.querySelector<HTMLElement>(pageSelector);
  9. if (!pageContent) return;
  10. // for guest view, the modal is not available, the "labels" are read-only
  11. const elModal = pageContent.querySelector<HTMLElement>('#issue-label-edit-modal');
  12. if (!elModal) return;
  13. const elLabelId = elModal.querySelector<HTMLInputElement>('input[name="id"]');
  14. const elNameInput = elModal.querySelector<HTMLInputElement>('.label-name-input');
  15. const elExclusiveField = elModal.querySelector('.label-exclusive-input-field');
  16. const elExclusiveInput = elModal.querySelector<HTMLInputElement>('.label-exclusive-input');
  17. const elExclusiveWarning = elModal.querySelector('.label-exclusive-warning');
  18. const elExclusiveOrderField = elModal.querySelector<HTMLInputElement>('.label-exclusive-order-input-field');
  19. const elExclusiveOrderInput = elModal.querySelector<HTMLInputElement>('.label-exclusive-order-input');
  20. const elIsArchivedField = elModal.querySelector('.label-is-archived-input-field');
  21. const elIsArchivedInput = elModal.querySelector<HTMLInputElement>('.label-is-archived-input');
  22. const elDescInput = elModal.querySelector<HTMLInputElement>('.label-desc-input');
  23. const elColorInput = elModal.querySelector<HTMLInputElement>('.color-picker-combo input');
  24. const syncModalUi = () => {
  25. const hasScope = nameHasScope(elNameInput.value);
  26. elExclusiveField.classList.toggle('disabled', !hasScope);
  27. const showExclusiveWarning = hasScope && elExclusiveInput.checked && elModal.hasAttribute('data-need-warn-exclusive');
  28. toggleElem(elExclusiveWarning, showExclusiveWarning);
  29. if (!hasScope) elExclusiveInput.checked = false;
  30. toggleElem(elExclusiveOrderField, elExclusiveInput.checked);
  31. if (parseInt(elExclusiveOrderInput.value) <= 0) {
  32. elExclusiveOrderInput.style.color = 'var(--color-placeholder-text) !important';
  33. } else {
  34. elExclusiveOrderInput.style.color = null;
  35. }
  36. };
  37. const showLabelEditModal = (btn:HTMLElement) => {
  38. // the "btn" should contain the label's attributes by its `data-label-xxx` attributes
  39. const form = elModal.querySelector<HTMLFormElement>('form');
  40. elLabelId.value = btn.getAttribute('data-label-id') || '';
  41. elNameInput.value = btn.getAttribute('data-label-name') || '';
  42. elExclusiveOrderInput.value = btn.getAttribute('data-label-exclusive-order') || '0';
  43. elIsArchivedInput.checked = btn.getAttribute('data-label-is-archived') === 'true';
  44. elExclusiveInput.checked = btn.getAttribute('data-label-exclusive') === 'true';
  45. elDescInput.value = btn.getAttribute('data-label-description') || '';
  46. elColorInput.value = btn.getAttribute('data-label-color') || '';
  47. elColorInput.dispatchEvent(new Event('input', {bubbles: true})); // trigger the color picker
  48. // if label id exists: "edit label" mode; otherwise: "new label" mode
  49. const isEdit = Boolean(elLabelId.value);
  50. // if a label was not exclusive but has issues, then it should warn user if it will become exclusive
  51. const numIssues = parseInt(btn.getAttribute('data-label-num-issues') || '0');
  52. elModal.toggleAttribute('data-need-warn-exclusive', !elExclusiveInput.checked && numIssues > 0);
  53. elModal.querySelector('.header').textContent = isEdit ? elModal.getAttribute('data-text-edit-label') : elModal.getAttribute('data-text-new-label');
  54. const curPageLink = elModal.getAttribute('data-current-page-link');
  55. form.action = isEdit ? `${curPageLink}/edit` : `${curPageLink}/new`;
  56. toggleElem(elIsArchivedField, isEdit);
  57. syncModalUi();
  58. fomanticQuery(elModal).modal({
  59. onApprove() {
  60. if (!form.checkValidity()) {
  61. form.reportValidity();
  62. return false;
  63. }
  64. submitFormFetchAction(form);
  65. return false;
  66. },
  67. }).modal('show');
  68. };
  69. elModal.addEventListener('input', () => syncModalUi());
  70. // theoretically, if the modal exists, the "new label" button should also exist, just in case it doesn't, use "?."
  71. const elNewLabel = pageContent.querySelector<HTMLElement>('.ui.button.new-label');
  72. elNewLabel?.addEventListener('click', () => showLabelEditModal(elNewLabel));
  73. const elEditLabelButtons = pageContent.querySelectorAll<HTMLElement>('.edit-label-button');
  74. for (const btn of elEditLabelButtons) {
  75. btn.addEventListener('click', (e) => {
  76. e.preventDefault();
  77. showLabelEditModal(btn);
  78. });
  79. }
  80. }