|
1 |
| -import $ from 'jquery'; |
| 1 | +import {toggleElem} from '../../utils/dom.ts'; |
| 2 | +import {fomanticQuery} from '../../modules/fomantic/base.ts'; |
2 | 3 |
|
3 |
| -function isExclusiveScopeName(name) { |
| 4 | +function nameHasScope(name: string) { |
4 | 5 | return /.*[^/]\/[^/].*/.test(name);
|
5 | 6 | }
|
6 | 7 |
|
7 |
| -function updateExclusiveLabelEdit(form) { |
8 |
| - const nameInput = document.querySelector(`${form} .label-name-input`); |
9 |
| - const exclusiveField = document.querySelector(`${form} .label-exclusive-input-field`); |
10 |
| - const exclusiveCheckbox = document.querySelector(`${form} .label-exclusive-input`); |
11 |
| - const exclusiveWarning = document.querySelector(`${form} .label-exclusive-warning`); |
| 8 | +export function initCompLabelEdit(pageSelector: string) { |
| 9 | + const pageContent = document.querySelector<HTMLElement>(pageSelector); |
| 10 | + if (!pageContent) return; |
12 | 11 |
|
13 |
| - if (isExclusiveScopeName(nameInput.value)) { |
14 |
| - exclusiveField?.classList.remove('muted'); |
15 |
| - exclusiveField?.removeAttribute('aria-disabled'); |
16 |
| - if (exclusiveCheckbox.checked && exclusiveCheckbox.getAttribute('data-exclusive-warn')) { |
17 |
| - exclusiveWarning?.classList.remove('tw-hidden'); |
18 |
| - } else { |
19 |
| - exclusiveWarning?.classList.add('tw-hidden'); |
20 |
| - } |
21 |
| - } else { |
22 |
| - exclusiveField?.classList.add('muted'); |
23 |
| - exclusiveField?.setAttribute('aria-disabled', 'true'); |
24 |
| - exclusiveWarning?.classList.add('tw-hidden'); |
25 |
| - } |
26 |
| -} |
27 |
| - |
28 |
| -export function initCompLabelEdit(selector) { |
29 |
| - if (!$(selector).length) return; |
30 |
| - |
31 |
| - // Create label |
32 |
| - $('.new-label.button').on('click', () => { |
33 |
| - updateExclusiveLabelEdit('.new-label'); |
34 |
| - $('.new-label.modal').modal({ |
35 |
| - onApprove() { |
36 |
| - const form = document.querySelector('.new-label.form'); |
37 |
| - if (!form.checkValidity()) { |
38 |
| - form.reportValidity(); |
39 |
| - return false; |
40 |
| - } |
41 |
| - $('.new-label.form').trigger('submit'); |
42 |
| - }, |
43 |
| - }).modal('show'); |
44 |
| - return false; |
45 |
| - }); |
46 |
| - |
47 |
| - // Edit label |
48 |
| - $('.edit-label-button').on('click', function () { |
49 |
| - $('#label-modal-id').val($(this).data('id')); |
| 12 | + const elModal = pageContent.querySelector<HTMLElement>('#issue-label-edit-modal'); |
| 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 elIsArchivedField = elModal.querySelector('.label-is-archived-input-field'); |
| 19 | + const elIsArchivedInput = elModal.querySelector<HTMLInputElement>('.label-is-archived-input'); |
| 20 | + const elDescInput = elModal.querySelector<HTMLInputElement>('.label-desc-input'); |
| 21 | + const elColorInput = elModal.querySelector<HTMLInputElement>('.js-color-picker-input input'); |
50 | 22 |
|
51 |
| - const $nameInput = $('.edit-label .label-name-input'); |
52 |
| - $nameInput.val($(this).data('title')); |
| 23 | + const syncModalUi = () => { |
| 24 | + const hasScope = nameHasScope(elNameInput.value); |
| 25 | + elExclusiveField.classList.toggle('disabled', !hasScope); |
| 26 | + const showExclusiveWarning = hasScope && elExclusiveInput.checked && elModal.hasAttribute('data-need-warn-exclusive'); |
| 27 | + toggleElem(elExclusiveWarning, showExclusiveWarning); |
| 28 | + if (!hasScope) elExclusiveInput.checked = false; |
| 29 | + }; |
53 | 30 |
|
54 |
| - const $isArchivedCheckbox = $('.edit-label .label-is-archived-input'); |
55 |
| - $isArchivedCheckbox[0].checked = this.hasAttribute('data-is-archived'); |
| 31 | + const showLabelEditModal = (btn:HTMLElement) => { |
| 32 | + const form = elModal.querySelector<HTMLFormElement>('form'); |
| 33 | + elLabelId.value = btn.getAttribute('data-label-id') || ''; |
| 34 | + elNameInput.value = btn.getAttribute('data-label-name') || ''; |
| 35 | + elIsArchivedInput.checked = btn.getAttribute('data-label-is-archived') === 'true'; |
| 36 | + elExclusiveInput.checked = btn.getAttribute('data-label-exclusive') === 'true'; |
| 37 | + elDescInput.value = btn.getAttribute('data-label-description') || ''; |
| 38 | + elColorInput.value = btn.getAttribute('data-label-color') || ''; |
| 39 | + elColorInput.dispatchEvent(new Event('input', {bubbles: true})); // trigger the color picker |
56 | 40 |
|
57 |
| - const $exclusiveCheckbox = $('.edit-label .label-exclusive-input'); |
58 |
| - $exclusiveCheckbox[0].checked = this.hasAttribute('data-exclusive'); |
59 |
| - // Warn when label was previously not exclusive and used in issues |
60 |
| - $exclusiveCheckbox.data('exclusive-warn', |
61 |
| - $(this).data('num-issues') > 0 && |
62 |
| - (!this.hasAttribute('data-exclusive') || !isExclusiveScopeName($nameInput.val()))); |
63 |
| - updateExclusiveLabelEdit('.edit-label'); |
| 41 | + const isEdit = Boolean(elLabelId.value); |
64 | 42 |
|
65 |
| - $('.edit-label .label-desc-input').val(this.getAttribute('data-description')); |
| 43 | + // if a label was not exclusive but has issues, then it should warn user if it will become exclusive |
| 44 | + const numIssues = parseInt(btn.getAttribute('data-label-num-issues') || '0'); |
| 45 | + elModal.toggleAttribute('data-need-warn-exclusive', !elExclusiveInput.checked && numIssues > 0); |
| 46 | + elModal.querySelector('.header').textContent = isEdit ? elModal.getAttribute('data-text-edit-label') : elModal.getAttribute('data-text-new-label'); |
66 | 47 |
|
67 |
| - const colorInput = document.querySelector('.edit-label .js-color-picker-input input'); |
68 |
| - colorInput.value = this.getAttribute('data-color'); |
69 |
| - colorInput.dispatchEvent(new Event('input', {bubbles: true})); |
70 |
| - |
71 |
| - $('.edit-label.modal').modal({ |
| 48 | + const repoLink = elModal.getAttribute('data-repo-link'); |
| 49 | + form.action = isEdit ? `${repoLink}/edit` : `${repoLink}/new`; |
| 50 | + toggleElem(elIsArchivedField, isEdit); |
| 51 | + syncModalUi(); |
| 52 | + fomanticQuery(elModal).modal({ |
72 | 53 | onApprove() {
|
73 |
| - const form = document.querySelector('.edit-label.form'); |
74 | 54 | if (!form.checkValidity()) {
|
75 | 55 | form.reportValidity();
|
76 | 56 | return false;
|
77 | 57 | }
|
78 |
| - $('.edit-label.form').trigger('submit'); |
| 58 | + form.submit(); |
79 | 59 | },
|
80 | 60 | }).modal('show');
|
81 |
| - return false; |
82 |
| - }); |
| 61 | + }; |
| 62 | + |
| 63 | + elModal.addEventListener('input', () => syncModalUi()); |
83 | 64 |
|
84 |
| - $('.new-label .label-name-input').on('input', () => { |
85 |
| - updateExclusiveLabelEdit('.new-label'); |
86 |
| - }); |
87 |
| - $('.new-label .label-exclusive-input').on('change', () => { |
88 |
| - updateExclusiveLabelEdit('.new-label'); |
89 |
| - }); |
90 |
| - $('.edit-label .label-name-input').on('input', () => { |
91 |
| - updateExclusiveLabelEdit('.edit-label'); |
92 |
| - }); |
93 |
| - $('.edit-label .label-exclusive-input').on('change', () => { |
94 |
| - updateExclusiveLabelEdit('.edit-label'); |
95 |
| - }); |
| 65 | + const elNewLabel = pageContent.querySelector<HTMLElement>('.ui.button.new-label'); |
| 66 | + elNewLabel.addEventListener('click', () => showLabelEditModal(elNewLabel)); |
| 67 | + |
| 68 | + const elEditLabelButtons = pageContent.querySelectorAll<HTMLElement>('.edit-label-button'); |
| 69 | + for (const btn of elEditLabelButtons) { |
| 70 | + btn.addEventListener('click', (e) => { |
| 71 | + e.preventDefault(); |
| 72 | + showLabelEditModal(btn); |
| 73 | + }); |
| 74 | + } |
96 | 75 | }
|
0 commit comments