Skip to content
Open
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 frontend/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ declare module 'vue' {
IconEcosystem: typeof import('./src/components/icons/IconEcosystem.vue')['default']
IconSupport: typeof import('./src/components/icons/IconSupport.vue')['default']
IconTooling: typeof import('./src/components/icons/IconTooling.vue')['default']
InputText: typeof import('primevue/inputtext')['default']
Menubar: typeof import('primevue/menubar')['default']
Panel: typeof import('primevue/panel')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
TaskDetail: typeof import('./src/components/TaskDetail.vue')['default']
TasksTable: typeof import('./src/components/TasksTable.vue')['default']
ToggleButton: typeof import('primevue/togglebutton')['default']
}
}
37 changes: 33 additions & 4 deletions frontend/src/components/TaskDetail.vue
Original file line number Diff line number Diff line change
@@ -1,22 +1,51 @@
<script setup lang="ts">
import { ref, watch } from 'vue';
import { useTasksStore } from '@/stores/tasks';

defineProps<{
task: any | null
const props = defineProps<{
task: any | null,
session?: string
}>();

const tasksStore = useTasksStore();
const editMode = ref(false);
const editableTrace = ref<any>({});

watch(() => props.task, (newVal) => {
if (newVal && newVal.trace) {
editableTrace.value = { ...newVal.trace };
} else {
editableTrace.value = {};
}
}, { immediate: true, deep: true });

const saveChanges = async () => {
if (props.task && props.session) {
await tasksStore.updateTask(props.session, props.task.id, editableTrace.value);
editMode.value = false;
}
};
</script>

<template>
<Panel>
<DataTable :value="task?.trace" tableStyle="min-width: 50rem" scrollable scrollHeight="400px">
<template #header>
<div style="display: flex; gap: 1rem; align-items: center;">
<span class="p-panel-title">Trace Details</span>
<ToggleButton v-model="editMode" onLabel="Editing" offLabel="Edit Mode" onIcon="pi pi-check" offIcon="pi pi-pencil" style="width: 8rem" />
<Button v-if="editMode" label="Save" icon="pi pi-save" severity="success" @click="saveChanges" />
</div>
</template>
<DataTable :value="editMode ? editableTrace : task?.trace" tableStyle="min-width: 50rem" scrollable scrollHeight="400px">
<Column header="Key">
<template #body="slotProps">
{{ slotProps.index }}
</template>
</Column>
<Column header="Value">
<template #body="slotProps">
{{ slotProps.data }}
<InputText v-if="editMode" v-model="editableTrace[slotProps.index]" style="width: 100%" />
<span v-else>{{ slotProps.data }}</span>
</template>
</Column>
</DataTable>
Expand Down
20 changes: 17 additions & 3 deletions frontend/src/stores/tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import {defineStore} from 'pinia'

export const useTasksStore = defineStore('tasks', () => {

const tasks = ref([])
const tasks = ref<any[]>([])

const taskSelected = ref(null)
const taskSelected = ref<any>(null)

const load = async (id:string)=>{
const data = await fetch(`${import.meta.env.VITE_API_URL}/tasks/${id}`)
Expand All @@ -16,5 +16,19 @@ export const useTasksStore = defineStore('tasks', () => {
taskSelected.value = task
}

return { tasks, load, taskSelected, setSelected }
const updateTask = async (session: string, taskId: number, updates: any) => {
const response = await fetch(`${import.meta.env.VITE_API_URL}/tasks/${session}/${taskId}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(updates)
})
tasks.value = await response.json()
if (taskSelected.value && taskSelected.value.id === taskId) {
taskSelected.value = tasks.value.find((t: any) => t.id === taskId) || taskSelected.value
}
}

return { tasks, load, taskSelected, setSelected, updateTask }
})
1 change: 1 addition & 0 deletions frontend/src/views/TaskView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const goBack = ()=>{
<div class="content-container">
<TaskDetail
:task="store.taskSelected"
:session="refIds.id"
/>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ interface StorageService {
List<TaskDetail> tasks(String session)

void renameWorkDir(String oldPath, String newPath, String task)

void updateTask(String session, Long taskId, Map<String, Object> traceUpdates)
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,10 @@ class ApiController {
storageService.renameWorkDir(renameRequest.oldPath(), renameRequest.newPath(), renameRequest.task())
executions()
}

@Put("/tasks/{session}/{taskId}")
List<TaskDetail> updateTask(String session, Long taskId, @Body Map<String, Object> updates){
storageService.updateTask(session, taskId, updates)
tasks(session)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,17 @@ abstract class AbstractStorage implements StorageService{
renameWorkDir0(oldPath, newPath, task)
}

final void updateTask(String session, Long taskId, Map<String, Object> traceUpdates) {
def details = tasks(session)
def task = details.find { it.id == taskId }
if (task) {
traceUpdates.each { k, v ->
task.trace[k] = v
}
saveTasks(session, details)
}
}

private void renameWorkDir0(String oldPath, String newPath, String task){
newPath = newPath.endsWith("/") ? newPath : "$newPath/"
def executions = executions()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,15 @@ class DuckdbStorage extends AbstractStorage{

@Override
protected void saveTasks(String session, List<TaskDetail> tasks) {

validateConnection()
tasks.each { task ->
def payload = [
KryoHelper.serialize(task.trace),
task.context ? KryoHelper.serialize(task.context) : new byte[0],
Integer.valueOf(task.refCount)
]
byte[] bytes = KryoHelper.serialize(payload)
sql.execute("update CACHE_ENTRIES set entry=? where id=? and session_id=?", [bytes, task.id, session])
}
}
}