diff --git a/frontend/src/metabase/containers/FormikForm/FormikForm.tsx b/frontend/src/metabase/containers/FormikForm/FormikForm.tsx
index 6de3c66b64c38261f3c99ceafbfa15ee86161ae3..5e8ef961ab96bc8749d501ca3c9266ed07de8f48 100644
--- a/frontend/src/metabase/containers/FormikForm/FormikForm.tsx
+++ b/frontend/src/metabase/containers/FormikForm/FormikForm.tsx
@@ -1,7 +1,7 @@
 import React, { useCallback, useMemo, useState } from "react";
 import { t } from "ttag";
 import _ from "underscore";
-import { merge } from "icepick";
+import { assocIn, getIn, merge } from "icepick";
 
 // eslint-disable-next-line import/named
 import { Formik, FormikProps, FormikErrors, FormikHelpers } from "formik";
@@ -16,7 +16,12 @@ import {
 
 import FormikFormViewAdapter from "./FormikFormViewAdapter";
 import useInlineFields from "./useInlineFields";
-import { makeFormObject, cleanObject } from "../formUtils";
+import {
+  makeFormObject,
+  cleanObject,
+  isNestedFieldName,
+  getMaybeNestedValue,
+} from "../formUtils";
 
 interface FormContainerProps<Values extends BaseFieldValues> {
   form?: FormObject<Values>;
@@ -125,14 +130,28 @@ function Form<Values extends BaseFieldValues>({
 
   const initialValues = useMemo(() => {
     const fieldNames = formObject.fieldNames(values);
+    const [nestedFieldNames, regularFieldNames] = _.partition(
+      fieldNames,
+      isNestedFieldName,
+    );
+
+    let filteredInitialValues: FieldValues = {};
 
-    const filteredInitialValues: FieldValues = {};
     Object.keys(initialValuesProp || {}).forEach(fieldName => {
-      if (fieldNames.includes(fieldName)) {
+      if (regularFieldNames.includes(fieldName)) {
         filteredInitialValues[fieldName] = initialValuesProp[fieldName];
       }
     });
 
+    nestedFieldNames.forEach(nestedFieldName => {
+      const fieldValuePath = (nestedFieldName as string).split(".");
+      filteredInitialValues = assocIn(
+        filteredInitialValues,
+        fieldValuePath,
+        getIn(initialValuesProp, fieldValuePath),
+      );
+    });
+
     return merge(formObject.initial(values), filteredInitialValues);
   }, [values, initialValuesProp, formObject]);
 
diff --git a/frontend/src/metabase/containers/FormikForm/FormikFormViewAdapter.tsx b/frontend/src/metabase/containers/FormikForm/FormikFormViewAdapter.tsx
index 3b187a928fe10c48d41c6f0e4f744306b6c8cfe6..1b7af57a409ddc090a8dc0864551b8937dbe07e1 100644
--- a/frontend/src/metabase/containers/FormikForm/FormikFormViewAdapter.tsx
+++ b/frontend/src/metabase/containers/FormikForm/FormikFormViewAdapter.tsx
@@ -1,6 +1,5 @@
 import React, { useEffect, useState } from "react";
 import _ from "underscore";
-import { getIn } from "icepick";
 
 // eslint-disable-next-line import/named
 import { FormikProps } from "formik";
@@ -11,6 +10,7 @@ import { usePrevious } from "metabase/hooks/use-previous";
 
 import { BaseFieldValues, FormField } from "metabase-types/forms";
 
+import { getMaybeNestedValue } from "../formUtils";
 import FormView from "./FormView";
 
 type FormProps<Values extends BaseFieldValues> = Omit<
@@ -34,14 +34,6 @@ type FormProps<Values extends BaseFieldValues> = Omit<
   | "submitFailed"
 >;
 
-function getMaybeNestedValue<Value = string>(
-  obj: Record<string, Value>,
-  fieldName: string,
-): Value {
-  const isNestedField = fieldName.includes(".");
-  return isNestedField ? getIn(obj, fieldName.split(".")) : obj[fieldName];
-}
-
 interface FormikFormViewAdapterOwnProps<Values> {
   onValuesChange: (values: Values) => void;
 }
@@ -88,7 +80,7 @@ function FormikFormViewAdapter<Values extends BaseFieldValues>({
     const value = getMaybeNestedValue(values, name);
     const initialValue = getMaybeNestedValue(initialValues, name);
     const error = getMaybeNestedValue(errors as Record<string, string>, name);
-    const isTouched = !!getMaybeNestedValue<boolean>(
+    const isTouched = !!getMaybeNestedValue(
       touched as Record<string, boolean>,
       name,
     );
diff --git a/frontend/src/metabase/containers/formUtils.js b/frontend/src/metabase/containers/formUtils.js
index c3f96bc93c996906228e29c71c70c84d64a7de4b..fe94b57d303fa6ca63689a63419a8f91400f8325 100644
--- a/frontend/src/metabase/containers/formUtils.js
+++ b/frontend/src/metabase/containers/formUtils.js
@@ -100,3 +100,13 @@ export function cleanObject(object) {
   });
   return result;
 }
+
+export function isNestedFieldName(name) {
+  return name.includes(".");
+}
+
+export function getMaybeNestedValue(obj, fieldName) {
+  return isNestedFieldName(fieldName)
+    ? getIn(obj, fieldName.split("."))
+    : obj[fieldName];
+}
diff --git a/frontend/src/metabase/core/components/EditableText/EditableText.tsx b/frontend/src/metabase/core/components/EditableText/EditableText.tsx
index bb59cf66c846a24cc7eef9f3f9a143ef38932f49..3673abc4f3c7bfc408bca0c7aa6d2eabebe61937 100644
--- a/frontend/src/metabase/core/components/EditableText/EditableText.tsx
+++ b/frontend/src/metabase/core/components/EditableText/EditableText.tsx
@@ -5,9 +5,13 @@ import React, {
   HTMLAttributes,
   Ref,
   useCallback,
+  useEffect,
   useState,
   useRef,
 } from "react";
+
+import { usePrevious } from "metabase/hooks/use-previous";
+
 import { EditableTextArea, EditableTextRoot } from "./EditableText.styled";
 
 export type EditableTextAttributes = Omit<
@@ -42,6 +46,13 @@ const EditableText = forwardRef(function EditableText(
   const [submitValue, setSubmitValue] = useState(initialValue ?? "");
   const displayValue = inputValue ? inputValue : placeholder;
   const submitOnBlur = useRef(true);
+  const previousInitialValue = usePrevious(initialValue);
+
+  useEffect(() => {
+    if (initialValue && initialValue !== previousInitialValue) {
+      setInputValue(initialValue);
+    }
+  }, [initialValue, previousInitialValue]);
 
   const handleBlur = useCallback(
     e => {
diff --git a/frontend/src/metabase/entities/data-apps/data-apps.ts b/frontend/src/metabase/entities/data-apps/data-apps.ts
index b12333e22b14603f23aa0e01552c351b2b49091b..a7ebd209249d114b5844188a65b2631556aeabfd 100644
--- a/frontend/src/metabase/entities/data-apps/data-apps.ts
+++ b/frontend/src/metabase/entities/data-apps/data-apps.ts
@@ -2,13 +2,13 @@ import { color } from "metabase/lib/colors";
 import { createEntity } from "metabase/lib/entities";
 
 import { DataAppSchema } from "metabase/schema";
-import { DataAppsApi } from "metabase/services";
+import { CollectionsApi, DataAppsApi } from "metabase/services";
 
 import { Collection, DataApp } from "metabase-types/api";
 
 import { DEFAULT_COLLECTION_COLOR_ALIAS } from "../collections/constants";
 
-import { createForm } from "./forms";
+import { createNewAppForm, createAppSettingsForm } from "./forms";
 import { getDataAppIcon, isDataAppCollection } from "./utils";
 
 type EditableDataAppParams = Pick<
@@ -20,6 +20,10 @@ type EditableDataAppParams = Pick<
 type CreateDataAppParams = Partial<EditableDataAppParams> &
   Pick<EditableDataAppParams, "name">;
 
+type UpdateDataAppParams = Pick<DataApp, "id" | "collection_id"> & {
+  collection: Pick<Collection, "name" | "description">;
+};
+
 const DataApps = createEntity({
   name: "dataApps",
   nameOne: "dataApp",
@@ -45,6 +49,15 @@ const DataApps = createEntity({
         },
       });
     },
+    update: async ({
+      id,
+      collection,
+      collection_id,
+      ...rest
+    }: UpdateDataAppParams) => {
+      await CollectionsApi.update({ ...collection, id: collection_id });
+      return DataAppsApi.update({ id, ...rest });
+    },
   },
 
   objectSelectors: {
@@ -52,8 +65,11 @@ const DataApps = createEntity({
   },
 
   forms: {
-    details: {
-      fields: createForm,
+    create: {
+      fields: createNewAppForm,
+    },
+    settings: {
+      fields: createAppSettingsForm,
     },
   },
 });
diff --git a/frontend/src/metabase/entities/data-apps/forms.ts b/frontend/src/metabase/entities/data-apps/forms.ts
index c7cd5738b60a155e7245f88b8bef1742dac554a8..fa931ecff5083200a8b7df8c962ff1fb092c2c56 100644
--- a/frontend/src/metabase/entities/data-apps/forms.ts
+++ b/frontend/src/metabase/entities/data-apps/forms.ts
@@ -1,5 +1,22 @@
 import { createNameField, createDescriptionField } from "../collections/forms";
 
-export function createForm() {
+export function createNewAppForm() {
   return [createNameField(), createDescriptionField()];
 }
+
+export function createAppSettingsForm() {
+  return [
+    {
+      ...createNameField(),
+      name: "collection.name",
+    },
+    {
+      ...createDescriptionField(),
+      name: "collection.description",
+    },
+    {
+      name: "collection_id",
+      type: "hidden",
+    },
+  ];
+}
diff --git a/frontend/src/metabase/nav/containers/MainNavbar/DataAppNavbarContainer.tsx b/frontend/src/metabase/nav/containers/MainNavbar/DataAppNavbarContainer.tsx
index 7e38b9db4be66d6d1e9d9e2f97442c3c972fbf33..484497b4a407c8fb0dcabde5bca648b88fe88055 100644
--- a/frontend/src/metabase/nav/containers/MainNavbar/DataAppNavbarContainer.tsx
+++ b/frontend/src/metabase/nav/containers/MainNavbar/DataAppNavbarContainer.tsx
@@ -1,4 +1,7 @@
-import React, { useMemo } from "react";
+import React, { useCallback, useMemo, useState } from "react";
+import { t } from "ttag";
+
+import Modal from "metabase/components/Modal";
 
 import * as Urls from "metabase/lib/urls";
 
@@ -15,6 +18,8 @@ import DataAppNavbarView from "./DataAppNavbarView";
 const FETCHING_SEARCH_MODELS = ["dashboard", "dataset", "card"];
 const LIMIT = 100;
 
+type NavbarModal = "MODAL_APP_SETTINGS" | null;
+
 interface Props extends MainNavbarProps {
   dataApp: DataApp;
   loading: boolean;
@@ -31,6 +36,8 @@ function DataAppNavbarContainer({
   loading: loadingDataApp,
   ...props
 }: Props) {
+  const [modal, setModal] = useState<NavbarModal>(null);
+
   const collectionContentQuery = useMemo(() => {
     if (!dataApp) {
       return {};
@@ -42,22 +49,54 @@ function DataAppNavbarContainer({
     };
   }, [dataApp]);
 
+  const onEditAppSettings = useCallback(() => {
+    setModal("MODAL_APP_SETTINGS");
+  }, []);
+
+  const closeModal = useCallback(() => setModal(null), []);
+
+  const renderModalContent = useCallback(() => {
+    if (modal === "MODAL_APP_SETTINGS") {
+      return (
+        <DataApps.ModalForm
+          form={DataApps.forms.settings}
+          title={t`Settings`}
+          dataApp={dataApp}
+          onClose={closeModal}
+          onSaved={closeModal}
+          submitTitle={t`Save`}
+        />
+      );
+    }
+    return null;
+  }, [dataApp, modal, closeModal]);
+
   if (loadingDataApp) {
     return <NavbarLoadingView />;
   }
 
   return (
-    <Search.ListLoader
-      query={collectionContentQuery}
-      loadingAndErrorWrapper={false}
-    >
-      {({ list = [], loading: loadingAppContent }: SearchRenderProps) => {
-        if (loadingAppContent) {
-          return <NavbarLoadingView />;
-        }
-        return <DataAppNavbarView {...props} dataApp={dataApp} items={list} />;
-      }}
-    </Search.ListLoader>
+    <>
+      <Search.ListLoader
+        query={collectionContentQuery}
+        loadingAndErrorWrapper={false}
+      >
+        {({ list = [], loading: loadingAppContent }: SearchRenderProps) => {
+          if (loadingAppContent) {
+            return <NavbarLoadingView />;
+          }
+          return (
+            <DataAppNavbarView
+              {...props}
+              dataApp={dataApp}
+              items={list}
+              onEditAppSettings={onEditAppSettings}
+            />
+          );
+        }}
+      </Search.ListLoader>
+      {modal && <Modal onClose={closeModal}>{renderModalContent()}</Modal>}
+    </>
   );
 }
 
diff --git a/frontend/src/metabase/nav/containers/MainNavbar/DataAppNavbarView.tsx b/frontend/src/metabase/nav/containers/MainNavbar/DataAppNavbarView.tsx
index fe2637d94fa3f32f43b5f3b643d4fc8fb94ce3b8..f47c3a6c064423f4e7c5e141876dae2fcef9e803 100644
--- a/frontend/src/metabase/nav/containers/MainNavbar/DataAppNavbarView.tsx
+++ b/frontend/src/metabase/nav/containers/MainNavbar/DataAppNavbarView.tsx
@@ -26,9 +26,15 @@ interface Props extends MainNavbarProps {
   dataApp: DataApp;
   items: any[];
   selectedItems: SelectedItem[];
+  onEditAppSettings: () => void;
 }
 
-function DataAppNavbarView({ dataApp, items, selectedItems }: Props) {
+function DataAppNavbarView({
+  dataApp,
+  items,
+  selectedItems,
+  onEditAppSettings,
+}: Props) {
   const appPages = useMemo(
     () => items.filter(item => item.model === "dashboard"),
     [items],
@@ -63,7 +69,11 @@ function DataAppNavbarView({ dataApp, items, selectedItems }: Props) {
             <DataAppActionButton icon="add" onlyIcon />
           </Tooltip>
           <Tooltip tooltip={t`Settings`}>
-            <DataAppActionButton icon="gear" onlyIcon />
+            <DataAppActionButton
+              icon="gear"
+              onClick={onEditAppSettings}
+              onlyIcon
+            />
           </Tooltip>
         </ButtonGroup>
         <ExitDataAppButton
diff --git a/frontend/src/metabase/services.js b/frontend/src/metabase/services.js
index 02e5564e60aaf0f25b89d87905440ca06472f3c9..e24743cd747ce26cc8e8ebb9d05e1b738de3c708 100644
--- a/frontend/src/metabase/services.js
+++ b/frontend/src/metabase/services.js
@@ -183,7 +183,7 @@ export const CollectionsApi = {
 export const DataAppsApi = {
   list: GET("/api/app"),
   create: POST("/api/app"),
-  update: PUT("/api/app"),
+  update: PUT("/api/app/:id"),
 };
 
 const PIVOT_PUBLIC_PREFIX = "/api/public/pivot/";
diff --git a/frontend/src/metabase/writeback/containers/CreateDataAppModal/CreateDataAppModal.tsx b/frontend/src/metabase/writeback/containers/CreateDataAppModal/CreateDataAppModal.tsx
index 7dcdae8918b487058e0bf1115f252261e1715dac..7450e18cb23885205915eb9032d3f83481cf93c3 100644
--- a/frontend/src/metabase/writeback/containers/CreateDataAppModal/CreateDataAppModal.tsx
+++ b/frontend/src/metabase/writeback/containers/CreateDataAppModal/CreateDataAppModal.tsx
@@ -35,7 +35,7 @@ function CreateDataAppModal({ onClose, onChangeLocation }: Props) {
 
   return (
     <DataApps.ModalForm
-      form={DataApps.forms.details}
+      form={DataApps.forms.create}
       onSaved={handleSave}
       onClose={onClose}
     />