Skip to content

Commit 2c2d3fb

Browse files
committed
fix
1 parent 9d08d3f commit 2c2d3fb

File tree

6 files changed

+123
-4
lines changed

6 files changed

+123
-4
lines changed

Diff for: .eslintrc.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,7 @@ rules:
818818
unicorn/consistent-destructuring: [2]
819819
unicorn/consistent-empty-array-spread: [2]
820820
unicorn/consistent-existence-index-check: [0]
821-
unicorn/consistent-function-scoping: [2]
821+
unicorn/consistent-function-scoping: [0]
822822
unicorn/custom-error-definition: [0]
823823
unicorn/empty-brace-spaces: [2]
824824
unicorn/error-message: [0]

Diff for: templates/repo/issue/sidebar/label_list.tmpl

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
{{range $data.RepoLabels}}
2323
{{$exclusiveScope := .ExclusiveScope}}
2424
{{if and (ne $previousExclusiveScope "_no_scope") (ne $previousExclusiveScope $exclusiveScope)}}
25-
<div class="divider"></div>
25+
<div class="divider" data-scope="{{.ExclusiveScope}}"></div>
2626
{{end}}
2727
{{$previousExclusiveScope = $exclusiveScope}}
2828
{{template "repo/issue/sidebar/label_list_item" dict "Label" .}}
@@ -32,7 +32,7 @@
3232
{{range $data.OrgLabels}}
3333
{{$exclusiveScope := .ExclusiveScope}}
3434
{{if and (ne $previousExclusiveScope "_no_scope") (ne $previousExclusiveScope $exclusiveScope)}}
35-
<div class="divider"></div>
35+
<div class="divider" data-scope="{{.ExclusiveScope}}"></div>
3636
{{end}}
3737
{{$previousExclusiveScope = $exclusiveScope}}
3838
{{template "repo/issue/sidebar/label_list_item" dict "Label" .}}
+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import {createElementFromHTML} from '../utils/dom.ts';
2+
import {hideScopedEmptyDividers} from './repo-issue-sidebar-combolist.ts';
3+
4+
test('hideScopedEmptyDividers-simple', () => {
5+
const container = createElementFromHTML(`<div>
6+
<div class="divider"></div>
7+
<div class="item">a</div>
8+
<div class="divider"></div>
9+
<div class="divider"></div>
10+
<div class="item">b</div>
11+
<div class="divider"></div>
12+
</div>`);
13+
hideScopedEmptyDividers(container);
14+
expect(container.innerHTML).toEqual(`
15+
<div class="divider hidden transition"></div>
16+
<div class="item">a</div>
17+
<div class="divider hidden transition"></div>
18+
<div class="divider"></div>
19+
<div class="item">b</div>
20+
<div class="divider hidden transition"></div>
21+
`);
22+
});
23+
24+
test('hideScopedEmptyDividers-hidden1', () => {
25+
const container = createElementFromHTML(`<div>
26+
<div class="item">a</div>
27+
<div class="divider" data-scope="b"></div>
28+
<div class="item tw-hidden" data-scope="b">b</div>
29+
</div>`);
30+
hideScopedEmptyDividers(container);
31+
expect(container.innerHTML).toEqual(`
32+
<div class="item">a</div>
33+
<div class="divider hidden transition" data-scope="b"></div>
34+
<div class="item tw-hidden" data-scope="b">b</div>
35+
`);
36+
});
37+
38+
test('hideScopedEmptyDividers-hidden2', () => {
39+
const container = createElementFromHTML(`<div>
40+
<div class="item" data-scope="">a</div>
41+
<div class="divider" data-scope="b"></div>
42+
<div class="item tw-hidden" data-scope="b">b</div>
43+
<div class="divider" data-scope=""></div>
44+
<div class="item" data-scope="">c</div>
45+
</div>`);
46+
hideScopedEmptyDividers(container);
47+
expect(container.innerHTML).toEqual(`
48+
<div class="item" data-scope="">a</div>
49+
<div class="divider hidden transition" data-scope="b"></div>
50+
<div class="item tw-hidden" data-scope="b">b</div>
51+
<div class="divider hidden transition" data-scope=""></div>
52+
<div class="item" data-scope="">c</div>
53+
`);
54+
});

Diff for: web_src/js/features/repo-issue-sidebar-combolist.ts

+58
Original file line numberDiff line numberDiff line change
@@ -146,14 +146,72 @@ class IssueSidebarComboList {
146146

147147
this.elDropdown.addEventListener('click', (e) => this.onItemClick(e));
148148

149+
const itemsMenu = this.elDropdown.querySelector('.scrolling.menu') || this.elDropdown.querySelector('.menu');
149150
fomanticQuery(this.elDropdown).dropdown('setting', {
150151
action: 'nothing', // do not hide the menu if user presses Enter
151152
fullTextSearch: 'exact',
153+
onShow: () => hideScopedEmptyDividers(itemsMenu),
154+
onAfterFilterItems: () => hideScopedEmptyDividers(itemsMenu),
152155
onHide: () => this.onHide(),
153156
});
154157
}
155158
}
156159

160+
export function hideScopedEmptyDividers(container: Element) {
161+
const visibleItems: Element[] = [];
162+
const curScopeVisibleItems: Element[] = [];
163+
let curScope = '', lastVisibleScope = '';
164+
const isScopedDivider = (item: Element) => item.matches('.divider') && item.hasAttribute('data-scope');
165+
const hideDivider = (item: Element) => item.classList.add('hidden', 'transition'); // dropdown has its own classes to hide items
166+
167+
const handleScopeSwitch = (itemScope: string) => {
168+
if (curScopeVisibleItems.length === 1 && isScopedDivider(curScopeVisibleItems[0])) {
169+
hideDivider(curScopeVisibleItems[0]);
170+
} else if (curScopeVisibleItems.length) {
171+
if (isScopedDivider(curScopeVisibleItems[0]) && lastVisibleScope === curScope) {
172+
hideDivider(curScopeVisibleItems[0]);
173+
curScopeVisibleItems.shift();
174+
}
175+
visibleItems.push(...curScopeVisibleItems);
176+
lastVisibleScope = curScope;
177+
}
178+
curScope = itemScope;
179+
curScopeVisibleItems.length = 0;
180+
};
181+
182+
// remove the scope dividers if the scope items are empty
183+
for (const item of container.children) {
184+
const itemScope = item.getAttribute('data-scope') || '';
185+
if (itemScope !== curScope) {
186+
handleScopeSwitch(itemScope);
187+
}
188+
if (!item.classList.contains('filtered') && !item.classList.contains('tw-hidden')) {
189+
curScopeVisibleItems.push(item as HTMLElement);
190+
}
191+
}
192+
handleScopeSwitch('');
193+
194+
// hide all leading and trailing dividers
195+
while (visibleItems.length) {
196+
if (!visibleItems[0].matches('.divider')) break;
197+
hideDivider(visibleItems[0]);
198+
visibleItems.shift();
199+
}
200+
while (visibleItems.length) {
201+
if (!visibleItems[visibleItems.length - 1].matches('.divider')) break;
202+
hideDivider(visibleItems[visibleItems.length - 1]);
203+
visibleItems.pop();
204+
}
205+
// hide all duplicate dividers
206+
for (let i = 0; i < visibleItems.length; i++) {
207+
const item = visibleItems[i];
208+
if (!item.matches('.divider')) continue;
209+
if (i === 0 || i === visibleItems.length - 1 || item.nextElementSibling?.matches('.divider')) {
210+
hideDivider(item);
211+
}
212+
}
213+
}
214+
157215
export function initIssueSidebarComboList(container: HTMLElement) {
158216
new IssueSidebarComboList(container).init();
159217
}

Diff for: web_src/js/modules/fomantic/dropdown.ts

+7
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ function delegateOne($dropdown: any) {
7272
// * If the "dropdown icon" is clicked again when the menu is visible, Fomantic calls "blurSearch", so hide the menu
7373
dropdownCall('internal', 'blurSearch', function () { oldBlurSearch.call(this); dropdownCall('hide') });
7474

75+
const oldFilterItems = dropdownCall('internal', 'filterItems');
76+
dropdownCall('internal', 'filterItems', function () {
77+
oldFilterItems.call(this);
78+
const onAfterFilterItems = dropdownCall('setting', 'onAfterFilterItems');
79+
if (onAfterFilterItems) onAfterFilterItems();
80+
});
81+
7582
// the "template" functions are used for dynamic creation (eg: AJAX)
7683
const dropdownTemplates = {...dropdownCall('setting', 'templates'), t: performance.now()};
7784
const dropdownTemplatesMenuOld = dropdownTemplates.menu;

Diff for: web_src/js/webcomponents/overflow-menu.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ window.customElements.define('overflow-menu', class extends HTMLElement {
1212
mutationObserver: MutationObserver;
1313
lastWidth: number;
1414

15-
updateItems = throttle(100, () => { // eslint-disable-line unicorn/consistent-function-scoping -- https://github.com/sindresorhus/eslint-plugin-unicorn/issues/2088
15+
updateItems = throttle(100, () => {
1616
if (!this.tippyContent) {
1717
const div = document.createElement('div');
1818
div.classList.add('tippy-target');

0 commit comments

Comments
 (0)