Skip to content

Commit

Permalink
Refactor repo-new.ts (go-gitea#33070)
Browse files Browse the repository at this point in the history
1. merge `repo-template.ts` into `repo-new.ts` (they are all for "/repo/create")
2. remove jquery
3. fix an anonying fomantic dropdown bug, see the comment of `onResponseKeepSelectedItem`
  • Loading branch information
wxiaoguang authored Jan 1, 2025
1 parent 85c756e commit c116770
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 57 deletions.
49 changes: 47 additions & 2 deletions web_src/js/features/repo-new.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,53 @@
import {hideElem, showElem} from '../utils/dom.ts';
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() {
const pageContent = document.querySelector('.page-content.repository.new-repo');
if (!pageContent) return;

const form = document.querySelector('.new-repo-form');
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"]');
Expand Down Expand Up @@ -32,4 +75,6 @@ export function initRepoNew() {
};
inputRepoName.addEventListener('input', updateUiRepoName);
updateUiRepoName();

initRepoNewTemplateSearch(form);
}
51 changes: 0 additions & 51 deletions web_src/js/features/repo-template.ts

This file was deleted.

3 changes: 2 additions & 1 deletion web_src/js/globals.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 0 additions & 2 deletions web_src/js/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import {
import {initRepoEllipsisButton, initCommitStatuses} from './features/repo-commit.ts';
import {initRepoTopicBar} from './features/repo-home.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';
Expand Down Expand Up @@ -193,7 +192,6 @@ onDomReady(() => {
initRepoPullRequestReview,
initRepoRelease,
initRepoReleaseNew,
initRepoTemplateSearch,
initRepoTopicBar,
initRepoWikiForm,
initRepository,
Expand Down
3 changes: 2 additions & 1 deletion web_src/js/modules/fomantic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 18 additions & 0 deletions web_src/js/modules/fomantic/dropdown.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
}

Expand Down Expand Up @@ -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);
}

0 comments on commit c116770

Please sign in to comment.