Skip to content

Commit 04f992d

Browse files
committed
Creating tickets of types, updating them at midnight, needs testing
1 parent c914562 commit 04f992d

13 files changed

Lines changed: 200 additions & 75 deletions

File tree

client/src/pages/makerspace_page/equipment_pages/EquipmentInstanceCard.tsx

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Autocomplete, Button, Card, Chip, IconButton, Link, MenuItem, Select, Stack, TextField, Typography } from "@mui/material";
2-
import { DELETE_EQUIPMENT_INSTANCE, EquipmentInstance, InstanceStatus, UPDATE_INSTANCE, UPDATE_INSTANCE_CONTROLLER_ASSIGNMENT, UPDATE_INSTANCE_HOBBS_TIME } from "../../../queries/equipmentInstanceQueries";
2+
import { DELETE_EQUIPMENT_INSTANCE, EquipmentInstance, formatHobbsTime, InstanceStatus, UPDATE_INSTANCE, UPDATE_INSTANCE_CONTROLLER_ASSIGNMENT, UPDATE_INSTANCE_HOBBS_TIME } from "../../../queries/equipmentInstanceQueries";
33
import ActionButton from "../../../common/ActionButton";
44
import DriveFileRenameOutlineIcon from '@mui/icons-material/DriveFileRenameOutline';
55
import { useMutation, useQuery } from "@apollo/client/react";
@@ -100,19 +100,6 @@ export default function EquipmentInstanceCard(props: EquipmentInstanceCardProps)
100100
/>;
101101
}
102102

103-
function formatSeconds(allSeconds: number){
104-
const hours = Math.floor(allSeconds / 3600);
105-
if (hours > 0){
106-
return (allSeconds / 3600).toFixed(2) + " hrs"
107-
}
108-
const minutes = Math.floor((allSeconds % 3600) / 60);
109-
const seconds = allSeconds % 60;
110-
if (minutes > 0){
111-
return (minutes + seconds / 50).toFixed(2) + " min"
112-
} else {
113-
return Math.floor(allSeconds) + "sec"
114-
}
115-
}
116103

117104
function activeUserDisplay() {
118105
if (!currentAccessController) {
@@ -165,7 +152,7 @@ export default function EquipmentInstanceCard(props: EquipmentInstanceCardProps)
165152
<Stack alignItems={"center"} justifyContent={"space-between"}>
166153
{
167154
!allowEdit
168-
? formatSeconds(props.instance.hobbsTime)
155+
? formatHobbsTime(props.instance.hobbsTime)
169156
: hobbsTimeSetField()
170157
}
171158
</Stack>

client/src/pages/makerspace_page/equipment_pages/EquipmentInstanceRow.tsx

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Autocomplete, Button, Card, Chip, IconButton, Link, MenuItem, Select, Stack, TextField, Typography } from "@mui/material";
2-
import { DELETE_EQUIPMENT_INSTANCE, EquipmentInstance, InstanceStatus, UPDATE_INSTANCE, UPDATE_INSTANCE_CONTROLLER_ASSIGNMENT, UPDATE_INSTANCE_HOBBS_TIME } from "../../../queries/equipmentInstanceQueries";
2+
import { DELETE_EQUIPMENT_INSTANCE, EquipmentInstance, formatHobbsTime, InstanceStatus, UPDATE_INSTANCE, UPDATE_INSTANCE_CONTROLLER_ASSIGNMENT, UPDATE_INSTANCE_HOBBS_TIME } from "../../../queries/equipmentInstanceQueries";
33
import DriveFileRenameOutlineIcon from '@mui/icons-material/DriveFileRenameOutline';
44
import { useMutation, useQuery } from "@apollo/client/react";
55
import { useState } from "react";
@@ -99,20 +99,6 @@ export default function EquipmentInstanceRow(props: EquipmentInstanceRowProps) {
9999
/>;
100100
}
101101

102-
function formatSeconds(allSeconds: number){
103-
const hours = Math.floor(allSeconds / 3600);
104-
if (hours > 0){
105-
return (allSeconds / 3600).toFixed(2) + " hrs"
106-
}
107-
const minutes = Math.floor((allSeconds % 3600) / 60);
108-
const seconds = allSeconds % 60;
109-
if (minutes > 0){
110-
return (minutes + seconds / 50).toFixed(2) + " min"
111-
} else {
112-
return Math.floor(allSeconds) + "sec"
113-
}
114-
}
115-
116102
function activeUserDisplay() {
117103
if (!currentAccessController) {
118104
return <Typography>No User</Typography>;
@@ -162,7 +148,7 @@ export default function EquipmentInstanceRow(props: EquipmentInstanceRowProps) {
162148
<Stack alignItems={"center"} direction={"row"} width={"200px"}>
163149
{
164150
!allowEdit
165-
? formatSeconds(props.instance.hobbsTime)
151+
? formatHobbsTime(props.instance.hobbsTime)
166152
: hobbsTimeSetField()
167153
}
168154
</Stack>

client/src/pages/makerspace_page/maintenance_pages/MaintenanceTicketModal.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { useParams } from "react-router-dom";
1717
import { GET_VALID_STAFF } from "../../../queries/makerspaceQueries";
1818
import { CurrentUser, useCurrentUser } from "../../../common/CurrentUserProvider";
1919
import { isManager } from "../../../common/PrivilegeUtils";
20+
import { formatHobbsTime } from "../../../queries/equipmentInstanceQueries";
2021

2122
interface TicketModalProps {
2223
open: boolean,
@@ -194,6 +195,7 @@ export default function MaintenanceTicketModal(props: TicketModalProps) {
194195
}
195196
}
196197

198+
197199
return (
198200
<PrettyModal open={props.open} onClose={handleClose} width={"600px"}>
199201
<Stack spacing={2}>
@@ -317,6 +319,10 @@ export default function MaintenanceTicketModal(props: TicketModalProps) {
317319
</Stack>
318320
}
319321
</Stack>
322+
<Stack justifyContent={"space-between"} direction={"row"}>
323+
<Typography variant="body1">Usage at Open: {formatHobbsTime(props.ticket.hobbsTimeAtCreate)}</Typography>
324+
<Typography variant="body1">Usage at Close: {props.ticket.hobbsTimeAtClose ? formatHobbsTime(props.ticket.hobbsTimeAtClose) : "N/A"}</Typography>
325+
</Stack>
320326
{
321327
editing
322328
? <TextField

client/src/pages/makerspace_page/maintenance_pages/NewIntervalTicketModal.tsx

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,20 @@ export default function NewIntervalTicketModal(props: NewTicketModalProps) {
5050
const makerspace_equipments = makerspace_equipments_2?.flat(1);
5151

5252
const [startDate, setStartDate] = useState(new Date());
53-
const [scale, setScale] = useState("days");
53+
const [timeUnit, setTimeUnit] = useState("USAGE"); // USAGE | CALENDAR
54+
const [scale, setScale] = useState("days"); // hours | days | weeks
5455
const [interval, setInterval] = useState("1");
5556

5657
function handleChangeScale(_event: React.MouseEvent<HTMLElement>, value: string) {
5758
if (value !== null && value !== scale) {
5859
setScale(value);
5960
}
6061
}
62+
function handleChangeTimeUnit(_event: React.MouseEvent<HTMLElement>, value: string) {
63+
if (value !== null && value !== timeUnit) {
64+
setTimeUnit(value);
65+
}
66+
}
6167

6268
function handleClose() {
6369
setEquipment(undefined);
@@ -67,6 +73,7 @@ export default function NewIntervalTicketModal(props: NewTicketModalProps) {
6773
setImageUrl(undefined);
6874
setStartDate(new Date());
6975
setScale("days");
76+
setTimeUnit("calendar")
7077
setInterval("1");
7178

7279
props.onClose();
@@ -78,14 +85,18 @@ export default function NewIntervalTicketModal(props: NewTicketModalProps) {
7885
return;
7986
}
8087
try {
88+
const intervalHours = scale === "days" ? Number(interval) * 24 : (scale == "weeks" ? Number(interval) * 168 : interval)
8189
await createTicket({
8290
variables: {
8391
severity: severity,
8492
instanceID: Number(reportedInstance.id),
8593
description: description,
8694
startDate: startDate.toISOString(),
8795
imageUrl: imageUrl,
88-
intervalHours: scale === "days" ? Number(interval) * 24 : Number(interval) * 168
96+
intervalHours: intervalHours,
97+
timeUnit: timeUnit,
98+
hobbsTimeAtCreate: instance?.hobbsTime
99+
89100
}
90101
})
91102
} catch (e) {
@@ -127,6 +138,7 @@ export default function NewIntervalTicketModal(props: NewTicketModalProps) {
127138
{
128139
equipment
129140
? <Autocomplete
141+
fullWidth
130142
key={instances.length === 1 ? "auto-selected" : "manual-select"}
131143
renderInput={
132144
(params) => (
@@ -159,21 +171,40 @@ export default function NewIntervalTicketModal(props: NewTicketModalProps) {
159171
disabled
160172
/>
161173
}
162-
<Autocomplete
163-
renderInput={
164-
(params) => (
165-
<TextField
166-
{...params}
167-
label="Severity"
168-
placeholder="Select Severity..."
169-
required
170-
/>
171-
)
172-
}
173-
options={[MaintenanceTicketSeverity.HIGH, MaintenanceTicketSeverity.MEDIUM, MaintenanceTicketSeverity.LOW]}
174-
value={severity}
175-
onChange={(event, newValue) => setSeverity(newValue ?? undefined)}
176-
/>
174+
<Stack direction={"row"} spacing={1}>
175+
<Autocomplete
176+
renderInput={
177+
(params) => (
178+
<TextField
179+
{...params}
180+
label="Severity"
181+
placeholder="Select Severity..."
182+
required
183+
/>
184+
)
185+
}
186+
options={[MaintenanceTicketSeverity.HIGH, MaintenanceTicketSeverity.MEDIUM, MaintenanceTicketSeverity.LOW]}
187+
value={severity}
188+
onChange={(event, newValue) => setSeverity(newValue ?? undefined)}
189+
sx={{flexGrow: 1}}
190+
/>
191+
192+
<ToggleButtonGroup
193+
exclusive
194+
value={timeUnit}
195+
onChange={handleChangeTimeUnit}
196+
>
197+
<ToggleButton value="USAGE">
198+
Usage
199+
</ToggleButton>
200+
<ToggleButton value="CALENDAR">
201+
Calendar
202+
</ToggleButton>
203+
</ToggleButtonGroup>
204+
205+
206+
</Stack>
207+
177208
<Stack direction={"row"} justifyContent={"space-between"}>
178209
<DatePicker
179210
value={startDate}
@@ -196,11 +227,15 @@ export default function NewIntervalTicketModal(props: NewTicketModalProps) {
196227
width: "120px"
197228
}}
198229
/>
230+
199231
<ToggleButtonGroup
200232
exclusive
201233
value={scale}
202234
onChange={handleChangeScale}
203235
>
236+
<ToggleButton value="hours">
237+
Hours
238+
</ToggleButton>
204239
<ToggleButton value="days">
205240
Days
206241
</ToggleButton>

client/src/queries/equipmentInstanceQueries.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,21 @@ export interface EquipmentInstance {
2222
accessController: AccessController | undefined;
2323
hobbsTime: number
2424
}
25+
export function formatHobbsTime(allSeconds: number){
26+
const hours = Math.floor(allSeconds / 3600);
27+
if (hours > 0){
28+
return (allSeconds / 3600).toFixed(2) + " hrs"
29+
}
30+
const minutes = Math.floor((allSeconds % 3600) / 60);
31+
const seconds = allSeconds % 60;
32+
if (minutes > 0){
33+
return (minutes + seconds / 50).toFixed(2) + " min"
34+
} else {
35+
return Math.floor(allSeconds) + "sec"
36+
}
37+
}
38+
39+
2540

2641
export const GET_EQUIPMENT_INSTANCES = gql`
2742
query EquipmentInstances($equipmentID: ID!) {

client/src/queries/maintenanceTicketQueries.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ import { gql } from "@apollo/client";
22
import { CurrentUser } from "../common/CurrentUserProvider";
33
import { EquipmentInstance } from "./equipmentInstanceQueries";
44

5+
export enum MaintenanceTicketTimeUnit {
6+
USAGE = "USAGE",
7+
CALENDAR = "CALENDAR"
8+
}
9+
510
export enum MaintenanceTicketType {
611
AUTOMATIC = "AUTOMATIC",
712
REPORTED = "REPORTED"
@@ -32,7 +37,10 @@ export interface MaintenanceTicket {
3237
creator: CurrentUser | null,
3338
instance: EquipmentInstance,
3439
assigned: CurrentUser | null,
35-
intervalHours: number | null
40+
intervalHours: number | null,
41+
timeUnit: MaintenanceTicketTimeUnit,
42+
hobbsTimeAtCreate: number,
43+
hobbsTimeAtClose: number | null
3644
}
3745

3846
export const PAGINATED_MAINTENANCE_TICKETS = gql`
@@ -47,6 +55,9 @@ export const PAGINATED_MAINTENANCE_TICKETS = gql`
4755
dateCreated
4856
dateClosed
4957
intervalHours
58+
timeUnit
59+
hobbsTimeAtCreate
60+
hobbsTimeAtClose
5061
creator {
5162
id
5263
ritUsername
@@ -80,6 +91,9 @@ export const GET_MAINTENANCE_TICKET = gql`
8091
imageUrl
8192
dateCreated
8293
dateClosed
94+
timeUnit
95+
hobbsTimeAtCreate
96+
hobbsTimeAtClose
8397
creator {
8498
id
8599
ritUsername
@@ -133,6 +147,9 @@ export const GET_MAINTENANCE_TICKETS = gql`
133147
dateCreated
134148
dateClosed
135149
intervalHours
150+
timeUnit
151+
hobbsTimeAtCreate
152+
hobbsTimeAtClose
136153
creator {
137154
id
138155
ritUsername
@@ -180,15 +197,19 @@ export const CREATE_INTERVAL_MAINTENANCE_TICKET = gql`
180197
$description: String!,
181198
$startDate: String!,
182199
$intervalHours: Int!,
183-
$imageUrl: String
200+
$imageUrl: String,
201+
$timeUnit: String!,
202+
$hobbsTimeAtCreate: Int!,
184203
) {
185204
createIntervalMaintenanceTicket(
186205
severity: $severity,
187206
instanceID: $instanceID,
188207
description: $description,
189208
startDate: $startDate,
190209
intervalHours: $intervalHours,
191-
imageUrl: $imageUrl
210+
imageUrl: $imageUrl,
211+
timeUnit: $timeUnit,
212+
hobbsTimeAtCreate: $hobbsTimeAtCreate,
192213
) {
193214
id
194215
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import type { Knex } from "knex";
2+
3+
4+
export async function up(knex: Knex): Promise<void> {
5+
knex.schema.hasTable("MaintenanceTickets").then(function (exists) {
6+
if (!exists) return;
7+
8+
return knex.schema.alterTable("MaintenanceTickets", function (t) {
9+
t.enum("timeUnit", ["USAGE", "CALENDAR"]).notNullable().defaultTo("CALENDAR")
10+
t.integer("hobbsTimeAtCreate").notNullable().defaultTo(0);
11+
t.integer("hobbsTimeAtClose").nullable();
12+
});
13+
});
14+
}
15+
16+
17+
export async function down(knex: Knex): Promise<void> {
18+
knex.schema.hasTable("MaintenanceTickets").then(function (exists) {
19+
if (!exists) return;
20+
21+
return knex.schema.alterTable("MaintenanceTickets", function (t) {
22+
t.dropColumns("timeUnit", "hobbsTimeAtCreate", "hobbsTimeAtClose");
23+
});
24+
});
25+
26+
}
27+

server/src/database/knex/tables.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,11 @@ export interface ReservationRow {
626626
end: string; // ^
627627
}
628628

629+
export enum MaintenanceTicketTimeUnit {
630+
USAGE = "USAGE",
631+
CALENDAR = "CALENDAR"
632+
}
633+
629634
export enum MaintenanceTicketType {
630635
AUTOMATIC = "AUTOMATIC",
631636
REPORTED = "REPORTED"
@@ -640,7 +645,7 @@ export enum MaintenanceTicketSeverity {
640645
export enum MaintenanceTicketStatus {
641646
UPCOMING = "UPCOMING",
642647
TODO = "TODO",
643-
IN_PROGESS = "IN_PROGRESS",
648+
IN_PROGRESS = "IN_PROGRESS",
644649
CLOSED = "CLOSED"
645650
}
646651

@@ -657,6 +662,9 @@ export interface MaintenanceTicketRow {
657662
dateClosed: string | null; // ^
658663
intervalHours: number | null;
659664
assignedID: number | null;
665+
timeUnit: MaintenanceTicketTimeUnit;
666+
hobbsTimeAtCreate: number;
667+
hobbsTimeAtClose: number | null;
660668
}
661669

662670
export interface TempCardRow {

0 commit comments

Comments
 (0)