Skip to content

Commit

Permalink
Merge pull request #4637 from inception-project/feature/4636-Ability-…
Browse files Browse the repository at this point in the history
…to-collapse-groups-in-annotation-sidebar

#4636 - Ability to collapse groups in annotation sidebar
  • Loading branch information
reckart authored Mar 17, 2024
2 parents 2f91d50 + 644b812 commit 529f467
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,20 @@
import { compareSpanText, groupBy, renderLabel, uniqueLabels } from "./Utils";
import { sortByScore, recommendationsFirst } from "./AnnotationBrowserState"
export let ajaxClient: DiamAjax;
export let data: AnnotatedText;
export let pinnedGroups: string[];
export let ajaxClient: DiamAjax
export let data: AnnotatedText
export let pinnedGroups: string[]
let groupedAnnotations: Record<string, Annotation[]>;
let sortedLabels: string[];
let groupedAnnotations: Record<string, Annotation[]>
let groups: { label: string, collapsed: boolean }[]
let collapsedGroups = new Set<string>()
$: {
sortedLabels = [...pinnedGroups, ...uniqueLabels(data).filter(v => !pinnedGroups.includes(v))]
const sortedLabels = [...pinnedGroups, ...uniqueLabels(data).filter(v => !pinnedGroups.includes(v))]
groups = sortedLabels.map(label => {
return { label: label, collapsed: collapsedGroups.has(label) };
});
const relations = data?.relations.values() || []
const spans = data?.spans.values() || []
Expand Down Expand Up @@ -97,9 +102,32 @@
function mouseOverAnnotation(event: MouseEvent, annotation: Annotation) {
event.target.dispatchEvent(new AnnotationOverEvent(annotation, event))
}
function mouseOutAnnotation(event: MouseEvent, annotation: Annotation) {
event.target.dispatchEvent(new AnnotationOutEvent(annotation, event))
}
function toggleCollapsed(group) {
if (!collapsedGroups.has(group.label)) {
collapsedGroups.add(group.label)
}
else {
collapsedGroups.delete(group.label)
}
data = data // Trigger reactive update
}
function collapseAll() {
for (const group of groups) {
collapsedGroups.add(group.label)
}
data = data // Trigger reactive update
}
function expandAll() {
collapsedGroups.clear()
data = data // Trigger reactive update
}
</script>

{#if !data}
Expand All @@ -111,7 +139,7 @@
</div>
</div>
{:else}
<div class="d-flex flex-column">
<div class="d-flex flex-row flex-wrap">
<div class="form-check form-switch mx-2">
<input
class="form-check-input"
Expand All @@ -133,23 +161,36 @@
bind:checked={$recommendationsFirst}
/>
<label class="form-check-label" for="recommendationsFirst"
>Recommendations first</label
>Suggestions first</label
>
</div>
</div>
<div class="d-flex flex-row flex-wrap">
<button class="btn btn-outline-secondary btn-sm p-0 m-1" style="width: 2em;" on:click={expandAll}>
<i class="fas fa-caret-down"/>
</button>
<button class="btn btn-outline-secondary btn-sm p-0 m-1" style="width: 2em;" on:click={collapseAll}>
<i class="fas fa-caret-down group-collapsed"/>
</button>
</div>
<div class="flex-content fit-child-snug">
{#if sortedLabels || sortedLabels?.length}
{#if groups || groups?.length}
<ul class="scrolling flex-content list-group list-group-flush">
{#each sortedLabels as label}
{#each groups as group}
<li class="list-group-item py-0 px-0 border-0">
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div
class="px-2 py-1 bg-light-subtle fw-bold sticky-top border-top border-bottom"
on:click={() => toggleCollapsed(group)}
>
{label || "No label"}
<button class="btn btn-link p-0" style="color: var(--bs-body-color)">
<i class="fas fa-caret-down d-inline-block" class:group-collapsed={group.collapsed}/>
</button>
<span>{group.label || "No label"}</span>
</div>
<ul class="px-0 list-group list-group-flush">
{#if groupedAnnotations[label]}
{#each groupedAnnotations[label] as ann}
<ul class="px-0 list-group list-group-flush" class:d-none={group.collapsed}>
{#if groupedAnnotations[group.label]}
{#each groupedAnnotations[group.label] as ann}
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<li
class="list-group-item list-group-item-action p-0 d-flex"
Expand Down Expand Up @@ -218,4 +259,8 @@
.list-group-flush > .list-group-item:last-child {
border-bottom-width: 1px;
}
.group-collapsed {
transform: rotate(-90deg);
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,15 @@
export let data: AnnotatedText;
let groupedAnnotations: Record<string, Annotation[]>;
let sortedLayers: Layer[];
let groups: { layer: Layer, collapsed: boolean }[]
let collapsedGroups = new Set<number>()
$: {
sortedLayers = uniqueLayers(data)
const sortedLayers = uniqueLayers(data)
groups = sortedLayers.map(layer => {
return { layer: layer, collapsed: collapsedGroups.has(layer.id) };
});
const relations = data?.relations.values() || []
const spans = data?.spans.values() || []
Expand Down Expand Up @@ -97,9 +102,32 @@
function mouseOverAnnotation(event: MouseEvent, annotation: Annotation) {
event.target.dispatchEvent(new AnnotationOverEvent(annotation, event))
}
function mouseOutAnnotation(event: MouseEvent, annotation: Annotation) {
event.target.dispatchEvent(new AnnotationOutEvent(annotation, event))
}
function toggleCollapsed(group) {
if (!collapsedGroups.has(group.layer.id)) {
collapsedGroups.add(group.layer.id)
}
else {
collapsedGroups.delete(group.layer.id)
}
data = data // Trigger reactive update
}
function collapseAll() {
for (const group of groups) {
collapsedGroups.add(group.layer.id)
}
data = data // Trigger reactive update
}
function expandAll() {
collapsedGroups.clear()
data = data // Trigger reactive update
}
</script>

{#if !data}
Expand All @@ -111,7 +139,7 @@
</div>
</div>
{:else}
<div class="d-flex flex-column">
<div class="d-flex flex-row flex-wrap">
<div class="form-check form-switch mx-2">
<input
class="form-check-input"
Expand All @@ -133,23 +161,36 @@
bind:checked={$recommendationsFirst}
/>
<label class="form-check-label" for="recommendationsFirst"
>Recommendations first</label
>Suggestions first</label
>
</div>
</div>
<div class="d-flex flex-row flex-wrap">
<button class="btn btn-outline-secondary btn-sm p-0 m-1" style="width: 2em;" on:click={expandAll}>
<i class="fas fa-caret-down"/>
</button>
<button class="btn btn-outline-secondary btn-sm p-0 m-1" style="width: 2em;" on:click={collapseAll}>
<i class="fas fa-caret-down group-collapsed"/>
</button>
</div>
<div class="flex-content fit-child-snug">
{#if sortedLayers || sortedLayers?.length}
{#if groups || groups?.length}
<ul class="scrolling flex-content list-group list-group-flush">
{#each sortedLayers as layer}
{#each groups as group}
<li class="list-group-item py-0 px-0 border-0">
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div
class="px-2 py-1 bg-light-subtle fw-bold sticky-top border-top border-bottom"
on:click={() => toggleCollapsed(group)}
>
{layer.name}
<button class="btn btn-link p-0" style="color: var(--bs-body-color)">
<i class="fas fa-caret-down d-inline-block" class:group-collapsed={group.collapsed}/>
</button>
<span>{group.layer.name}</span>
</div>
<ul class="px-0 list-group list-group-flush">
{#if groupedAnnotations[layer.name]}
{#each groupedAnnotations[layer.name] as ann}
<ul class="px-0 list-group list-group-flush" class:d-none={group.collapsed}>
{#if groupedAnnotations[group.layer.name]}
{#each groupedAnnotations[group.layer.name] as ann}
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<li
class="list-group-item list-group-item-action p-0 d-flex"
Expand Down Expand Up @@ -218,4 +259,8 @@
.list-group-flush > .list-group-item:last-child {
border-bottom-width: 1px;
}
.group-collapsed {
transform: rotate(-90deg);
}
</style>

0 comments on commit 529f467

Please sign in to comment.