Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6527e68e52 |
@ -50,7 +50,6 @@ class WebConfig: WebMvcConfigurer {
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
override fun configurePathMatch(configurer: PathMatchConfigurer) {
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
package no.iktdev.mediaprocessing.ui.dto
|
||||
|
||||
import no.iktdev.mediaprocessing.shared.common.contract.data.Event
|
||||
|
||||
data class DatabaseEntriesDelete(
|
||||
val referenceId: String,
|
||||
val eventId: String
|
||||
)
|
||||
|
||||
data class DatabaseEventEntries(
|
||||
val referenceId: String,
|
||||
val events: List<Event>,
|
||||
val created: Long,
|
||||
val lastEventCreated: Long,
|
||||
)
|
||||
@ -0,0 +1,68 @@
|
||||
package no.iktdev.mediaprocessing.ui.socket
|
||||
|
||||
import no.iktdev.eventi.data.referenceId
|
||||
import no.iktdev.eventi.database.executeWithStatus
|
||||
import no.iktdev.eventi.database.toEpochSeconds
|
||||
import no.iktdev.eventi.database.withDirtyRead
|
||||
import no.iktdev.eventi.database.withTransaction
|
||||
import no.iktdev.mediaprocessing.shared.common.database.cal.toEvent
|
||||
import no.iktdev.mediaprocessing.shared.common.database.tables.events
|
||||
import no.iktdev.mediaprocessing.ui.dto.DatabaseEntriesDelete
|
||||
import no.iktdev.mediaprocessing.ui.dto.DatabaseEventEntries
|
||||
import no.iktdev.mediaprocessing.ui.eventDatabase
|
||||
import no.iktdev.mediaprocessing.ui.eventsManager
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
import org.jetbrains.exposed.sql.and
|
||||
import org.jetbrains.exposed.sql.deleteWhere
|
||||
import org.jetbrains.exposed.sql.selectAll
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.messaging.handler.annotation.MessageMapping
|
||||
import org.springframework.messaging.handler.annotation.Payload
|
||||
import org.springframework.messaging.simp.SimpMessagingTemplate
|
||||
import org.springframework.stereotype.Controller
|
||||
|
||||
@Controller
|
||||
class DatabaseEntriesTopic(
|
||||
@Autowired private val template: SimpMessagingTemplate?
|
||||
) {
|
||||
|
||||
private fun push(destination: String, payload: Any) = template?.convertAndSend(destination, payload)
|
||||
private fun push(payload: Any) = template?.convertAndSend(payload)
|
||||
|
||||
@MessageMapping("/database/events/pull")
|
||||
fun pullAllDatabaseEvents() {
|
||||
val result = withDirtyRead(eventDatabase.database) {
|
||||
events.selectAll().toEvent()
|
||||
.groupBy { it.referenceId() }.onEach { (t, u) ->
|
||||
u.sortedBy { x -> x.metadata.created }
|
||||
}
|
||||
} ?: emptyMap()
|
||||
result.map { it -> DatabaseEventEntries(
|
||||
referenceId = it.key,
|
||||
events = it.value,
|
||||
created = it.value.first().metadata.created.toEpochSeconds() * 1000L,
|
||||
lastEventCreated = it.value.last().metadata.created.toEpochSeconds() * 1000L
|
||||
) }.also {
|
||||
push(it)
|
||||
}
|
||||
}
|
||||
|
||||
@MessageMapping("/database/events/delete")
|
||||
fun deleteEvent(@Payload payload: DatabaseEntriesDelete) {
|
||||
val status = executeWithStatus (eventDatabase.database) {
|
||||
events.deleteWhere {
|
||||
(referenceId eq payload.referenceId) and
|
||||
(eventId eq payload.eventId)
|
||||
}
|
||||
}
|
||||
if (status) {
|
||||
pullAllDatabaseEvents()
|
||||
}
|
||||
}
|
||||
|
||||
@MessageMapping("/database/tasks")
|
||||
fun pullAllDatabaseTasks() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -5,7 +5,6 @@ import no.iktdev.eventi.data.referenceId
|
||||
import no.iktdev.eventi.database.toEpochSeconds
|
||||
import no.iktdev.eventi.database.withDirtyRead
|
||||
import no.iktdev.eventi.database.withTransaction
|
||||
import no.iktdev.mediaprocessing.shared.common.contract.Events
|
||||
import no.iktdev.mediaprocessing.shared.common.contract.ProcessType
|
||||
import no.iktdev.mediaprocessing.shared.common.contract.data.*
|
||||
import no.iktdev.mediaprocessing.shared.common.contract.dto.OperationEvents
|
||||
@ -19,6 +18,7 @@ import no.iktdev.mediaprocessing.shared.common.task.TaskType
|
||||
import no.iktdev.mediaprocessing.ui.WebSocketMonitoringService
|
||||
import no.iktdev.mediaprocessing.ui.eventDatabase
|
||||
import no.iktdev.mediaprocessing.ui.socket.a2a.ProcesserListenerService
|
||||
import no.iktdev.mediaprocessing.ui.socket.impl.SocketListener
|
||||
import org.jetbrains.exposed.sql.selectAll
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.messaging.handler.annotation.MessageMapping
|
||||
@ -85,6 +85,7 @@ class ProcesserTasksTopic(
|
||||
val encode: Status = Status.Skipped,
|
||||
val extract: Status = Status.Skipped,
|
||||
val convert: Status = Status.Skipped,
|
||||
val completed: Status = Status.Awaiting,
|
||||
val created: Long
|
||||
) {}
|
||||
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
package no.iktdev.mediaprocessing.ui.socket
|
||||
|
||||
import no.iktdev.eventi.database.withTransaction
|
||||
import no.iktdev.mediaprocessing.shared.common.database.cal.toTask
|
||||
import no.iktdev.mediaprocessing.shared.common.database.tables.tasks
|
||||
import no.iktdev.mediaprocessing.shared.common.task.Task
|
||||
import no.iktdev.mediaprocessing.ui.eventDatabase
|
||||
import no.iktdev.mediaprocessing.ui.socket.impl.SocketListener
|
||||
import org.jetbrains.exposed.sql.selectAll
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.messaging.handler.annotation.MessageMapping
|
||||
import org.springframework.messaging.simp.SimpMessagingTemplate
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class TaskTableTopic(
|
||||
@Autowired private val message: SimpMessagingTemplate?,
|
||||
) : SocketListener(message) {
|
||||
|
||||
|
||||
|
||||
data class TaskGroup(
|
||||
val referenceId: String,
|
||||
val tasks: List<Task>
|
||||
)
|
||||
|
||||
@MessageMapping("/taskTable/all")
|
||||
fun pullAllTasks() {
|
||||
val result = withTransaction(eventDatabase.database) {
|
||||
tasks.selectAll().toTask()
|
||||
.groupBy { it.referenceId }.map { g -> TaskGroup(g.key, g.value) }
|
||||
} ?: emptyList()
|
||||
template?.convertAndSend("/topic/taskTable/all", result)
|
||||
}
|
||||
}
|
||||
@ -7,10 +7,9 @@ import no.iktdev.mediaprocessing.shared.common.task.Task
|
||||
import no.iktdev.mediaprocessing.ui.UIEnv
|
||||
import no.iktdev.mediaprocessing.ui.WebSocketMonitoringService
|
||||
import no.iktdev.mediaprocessing.ui.log
|
||||
import no.iktdev.mediaprocessing.ui.socket.SocketClient
|
||||
import no.iktdev.mediaprocessing.ui.socket.SocketMessageHandler
|
||||
import no.iktdev.mediaprocessing.ui.socket.impl.SocketClient
|
||||
import no.iktdev.mediaprocessing.ui.socket.impl.SocketMessageHandler
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.messaging.simp.SimpMessagingTemplate
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package no.iktdev.mediaprocessing.ui.socket
|
||||
package no.iktdev.mediaprocessing.ui.socket.impl
|
||||
|
||||
import mu.KotlinLogging
|
||||
import org.springframework.messaging.simp.stomp.StompCommand
|
||||
@ -1,4 +1,4 @@
|
||||
package no.iktdev.mediaprocessing.ui.socket
|
||||
package no.iktdev.mediaprocessing.ui.socket.impl
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.messaging.simp.SimpMessagingTemplate
|
||||
@ -1,4 +1,4 @@
|
||||
package no.iktdev.mediaprocessing.ui.socket
|
||||
package no.iktdev.mediaprocessing.ui.socket.impl
|
||||
|
||||
import org.springframework.messaging.simp.stomp.StompHeaders
|
||||
import org.springframework.messaging.simp.stomp.StompSessionHandlerAdapter
|
||||
@ -28,6 +28,7 @@ import InputIcon from '@mui/icons-material/Input';
|
||||
import NotStartedIcon from '@mui/icons-material/NotStarted';
|
||||
import EventsPage from './app/page/EventsPage';
|
||||
import TableChartIcon from '@mui/icons-material/TableChart';
|
||||
import SubscriptionsIcon from '@mui/icons-material/Subscriptions';
|
||||
|
||||
function App() {
|
||||
const client = useStompClient();
|
||||
@ -94,21 +95,22 @@ function App() {
|
||||
}}>
|
||||
<QueueIcon />
|
||||
</IconButton>
|
||||
<IconButton onClick={() => window.location.href = "/tasks"} sx={{
|
||||
<IconButton onClick={() => window.location.href = "/events"} sx={{
|
||||
...iconHeight
|
||||
}}>
|
||||
<TableChartIcon />
|
||||
<SubscriptionsIcon />
|
||||
</IconButton>
|
||||
</Box>
|
||||
<Box sx={{
|
||||
display: "block",
|
||||
maxHeight: window.screen.height - 70,
|
||||
height: window.screen.height - 70,
|
||||
maxHeight: window.innerHeight - 70,
|
||||
height: window.innerHeight - 70,
|
||||
width: "100vw",
|
||||
maxWidth: "100vw"
|
||||
}}>
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route path='/events' element={<EventsPage />} />
|
||||
<Route path='/processer' element={<EventsPage />} />
|
||||
<Route path='/unprocessed' element={<UnprocessedFilesPage />} />
|
||||
<Route path='/files' element={<ExplorePage />} />
|
||||
|
||||
@ -3,4 +3,19 @@ export interface CoordinatorOperationRequest {
|
||||
file: string;
|
||||
source: string;
|
||||
mode: "FLOW" | "MANUAL";
|
||||
}
|
||||
}
|
||||
|
||||
export interface Event {
|
||||
referenceId: string;
|
||||
eventId: string;
|
||||
event: string;
|
||||
data: any;
|
||||
created: number;
|
||||
}
|
||||
|
||||
export interface DatabaseEventEntry {
|
||||
referenceId: string;
|
||||
events: Array<Event>
|
||||
created: number;
|
||||
lastEventCreated: number;
|
||||
}
|
||||
@ -25,7 +25,7 @@ import SimpleTable from "../features/table/sortableTable";
|
||||
import { UnixTimestamp } from "../features/UxTc";
|
||||
import ProgressbarWithLabel from "../features/components/ProgressbarWithLabel";
|
||||
import { LinearProgress, Typography } from "@mui/material";
|
||||
import { stat } from "fs";
|
||||
import SaveIcon from '@mui/icons-material/Save';
|
||||
|
||||
interface RawNodeDatum {
|
||||
name: string;
|
||||
@ -107,6 +107,10 @@ function renderCustomNodeElement(nodeData: CustomNodeElementProps): JSX.Element
|
||||
workIcon = <AutoAwesomeMotionIcon />
|
||||
break;
|
||||
}
|
||||
case "completed": {
|
||||
workIcon = <SaveIcon />
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -163,6 +167,16 @@ const transformToSteps = (state: ContentEventState): RawNodeDatum => ({
|
||||
type: "convert",
|
||||
status: state.extract
|
||||
},
|
||||
children: [
|
||||
{
|
||||
name: state.referenceId,
|
||||
attributes: {
|
||||
type: "completed",
|
||||
status: state.completed
|
||||
},
|
||||
children: []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -181,7 +195,7 @@ export default function EventsPage() {
|
||||
const items = events.items.map((event: ContentEventState) => {
|
||||
return {
|
||||
rowId: event.referenceId,
|
||||
title: event.referenceId,
|
||||
title: event.title ?? event.referenceId,
|
||||
item: event
|
||||
} as ExpandableItemRow
|
||||
});
|
||||
@ -210,7 +224,7 @@ export default function EventsPage() {
|
||||
return (<>
|
||||
<div id="treeWrapper" style={{
|
||||
...linkThicc,
|
||||
width: '150px', height: '90px'
|
||||
width: '200px', height: '90px'
|
||||
}} ref={containerRef}>
|
||||
<Tree
|
||||
dimensions={dimensions}
|
||||
|
||||
@ -43,6 +43,7 @@ export interface ContentEventState {
|
||||
encode: Status
|
||||
extract: Status
|
||||
convert: Status
|
||||
completed: Status
|
||||
created: number
|
||||
encodeWork: ProcesserEventInfo
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user