Skip to content

Commit eac1134

Browse files
committed
chore: fix color display of visualizer
1 parent 0d0eea9 commit eac1134

6 files changed

Lines changed: 29 additions & 51 deletions

File tree

src/components/DatastoreRelationshipEditor.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ export function DatastoreRelationshipEditor(props: DatastoreRelationshipEditorPr
119119
highlights={highlights}
120120
dataUpdated={handleDataUpdated}
121121
isReadOnly={props.isReadOnly}
122+
schema={props.services.localParseService.state.parsed}
122123
/>
123124
);
124125
}

src/components/relationshipeditor/RelationshipEditor.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Resolver } from "@authzed/spicedb-parser-js";
1+
import { ParsedSchema, Resolver } from "@authzed/spicedb-parser-js";
22
import DataEditor, {
33
CompactSelection,
44
EditableGridCell,
@@ -121,6 +121,7 @@ export type RelationshipEditorProps = {
121121
resolver?: Resolver;
122122
themeOverrides?: Partial<Theme>;
123123
dimensions?: { width: number; height: number };
124+
schema?: ParsedSchema;
124125
};
125126

126127
interface TooltipData {
@@ -144,6 +145,7 @@ export function RelationshipEditor({
144145
resolver,
145146
themeOverrides,
146147
dimensions,
148+
schema,
147149
}: RelationshipEditorProps) {
148150
// data holds the grid data+metadata array for the grid, indexed by row.
149151
const [data, setDataDirectly] = useState<AnnotatedData>(() => {
@@ -214,7 +216,7 @@ export function RelationshipEditor({
214216

215217
// relationshipsService is a service for quickly accessing the types, ids and relations defined
216218
// for all *valid* relationships.
217-
const relationshipsService = useRelationshipsService(relationships);
219+
const relationshipsService = useRelationshipsService(relationships, schema);
218220

219221
const adjustData = (dataRowIndex: number, newColumnData: string[]) => {
220222
if (isReadOnly) {

src/components/visualizer/RelationshipGraph.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { ParsedSchema } from "@authzed/spicedb-parser-js";
12
import dagre from "@dagrejs/dagre";
23
import {
34
ReactFlow,
@@ -25,6 +26,10 @@ export interface RelationshipGraphProps {
2526
* relationships are the test relationships for the schema.
2627
*/
2728
relationships: Relationship[];
29+
/**
30+
* schema is the parsed schema reference.
31+
*/
32+
schema: ParsedSchema;
2833
}
2934

3035
// Helper to create a unique node ID from namespace and object ID
@@ -93,8 +98,8 @@ type RelationshipGraphEdgeType = Omit<CustomEdgeType, "data"> & {
9398
/**
9499
* RelationshipGraph renders a graphical view of relationship instances.
95100
*/
96-
export default function RelationshipGraph({ relationships }: RelationshipGraphProps) {
97-
const relationshipsService = useRelationshipsService(relationships);
101+
export default function RelationshipGraph({ relationships, schema }: RelationshipGraphProps) {
102+
const relationshipsService = useRelationshipsService(relationships, schema);
98103
const [hoveredNodeId, setHoveredNodeId] = useState<string | null>(null);
99104
const [hoveredEdgeId, setHoveredEdgeId] = useState<string | null>(null);
100105
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });
@@ -190,7 +195,6 @@ export default function RelationshipGraph({ relationships }: RelationshipGraphPr
190195

191196
edges.push({
192197
id: `${resourceId}:${relationLabel}:${subjectId}`,
193-
type: "custom",
194198
source: resourceId,
195199
target: subjectId,
196200
label: relationLabel,

src/components/visualizer/SchemaGraph.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ function generateSchemaEdges(definitions: ParsedObjectDefinition[]): Edge[] {
193193
* SchemaGraph renders a graphical view of the schema structure.
194194
*/
195195
export default function SchemaGraph({ schema, relationships }: SchemaGraphProps) {
196-
const relationshipsService = useRelationshipsService(relationships ?? []);
196+
const relationshipsService = useRelationshipsService(relationships ?? [], schema);
197197

198198
const definitions = useMemo(
199199
() =>
@@ -206,6 +206,8 @@ export default function SchemaGraph({ schema, relationships }: SchemaGraphProps)
206206
useMemo(() => {
207207
// Create node for each definition
208208
const nodes: RelationshipNodeType[] = definitions.map((def) => {
209+
// This is using the names in the relationship service to color the schema
210+
// elements, which only makes sense if you have edges defined in your schema.
209211
const color = relationshipsService.getTypeColor(def.name) || "#e0e0e0";
210212

211213
return {

src/components/visualizer/TenantGraph.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,9 @@ export default function TenantGraph({ schema, relationships }: TenantGraphProps)
4444
</ToggleGroup>
4545
</div>
4646

47-
{viewMode === "relationships" ? (
48-
<RelationshipGraph relationships={relationships ?? []} />
49-
) : (
50-
schema && <SchemaGraph schema={schema} relationships={relationships} />
51-
)}
47+
{viewMode === "relationships"
48+
? schema && <RelationshipGraph schema={schema} relationships={relationships ?? []} />
49+
: schema && <SchemaGraph schema={schema} relationships={relationships} />}
5250
</div>
5351
);
5452
}

src/spicedb-common/services/relationshipsservice.ts

Lines changed: 11 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { ParsedSchema } from "@authzed/spicedb-parser-js";
12
import {
23
interpolateBlues,
34
interpolateGreens,
@@ -22,11 +23,6 @@ export interface RelationshipsService {
2223
*/
2324
relationships: Relationship[];
2425

25-
/**
26-
* resourceTypes is the set of object types used for resources.
27-
*/
28-
resourceTypes: string[];
29-
3026
/**
3127
* resources is the set of resources defined, without relations, in the form
3228
* `namespacename:objectid`.
@@ -40,11 +36,6 @@ export interface RelationshipsService {
4036
*/
4137
subjects: string[];
4238

43-
/**
44-
* subjectTypes is the set of object types used for subjects.
45-
*/
46-
subjectTypes: string[];
47-
4839
/**
4940
* getObjectIds returns the set of IDs for objects used as resources or subjects
5041
* for the given object type.
@@ -89,7 +80,10 @@ const colorSchemes = [
8980
* based on entered test relationships.
9081
* @param relationshipsString The encoded string of test relationships.
9182
*/
92-
export function useRelationshipsService(relationships: Relationship[]): RelationshipsService {
83+
export function useRelationshipsService(
84+
relationships: Relationship[],
85+
parsedSchema?: ParsedSchema,
86+
): RelationshipsService {
9387
return useMemo(() => {
9488
const buildingObjectsByType: Map<string, Set<string>> = new Map<string, Set<string>>();
9589

@@ -113,17 +107,6 @@ export function useRelationshipsService(relationships: Relationship[]): Relation
113107
}),
114108
);
115109

116-
const resourceTypes = filter(
117-
relationships.map((rt) => {
118-
const onr = rt.resourceAndRelation;
119-
if (onr === undefined) {
120-
return null;
121-
}
122-
123-
return onr.namespace;
124-
}),
125-
);
126-
127110
const subjects = filter(
128111
relationships.map((rt) => {
129112
const subject = rt.subject;
@@ -139,27 +122,17 @@ export function useRelationshipsService(relationships: Relationship[]): Relation
139122
}),
140123
);
141124

142-
const subjectTypes = filter(
143-
relationships.map((rt) => {
144-
const subject = rt.subject;
145-
if (subject === undefined) {
146-
return null;
147-
}
148-
149-
return subject.namespace;
150-
}),
151-
);
152-
153125
const calculateColor = (colorSet: (n: number) => string, valueSet: string[], value: string) => {
154126
if (valueSet.indexOf(value) < 0) {
155127
return undefined;
156128
}
157-
return colorSet(1 - valueSet.indexOf(value) / 9);
129+
const offset = 1 - valueSet.indexOf(value) / 9;
130+
return colorSet(offset);
158131
};
159132

160-
const possibleObjectTypes = [...resourceTypes, ...subjectTypes];
161-
162-
const objectTypes = Array.from(new Set(possibleObjectTypes));
133+
const objectTypes =
134+
parsedSchema?.definitions.filter((tld) => tld.kind === "objectDef").map((def) => def.name) ??
135+
[];
163136

164137
const objectsByType: Record<string, string[]> = {};
165138
buildingObjectsByType.forEach((idSet: Set<string>, objectType: string) => {
@@ -171,8 +144,6 @@ export function useRelationshipsService(relationships: Relationship[]): Relation
171144
return {
172145
relationships: relationships,
173146
resources: resources,
174-
resourceTypes: resourceTypes,
175-
subjectTypes: subjectTypes,
176147
subjects: subjects,
177148
getObjectIds: (objectType: string) => {
178149
const resourceIDs = relationships
@@ -202,5 +173,5 @@ export function useRelationshipsService(relationships: Relationship[]): Relation
202173
return scheme(0.65);
203174
},
204175
};
205-
}, [relationships]);
176+
}, [relationships, parsedSchema]);
206177
}

0 commit comments

Comments
 (0)