<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Demo</title>
  <script src="bootConfig.js"></script>
  <script src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js" id="sap-ui-bootstrap"></script>
</head>
<body class="sapUiBody" id="content">
</body>
</html>
sap.ui.define([
  "sap/ui/core/mvc/Controller",
  "sap/m/MessageToast",
], function(Controller, MessageToast) {
  "use strict";
  const batchGroupId = "myUpdateGroupId";

  return Controller.extend("demo.controller.Detail", {
    onInit: function() {
      const route = this.getOwnerComponent().getRouter().getRoute("masterDetail");
      route.attachPatternMatched(this.onPatternMatched, this);
      route.attachBeforeMatched(this.reset, this);
    },

    onPatternMatched: function(event) {
      this.bindSelectedItem(event.getParameter("arguments").userName);
    },

    bindSelectedItem: function(userName) {
      this.getView().bindElement({
        path: `/People('${userName}')`,
        parameters: {
          $$updateGroupId: batchGroupId
        },
        events: {
          dataRequested: () => this.byId("page").setBusy(true),
          dataReceived: () => this.byId("page").setBusy(false),
        },
      });
    },

    onSubmitPress: function() {
      if (this.getOwnerComponent().getModel().hasPendingChanges()) {
        this.byId("page").setBusy(true);
        this.refreshMasterList(batchGroupId);
        this.submitBatch(batchGroupId).then(() => {
          this.resetEditingStatus();
          this.byId("page").setBusy(false);
          MessageToast.show("User updated");
        });
      }
    },

    refreshMasterList: function(groupId) {
      const bus = this.getOwnerComponent().getEventBus();
      bus.publish("master", "refresh", groupId);
    },

    submitBatch: function(id) {
      return this.getOwnerComponent().getModel().submitBatch(id);
    },

    onCancelPress: function() {
      this.reset();
    },

    reset: function(event) {
      this.getOwnerComponent().getModel().resetChanges(batchGroupId);
      this.resetEditingStatus();
    },

    resetEditingStatus: function() {
      const model = this.getOwnerComponent().getModel("detailViewModel");
      model.setProperty("/editing", false);
    }

  });
});
sap.ui.define([
  "sap/ui/core/mvc/Controller",
  "sap/ui/Device"
], function(Controller, Device) {
  "use strict";

  return Controller.extend("demo.controller.Master", {
    onInit: function() {
      const bus = this.getOwnerComponent().getEventBus();
      bus.subscribe("master", "refresh", this.shouldRefresh, this);
    },

    onItemPress: function(event) {
      const item = event.getParameter("listItem");
      this.navToDetailOf(item);
    },

    navToDetailOf: function(item) {
      this.getOwnerComponent().getRouter().navTo("masterDetail", {
        userName: item.getBindingContext().getProperty("UserName")
      }, !Device.system.phone);
    },

    shouldRefresh: function(channelId, eventId, groupId) {
      const listBinding = this.byId("masterList").getBinding("items");
      this.refresh(listBinding, groupId);
    },
    
    refresh: function(binding, groupId) {
      if (binding.hasPendingChanges()) {
        // show message that there are some changes left
      } else {
        return binding.refresh(groupId);
      }
    },

  });
});
<mvc:View
  xmlns:mvc="sap.ui.core.mvc"
  xmlns="sap.m"
  displayBlock="true"
  height="100%"
>
  <SplitApp id="rootSplitContainer">
    <masterPages>
      <!-- will be added by Router -->
    </masterPages>
    <detailPages>
      <!-- will be added by Router -->
    </detailPages>
  </SplitApp>
</mvc:View>
<mvc:View
  xmlns:mvc="sap.ui.core.mvc"
  xmlns="sap.m"
  controllerName="demo.controller.Master"
>
  <Page
    title="Users"
    backgroundDesign="List"
  >
    <List id="masterList"
      busyIndicatorDelay="0"
      mode="SingleSelectMaster"
      growing="true"
      items="{/People}"
      itemPress=".onItemPress"
    >
      <StandardListItem
        title="{FirstName}"
        description="{LastName}"
        type="Active"
      />
    </List>
  </Page>
</mvc:View>
<mvc:View
  xmlns:mvc="sap.ui.core.mvc"
  xmlns="sap.m"
>
  <MessagePage
    title="Demo"
    text="Choose an Item from Master List"
    description="Nothing to see here"
  />
</mvc:View>
<mvc:View
  xmlns:mvc="sap.ui.core.mvc"
  xmlns="sap.m"
  xmlns:form="sap.ui.layout.form"
  controllerName="demo.controller.Detail"
>
  <Page id="page"
    title="User: {UserName}"
    floatingFooter="true"
    showFooter="{detailViewModel>/editing}"
  >
    <headerContent>
      <ToggleButton
        icon="sap-icon://edit"
        pressed="{detailViewModel>/editing}"
        visible="{= !${detailViewModel>/editing}}"
      />
    </headerContent>
    <form:SimpleForm id="form"
      layout="ResponsiveGridLayout"
      editable="true"
    >
      <Label text="First Name"/>
      <Input
        value="{
          path: 'FirstName',
          type: 'sap.ui.model.odata.type.String',
          constraints: {
            nullable: false,
            maxLength: 30
          }
        }"
        editable="{detailViewModel>/editing}"
      />
      <Label text="Last Name"/>
      <Input
        value="{
          path: 'LastName',
          type: 'sap.ui.model.odata.type.String',
          constraints: {
            nullable: false,
            maxLength: 30
          }
        }"
        editable="{detailViewModel>/editing}"
      />
    </form:SimpleForm>
    <footer>
      <OverflowToolbar>
        <ToolbarSpacer/>
        <Button id="submitBtn"
          text="Submit"
          type="Emphasized"
          press=".onSubmitPress"
        />
        <Button id="cancelBtn"
          text="Cancel"
          press=".onCancelPress"
        />
      </OverflowToolbar>
    </footer>
  </Page>
</mvc:View>
{
  "_version": "1.10.0",
  "start_url": "index.html",
  "sap.app": {
    "id": "demo",
    "type": "application",
    "title": "Demo",
    "description": "Sample Code",
    "applicationVersion": {
      "version": "1.0.0"
    },
    "dataSources": {
      "myDataSource": {
        "uri": "https://cors-anywhere.herokuapp.com/https://services.odata.org/TripPinRESTierService/(S(0m1hkqy5kzmpz1xxhqwjihdk))/",
        "type": "OData",
        "settings": {
          "odataVersion": "4.0"
        }
      }
    }
  },
  "sap.ui": {
    "technology": "UI5",
    "deviceTypes": {
      "desktop": true,
      "tablet": true,
      "phone": true
    },
    "supportedThemes": [
      "sap_belize_hcw",
      "sap_belize_hcb",
      "sap_belize",
      "sap_belize_plus"
    ]
  },
  "sap.ui5": {
    "handleValidation": true,
    "dependencies": {
      "minUI5Version": "1.54.0",
      "libs": {
        "sap.ui.core": {},
        "sap.m": {},
        "sap.ui.layout": {}
      }
    },
    "contentDensities": {
      "compact": true,
      "cozy": true
    },
    "resources": {
      "js": [

      ],
      "css": [

      ]
    },
    "models": {
      "": {
        "dataSource": "myDataSource",
        "settings": {
          "autoExpandSelect": true,
          "operationMode": "Server",
          "synchronizationMode": "None"
        },
        "preload": true
      },
      "detailViewModel": {
        "type": "sap.ui.model.json.JSONModel"
      }
    },
    "rootView": {
      "viewName": "demo.view.Root",
      "id": "rootView",
      "type": "XML",
      "async": true,
      "height": "100%",
      "displayBlock": true
    },
    "routing": {
      "routes": [{
        "name": "master",
        "pattern": "",
        "target": ["emptyDetail", "master"]
      }, {
        "name": "masterDetail",
        "pattern": "user/{userName}",
        "target": ["detail", "master"]
      }],
      "targets": {
        "master": {
          "viewId": "masterView",
          "viewName": "Master",
          "controlAggregation": "masterPages"
        },
        "detail": {
          "viewId": "detailView",
          "viewName": "Detail",
          "controlAggregation": "detailPages",
          "viewLevel": 1,
          "transition": "show"
        },
        "emptyDetail": {
          "viewId": "emptyDetailView",
          "viewName": "EmptyDetail",
          "controlAggregation": "detailPages"
        }
      },
      "config": {
        "routerClass": "sap.m.routing.Router",
        "async": true,
        "viewType": "XML",
        "viewPath": "demo.view",
        "controlId": "rootSplitContainer"
      }
    }
  }
}
sap.ui.define([
  "sap/ui/core/UIComponent",
], function(UIComponent) {
  "use strict";

  return UIComponent.extend("demo.Component", {
    metadata: {
      manifest: "json"
    },

    init: function() {
      UIComponent.prototype.init.apply(this, arguments);
      this.getModel("detailViewModel").setProperty("/editing", false);
      this.getRouter().initialize();
      window.onbeforeunload = () => this.getModel().hasPendingChanges() || null;
    },
    
  });
});
this["sap-ui-config"] = {
  libs: "sap.ui.core, sap.m, sap.ui.layout",
  preload: "async",
  theme: "sap_belize",
  compatVersion: "edge",
  resourceRoots: {
    "demo": "./"
  },

  onInit: () => sap.ui.component({
    name: "demo",
    manifest: true,
  }).then(createdComponent => sap.ui.require([
    "sap/m/Shell",
    "sap/ui/core/ComponentContainer",
  ], (Shell, ComponentContainer) => new Shell({
    app: new ComponentContainer({
      component: createdComponent,
      height: "100%",
    }),
  }).placeAt("content"))),

  "xx-componentPreload": "off",
  "xx-waitForTheme": true,
  "xx-async": true,
  "xx-xml-processing": "sequential",
};