Add power restore policy page

- This page will show how the system boots once power
  is restored after a power disturbance.

- API used to fetch the JSON:
  /redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json
- API used to fetch the current policy and to save updated policy:
  /redfish/v1/Systems/system/

Signed-off-by: Sukanya Pandey <sukapan1@in.ibm.com>
Change-Id: I203bd3c5d26071b882cce6b9950cdb3fb1deb212
diff --git a/src/components/AppNavigation/AppNavigationMixin.js b/src/components/AppNavigation/AppNavigationMixin.js
index 7fe63a0..a83b6c7 100644
--- a/src/components/AppNavigation/AppNavigationMixin.js
+++ b/src/components/AppNavigation/AppNavigationMixin.js
@@ -61,6 +61,11 @@
               route: '/control/manage-power-usage',
             },
             {
+              id: 'power-restore-policy',
+              label: this.$t('appNavigation.powerRestorePolicy'),
+              route: '/control/power-restore-policy',
+            },
+            {
               id: 'reboot-bmc',
               label: this.$t('appNavigation.rebootBmc'),
               route: '/control/reboot-bmc',
diff --git a/src/env/components/AppNavigation/ibm.js b/src/env/components/AppNavigation/ibm.js
index 4fd2096..dadb65d 100644
--- a/src/env/components/AppNavigation/ibm.js
+++ b/src/env/components/AppNavigation/ibm.js
@@ -61,6 +61,11 @@
               route: '/control/manage-power-usage',
             },
             {
+              id: 'power-restore-policy',
+              label: this.$t('appNavigation.powerRestorePolicy'),
+              route: '/control/power-restore-policy',
+            },
+            {
               id: 'reboot-bmc',
               label: this.$t('appNavigation.rebootBmc'),
               route: '/control/reboot-bmc',
diff --git a/src/env/router/ibm.js b/src/env/router/ibm.js
index e494047..969146c 100644
--- a/src/env/router/ibm.js
+++ b/src/env/router/ibm.js
@@ -13,6 +13,7 @@
 import NetworkSettings from '@/views/Configuration/NetworkSettings';
 import Overview from '@/views/Overview';
 import PageNotFound from '@/views/PageNotFound';
+import PowerRestorePolicy from '@/views/Control/PowerRestorePolicy';
 import ProfileSettings from '@/views/ProfileSettings';
 import RebootBmc from '@/views/Control/RebootBmc';
 import SecuritySettings from '@/views/Configuration/SecuritySettings';
@@ -181,6 +182,14 @@
         },
       },
       {
+        path: '/control/power-restore-policy',
+        name: 'power-restore-policy',
+        component: PowerRestorePolicy,
+        meta: {
+          title: i18n.t('appPageTitle.powerRestorePolicy'),
+        },
+      },
+      {
         path: '/configuration/network-settings',
         name: 'network-settings',
         component: NetworkSettings,
diff --git a/src/locales/en-US.json b/src/locales/en-US.json
index 1f68d5c..ed2495c 100644
--- a/src/locales/en-US.json
+++ b/src/locales/en-US.json
@@ -111,6 +111,7 @@
     "networkSettings": "@:appPageTitle.networkSettings",
     "overview": "@:appPageTitle.overview",
     "primaryNavigation": "Primary navigation",
+    "powerRestorePolicy": "@:appPageTitle.powerRestorePolicy",
     "rebootBmc": "@:appPageTitle.rebootBmc",
     "securitySettings": "@:appPageTitle.securitySettings",
     "sensors": "@:appPageTitle.sensors",
@@ -137,6 +138,7 @@
     "networkSettings": "Network settings",
     "overview": "Overview",
     "pageNotFound": "Page not found",
+    "powerRestorePolicy": "Power restore policy",
     "profileSettings": "Profile settings",
     "rebootBmc": "Reboot BMC",
     "securitySettings": "Security settings",
@@ -592,6 +594,20 @@
   "pagePageNotFound": {
     "description": "The requested resource could not be found."
   },
+  "pagePowerRestorePolicy": {
+    "currentPolicy": "Current Policy",
+    "description": "Configure power policy to determine how the system starts after a power disturbance.",
+    "powerPoliciesLabel": "Power restore policies",
+    "policies" :{
+      "AlwaysOn": "Always on",
+      "AlwaysOff": "Always off",
+      "LastState": "Last state"
+    },
+    "toast": {
+      "errorSaveSettings": "Error saving settings.",
+      "successSaveSettings": "Power restore policy updated successfully."
+    }
+  },
   "pageRebootBmc": {
     "lastReboot": "Last BMC reboot",
     "rebootBmc": "Reboot BMC",
diff --git a/src/router/routes.js b/src/router/routes.js
index 9a9b713..533f185 100644
--- a/src/router/routes.js
+++ b/src/router/routes.js
@@ -16,6 +16,7 @@
 import NetworkSettings from '@/views/Configuration/NetworkSettings';
 import Overview from '@/views/Overview';
 import PageNotFound from '@/views/PageNotFound';
+import PowerRestorePolicy from '@/views/Control/PowerRestorePolicy';
 import ProfileSettings from '@/views/ProfileSettings';
 import RebootBmc from '@/views/Control/RebootBmc';
 import SecuritySettings from '@/views/Configuration/SecuritySettings';
@@ -197,6 +198,14 @@
         },
       },
       {
+        path: '/control/power-restore-policy',
+        name: 'power-restore-policy',
+        component: PowerRestorePolicy,
+        meta: {
+          title: i18n.t('appPageTitle.powerRestorePolicy'),
+        },
+      },
+      {
         path: '/configuration/network-settings',
         name: 'network-settings',
         component: NetworkSettings,
diff --git a/src/store/index.js b/src/store/index.js
index 151eb68..fd8b1fc 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -11,6 +11,7 @@
 import BootSettingsStore from './modules/Control/BootSettingsStore';
 import ControlStore from './modules/Control/ControlStore';
 import PowerControlStore from './modules/Control/PowerControlStore';
+import PowerPolicyStore from './modules/Control/PowerPolicyStore';
 import NetworkSettingStore from './modules/Configuration/NetworkSettingsStore';
 import EventLogStore from './modules/Health/EventLogStore';
 import SensorsStore from './modules/Health/SensorsStore';
@@ -45,6 +46,7 @@
     hostBootSettings: BootSettingsStore,
     controls: ControlStore,
     powerControl: PowerControlStore,
+    powerPolicy: PowerPolicyStore,
     powerSupply: PowerSupplyStore,
     networkSettings: NetworkSettingStore,
     eventLog: EventLogStore,
diff --git a/src/store/modules/Control/PowerPolicyStore.js b/src/store/modules/Control/PowerPolicyStore.js
new file mode 100644
index 0000000..4e76cdf
--- /dev/null
+++ b/src/store/modules/Control/PowerPolicyStore.js
@@ -0,0 +1,72 @@
+import api from '@/store/api';
+import i18n from '@/i18n';
+
+const PowerControlStore = {
+  namespaced: true,
+  state: {
+    powerRestoreCurrentPolicy: null,
+    powerRestorePolicies: [],
+  },
+  getters: {
+    powerRestoreCurrentPolicy: (state) => state.powerRestoreCurrentPolicy,
+    powerRestorePolicies: (state) => state.powerRestorePolicies,
+  },
+  mutations: {
+    setPowerRestoreCurrentPolicy: (state, powerRestoreCurrentPolicy) =>
+      (state.powerRestoreCurrentPolicy = powerRestoreCurrentPolicy),
+    setPowerRestorePolicies: (state, powerRestorePolicies) =>
+      (state.powerRestorePolicies = powerRestorePolicies),
+  },
+  actions: {
+    async getPowerRestorePolicies({ commit }) {
+      return await api
+        .get('/redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json')
+        .then(
+          ({
+            data: {
+              definitions: { PowerRestorePolicyTypes = {} },
+            },
+          }) => {
+            let powerPoliciesData = PowerRestorePolicyTypes.enum.map(
+              (powerState) => {
+                let desc = `${i18n.t(
+                  `pagePowerRestorePolicy.policies.${powerState}`
+                )} - ${PowerRestorePolicyTypes.enumDescriptions[powerState]}`;
+                return {
+                  state: powerState,
+                  desc,
+                };
+              }
+            );
+            commit('setPowerRestorePolicies', powerPoliciesData);
+          }
+        );
+    },
+    async getPowerRestoreCurrentPolicy({ commit }) {
+      api
+        .get('/redfish/v1/Systems/system')
+        .then(({ data: { PowerRestorePolicy } }) => {
+          commit('setPowerRestoreCurrentPolicy', PowerRestorePolicy);
+        })
+        .catch((error) => console.log(error));
+    },
+    async setPowerRestorePolicy({ commit }, powerPolicy) {
+      const data = { PowerRestorePolicy: powerPolicy };
+
+      return await api
+        .patch('/redfish/v1/Systems/system', data)
+        .then(() =>
+          commit('setPowerRestoreCurrentPolicy', data.PowerRestorePolicy)
+        )
+        .then(() => i18n.t('pagePowerRestorePolicy.toast.successSaveSettings'))
+        .catch((error) => {
+          console.log(error);
+          throw new Error(
+            i18n.t('pagePowerRestorePolicy.toast.errorSaveSettings')
+          );
+        });
+    },
+  },
+};
+
+export default PowerControlStore;
diff --git a/src/views/Control/PowerRestorePolicy/PowerRestorePolicy.vue b/src/views/Control/PowerRestorePolicy/PowerRestorePolicy.vue
new file mode 100644
index 0000000..8589aed
--- /dev/null
+++ b/src/views/Control/PowerRestorePolicy/PowerRestorePolicy.vue
@@ -0,0 +1,80 @@
+<template>
+  <b-container fluid="xl">
+    <page-title :description="$t('pagePowerRestorePolicy.description')" />
+
+    <b-row>
+      <b-col sm="8" md="6" xl="12">
+        <b-form-group :label="$t('pagePowerRestorePolicy.powerPoliciesLabel')">
+          <b-form-radio
+            v-for="policy in powerRestorePolicies"
+            :key="policy.state"
+            v-model="currentPowerRestorePolicy"
+            :value="policy.state"
+            name="power-restore-policy"
+          >
+            {{ policy.desc }}
+          </b-form-radio>
+        </b-form-group>
+      </b-col>
+    </b-row>
+
+    <b-button variant="primary" type="submit" @click="submitForm">
+      {{ $t('global.action.saveSettings') }}
+    </b-button>
+  </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
+import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+
+export default {
+  name: 'PowerRestorePolicy',
+  components: { PageTitle },
+  mixins: [VuelidateMixin, BVToastMixin, LoadingBarMixin],
+  beforeRouteLeave(to, from, next) {
+    this.hideLoader();
+    next();
+  },
+  data() {
+    return {
+      policyValue: null,
+    };
+  },
+  computed: {
+    powerRestorePolicies() {
+      return this.$store.getters['powerPolicy/powerRestorePolicies'];
+    },
+    currentPowerRestorePolicy: {
+      get() {
+        return this.$store.getters['powerPolicy/powerRestoreCurrentPolicy'];
+      },
+      set(policy) {
+        this.policyValue = policy;
+      },
+    },
+  },
+  created() {
+    this.startLoader();
+    Promise.all([
+      this.$store.dispatch('powerPolicy/getPowerRestorePolicies'),
+      this.$store.dispatch('powerPolicy/getPowerRestoreCurrentPolicy'),
+    ]).finally(() => this.endLoader());
+  },
+  methods: {
+    submitForm() {
+      this.startLoader();
+      this.$store
+        .dispatch(
+          'powerPolicy/setPowerRestorePolicy',
+          this.policyValue || this.currentPowerRestorePolicy
+        )
+        .then((message) => this.successToast(message))
+        .catch(({ message }) => this.errorToast(message))
+        .finally(() => this.endLoader());
+    },
+  },
+};
+</script>
diff --git a/src/views/Control/PowerRestorePolicy/index.js b/src/views/Control/PowerRestorePolicy/index.js
new file mode 100644
index 0000000..fab0d47
--- /dev/null
+++ b/src/views/Control/PowerRestorePolicy/index.js
@@ -0,0 +1,2 @@
+import PowerRestorePolicy from './PowerRestorePolicy.vue';
+export default PowerRestorePolicy;