Skip to content

Commit f973708

Browse files
committed
Refactor repo-projects.ts
1 parent 2beaedc commit f973708

File tree

2 files changed

+34
-41
lines changed

2 files changed

+34
-41
lines changed

web_src/js/features/repo-projects.ts

Lines changed: 32 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
1-
import $ from 'jquery';
21
import {contrastColor} from '../utils/color.ts';
32
import {createSortable} from '../modules/sortable.ts';
43
import {POST, DELETE, PUT} from '../modules/fetch.ts';
4+
import {fomanticQuery} from '../modules/fomantic/base.ts';
55

6-
function updateIssueCount(cards) {
7-
const parent = cards.parentElement;
6+
function updateIssueCount(card: HTMLElement): void {
7+
const parent = card.parentElement;
88
const cnt = parent.querySelectorAll('.issue-card').length;
9-
parent.querySelectorAll('.project-column-issue-count')[0].textContent = cnt;
9+
parent.querySelectorAll('.project-column-issue-count')[0].textContent = String(cnt);
1010
}
1111

12-
async function createNewColumn(url, columnTitle, projectColorInput) {
12+
async function createNewColumn(url: string, columnTitleInput: HTMLInputElement, projectColorInput: HTMLInputElement): Promise<void> {
1313
try {
1414
await POST(url, {
1515
data: {
16-
title: columnTitle.val(),
17-
color: projectColorInput.val(),
16+
title: columnTitleInput.value,
17+
color: projectColorInput.value,
1818
},
1919
});
2020
} catch (error) {
2121
console.error(error);
2222
} finally {
23-
columnTitle.closest('form').removeClass('dirty');
23+
columnTitleInput.closest('form').classList.remove('dirty');
2424
window.location.reload();
2525
}
2626
}
2727

28-
async function moveIssue({item, from, to, oldIndex}: {item: HTMLElement, from: HTMLElement, to: HTMLElement, oldIndex: number}) {
28+
async function moveIssue({item, from, to, oldIndex}: {item: HTMLElement, from: HTMLElement, to: HTMLElement, oldIndex: number}): Promise<void> {
2929
const columnCards = to.querySelectorAll('.issue-card');
3030
updateIssueCount(from);
3131
updateIssueCount(to);
@@ -47,21 +47,21 @@ async function moveIssue({item, from, to, oldIndex}: {item: HTMLElement, from: H
4747
}
4848
}
4949

50-
async function initRepoProjectSortable() {
50+
async function initRepoProjectSortable(): Promise<void> {
5151
const els = document.querySelectorAll('#project-board > .board.sortable');
5252
if (!els.length) return;
5353

5454
// the HTML layout is: #project-board > .board > .project-column .cards > .issue-card
5555
const mainBoard = els[0];
56-
let boardColumns = mainBoard.querySelectorAll('.project-column');
56+
let boardColumns = mainBoard.querySelectorAll<HTMLDivElement>('.project-column');
5757
createSortable(mainBoard, {
5858
group: 'project-column',
5959
draggable: '.project-column',
6060
handle: '.project-column-header',
6161
delayOnTouchOnly: true,
6262
delay: 500,
6363
onSort: async () => { // eslint-disable-line @typescript-eslint/no-misused-promises
64-
boardColumns = mainBoard.querySelectorAll('.project-column');
64+
boardColumns = mainBoard.querySelectorAll<HTMLDivElement>('.project-column');
6565

6666
const columnSorting = {
6767
columns: Array.from(boardColumns, (column, i) => ({
@@ -92,14 +92,14 @@ async function initRepoProjectSortable() {
9292
}
9393
}
9494

95-
export function initRepoProject() {
95+
export function initRepoProject(): void {
9696
if (!document.querySelector('.repository.projects')) {
9797
return;
9898
}
9999

100100
initRepoProjectSortable(); // no await
101101

102-
for (const modal of document.querySelectorAll('.edit-project-column-modal')) {
102+
for (const modal of document.querySelectorAll<HTMLDivElement>('.edit-project-column-modal')) {
103103
const projectHeader = modal.closest<HTMLElement>('.project-column-header');
104104
const projectTitleLabel = projectHeader?.querySelector<HTMLElement>('.project-column-title-label');
105105
const projectTitleInput = modal.querySelector<HTMLInputElement>('.project-column-title-input');
@@ -134,55 +134,47 @@ export function initRepoProject() {
134134
divider.style.removeProperty('color');
135135
}
136136
}
137-
$('.ui.modal').modal('hide');
137+
fomanticQuery('.ui.modal').modal('hide');
138138
}
139139
});
140140
}
141141

142-
$('.default-project-column-modal').each(function () {
143-
const $boardColumn = $(this).closest('.project-column');
144-
const $showButton = $($boardColumn).find('.default-project-column-show');
145-
const $commitButton = $(this).find('.actions > .ok.button');
146-
147-
$($commitButton).on('click', async (e) => {
142+
for (const modal of document.querySelectorAll('.default-project-column-modal')) {
143+
const column = modal.closest('.project-column');
144+
const showBtn = column.querySelector('.default-project-column-show');
145+
const okBtn = modal.querySelector('.actions .ok.button');
146+
okBtn.addEventListener('click', async (e: MouseEvent) => {
148147
e.preventDefault();
149-
150148
try {
151-
await POST($($showButton).data('url'));
149+
await POST(showBtn.getAttribute('data-url'));
152150
} catch (error) {
153151
console.error(error);
154152
} finally {
155153
window.location.reload();
156154
}
157155
});
158-
});
159-
160-
$('.show-delete-project-column-modal').each(function () {
161-
const $deleteColumnModal = $(`${this.getAttribute('data-modal')}`);
162-
const $deleteColumnButton = $deleteColumnModal.find('.actions > .ok.button');
163-
const deleteUrl = this.getAttribute('data-url');
156+
}
164157

165-
$deleteColumnButton.on('click', async (e) => {
158+
for (const btn of document.querySelectorAll('.show-delete-project-column-modal')) {
159+
const okBtn = document.querySelector(`${btn.getAttribute('data-modal')} .actions .ok.button`);
160+
okBtn?.addEventListener('click', async (e: MouseEvent) => {
166161
e.preventDefault();
167-
168162
try {
169-
await DELETE(deleteUrl);
163+
await DELETE(btn.getAttribute('data-url'));
170164
} catch (error) {
171165
console.error(error);
172166
} finally {
173167
window.location.reload();
174168
}
175169
});
176-
});
170+
}
177171

178-
$('#new_project_column_submit').on('click', (e) => {
172+
document.querySelector('#new_project_column_submit')?.addEventListener('click', async (e: MouseEvent & {target: HTMLButtonElement}) => {
179173
e.preventDefault();
180-
const $columnTitle = $('#new_project_column');
181-
const $projectColorInput = $('#new_project_column_color_picker');
182-
if (!$columnTitle.val()) {
183-
return;
184-
}
174+
const columnTitleInput = document.querySelector<HTMLInputElement>('#new_project_column');
175+
const projectColorInput = document.querySelector<HTMLInputElement>('#new_project_column_color_picker');
176+
if (!columnTitleInput.value) return;
185177
const url = e.target.getAttribute('data-url');
186-
createNewColumn(url, $columnTitle, $projectColorInput);
178+
await createNewColumn(url, columnTitleInput, projectColorInput);
187179
});
188180
}

web_src/js/modules/sortable.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type {SortableOptions, SortableEvent} from 'sortablejs';
2+
import type Sortable from 'sortablejs';
23

3-
export async function createSortable(el: Element, opts: {handle?: string} & SortableOptions = {}) {
4+
export async function createSortable(el: Element, opts: {handle?: string} & SortableOptions = {}): Promise<Sortable> {
45
// @ts-expect-error: wrong type derived by typescript
56
const {Sortable} = await import(/* webpackChunkName: "sortablejs" */'sortablejs');
67

0 commit comments

Comments
 (0)