Skip to content

Commit

Permalink
initial annotation-recording list
Browse files Browse the repository at this point in the history
  • Loading branch information
BryonLewis committed Feb 22, 2024
1 parent 46493c7 commit 52a30e7
Show file tree
Hide file tree
Showing 3 changed files with 328 additions and 15 deletions.
52 changes: 38 additions & 14 deletions client/src/components/AnnotationList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import { defineComponent, PropType } from "vue";
import { SpectroInfo } from './geoJS/geoJSUtils';
import useState from "../use/useState";
import { watch, ref } from "vue";
import RecordingList from "./RecordingList.vue";
export default defineComponent({
name: "AnnotationList",
components: {
RecordingList,
},
props: {
spectroInfo: {
Expand Down Expand Up @@ -36,9 +38,13 @@ export default defineComponent({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const tabSwitch = (event: any) => {
// On tab switches we want to deselect the curret anntation
tab.value = event as 'sequence' | 'pulse';
selectedType.value = event as 'sequence' | 'pulse';
selectedId.value = null;
if (['sequence', 'pulse'].includes(event)) {
tab.value = event as 'sequence' | 'pulse';
selectedType.value = event as 'sequence' | 'pulse';
selectedId.value = null;
} else {
tab.value = 'recordings';
}
};
return {
Expand All @@ -60,20 +66,38 @@ export default defineComponent({
<template>
<v-card class="pa-0 ma-0">
<v-card-title>
<v-tabs
v-model="tab"
@update:model-value="tabSwitch($event)"
>
<v-tab value="pulse">
Pulse
</v-tab>
<v-tab value="sequence">
Sequence
</v-tab>
</v-tabs>
<v-row dense>
<v-tabs
v-model="tab"
class="ma-auto"
@update:model-value="tabSwitch($event)"
>
<v-tab
value="recordings"
size="x-small"
>
Recordings
</v-tab>
<v-tab
value="pulse"
size="x-small"
>
Pulse
</v-tab>
<v-tab
value="sequence"
size="x-small"
>
Sequence
</v-tab>
</v-tabs>
</v-row>
</v-card-title>
<v-card-text class="">
<v-window v-model="tab">
<v-window-item value="recordings">
<recording-list />
</v-window-item>
<v-window-item value="pulse">
<v-row class="pa-2">
<v-col>
Expand Down
286 changes: 286 additions & 0 deletions client/src/components/RecordingList.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
<script lang="ts">
import { defineComponent, ref, Ref, onMounted } from 'vue';
import { deleteRecording, getRecordings, Recording } from '../api/api';
import {
VDataTable,
} from "vuetify/labs/VDataTable";
import { EditingRecording } from './UploadRecording.vue';
import MapLocation from './MapLocation.vue';
export default defineComponent({
components: {
VDataTable,

Check failure on line 12 in client/src/components/RecordingList.vue

View workflow job for this annotation

GitHub Actions / Lint [eslint]

The "VDataTable" component has been registered but not used
MapLocation,

Check failure on line 13 in client/src/components/RecordingList.vue

View workflow job for this annotation

GitHub Actions / Lint [eslint]

The "MapLocation" component has been registered but not used
},
setup() {
const itemsPerPage = ref(-1);
const recordingList: Ref<Recording[]> = ref([]);
const sharedList: Ref<Recording[]> = ref([]);
const editingRecording: Ref<EditingRecording | null> = ref(null);
let intervalRef: number | null = null;
const uploadDialog = ref(false);
const headers = ref([
{
title:'Edit',
key:'edit',
},
{
title:'Name',
key:'name',
},
{
title:'Owner',
key:'owner_username',
},
{
title:'Recorded Date',
key:'recorded_date',
},
{
title:'Public',
key:'public',
},
{
title: 'Location',
key:'recording_location'
},
{
title:'Equipment',
key:'equipment',
},
{
title:'Comments',
key:'comments',
},
{
title:'Users Annotated',
key:'userAnnotations',
},
]);
const sharedHeaders = ref([
{
title:'Name',
key:'name',
},
{
title:'Owner',
key:'owner_username',
},
{
title:'Recorded Date',
key:'recorded_date',
},
{
title:'Public',
key:'public',
},
{
title: 'Location',
key:'recording_location'
},
{
title:'Equipment',
key:'equipment',
},
{
title:'Comments',
key:'comments',
},
{
title:'Annotated by Me',
key:'userMadeAnnotations',
},
]);
const fetchRecordings = async () => {
const recordings = await getRecordings();
recordingList.value = recordings.data;
// If we have a spectrogram being generated we need to refresh on an interval
let missingSpectro = false;
for (let i =0; i< recordingList.value.length; i+=1) {
if (!recordingList.value[i].hasSpectrogram) {
missingSpectro = true;
break;
}
}
if (missingSpectro) {
if (intervalRef === null) {
intervalRef = setInterval(() => fetchRecordings(), 5000);
}
} else {
if (intervalRef !== null) {
clearInterval(intervalRef);
}
}
const shared = await getRecordings(true);
sharedList.value = shared.data;
};
onMounted(() => fetchRecordings());
const uploadDone = () => {
uploadDialog.value = false;
editingRecording.value = null;
fetchRecordings();
};
const editRecording = (item: Recording) => {
editingRecording.value = {
name: item.name,
equipment: item.equipment || '',
comments: item.comments || '',
date: item.recorded_date,
public: item.public,
id: item.id,
};
if (item.recording_location) {
const [ lon, lat ] = item.recording_location.coordinates;
editingRecording.value['location'] = {lat, lon};
}
uploadDialog.value = true;
};
const delRecording = async (id: number) => {
await deleteRecording(id);
fetchRecordings();
};
return {
itemsPerPage,
headers,
sharedHeaders,
recordingList,
sharedList,
uploadDialog,
uploadDone,
editRecording,
delRecording,
editingRecording,
};
},
});
</script>

<template>
<v-expansion-panels>
<v-expansion-panel>
<v-expansion-panel-title>My Recordings</v-expansion-panel-title>
<v-expansion-panel-text>
<div>
<v-row
dense
class="text-center"
>
<v-col class="text-left">
<b>Name</b>
</v-col>
<v-col><b>Public</b></v-col>
<v-col><b>Annotations</b></v-col>
</v-row>
</div>
<div
v-for="item in recordingList"
:key="`public_${item.id}`"
>
<v-row
dense
class="text-center"
>
<v-col class="text-left">
<router-link
:to="`/recording/${item.id.toString()}/spectrogram`"
>
{{ item.name }}
</router-link>
</v-col>
<v-col>
<v-icon
v-if="item.public"
color="success"
>
mdi-check
</v-icon>
<v-icon
v-else
color="error"
>
mdi-close
</v-icon>
</v-col>
<v-col>
<div>
{{ item.userAnnotations }}
</div>
</v-col>
</v-row>
</div>
</v-expansion-panel-text>
</v-expansion-panel>
<v-expansion-panel>
<v-expansion-panel-title>Public</v-expansion-panel-title>
<v-expansion-panel-text class="ma-0 pa-0">
<div>
<v-row
dense
class="text-center"
>
<v-col class="text-left">
<b>Name</b>
</v-col>
<v-col><b>Owner</b></v-col>
<v-col><b>Annotated</b></v-col>
</v-row>
</div>
<div
v-for="item in sharedList"
:key="`public_${item.id}`"
>
<v-row
dense
class="text-center"
>
<v-col class="text-left">
<router-link
:to="`/recording/${item.id.toString()}/spectrogram`"
>
{{ item.name }}
</router-link>
</v-col>
<v-col>
<div style="font-size:0.75em">
{{ item.owner_username }}
</div>
</v-col>
<v-col>
<div>
<v-icon
v-if="item.userMadeAnnotations"
color="success"
>
mdi-check
</v-icon>
<v-icon
v-else
color="error"
>
mdi-close
</v-icon>
</div>
</v-col>
</v-row>
</div>
</v-expansion-panel-text>
</v-expansion-panel>
</v-expansion-panels>
</template>

<style scoped>
.v-expansion-panel-text>>> .v-expansion-panel-text__wrap {
padding: 0 !important;
}
.v-expansion-panel-text__wrapper {
padding: 0 !important;
}
</style>
5 changes: 4 additions & 1 deletion client/src/views/Spectrogram.vue
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ export default defineComponent({
watch(gridEnabled, () => {
toggleLayerVisibility("grid");
});
watch(() => props.id, () => {
loadData();
});
onMounted(() => loadData());
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const parentGeoViewerRef: Ref<any> = ref(null);
Expand Down Expand Up @@ -353,7 +356,7 @@ export default defineComponent({
@selected="setSelection($event)"
/>
</v-col>
<v-col style="max-width: 300px">
<v-col style="max-width: 400px">
<annotation-list
:annotations="annotations"
:temporal-annotations="temporalAnnotations"
Expand Down

0 comments on commit 52a30e7

Please sign in to comment.