Eye on the Tags header hides all tags, also tags added later
This commit is contained in:
@@ -23,7 +23,8 @@
|
||||
local branches, remote branches and tags, and the checked-out commit is ringed.
|
||||
- **Hides what you don't need.** Hide one branch with its eye button in the sidebar, or
|
||||
with <kbd>h</kbd> on a commit. Type a pattern such as `prototypes/*` and choose
|
||||
**hide** or **show only**. gites remembers the filters of each repository.
|
||||
**hide** or **show only**. The eye next to **Tags** hides all tags, also tags added
|
||||
later. gites remembers the filters of each repository.
|
||||
- **Folds long straight stretches.** Commits in a row that have no branch, tag, fork or
|
||||
merge fold into one dotted line. <kbd>c</kbd> folds all of them, <kbd>space</kbd>
|
||||
opens or closes the one at the selected commit.
|
||||
|
||||
+2
-1
@@ -150,6 +150,7 @@ async function applyRepo(data: RepoData) {
|
||||
});
|
||||
filters.hidden = saved?.hidden ?? [];
|
||||
filters.rules = saved?.rules ?? [];
|
||||
filters.hideTags = saved?.hideTags ?? false;
|
||||
collapseAll.value = saved?.collapseAll ?? false;
|
||||
filtersLoadedFor = data.root;
|
||||
toggled.value = new Set();
|
||||
@@ -173,7 +174,7 @@ watch(
|
||||
saveTimer = window.setTimeout(() => {
|
||||
invoke("save_filters", {
|
||||
repo: repoRoot,
|
||||
value: { hidden: filters.hidden, rules: filters.rules, collapseAll: collapseAll.value },
|
||||
value: { hidden: filters.hidden, rules: filters.rules, hideTags: filters.hideTags, collapseAll: collapseAll.value },
|
||||
}).catch((e) => showToast(`could not save filters: ${e}`));
|
||||
}, 300);
|
||||
},
|
||||
|
||||
@@ -46,7 +46,15 @@ function toggleFolder(n: TreeNode) {
|
||||
<path d="M1.5 4a1 1 0 0 1 1-1h3.5l1.5 1.5h6a1 1 0 0 1 1 1V12a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1z" />
|
||||
</svg>
|
||||
<span class="name" :title="n.ref?.name ?? n.path">{{ n.label }}</span>
|
||||
<EyeButton :shut="allHidden(n)" @click.stop="emit('toggle', refsUnder(n).map((r) => r.name))" />
|
||||
<EyeButton
|
||||
v-if="kind === 'tag' && filters.hideTags"
|
||||
class="locked"
|
||||
:shut="true"
|
||||
disabled
|
||||
title="all tags are hidden: use the eye next to Tags"
|
||||
@click.stop
|
||||
/>
|
||||
<EyeButton v-else :shut="allHidden(n)" @click.stop="emit('toggle', refsUnder(n).map((r) => r.name))" />
|
||||
</div>
|
||||
<RefTree
|
||||
v-if="n.children.length && !closed.has(key(n))"
|
||||
@@ -80,4 +88,5 @@ function toggleFolder(n: TreeNode) {
|
||||
.arrow.open { transform: rotate(90deg); }
|
||||
.name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.item:hover :deep(.eye) { opacity: 1; }
|
||||
.item :deep(.eye.locked) { opacity: 0.35; cursor: default; }
|
||||
</style>
|
||||
|
||||
@@ -3,6 +3,7 @@ import { computed, reactive, ref } from "vue";
|
||||
import { refKind, shortName } from "../lib/filter";
|
||||
import { buildTree, type TreeNode } from "../lib/tree";
|
||||
import type { FilterState, Ref, RefKind } from "../lib/types";
|
||||
import EyeButton from "./EyeButton.vue";
|
||||
import RefTree from "./RefTree.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -98,7 +99,15 @@ function onPatternKey(e: KeyboardEvent) {
|
||||
</section>
|
||||
|
||||
<section v-for="g in groups" v-show="byKind[g.kind].length" :key="g.kind" class="group">
|
||||
<h3>{{ g.title }} <span class="count">{{ byKind[g.kind].length }}</span></h3>
|
||||
<h3>
|
||||
{{ g.title }} <span class="count">{{ byKind[g.kind].length }}</span>
|
||||
<EyeButton
|
||||
v-if="g.kind === 'tag'"
|
||||
:shut="!!filters.hideTags"
|
||||
:title="filters.hideTags ? 'show all tags' : 'hide all tags, also tags added later'"
|
||||
@click="filters.hideTags = !filters.hideTags"
|
||||
/>
|
||||
</h3>
|
||||
<RefTree
|
||||
:nodes="trees[g.kind]"
|
||||
:kind="g.kind"
|
||||
@@ -122,6 +131,9 @@ function onPatternKey(e: KeyboardEvent) {
|
||||
padding: 10px 0 20px;
|
||||
}
|
||||
h3 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
margin: 12px 14px 6px;
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
@@ -129,6 +141,8 @@ h3 {
|
||||
color: var(--text-dim);
|
||||
}
|
||||
.count { font-weight: normal; opacity: 0.7; }
|
||||
h3 :deep(.eye) { margin-left: auto; margin-right: -6px; }
|
||||
h3:hover :deep(.eye) { opacity: 1; }
|
||||
.rules { padding: 0 14px; }
|
||||
.rules h3 { margin-left: 0; margin-top: 2px; }
|
||||
.rules input { width: 100%; }
|
||||
|
||||
@@ -78,3 +78,18 @@ describe("lineOwners", () => {
|
||||
expect(owners.get("f")).toBe("refs/heads/feature");
|
||||
});
|
||||
});
|
||||
|
||||
describe("hiding all tags", () => {
|
||||
const state = { hidden: [], rules: [], hideTags: true };
|
||||
it("hides every tag", () => {
|
||||
expect(isRefVisible("refs/tags/v1", state)).toBe(false);
|
||||
expect(isRefVisible("refs/tags/release/2", state)).toBe(false);
|
||||
});
|
||||
it("leaves branches alone", () => {
|
||||
expect(isRefVisible("refs/heads/main", state)).toBe(true);
|
||||
expect(isRefVisible("refs/remotes/origin/main", state)).toBe(true);
|
||||
});
|
||||
it("shows tags again when turned off", () => {
|
||||
expect(isRefVisible("refs/tags/v1", { ...state, hideTags: false })).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -21,6 +21,7 @@ export function globMatch(pattern: string, text: string): boolean {
|
||||
|
||||
export function isRefVisible(name: string, state: FilterState): boolean {
|
||||
if (state.hidden.includes(name)) return false;
|
||||
if (state.hideTags && name.startsWith("refs/tags/")) return false;
|
||||
const short = shortName(name);
|
||||
const only = state.rules.filter((r) => r.mode === "only");
|
||||
if (only.length > 0 && !only.some((r) => globMatch(r.pattern, short))) return false;
|
||||
|
||||
@@ -33,6 +33,8 @@ export interface FilterState {
|
||||
/** Full ref names hidden with the eye toggle. */
|
||||
hidden: string[];
|
||||
rules: FilterRule[];
|
||||
/** Hides every tag, also tags created later. */
|
||||
hideTags?: boolean;
|
||||
}
|
||||
|
||||
/** A commit as shown on screen, with its parent edges after collapsing. */
|
||||
|
||||
Reference in New Issue
Block a user