xref: /openbmc/webui-vue/src/views/Operations/Firmware/FirmwareFormUpdate.vue (revision 68cbbe9014cbdcf7229a878f564d38f6d6199f25)
1<template>
2  <div>
3    <div class="form-background p-3">
4      <b-form @submit.prevent="onSubmitUpload">
5        <b-form-group
6          v-if="isTftpUploadAvailable"
7          :label="$t('pageFirmware.form.updateFirmware.fileSource')"
8          :disabled="isPageDisabled"
9        >
10          <b-form-radio v-model="isWorkstationSelected" :value="true">
11            {{ $t('pageFirmware.form.updateFirmware.workstation') }}
12          </b-form-radio>
13          <b-form-radio v-model="isWorkstationSelected" :value="false">
14            {{ $t('pageFirmware.form.updateFirmware.tftpServer') }}
15          </b-form-radio>
16        </b-form-group>
17
18        <!-- Workstation Upload -->
19        <template v-if="isWorkstationSelected">
20          <b-form-group
21            :label="$t('pageFirmware.form.updateFirmware.imageFile')"
22            label-for="image-file"
23          >
24            <form-file
25              id="image-file"
26              :disabled="isPageDisabled"
27              :state="getValidationState($v.file)"
28              aria-describedby="image-file-help-block"
29              @input="onFileUpload($event)"
30            >
31              <template #invalid>
32                <b-form-invalid-feedback role="alert">
33                  {{ $t('global.form.required') }}
34                </b-form-invalid-feedback>
35              </template>
36            </form-file>
37          </b-form-group>
38        </template>
39
40        <!-- TFTP Server Upload -->
41        <template v-else>
42          <b-form-group
43            :label="$t('pageFirmware.form.updateFirmware.fileAddress')"
44            label-for="tftp-address"
45          >
46            <b-form-input
47              id="tftp-address"
48              v-model="tftpFileAddress"
49              type="text"
50              :state="getValidationState($v.tftpFileAddress)"
51              :disabled="isPageDisabled"
52              @input="$v.tftpFileAddress.$touch()"
53            />
54            <b-form-invalid-feedback role="alert">
55              {{ $t('global.form.fieldRequired') }}
56            </b-form-invalid-feedback>
57          </b-form-group>
58        </template>
59        <b-btn
60          data-test-id="firmware-button-startUpdate"
61          type="submit"
62          variant="primary"
63          :disabled="isPageDisabled"
64        >
65          {{ $t('pageFirmware.form.updateFirmware.startUpdate') }}
66        </b-btn>
67        <alert
68          v-if="isServerPowerOffRequired && !isServerOff"
69          variant="warning"
70          :small="true"
71          class="mt-4"
72        >
73          <p class="col-form-label">
74            {{
75              $t('pageFirmware.alert.serverMustBePoweredOffToUpdateFirmware')
76            }}
77          </p>
78        </alert>
79      </b-form>
80    </div>
81
82    <!-- Modals -->
83    <modal-update-firmware @ok="updateFirmware" />
84  </div>
85</template>
86
87<script>
88import { requiredIf } from 'vuelidate/lib/validators';
89
90import BVToastMixin from '@/components/Mixins/BVToastMixin';
91import LoadingBarMixin, { loading } from '@/components/Mixins/LoadingBarMixin';
92import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
93
94import Alert from '@/components/Global/Alert';
95import FormFile from '@/components/Global/FormFile';
96import ModalUpdateFirmware from './FirmwareModalUpdateFirmware';
97
98export default {
99  components: { Alert, FormFile, ModalUpdateFirmware },
100  mixins: [BVToastMixin, LoadingBarMixin, VuelidateMixin],
101  props: {
102    isPageDisabled: {
103      required: true,
104      type: Boolean,
105      default: false,
106    },
107    isServerOff: {
108      required: true,
109      type: Boolean,
110    },
111  },
112  data() {
113    return {
114      loading,
115      isWorkstationSelected: true,
116      file: null,
117      tftpFileAddress: null,
118      isServerPowerOffRequired:
119        process.env.VUE_APP_SERVER_OFF_REQUIRED === 'true',
120    };
121  },
122  computed: {
123    isTftpUploadAvailable() {
124      return this.$store.getters['firmware/isTftpUploadAvailable'];
125    },
126  },
127  watch: {
128    isWorkstationSelected: function () {
129      this.$v.$reset();
130      this.file = null;
131      this.tftpFileAddress = null;
132    },
133  },
134  validations() {
135    return {
136      file: {
137        required: requiredIf(function () {
138          return this.isWorkstationSelected;
139        }),
140      },
141      tftpFileAddress: {
142        required: requiredIf(function () {
143          return !this.isWorkstationSelected;
144        }),
145      },
146    };
147  },
148  created() {
149    this.$store.dispatch('firmware/getUpdateServiceSettings');
150  },
151  methods: {
152    updateFirmware() {
153      this.startLoader();
154      const timerId = setTimeout(() => {
155        this.endLoader();
156        this.infoToast(this.$t('pageFirmware.toast.verifyUpdateMessage'), {
157          title: this.$t('pageFirmware.toast.verifyUpdate'),
158          refreshAction: true,
159        });
160      }, 360000);
161      this.infoToast(this.$t('pageFirmware.toast.updateStartedMessage'), {
162        title: this.$t('pageFirmware.toast.updateStarted'),
163        timestamp: true,
164      });
165      if (this.isWorkstationSelected) {
166        this.dispatchWorkstationUpload(timerId);
167      } else {
168        this.dispatchTftpUpload(timerId);
169      }
170    },
171    dispatchWorkstationUpload(timerId) {
172      this.$store
173        .dispatch('firmware/uploadFirmware', this.file)
174        .catch(({ message }) => {
175          this.endLoader();
176          this.errorToast(message);
177          clearTimeout(timerId);
178        });
179    },
180    dispatchTftpUpload(timerId) {
181      this.$store
182        .dispatch('firmware/uploadFirmwareTFTP', this.tftpFileAddress)
183        .catch(({ message }) => {
184          this.endLoader();
185          this.errorToast(message);
186          clearTimeout(timerId);
187        });
188    },
189    onSubmitUpload() {
190      this.$v.$touch();
191      if (this.$v.$invalid) return;
192      this.$bvModal.show('modal-update-firmware');
193    },
194    onFileUpload(file) {
195      this.file = file;
196      this.$v.file.$touch();
197    },
198  },
199};
200</script>
201