diff --git a/docs/development/plugins/functionality/extending-the-map.md b/docs/development/plugins/functionality/extending-the-map.md
new file mode 100644
index 00000000000..2e81f1a1744
--- /dev/null
+++ b/docs/development/plugins/functionality/extending-the-map.md
@@ -0,0 +1,141 @@
+---
+title: Extending the Map
+sidebar_label: Extending the Map
+---
+
+Map view displays cluster resource on a graph. Plugins can extend this graph by adding nodes and edges.
+
+## Nodes, edges and sources
+
+**Node** represents a Kubernetes resource. **Edges** connect different **nodes**, for example ReplicaSet connects to Pods it owns.
+
+
+
+To add your own nodes and edges you need to define a **Source**
+
+A graph **Source** represents a collection of Nodes and Edges along with name and icon. Source may contain other Sources.
+
+
+
+## Creating and registering a Source
+
+To define a Source create an object with the following structure:
+
+```tsx
+const mySource = {
+ id: "my-source", // ID of the source should be unique
+ label: "My Source", // label will be displayed in source picker
+ // you can provide an icon
+ icon: (
+
+ ),
+ /**
+ * useData is a hook that will be called to load nodes and edges for your source
+ * You can use hooks here that Headlamp provides to load Kubernetes resources
+ * this hook should return an object with nodes and edges or `null` if it's loading
+ * it's important that return object is not recreated every time, so useMemo is required
+ */
+ useData() {
+ return useMemo(() => {
+ // This would come from kubernetes API but it's hardcoded here as an example
+ const myResource = {
+ kind: "MyResourceKind",
+ metadata: {
+ uid: "1234",
+ name: "my-test-resource",
+ namespace: "test-namespace",
+ creationTimestamp: "1234",
+ },
+ };
+
+ const edges = []; // no edges in this source
+ const nodes = [
+ {
+ id: "1234", // ID should be unique
+ type: "kubeObject", // 'kubeObject' type represnets a kubernetes resource
+ data: {
+ // resource field is required and should contain KubeObject
+ resource: new KubeObject(myResource),
+ },
+ },
+ ];
+
+ return { edges, nodes };
+ }, []);
+ },
+};
+```
+
+Then to register it call `registerMapSource`
+
+```tsx
+registerMapSource(mySource);
+```
+
+You'll now see it in the Source picker and the Node on the Map:
+
+
+
+
+
+## Node Icons
+
+To add an icon to the Node you need to call `registerKindIcon`.
+
+Note: This is different from the Source icon. One Source may contain multiple different kinds of objects.
+
+```tsx
+registerKindIcon("MyCustomResource", {
+ // icon is a JSX element
+ icon: ,
+});
+```
+
+
+
+## Details panel
+
+When selecting a Node Map will display a details panel for the selected object.
+To add a details Panel for your Nodes call function `registerKindDetailsPage`
+
+```tsx
+// You need to provide 'kind' of the resource and a React Component that will render details
+// The props will contain name and a namespace of the Kubernetes Resource
+// Details page usually loads the resource by name and namespace
+registerKindDetailsPage("MyCustomResource", {
+ component: (props) => (
+
+ Details {props.name} {props.namespace}
+
+ ),
+});
+```
diff --git a/docs/development/plugins/functionality/images/map-rs-and-pods.png b/docs/development/plugins/functionality/images/map-rs-and-pods.png
new file mode 100644
index 00000000000..b0a6acaa214
Binary files /dev/null and b/docs/development/plugins/functionality/images/map-rs-and-pods.png differ
diff --git a/docs/development/plugins/functionality/images/node-with-an-icon.png b/docs/development/plugins/functionality/images/node-with-an-icon.png
new file mode 100644
index 00000000000..89bfaae1bf0
Binary files /dev/null and b/docs/development/plugins/functionality/images/node-with-an-icon.png differ
diff --git a/docs/development/plugins/functionality/images/node-without-an-icon.png b/docs/development/plugins/functionality/images/node-without-an-icon.png
new file mode 100644
index 00000000000..e63e1cd7bfa
Binary files /dev/null and b/docs/development/plugins/functionality/images/node-without-an-icon.png differ
diff --git a/docs/development/plugins/functionality/images/source-picker-workloads.png b/docs/development/plugins/functionality/images/source-picker-workloads.png
new file mode 100644
index 00000000000..f92de8a1071
Binary files /dev/null and b/docs/development/plugins/functionality/images/source-picker-workloads.png differ
diff --git a/docs/development/plugins/functionality/images/source-picker.png b/docs/development/plugins/functionality/images/source-picker.png
new file mode 100644
index 00000000000..c305bca8f71
Binary files /dev/null and b/docs/development/plugins/functionality/images/source-picker.png differ
diff --git a/docs/development/plugins/functionality.md b/docs/development/plugins/functionality/index.md
similarity index 92%
rename from docs/development/plugins/functionality.md
rename to docs/development/plugins/functionality/index.md
index bae6407d088..4b88f992c94 100644
--- a/docs/development/plugins/functionality.md
+++ b/docs/development/plugins/functionality/index.md
@@ -59,7 +59,7 @@ what we have so far:
Show a component in the app bar (in the top right) with
[registerAppBarAction](../api/plugin/registry/functions/registerappbaraction).
-![screenshot of the header showing two actions](./images/podcounter_screenshot.png)
+![screenshot of the header showing two actions](../images/podcounter_screenshot.png)
- Example plugin shows [How To Register an App Bar Action](https://github.com/headlamp-k8s/headlamp/tree/main/plugins/examples/pod-counter)
- API reference for [registerAppBarAction](../api/plugin/registry/functions/registerappbaraction)
@@ -69,7 +69,7 @@ Show a component in the app bar (in the top right) with
Change the logo (at the top left) with
[registerAppLogo](../api/plugin/registry/functions/registerapplogo).
-![screenshot of the logo being changed](./images/change-logo.png)
+![screenshot of the logo being changed](../images/change-logo.png)
- Example plugin shows [How To Change The Logo](https://github.com/headlamp-k8s/headlamp/tree/main/plugins/examples/change-logo)
- API reference for [registerAppLogo](../api/plugin/registry/functions/registerapplogo)
@@ -79,7 +79,7 @@ Change the logo (at the top left) with
Add menus when Headlamp is running as an app.
[Headlamp.setAppMenu](../api/plugin/lib/classes/Headlamp#setappmenu)
-![screenshot of the logo being changed](./images/app-menus.png)
+![screenshot of the logo being changed](../images/app-menus.png)
- Example plugin shows [How To Add App Menus](https://github.com/headlamp-k8s/headlamp/tree/main/plugins/examples/app-menus)
- API reference for [Headlamp.setAppMenu](../api/plugin/lib/classes/Headlamp#setappmenu)
@@ -89,7 +89,7 @@ Add menus when Headlamp is running as an app.
Change the Cluster Chooser button (in the middle top of the Headlamp app bar) with
[registerClusterChooser](../api/plugin/registry/functions/registerclusterchooser).
-![screenshot of the cluster chooser button](./images/cluster-chooser.png)
+![screenshot of the cluster chooser button](../images/cluster-chooser.png)
- Example plugin shows [How To Register Cluster Chooser button](https://github.com/headlamp-k8s/headlamp/tree/main/plugins/examples/clusterchooser)
- API reference for [registerClusterChooser](../api/plugin/registry/functions/registerclusterchooser)
@@ -100,7 +100,7 @@ Show a component to the top right area of a detail view
(in the area of the screenshot below that's highlighted as yellow)
[registerDetailsViewHeaderAction](../api/plugin/registry/functions/registerdetailsviewheaderaction).
-![screenshot of the header showing two actions](./images/header_actions_screenshot.png)
+![screenshot of the header showing two actions](../images/header_actions_screenshot.png)
- Example plugin shows [How To set a Details View Header Action](https://github.com/headlamp-k8s/headlamp/tree/main/plugins/examples/details-view)
- API reference for [registerDetailsViewHeaderAction](../api/plugin/registry/functions/registerdetailsviewheaderaction)
@@ -112,7 +112,7 @@ Change sections in cluster resources' details views with [registerDetailsViewSec
Or simply append a component at the bottom of different details views with
[registerDetailsViewSection](../api/plugin/registry/functions/registerdetailsviewsection).
-![screenshot of the appended Details View Section](./images/details-view.jpeg)
+![screenshot of the appended Details View Section](../images/details-view.jpeg)
- Example plugin shows [How To set a Details View Section](https://github.com/headlamp-k8s/headlamp/tree/main/plugins/examples/details-view)
- API reference for [registerDetailsViewSection](../api/plugin/registry/functions/registerdetailsviewsection)
@@ -140,7 +140,7 @@ Add sidebar items (menu on the left) with
[registerSidebarEntry](../api/plugin/registry/functions/registersidebarentry).
Remove sidebar items with [registerSidebarEntryFilter](../api/plugin/registry/functions/registersidebarentryfilter).
-![screenshot of the sidebar being changed](./images/sidebar.png)
+![screenshot of the sidebar being changed](../images/sidebar.png)
- Example plugin shows [How To add items to the sidebar](https://github.com/headlamp-k8s/headlamp/tree/main/plugins/examples/sidebar), and also how to remove sidebar items.
- API reference for [registerSidebarEntry](../api/plugin/registry/functions/registersidebarentry)
@@ -150,7 +150,7 @@ Remove sidebar items with [registerSidebarEntryFilter](../api/plugin/registry/fu
Change what tables across Headlamp show with [registerResourceTableColumnsProcessor](../api/plugin/registry/functions/registersidebarentry). This allows you to remove, add, update, or shuffle table columns.
-![screenshot of the pods list with a context menu added by a plugin](./images/table-context-menu.png)
+![screenshot of the pods list with a context menu added by a plugin](../images/table-context-menu.png)
- Example plugin shows [How to add a context menu to each row in the pods list table](https://github.com/headlamp-k8s/headlamp/tree/main/plugins/examples/tables).
- API reference for [registerResourceTableColumnsProcessor](../api/plugin/registry/functions/registerresourcetablecolumnsprocessor)
@@ -161,7 +161,7 @@ Headlamp has the concept of "Headlamp events". Those are fired when something re
React to Headlamp events with [registerHeadlampEventCallback](../api/plugin/registry/functions/registerheadlampeventcallback).
-![screenshot of a snackbar notification when an event occurred](./images/event-snackbar.png)
+![screenshot of a snackbar notification when an event occurred](../images/event-snackbar.png)
- Example plugin shows [How to show snackbars for Headlamp events](https://github.com/headlamp-k8s/headlamp/tree/main/plugins/examples/headlamp-events).
- API reference for [registerHeadlampEventCallback](../api/plugin/registry/functions/registerheadlampeventcallback)
@@ -172,4 +172,4 @@ The plugins can have user-configurable settings that can be used to change the b
- Example plugin shows [How to create plugin settings and use them](https://github.com/headlamp-k8s/headlamp/tree/main/plugins/examples/change-logo)
-![screenshot of the plugin settings](./images/plugin-settings.png)
+![screenshot of the plugin settings](../images/plugin-settings.png)