Skip to content

Commit

Permalink
Merge pull request #139 from LCOGT/feature/operation_graph
Browse files Browse the repository at this point in the history
Added a graph view of the operations using vueflow
  • Loading branch information
LTDakin authored Jan 21, 2025
2 parents ac48161 + b1982b1 commit 97fbd06
Show file tree
Hide file tree
Showing 9 changed files with 9,476 additions and 552 deletions.
9,524 changes: 9,031 additions & 493 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"@dagrejs/dagre": "^1.1.4",
"@geoman-io/leaflet-geoman-free": "^2.17.0",
"@mdi/font": "5.9.55",
"@vue-flow/background": "^1.3.2",
"@vue-flow/core": "^1.42.0",
"chart.js": "^4.4.6",
"core-js": "^3.8.3",
"leaflet": "^1.9.4",
Expand All @@ -19,6 +22,7 @@
"pinia-plugin-persistedstate": "^3.2.1",
"roboto-fontface": "*",
"serve": "^14.2.1",
"update": "^0.7.4",
"vue": "^3.5.9",
"vue-router": "^4.2.5",
"vuetify": "^3.7.4",
Expand Down
136 changes: 90 additions & 46 deletions src/components/DataSession/DataSession.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<script setup>
import { ref, defineEmits, defineProps, onMounted, watch } from 'vue'
import OperationPipeline from './OperationPipeline.vue'
import { fetchApiCall, handleError, deleteOperation } from '../../utils/api'
import OperationPipelineFlow from './OperationGraph/OperationPipelineFlow.vue'
import { fetchApiCall, handleError, deleteOperation } from '@/utils/api.js'
import { calculateColumnSpan } from '@/utils/common'
import { useConfigurationStore } from '@/stores/configuration'
import ImageGrid from '../Global/ImageGrid'
import OperationWizard from './OperationWizard.vue'
import ImageGrid from '@/components/Global/ImageGrid.vue'
import OperationWizard from '@/components/DataSession/OperationWizard.vue'
const props = defineProps({
data: {
Expand All @@ -24,11 +25,13 @@ const emit = defineEmits(['reloadSession'])
const images = ref([...props.data.input_data])
const filteredImages = ref([...images.value])
const showWizardDialog = ref(false)
const tab = ref('main')
const dataSessionsUrl = store.datalabApiBaseUrl + 'datasessions/'
const imagesPerRow = 4
var operationMap = {}
var selectedOperation = -1
var selectedOperationIndex = ref(-1)
async function addCompletedOperationsOutput() {
const url = dataSessionsUrl + props.data.id + '/operations/'
Expand Down Expand Up @@ -67,15 +70,15 @@ function addCompletedOperation(operationResponse) {
}
function selectOperation(operationIndex) {
if (operationIndex != operationMap[selectedOperation]) {
if (operationIndex == -1) {
selectedOperation = -1
}
else {
selectedOperation = props.data.operations[operationIndex].id
}
reconcileFilteredImages()
if (operationIndex == selectedOperationIndex.value) {
selectedOperationIndex.value = -1
selectedOperation = -1
}
else {
selectedOperation = props.data.operations[operationIndex].id
selectedOperationIndex.value = operationIndex
}
reconcileFilteredImages()
}
function reconcileOperationImages() {
Expand Down Expand Up @@ -135,52 +138,93 @@ onMounted(() => {
</script>

<template>
<v-container class="d-lg-flex ds-container">
<v-col
cols="3"
align="center"
<v-card>
<v-tabs
v-model="tab"
class="hide-tabs"
>
<!-- The operations bar list goes here -->
<operation-pipeline
:session-id="data.id"
:operations="data.operations"
:active="props.active"
@operation-completed="addCompletedOperation"
@select-operation="selectOperation"
@operation-was-deleted="emit('reloadSession')"
@delete-operation="(operationID) => deleteOperation(props.data.id, operationID, emit('reloadSession'))"
<v-tab
value="graph"
class="d-none"
/>
<v-tab
value="main"
class="d-none"
/>
<v-btn
variant="flat"
class="addop_button"
>
Add Operation
<v-dialog
v-model="showWizardDialog"
activator="parent"
fullscreen
transition="dialog-bottom-transition"
>
<operation-wizard
</v-tabs>
<v-tabs-window v-model="tab">
<v-tabs-window-item value="graph">
<v-container class="d-lg-flex ds-container graph-container">
<operation-pipeline-flow
:session-id="data.id"
:operations="data.operations"
:selected-operation="selectedOperationIndex"
:images="images"
@close-wizard="showWizardDialog = false"
@add-operation="addOperation"
:active="props.active"
@select-operation="selectOperation"
@close-graph="tab = 'main'"
/>
</v-container>
</v-tabs-window-item>
<v-tabs-window-item value="main">
<v-container class="d-lg-flex ds-container">
<v-col
cols="3"
align="center"
>
<!-- The operations bar list goes here -->
<operation-pipeline
:session-id="data.id"
:operations="data.operations"
:active="props.active"
:selected-operation="selectedOperationIndex"
@operation-completed="addCompletedOperation"
@select-operation="selectOperation"
@operation-was-deleted="emit('reloadSession')"
@delete-operation="(operationID) => deleteOperation(props.data.id, operationID, emit('reloadSession'))"
@view-graph="tab = 'graph'"
/>
<v-btn
variant="flat"
class="addop_button"
>
Add Operation
<v-dialog
v-model="showWizardDialog"
activator="parent"
fullscreen
transition="dialog-bottom-transition"
>
<operation-wizard
:images="images"
@close-wizard="showWizardDialog = false"
@add-operation="addOperation"
/>
</v-dialog>
</v-btn>
</v-col>
<image-grid
:images="filteredImages"
:column-span="calculateColumnSpan(filteredImages.length, imagesPerRow)"
/>
</v-dialog>
</v-btn>
</v-col>
<image-grid
:images="filteredImages"
:column-span="calculateColumnSpan(filteredImages.length, imagesPerRow)"
/>
</v-container>
</v-container>
</v-tabs-window-item>
</v-tabs-window>
</v-card>
</template>

<style scoped>
.hide-tabs {
height:0px;
}
.ds-container {
background-color: var(--metal);
display: flex;
}
.graph-container {
padding: 0;
height: 800px;
}
.addop_button {
font-size: 1rem;
align-content: center;
Expand Down
28 changes: 28 additions & 0 deletions src/components/DataSession/OperationGraph/ImagesNode.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<script setup>
import ImageGrid from '@/components/Global/ImageGrid.vue'
import { calculateColumnSpan } from '@/utils/common'
const props = defineProps({
id: {
type: String,
required: true,
},
data: {
type: Object,
required: true,
},
})
const imagesPerRow = 6
</script>

<template>
<image-grid
:images="props.data.images"
:column-span="calculateColumnSpan(props.data.images.length, data.imagesPerRow || imagesPerRow)"
/>
</template>

<style scoped>
</style>
53 changes: 53 additions & 0 deletions src/components/DataSession/OperationGraph/OperationNode.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<script setup>
import LoadBarButton from '@/components/DataSession/LoadBarButton.vue'
import { defineEmits} from 'vue'
const props = defineProps({
id: {
type: String,
required: true,
},
selectedId: {
type: Number,
required: true,
},
data: {
type: Object,
required: true,
},
})
const emit = defineEmits(['selectOperation'])
function selectOperation(index) {
if (index == props.selectedId) {
emit('selectOperation', -1)
}
else {
emit('selectOperation', index)
}
}
</script>

<template>
<load-bar-button
:class="{selected: props.id == props.selectedId}"
class="operation_button nodrag"
progress="100"
@click="selectOperation(props.id)"
>
<p>
{{ props.id }}: {{ props.data.name }}
</p>
</load-bar-button>
</template>

<style scoped>
.operation_button {
width: 12rem;
height: 3rem;
font-size: 1rem;
font-weight: 600;
color: var(--metal);
}
</style>
Loading

0 comments on commit 97fbd06

Please sign in to comment.