Add new style for form file component

- Now only add file button will be visible.
- And selected file name will come down to the button.
- Changed form file component from custom type to plain.

Signed-off-by: Suren Neware <sneware9@in.ibm.com>
Change-Id: Ib59135691495c4dddfdbbae0e4228b55cdfda2a8
diff --git a/src/components/Global/FormFile.vue b/src/components/Global/FormFile.vue
new file mode 100644
index 0000000..30af00d
--- /dev/null
+++ b/src/components/Global/FormFile.vue
@@ -0,0 +1,90 @@
+<template>
+  <div class="custom-form-file-container">
+    <label>
+      <b-form-file
+        :id="id"
+        v-model="file"
+        :accept="accept"
+        :disabled="disabled"
+        :state="state"
+        plain
+        @input="$emit('input', file)"
+      >
+      </b-form-file>
+      <span class="add-file-btn btn btn-primary">
+        {{ $t('global.fileUpload.browseText') }}
+      </span>
+      <slot name="invalid"></slot>
+    </label>
+    <div v-if="file" class="clear-selected-file px-3 py-2 mt-2">
+      {{ file ? file.name : '' }}
+      <b-button variant="light" class="px-2 ml-auto" @click="file = null"
+        ><icon-close :title="$t('global.fileUpload.clearSelectedFile')"
+      /></b-button>
+    </div>
+  </div>
+</template>
+
+<script>
+import { BFormFile } from 'bootstrap-vue';
+import IconClose from '@carbon/icons-vue/es/close/20';
+
+export default {
+  name: 'FormFile',
+  components: { BFormFile, IconClose },
+  props: {
+    id: {
+      type: String,
+      default: '',
+    },
+    disabled: {
+      type: Boolean,
+      default: false,
+    },
+    accept: {
+      type: String,
+      default: '',
+    },
+    state: {
+      type: Boolean,
+      default: true,
+    },
+  },
+  data() {
+    return {
+      file: null,
+    };
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.form-control-file {
+  opacity: 0;
+  height: 0;
+  &:focus + span {
+    box-shadow: inset 0 0 0 3px theme-color('primary'), inset 0 0 0 5px $white;
+  }
+}
+
+// Get mouse pointer on complete element
+.add-file-btn {
+  position: relative;
+}
+
+.clear-selected-file {
+  display: flex;
+  align-items: center;
+  background-color: theme-color('light');
+  .btn {
+    width: 36px;
+    height: 36px;
+    display: flex;
+    align-items: center;
+
+    &:focus {
+      box-shadow: inset 0 0 0 2px theme-color('primary');
+    }
+  }
+}
+</style>
diff --git a/src/locales/en-US.json b/src/locales/en-US.json
index 0c4dcd6..5c03e39 100644
--- a/src/locales/en-US.json
+++ b/src/locales/en-US.json
@@ -30,9 +30,8 @@
       "useCursorKeysToNavigateCalendarDates": "Use cursor keys to navigate calendar dates"
     },
     "fileUpload": {
-      "browseText": "Browse",
-      "dropPlaceholder": "Drop files here",
-      "placeholder": "No file selected"
+      "browseText": "Add file",
+      "clearSelectedFile": "Clear selected file"
     },
     "form": {
       "dateMustBeAfter": "Date must be after %{date}",
diff --git a/src/views/AccessControl/SslCertificates/ModalUploadCertificate.vue b/src/views/AccessControl/SslCertificates/ModalUploadCertificate.vue
index 50df9a4..8a71977 100644
--- a/src/views/AccessControl/SslCertificates/ModalUploadCertificate.vue
+++ b/src/views/AccessControl/SslCertificates/ModalUploadCertificate.vue
@@ -39,24 +39,19 @@
         </b-form-group>
       </template>
 
-      <b-form-group
-        :label="$t('pageSslCertificates.modal.certificateFile')"
-        label-for="certificate-file"
-      >
-        <b-form-file
+      <b-form-group :label="$t('pageSslCertificates.modal.certificateFile')">
+        <form-file
           id="certificate-file"
           v-model="form.file"
           accept=".pem"
-          :browse-text="$t('global.fileUpload.browseText')"
-          :drop-placeholder="$t('global.fileUpload.dropPlaceholder')"
-          :placeholder="$t('global.fileUpload.placeholder')"
           :state="getValidationState($v.form.file)"
-        />
-        <b-form-invalid-feedback role="alert">
-          <template v-if="!$v.form.file.required">
-            {{ $t('global.form.required') }}
+        >
+          <template #invalid>
+            <b-form-invalid-feedback role="alert">
+              {{ $t('global.form.required') }}
+            </b-form-invalid-feedback>
           </template>
-        </b-form-invalid-feedback>
+        </form-file>
       </b-form-group>
     </b-form>
     <template #modal-ok>
@@ -74,7 +69,10 @@
 import { required, requiredIf } from 'vuelidate/lib/validators';
 import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
 
+import FormFile from '@/components/Global/FormFile';
+
 export default {
+  components: { FormFile },
   mixins: [VuelidateMixin],
   props: {
     certificate: {
diff --git a/src/views/Configuration/Firmware/Firmware.vue b/src/views/Configuration/Firmware/Firmware.vue
index 24ef33c..d78b43f 100644
--- a/src/views/Configuration/Firmware/Firmware.vue
+++ b/src/views/Configuration/Firmware/Firmware.vue
@@ -99,27 +99,26 @@
 
             <!-- Workstation Upload -->
             <template v-if="isWorkstationSelected">
-              <b-form-group
-                :label="$t('pageFirmware.form.imageFile')"
-                label-for="image-file"
-              >
+              <b-form-group :label="$t('pageFirmware.form.imageFile')">
                 <b-form-text id="image-file-help-block">
                   {{ $t('pageFirmware.form.onlyTarFilesAccepted') }}
                 </b-form-text>
-                <b-form-file
+                <form-file
                   id="image-file"
-                  v-model="file"
                   accept=".tar"
-                  aria-describedby="image-file-help-block"
-                  :browse-text="$t('global.fileUpload.browseText')"
-                  :drop-placeholder="$t('global.fileUpload.dropPlaceholder')"
-                  :placeholder="$t('global.fileUpload.placeholder')"
+                  :disabled="isPageDisabled"
                   :state="getValidationState($v.file)"
-                  @input="$v.file.$touch()"
-                />
-                <b-form-invalid-feedback role="alert">
-                  {{ $t('global.form.required') }}
-                </b-form-invalid-feedback>
+                  aria-describedby="image-file-help-block"
+                  @input="onFileUpload($event)"
+                >
+                  <template #invalid>
+                    <b-form-invalid-feedback role="alert">
+                      <template>
+                        {{ $t('global.form.required') }}
+                      </template>
+                    </b-form-invalid-feedback>
+                  </template>
+                </form-file>
               </b-form-group>
             </template>
 
@@ -198,6 +197,7 @@
 import Alert from '@/components/Global/Alert';
 import ModalUpload from './FirmwareModalUpload';
 import ModalRebootBackupBmc from './FirmwareModalRebootBackupBmc';
+import FormFile from '@/components/Global/FormFile';
 
 import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
 import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
@@ -212,6 +212,7 @@
     ModalUpload,
     PageSection,
     PageTitle,
+    FormFile,
   },
   mixins: [BVToastMixin, LoadingBarMixin, VuelidateMixin],
   beforeRouteLeave(to, from, next) {
@@ -226,6 +227,7 @@
       tftpIpAddress: null,
       tftpFileName: null,
       timeoutId: null,
+      isPageDisabled: null,
     };
   },
   computed: {
@@ -275,6 +277,10 @@
     };
   },
   methods: {
+    onFileUpload(file) {
+      this.file = file;
+      this.$v.file.$touch();
+    },
     uploadFirmware() {
       const startTime = this.$options.filters.formatTime(new Date());
       this.setRebootTimeout(360000); //6 minute timeout
diff --git a/src/views/Control/VirtualMedia/VirtualMedia.vue b/src/views/Control/VirtualMedia/VirtualMedia.vue
index a15f2cd..8264c5a 100644
--- a/src/views/Control/VirtualMedia/VirtualMedia.vue
+++ b/src/views/Control/VirtualMedia/VirtualMedia.vue
@@ -8,17 +8,20 @@
         >
           <b-row>
             <b-col v-for="(dev, $index) in proxyDevices" :key="$index" md="6">
-              <b-form-group
-                :label="dev.id"
-                :label-for="dev.id"
-                label-class="bold"
-              >
-                <b-form-file
-                  v-show="!dev.isActive"
-                  :id="dev.id"
+              <b-form-group :label="dev.id" label-class="bold">
+                <form-file
+                  v-if="!dev.isActive"
+                  :id="concatId(dev.id)"
                   v-model="dev.file"
-                />
-                <p v-if="dev.isActive">{{ dev.file.name }}</p>
+                >
+                  <template #invalid>
+                    <b-form-invalid-feedback role="alert">
+                      <template>
+                        {{ $t('global.form.required') }}
+                      </template>
+                    </b-form-invalid-feedback>
+                  </template>
+                </form-file>
               </b-form-group>
               <b-button
                 v-if="!dev.isActive"
@@ -102,10 +105,11 @@
 import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
 import ModalConfigureConnection from './ModalConfigureConnection';
 import NbdServer from '@/utilities/NBDServer';
+import FormFile from '@/components/Global/FormFile';
 
 export default {
   name: 'VirtualMedia',
-  components: { PageTitle, PageSection, ModalConfigureConnection },
+  components: { PageTitle, PageSection, ModalConfigureConnection, FormFile },
   mixins: [BVToastMixin, LoadingBarMixin],
   data() {
     return {
@@ -211,6 +215,9 @@
       this.modalConfigureConnection = connectionData;
       this.$bvModal.show('configure-connection');
     },
+    concatId(val) {
+      return val.split(' ').join('_').toLowerCase();
+    },
   },
 };
 </script>