Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions client/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export default defineComponent({
configuration ,
loadCurrentUser,
loadReviewerMaterials,
loadFilterTags,
} = useState();
const getShared = async () => {
sharedList.value = (await getRecordings(true)).data.items;
Expand Down Expand Up @@ -55,6 +56,7 @@ export default defineComponent({
};
onMounted(async () => {
checkLogin();
loadFilterTags();
});
router.afterEach((guard) => {
if (guard.path.includes("spectrogram")) {
Expand Down
6 changes: 4 additions & 2 deletions client/src/components/RecordingList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export default defineComponent({
showSubmittedRecordings,
myRecordingsDisplay,
sharedRecordingsDisplay,
filterTags,
sharedFilterTags,
} = useState();
const editingRecording: Ref<EditingRecording | null> = ref(null);

Expand All @@ -33,9 +35,9 @@ export default defineComponent({

const fetchRecordings = async () => {
const params = buildListParams();
const recordings = await getRecordings(false, params);
const recordings = await getRecordings(false, { ...params, tags: filterTags.value });
recordingList.value = recordings.data.items;
const shared = await getRecordings(true, { ...params, public: true });
const shared = await getRecordings(true, { ...params, public: true, tags: sharedFilterTags.value });
sharedList.value = shared.data.items;
};
onMounted(() => fetchRecordings());
Expand Down
21 changes: 21 additions & 0 deletions client/src/use/useState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ const reviewerMaterials = ref('');

const transparencyThreshold = ref(0); // 0-100 percentage

const FILTER_TAG_STORAGE_KEY = 'bataiFilterTags';
const SHARED_FILTER_TAG_STORAGE_KEY = 'bataiSharedFilterTags';

const filterTags: Ref<string[]> = ref([]);
const sharedFilterTags: Ref<string[]> = ref([]);

type AnnotationState = "" | "editing" | "creating" | "disabled";
export default function useState() {
const setAnnotationState = (state: AnnotationState) => {
Expand Down Expand Up @@ -204,6 +210,17 @@ export default function useState() {
}
}

function saveFilterTags() {
localStorage.setItem(FILTER_TAG_STORAGE_KEY, JSON.stringify(filterTags.value));
localStorage.setItem(SHARED_FILTER_TAG_STORAGE_KEY, JSON.stringify(sharedFilterTags.value));
}

function loadFilterTags() {
filterTags.value = JSON.parse(localStorage.getItem(FILTER_TAG_STORAGE_KEY) || '[]');
sharedFilterTags.value = JSON.parse(localStorage.getItem(SHARED_FILTER_TAG_STORAGE_KEY) || '[]');

}

return {
annotationState,
creationType,
Expand Down Expand Up @@ -264,5 +281,9 @@ export default function useState() {
loadReviewerMaterials,
viewMaskOverlay,
maskOverlayOpacity,
filterTags,
sharedFilterTags,
saveFilterTags,
loadFilterTags,
};
}
40 changes: 34 additions & 6 deletions client/src/views/Recordings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ export default defineComponent({
showSubmittedRecordings,
myRecordingsDisplay,
sharedRecordingsDisplay,
filterTags,
sharedFilterTags,
saveFilterTags,
} = useState();
const editingRecording: Ref<EditingRecording | null> = ref(null);
let intervalRef: number | null = null;
Expand Down Expand Up @@ -183,8 +186,6 @@ export default defineComponent({
recordingTagList.value = tags.data;
};

const filterTags: Ref<string[]> = ref([]);
const sharedFilterTags: Ref<string[]> = ref([]);
const recordingTagOptions = computed(() =>
recordingTagList.value.map((t) => t.text).filter(Boolean)
);
Expand All @@ -198,7 +199,7 @@ export default defineComponent({
}
return userAnnotations.length ? 0 : -1;
}


function currentUserSubmissionLabel(recording: Recording) {
const userSubmittedAnnotation = recording.fileAnnotations.find((annotation: FileAnnotation) => (
Expand All @@ -216,7 +217,7 @@ export default defineComponent({
if (showSubmittedRecordings.value) {
headers.value.push(myLabelHeader);
sharedHeaders.value.push(myLabelHeader);
}
}
}
}

Expand Down Expand Up @@ -261,8 +262,22 @@ export default defineComponent({
await fetchSharedRecordings({ page: 1, itemsPerPage: 20 });
});

watch(filterTags, () => fetchMyRecordings(lastMyOptions.value), { deep: true });
watch(sharedFilterTags, () => fetchSharedRecordings(lastSharedOptions.value), { deep: true });
watch(
filterTags,
() => {
fetchMyRecordings(lastMyOptions.value);
saveFilterTags();
},
{ deep: true }
);
watch(
sharedFilterTags,
() => {
fetchSharedRecordings(lastSharedOptions.value);
saveFilterTags();
},
{ deep: true }
);

const uploadDone = () => {
uploadDialog.value = false;
Expand Down Expand Up @@ -673,6 +688,19 @@ export default defineComponent({
{{ item.name }}
</router-link>
</template>

<template #item.tag_text="{ item }">
<span v-if="item.tags_text">
<v-chip
v-for="tag in item.tags_text"
:key="tag"
size="small"
>
{{ tag }}
</v-chip>
</span>
</template>

<template #item.recorded_date="{ item }">
{{ item.recorded_date }} {{ item.recorded_time }}
</template>
Expand Down
99 changes: 64 additions & 35 deletions client/src/views/Spectrogram.vue
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ export default defineComponent({
clearContours,
currentRecordingId,
viewMaskOverlay,
filterTags,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we in the template show what the filtering tags are in the UI? I.E some indication that this is filtered data on a tag/tags?

Just thinking of the case of someone copying a link to another PC for a spectrogram (this wouldn't copy over the local storage tags) and they start hitting next/previous. Maybe inbetween the Prev/Next buttons adding the tag just as an indication that the data is filtered. Show the tag only if it exists.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sharedFilterTags,
} = useState();
const {
clearPulseMetadata,
Expand Down Expand Up @@ -139,6 +141,8 @@ export default defineComponent({
}
};

const combinedTags = computed(() => Array.from (new Set([...filterTags.value, ...sharedFilterTags.value])));

const loading = ref(false);
const spectrogramData: Ref<Spectrogram | null> = ref(null);
const loadData = async () => {
Expand Down Expand Up @@ -219,9 +223,11 @@ export default defineComponent({

if (configuration.value.mark_annotations_completed_enabled) {
try {
const tags = Array.from(new Set([...filterTags.value, ...sharedFilterTags.value]));
const neighborsRes = await getUnsubmittedNeighbors(parseInt(props.id, 10), {
sort_by: 'created',
sort_direction: 'desc',
tags: tags,
});
nextUnsubmittedId.value = neighborsRes.data.next_id;
previousUnsubmittedId.value = neighborsRes.data.previous_id;
Expand Down Expand Up @@ -378,6 +384,7 @@ export default defineComponent({
fixedAxes,
toggleFixedAxes,
contoursLoading,
combinedTags,
// Other user selection
otherUserAnnotations,
sequenceAnnotations,
Expand Down Expand Up @@ -674,42 +681,64 @@ export default defineComponent({
<v-card>
<v-card-title>
<v-row dense>
<v-spacer />
<v-tooltip bottom>
<template #activator="{ props: subProps }">
<v-btn
v-bind="subProps"
:variant="sideTab === 'recordings' ? 'flat' : 'outlined'"
:color="sideTab === 'recordings' ? 'primary' : ''"
class="mx-2"
size="small"
@click="sideTab = 'recordings'"
>
Recordings
</v-btn>
</template>
<span>
View Recordings in sideTab
</span>
</v-tooltip>
<v-tooltip bottom>
<template #activator="{ props: subProps }">
<v-btn
v-bind="subProps"
:variant="sideTab === 'annotations' ? 'flat' : 'outlined'"
:color="sideTab === 'annotations' ? 'primary' : ''"
class="mx-2"
size="small"
@click="sideTab = 'annotations'"
<v-col cols="2">
<v-tooltip v-if="combinedTags.length">
<template #activator="{ props: subProps }">
<v-icon v-bind="subProps">
mdi-filter
</v-icon>
</template>
Filtering by:
<v-chip
v-for="tag in combinedTags"
:key="tag"
>
Annotations
</v-btn>
</template>
<span>
View Annotations in sideTab
</span>
</v-tooltip>
<v-spacer />
{{ tag }}
</v-chip>
</v-tooltip>
<v-spacer v-else />
</v-col>
<v-col cols="4">
<v-tooltip bottom>
<template #activator="{ props: subProps }">
<v-btn
v-bind="subProps"
:variant="sideTab === 'recordings' ? 'flat' : 'outlined'"
:color="sideTab === 'recordings' ? 'primary' : ''"
class="mx-2"
size="small"
@click="sideTab = 'recordings'"
>
Recordings
</v-btn>
</template>
<span>
View Recordings in sideTab
</span>
</v-tooltip>
</v-col>
<v-col cols="4">
<v-tooltip bottom>
<template #activator="{ props: subProps }">
<v-btn
v-bind="subProps"
:variant="sideTab === 'annotations' ? 'flat' : 'outlined'"
:color="sideTab === 'annotations' ? 'primary' : ''"
class="mx-2"
size="small"
@click="sideTab = 'annotations'"
>
Annotations
</v-btn>
</template>
<span>
View Annotations in sideTab
</span>
</v-tooltip>
</v-col>
<v-col>
<v-spacer />
</v-col>
</v-row>
</v-card-title>
<v-card-text class="pa-0">
Expand Down