-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(Knowledge Graph): adding KG parent component, search and explore…
… logic
- Loading branch information
Showing
40 changed files
with
566 additions
and
487 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file modified
BIN
+32 Bytes
(100%)
...ponents/e2e/tests/charts/charts.spec.ts-snapshots/bar-chart-chromium-darwin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified
BIN
+30 Bytes
(100%)
...onents/e2e/tests/charts/charts.spec.ts-snapshots/line-chart-chromium-darwin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified
BIN
+30 Bytes
(100%)
...nts/e2e/tests/charts/charts.spec.ts-snapshots/scatter-chart-chromium-darwin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified
BIN
+157 Bytes
(100%)
...s/e2e/tests/charts/charts.spec.ts-snapshots/status-timeline-chromium-darwin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified
BIN
+37 Bytes
(100%)
...nents/e2e/tests/kpi/kpi.spec.ts-snapshots/custom-font-sizes-chromium-darwin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified
BIN
-59 Bytes
(99%)
...eact-components/e2e/tests/kpi/kpi.spec.ts-snapshots/default-chromium-darwin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified
BIN
+76 Bytes
(100%)
.../react-components/e2e/tests/kpi/kpi.spec.ts-snapshots/error-chromium-darwin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified
BIN
-57 Bytes
(99%)
...s/react-components/e2e/tests/kpi/kpi.spec.ts-snapshots/icon-chromium-darwin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified
BIN
+30 Bytes
(100%)
...eact-components/e2e/tests/kpi/kpi.spec.ts-snapshots/loading-chromium-darwin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified
BIN
-66 Bytes
(99%)
...s/react-components/e2e/tests/kpi/kpi.spec.ts-snapshots/name-chromium-darwin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified
BIN
-70 Bytes
(99%)
...s/react-components/e2e/tests/kpi/kpi.spec.ts-snapshots/unit-chromium-darwin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified
BIN
+0 Bytes
(100%)
...e2e/tests/status/status.spec.ts-snapshots/custom-font-sizes-chromium-darwin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
128 changes: 0 additions & 128 deletions
128
packages/react-components/src/components/graph/__snapshots__/graph.spec.tsx.snap
This file was deleted.
Oops, something went wrong.
108 changes: 108 additions & 0 deletions
108
packages/react-components/src/components/knowledge-graph/KnowledgeGraphPanel.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import React, { useEffect, useCallback, useMemo, useState } from 'react'; | ||
import { IntlProvider, FormattedMessage } from 'react-intl'; | ||
import { ElementDefinition } from 'cytoscape'; | ||
import { Button, Container, Header, Input, SpaceBetween } from '@cloudscape-design/components'; | ||
import { TwinMakerKGQueryDataModule } from '@iot-app-kit/source-iottwinmaker'; | ||
import { Graph } from './graph'; | ||
import StateManager, { useKnowledgeGraphState } from './StateManager'; | ||
import { createKnowledgeGraphQueryClient } from './KnowledgeGraphQueries'; | ||
import { ResponseParser } from './responseParser'; | ||
import { getElementsDefinition } from './utils'; | ||
|
||
interface KnowledgeGraphInterface { | ||
kgDataSource: TwinMakerKGQueryDataModule; | ||
} | ||
const MAX_NUMBER_HOPS = 10; | ||
|
||
const KnowledgeGraphContainer: React.FC<KnowledgeGraphInterface> = ({ kgDataSource }) => { | ||
const { selectedGraphNodeEntityId, setQueryResult, queryResult, clearGraphResults } = useKnowledgeGraphState(); | ||
const [searchTerm, setSearchTerm] = useState(''); | ||
const [elements, setElements] = useState<ElementDefinition[]>([]); | ||
|
||
const knowledgeGraphQueryClient = useMemo(() => { | ||
return createKnowledgeGraphQueryClient(kgDataSource, setQueryResult); | ||
}, [kgDataSource, setQueryResult]); | ||
|
||
const onSearchClicked = useCallback(() => { | ||
if (searchTerm) { | ||
knowledgeGraphQueryClient.findEntitiesByName(searchTerm); | ||
} | ||
}, [knowledgeGraphQueryClient, searchTerm]); | ||
|
||
const onExploreClicked = useCallback(() => { | ||
if (selectedGraphNodeEntityId) { | ||
knowledgeGraphQueryClient.findRelatedEntities(selectedGraphNodeEntityId, MAX_NUMBER_HOPS); | ||
} | ||
}, [selectedGraphNodeEntityId, knowledgeGraphQueryClient]); | ||
|
||
const onClearClicked = useCallback(() => { | ||
clearGraphResults(true); | ||
}, [clearGraphResults]); | ||
|
||
useEffect(() => { | ||
if (queryResult) { | ||
console.log('queryResults: ', queryResult); | ||
const { nodeData, edgeData } = ResponseParser.parse(queryResult['rows'], queryResult['columnDescriptions']); | ||
setElements(getElementsDefinition([...nodeData.values()], [...edgeData.values()])); | ||
} else { | ||
setElements([]); | ||
setSearchTerm(''); | ||
} | ||
}, [queryResult]); | ||
return ( | ||
<Container header={<Header variant='h3'>Knowledge Graph</Header>}> | ||
<SpaceBetween direction='vertical' size='s'> | ||
<SpaceBetween direction='horizontal' size='s'> | ||
<Input | ||
type='text' | ||
value={searchTerm} | ||
onChange={(e) => { | ||
setSearchTerm(e.detail.value); | ||
}} | ||
></Input> | ||
<Button onClick={onSearchClicked}> | ||
{/* eventually will move to auto-generated IDs */} | ||
<FormattedMessage | ||
id='KnowledgeGraphPanel.button.search' | ||
defaultMessage='Search' | ||
description='Search button text' | ||
/> | ||
</Button> | ||
</SpaceBetween> | ||
{/* inline styling here for testing only this will be fixed in the next PR */} | ||
<Graph elements={elements} style={{ width: '1000px', height: '1000px' }} /> | ||
<SpaceBetween direction='horizontal' size='s'> | ||
<Button disabled={selectedGraphNodeEntityId ? false : true} onClick={onExploreClicked}> | ||
<FormattedMessage | ||
id='KnowledgeGraphPanel.button.explore' | ||
defaultMessage='Explore' | ||
description='Explore button text' | ||
/> | ||
</Button> | ||
{queryResult ? ( | ||
<Button onClick={onClearClicked}>Clear</Button> | ||
) : ( | ||
<Button disabled onClick={onClearClicked}> | ||
<FormattedMessage | ||
id='KnowledgeGraphPanel.button.clear' | ||
defaultMessage='Clear' | ||
description='Clear button text' | ||
/> | ||
</Button> | ||
)} | ||
</SpaceBetween> | ||
</SpaceBetween> | ||
</Container> | ||
); | ||
}; | ||
export const KnowledgeGraph: React.FC<KnowledgeGraphInterface> = (props) => { | ||
return ( | ||
<StateManager> | ||
{/* For the moment we're setting it to a fixed language, | ||
later we will determine the user's locale by evaluating the language request sent by the browser */} | ||
<IntlProvider locale='en' defaultLocale='en'> | ||
<KnowledgeGraphContainer {...props} /> | ||
</IntlProvider> | ||
</StateManager> | ||
); | ||
}; |
26 changes: 26 additions & 0 deletions
26
packages/react-components/src/components/knowledge-graph/KnowledgeGraphQueries.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { TwinMakerKGQueryDataModule } from '@iot-app-kit/source-iottwinmaker'; | ||
import { ExecuteQueryCommandOutput } from '@aws-sdk/client-iottwinmaker'; | ||
export interface KnowledgeGraphQueryInterface { | ||
findEntitiesByName(name: string): Promise<void>; | ||
findRelatedEntities(entityId: string, numberOfHops: number): Promise<void>; | ||
} | ||
export const createKnowledgeGraphQueryClient = function ( | ||
dataSource: TwinMakerKGQueryDataModule, | ||
updateQueryResults: (result: ExecuteQueryCommandOutput) => void | ||
) { | ||
const knowledgeGraphQuery: KnowledgeGraphQueryInterface = { | ||
findEntitiesByName: async (name: string): Promise<void> => { | ||
const result = await dataSource.executeQuery({ | ||
queryStatement: `SELECT e FROM EntityGraph MATCH (e) WHERE e.entityName like '%${name}%'`, | ||
}); | ||
updateQueryResults(result); | ||
}, | ||
findRelatedEntities: async (entityId: string, numberOfHops: number): Promise<void> => { | ||
const result = await dataSource.executeQuery({ | ||
queryStatement: `SELECT e1 FROM EntityGraph MATCH (e)-[]-{1,${numberOfHops}}(e1) WHERE e.entityId = '${entityId}'`, | ||
}); | ||
updateQueryResults(result); | ||
}, | ||
}; | ||
return knowledgeGraphQuery; | ||
}; |
43 changes: 43 additions & 0 deletions
43
packages/react-components/src/components/knowledge-graph/StateManager.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import React, { ReactNode, createContext, useContext, useState } from 'react'; | ||
import { ExecuteQueryCommandOutput } from '@aws-sdk/client-iottwinmaker'; | ||
interface KnowledgeGraphContext { | ||
selectedGraphNodeEntityId?: string; | ||
setSelectedGraphNodeEntityId: (entityId?: string) => void; | ||
queryStatement?: string; | ||
setQueryStatement: (query: string) => void; | ||
queryResult?: ExecuteQueryCommandOutput; | ||
setQueryResult: (result: ExecuteQueryCommandOutput) => void; | ||
clearGraphResults: (clear: boolean) => void; | ||
} | ||
export interface StateManagerProps { | ||
children: ReactNode; | ||
} | ||
|
||
const context = createContext<KnowledgeGraphContext>({} as KnowledgeGraphContext); | ||
export function useKnowledgeGraphState() { | ||
return useContext(context); | ||
} | ||
const StateManager: React.FC<StateManagerProps> = ({ children }) => { | ||
const [selectedGraphNodeEntityId, setSelectedGraphNodeEntityId] = useState<string>(); | ||
const [queryStatement, setQueryStatement] = useState<string>(); | ||
const [queryResult, setQueryResult] = useState<ExecuteQueryCommandOutput>(); | ||
const clearGraphResults = (clear: boolean) => { | ||
if (clear) setQueryResult(undefined); | ||
}; | ||
return ( | ||
<context.Provider | ||
value={{ | ||
selectedGraphNodeEntityId, | ||
setSelectedGraphNodeEntityId, | ||
queryStatement, | ||
setQueryStatement, | ||
queryResult, | ||
setQueryResult, | ||
clearGraphResults, | ||
}} | ||
> | ||
{children} | ||
</context.Provider> | ||
); | ||
}; | ||
export default StateManager; |
128 changes: 128 additions & 0 deletions
128
...s/react-components/src/components/knowledge-graph/graph/__snapshots__/graph.spec.tsx.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`<graph /> renders default elements 1`] = ` | ||
<div> | ||
<div | ||
class="iot-app-kit-graph" | ||
> | ||
<div | ||
data-mocked="CytoscapeComponent" | ||
layout="[object Object]" | ||
style="width: 100%; height: 100%;" | ||
stylesheet="[object Object],[object Object],[object Object],[object Object]" | ||
> | ||
[] | ||
</div> | ||
<ul | ||
class="iot-app-kit-graph-controls" | ||
> | ||
<li | ||
class="iot-app-kit-graph-control-item" | ||
> | ||
<button | ||
class="iot-app-kit-graph-button awsui_button_vjswe_12zyy_101 awsui_variant-icon_vjswe_12zyy_166 awsui_button-no-text_vjswe_12zyy_885" | ||
data-testid="fit-button" | ||
type="submit" | ||
> | ||
<span | ||
class="awsui_icon_vjswe_12zyy_905 awsui_icon-left_vjswe_12zyy_905 awsui_icon_h11ix_ahfiu_98 awsui_size-normal-mapped-height_h11ix_ahfiu_151 awsui_size-normal_h11ix_ahfiu_147 awsui_variant-normal_h11ix_ahfiu_219" | ||
> | ||
<svg | ||
aria-hidden="true" | ||
focusable="false" | ||
viewBox="0 0 16 16" | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<path | ||
d="M14 11v3h-4M2 11v3h4M2 5V2h4M14 5V2h-4M10 6H6v4h4V6Z" | ||
/> | ||
</svg> | ||
</span> | ||
</button> | ||
</li> | ||
<li | ||
class="iot-app-kit-graph-control-item" | ||
> | ||
<button | ||
class="iot-app-kit-graph-button awsui_button_vjswe_12zyy_101 awsui_variant-icon_vjswe_12zyy_166 awsui_button-no-text_vjswe_12zyy_885" | ||
data-testid="center-button" | ||
type="submit" | ||
> | ||
<span | ||
class="awsui_icon_vjswe_12zyy_905 awsui_icon-left_vjswe_12zyy_905 awsui_icon_h11ix_ahfiu_98 awsui_size-normal-mapped-height_h11ix_ahfiu_151 awsui_size-normal_h11ix_ahfiu_147 awsui_variant-normal_h11ix_ahfiu_219" | ||
> | ||
<svg | ||
aria-hidden="true" | ||
focusable="false" | ||
viewBox="0 0 16 16" | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<path | ||
d="M9 2h5v5M7 2H2v5M7 14H2V9M9 14h5V9M2 2l12 12M14 2 2 14" | ||
/> | ||
</svg> | ||
</span> | ||
</button> | ||
</li> | ||
<li | ||
class="iot-app-kit-graph-control-item" | ||
> | ||
<button | ||
class="iot-app-kit-graph-button awsui_button_vjswe_12zyy_101 awsui_variant-icon_vjswe_12zyy_166 awsui_button-no-text_vjswe_12zyy_885" | ||
data-testid="zoom-in-button" | ||
type="submit" | ||
> | ||
<span | ||
class="awsui_icon_vjswe_12zyy_905 awsui_icon-left_vjswe_12zyy_905 awsui_icon_h11ix_ahfiu_98 awsui_size-normal-mapped-height_h11ix_ahfiu_151 awsui_size-normal_h11ix_ahfiu_147 awsui_variant-normal_h11ix_ahfiu_219" | ||
> | ||
<svg | ||
aria-hidden="true" | ||
focusable="false" | ||
viewBox="0 0 16 16" | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<circle | ||
cx="6.885" | ||
cy="6.885" | ||
r="5.385" | ||
/> | ||
<path | ||
d="m14.5 14.5-3.846-3.846M7 4v6M10 7H4" | ||
/> | ||
</svg> | ||
</span> | ||
</button> | ||
</li> | ||
<li | ||
class="iot-app-kit-graph-control-item" | ||
> | ||
<button | ||
class="iot-app-kit-graph-button awsui_button_vjswe_12zyy_101 awsui_variant-icon_vjswe_12zyy_166 awsui_button-no-text_vjswe_12zyy_885" | ||
data-testid="zoom-out-button" | ||
type="submit" | ||
> | ||
<span | ||
class="awsui_icon_vjswe_12zyy_905 awsui_icon-left_vjswe_12zyy_905 awsui_icon_h11ix_ahfiu_98 awsui_size-normal-mapped-height_h11ix_ahfiu_151 awsui_size-normal_h11ix_ahfiu_147 awsui_variant-normal_h11ix_ahfiu_219" | ||
> | ||
<svg | ||
aria-hidden="true" | ||
focusable="false" | ||
viewBox="0 0 16 16" | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<circle | ||
cx="6.885" | ||
cy="6.885" | ||
r="5.385" | ||
/> | ||
<path | ||
d="m14.5 14.5-3.846-3.846M10 7H4" | ||
/> | ||
</svg> | ||
</span> | ||
</button> | ||
</li> | ||
</ul> | ||
</div> | ||
</div> | ||
`; |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.