Skip to content

Commit

Permalink
Merge pull request #72 from LCOGT/fix/schedule-flow
Browse files Browse the repository at this point in the history
Fix/schedule flow
  • Loading branch information
capetillo authored Nov 1, 2024
2 parents 3604531 + ac1e33f commit 2eac46b
Show file tree
Hide file tree
Showing 29 changed files with 2,007 additions and 1,137 deletions.
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>
</div>
</div>
</div>
<button class="button red-bg" @click="router.push('/schedule')">Schedule Observations</button>
Expand Down
29 changes: 11 additions & 18 deletions src/components/Images/MyGallery.vue
Original file line number Diff line number Diff line change
@@ -1,48 +1,41 @@
<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 || []
// choosing 16 minutes because each session is 15 minutes long and this way we can show the last session once it's completed
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

0 comments on commit 2eac46b

Please sign in to comment.