mirror of
https://github.com/soconnor0919/hristudio.git
synced 2026-03-24 03:37:51 -04:00
feat: Implement dynamic plugin definition loading from remote/local sources and standardize action IDs using plugin metadata.
This commit is contained in:
@@ -161,7 +161,7 @@ export default function NaoTestPage() {
|
||||
data.topic?.includes("touch") ||
|
||||
data.topic?.includes("sonar")
|
||||
) {
|
||||
setSensorData((prev) => ({
|
||||
setSensorData((prev: any) => ({
|
||||
...prev,
|
||||
[data.topic]: data.msg,
|
||||
}));
|
||||
@@ -196,14 +196,14 @@ export default function NaoTestPage() {
|
||||
|
||||
const walkForward = () => {
|
||||
publishMessage("/cmd_vel", "geometry_msgs/Twist", {
|
||||
linear: { x: walkSpeed[0], y: 0, z: 0 },
|
||||
linear: { x: walkSpeed[0] ?? 0, y: 0, z: 0 },
|
||||
angular: { x: 0, y: 0, z: 0 },
|
||||
});
|
||||
};
|
||||
|
||||
const walkBackward = () => {
|
||||
publishMessage("/cmd_vel", "geometry_msgs/Twist", {
|
||||
linear: { x: -walkSpeed[0], y: 0, z: 0 },
|
||||
linear: { x: -(walkSpeed[0] ?? 0), y: 0, z: 0 },
|
||||
angular: { x: 0, y: 0, z: 0 },
|
||||
});
|
||||
};
|
||||
@@ -211,14 +211,14 @@ export default function NaoTestPage() {
|
||||
const turnLeft = () => {
|
||||
publishMessage("/cmd_vel", "geometry_msgs/Twist", {
|
||||
linear: { x: 0, y: 0, z: 0 },
|
||||
angular: { x: 0, y: 0, z: turnSpeed[0] },
|
||||
angular: { x: 0, y: 0, z: turnSpeed[0] ?? 0 },
|
||||
});
|
||||
};
|
||||
|
||||
const turnRight = () => {
|
||||
publishMessage("/cmd_vel", "geometry_msgs/Twist", {
|
||||
linear: { x: 0, y: 0, z: 0 },
|
||||
angular: { x: 0, y: 0, z: -turnSpeed[0] },
|
||||
angular: { x: 0, y: 0, z: -(turnSpeed[0] ?? 0) },
|
||||
});
|
||||
};
|
||||
|
||||
@@ -232,7 +232,7 @@ export default function NaoTestPage() {
|
||||
const moveHead = () => {
|
||||
publishMessage("/joint_angles", "naoqi_bridge_msgs/JointAnglesWithSpeed", {
|
||||
joint_names: ["HeadYaw", "HeadPitch"],
|
||||
joint_angles: [headYaw[0], headPitch[0]],
|
||||
joint_angles: [headYaw[0] ?? 0, headPitch[0] ?? 0],
|
||||
speed: 0.3,
|
||||
});
|
||||
};
|
||||
@@ -365,7 +365,7 @@ export default function NaoTestPage() {
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label>Walk Speed: {walkSpeed[0].toFixed(2)} m/s</Label>
|
||||
<Label>Walk Speed: {(walkSpeed[0] ?? 0).toFixed(2)} m/s</Label>
|
||||
<Slider
|
||||
value={walkSpeed}
|
||||
onValueChange={setWalkSpeed}
|
||||
@@ -375,7 +375,7 @@ export default function NaoTestPage() {
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label>Turn Speed: {turnSpeed[0].toFixed(2)} rad/s</Label>
|
||||
<Label>Turn Speed: {(turnSpeed[0] ?? 0).toFixed(2)} rad/s</Label>
|
||||
<Slider
|
||||
value={turnSpeed}
|
||||
onValueChange={setTurnSpeed}
|
||||
@@ -415,7 +415,7 @@ export default function NaoTestPage() {
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label>Head Yaw: {headYaw[0].toFixed(2)} rad</Label>
|
||||
<Label>Head Yaw: {(headYaw[0] ?? 0).toFixed(2)} rad</Label>
|
||||
<Slider
|
||||
value={headYaw}
|
||||
onValueChange={setHeadYaw}
|
||||
@@ -425,7 +425,7 @@ export default function NaoTestPage() {
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label>Head Pitch: {headPitch[0].toFixed(2)} rad</Label>
|
||||
<Label>Head Pitch: {(headPitch[0] ?? 0).toFixed(2)} rad</Label>
|
||||
<Slider
|
||||
value={headPitch}
|
||||
onValueChange={setHeadPitch}
|
||||
|
||||
@@ -260,7 +260,6 @@ export default function StudyAnalyticsPage() {
|
||||
setSelectedTrialId={setSelectedTrialId}
|
||||
trialsList={trialsList ?? []}
|
||||
isLoadingList={isLoadingList}
|
||||
studyId={studyId}
|
||||
/>
|
||||
</Suspense>
|
||||
</div>
|
||||
|
||||
@@ -26,21 +26,17 @@ import {
|
||||
import { toast } from "sonner";
|
||||
import { api } from "~/trpc/react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { type Experiment } from "~/lib/experiments/types";
|
||||
import { type experiments, experimentStatusEnum } from "~/server/db/schema";
|
||||
import { type InferSelectModel } from "drizzle-orm";
|
||||
|
||||
type Experiment = InferSelectModel<typeof experiments>;
|
||||
|
||||
const formSchema = z.object({
|
||||
name: z.string().min(2, {
|
||||
message: "Name must be at least 2 characters.",
|
||||
}),
|
||||
description: z.string().optional(),
|
||||
status: z.enum([
|
||||
"draft",
|
||||
"ready",
|
||||
"data_collection",
|
||||
"analysis",
|
||||
"completed",
|
||||
"archived",
|
||||
]),
|
||||
status: z.enum(experimentStatusEnum.enumValues),
|
||||
});
|
||||
|
||||
interface ExperimentFormProps {
|
||||
@@ -133,11 +129,9 @@ export function ExperimentForm({ experiment }: ExperimentFormProps) {
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
<SelectItem value="draft">Draft</SelectItem>
|
||||
<SelectItem value="testing">Testing</SelectItem>
|
||||
<SelectItem value="ready">Ready</SelectItem>
|
||||
<SelectItem value="data_collection">Data Collection</SelectItem>
|
||||
<SelectItem value="analysis">Analysis</SelectItem>
|
||||
<SelectItem value="completed">Completed</SelectItem>
|
||||
<SelectItem value="archived">Archived</SelectItem>
|
||||
<SelectItem value="deprecated">Deprecated</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormDescription>
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { notFound } from "next/navigation";
|
||||
import { type Experiment } from "~/lib/experiments/types";
|
||||
import { type experiments } from "~/server/db/schema";
|
||||
import { type InferSelectModel } from "drizzle-orm";
|
||||
|
||||
type Experiment = InferSelectModel<typeof experiments>;
|
||||
import { api } from "~/trpc/server";
|
||||
import { ExperimentForm } from "./experiment-form";
|
||||
import {
|
||||
@@ -43,14 +46,6 @@ export default async function ExperimentEditPage({
|
||||
title="Edit Experiment"
|
||||
subtitle={`Update settings for ${experiment.name}`}
|
||||
icon="Edit"
|
||||
backButton={
|
||||
<Button variant="ghost" size="sm" asChild className="-ml-2 mb-2">
|
||||
<Link href={`/studies/${studyId}/experiments/${experimentId}`}>
|
||||
<ArrowLeft className="mr-2 h-4 w-4" />
|
||||
Back to Experiment
|
||||
</Link>
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
|
||||
<div className="max-w-2xl">
|
||||
|
||||
@@ -39,11 +39,10 @@ export default async function ParticipantDetailPage({
|
||||
title={participant.participantCode}
|
||||
subtitle={participant.name ?? "Unnamed Participant"}
|
||||
icon="Users"
|
||||
badge={
|
||||
<Badge variant={participant.consentGiven ? "default" : "secondary"}>
|
||||
{participant.consentGiven ? "Consent Given" : "No Consent"}
|
||||
</Badge>
|
||||
}
|
||||
status={{
|
||||
label: participant.consentGiven ? "Consent Given" : "No Consent",
|
||||
variant: participant.consentGiven ? "default" : "secondary"
|
||||
}}
|
||||
actions={
|
||||
<Button asChild variant="outline" size="sm">
|
||||
<Link href={`/studies/${studyId}/participants/${participantId}/edit`}>
|
||||
|
||||
Reference in New Issue
Block a user