Update the default firmware page

- Minor updates made to the general layout and styles
  - Changes to some page copy
  - Moves update firmware form to bottom of page
- Adds dynamic TFTP upload option
- Adds dynamic card layout for BMC and host firmwre
  - 2 cards for combined
  - 4 cards for separate
- Removes FirmwareSingleImage components that were used for IBM builds

Signed-off-by: Yoshie Muranaka <yoshiemuranaka@gmail.com>
Change-Id: Ib5465ecc30dd1505824bf41c82d33b7655d5e598
diff --git a/src/views/Configuration/Firmware/FirmwareFormUpdate.vue b/src/views/Configuration/Firmware/FirmwareFormUpdate.vue
new file mode 100644
index 0000000..9f67e8d
--- /dev/null
+++ b/src/views/Configuration/Firmware/FirmwareFormUpdate.vue
@@ -0,0 +1,204 @@
+<template>
+  <div>
+    <div class="form-background p-3">
+      <b-form @submit.prevent="onSubmitUpload">
+        <b-form-group
+          v-if="isTftpUploadAvailable"
+          :label="$t('pageFirmware.form.updateFirmware.fileSource')"
+          :disabled="isPageDisabled"
+        >
+          <b-form-radio v-model="isWorkstationSelected" :value="true">
+            {{ $t('pageFirmware.form.updateFirmware.workstation') }}
+          </b-form-radio>
+          <b-form-radio v-model="isWorkstationSelected" :value="false">
+            {{ $t('pageFirmware.form.updateFirmware.tftpServer') }}
+          </b-form-radio>
+        </b-form-group>
+
+        <!-- Workstation Upload -->
+        <template v-if="isWorkstationSelected">
+          <b-form-group
+            :label="$t('pageFirmware.form.updateFirmware.imageFile')"
+            label-for="image-file"
+          >
+            <b-form-text id="image-file-help-block">
+              {{ $t('pageFirmware.form.updateFirmware.imageFileHelperText') }}
+            </b-form-text>
+            <form-file
+              id="image-file"
+              accept=".tar"
+              :disabled="isPageDisabled"
+              :state="getValidationState($v.file)"
+              aria-describedby="image-file-help-block"
+              @input="onFileUpload($event)"
+            >
+              <template #invalid>
+                <b-form-invalid-feedback role="alert">
+                  {{ $t('global.form.required') }}
+                </b-form-invalid-feedback>
+              </template>
+            </form-file>
+          </b-form-group>
+        </template>
+
+        <!-- TFTP Server Upload -->
+        <template v-else>
+          <b-form-group
+            :label="$t('pageFirmware.form.updateFirmware.fileAddress')"
+            label-for="tftp-address"
+          >
+            <b-form-input
+              id="tftp-address"
+              v-model="tftpFileAddress"
+              type="text"
+              :state="getValidationState($v.tftpFileAddress)"
+              :disabled="isPageDisabled"
+              @input="$v.tftpFileAddress.$touch()"
+            />
+            <b-form-invalid-feedback role="alert">
+              {{ $t('global.form.fieldRequired') }}
+            </b-form-invalid-feedback>
+          </b-form-group>
+        </template>
+        <b-btn
+          data-test-id="firmware-button-startUpdate"
+          type="submit"
+          variant="primary"
+          :disabled="isPageDisabled"
+        >
+          {{ $t('pageFirmware.form.updateFirmware.startUpdate') }}
+        </b-btn>
+        <alert
+          v-if="isServerPowerOffRequired && !isHostOff"
+          variant="warning"
+          :small="true"
+          class="mt-4"
+        >
+          <p class="col-form-label">
+            {{
+              $t('pageFirmware.alert.serverMustBePoweredOffToUpdateFirmware')
+            }}
+          </p>
+        </alert>
+      </b-form>
+    </div>
+
+    <!-- Modals -->
+    <modal-update-firmware @ok="updateFirmware" />
+  </div>
+</template>
+
+<script>
+import { requiredIf } from 'vuelidate/lib/validators';
+
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import LoadingBarMixin, { loading } from '@/components/Mixins/LoadingBarMixin';
+import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
+
+import Alert from '@/components/Global/Alert';
+import FormFile from '@/components/Global/FormFile';
+import ModalUpdateFirmware from './FirmwareModalUpdateFirmware';
+
+export default {
+  components: { Alert, FormFile, ModalUpdateFirmware },
+  mixins: [BVToastMixin, LoadingBarMixin, VuelidateMixin],
+  props: {
+    isPageDisabled: {
+      required: true,
+      type: Boolean,
+      default: false,
+    },
+    isHostOff: {
+      required: true,
+      type: Boolean,
+    },
+  },
+  data() {
+    return {
+      loading,
+      isWorkstationSelected: true,
+      file: null,
+      tftpFileAddress: null,
+      isServerPowerOffRequired:
+        process.env.VUE_APP_SERVER_OFF_REQUIRED === 'true',
+    };
+  },
+  computed: {
+    isTftpUploadAvailable() {
+      return this.$store.getters['firmware/isTftpUploadAvailable'];
+    },
+  },
+  watch: {
+    isWorkstationSelected: function () {
+      this.$v.$reset();
+      this.file = null;
+      this.tftpFileAddress = null;
+    },
+  },
+  validations() {
+    return {
+      file: {
+        required: requiredIf(function () {
+          return this.isWorkstationSelected;
+        }),
+      },
+      tftpFileAddress: {
+        required: requiredIf(function () {
+          return !this.isWorkstationSelected;
+        }),
+      },
+    };
+  },
+  created() {
+    this.$store.dispatch('firmware/getUpdateServiceSettings');
+  },
+  methods: {
+    updateFirmware() {
+      this.startLoader();
+      const timerId = setTimeout(() => {
+        this.endLoader();
+        this.infoToast(this.$t('pageFirmware.toast.verifyUpdateMessage'), {
+          title: this.$t('pageFirmware.toast.verifyUpdate'),
+          refreshAction: true,
+        });
+      }, 360000);
+      this.infoToast(this.$t('pageFirmware.toast.updateStartedMessage'), {
+        title: this.$t('pageFirmware.toast.updateStarted'),
+        timestamp: true,
+      });
+      if (this.isWorkstationSelected) {
+        this.dispatchWorkstationUpload(timerId);
+      } else {
+        this.dispatchTftpUpload(timerId);
+      }
+    },
+    dispatchWorkstationUpload(timerId) {
+      this.$store
+        .dispatch('firmware/uploadFirmware', this.file)
+        .catch(({ message }) => {
+          this.endLoader();
+          this.errorToast(message);
+          clearTimeout(timerId);
+        });
+    },
+    dispatchTftpUpload(timerId) {
+      this.$store
+        .dispatch('firmware/uploadFirmwareTFTP', this.tftpFileAddress)
+        .catch(({ message }) => {
+          this.endLoader();
+          this.errorToast(message);
+          clearTimeout(timerId);
+        });
+    },
+    onSubmitUpload() {
+      this.$v.$touch();
+      if (this.$v.$invalid) return;
+      this.$bvModal.show('modal-update-firmware');
+    },
+    onFileUpload(file) {
+      this.file = file;
+      this.$v.file.$touch();
+    },
+  },
+};
+</script>