Skip to content

Commit

Permalink
feat(job): create recurring job
Browse files Browse the repository at this point in the history
  • Loading branch information
soofstad committed Nov 22, 2023
1 parent 5110039 commit 67f053b
Show file tree
Hide file tree
Showing 13 changed files with 215 additions and 212 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,14 @@
"name": "Dashboard",
"type": "CORE:UiRecipe",
"description": "ESS Plot",
"showRefreshButton": true,
"plugin": "@development-framework/dm-core-plugins/grid",
"config": {
"type": "PLUGINS:dm-core-plugins/grid/GridPluginConfig",
"size": {
"type": "PLUGINS:dm-core-plugins/grid/GridSize",
"columns": 2,
"rows": 2,
"rowSizes": [
"4fr",
"1fr"
],
"columnSizes": [
"1fr",
"2fr"
]
"rows": 4
},
"showItemBorders": false,
"items": [
Expand All @@ -33,7 +26,7 @@
"type": "PLUGINS:dm-core-plugins/grid/GridArea",
"rowStart": 1,
"columnStart": 1,
"rowEnd": 1,
"rowEnd": 3,
"columnEnd": 1
}
},
Expand All @@ -48,7 +41,7 @@
"type": "PLUGINS:dm-core-plugins/grid/GridArea",
"rowStart": 1,
"columnStart": 2,
"rowEnd": 1,
"rowEnd": 3,
"columnEnd": 2
}
},
Expand All @@ -60,9 +53,9 @@
},
"gridArea": {
"type": "PLUGINS:dm-core-plugins/grid/GridArea",
"rowStart": 2,
"rowStart": 4,
"columnStart": 1,
"rowEnd": 2,
"rowEnd": 4,
"columnEnd": 2
}
}
Expand Down Expand Up @@ -112,7 +105,6 @@
"plugin": "@development-framework/dm-core-plugins/job/single_job",
"config": {
"type": "PLUGINS:dm-core-plugins/job/JobConfig",
"recurring": false,
"jobTargetAddress": {
"type": "PLUGINS:dm-core-plugins/job/TargetAddress",
"targetAddress": ".job",
Expand Down
1 change: 1 addition & 0 deletions example/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ services:
environment:
AUTH_ENABLED: 0
ENVIRONMENT: local
# RESET_DATA_SOURCE: off
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: xd7wCEhEx4kszsecYFfC
SECRET_KEY: sg9aeUM5i1JO4gNN8fQadokJa3_gXQMLBjSGGYcfscs= # Don't reuse this in production...
Expand Down
4 changes: 2 additions & 2 deletions example/job_handlers/signal-app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ def start(self) -> str:
logger.info("Job started")
self.job.status = JobStatus.RUNNING
logger.info("after sleep")
application_input_reference = self.job.entity['applicationInput']['address']
application_input_reference = self.job.application_input['address']
input_entity = self._get_by_id(application_input_reference)
signal_length = int(input_entity["duration"] / input_entity["timeStep"])
new_signal_value = [random.randint(-50, 50) for value in range(signal_length)]
signal_reference: str = self.job.entity['outputTarget']
signal_reference: str = self.job.outputTarget
signal_entity = self._get_by_id(signal_reference)
signal_entity["value"] = new_signal_value
self._update(f"{signal_reference}", {"data": signal_entity})
Expand Down
2 changes: 0 additions & 2 deletions example/src/plugins/marmo-ui/containers/views/SignalPlot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import Plot from 'react-plotly.js'
const ESSPlotPlugin = (props: { document: TGenericObject }) => {
const { document } = props

console.log(document)

const yData = document.value
const xData: number[] = []

Expand Down
86 changes: 33 additions & 53 deletions packages/dm-core-plugins/src/job/CronJob.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { useEffect, useState } from 'react'
import { Autocomplete, Button } from '@equinor/eds-core-react'
import { Autocomplete } from '@equinor/eds-core-react'
import DateRangePicker from './DateRangePicker'
import styled from 'styled-components'
import { EBlueprint, TSchedule } from '@development-framework/dm-core'
import { TSchedule } from '@development-framework/dm-core'

enum EInterval {
HOURLY = 'Hourly',
Expand All @@ -27,26 +27,22 @@ const InputWrapper = styled.div`
padding-top: 1rem;
`

const ButtonWrapper = styled.div`
display: flex;
justify-content: flex-end;
gap: 0.5rem;
margin-top: 1rem;
`
const getIntervall = ({ cron }: { cron: string }): EInterval => {
const [, hour, dayOfMonth, , dayOfWeek] = cron.split(' ')
if (hour.includes('/')) return EInterval.HOURLY
if (dayOfMonth !== '*') return EInterval.MONTHLY
if (dayOfWeek !== '*') return EInterval.WEEKLY
if (dayOfWeek == '*') return EInterval.DAILY
return EInterval.DAILY
}

export function CreateRecurringJob(props: {
close: () => void
removeJob: () => void
export function ConfigureSchedule(props: {
isRegistered: boolean
// TODO: Export TCronJob from dm-core
setCronJob: (job: TSchedule) => void
cronJob?: TSchedule | undefined
setSchedule: (s: TSchedule) => void
schedule: TSchedule
}) {
const { close, removeJob, setCronJob, cronJob } = props
const [schedule, setSchedule] = useState<string | null>(null)
const [dateRange, setDateRange] = useState<{
startDate: string
endDate: string
}>({ startDate: cronJob?.startDate ?? '', endDate: cronJob?.endDate ?? '' })
const { setSchedule, schedule, isRegistered } = props
const [interval, setInterval] = useState<EInterval>(EInterval.HOURLY)
const [hour, setHour] = useState<string>('23')
const [hourStep, setHourStep] = useState<string>('1')
Expand Down Expand Up @@ -88,7 +84,10 @@ export function CreateRecurringJob(props: {
case EInterval.HOURLY:
newHour = hourStep ? `*/${hourStep}` : '*'
}
setSchedule(`${newMinute} ${newHour} ${dayOfMonth} ${month} ${dayOfWeek}`)
setSchedule({
...schedule,
cron: `${newMinute} ${newHour} ${dayOfMonth} ${month} ${dayOfWeek}`,
})
}, [interval, hour, minute, hourStep])

return (
Expand All @@ -100,19 +99,26 @@ export function CreateRecurringJob(props: {
}}
>
<div>
<div style={{ paddingBottom: '10px' }}>
{cronJob && Object.keys(cronJob).length > 0
? 'A job is already scheduled. You can update it here.'
: ''}
</div>
{isRegistered && (
<div style={{ paddingBottom: '10px' }}>
A job is already scheduled. You can update it here.
</div>
)}
<DateRangePicker
setDateRange={(dateRange) => setDateRange(dateRange)}
value={dateRange}
setDateRange={(dateRange) =>
setSchedule({
...schedule,
startDate: dateRange.startDate,
endDate: dateRange.endDate,
})
}
value={{ startDate: schedule.startDate, endDate: schedule.endDate }}
/>
<InputWrapper>
<Autocomplete
options={Object.values(EInterval)}
label={'Interval'}
initialSelectedOptions={[getIntervall({ cron: schedule.cron })]}
onInputChange={(label: string) => {
const chosenIntervalType = Object.entries(EInterval)
.filter((l) => l.length > 0 && l[1] == label)
Expand Down Expand Up @@ -143,32 +149,6 @@ export function CreateRecurringJob(props: {
</InputWrapper>
</div>
<div style={{ paddingTop: '.5rem', height: '1rem' }}>{getLabel()}</div>
<ButtonWrapper>
<Button
disabled={cronJob && Object.keys(cronJob).length === 0}
color="danger"
variant="outlined"
onClick={() => {
removeJob()
close()
}}
>
Remove
</Button>
<Button
disabled={!schedule}
onClick={() => {
setCronJob({
type: EBlueprint.CRON_JOB,
cron: schedule ?? '* * * * *',
startDate: dateRange.startDate,
endDate: dateRange.endDate,
})
}}
>
Schedule
</Button>
</ButtonWrapper>
</div>
)
}
22 changes: 15 additions & 7 deletions packages/dm-core-plugins/src/job/JobControlButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,40 @@ import React, { MutableRefObject, useRef, useState } from 'react'
export const JobControlButton = (props: {
jobStatus: JobStatus
createJob: () => void
remove: () => void
asCronJob: boolean
disabled: boolean
exists: boolean
}) => {
const { jobStatus, createJob, asCronJob, disabled } = props
const { jobStatus, createJob, asCronJob, disabled, exists, remove } = props
const [hovering, setHovering] = useState(false)
const buttonRef: MutableRefObject<HTMLButtonElement | undefined> = useRef()
buttonRef.current?.addEventListener('mouseenter', () => setHovering(true))
buttonRef.current?.addEventListener('mouseleave', () => setHovering(false))

const buttonText = () => {
switch (jobStatus) {
case 'running':
case JobStatus.Running:
return hovering ? 'Stop' : 'Running'
case 'completed':
return 'Re-run'
case 'failed':
case JobStatus.Failed:
case JobStatus.Completed:
return 'Re-run'
case JobStatus.Registered:
return 'Remove'
default:
return asCronJob ? 'Schedule' : 'Run'
}
}

const buttonIcon = () => {
switch (jobStatus) {
case JobStatus.Removed:
case JobStatus.Failed:
return <Icon data={refresh} />
case JobStatus.Running:
case JobStatus.Registered:
return <Icon data={stop} />
case JobStatus.Removed || JobStatus.NotStarted:
case JobStatus.NotStarted:
return <Icon data={play} />
default:
return <Icon data={play} />
Expand All @@ -44,7 +49,10 @@ export const JobControlButton = (props: {
return (
<Button
ref={buttonRef}
onClick={createJob}
onClick={() => {
if (exists) return remove()
createJob()
}}
style={{ width: '7rem' }}
disabled={disabled}
>
Expand Down
3 changes: 0 additions & 3 deletions packages/dm-core-plugins/src/job/JobLogsDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ export const JobLogsDialog = (props: AboutDialogProps) => {
width={'60vw'}
style={{ maxHeight: '70vh' }}
>
<Dialog.Header>
<Dialog.Title>Job logs</Dialog.Title>
</Dialog.Header>
<Dialog.CustomContent style={{ overflow: 'auto' }}>
<LogBlock
title={error ? 'Error' : 'Logs'}
Expand Down
Loading

0 comments on commit 67f053b

Please sign in to comment.