+
+
+ At times, you will need to render many embeddables and allow users to add, remove, and
+ re-arrange embeddables. Use the PresentationContainer and{' '}
+ CanAddNewPanel interfaces for this functionallity.
+
+
+ Each embeddable manages its own state. The page is only responsible for persisting and
+ providing the last persisted state to the embeddable. Implement{' '}
+ HasSerializedChildState interface to provide an embeddable with last
+ persisted state. Implement HasRuntimeChildState interface to provide an
+ embeddable with a previous session's unsaved changes.
+
+
+ This example uses session storage to persist saved state and unsaved changes while a
+ production implementation may choose to persist state elsewhere.
+ {
+ lastSavedStateSessionStorage.clear();
+ unsavedChangesSessionStorage.clear();
+ window.location.reload();
+ }}
+ >
+ Reset
+
+
+
+
+
+
+
+
+ {
+ componentApi.setTimeRange({
+ from: start,
+ to: end,
+ });
+ }}
+ onRefresh={() => {
+ componentApi.onReload();
+ }}
+ />
+
+
+
+
+
+
+
+
+
+ {panels.map(({ id, type }) => {
+ return (
+
+ parentApi}
+ hidePanelChrome={false}
+ onApiAvailable={(api) => {
+ componentApi.setChild(id, api);
+ }}
+ />
+
+
+ );
+ })}
+
+
+
+ );
+};
diff --git a/examples/embeddable_examples/public/app/presentation_container_example/components/top_nav.tsx b/examples/embeddable_examples/public/app/presentation_container_example/components/top_nav.tsx
new file mode 100644
index 0000000000000..4c33c1139056b
--- /dev/null
+++ b/examples/embeddable_examples/public/app/presentation_container_example/components/top_nav.tsx
@@ -0,0 +1,62 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import React, { useEffect, useState } from 'react';
+import useMountedState from 'react-use/lib/useMountedState';
+import { EuiBadge, EuiButton, EuiButtonEmpty, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
+import { PublishesUnsavedChanges } from '@kbn/presentation-publishing';
+
+interface Props {
+ onSave: () => Promise