Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .env.ibm
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,4 @@ VITE_CUSTOM_APP_NAV=true
VITE_CUSTOM_ROUTER=true
VITE_CUSTOM_STORE=true
VITE_APP_SERVER_OFF_REQUIRED=true
VITE_APP_TFTP_SERVER=false
VITE_APP_ACF_UPLOAD_REQUIRED=true
5 changes: 4 additions & 1 deletion .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ module.exports = {
trailingComma: 'all',
},
],
'vue/component-name-in-template-casing': ['error', 'kebab-case'],
'vue/component-name-in-template-casing': [
'error',
'PascalCase' | 'kebab-case',
],
},
ignorePatterns: ['*.timestamp-*.mjs'],
overrides: [
Expand Down
15 changes: 15 additions & 0 deletions src/assets/styles/bmc/custom/_card.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,18 @@
background-color: theme-color-light($success) !important;
}
}

.card-header,
.card-footer {
padding: 12px 20px;
}

.card-body {
padding: 20px;
}

@media (max-width: 576px) {
.card-deck > .card {
margin-bottom: 15px !important;
}
}
10 changes: 10 additions & 0 deletions src/assets/styles/bmc/custom/_forms.scss
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@ div[role='group'] {
}
}

.form-control.form-control-file {
opacity: 0;
height: 0;
&:focus + span {
box-shadow:
inset 0 0 0 3px $primary,
inset 0 0 0 5px $white;
}
}

.form-select,
.form-check-label,
.form-control {
Expand Down
83 changes: 39 additions & 44 deletions src/components/Global/FormFile.vue
Original file line number Diff line number Diff line change
@@ -1,39 +1,50 @@
<!-- TODO: Work Requird -->
<template>
<div class="custom-form-file-container">
<label>
<b-form-file
<BFormFile
:id="id"
v-model="file"
:accept="accept"
:disabled="disabled"
:state="state"
@change="$emit('input', file)"
plain
@update:model-value="$emit('input', file)"
class="form-control-file"
>
</b-form-file>
</BFormFile>
<span
class="add-file-btn btn"
:class="{
disabled,
'btn-secondary': isSecondary,
'btn-primary': !isSecondary,
}"
>
{{ $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 : '' }}
<BButton
variant="light"
class="px-2 ms-auto"
class="px-2 ml-auto"
:disabled="disabled"
@click="file = null"
><icon-close :title="t('global.fileUpload.clearSelectedFile')" />
<span class="sr-only">{{
$t('global.fileUpload.clearSelectedFile')
}}</span>
@click="clearFile"
><icon-close :title="$t('global.fileUpload.clearSelectedFile')" /><span
class="visually-hidden"
>{{ $t('global.fileUpload.clearSelectedFile') }}</span
>
</BButton>
</div>
</div>
</template>

<script setup>
import { useI18n } from 'vue-i18n';
import { BFormFile } from 'bootstrap-vue-next';
import { ref, computed, defineEmits } from 'vue';
import IconClose from '@carbon/icons-vue/es/close/20';
import { ref } from 'vue';

const emit = defineEmits(['input']);

const props = defineProps({
id: {
Expand All @@ -57,51 +68,35 @@ const props = defineProps({
default: 'secondary',
},
});
console.log(
'id: ',
props.id,
'disabled: ',
props.disabled,
'accept: ',
props.accept,
'state: ',
props.state,
'variant',
props.variant,
);
const { t } = useI18n();

const file = ref(null);
// const isSecondary = computed(() => {
// return props.variant === 'secondary';
// });
</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;
}
const isSecondary = computed(() => {
return props.variant === 'secondary';
});

function clearFile() {
file.value = null;
emit('input', file.value);
}
</script>

<style lang="scss" scoped>
// Get mouse pointer on complete element
.add-file-btn {
position: relative;
&.disabled {
border-color: gray('400');
background-color: gray('400');
color: gray('600');
border-color: $gray-400;
background-color: $gray-400;
color: $gray-600;
box-shadow: none !important;
}
}

.clear-selected-file {
display: flex;
align-items: center;
background-color: #f4f4f4; //theme-color('light'); Need to check the theme colors
background-color: $light;
position: relative;
z-index: 2;
.btn {
Expand All @@ -111,7 +106,7 @@ const file = ref(null);
align-items: center;

&:focus {
box-shadow: inset 0 0 0 2px theme-color('primary');
box-shadow: inset 0 0 0 2px $primary;
}
}
}
Expand Down
9 changes: 4 additions & 5 deletions src/components/Global/Toast.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,22 @@
</template>
<template #default>
<p class="mb-0">{{ body }}</p>
<p v-if="timestamp" class="mt-3 mb-0">{{ formattedTimestamp }}</p>
<p v-if="refreshAction">
<BLink class="d-inline-block mt-3" @click="handleRefresh">
{{ i18n.global.t('global.action.refresh') }}
</BLink>
</p>
<p v-if="timestamp" class="mt-3 mb-0">{{ formattedTimestamp }}</p>
</template>
</BToast>
</template>

<script setup>
import { ref, defineProps, computed, defineEmits } from 'vue';
import { ref, defineProps, computed } from 'vue';
import i18n from '@/i18n';
import StatusIcon from './StatusIcon.vue';
import { formatTime } from '../utilities/dateFilter';
const emit = defineEmits(['refresh']);
import eventBus from '@/eventBus';

const { title, body, statusPassed, timestamp, refreshAction } = defineProps({
// eslint-disable-next-line vue/require-default-prop
Expand All @@ -41,15 +41,14 @@ const { title, body, statusPassed, timestamp, refreshAction } = defineProps({
const showToast = ref(false);

const formattedTimestamp = computed(() => {
console.log('in toast component');
if (timestamp) {
return formatTime(new Date());
} else {
return ''; // Provide a default value when timestamp is false
}
});
const handleRefresh = () => {
emit('refresh-application');
eventBus.emit('refresh-application');
};
</script>

Expand Down
2 changes: 2 additions & 0 deletions src/layouts/AppLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ import AppHeader from '@/components/AppHeader/AppHeader.vue';
// import useJumpLinkComposable from '@/components/Composables/useJumpLinkComposable';
import { ref, watch, onMounted } from 'vue';
import { useRoute } from 'vue-router';
import eventBus from '@/eventBus';

// const { setFocus } = useJumpLinkComposable();
const routerKey = ref(0);
const route = useRoute();
const currentRoute = ref(null);
onMounted(() => {
currentRoute.value = route;
eventBus.on('refresh-application', () => refreshPage());
});

watch(
Expand Down
2 changes: 0 additions & 2 deletions src/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -766,8 +766,6 @@
"imageFile": "Image file",
"manageAccessKeys": "Manage access keys",
"startUpdate": "Start update",
"tftpServer": "TFTP server",
"tftpServerInfo": "<server_ip>/<file_name>.tar",
"workstation": "Workstation"
}
},
Expand Down
9 changes: 9 additions & 0 deletions src/router/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import ConcurrentMaintenance from '../views/HardwareStatus/ConcurrentMaintenance
import IBMiServiceFunctions from '@/views/Logs/IBMiServiceFunctions';
import Notices from '@/views/Notices/Notices.vue';
import Sessions from '@/views/SecurityAndAccess/Sessions';
import Firmware from '@/views/Operations/Firmware';

const roles = {
administrator: 'Administrator',
Expand Down Expand Up @@ -129,6 +130,14 @@ export const routes = [
title: i18n.global.t('appPageTitle.factoryReset'),
},
},
{
path: '/operations/firmware',
name: 'firmware',
component: Firmware,
meta: {
title: i18n.global.t('appPageTitle.firmware'),
},
},
{
path: '/settings/power-restore-policy',
name: 'power-restore-policy',
Expand Down
4 changes: 4 additions & 0 deletions src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import ConcurrentMaintenanceStore from './modules/HardwareStatus/ConcurrentMaint
import IBMiServiceFunctionsStore from './modules/Logs/IBMiServiceFunctionsStore';
import AuditLogsStore from './modules/Logs/AuditLogsStore';
import SessionsStore from './modules/SecurityAndAccess/SessionsStore.js';
import LicenseStore from './modules/ResourceManagement/LicenseStore';
import BmcStore from './modules/HardwareStatus/BmcStore';

// ... (export use other stores)
export {
Expand All @@ -36,4 +38,6 @@ export {
IBMiServiceFunctionsStore,
AuditLogsStore,
SessionsStore,
LicenseStore,
BmcStore,
};
5 changes: 5 additions & 0 deletions src/store/modules/GlobalStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ export const GlobalStore = defineStore('global', {
setUtcTime(state, isUtcDisplay) {
state.isUtcDisplay = isUtcDisplay;
},
async getCurrentTask(task) {
return await api.get(task).then(({ data }) => {
return data;
});
},
},
});

Expand Down
42 changes: 22 additions & 20 deletions src/store/modules/HardwareStatus/BmcStore.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import api from '@/store/api';
import i18n from '@/i18n';
import { defineStore } from 'pinia';

const BmcStore = {
namespaced: true,
state: {
export const BmcStore = defineStore('bmc', {
state: () => ({
bmc: null,
},
}),
getters: {
bmc: (state) => state.bmc,
bmcGetter: (state) => state.bmc,
},
mutations: {
setBmcInfo: (state, data) => {
actions: {
setBmcInfo(data) {
const bmc = {};
bmc.dateTime = new Date(data.DateTime);
bmc.description = data.Description;
Expand All @@ -26,46 +26,48 @@ const BmcStore = {
bmc.sparePartNumber = data.SparePartNumber;
bmc.statusState = data.Status.State;
bmc.uri = data['@odata.id'];
state.bmc = bmc;
this.bmc = bmc;
},
},
actions: {
async getBmcInfo({ commit }) {
async getBmcInfo() {
return await api
.get('/redfish/v1/Managers/bmc')
.then(({ data }) => commit('setBmcInfo', data))
.then(({ data }) => this.setBmcInfo(data))
.catch((error) => console.log(error));
},
async updateIdentifyLedValue({ dispatch }, led) {
async updateIdentifyLedValue(led) {
const uri = led.uri;
const updatedIdentifyLedValue = {
LocationIndicatorActive: led.identifyLed,
};
return await api
.patch(uri, updatedIdentifyLedValue)
.then(() => {
dispatch('getBmcInfo');
this.getBmcInfo();
if (led.identifyLed) {
return i18n.t('pageInventory.toast.successEnableIdentifyLed');
return i18n.global.t(
'pageInventory.toast.successEnableIdentifyLed',
);
} else {
return i18n.t('pageInventory.toast.successDisableIdentifyLed');
return i18n.global.t(
'pageInventory.toast.successDisableIdentifyLed',
);
}
})
.catch((error) => {
dispatch('getBmcInfo');
this.getBmcInfo();
console.log('error', error);
if (led.identifyLed) {
throw new Error(
i18n.t('pageInventory.toast.errorEnableIdentifyLed'),
i18n.global.t('pageInventory.toast.errorEnableIdentifyLed'),
);
} else {
throw new Error(
i18n.t('pageInventory.toast.errorDisableIdentifyLed'),
i18n.global.t('pageInventory.toast.errorDisableIdentifyLed'),
);
}
});
},
},
};
});

export default BmcStore;
Loading