Skip to content
Merged
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
8 changes: 0 additions & 8 deletions frontend/src/helpers/selectionRange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,6 @@ export function mergeSelectedIds(selected: string[], idsToAdd: string[]) {
return [...new Set([...selected, ...idsToAdd])]
}

// Devices are selected in click order, so re-order on each change to follow the list the user
// is looking at — which respects whatever sort they've chosen. Ids no longer in the list (a
// selection outliving a filter change) keep their relative order at the end.
export function sortSelectedIds(selected: string[], devices: IDevice[]) {
const order = new Map(devices.map((device, index) => [device.id, index]))
return [...selected].sort((a, b) => (order.get(a) ?? Infinity) - (order.get(b) ?? Infinity))
}

export function removeSelectedIds(selected: string[], idsToRemove: string[]) {
const remove = new Set(idsToRemove)
return selected.filter(id => !remove.has(id))
Expand Down
3 changes: 1 addition & 2 deletions frontend/src/hooks/useSelect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
getSelectableDeviceIds,
mergeSelectedIds,
removeSelectedIds,
sortSelectedIds,
} from '../helpers/selectionRange'

type UseSelectParams = {
Expand All @@ -29,7 +28,7 @@ export const useSelect = ({ deviceId, selectMode }: UseSelectParams) => {
const ids = range.length ? range : [deviceId]
const nextSelected = isSelected ? removeSelectedIds(selected, ids) : mergeSelectedIds(selected, ids)

dispatch.ui.set({ selected: sortSelectedIds(nextSelected, visibleDevices), selectionAnchor: deviceId })
dispatch.ui.set({ selected: nextSelected, selectionAnchor: deviceId })
}

return { isSelected, isAnchorRow, handleSelect }
Expand Down
20 changes: 0 additions & 20 deletions frontend/src/models/jobs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,26 +134,6 @@ export default createModel<RootModel>()({
console.log('STARTED JOB', { result, jobId })
dispatch.ui.set({ redirect: `/script/${fileId}/latest` })
},
async runAgain(script: IScript) {
const deviceIds = script?.job?.jobDevices.map(d => d.device.id) || []
const tagValues = script?.job?.tag?.values || []
// Convert job arguments to argument values format
const argumentValues: IArgumentValue[] = script?.job?.arguments?.map(arg => ({
name: arg.name,
value: arg.value || '',
})) || []
await dispatch.jobs.saveRun({
deviceIds,
jobId: script.job?.id || '',
fileId: script.id,
name: script.name || '',
description: script.shortDesc || '',
executable: script.executable,
tag: script.job?.tag,
access: tagValues.length ? 'TAG' : deviceIds.length ? 'CUSTOM' : 'NONE',
argumentValues,
})
},
async downloadLogs({ jobId, jobDeviceId }: { jobId: string; jobDeviceId: string }) {
const result = await getJobLogs(jobId)
if (result.kind === 'error') {
Expand Down
21 changes: 13 additions & 8 deletions frontend/src/pages/ScriptRunPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,19 @@ export const ScriptRunPage: React.FC<Props> = ({ isNew }) => {
return lookup
}, [script?.job?.jobDevices])

// Resolve device names for the current run form
// Resolve device names for the current run form, ordered by the device list so the run
// follows whatever sort the user has chosen. Derived rather than stored, so changing the
// sort after selecting reorders these too. Devices no longer in the list go last.
const resolvedDevices: { id: string; name: string }[] = useMemo(() => {
const ids = runForm.access === 'SELECTED' ? selectedIds : runForm.access === 'CUSTOM' ? runForm.deviceIds : []
return ids.map(id => {
if (jobDeviceNames[id]) return { id, name: jobDeviceNames[id] }
const device = devices.find(d => d.id === id) || allDevices.find(d => d.id === id)
return { id, name: device?.name || id.slice(0, 8) + '…' }
})
const order = new Map(devices.map((device, index) => [device.id, index]))
return ids
.map(id => {
if (jobDeviceNames[id]) return { id, name: jobDeviceNames[id] }
const device = devices.find(d => d.id === id) || allDevices.find(d => d.id === id)
return { id, name: device?.name || id.slice(0, 8) + '…' }
})
.sort((a, b) => (order.get(a.id) ?? Infinity) - (order.get(b.id) ?? Infinity))
}, [runForm.access, runForm.deviceIds, selectedIds, jobDeviceNames, devices, allDevices])

const uploadScript = async (): Promise<string | undefined> => {
Expand All @@ -175,7 +180,7 @@ export const ScriptRunPage: React.FC<Props> = ({ isNew }) => {
const handleRun = async () => {
setRunning(true)
const form = { ...runForm }
if (runForm.access === 'SELECTED') form.deviceIds = selectedIds
if (runForm.access === 'SELECTED' || runForm.access === 'CUSTOM') form.deviceIds = resolvedDevices.map(d => d.id)
if (isNew) {
const newFileId = await uploadScript()
if (newFileId) { form.fileId = newFileId; await dispatch.jobs.saveRun(form) }
Expand All @@ -190,7 +195,7 @@ export const ScriptRunPage: React.FC<Props> = ({ isNew }) => {
const handlePrepare = async () => {
setRunning(true)
const form = { ...runForm }
if (runForm.access === 'SELECTED') form.deviceIds = selectedIds
if (runForm.access === 'SELECTED' || runForm.access === 'CUSTOM') form.deviceIds = resolvedDevices.map(d => d.id)
if (isNew) {
const newFileId = await uploadScript()
if (newFileId) { form.fileId = newFileId; await dispatch.jobs.save(form) }
Expand Down
Loading