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
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Autocomplete, Button, Card, Chip, IconButton, Link, MenuItem, Select, Stack, TextField, Typography } from "@mui/material";
import { DELETE_EQUIPMENT_INSTANCE, EquipmentInstance, InstanceStatus, UPDATE_INSTANCE, UPDATE_INSTANCE_CONTROLLER_ASSIGNMENT } from "../../../queries/equipmentInstanceQueries";
import { DELETE_EQUIPMENT_INSTANCE, EquipmentInstance, InstanceStatus, UPDATE_INSTANCE, UPDATE_INSTANCE_CONTROLLER_ASSIGNMENT, UPDATE_INSTANCE_HOBBS_TIME } from "../../../queries/equipmentInstanceQueries";
import ActionButton from "../../../common/ActionButton";
import DriveFileRenameOutlineIcon from '@mui/icons-material/DriveFileRenameOutline';
import { useMutation, useQuery } from "@apollo/client/react";
Expand Down Expand Up @@ -30,6 +30,11 @@ export default function EquipmentInstanceCard(props: EquipmentInstanceCardProps)
awaitRefetchQueries: true
});

const [updateInstanceHobbsTime] = useMutation(UPDATE_INSTANCE_HOBBS_TIME, {
refetchQueries: ["EquipmentInstances", "GetUnpairedAccessControllers"],
awaitRefetchQueries: true
});

const [updatePairing] = useMutation(UPDATE_INSTANCE_CONTROLLER_ASSIGNMENT, {
refetchQueries: ["EquipmentInstances", "GetUnpairedAccessControllers"],
awaitRefetchQueries: true
Expand All @@ -48,9 +53,11 @@ export default function EquipmentInstanceCard(props: EquipmentInstanceCardProps)
const [sendCommandedState] = useMutation(COMMAND_CONTROLLER_STATE);
const [commandedState, setCommandedState] = useState<string>("IDLE");

const [hobbsTime, setHobbsTime] = useState(props.instance.hobbsTime);

async function handleSave() {
setAllowEdit(false);
await updateInstanceHobbsTime({ variables: { id: props.instance.id, hobbsTime: hobbsTime } })
await updateInstance({ variables: { id: props.instance.id, name: name, status: status } })
await updatePairing({ variables: { id: Number(props.instance.id), accessControllerID: pairedController?.id } })
}
Expand Down Expand Up @@ -93,6 +100,20 @@ export default function EquipmentInstanceCard(props: EquipmentInstanceCardProps)
/>;
}

function formatSeconds(allSeconds: number){
const hours = Math.floor(allSeconds / 3600);
if (hours > 0){
return (allSeconds / 3600).toFixed(2) + " hrs"
}
const minutes = Math.floor((allSeconds % 3600) / 60);
const seconds = allSeconds % 60;
if (minutes > 0){
return (minutes + seconds / 50).toFixed(2) + " min"
} else {
return Math.floor(allSeconds) + "sec"
}
}

function activeUserDisplay() {
if (!currentAccessController) {
return <Typography>No User</Typography>;
Expand All @@ -109,6 +130,15 @@ export default function EquipmentInstanceCard(props: EquipmentInstanceCardProps)
<AuditLogEntity entityCode={`user:${currentAccessController.core?.activeUser.id}:${currentAccessController.core?.activeUser?.firstName} ${currentAccessController.core?.activeUser?.lastName}`} />
</Stack>
}
function hobbsTimeSetField(){
return <TextField label="Hobbs (s)"
required
fullWidth
value={hobbsTime}
onChange={(e) => setHobbsTime(Math.abs(Number(e.target.value)))}
>
</TextField>
}

return (
<Card sx={{ padding: "15px" }} >
Expand All @@ -131,6 +161,16 @@ export default function EquipmentInstanceCard(props: EquipmentInstanceCardProps)
</>
}
</Stack>

<Stack alignItems={"center"} justifyContent={"space-between"}>
{
!allowEdit
? formatSeconds(props.instance.hobbsTime)
: hobbsTimeSetField()
}
</Stack>


<Stack alignItems={"center"} spacing={1}>
{
!allowEdit
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Autocomplete, Button, Card, Chip, IconButton, Link, MenuItem, Select, Stack, TextField, Typography } from "@mui/material";
import { DELETE_EQUIPMENT_INSTANCE, EquipmentInstance, InstanceStatus, UPDATE_INSTANCE, UPDATE_INSTANCE_CONTROLLER_ASSIGNMENT } from "../../../queries/equipmentInstanceQueries";
import { DELETE_EQUIPMENT_INSTANCE, EquipmentInstance, InstanceStatus, UPDATE_INSTANCE, UPDATE_INSTANCE_CONTROLLER_ASSIGNMENT, UPDATE_INSTANCE_HOBBS_TIME } from "../../../queries/equipmentInstanceQueries";
import DriveFileRenameOutlineIcon from '@mui/icons-material/DriveFileRenameOutline';
import { useMutation, useQuery } from "@apollo/client/react";
import { useState } from "react";
Expand Down Expand Up @@ -29,6 +29,11 @@ export default function EquipmentInstanceRow(props: EquipmentInstanceRowProps) {
awaitRefetchQueries: true
});

const [updateInstanceHobbsTime] = useMutation(UPDATE_INSTANCE_HOBBS_TIME, {
refetchQueries: ["EquipmentInstances", "GetUnpairedAccessControllers"],
awaitRefetchQueries: true
});

const [updatePairing] = useMutation(UPDATE_INSTANCE_CONTROLLER_ASSIGNMENT, {
refetchQueries: ["EquipmentInstances", "GetUnpairedAccessControllers"],
awaitRefetchQueries: true
Expand All @@ -47,9 +52,12 @@ export default function EquipmentInstanceRow(props: EquipmentInstanceRowProps) {
const [sendCommandedState] = useMutation(COMMAND_CONTROLLER_STATE);
const [commandedState, setCommandedState] = useState<string>("IDLE");

const [hobbsTime, setHobbsTime] = useState(props.instance.hobbsTime);


async function handleSave() {
setAllowEdit(false);
await updateInstanceHobbsTime({ variables: { id: props.instance.id, hobbsTime: hobbsTime } })
await updateInstance({ variables: { id: props.instance.id, name: name, status: status } })
await updatePairing({ variables: { id: Number(props.instance.id), accessControllerID: pairedController?.id } })
}
Expand Down Expand Up @@ -91,6 +99,20 @@ export default function EquipmentInstanceRow(props: EquipmentInstanceRowProps) {
/>;
}

function formatSeconds(allSeconds: number){
const hours = Math.floor(allSeconds / 3600);
if (hours > 0){
return (allSeconds / 3600).toFixed(2) + " hrs"
}
const minutes = Math.floor((allSeconds % 3600) / 60);
const seconds = allSeconds % 60;
if (minutes > 0){
return (minutes + seconds / 50).toFixed(2) + " min"
} else {
return Math.floor(allSeconds) + "sec"
}
}

function activeUserDisplay() {
if (!currentAccessController) {
return <Typography>No User</Typography>;
Expand All @@ -108,6 +130,15 @@ export default function EquipmentInstanceRow(props: EquipmentInstanceRowProps) {
</Stack>
}

function hobbsTimeSetField(){
return <TextField label="Hobbs (s)"
required
value={hobbsTime}
onChange={(e) => setHobbsTime(Math.abs(Number(e.target.value)))}
>
</TextField>
}

return (
<Card sx={{ padding: "15px" }} >
<Stack spacing={1} direction={"row"} width={"100%"} height={"60px"} alignItems={"center"}>
Expand All @@ -127,6 +158,16 @@ export default function EquipmentInstanceRow(props: EquipmentInstanceRowProps) {
: controllerPairingField()
}
</Stack>

<Stack alignItems={"center"} direction={"row"} width={"200px"}>
{
!allowEdit
? formatSeconds(props.instance.hobbsTime)
: hobbsTimeSetField()
}
</Stack>


<Stack direction={"row"} alignItems={"center"} width={"300px"}>
{activeUserDisplay()}
</Stack>
Expand Down
19 changes: 19 additions & 0 deletions client/src/queries/equipmentInstanceQueries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export interface EquipmentInstance {
name: string;
status: InstanceStatus;
accessController: AccessController | undefined;
hobbsTime: number
}

export const GET_EQUIPMENT_INSTANCES = gql`
Expand All @@ -32,6 +33,7 @@ export const GET_EQUIPMENT_INSTANCES = gql`
}
name
status
hobbsTime
accessController {
id
channelID
Expand Down Expand Up @@ -63,6 +65,7 @@ export const GET_EQUIPMENT_INSTANCE_BY_ID = gql`
}
name
status
hobbsTime
reader {
id
name
Expand Down Expand Up @@ -106,6 +109,22 @@ export const UPDATE_INSTANCE = gql`
}
name
status
hobbsTime
}
}
`;

export const UPDATE_INSTANCE_HOBBS_TIME = gql`
mutation UpdateInstanceHobbsTime($id: ID!, $hobbsTime: Int!) {
updateInstanceHobbsTime(id: $id, hobbsTime: $hobbsTime) {
id
equipment {
id
name
}
name
status
hobbsTime
}
}
`;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { Knex } from "knex";


export async function up(knex: Knex): Promise<void> {
knex.schema.hasTable("EquipmentInstances").then(function (exists) {
if (!exists) return;

return knex.schema.alterTable("EquipmentInstances", function (t) {
t.integer("hobbsTime").defaultTo(0);
});
});

}


export async function down(knex: Knex): Promise<void> {
knex.schema.hasTable("EquipmentInstances").then(function (exists) {
if (!exists) return;

return knex.schema.alterTable("EquipmentInstances", function (t) {
t.dropColumn("hobbsTime");
});
});

}

5 changes: 4 additions & 1 deletion server/src/database/knex/tables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ export interface EquipmentInstancesRow {
/** The state of the equipment, ACTIVE,RETIRED,NEEDS_REPAIRED, etc. */
status: string;
/** Optional FK of the card reader associated with this instance */
accessControllerID: number | null
accessControllerID: number | null;
/** Required number of seconds that this equipment has been run for */
hobbsTime: number;
}

export interface HoldRow {
Expand Down Expand Up @@ -700,6 +702,7 @@ export interface CoreRow {
flags: CoreFlags;
sealedDeployment: ACSDeployment | undefined;
reportedDeployment: ACSDeployment | undefined;
hobbsTime: number
}

export enum AccessControllerState {
Expand Down
14 changes: 11 additions & 3 deletions server/src/database/models/api/ACSFormats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { ACSDeployment } from "../ACS/deployment.js";
export interface CoreStatusReport {
channels: {
channelID: number,
state: AccessControllerState
state: AccessControllerState,
hobbsTime: number,
}[];
currentCardTag: string;
}
Expand Down Expand Up @@ -66,7 +67,8 @@ export enum CoreInfoOptions {
TIME = "TIME",
STATE = "STATE",
HMI = "HMI",
FLAGS = "FLAGS"
FLAGS = "FLAGS",
HOBBS_TIME = "HOBBS_TIME"
}

export interface CoreInfoRequest {
Expand Down Expand Up @@ -125,6 +127,7 @@ export interface ServerCommand {
action?: CoreActions;
identifyChannel?: number;
flags?: CoreFlags;
hobbsTime?: {channelID: number, hobbsTime: number}[]
}

export enum CoreRole {
Expand All @@ -144,13 +147,18 @@ export interface ServerInfoResponse {
}[];
hmi?: {
role: CoreRole;
deviceName: string,
makerspace: string;
channels: {
channelID: number;
pairedEntity: string;
}[];
};
flags?: CoreFlags
flags?: CoreFlags;
hobbsTime?: {
channelID: number;
hobbsTime: number;
}[]
}

export interface WelcomeRequest {
Expand Down
Loading
Loading