Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/schedule flow #72

Merged
merged 30 commits into from
Nov 1, 2024
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f29b79a
allows user to select different targets
capetillo Sep 23, 2024
f5f5f65
adds object selection and populates from api
capetillo Sep 30, 2024
cfb90e4
adds recommended filters
capetillo Sep 30, 2024
78eac9f
sends post request to requestgroups
capetillo Oct 1, 2024
0c66eb9
added scheduling settings component
capetillo Oct 4, 2024
09d8080
added props and changed computed property
capetillo Oct 4, 2024
bbd8e18
imports calendar and scheduling settings components
capetillo Oct 4, 2024
34e4f5f
installs vue date picker
capetillo Oct 4, 2024
ab47657
renders based on beginner or advanced mode
capetillo Oct 4, 2024
a2f9371
updates store format to have upcoming and fulfilled requests
capetillo Oct 16, 2024
4172973
applies updated store format
capetillo Oct 16, 2024
95179c6
updates tests and components to reflect changes in store
capetillo Oct 21, 2024
daa41d8
updates store. sessions are now separated as upcomingrealtimesessions…
capetillo Oct 21, 2024
f2faa33
adds test for session store
capetillo Oct 22, 2024
4cee727
updates test to include another poll
capetillo Oct 22, 2024
cb1d706
tests for api calls success and failures in scheduling settings
capetillo Oct 23, 2024
fb99cd3
improves the flow of advanced scheduling, beginner scheduling, and th…
capetillo Oct 23, 2024
40e9247
tests scheduling view to schedule an observation
capetillo Oct 23, 2024
815bac2
merge
capetillo Oct 23, 2024
0974e95
corrects an error in the test (and some console logs)
capetillo Oct 23, 2024
61c9f11
fixes issue where 'MANY' was the default for advanced
capetillo Oct 23, 2024
3cf0b74
fixes issue where schedule my observation button was enabled when it …
capetillo Oct 24, 2024
2ddd2eb
PR fixes
capetillo Oct 30, 2024
0c4f292
separated stores -> updated files where old store was used. removed h…
capetillo Nov 1, 2024
4bb6dd7
updated tests
capetillo Nov 1, 2024
4926a52
renamed sessions store to realtimesessionsstore
capetillo Nov 1, 2024
11a8f6c
updated the way dates are split
capetillo Nov 1, 2024
149e154
updates test to reflect changes on whatsup api call
capetillo Nov 1, 2024
0f5555c
removes console log
capetillo Nov 1, 2024
ac1e33f
adds comments
capetillo Nov 1, 2024
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
1,297 changes: 640 additions & 657 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,22 @@
"@fortawesome/free-solid-svg-icons": "^6.5.2",
"@fortawesome/pro-regular-svg-icons": "^6.6.0",
"@fortawesome/vue-fontawesome": "^3.0.6",
"@vuepic/vue-datepicker": "^9.0.3",
"bulma": "^1.0.0",
"core-js": "^3.8.3",
"d3-celestial": "^0.7.35",
"date-fns": "^4.1.0",
"flush-promises": "^1.0.2",
"leaflet": "^1.9.4",
"lottie-web-vue": "^2.0.7",
"material-icons": "^1.13.12",
"pinia": "^2.1.7",
"pinia": "^2.2.2",
"pinia-plugin-persistedstate": "^3.2.1",
"sass": "^1.75.0",
"sass-loader": "^14.2.1",
"v-calendar": "^3.1.2",
"vue": "^3.2.13",
"vue-demi": "^0.14.10",
"vue-router": "^4.3.2",
"vuetify": "^3.5.16"
},
Expand Down
36 changes: 19 additions & 17 deletions src/components/Dashboard/UpcomingBookings.vue
Original file line number Diff line number Diff line change
@@ -1,54 +1,52 @@
<script setup>
import { useRouter } from 'vue-router'
import { ref, computed, onMounted } from 'vue'
import { useSessionsStore } from '../../stores/sessions'
import { useRealTimeSessionsStore } from '../../stores/realTimeSessions'
import { useObsPortalDataStore } from '../../stores/obsPortalData'
import { useUserDataStore } from '../../stores/userData'
import { useConfigurationStore } from '../../stores/configuration'
import { formatDate, formatTime } from '../../utils/formatTime.js'
import { fetchApiCall } from '../../utils/api.js'

const router = useRouter()
const sessionsStore = useSessionsStore()
const realTimeSessionsStore = useRealTimeSessionsStore()
const userDataStore = useUserDataStore()
const configurationStore = useConfigurationStore()
const obsPortalDataStore = useObsPortalDataStore()

const requestGroups = ref([])
// change to bookings and add an icon to show completion
const sortedSessions = computed(() => {
const now = new Date().getTime()
// TODO: Show past sessions for a certain amount of time in a separate section
const twoHoursAgo = now - 120 * 60 * 1000
const sessions = sessionsStore.sessions.results || []
const sessions = Object.values(obsPortalDataStore.upcomingRealTimeSessions)
return sessions.filter(session => new Date(session.start).getTime() >= twoHoursAgo)
.slice()
.sort((a, b) => new Date(a.start) - new Date(b.start))
})

const observations = ref([
{ id: 1, title: 'M83', progress: 10, state: 'scheduled' },
{ id: 2, title: 'NGC891', progress: 30 },
{ id: 3, title: 'Andromeda in RGB', progress: 80 },
{ id: 4, title: 'M16', progress: 30 }
])

const selectSession = (sessionId) => {
sessionsStore.currentSessionId = sessionId
realTimeSessionsStore.currentSessionId = sessionId
router.push(`/realtime/${sessionId}`)
}

async function deleteSession (sessionId) {
sessionsStore.currentSessionId = sessionId
realTimeSessionsStore.currentSessionId = sessionId
const token = userDataStore.authToken
await fetchApiCall({
url: configurationStore.observationPortalUrl + `realtime/${sessionId}/`,
method: 'DELETE',
header: { Authorization: `Token ${token}` },
successCallback: sessionsStore.sessions.results = sessionsStore.sessions.results.filter(session => session.id !== sessionId),
successCallback: obsPortalDataStore.upcomingRealTimeSessions = obsPortalDataStore.upcomingRealTimeSessions.filter(session => session.id !== sessionId),
failCallback: (error) => { console.error('API call failed with error', error) }
})
}

onMounted(() => {
sessionsStore.fetchSessions()
obsPortalDataStore.fetchCompleteObservationsAndUpcomingRTSessions()
obsPortalDataStore.fetchPendingRequestGroups()
requestGroups.value = obsPortalDataStore.pendingRequestGroups
})

</script>
Expand All @@ -66,10 +64,14 @@ onMounted(() => {
<button class="button red-bg" @click="router.push('/book/realtime')"> Book Slot </button>
</div>
<div class="observations">
<h3>Scheduled Observations</h3>
<h3>Pending Requests</h3>
<div class="table-summary">
<div v-for="({id, title, progress}) in observations" :key="id">
<div>{{ title }}</div><div><progress class="progress is-large is-primary" :value="progress" max="100">{{ progress }}%</progress></div>
<div v-for="requestGroup in requestGroups" :key="requestGroup.id">
<div v-for="request in requestGroup.requests" :key="request.id">
<div>{{ request.configurations[0].target.name }}</div>
<!-- TO DO: Define progress and get progress from api -->
<div><progress class="progress is-large is-primary" :value="progress" max="100">{{ progress }}%</progress></div>
capetillo marked this conversation as resolved.
Show resolved Hide resolved
</div>
</div>
</div>
<button class="button red-bg" @click="router.push('/schedule')">Schedule Observations</button>
Expand Down
28 changes: 10 additions & 18 deletions src/components/Images/MyGallery.vue
Original file line number Diff line number Diff line change
@@ -1,48 +1,40 @@
<script setup>
import { computed, ref, onMounted } from 'vue'
import { useSessionsStore } from '../../stores/sessions'
import { useUserDataStore } from '../../stores/userData'
import { useObsPortalDataStore } from '../../stores/obsPortalData'
import { useConfigurationStore } from '../../stores/configuration'
import { formatDate } from '../../utils/formatTime.js'
import { fetchApiCall } from '../../utils/api.js'

const sessionsStore = useSessionsStore()
const userDataStore = useUserDataStore()
const configurationStore = useConfigurationStore()
const obsPortalDataStore = useObsPortalDataStore()

const thumbnailsMap = ref({})
const loading = ref(true)

const filteredSessions = computed(() => {
const now = new Date()
const cutoffTime = new Date(now.getTime() - 16 * 60 * 1000)
const sessions = sessionsStore.sessions.results || []
const sixteenMinutes = 16 * 60 * 1000
const cutoffTime = new Date(now.getTime() - sixteenMinutes)
// Object.values returns an array of all the values of the object
const sessions = Object.values(obsPortalDataStore.completedObservations)
const filtered = sessions
.filter(session => new Date(session.start) < cutoffTime)
.sort((a, b) => new Date(b.start) - new Date(a.start))
return filtered
})

const getThumbnails = async (sessionId) => {
const token = userDataStore.authToken
const headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Token ${token}`
}

const getThumbnails = async (observationId) => {
await fetchApiCall({
url: configurationStore.thumbnailArchiveUrl + `thumbnails/?observation_id=${sessionId}&size=large`,
url: configurationStore.thumbnailArchiveUrl + `thumbnails/?observation_id=${observationId}&size=large`,
method: 'GET',
header: headers,
successCallback: (data) => {
if (data.results.length > 0) {
thumbnailsMap.value[sessionId] = data.results.map(result => result.url)
thumbnailsMap.value[observationId] = data.results.map(result => result.url)
}
loading.value = false
},
failCallback: (error) => {
console.error('Error fetching thumbnails for session:', sessionId, error)
console.error('Error fetching thumbnails for session:', observationId, error)
loading.value = false
}
})
Expand Down
8 changes: 4 additions & 4 deletions src/components/RealTimeInterface/CelestialMap/SkyChart.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<script setup>
import { ref, onMounted, watch } from 'vue'
import { useSessionsStore } from '../../../stores/sessions'
import { ref, onMounted } from 'vue'
import { useRealTimeSessionsStore } from '../../../stores/realTimeSessions'
import sites from '../../../utils/sites.JSON'
import celestial from 'd3-celestial'

const Celestial = celestial.Celestial ? celestial.Celestial() : celestial
const sessionsStore = useSessionsStore()
const realTimeSessionsStore = useRealTimeSessionsStore()

const lat = ref(35)
const lng = ref(-105)
Expand Down Expand Up @@ -146,7 +146,7 @@ function initializeCelestial () {
}

onMounted(() => {
const currentSession = sessionsStore.currentSession
const currentSession = realTimeSessionsStore.currentSession
if (currentSession && currentSession.site) {
const siteInfo = sites[currentSession.site]
if (siteInfo && Celestial) {
Expand Down
6 changes: 3 additions & 3 deletions src/components/RealTimeInterface/GlobeMap/WindyMap.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<script setup>
import { computed } from 'vue'
import { useSessionsStore } from '../../../stores/sessions'
import { useRealTimeSessionsStore } from '../../../stores/realTimeSessions'
import sites from '../../../utils/sites.JSON'

const sessionsStore = useSessionsStore()
const realTimeSessionsStore = useRealTimeSessionsStore()

const selectedSession = sessionsStore.currentSession
const selectedSession = realTimeSessionsStore.currentSession

const siteInfo = computed(() => {
if (selectedSession && selectedSession.site) {
Expand Down
15 changes: 3 additions & 12 deletions src/components/RealTimeInterface/PolledThumbnails.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
<script setup>
import { ref, onMounted, defineEmits } from 'vue'
import { useSessionsStore } from '../../stores/sessions'
import { useRealTimeSessionsStore } from '../../stores/realTimeSessions'
import { fetchApiCall } from '../../utils/api'
import { useConfigurationStore } from '../../stores/configuration'
import { useUserDataStore } from '../../stores/userData'

const sessionsStore = useSessionsStore()
const currentSession = sessionsStore.currentSession
const userDataStore = useUserDataStore()
const realTimeSessionsStore = useRealTimeSessionsStore()
const currentSession = realTimeSessionsStore.currentSession
const configurationStore = useConfigurationStore()

const sessionId = currentSession.id
Expand All @@ -19,16 +17,9 @@ const thumbnails = ref([])
let pollingInterval = null

const getThumbnails = async () => {
const token = userDataStore.authToken
const headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Token ${token}`
}
await fetchApiCall({
url: configurationStore.thumbnailArchiveUrl + `thumbnails/?observation_id=${sessionId}&size=large`,
method: 'GET',
header: headers,
successCallback: (data) => {
thumbnails.value = data.results.map(result => result.url)
if (thumbnails.value.length > 0) {
Expand Down
8 changes: 4 additions & 4 deletions src/components/RealTimeInterface/SessionImageCapture.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import PolledThumbnails from './PolledThumbnails.vue'
import { fetchApiCall } from '../../utils/api.js'
import { useConfigurationStore } from '../../stores/configuration'
import { useSessionsStore } from '../../stores/sessions'
import { useRealTimeSessionsStore } from '../../stores/realTimeSessions'
import { LottieAnimation } from 'lottie-web-vue'
import BlocksJSON from '@/assets/progress-blocks-bodymovin.json'
import GalaxyJSON from '@/assets/galaxy_loading_pixels.json'

const configurationStore = useConfigurationStore()
const sessionsStore = useSessionsStore()
const realTimeSessionsStore = useRealTimeSessionsStore()

const status = ref(null)
let pollingInterval = null
Expand Down Expand Up @@ -40,7 +40,7 @@ const fetchTelescopeStatus = async () => {
imagesDone.value = false
return
}
const token = sessionsStore.getTokenForCurrentSession
const token = realTimeSessionsStore.getTokenForCurrentSession
const headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
Expand Down Expand Up @@ -71,7 +71,7 @@ const goBackToSessionStarted = () => {
}

const sendStopCommand = async () => {
const token = sessionsStore.getTokenForCurrentSession
const token = realTimeSessionsStore.getTokenForCurrentSession
const headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
Expand Down
6 changes: 3 additions & 3 deletions src/components/RealTimeInterface/SessionPending.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<script setup>
import { computed } from 'vue'
import { useSessionsStore } from '../../stores/sessions'
import { useRealTimeSessionsStore } from '../../stores/realTimeSessions'
import sites from '../../utils/sites.JSON'
import WindyMap from './GlobeMap/WindyMap.vue'

const sessionsStore = useSessionsStore()
const realTimeSessionsStore = useRealTimeSessionsStore()

const selectedSession = sessionsStore.currentSession
const selectedSession = realTimeSessionsStore.currentSession

const lat = computed(() => sites[selectedSession.site]?.lat)
const lon = computed(() => sites[selectedSession.site]?.lon)
Expand Down
20 changes: 10 additions & 10 deletions src/components/RealTimeInterface/SessionStarted.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import AladinSkyMap from '../RealTimeInterface/AladinSkyMap.vue'
import SkyChart from '../RealTimeInterface/CelestialMap/SkyChart.vue'
import SessionImageCapture from '../RealTimeInterface/SessionImageCapture.vue'
import { calcAltAz } from '../../utils/visibility.js'
import { useSessionsStore } from '../../stores/sessions'
import { useRealTimeSessionsStore } from '../../stores/realTimeSessions'
import sites from '../../utils/sites.JSON'
import { fetchApiCall } from '../../utils/api'
import { useConfigurationStore } from '../../stores/configuration'
import { useUserDataStore } from '../../stores/userData'

const sessionsStore = useSessionsStore()
const realTimeSessionsStore = useRealTimeSessionsStore()
const configurationStore = useConfigurationStore()
const userDataStore = useUserDataStore()

Expand All @@ -20,7 +20,7 @@ const isCapturingImages = computed(() => {
// Change this to true to test the image capture component and false for target select
return true
} else {
return sessionsStore.isCapturingImagesForCurrentSession
return realTimeSessionsStore.isCapturingImagesForCurrentSession
}
})

Expand All @@ -39,7 +39,7 @@ const loading = ref(false)
const exposureError = ref('')
const isExposureTimeValid = ref(true)

const currentSession = sessionsStore.currentSession
const currentSession = realTimeSessionsStore.currentSession
const siteInfo = sites[currentSession.site]

function getRaDecFromTargetName () {
Expand Down Expand Up @@ -87,7 +87,7 @@ function changeFov (fov) {
}

const resetValues = () => {
sessionsStore.updateImageCaptureState(true)
realTimeSessionsStore.updateImageCaptureState(true)
ra.value = ''
dec.value = ''
targetName.value = ''
Expand All @@ -103,7 +103,7 @@ const sendGoCommand = async () => {
exposureError.value = ''
isExposureTimeValid.value = true

const token = sessionsStore.getTokenForCurrentSession
const token = realTimeSessionsStore.getTokenForCurrentSession
const headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
Expand All @@ -117,9 +117,9 @@ const sendGoCommand = async () => {
expTime: exposTime,
name: targetName.value,
ra: Number(ra.value) / 15,
proposalId: sessionsStore.currentSession.proposal,
requestGroupId: sessionsStore.currentSession.request_group_id,
requestId: sessionsStore.currentSession.request.id
proposalId: realTimeSessionsStore.currentSession.proposal,
requestGroupId: realTimeSessionsStore.currentSession.request_group_id,
requestId: realTimeSessionsStore.currentSession.request.id
}
if (configurationStore.demo == true) {
loading.value = false
Expand Down Expand Up @@ -163,7 +163,7 @@ const getFilterList = async () => {

function updateRenderGallery (value) {
if (!value) {
sessionsStore.updateImageCaptureState(false)
realTimeSessionsStore.updateImageCaptureState(false)
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/components/RealTimeInterface/TimePicker.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<script setup>
import { ref, watch, defineEmits, onMounted, computed } from 'vue'
import { useRouter } from 'vue-router'
import { useSessionsStore } from '../../stores/sessions'
import { useRealTimeSessionsStore } from '../../stores/realTimeSessions'
import { useUserDataStore } from '../../stores/userData'
import { fetchApiCall } from '../../utils/api'
import { formatToUTC, formatDate } from '../../utils/formatTime.js'
import { useConfigurationStore } from '../../stores/configuration'
import LeafletMap from './GlobeMap/LeafletMap.vue'

const router = useRouter()
const sessionsStore = useSessionsStore()
const realTimeSessionsStore = useRealTimeSessionsStore()
const configurationStore = useConfigurationStore()
const userDataStore = useUserDataStore()

Expand Down Expand Up @@ -126,7 +126,7 @@ const refreshTimes = () => {
const resetSession = () => {
errorMessage.value = null
selectedSite.value = null
sessionsStore.currentSessionId = null
realTimeSessionsStore.currentSessionId = null
}

const blockRti = async () => {
Expand Down
Loading
Loading