IA update: Update configuration to settings

This is the fourth update to information architecture changes and has
the following changes:

- The configuration section is updated to settings
- The date and time settings page is updated to date and time
- The network settings page is updated to network
- The power restore policy page in operations section is moved to
settings section

Signed-off-by: Sandeepa Singh <sandeepa.singh@ibm.com>
Change-Id: I6f5ab25f5227530be430bd39a4d9629b3bf09d8b
diff --git a/src/views/Settings/DateTime/DateTime.vue b/src/views/Settings/DateTime/DateTime.vue
new file mode 100644
index 0000000..e62e344
--- /dev/null
+++ b/src/views/Settings/DateTime/DateTime.vue
@@ -0,0 +1,405 @@
+<template>
+  <b-container fluid="xl">
+    <page-title />
+    <b-row>
+      <b-col md="8" xl="6">
+        <alert variant="info" class="mb-4">
+          <span>
+            {{ $t('pageDateTime.alert.message') }}
+            <b-link to="/profile-settings">
+              {{ $t('pageDateTime.alert.link') }}</b-link
+            >
+          </span>
+        </alert>
+      </b-col>
+    </b-row>
+    <page-section>
+      <b-row>
+        <b-col lg="3">
+          <dl>
+            <dt>{{ $t('pageDateTime.form.date') }}</dt>
+            <dd v-if="bmcTime">{{ bmcTime | formatDate }}</dd>
+            <dd v-else>--</dd>
+          </dl>
+        </b-col>
+        <b-col lg="3">
+          <dl>
+            <dt>{{ $t('pageDateTime.form.time.label') }}</dt>
+            <dd v-if="bmcTime">{{ bmcTime | formatTime }}</dd>
+            <dd v-else>--</dd>
+          </dl>
+        </b-col>
+      </b-row>
+    </page-section>
+    <page-section :section-title="$t('pageDateTime.configureSettings')">
+      <b-form novalidate @submit.prevent="submitForm">
+        <b-form-group
+          label="Configure date and time"
+          :disabled="loading"
+          label-sr-only
+        >
+          <b-form-radio
+            v-model="form.configurationSelected"
+            value="manual"
+            data-test-id="dateTime-radio-configureManual"
+          >
+            {{ $t('pageDateTime.form.manual') }}
+          </b-form-radio>
+          <b-row class="mt-3 ml-3">
+            <b-col sm="6" lg="4" xl="3">
+              <b-form-group
+                :label="$t('pageDateTime.form.date')"
+                label-for="input-manual-date"
+              >
+                <b-form-text id="date-format-help">YYYY-MM-DD</b-form-text>
+                <b-input-group>
+                  <b-form-input
+                    id="input-manual-date"
+                    v-model="form.manual.date"
+                    :state="getValidationState($v.form.manual.date)"
+                    :disabled="ntpOptionSelected"
+                    data-test-id="dateTime-input-manualDate"
+                    class="form-control-with-button"
+                    @blur="$v.form.manual.date.$touch()"
+                  />
+                  <b-form-invalid-feedback role="alert">
+                    <div v-if="!$v.form.manual.date.pattern">
+                      {{ $t('global.form.invalidFormat') }}
+                    </div>
+                    <div v-if="!$v.form.manual.date.required">
+                      {{ $t('global.form.fieldRequired') }}
+                    </div>
+                  </b-form-invalid-feedback>
+                  <b-form-datepicker
+                    v-model="form.manual.date"
+                    class="btn-datepicker btn-icon-only"
+                    button-only
+                    right
+                    :hide-header="true"
+                    :locale="locale"
+                    :label-help="
+                      $t('global.calendar.useCursorKeysToNavigateCalendarDates')
+                    "
+                    :title="$t('global.calendar.selectDate')"
+                    :disabled="ntpOptionSelected"
+                    button-variant="link"
+                    aria-controls="input-manual-date"
+                  >
+                    <template #button-content>
+                      <icon-calendar />
+                      <span class="sr-only">
+                        {{ $t('global.calendar.selectDate') }}
+                      </span>
+                    </template>
+                  </b-form-datepicker>
+                </b-input-group>
+              </b-form-group>
+            </b-col>
+            <b-col sm="6" lg="4" xl="3">
+              <b-form-group
+                :label="$t('pageDateTime.form.time.timezone', { timezone })"
+                label-for="input-manual-time"
+              >
+                <b-form-text id="time-format-help">HH:MM</b-form-text>
+                <b-input-group>
+                  <b-form-input
+                    id="input-manual-time"
+                    v-model="form.manual.time"
+                    :state="getValidationState($v.form.manual.time)"
+                    :disabled="ntpOptionSelected"
+                    data-test-id="dateTime-input-manualTime"
+                    @blur="$v.form.manual.time.$touch()"
+                  />
+                  <b-form-invalid-feedback role="alert">
+                    <div v-if="!$v.form.manual.time.pattern">
+                      {{ $t('global.form.invalidFormat') }}
+                    </div>
+                    <div v-if="!$v.form.manual.time.required">
+                      {{ $t('global.form.fieldRequired') }}
+                    </div>
+                  </b-form-invalid-feedback>
+                </b-input-group>
+              </b-form-group>
+            </b-col>
+          </b-row>
+          <b-form-radio
+            v-model="form.configurationSelected"
+            value="ntp"
+            data-test-id="dateTime-radio-configureNTP"
+          >
+            NTP
+          </b-form-radio>
+          <b-row class="mt-3 ml-3">
+            <b-col sm="6" lg="4" xl="3">
+              <b-form-group
+                :label="$t('pageDateTime.form.ntpServers.server1')"
+                label-for="input-ntp-1"
+              >
+                <b-input-group>
+                  <b-form-input
+                    id="input-ntp-1"
+                    v-model="form.ntp.firstAddress"
+                    :state="getValidationState($v.form.ntp.firstAddress)"
+                    :disabled="manualOptionSelected"
+                    data-test-id="dateTime-input-ntpServer1"
+                    @blur="$v.form.ntp.firstAddress.$touch()"
+                  />
+                  <b-form-invalid-feedback role="alert">
+                    <div v-if="!$v.form.ntp.firstAddress.required">
+                      {{ $t('global.form.fieldRequired') }}
+                    </div>
+                  </b-form-invalid-feedback>
+                </b-input-group>
+              </b-form-group>
+            </b-col>
+            <b-col sm="6" lg="4" xl="3">
+              <b-form-group
+                :label="$t('pageDateTime.form.ntpServers.server2')"
+                label-for="input-ntp-2"
+              >
+                <b-input-group>
+                  <b-form-input
+                    id="input-ntp-2"
+                    v-model="form.ntp.secondAddress"
+                    :disabled="manualOptionSelected"
+                    data-test-id="dateTime-input-ntpServer2"
+                  />
+                </b-input-group>
+              </b-form-group>
+            </b-col>
+            <b-col sm="6" lg="4" xl="3">
+              <b-form-group
+                :label="$t('pageDateTime.form.ntpServers.server3')"
+                label-for="input-ntp-3"
+              >
+                <b-input-group>
+                  <b-form-input
+                    id="input-ntp-3"
+                    v-model="form.ntp.thirdAddress"
+                    :disabled="manualOptionSelected"
+                    data-test-id="dateTime-input-ntpServer3"
+                  />
+                </b-input-group>
+              </b-form-group>
+            </b-col>
+          </b-row>
+          <b-button
+            variant="primary"
+            type="submit"
+            data-test-id="dateTime-button-saveSettings"
+          >
+            {{ $t('global.action.saveSettings') }}
+          </b-button>
+        </b-form-group>
+      </b-form>
+    </page-section>
+  </b-container>
+</template>
+
+<script>
+import Alert from '@/components/Global/Alert';
+import IconCalendar from '@carbon/icons-vue/es/calendar/20';
+import PageTitle from '@/components/Global/PageTitle';
+import PageSection from '@/components/Global/PageSection';
+
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import LoadingBarMixin, { loading } from '@/components/Mixins/LoadingBarMixin';
+import LocalTimezoneLabelMixin from '@/components/Mixins/LocalTimezoneLabelMixin';
+import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
+
+import { mapState } from 'vuex';
+import { requiredIf, helpers } from 'vuelidate/lib/validators';
+
+const isoDateRegex = /([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))/;
+const isoTimeRegex = /^(0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$/;
+
+export default {
+  name: 'DateTime',
+  components: { Alert, IconCalendar, PageTitle, PageSection },
+  mixins: [
+    BVToastMixin,
+    LoadingBarMixin,
+    LocalTimezoneLabelMixin,
+    VuelidateMixin,
+  ],
+  beforeRouteLeave(to, from, next) {
+    this.hideLoader();
+    next();
+  },
+  data() {
+    return {
+      locale: this.$store.getters['global/languagePreference'],
+      form: {
+        configurationSelected: 'manual',
+        manual: {
+          date: '',
+          time: '',
+        },
+        ntp: { firstAddress: '', secondAddress: '', thirdAddress: '' },
+      },
+      loading,
+    };
+  },
+  validations() {
+    return {
+      form: {
+        manual: {
+          date: {
+            required: requiredIf(function () {
+              return this.form.configurationSelected === 'manual';
+            }),
+            pattern: helpers.regex('pattern', isoDateRegex),
+          },
+          time: {
+            required: requiredIf(function () {
+              return this.form.configurationSelected === 'manual';
+            }),
+            pattern: helpers.regex('pattern', isoTimeRegex),
+          },
+        },
+        ntp: {
+          firstAddress: {
+            required: requiredIf(function () {
+              return this.form.configurationSelected === 'ntp';
+            }),
+          },
+        },
+      },
+    };
+  },
+  computed: {
+    ...mapState('dateTime', ['ntpServers', 'isNtpProtocolEnabled']),
+    bmcTime() {
+      return this.$store.getters['global/bmcTime'];
+    },
+    ntpOptionSelected() {
+      return this.form.configurationSelected === 'ntp';
+    },
+    manualOptionSelected() {
+      return this.form.configurationSelected === 'manual';
+    },
+    isUtcDisplay() {
+      return this.$store.getters['global/isUtcDisplay'];
+    },
+    timezone() {
+      if (this.isUtcDisplay) {
+        return 'UTC';
+      }
+      return this.localOffset();
+    },
+  },
+  watch: {
+    ntpServers() {
+      this.setNtpValues();
+    },
+    manualDate() {
+      this.emitChange();
+    },
+    bmcTime() {
+      this.form.manual.date = this.$options.filters.formatDate(
+        this.$store.getters['global/bmcTime']
+      );
+      this.form.manual.time = this.$options.filters
+        .formatTime(this.$store.getters['global/bmcTime'])
+        .slice(0, 5);
+    },
+  },
+  created() {
+    this.startLoader();
+    this.setNtpValues();
+    Promise.all([
+      this.$store.dispatch('global/getBmcTime'),
+      this.$store.dispatch('dateTime/getNtpData'),
+    ]).finally(() => this.endLoader());
+  },
+  methods: {
+    emitChange() {
+      if (this.$v.$invalid) return;
+      this.$v.$reset(); //reset to re-validate on blur
+      this.$emit('change', {
+        manualDate: this.manualDate ? new Date(this.manualDate) : null,
+      });
+    },
+    setNtpValues() {
+      this.form.configurationSelected = this.isNtpProtocolEnabled
+        ? 'ntp'
+        : 'manual';
+      [
+        this.form.ntp.firstAddress = '',
+        this.form.ntp.secondAddress = '',
+        this.form.ntp.thirdAddress = '',
+      ] = [this.ntpServers[0], this.ntpServers[1], this.ntpServers[2]];
+    },
+    submitForm() {
+      this.$v.$touch();
+      if (this.$v.$invalid) return;
+      this.startLoader();
+
+      let dateTimeForm = {};
+      let isNTPEnabled = this.form.configurationSelected === 'ntp';
+
+      if (!isNTPEnabled) {
+        const isUtcDisplay = this.$store.getters['global/isUtcDisplay'];
+        let date;
+
+        dateTimeForm.ntpProtocolEnabled = false;
+
+        if (isUtcDisplay) {
+          // Create UTC Date
+          date = this.getUtcDate(this.form.manual.date, this.form.manual.time);
+        } else {
+          // Create local Date
+          date = new Date(`${this.form.manual.date} ${this.form.manual.time}`);
+        }
+
+        dateTimeForm.updatedDateTime = date.toISOString();
+      } else {
+        dateTimeForm.ntpProtocolEnabled = true;
+
+        dateTimeForm.ntpServersArray = [
+          this.form.ntp.firstAddress,
+          this.form.ntp.secondAddress,
+          this.form.ntp.thirdAddress,
+        ];
+      }
+
+      this.$store
+        .dispatch('dateTime/updateDateTime', dateTimeForm)
+        .then((success) => {
+          this.successToast(success);
+          if (!isNTPEnabled) return;
+          // Shift address up if second address is empty
+          // to avoid refreshing after delay when updating NTP
+          if (!this.form.ntp.secondAddress && this.form.ntp.thirdAddres) {
+            this.form.ntp.secondAddress = this.form.ntp.thirdAddres;
+            this.form.ntp.thirdAddress = '';
+          }
+        })
+        .then(() => {
+          this.$store.dispatch('global/getBmcTime');
+        })
+        .catch(({ message }) => this.errorToast(message))
+        .finally(() => {
+          this.$v.form.$reset();
+          this.endLoader();
+        });
+    },
+    getUtcDate(date, time) {
+      // Split user input string values to create
+      // a UTC Date object
+      const datesArray = date.split('-');
+      const timeArray = time.split(':');
+      let utcDate = Date.UTC(
+        datesArray[0], // User input year
+        //UTC expects zero-index month value 0-11 (January-December)
+        //for reference https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC#Parameters
+        parseInt(datesArray[1]) - 1, // User input month
+        datesArray[2], // User input day
+        timeArray[0], // User input hour
+        timeArray[1] // User input minute
+      );
+      return new Date(utcDate);
+    },
+  },
+};
+</script>