Skip to content
Closed
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
Expand Up @@ -11,19 +11,23 @@ governing permissions and limitations under the License.
*/

import React from "react";
import { Heading, Text, Divider } from "@react-spectrum/s2";
import { Button, Heading, Text, Divider } from "@react-spectrum/s2";
import { Experience } from "@adobe/genstudio-extensibility-sdk";

interface ContentProps {
experience: Experience;
flaggedFieldName?: string;
onApplySuggestion?: (fieldName: string) => void;
}

/**
* Content component that displays the details of an experience.
* @param experience - The experience to display
* @param flaggedFieldName - The field name that has been flagged
* @param onApplySuggestion - Callback to apply the suggestion for a flagged field
* @returns The Content component
*/
export default function Content({ experience }: ContentProps) {
export default function Content({ experience, flaggedFieldName, onApplySuggestion }: ContentProps) {
if (!experience) return null;
return (
<div style={{ display: "flex", flexDirection: "column", gap: "1rem" }}>
Expand All @@ -32,25 +36,55 @@ export default function Content({ experience }: ContentProps) {
<Text>ID: {experience.id}</Text>
<Divider size="S" />
<Heading>Fields</Heading>
{Object.entries(experience.experienceFields).map(([key, field]) => (
<div
style={{ display: "flex", flexDirection: "column", gap: "0.25rem" }}
key={key}
>
<Text>
<strong>{field.fieldName}</strong>
</Text>
<Text>{field.fieldValue}</Text>
{field.keywords && (
<Text>keywords: {field.keywords.join(", ")}</Text>
)}
{field.additionalMetadata && (
{Object.entries(experience.experienceFields).map(([key, field]) => {
const isFlagged = field.fieldName === flaggedFieldName;
return (
<div
style={{
display: "flex",
flexDirection: "column",
gap: "0.25rem",
padding: isFlagged ? "0.5rem" : undefined,
border: isFlagged ? "1px solid #e04a0e" : undefined,
borderRadius: isFlagged ? "4px" : undefined,
backgroundColor: isFlagged ? "#fff3f0" : undefined,
}}
key={key}
>
<Text>
additionalMetadata: {JSON.stringify(field.additionalMetadata)}
<strong>{field.fieldName}</strong>
{isFlagged && (
<span style={{ color: "#e04a0e", marginLeft: "0.5rem" }}>
⚠ Needs review
</span>
)}
</Text>
)}
</div>
))}
<Text>{field.fieldValue}</Text>
{field.keywords && (
<Text>keywords: {field.keywords.join(", ")}</Text>
)}
{field.additionalMetadata && (
<Text>
additionalMetadata: {JSON.stringify(field.additionalMetadata)}
</Text>
)}
{isFlagged && onApplySuggestion && (
<div style={{ display: "flex", flexDirection: "column", gap: "0.25rem", marginTop: "0.25rem" }}>
<Text>
<em>Suggestion: "This is a suggested field value from the Validation App!"</em>
</Text>
<Button
variant="accent"
size="S"
onPress={() => onApplySuggestion(field.fieldName)}
>
Apply suggestion
</Button>
</div>
)}
</div>
);
})}
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export default function ValidationPanel(): JSX.Element {
const [generationContext, setGenerationContext] =
useState<GenerationContext | null>(null);
const [isLoading, setIsLoading] = useState<boolean>(false);
const [flaggedFieldName, setFlaggedFieldName] = useState<string | null>(null);

/**
* Polls for experiences from the host.
Expand Down Expand Up @@ -98,8 +99,34 @@ export default function ValidationPanel(): JSX.Element {
* @returns void
*/
const handleRunClaimsCheck = (): void => {
if (experiences && selectedExperienceIndex !== null)
setSelectedExperience(experiences[selectedExperienceIndex]);
if (experiences && selectedExperienceIndex !== null) {
const experience = experiences[selectedExperienceIndex];
setSelectedExperience(experience);
const fieldNames = Object.keys(experience.experienceFields);
if (fieldNames.length > 0) {
// Filter out image fields from the fieldNames array before selecting one to flag
const nonImageFieldNames = fieldNames.filter(
(name) => !/image/i.test(name)
);
if (nonImageFieldNames.length > 0) {
const randomFieldName = nonImageFieldNames[Math.floor(Math.random() * nonImageFieldNames.length)];
setFlaggedFieldName(randomFieldName);
} else {
// No non-image field found; do not flag any field
setFlaggedFieldName(null);
}
}
}
};

const handleApplySuggestion = (field: string): void => {
if (!guestConnection || !selectedExperience) return;
ValidationExtensionService.updateField(guestConnection, {
experienceId: selectedExperience.id,
field,
value: "This is a suggested field value from the Validation App!",
});
setFlaggedFieldName(null);
};

if (isLoading) return <Spinner message="Loading experiences..." />;
Expand Down Expand Up @@ -144,7 +171,11 @@ export default function ValidationPanel(): JSX.Element {
width: "100%",
}}
>
<Content experience={selectedExperience} />
<Content
experience={selectedExperience}
flaggedFieldName={flaggedFieldName ?? undefined}
onApplySuggestion={handleApplySuggestion}
/>
</div>
</div>
)}
Expand Down
Loading