summaryrefslogtreecommitdiff
path: root/src/views/_sila
diff options
context:
space:
mode:
Diffstat (limited to 'src/views/_sila')
-rw-r--r--src/views/_sila/BMC/Configuration/BMCConfiguration.vue105
-rw-r--r--src/views/_sila/BMC/Configuration/BMCConfigurationControl.vue121
-rw-r--r--src/views/_sila/BMC/Configuration/BMCConfigurationTable.vue91
-rw-r--r--src/views/_sila/BMC/Configuration/SettingsImportPopup.vue291
-rw-r--r--src/views/_sila/BMC/Configuration/index.js2
-rw-r--r--src/views/_sila/BMC/Firmware/FirmwarePage.vue273
-rw-r--r--src/views/_sila/BMC/Firmware/index.js2
-rw-r--r--src/views/_sila/BMC/Settings/SettingsPage.vue439
-rw-r--r--src/views/_sila/BMC/Settings/index.js2
-rw-r--r--src/views/_sila/Fans/DynamicInformation/FansDynamicPage.vue118
-rw-r--r--src/views/_sila/Fans/DynamicInformation/FansDynamicTable.vue126
-rw-r--r--src/views/_sila/Fans/DynamicInformation/IndicatorsTable.vue167
-rw-r--r--src/views/_sila/Fans/DynamicInformation/helpers.js820
-rw-r--r--src/views/_sila/Fans/DynamicInformation/index.js2
-rw-r--r--src/views/_sila/Fans/StaticInformation/FansStaticPage.vue152
-rw-r--r--src/views/_sila/Fans/StaticInformation/index.js2
-rw-r--r--src/views/_sila/HardwareStatus/Inventory/Inventory.vue196
-rw-r--r--src/views/_sila/HardwareStatus/Inventory/InventoryServiceIndicator.vue82
-rw-r--r--src/views/_sila/HardwareStatus/Inventory/InventoryTableAssembly.vue160
-rw-r--r--src/views/_sila/HardwareStatus/Inventory/InventoryTableBmcManager.vue254
-rw-r--r--src/views/_sila/HardwareStatus/Inventory/InventoryTableChassis.vue199
-rw-r--r--src/views/_sila/HardwareStatus/Inventory/InventoryTableDimmSlot.vue263
-rw-r--r--src/views/_sila/HardwareStatus/Inventory/InventoryTableFans.vue198
-rw-r--r--src/views/_sila/HardwareStatus/Inventory/InventoryTablePowerSupplies.vue216
-rw-r--r--src/views/_sila/HardwareStatus/Inventory/InventoryTableProcessors.vue275
-rw-r--r--src/views/_sila/HardwareStatus/Inventory/InventoryTableSystem.vue236
-rw-r--r--src/views/_sila/HardwareStatus/Inventory/index.js2
-rw-r--r--src/views/_sila/HardwareStatus/Sensors/Sensors.vue7
-rw-r--r--src/views/_sila/InformationAndFAQ/InformationAndFAQ.vue9
-rw-r--r--src/views/_sila/InformationAndFAQ/index.js1
-rw-r--r--src/views/_sila/Login/Login.vue86
-rw-r--r--src/views/_sila/Login/index.js3
-rw-r--r--src/views/_sila/Logs/Dumps/DumpsForm.vue6
-rw-r--r--src/views/_sila/Logs/Dumps/DumpsModalConfirmation.vue4
-rw-r--r--src/views/_sila/Logs/EventLogs/EventLogs.vue337
-rw-r--r--src/views/_sila/Logs/PostCodeLogs/PostCodeLogs.vue256
-rw-r--r--src/views/_sila/MemoryModules/DynamicInfo/MemoryDynamicPage.vue224
-rw-r--r--src/views/_sila/MemoryModules/DynamicInfo/TemperatureTable.vue126
-rw-r--r--src/views/_sila/MemoryModules/DynamicInfo/helpers.js458
-rw-r--r--src/views/_sila/MemoryModules/DynamicInfo/index.js2
-rw-r--r--src/views/_sila/MemoryModules/Specification/MemoryStaticPage.vue228
-rw-r--r--src/views/_sila/MemoryModules/Specification/index.js2
-rw-r--r--src/views/_sila/Motherboard/DynamicInfo/MotherboardDynamicPage.vue159
-rw-r--r--src/views/_sila/Motherboard/DynamicInfo/TemperatureTable.vue112
-rw-r--r--src/views/_sila/Motherboard/DynamicInfo/helpers.js458
-rw-r--r--src/views/_sila/Motherboard/DynamicInfo/index.js2
-rw-r--r--src/views/_sila/Motherboard/Specification/MotherboardSpecificationPage.vue83
-rw-r--r--src/views/_sila/Motherboard/Specification/index.js2
-rw-r--r--src/views/_sila/Operations/ConsoleSettings/ConsoleSettings.vue154
-rw-r--r--src/views/_sila/Operations/ConsoleSettings/index.js2
-rw-r--r--src/views/_sila/Operations/FactoryReset/FactoryReset.vue13
-rw-r--r--src/views/_sila/Operations/Firmware/Firmware.vue13
-rw-r--r--src/views/_sila/Operations/Firmware/FirmwareAlertServerPower.vue2
-rw-r--r--src/views/_sila/Operations/Firmware/FirmwareCardsBmc.vue8
-rw-r--r--src/views/_sila/Operations/Firmware/FirmwareCardsHost.vue2
-rw-r--r--src/views/_sila/Operations/Firmware/FirmwareFormUpdate.vue11
-rw-r--r--src/views/_sila/Operations/KeyClear/KeyClear.vue17
-rw-r--r--src/views/_sila/Operations/Kvm/Kvm.vue4
-rw-r--r--src/views/_sila/Operations/Kvm/KvmConsole.vue26
-rw-r--r--src/views/_sila/Operations/RebootBmc/RebootBmc.vue40
-rw-r--r--src/views/_sila/Operations/SerialOverLan/SerialOverLanConsole.vue2
-rw-r--r--src/views/_sila/Operations/ServerPowerOperations/BootSettings.vue41
-rw-r--r--src/views/_sila/Operations/ServerPowerOperations/ServerPowerOperations.vue193
-rw-r--r--src/views/_sila/Operations/VirtualMedia/ModalConfigureConnection.vue25
-rw-r--r--src/views/_sila/Operations/VirtualMedia/VirtualMedia.vue68
-rw-r--r--src/views/_sila/Overview/Inventory/index.js2
-rw-r--r--src/views/_sila/Overview/Network/index.js2
-rw-r--r--src/views/_sila/Overview/Overview.vue6
-rw-r--r--src/views/_sila/Overview/OverviewDumps.vue2
-rw-r--r--src/views/_sila/Overview/OverviewEvents.vue4
-rw-r--r--src/views/_sila/Overview/OverviewFirmware.vue2
-rw-r--r--src/views/_sila/Overview/OverviewNetwork.vue2
-rw-r--r--src/views/_sila/Overview/OverviewPower.vue2
-rw-r--r--src/views/_sila/Overview/OverviewQuickLinks.vue2
-rw-r--r--src/views/_sila/Overview/OverviewServer.vue4
-rw-r--r--src/views/_sila/PowerSupplies/DynamicInfo/PowerDynamicPage.vue592
-rw-r--r--src/views/_sila/PowerSupplies/DynamicInfo/PowerTable.vue126
-rw-r--r--src/views/_sila/PowerSupplies/DynamicInfo/TemperatureTable.vue126
-rw-r--r--src/views/_sila/PowerSupplies/DynamicInfo/UsingTable.vue126
-rw-r--r--src/views/_sila/PowerSupplies/DynamicInfo/VoltageTable.vue126
-rw-r--r--src/views/_sila/PowerSupplies/DynamicInfo/helpers.js1526
-rw-r--r--src/views/_sila/PowerSupplies/DynamicInfo/index.js2
-rw-r--r--src/views/_sila/PowerSupplies/Specification/PowerStaticPage.vue137
-rw-r--r--src/views/_sila/PowerSupplies/Specification/index.js2
-rw-r--r--src/views/_sila/Processors/DynamicInfo/FrequencyTable.vue107
-rw-r--r--src/views/_sila/Processors/DynamicInfo/PowerTable.vue126
-rw-r--r--src/views/_sila/Processors/DynamicInfo/ProcessorsDynamicPage.vue361
-rw-r--r--src/views/_sila/Processors/DynamicInfo/TemperatureTable.vue126
-rw-r--r--src/views/_sila/Processors/DynamicInfo/helpers.js1398
-rw-r--r--src/views/_sila/Processors/DynamicInfo/index.js2
-rw-r--r--src/views/_sila/Processors/Specification/AcceleratorSpecificationTable.vue146
-rw-r--r--src/views/_sila/Processors/Specification/ProcessorsSpecificationPage.vue117
-rw-r--r--src/views/_sila/Processors/Specification/ProcessorsSpecificationTable.vue251
-rw-r--r--src/views/_sila/Processors/Specification/helpers.js254
-rw-r--r--src/views/_sila/Processors/Specification/index.js2
-rw-r--r--src/views/_sila/SILA/AnalyticalPanel/AnalyticalPanelPage.vue272
-rw-r--r--src/views/_sila/SILA/AnalyticalPanel/PowerTable.vue82
-rw-r--r--src/views/_sila/SILA/AnalyticalPanel/TemperatureTable.vue115
-rw-r--r--src/views/_sila/SILA/AnalyticalPanel/helpers.js196
-rw-r--r--src/views/_sila/SILA/AnalyticalPanel/index.js2
-rw-r--r--src/views/_sila/SILA/NetworkAdapters/Dynamic/NetworkDynamicPage.vue135
-rw-r--r--src/views/_sila/SILA/NetworkAdapters/Dynamic/TemperatureTable.vue112
-rw-r--r--src/views/_sila/SILA/NetworkAdapters/Dynamic/helpers.js356
-rw-r--r--src/views/_sila/SILA/NetworkAdapters/Dynamic/index.js1
-rw-r--r--src/views/_sila/SILA/NetworkAdapters/EthernetAdapters/EthernetAdaptersPage.vue399
-rw-r--r--src/views/_sila/SILA/NetworkAdapters/EthernetAdapters/helpers.js99
-rw-r--r--src/views/_sila/SILA/NetworkAdapters/EthernetAdapters/index.js1
-rw-r--r--src/views/_sila/SILA/NetworkAdapters/FcHbaAdapters/FcHbaAdaptersPage.vue211
-rw-r--r--src/views/_sila/SILA/NetworkAdapters/FcHbaAdapters/helpers.js42
-rw-r--r--src/views/_sila/SILA/NetworkAdapters/FcHbaAdapters/index.js1
-rw-r--r--src/views/_sila/SILA/PciDevices/PciDevicesPage.vue115
-rw-r--r--src/views/_sila/SILA/PciDevices/index.js1
-rw-r--r--src/views/_sila/SILA/PhysicalDrivers/DynamicInfo/DriversDynamicPage.vue204
-rw-r--r--src/views/_sila/SILA/PhysicalDrivers/DynamicInfo/TemperatureTable.vue126
-rw-r--r--src/views/_sila/SILA/PhysicalDrivers/DynamicInfo/helpers.js564
-rw-r--r--src/views/_sila/SILA/PhysicalDrivers/DynamicInfo/index.js1
-rw-r--r--src/views/_sila/SILA/PhysicalDrivers/StaticInfo/DriversStaticPage.vue133
-rw-r--r--src/views/_sila/SILA/PhysicalDrivers/StaticInfo/index.js1
-rw-r--r--src/views/_sila/SILA/RAID/Cache/RAIDCachePage.vue107
-rw-r--r--src/views/_sila/SILA/RAID/Cache/index.js1
-rw-r--r--src/views/_sila/SILA/RAID/Settings/ActionSettingsPopover.vue131
-rw-r--r--src/views/_sila/SILA/RAID/Settings/OptionsPopover.vue87
-rw-r--r--src/views/_sila/SILA/RAID/Settings/RAIDSettingsPage.vue288
-rw-r--r--src/views/_sila/SILA/RAID/Settings/TomeModal.vue179
-rw-r--r--src/views/_sila/SILA/RAID/Settings/helpers.js62
-rw-r--r--src/views/_sila/SILA/RAID/Settings/index.js1
-rw-r--r--src/views/_sila/SILA/RAID/Specification/RAIDSpecificationPage.vue221
-rw-r--r--src/views/_sila/SILA/RAID/Specification/index.js1
-rw-r--r--src/views/_sila/SILA/VirtualDrivers/VirtualDriversPage.vue122
-rw-r--r--src/views/_sila/SILA/VirtualDrivers/index.js1
-rw-r--r--src/views/_sila/SecurityAndAccess/Certificates/Certificates.vue192
-rw-r--r--src/views/_sila/SecurityAndAccess/Certificates/ModalGenerateCsr.vue167
-rw-r--r--src/views/_sila/SecurityAndAccess/Policies/Policies.vue215
-rw-r--r--src/views/_sila/SecurityAndAccess/Sessions/Sessions.vue8
-rw-r--r--src/views/_sila/SecurityAndAccess/UserManagement/UserManagement.vue11
-rw-r--r--src/views/_sila/Settings/DateTime/DateTime.vue435
-rw-r--r--src/views/_sila/Settings/DateTime/index.js2
-rw-r--r--src/views/_sila/Settings/Network/ModalDns.vue92
-rw-r--r--src/views/_sila/Settings/Network/ModalHostname.vue110
-rw-r--r--src/views/_sila/Settings/Network/ModalIpv4.vue165
-rw-r--r--src/views/_sila/Settings/Network/ModalMacAddress.vue109
-rw-r--r--src/views/_sila/Settings/Network/Network.vue166
-rw-r--r--src/views/_sila/Settings/Network/NetworkGlobalSettings.vue161
-rw-r--r--src/views/_sila/Settings/Network/NetworkInterfaceSettings.vue117
-rw-r--r--src/views/_sila/Settings/Network/TableDns.vue156
-rw-r--r--src/views/_sila/Settings/Network/TableIpv4.vue183
-rw-r--r--src/views/_sila/Settings/Network/index.js2
-rw-r--r--src/views/_sila/Settings/PowerRestorePolicy/PowerRestorePolicy.vue8
-rw-r--r--src/views/_sila/Support/Support.vue9
-rw-r--r--src/views/_sila/Support/index.js1
-rw-r--r--src/views/_sila/SystemDescription/Info/InventoryTableSystem.vue81
-rw-r--r--src/views/_sila/SystemDescription/Info/SystemDescription.vue148
-rw-r--r--src/views/_sila/SystemDescription/Info/index.js2
-rw-r--r--src/views/_sila/SystemDescription/Network/InventoryIPv4Settings.vue277
-rw-r--r--src/views/_sila/SystemDescription/Network/InventoryIPv6Settings.vue263
-rw-r--r--src/views/_sila/SystemDescription/Network/SystemNetwork.vue101
-rw-r--r--src/views/_sila/SystemDescription/Network/index.js2
-rw-r--r--src/views/_sila/SystemDescription/ServerParametrs/ServerParametrs.vue21
-rw-r--r--src/views/_sila/SystemDescription/ServerParametrs/ServereParametrsSection.vue128
-rw-r--r--src/views/_sila/SystemDescription/ServerParametrs/index.js2
160 files changed, 20573 insertions, 792 deletions
diff --git a/src/views/_sila/BMC/Configuration/BMCConfiguration.vue b/src/views/_sila/BMC/Configuration/BMCConfiguration.vue
new file mode 100644
index 00000000..111fa81a
--- /dev/null
+++ b/src/views/_sila/BMC/Configuration/BMCConfiguration.vue
@@ -0,0 +1,105 @@
+<template>
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title :description="$t('appNavigation.description.configuration')" />
+ <!-- BMC table -->
+ <div class="page-collapse-decorator">
+ <b-button
+ v-b-toggle.toggle-collapse_1
+ variant="link"
+ class="collapse-button semi-bold-16px"
+ >
+ {{ $t('BMC.BmcTitle') }}
+ <component :is="iconChevronUp" class="icon-expand" />
+ </b-button>
+ <b-collapse id="toggle-collapse_1" visible class="nav-item__nav">
+ <span class="semi-bold-12px">{{ $t('BMC.BmcTable') }}</span>
+ <b-m-c-configuration-table />
+ <span class="semi-bold-12px">{{ $t('BMC.Bios') }}</span>
+ <div>
+ <span class="regular-12px bmc-configuration__bios-version">{{
+ $t('BMC.BiosV')
+ }}</span>
+ <span class="medium-12px">V 3.2.10.0</span>
+ </div>
+ </b-collapse>
+ </div>
+ <!-- Control -->
+ <div class="page-collapse-decorator">
+ <b-button
+ v-b-toggle.toggle-collapse_2
+ variant="link"
+ class="collapse-button semi-bold-16px"
+ >
+ {{ $t('BMC.ControlTitle') }}
+ <component :is="iconChevronUp" class="icon-expand" />
+ </b-button>
+ <b-collapse id="toggle-collapse_2" visible class="nav-item__nav">
+ <b-m-c-configuration-control />
+ </b-collapse>
+ </div>
+ </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import BMCConfigurationTable from './BMCConfigurationTable';
+import BMCConfigurationControl from './BMCConfigurationControl';
+import PageSection from '@/components/Global/PageSection';
+import iconChevronUp from '@carbon/icons-vue/es/chevron--up/16';
+import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
+
+export default {
+ components: {
+ PageTitle,
+ BMCConfigurationControl,
+ BMCConfigurationTable,
+ PageSection,
+ },
+ mixins: [LoadingBarMixin],
+ data() {
+ return {
+ text: '',
+ iconChevronUp: iconChevronUp,
+ };
+ },
+ created() {
+ this.startLoader();
+ const bmcManagerTablePromise = new Promise((resolve) => {
+ this.$root.$on('hardware-status-bmc-manager-complete', () => resolve());
+ });
+ Promise.all([bmcManagerTablePromise]).finally(() => this.endLoader());
+ },
+};
+</script>
+<style lang="scss" scoped>
+//nav items style
+.nav-item,
+.nav-link {
+ padding: 0;
+}
+
+.nav-item {
+ list-style-type: none;
+}
+
+.semi-bold-12px {
+ display: inline-block;
+ padding: 16px 0 0 2rem;
+}
+
+.bmc-configuration__bios-version {
+ display: inline-block;
+ color: #0c1c29;
+ padding: 8px 2px 2rem 2rem;
+}
+
+a {
+ color: $text-primary !important;
+ &:hover {
+ color: $text-primary !important;
+ }
+}
+</style>
diff --git a/src/views/_sila/BMC/Configuration/BMCConfigurationControl.vue b/src/views/_sila/BMC/Configuration/BMCConfigurationControl.vue
new file mode 100644
index 00000000..e75b5f7d
--- /dev/null
+++ b/src/views/_sila/BMC/Configuration/BMCConfigurationControl.vue
@@ -0,0 +1,121 @@
+<template>
+ <page-section class="bmc-control-section">
+ <div class="bmc-control__table">
+ <div class="bmc-control__table__cell">
+ <div>
+ <span class="semi-bold-12px"> {{ $t('BMC.ControlBmc') }} </span>
+ </div>
+ <popover
+ id="popover-reactive-1"
+ description="BMC.ReloadBmc"
+ popup="BMC.ReloadBmc_popup"
+ button="BMC.ReloadBmc"
+ :action="rebootBmc"
+ />
+ <settings-import-popup
+ id="popover-reactive-2"
+ description="BMC.ExportImport"
+ popup="BMC.ExportImport"
+ button="BMC.ExportImport_button"
+ />
+ <div>
+ <span
+ class="regular-12px underline"
+ @click="redirectNetworkParametrs"
+ >{{ $t('BMC.Parametrs') }}</span
+ >
+ </div>
+ </div>
+
+ <div class="bmc-control__table__cell">
+ <div>
+ <span class="semi-bold-12px">{{ $t('BMC.microcode') }}</span>
+ </div>
+ <b-button variant="unstyled" class="p-0" @click="redirectUpdateBmc">
+ <img src="@/assets/images/icon-reload-red.svg" />
+ <span style="margin-left: 5px" class="regular-12px red">{{
+ $t('BMC.ReloadMicrocodeBios')
+ }}</span>
+ </b-button>
+ </div>
+ </div>
+ </page-section>
+</template>
+
+<script>
+import SettingsImportPopup from './SettingsImportPopup';
+import PageSection from '@/components/Global/PageSection';
+import Popover from '@/components/Global/Popover';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+export default {
+ components: {
+ PageSection,
+ Popover,
+ SettingsImportPopup,
+ },
+ mixins: [BVToastMixin],
+ data() {
+ return {
+ timeOption: 'resetBios',
+ picked: '',
+ options: [
+ { text: 'Toggle this custom radio', value: 'first' },
+ { text: 'Or toggle this other custom radio', value: 'second' },
+ ],
+ progress1: {
+ value: 90,
+ },
+ progress2: {
+ value: null,
+ },
+ };
+ },
+ methods: {
+ redirectNetworkParametrs() {
+ this.$router.push('/network-parametrs');
+ },
+ redirectUpdateBmc() {
+ this.$router.push('/operations/firmware');
+ },
+ rebootBmc() {
+ this.$store
+ .dispatch('controls/rebootBmc')
+ .then((message) => this.successToast(message))
+ .catch(({ message }) => this.errorToast(message));
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+a {
+ list-style-type: none;
+}
+
+.bmc-control-section {
+ position: relative;
+ margin: 16px 2rem 2rem;
+ width: 70%;
+}
+
+.bmc-control__table {
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: space-between;
+ width: 85%;
+}
+
+.bmc-control__table__cell {
+ display: flex;
+ flex-flow: column nowrap;
+ align-items: flex-start;
+ row-gap: 6px;
+}
+
+.semi-bold-12px {
+ display: inline-block;
+}
+
+label {
+ padding-top: 5px;
+}
+</style>
diff --git a/src/views/_sila/BMC/Configuration/BMCConfigurationTable.vue b/src/views/_sila/BMC/Configuration/BMCConfigurationTable.vue
new file mode 100644
index 00000000..f7b6d951
--- /dev/null
+++ b/src/views/_sila/BMC/Configuration/BMCConfigurationTable.vue
@@ -0,0 +1,91 @@
+<template>
+ <page-section class="bootstrap-table__section">
+ <b-table
+ responsive="md"
+ show-empty
+ class="table-rounded"
+ no-border-collapse
+ :items="items"
+ :fields="fields"
+ :busy="isBusy"
+ :empty-text="$t('global.table.emptyMessage')"
+ >
+ </b-table>
+ </page-section>
+</template>
+
+<script>
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import PageSection from '@/components/Global/PageSection';
+
+import TableRowExpandMixin, {
+ expandRowLabel,
+} from '@/components/Mixins/TableRowExpandMixin';
+
+export default {
+ components: { PageSection },
+ mixins: [BVToastMixin, TableRowExpandMixin],
+ data() {
+ return {
+ isBusy: true,
+ isAddersСolon: false,
+ fields: [
+ {
+ key: 'param',
+ label: 'Параметр',
+ formatter: this.dataFormatter,
+ thStyle: { width: '50%' },
+ },
+ {
+ key: 'value',
+ label: 'Значение',
+ formatter: this.dataFormatter,
+ },
+ ],
+ expandRowLabel: expandRowLabel,
+ items: null,
+ };
+ },
+ computed: {
+ bmc() {
+ return this.$store.getters['bmc/bmc'];
+ },
+ },
+ watch: {
+ bmc() {
+ this.items = [
+ {
+ param: 'Время сервера',
+ value: this.bmc.dateTime,
+ },
+ {
+ param: 'uuid',
+ value: this.bmc.uuid,
+ },
+ {
+ param: 'Версия прошивки',
+ value: this.bmc.firmwareVersion,
+ },
+ {
+ param: 'Модель',
+ value: this.bmc.model,
+ },
+ {
+ param: 'Описание',
+ value: this.bmc.description,
+ },
+ {
+ param: 'Максимальное количество сессий',
+ value: this.bmc.graphicalConsoleMaxSessions,
+ },
+ ];
+ },
+ },
+ created() {
+ this.$store.dispatch('bmc/getBmcInfo').finally(() => {
+ this.$root.$emit('hardware-status-bmc-manager-complete');
+ this.isBusy = false;
+ });
+ },
+};
+</script>
diff --git a/src/views/_sila/BMC/Configuration/SettingsImportPopup.vue b/src/views/_sila/BMC/Configuration/SettingsImportPopup.vue
new file mode 100644
index 00000000..3807a694
--- /dev/null
+++ b/src/views/_sila/BMC/Configuration/SettingsImportPopup.vue
@@ -0,0 +1,291 @@
+<template>
+ <div id="my-container">
+ <span
+ :id="id"
+ ref="button"
+ class="regular-12px underline"
+ variant="primary"
+ >
+ {{ $t(description) }}
+ </span>
+ <!-- Our popover title and content render container -->
+ <b-popover
+ id="export-popup"
+ ref="popover"
+ :target="id"
+ triggers="click"
+ :show.sync="popoverShow"
+ placement="auto"
+ container="my-container"
+ @show="onShow"
+ @shown="onShown"
+ @hidden="onHidden"
+ >
+ <template #title>
+ <div class="popup-title">
+ <span class="semi-bold-20px">{{ $t(popup) }}</span>
+ <b-button class="popup-title__button_close" @click="onClose">
+ <img src="@/assets/images/_sila/popups/x-icon.svg" />
+ </b-button>
+ </div>
+ </template>
+ <div class="popup-switch">
+ <span
+ class="medium-16px popup-item"
+ :class="{ 'switch-active': isExport }"
+ @click="switchExport"
+ >{{ $t('global.action.export') }}</span
+ >
+ <span
+ class="medium-16px popup-item"
+ :class="{ 'switch-active': !isExport }"
+ @click="switchImport"
+ >{{ $t('global.action.import') }}</span
+ >
+ <div class="slider" />
+ </div>
+ <div v-if="isExport" class="popup-body">
+ <div class="ip-container">
+ <span class="regular-16px"
+ >Оставить IP адрес из настроек сервера</span
+ >
+ <b-form-checkbox switch> </b-form-checkbox>
+ </div>
+ <b-button class="popover-button" variant="primary" @click="onClose">
+ {{ $t(button) }}
+ </b-button>
+ </div>
+ <div v-else class="settings-import_container">
+ <b-form-file
+ id="settings-import__file-input"
+ placeholder="Нажмите на область или перетащите в нее файл с настройками"
+ ></b-form-file>
+ </div>
+ </b-popover>
+ </div>
+</template>
+
+<script>
+export default {
+ props: {
+ description: {
+ type: String,
+ default: '',
+ },
+ id: {
+ type: String,
+ default: '',
+ },
+ button: {
+ type: String,
+ default: 'global.action.reload',
+ },
+ popup: {
+ type: String,
+ default: '',
+ },
+ },
+ data() {
+ return {
+ input1: '',
+ input1state: null,
+ input1Return: '',
+ popoverShow: false,
+ isExport: true,
+ };
+ },
+ watch: {
+ input1(val) {
+ if (val) {
+ this.input1state = true;
+ }
+ },
+ },
+ methods: {
+ onClose() {
+ this.popoverShow = false;
+ },
+ onOk() {
+ if (!this.input1) {
+ this.input1state = false;
+ }
+ if (this.input1) {
+ this.onClose();
+ // Return our popover form results
+ this.input1Return = this.input1;
+ }
+ },
+ onShow() {
+ this.$root.$emit('bv::hide::popover');
+ // This is called just before the popover is shown
+ // Reset our popover form variables
+ this.input1 = '';
+ this.input1state = null;
+ this.input1Return = '';
+ },
+ onShown() {
+ // Called just after the popover has been shown
+ // Transfer focus to the first input
+ this.focusRef(this.$refs.input1);
+ },
+ onHidden() {
+ // Called just after the popover has finished hiding
+ // Bring focus back to the button
+ this.focusRef(this.$refs.button);
+ },
+ focusRef(ref) {
+ // Some references may be a component, functional component, or plain element
+ // This handles that check before focusing, assuming a `focus()` method exists
+ // We do this in a double `$nextTick()` to ensure components have
+ // updated & popover positioned first
+ this.$nextTick(() => {
+ this.$nextTick(() => {
+ (ref.$el || ref).focus();
+ });
+ });
+ },
+ switchExport() {
+ this.isExport = true;
+ },
+ switchImport() {
+ this.isExport = false;
+ },
+ },
+};
+</script>
+<style lang="scss">
+.custom-file {
+ width: 432px;
+ height: 108px;
+}
+
+#settings-import__file-input ~ .custom-file-label {
+ background-color: transparent;
+ border: 1px dashed rgba(12, 28, 41, 0.6);
+ box-sizing: border-box;
+ border-radius: 8px;
+ width: 432px;
+ height: 108px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ text-align: center;
+ white-space: normal;
+ padding: 0 65px;
+}
+
+#settings-import__file-input ~ .custom-file-label::after {
+ display: none;
+}
+</style>
+<style lang="scss" scoped>
+#export-popup {
+ flex-direction: column;
+ align-items: flex-start;
+ background: #ffffff;
+ box-shadow: 0px -4px 12px rgb(0 0 0 / 5%);
+ border-radius: 16px !important;
+ border-radius: 4px;
+ max-width: 480px;
+ width: 480px;
+ height: auto;
+}
+
+.form-group {
+ margin: 0;
+}
+
+.popup-title {
+ display: flex;
+ align-items: baseline;
+ width: 465px;
+}
+
+.popup-title__button_close {
+ margin: 0 28px 0 auto;
+ background: none;
+ border: none;
+ &:active {
+ background-color: $faint-secondary-primary-5-hover !important;
+ box-shadow: none !important;
+ border-radius: 8px;
+ }
+ &:focus-visible {
+ border: none !important;
+ border-radius: 8px;
+ }
+ &:focus {
+ box-shadow: none;
+ border-radius: 8px;
+ }
+}
+
+.popup-body {
+ display: flex;
+ flex-direction: column;
+ align-content: center;
+ justify-content: center;
+}
+
+.medium-16px {
+ display: inline-block;
+ height: 45px;
+ margin: 10px;
+ cursor: pointer;
+}
+
+.popup-switch {
+ position: relative;
+ display: flex;
+ flex-flow: row nowrap;
+ border-bottom: 1px solid #f3f4f5;
+}
+
+.switch-active {
+ color: $red-brand-primary;
+ transition: ease-in 0.15s;
+}
+
+.slider {
+ position: absolute;
+ width: 130px;
+ height: 0px;
+ border-bottom: 4px solid $red-brand-primary;
+ transition: ease-in 0.2s;
+ bottom: 14px;
+ left: 10px;
+}
+
+.popup-item:nth-child(1).switch-active ~ .slider {
+ left: 10px;
+}
+
+.popup-item:nth-child(2).switch-active ~ .slider {
+ left: 160px;
+}
+
+.ip-container {
+ display: flex;
+ width: 461px;
+ height: 75px;
+ padding: 30px 15px 25px 15px;
+}
+
+.popover-button {
+ width: 432px;
+ height: 52px;
+ margin: 0 auto 10px;
+}
+
+.settings-import_container {
+ width: 478px;
+ height: 160px;
+ background-color: $surface-secondary;
+ margin: -15px -15px -8px -12px;
+ border-radius: 0 0 16px 16px;
+
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+</style>
diff --git a/src/views/_sila/BMC/Configuration/index.js b/src/views/_sila/BMC/Configuration/index.js
new file mode 100644
index 00000000..da796489
--- /dev/null
+++ b/src/views/_sila/BMC/Configuration/index.js
@@ -0,0 +1,2 @@
+import BMCConfiguration from './BMCConfiguration.vue';
+export default BMCConfiguration;
diff --git a/src/views/_sila/BMC/Firmware/FirmwarePage.vue b/src/views/_sila/BMC/Firmware/FirmwarePage.vue
new file mode 100644
index 00000000..8ffd9db1
--- /dev/null
+++ b/src/views/_sila/BMC/Firmware/FirmwarePage.vue
@@ -0,0 +1,273 @@
+<template>
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title :description="$t('appNavigation.deviceFirmware')" />
+ <!-- BMC table -->
+ <page-section class="bootstrap-table__section">
+ <b-table
+ responsive="md"
+ sort-by="id"
+ class="table-firmware"
+ no-border-collapse
+ sort-icon-left
+ no-sort-reset
+ :sort-desc="sortDesc"
+ :items="items"
+ :fields="fields"
+ >
+ <template #cell(name)="{ value }">
+ <span class="regular-12px tretiatry">
+ {{ value }}
+ </span>
+ </template>
+ <template #cell(minSpeedDate)="{ value }">
+ <span class="regular-12px">
+ {{ value.time }}
+ </span>
+ <span class="regular-12px tretiatry">
+ {{ value.date }}
+ </span>
+ </template>
+ <template #cell(maxSpeedDate)="{ value }">
+ <span class="regular-12px">
+ {{ value.time }}
+ </span>
+ <span class="regular-12px tretiatry">
+ {{ value.date }}
+ </span>
+ </template>
+ </b-table>
+ </page-section>
+ </b-container>
+</template>
+
+<script>
+import TableSortMixin from '@/components/Mixins/TableSortMixin';
+import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
+import TableFilterMixin from '@/components/Mixins/TableFilterMixin';
+import BVPaginationMixin from '@/components/Mixins/BVPaginationMixin';
+import BVTableSelectableMixin from '@/components/Mixins/BVTableSelectableMixin';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
+import TableRowExpandMixin from '@/components/Mixins/TableRowExpandMixin';
+
+import PageTitle from '@/components/Global/PageTitle';
+import PageSection from '@/components/Global/PageSection';
+import iconChevronUp from '@carbon/icons-vue/es/chevron--up/16';
+
+export default {
+ components: {
+ PageTitle,
+ PageSection,
+ },
+ mixins: [
+ BVPaginationMixin,
+ BVTableSelectableMixin,
+ BVToastMixin,
+ LoadingBarMixin,
+ TableFilterMixin,
+ DataFormatterMixin,
+ TableSortMixin,
+ TableRowExpandMixin,
+ ],
+ data() {
+ return {
+ text: '',
+ iconChevronUp: iconChevronUp,
+ sortDesc: true,
+ fields: [
+ {
+ key: 'name',
+ label: 'Устройство',
+ sortable: true,
+ formatter: this.dataFormatter,
+ thStyle: { paddingLeft: 'calc(1.2rem + 0.65em) !important' },
+ },
+ {
+ key: 'version',
+ label: 'Версия прошивки',
+ sortable: false,
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'date',
+ label: 'Дата прошивки',
+ sortable: true,
+ formatter: this.dataFormatter,
+ thStyle: { paddingLeft: '12px' },
+ },
+ ],
+ items: [
+ {
+ name: 'Встроенный контроллер Порт 1|Бокс 1|Вау 1',
+ version: 'HGP1',
+ date: '03.11.2021',
+ },
+ {
+ name: 'Встроенный девайс',
+ version: '2.5',
+ date: '03.11.2021',
+ },
+ {
+ name: 'Встроенный ALOM',
+ version: '10.52.7',
+ date: '03.11.2021',
+ },
+ {
+ name: 'Встроенный RAID',
+ version: '3.00',
+ date: '03.11.2021',
+ },
+ {
+ name: 'Системная плата',
+ version: '2.30 Aug 24 2020',
+ date: '03.11.2021',
+ },
+
+ {
+ name: 'Системная плата',
+ version: '11.0.0 Build 23',
+ date: '03.11.2021',
+ },
+ {
+ name: 'Системная плата',
+ version: '3.46.4',
+ date: '03.11.2021',
+ },
+ {
+ name: 'Системная плата',
+ version: '1.0.7',
+ date: '03.11.2021',
+ },
+ {
+ name: 'Встроенный контроллер Порт 1|Бокс 1|Вау 1',
+ version: 'HPG0.9',
+ date: '02.11.2021',
+ },
+ {
+ name: 'Встроенный девайс',
+ version: '2.5',
+ date: '02.11.2021',
+ },
+ {
+ name: 'Встроенный ALOM',
+ version: '10.52.7',
+ date: '02.11.2021',
+ },
+ {
+ name: 'Встроенный RAID',
+ version: '3.00',
+ date: '02.11.2021',
+ },
+ {
+ name: 'Системная плата',
+ version: '2.30 Aug 24 2020',
+ date: '02.11.2021',
+ },
+ {
+ name: 'Системная плата',
+ version: '11.0.0 Build 23',
+ date: '02.11.2021',
+ },
+ {
+ name: 'Системная плата',
+ version: '3.46.4',
+ date: '02.11.2021',
+ },
+ {
+ name: 'Системная плата',
+ version: '1.0.7',
+ date: '02.11.2021',
+ },
+ {
+ name: 'Встроенный контроллер Порт 1|Бокс 1|Вау 1',
+ version: 'HPG0.8',
+ date: '01.11.2021',
+ },
+ {
+ name: 'Встроенный девайс',
+ version: '2.5',
+ date: '01.11.2021',
+ },
+ {
+ name: 'Встроенный ALOM',
+ version: '10.52.7',
+ date: '01.11.2021',
+ },
+ {
+ name: 'Встроенный RAID',
+ version: '3.00',
+ date: '01.11.2021',
+ },
+ {
+ name: 'Системная плата',
+ version: '2.30 Aug 24 2020',
+ date: '01.11.2021',
+ },
+
+ {
+ name: 'Системная плата',
+ version: '11.0.0 Build 23',
+ date: '01.11.2021',
+ },
+ {
+ name: 'Системная плата',
+ version: '3.46.4',
+ date: '01.11.2021',
+ },
+ {
+ name: 'Системная плата',
+ version: '1.0.7',
+ date: '01.11.2021',
+ },
+ ],
+ };
+ },
+};
+</script>
+<style lang="scss" scoped>
+//nav items style
+.nav-item,
+.nav-link {
+ padding: 0;
+}
+
+.nav-item {
+ list-style-type: none;
+}
+
+.semi-bold-12px {
+ display: inline-block;
+ padding: 16px 0 0 2rem;
+}
+
+.bmc-configuration__bios-version {
+ display: inline-block;
+ color: #0c1c29;
+ padding: 8px 2px 2rem 2rem;
+}
+
+a {
+ color: $text-primary !important;
+ &:hover {
+ color: $text-primary !important;
+ }
+}
+
+.fans-colors {
+ display: inline-block;
+ width: 8px;
+ height: 8px;
+ border-radius: 2px;
+}
+.row {
+ align-items: center;
+ flex-wrap: nowrap;
+ justify-content: flex-end;
+}
+.medium-12px {
+ color: $text-primary !important;
+}
+</style>
diff --git a/src/views/_sila/BMC/Firmware/index.js b/src/views/_sila/BMC/Firmware/index.js
new file mode 100644
index 00000000..55a8c296
--- /dev/null
+++ b/src/views/_sila/BMC/Firmware/index.js
@@ -0,0 +1,2 @@
+import FirmwarePage from './FirmwarePage.vue';
+export default FirmwarePage;
diff --git a/src/views/_sila/BMC/Settings/SettingsPage.vue b/src/views/_sila/BMC/Settings/SettingsPage.vue
new file mode 100644
index 00000000..97b0ce9d
--- /dev/null
+++ b/src/views/_sila/BMC/Settings/SettingsPage.vue
@@ -0,0 +1,439 @@
+<template>
+ <b-container
+ id="page-bmc-settings"
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title :description="$t('appNavigation.broadcastSettings')" />
+ <!-- BMC table -->
+ <div class="bmc-settings-section">
+ <div class="smnp-settings-container">
+ <span class="bold-12px__caps section-label">{{ $t('BMC.smnp') }}</span>
+ <b-form-group class="form-group">
+ <label class="regular-12px tretiatry">{{ $t('BMC.system') }}</label>
+ <b-form-input
+ v-model="system"
+ type="text"
+ class="form-control medium-16px"
+ >
+ </b-form-input>
+ <img class="clear-icon" src="@/assets/images/_sila/popups/x-icon.svg" />
+ </b-form-group>
+ <b-form-group class="form-group">
+ <label class="regular-12px tretiatry">{{ $t('BMC.contacts') }}</label>
+ <b-form-input
+ type="text"
+ class="form-control medium-16px"
+ placeholder="Введите значение"
+ >
+ </b-form-input>
+ </b-form-group>
+ <b-form-group class="form-group">
+ <label class="regular-12px tretiatry">{{
+ $t('BMC.community')
+ }}</label>
+ <b-form-input
+ v-model="community"
+ type="text"
+ class="form-control medium-16px"
+ >
+ </b-form-input>
+ <img class="clear-icon" src="@/assets/images/_sila/popups/x-icon.svg" />
+ </b-form-group>
+ <b-form-group class="form-group">
+ <label class="regular-12px tretiatry">{{
+ $t('global.status.status')
+ }}</label>
+ <b-form-select
+ v-model="smnpStatus"
+ :options="smnpStatuses"
+ class="select-connection medium-16px"
+ />
+ </b-form-group>
+ <b-form-group class="form-group">
+ <label class="regular-12px tretiatry">{{ $t('BMC.smnpIp') }}</label>
+ <b-form-input
+ v-model="smnpIp"
+ type="text"
+ class="form-control medium-16px"
+ >
+ </b-form-input>
+ <img class="clear-icon" src="@/assets/images/_sila/popups/x-icon.svg" />
+ </b-form-group>
+ <b-form-group class="form-group">
+ <label class="regular-12px tretiatry">{{ $t('BMC.smnpPort') }}</label>
+ <b-form-input
+ v-model="smnpPort"
+ type="text"
+ class="form-control medium-16px"
+ >
+ </b-form-input>
+ <img class="clear-icon" src="@/assets/images/_sila/popups/x-icon.svg" />
+ </b-form-group>
+ <div class="accept-container">
+ <b-button variant="primary" class="accept-button">
+ {{ $t('global.action.acceptChanges') }}
+ </b-button>
+ </div>
+ </div>
+ </div>
+ <div class="bmc-settings-section">
+ <div class="smnp-settings-container">
+ <span class="bold-12px__caps section-label">{{
+ $t('BMC.smnpWarning')
+ }}</span>
+ <div class="table-section">
+ <b-table
+ responsive="md"
+ show-empty
+ no-border-collapse
+ :items="items"
+ :fields="fields"
+ >
+ <template #cell(value)="{ index }">
+ <b-row>
+ <b-col>
+ <span v-if="items[index].value">
+ {{ $t('global.status.enabled') }}
+ </span>
+ <span v-else>
+ {{ $t('global.status.disabled') }}
+ </span>
+ </b-col>
+ <b-col>
+ <b-form-checkbox v-model="items[index].value" switch>
+ </b-form-checkbox>
+ </b-col>
+ </b-row>
+ </template>
+ </b-table>
+ </div>
+ <div class="accept-container">
+ <b-button variant="secondary" class="test-message-button">
+ {{ $t('BMC.testMessage') }}
+ </b-button>
+ <b-button variant="primary" class="accept-button">
+ {{ $t('global.action.acceptChanges') }}
+ </b-button>
+ </div>
+ </div>
+ </div>
+
+ <div class="bmc-settings-section">
+ <div class="smnp-settings-container">
+ <span class="bold-12px__caps section-label">{{
+ $t('BMC.smtpWarning')
+ }}</span>
+ <div class="table-section">
+ <b-table
+ responsive="md"
+ show-empty
+ no-border-collapse
+ :items="items2"
+ :fields="fields2"
+ >
+ <template #cell(value)="data">
+ <b-row v-if="data.index === 0">
+ <b-col>
+ <span v-if="items2[data.index].value">
+ {{ $t('global.status.enabled') }}
+ </span>
+ <span v-else>
+ {{ $t('global.status.disabled') }}
+ </span>
+ </b-col>
+ <b-col>
+ <b-form-checkbox v-model="items2[data.index].value" switch>
+ </b-form-checkbox>
+ </b-col>
+ </b-row>
+ <b-row v-else-if="data.index === 4">
+ <b-col>
+ <span>
+ {{ data.value ? 'Да' : 'Нет' }}
+ </span>
+ </b-col>
+ <b-col>
+ <b-button
+ :id="`popover-choice-${data.index}`"
+ class="popover-option-ractive"
+ variant="toogle-popover"
+ >
+ <img :is="iconChevron" class="icon-chevron" />
+ </b-button>
+ <two-chioce-popover
+ :id="data.index"
+ fitst-option="Да"
+ second-option="Нет"
+ :chosen-option="chosenOption"
+ :first-action="setYes"
+ :second-action="setNo"
+ placement="leftbottom"
+ />
+ </b-col>
+ </b-row>
+ <b-row v-else>
+ <b-col>
+ <span>
+ {{ data.value }}
+ </span>
+ </b-col>
+ <b-col>
+ <img
+ src="@/assets/images/icon-edit.svg"
+ class="icon-chevron icon-edit"
+ />
+ </b-col>
+ </b-row>
+ </template>
+ </b-table>
+ </div>
+ </div>
+ </div>
+
+ <div class="bmc-settings-section last">
+ <div class="smnp-settings-container">
+ <span class="bold-12px__caps section-label">{{
+ $t('BMC.syslogSettings')
+ }}</span>
+ <b-form-group class="form-group">
+ <label class="regular-12px tretiatry">{{
+ $t('global.status.status')
+ }}</label>
+ <b-form-select
+ v-model="syslogStatus"
+ :options="syslogStatuses"
+ class="select-connection medium-16px"
+ />
+ </b-form-group>
+ <b-form-group class="form-group">
+ <label class="regular-12px tretiatry">{{ $t('BMC.syslogIP') }}</label>
+ <b-form-input
+ v-model="syslogIp"
+ type="text"
+ class="form-control medium-16px"
+ >
+ </b-form-input>
+ <img class="clear-icon" src="@/assets/images/_sila/popups/x-icon.svg" />
+ </b-form-group>
+ <b-form-group class="form-group">
+ <label class="regular-12px tretiatry">{{
+ $t('BMC.syslogPort')
+ }}</label>
+ <b-form-input
+ v-model="syslogPort"
+ type="text"
+ class="form-control medium-16px"
+ >
+ </b-form-input>
+ <img class="clear-icon" src="@/assets/images/_sila/popups/x-icon.svg" />
+ </b-form-group>
+ <div class="accept-container">
+ <b-button variant="primary" class="accept-button">
+ {{ $t('global.action.acceptChanges') }}
+ </b-button>
+ </div>
+ </div>
+ </div>
+ </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import TwoChiocePopover from '@/components/Global/SilaComponents/TwoChiocePopover';
+import iconChevron from '@carbon/icons-vue/es/chevron--down/16';
+
+export default {
+ components: {
+ PageTitle,
+ TwoChiocePopover,
+ },
+ data() {
+ return {
+ iconChevron,
+ text: '',
+ system: '2КА04.02_г17',
+ community: 'public',
+ smnpIp: '0.0.0.0',
+ smnpPort: '161',
+ syslogIp: '0.0.0.0',
+ syslogPort: '161',
+ chosenOption: 'Да',
+ smnpStatus: true,
+ smnpStatuses: [
+ {
+ value: true,
+ text: 'Включена',
+ },
+ {
+ value: false,
+ text: 'Выключена',
+ },
+ ],
+ syslogStatus: true,
+ syslogStatuses: [
+ {
+ value: true,
+ text: 'Включена',
+ },
+ {
+ value: false,
+ text: 'Выключена',
+ },
+ ],
+ fields: [
+ {
+ key: 'name',
+ label: 'Тип предупреждения',
+ formatter: this.dataFormatter,
+ thStyle: { width: '70%' },
+ },
+ {
+ key: 'value',
+ label: 'Значение',
+ formatter: this.dataFormatter,
+ },
+ ],
+ fields2: [
+ {
+ key: 'attributes',
+ label: 'Атрибуты',
+ formatter: this.dataFormatter,
+ thStyle: { width: '70%' },
+ },
+ {
+ key: 'value',
+ label: 'Значение',
+ formatter: this.dataFormatter,
+ },
+ ],
+ items: [
+ {
+ name: 'SNMPv1',
+ value: true,
+ },
+ {
+ name: 'SNMPv3',
+ value: true,
+ },
+ {
+ name: 'Постоянные запросы и предупреждения SNMPv1',
+ value: true,
+ },
+ ],
+ items2: [
+ {
+ attributes: 'Авторизация',
+ value: true,
+ },
+ {
+ attributes: 'Логин пользователя',
+ value: 'admin',
+ },
+ {
+ attributes: 'Пароль',
+ value: '******',
+ },
+ {
+ attributes: 'SMTP-сервер',
+ value: 'smtp.domian.ru',
+ },
+ {
+ attributes: 'Поддержка SSI',
+ value: true,
+ },
+ {
+ attributes: 'SMTP-порт',
+ value: 465,
+ },
+ ],
+ };
+ },
+ methods: {
+ setYes() {
+ this.chosenOption = 'Да';
+ this.items2[4].value = true;
+ },
+ setNo() {
+ this.chosenOption = 'Нет';
+ this.items2[4].value = false;
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+.main-container {
+ margin-top: 16px;
+}
+
+.bmc-settings-section {
+ border-bottom: 1px solid $faint-secondary-primary-10;
+ &.last {
+ margin-bottom: 40px;
+ }
+}
+.smnp-settings-container {
+ display: flex;
+ flex-flow: row wrap;
+ gap: 16px;
+ justify-content: flex-start;
+ align-items: flex-start;
+ margin: 16px 0 16px 28px;
+}
+
+.section-label {
+ display: block;
+ width: 100%;
+}
+.form-group {
+ width: 341px;
+ height: 35px;
+}
+.form-control {
+ margin: -31px 0px 0 -15px;
+ height: 52px;
+ width: 341px;
+ padding: 17px 0 0 15px;
+}
+.clear-icon {
+ margin: -80px 0px 0px 300px;
+}
+
+.select-connection {
+ height: 52px;
+ width: 341px;
+ padding-top: 30px;
+ border: none;
+ border-radius: 8px;
+ margin: -31px 0 18px -15px;
+ background-color: $faint-secondary-primary-5;
+ background-image: url('../../../../assets/images/_sila/icon-chevron.svg');
+}
+.accept-container {
+ width: 100%;
+ display: flex;
+ justify-content: flex-end;
+}
+
+.accept-button {
+ width: 245px;
+ height: 36px;
+ margin-right: 33px;
+}
+.test-message-button {
+ width: 245px;
+ height: 36px;
+ margin-right: 16px;
+ background-color: $faint-secondary-primary-5;
+}
+
+.table-section {
+ width: 100%;
+ margin: 0 20px 0 0;
+}
+
+.popover-option-ractive {
+ display: block;
+ margin: -6px 6px 0 auto;
+}
+</style>
diff --git a/src/views/_sila/BMC/Settings/index.js b/src/views/_sila/BMC/Settings/index.js
new file mode 100644
index 00000000..f74e1f4d
--- /dev/null
+++ b/src/views/_sila/BMC/Settings/index.js
@@ -0,0 +1,2 @@
+import SettingsPage from './SettingsPage.vue';
+export default SettingsPage;
diff --git a/src/views/_sila/Fans/DynamicInformation/FansDynamicPage.vue b/src/views/_sila/Fans/DynamicInformation/FansDynamicPage.vue
new file mode 100644
index 00000000..fe997c58
--- /dev/null
+++ b/src/views/_sila/Fans/DynamicInformation/FansDynamicPage.vue
@@ -0,0 +1,118 @@
+<template>
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title :description="$t('SystemDescription.FansDynamicInformation')" />
+ <date-switch :switch-time-scale="switchTimeScale" :time-scale="timeScale" />
+ <div class="speed-description">
+ <img src="@/assets/images/fans-page/fans-icon.svg" />
+ <span class="bold-16px">{{ $t('fansPage.speedDescription') }}</span>
+ </div>
+ <div class="limit-speed-container">
+ <div class="speed-limt">
+ <img src="@/assets/images/labels/warning.svg" />
+ <span class="semi-bold-12px">{{ $t('fansPage.speedWarhihg') }}</span>
+ <b-form-input
+ v-model="fanSpeedWarninigInput"
+ type="number"
+ :min="0"
+ :max="fanSpeedShutdownInput"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <div class="speed-limt">
+ <img src="@/assets/images/labels/shutdown.svg" />
+ <span class="semi-bold-12px">{{ $t('fansPage.speedShutdown') }}</span>
+ <b-form-input
+ v-model="fanSpeedShutdownInput"
+ :min="fanSpeedWarninigInput"
+ :max="4000"
+ type="number"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <b-button class="save-button" variant="primary" @click="updateFansSpeed">
+ {{ $t('global.action.save') }}
+ </b-button>
+ </div>
+
+ <fans-dynamic-table
+ :speed-warninig="fanSpeedWarninig"
+ :speed-shutdown="fanSpeedShutdown"
+ :time-scale="timeScale"
+ />
+ <indicators-table />
+ </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import DateSwitch from '@/components/Global/SilaComponents/DateSwitch';
+import FansDynamicTable from './FansDynamicTable';
+import IndicatorsTable from './IndicatorsTable';
+
+export default {
+ components: { PageTitle, DateSwitch, FansDynamicTable, IndicatorsTable },
+ data() {
+ return {
+ timeScale: 'hour',
+ fanSpeedWarninigInput: 2450,
+ fanSpeedShutdownInput: 3150,
+ fanSpeedWarninig: 2450,
+ fanSpeedShutdown: 3150,
+ };
+ },
+ methods: {
+ switchTimeScale(period) {
+ this.timeScale = period;
+ },
+ updateFansSpeed() {
+ this.fanSpeedWarninig = +this.fanSpeedWarninigInput;
+ this.fanSpeedShutdown = +this.fanSpeedShutdownInput;
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+.speed-description {
+ height: 56px;
+ padding-left: 36px;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ border-bottom: 1px solid $faint-secondary-primary-10;
+}
+
+.limit-speed-container {
+ height: 85px;
+ padding: 0 0 10px 32px;
+ display: flex;
+ align-items: flex-end;
+ gap: 24px;
+}
+
+.speed-limt {
+ height: 60px;
+ max-width: 312px;
+ display: flex;
+ align-items: baseline;
+ flex-flow: row wrap;
+ gap: 8px;
+}
+
+.save-button {
+ width: 151px;
+ height: 36px;
+}
+
+.form-control {
+ height: 36px;
+}
+
+.main-container {
+ overflow: auto;
+}
+</style>
diff --git a/src/views/_sila/Fans/DynamicInformation/FansDynamicTable.vue b/src/views/_sila/Fans/DynamicInformation/FansDynamicTable.vue
new file mode 100644
index 00000000..b0818255
--- /dev/null
+++ b/src/views/_sila/Fans/DynamicInformation/FansDynamicTable.vue
@@ -0,0 +1,126 @@
+<template>
+ <div>
+ <highcharts :options="chartOptions.line" />
+ </div>
+</template>
+
+<script>
+import { setTime, Series, setSpeed } from './helpers';
+import { Chart } from 'highcharts-vue';
+
+export default {
+ components: {
+ highcharts: Chart,
+ },
+ props: {
+ timeScale: {
+ type: String,
+ default: 'hour',
+ },
+ speedWarninig: {
+ type: Number,
+ default: 2450,
+ },
+ speedShutdown: {
+ type: Number,
+ default: 3150,
+ },
+ },
+ computed: {
+ chartOptions() {
+ return {
+ line: {
+ chart: {
+ type: 'line',
+ margin: [12, 50, 32, 60],
+ height: '320px',
+ },
+ title: null,
+ xAxis: {
+ categories: setTime(60, this.timeScale),
+ title: null,
+ labels: {
+ step: 6,
+ },
+ minorGridLineColor: '#1A3E5B1A',
+ },
+ yAxis: {
+ categories: setSpeed(4000),
+ min: 0,
+ title: null,
+ minRange: 4000,
+ minTickInterval: 1000,
+ minorGridLineColor: '#1A3E5B1A',
+ plotLines: [
+ {
+ color: '#E11717',
+ dashStyle: 'solid',
+ value: this.speedWarninig,
+ zIndex: '1000',
+ width: 2,
+ label: {
+ text: 'Пороговое значения предупреждение',
+ align: 'right',
+ style: {
+ fontFamily: 'Inter, sans-serif',
+ fontSize: '12px',
+ fontStyle: 'normal',
+ fontWeight: '400',
+ lineHeight: '16px',
+ color: '#0C1C2999',
+ },
+ },
+ },
+ {
+ color: '#1A3E5B',
+ dashStyle: 'solid',
+ value: this.speedShutdown,
+ width: 2,
+ label: {
+ text: 'Пороговое значения отказ',
+ align: 'right',
+ style: {
+ fontFamily: 'Inter, sans-serif',
+ fontSize: '12px',
+ fontStyle: 'normal',
+ fontWeight: '400',
+ lineHeight: '16px',
+ color: '#0C1C2999',
+ },
+ },
+ },
+ ],
+ },
+ series: Series[this.timeScale].map((item) => ({
+ ...item,
+ marker: {
+ enabled: false,
+ },
+ })),
+ legend: {
+ enabled: false,
+ },
+ tooltip: {
+ enabled: false,
+ crosshairs: false,
+ },
+ plotOptions: {
+ series: {
+ showInLegend: true,
+ },
+ },
+ },
+ };
+ },
+ },
+};
+</script>
+<style lang="scss">
+.highcharts-credits {
+ display: none;
+}
+
+.highcharts-plot-line-label {
+ transform: translate(-15px, 0) !important;
+}
+</style>
diff --git a/src/views/_sila/Fans/DynamicInformation/IndicatorsTable.vue b/src/views/_sila/Fans/DynamicInformation/IndicatorsTable.vue
new file mode 100644
index 00000000..4da9a556
--- /dev/null
+++ b/src/views/_sila/Fans/DynamicInformation/IndicatorsTable.vue
@@ -0,0 +1,167 @@
+<template>
+ <page-section class="bootstrap-table__section">
+ <span class="bold-12px__caps">
+ {{ $t('fansPage.valueIndicators') }}
+ </span>
+ <b-table
+ responsive="md"
+ class="table-accessory"
+ no-border-collapse
+ :items="filteredSensors"
+ :busy="isBusy"
+ :fields="fields"
+ >
+ <template #cell(name)="{ value, index }">
+ <div
+ class="fans-colors"
+ :style="`background-color: ${colors[index]}`"
+ ></div>
+ <span class="regular-12px tretiatry">
+ {{ value }}
+ </span>
+ </template>
+ <template #cell(middleSpeed)="{ value }">
+ <span class="regular-12px">
+ {{ value.time }}
+ </span>
+ <span class="regular-12px tretiatry">
+ {{ value.date }}
+ </span>
+ </template>
+ <template #cell(minSpeedDate)="{ value }">
+ <span class="regular-12px">
+ {{ value.time }}
+ </span>
+ <span class="regular-12px tretiatry">
+ {{ value.date }}
+ </span>
+ </template>
+ <template #cell(maxSpeedDate)="{ value }">
+ <span class="regular-12px">
+ {{ value.time }}
+ </span>
+ <span class="regular-12px tretiatry">
+ {{ value.date }}
+ </span>
+ </template>
+ </b-table>
+ </page-section>
+</template>
+
+<script>
+import PageSection from '@/components/Global/PageSection';
+import { colors } from './helpers';
+
+import TableFilterMixin from '@/components/Mixins/TableFilterMixin';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
+import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
+
+export default {
+ components: { PageSection },
+ mixins: [TableFilterMixin, DataFormatterMixin, LoadingBarMixin],
+ data() {
+ return {
+ isBusy: true,
+ colors,
+ fields: [
+ {
+ key: 'name',
+ label: 'Имя модуля',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'currentValue',
+ label: 'Текущая',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'middleSpeed',
+ label: 'Средняя',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'lowerCaution',
+ label: 'Минимальная',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'minSpeedDate',
+ label: 'Дата минимальной',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'upperCaution',
+ label: 'Максимальная',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'maxSpeedDate',
+ label: 'Дата максимальной',
+ formatter: this.dataFormatter,
+ },
+ ],
+ };
+ },
+
+ computed: {
+ allSensors() {
+ let sensors = this.$store.getters['sensors/fanSensors'];
+ if (this.isSensorsExist) {
+ sensors.forEach((sensor) => {
+ sensor.type = sensor.name.toLowerCase().includes('cpu')
+ ? this.$t('tablesDescription.cpu')
+ : this.$t('tablesDescription.system');
+ });
+ }
+ return sensors;
+ },
+
+ isSensorsExist() {
+ return (
+ this.$store.getters['sensors/fanSensors'] &&
+ this.$store.getters['sensors/fanSensors'].length > 0
+ );
+ },
+
+ filteredSensors() {
+ return this.getFilteredTableData(this.allSensors, this.activeFilters);
+ },
+ },
+
+ watch: {
+ filteredSensors(value) {
+ if (value && value.length > 0) {
+ this.colors = this.$randomColor({
+ count: value.length,
+ hue: 'random',
+ luminosity: 'random',
+ });
+ }
+ },
+ },
+
+ created() {
+ this.startLoader();
+ this.$store.dispatch('sensors/getFanSensors').finally(() => {
+ this.endLoader();
+ this.isBusy = false;
+ });
+ },
+};
+</script>
+<style lang="scss" scoped>
+.fans-colors {
+ display: inline-block;
+ width: 8px;
+ height: 8px;
+ border-radius: 2px;
+}
+.row {
+ align-items: center;
+ flex-wrap: nowrap;
+ justify-content: flex-end;
+}
+.medium-12px {
+ color: $text-primary !important;
+}
+</style>
diff --git a/src/views/_sila/Fans/DynamicInformation/helpers.js b/src/views/_sila/Fans/DynamicInformation/helpers.js
new file mode 100644
index 00000000..1268d34a
--- /dev/null
+++ b/src/views/_sila/Fans/DynamicInformation/helpers.js
@@ -0,0 +1,820 @@
+export const colors = [
+ '#CB32F1',
+ '#F18638',
+ '#139BB9',
+ '#E1AB17',
+ '#175AE1',
+ '#13B937',
+];
+
+export const Series = {
+ hour: [
+ {
+ name: 'Sean',
+ data: [
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 1100,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 2100,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 1526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 1526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ ],
+ color: '#CB32F1',
+ },
+ {
+ name: 'Ivan',
+ data: [
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 1315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 2200,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 1100,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 1600,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 1400,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ ],
+ color: '#175AE1',
+ },
+ {
+ name: 'Brendan',
+ data: [
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 1359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 2000,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 2100,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 1400,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ ],
+ color: '#B98D13',
+ },
+ {
+ name: 'Matteo',
+ data: [
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 1350,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 1590,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 1490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ ],
+ color: '#13B937',
+ },
+ {
+ name: 'Joan',
+ data: [
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 1487,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 794,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 1924,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 1924,
+ 467,
+ 467,
+ 794,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 1924,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 794,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ ],
+ color: '#F18638',
+ },
+ {
+ name: 'Avinash',
+ data: [
+ 410,
+ 410,
+ 410,
+ 410,
+ 1300,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 2110,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 1410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 1410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ ],
+ color: '#139BB9',
+ },
+ ],
+ day: [
+ {
+ name: 'Sean',
+ data: [
+ 526,
+ 526,
+ 526,
+ 526,
+ 626,
+ 626,
+ 626,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 726,
+ 1026,
+ 726,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 1326,
+ 1526,
+ 1326,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ 526,
+ ],
+ color: '#CB32F1',
+ },
+ {
+ name: 'Ivan',
+ data: [
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 815,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 1100,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 800,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 900,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 900,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ 315,
+ ],
+ color: '#175AE1',
+ },
+ {
+ name: 'Brendan',
+ data: [
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 1500,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 1500,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 500,
+ 1200,
+ 500,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ 359,
+ ],
+ color: '#B98D13',
+ },
+ {
+ name: 'Matteo',
+ data: [
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 950,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 890,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 990,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ 490,
+ ],
+ color: '#13B937',
+ },
+ {
+ name: 'Joan',
+ data: [
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 1087,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 794,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 1424,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 1424,
+ 467,
+ 467,
+ 794,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 1224,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 794,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ 467,
+ ],
+ color: '#F18638',
+ },
+ {
+ name: 'Avinash',
+ data: [
+ 410,
+ 1410,
+ 410,
+ 410,
+ 1300,
+ 410,
+ 410,
+ 410,
+ 410,
+ 1410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 2110,
+ 410,
+ 410,
+ 1410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 1410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 1410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 1410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 1410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 1410,
+ 410,
+ 410,
+ 410,
+ 410,
+ 1410,
+ 410,
+ 410,
+ 410,
+ 1410,
+ 410,
+ 410,
+ ],
+ color: '#139BB9',
+ },
+ ],
+};
+
+export const setTime = (count) => {
+ const arr = [...new Array(count)].map(() => '');
+ for (let i = 0; i < arr.length; i++) {
+ arr[i] = `15:${String(i).padStart(2, '0')}`;
+ }
+ return arr;
+};
+
+export const setSpeed = (count) => {
+ const arr = [...new Array(count)].map((i, k) => `${k}`);
+ return arr;
+};
diff --git a/src/views/_sila/Fans/DynamicInformation/index.js b/src/views/_sila/Fans/DynamicInformation/index.js
new file mode 100644
index 00000000..a3dadd5a
--- /dev/null
+++ b/src/views/_sila/Fans/DynamicInformation/index.js
@@ -0,0 +1,2 @@
+import FansDynamicPage from './FansDynamicPage.vue';
+export default FansDynamicPage;
diff --git a/src/views/_sila/Fans/StaticInformation/FansStaticPage.vue b/src/views/_sila/Fans/StaticInformation/FansStaticPage.vue
new file mode 100644
index 00000000..b661bfdf
--- /dev/null
+++ b/src/views/_sila/Fans/StaticInformation/FansStaticPage.vue
@@ -0,0 +1,152 @@
+<template>
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title :description="$t('appNavigation.specification')" />
+ <span class="bold-16px">{{ $t('tablesDescription.installedFans') }}</span>
+ <page-section class="bootstrap-table__section">
+ <b-table
+ responsive="md"
+ show-empty
+ class="table-rounded"
+ no-border-collapse
+ :items="items"
+ :busy="isBusy"
+ :fields="fields"
+ :empty-text="$t('global.table.emptyMessage')"
+ >
+ <template #cell(status)="{ value }">
+ <div v-if="value" class="fans-table-col-first__cell">
+ <img class="status__img" src="@/assets/images/status/on.svg" />
+ <span>
+ {{ $t('global.status.inWork') }}
+ </span>
+ </div>
+ <div v-else class="fans-table-col-first__cell">
+ <img class="status__img" src="@/assets/images/_sila/status/off.svg" />
+ <span>
+ {{ $t('global.status.outWorking') }}
+ </span>
+ </div>
+ </template>
+ <template #cell(currentValue)="data">
+ {{ data.value }}
+ </template>
+ </b-table>
+ </page-section>
+ </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import PageSection from '@/components/Global/PageSection';
+
+import TableFilterMixin from '@/components/Mixins/TableFilterMixin';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
+import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
+
+export default {
+ components: { PageTitle, PageSection },
+ mixins: [TableFilterMixin, DataFormatterMixin, LoadingBarMixin],
+ data() {
+ return {
+ isBusy: true,
+ isAddersСolon: false,
+ fields: [
+ {
+ key: 'status',
+ label: 'Статус',
+ formatter: this.dataFormatter,
+ thStyle: { width: '25%' },
+ },
+ {
+ key: 'name',
+ label: 'Имя',
+ formatter: this.dataFormatter,
+ thStyle: { width: '25%' },
+ },
+ {
+ key: 'type',
+ label: 'Тип',
+ formatter: this.dataFormatter,
+ thStyle: { width: '25%' },
+ },
+ {
+ key: 'currentValue',
+ label: 'Текущая скорость, об/мин',
+ formatter: this.dataFormatter,
+ thStyle: { width: '25%' },
+ },
+ ],
+ items: [
+ {
+ status: true,
+ name: 'Венититор 1',
+ type: 'Системная плата',
+ value: '2100',
+ },
+ {
+ status: true,
+ name: 'Венититор 2',
+ type: 'Системная плата',
+ value: '2300',
+ },
+ {
+ status: false,
+ name: 'Венититор 3',
+ type: 'Системная плата',
+ value: '2400',
+ },
+ ],
+ activeFilters: [],
+ };
+ },
+
+ computed: {
+ allSensors() {
+ let sensors = this.$store.getters['sensors/fanSensors'];
+ if (this.isSensorsExist) {
+ sensors.forEach((sensor) => {
+ sensor.type = sensor.name.toLowerCase().includes('cpu')
+ ? this.$t('tablesDescription.cpu')
+ : this.$t('tablesDescription.system');
+ });
+ }
+ return sensors;
+ },
+
+ isSensorsExist() {
+ return (
+ this.$store.getters['sensors/fanSensors'] &&
+ this.$store.getters['sensors/fanSensors'].length > 0
+ );
+ },
+
+ filteredSensors() {
+ return this.getFilteredTableData(this.allSensors, this.activeFilters);
+ },
+ },
+
+ created() {
+ this.startLoader();
+ this.$store.dispatch('sensors/getFanSensors').finally(() => {
+ this.endLoader();
+ this.isBusy = false;
+ });
+ },
+};
+</script>
+<style lang="scss" scoped>
+.row {
+ margin: 0px;
+}
+
+.status__img {
+ margin-right: 7px;
+}
+
+.bold-16px {
+ margin: 24px 0 0 2rem;
+}
+</style>
diff --git a/src/views/_sila/Fans/StaticInformation/index.js b/src/views/_sila/Fans/StaticInformation/index.js
new file mode 100644
index 00000000..9a5d913d
--- /dev/null
+++ b/src/views/_sila/Fans/StaticInformation/index.js
@@ -0,0 +1,2 @@
+import FansStaticPage from './FansStaticPage.vue';
+export default FansStaticPage;
diff --git a/src/views/_sila/HardwareStatus/Inventory/Inventory.vue b/src/views/_sila/HardwareStatus/Inventory/Inventory.vue
new file mode 100644
index 00000000..dac395c5
--- /dev/null
+++ b/src/views/_sila/HardwareStatus/Inventory/Inventory.vue
@@ -0,0 +1,196 @@
+<template>
+ <b-container id="page-inventory" fluid class="p-0 m-0">
+ <page-title :description="$t('appNavigation.overviewInfo')" />
+ <!-- Service indicators -->
+ <service-indicator />
+
+ <!-- Quicklinks section -->
+ <page-section
+ class="bootstrap-table__section"
+ :section-small-title="$t('pageInventory.quicklinkTitle')"
+ >
+ <b-row>
+ <b-col v-for="column in quicklinkColumns" :key="column.id">
+ <div v-for="item in column" :key="item.id">
+ <b-link
+ :href="item.href"
+ :data-ref="item.dataRef"
+ @click.prevent="scrollToOffset"
+ >
+ {{ item.linkText }}
+ </b-link>
+ </div>
+ </b-col>
+ </b-row>
+ </page-section>
+
+ <!-- System table -->
+ <table-system ref="system" />
+
+ <!-- BMC manager table -->
+ <table-bmc-manager ref="bmc" />
+
+ <!-- Chassis table -->
+ <table-chassis ref="chassis" />
+
+ <!-- DIMM slot table -->
+ <table-dimm-slot ref="dimms" />
+
+ <!-- Fans table -->
+ <table-fans ref="fans" />
+
+ <!-- Power supplies table -->
+ <table-power-supplies ref="powerSupply" />
+
+ <!-- Processors table -->
+ <table-processors ref="processors" />
+
+ <!-- Assembly table -->
+ <table-assembly ref="assembly" />
+ </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import ServiceIndicator from './InventoryServiceIndicator';
+import TableSystem from './InventoryTableSystem';
+import TablePowerSupplies from './InventoryTablePowerSupplies';
+import TableDimmSlot from './InventoryTableDimmSlot';
+import TableFans from './InventoryTableFans';
+import TableBmcManager from './InventoryTableBmcManager';
+import TableChassis from './InventoryTableChassis';
+import TableProcessors from './InventoryTableProcessors';
+import TableAssembly from './InventoryTableAssembly';
+import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
+import PageSection from '@/components/Global/PageSection';
+import JumpLinkMixin from '@/components/Mixins/JumpLinkMixin';
+import { chunk } from 'lodash';
+
+export default {
+ components: {
+ PageTitle,
+ ServiceIndicator,
+ TableDimmSlot,
+ TablePowerSupplies,
+ TableSystem,
+ TableFans,
+ TableBmcManager,
+ TableChassis,
+ TableProcessors,
+ TableAssembly,
+ PageSection,
+ },
+ mixins: [LoadingBarMixin, JumpLinkMixin],
+ beforeRouteLeave(to, from, next) {
+ // Hide loader if user navigates away from page
+ // before requests complete
+ this.hideLoader();
+ next();
+ },
+ data() {
+ return {
+ links: [
+ {
+ id: 'system',
+ dataRef: 'system',
+ href: '#system',
+ linkText: this.$t('pageInventory.system'),
+ },
+ {
+ id: 'bmc',
+ dataRef: 'bmc',
+ href: '#bmc',
+ linkText: this.$t('pageInventory.bmcManager'),
+ },
+ {
+ id: 'chassis',
+ dataRef: 'chassis',
+ href: '#chassis',
+ linkText: this.$t('pageInventory.chassis'),
+ },
+ {
+ id: 'dimms',
+ dataRef: 'dimms',
+ href: '#dimms',
+ linkText: this.$t('pageInventory.dimmSlot'),
+ },
+ {
+ id: 'fans',
+ dataRef: 'fans',
+ href: '#fans',
+ linkText: this.$t('pageInventory.fans'),
+ },
+ {
+ id: 'powerSupply',
+ dataRef: 'powerSupply',
+ href: '#powerSupply',
+ linkText: this.$t('pageInventory.powerSupplies'),
+ },
+ {
+ id: 'processors',
+ dataRef: 'processors',
+ href: '#processors',
+ linkText: this.$t('pageInventory.processors'),
+ },
+ {
+ id: 'assembly',
+ dataRef: 'assembly',
+ href: '#assembly',
+ linkText: this.$t('pageInventory.assemblies'),
+ },
+ ],
+ };
+ },
+ computed: {
+ quicklinkColumns() {
+ // Chunk links array to 3 array's to display 3 items per column
+ return chunk(this.links, 3);
+ },
+ },
+ created() {
+ this.startLoader();
+ const bmcManagerTablePromise = new Promise((resolve) => {
+ this.$root.$on('hardware-status-bmc-manager-complete', () => resolve());
+ });
+ const chassisTablePromise = new Promise((resolve) => {
+ this.$root.$on('hardware-status-chassis-complete', () => resolve());
+ });
+ const dimmSlotTablePromise = new Promise((resolve) => {
+ this.$root.$on('hardware-status-dimm-slot-complete', () => resolve());
+ });
+ const fansTablePromise = new Promise((resolve) => {
+ this.$root.$on('hardware-status-fans-complete', () => resolve());
+ });
+ const powerSuppliesTablePromise = new Promise((resolve) => {
+ this.$root.$on('hardware-status-power-supplies-complete', () =>
+ resolve()
+ );
+ });
+ const processorsTablePromise = new Promise((resolve) => {
+ this.$root.$on('hardware-status-processors-complete', () => resolve());
+ });
+ const serviceIndicatorPromise = new Promise((resolve) => {
+ this.$root.$on('hardware-status-service-complete', () => resolve());
+ });
+ const systemTablePromise = new Promise((resolve) => {
+ this.$root.$on('hardware-status-system-complete', () => resolve());
+ });
+ const assemblyTablePromise = new Promise((resolve) => {
+ this.$root.$on('hardware-status-assembly-complete', () => resolve());
+ });
+ // Combine all child component Promises to indicate
+ // when page data load complete
+ Promise.all([
+ bmcManagerTablePromise,
+ chassisTablePromise,
+ dimmSlotTablePromise,
+ fansTablePromise,
+ powerSuppliesTablePromise,
+ processorsTablePromise,
+ serviceIndicatorPromise,
+ systemTablePromise,
+ assemblyTablePromise,
+ ]).finally(() => this.endLoader());
+ },
+};
+</script>
diff --git a/src/views/_sila/HardwareStatus/Inventory/InventoryServiceIndicator.vue b/src/views/_sila/HardwareStatus/Inventory/InventoryServiceIndicator.vue
new file mode 100644
index 00000000..0589aed8
--- /dev/null
+++ b/src/views/_sila/HardwareStatus/Inventory/InventoryServiceIndicator.vue
@@ -0,0 +1,82 @@
+<template>
+ <page-section
+ class="bootstrap-table__section"
+ :section-small-title="$t('pageInventory.systemIndicator.sectionTitle')"
+ >
+ <div class="form-background">
+ <b-row>
+ <b-col md="4">
+ <dl>
+ <dt>{{ $t('pageInventory.systemIndicator.powerStatus') }}</dt>
+ <dd>
+ {{ $t(powerStatus) }}
+ </dd>
+ </dl>
+ </b-col>
+ <b-col md="6">
+ <dl>
+ <dt>
+ {{ $t('pageInventory.systemIndicator.identifyLed') }}
+ </dt>
+ <dd>
+ <b-form-checkbox
+ id="identifyLedSwitchService"
+ v-model="systems.locationIndicatorActive"
+ data-test-id="inventoryService-toggle-identifyLed"
+ switch
+ @change="toggleIdentifyLedSwitch"
+ >
+ <span v-if="systems.locationIndicatorActive">
+ {{ $t('global.status.on') }}
+ </span>
+ <span v-else>{{ $t('global.status.off') }}</span>
+ </b-form-checkbox>
+ </dd>
+ </dl>
+ </b-col>
+ </b-row>
+ </div>
+ </page-section>
+</template>
+<script>
+import PageSection from '@/components/Global/PageSection';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+
+export default {
+ components: { PageSection },
+ mixins: [BVToastMixin],
+ computed: {
+ systems() {
+ let systemData = this.$store.getters['system/systems'][0];
+ return systemData ? systemData : {};
+ },
+ serverStatus() {
+ return this.$store.getters['global/serverStatus'];
+ },
+ powerStatus() {
+ if (this.serverStatus === 'unreachable') {
+ return `global.status.off`;
+ }
+ return `global.status.${this.serverStatus}`;
+ },
+ },
+ created() {
+ this.$store.dispatch('system/getSystem').finally(() => {
+ // Emit initial data fetch complete to parent component
+ this.$root.$emit('hardware-status-service-complete');
+ });
+ },
+ methods: {
+ toggleIdentifyLedSwitch(state) {
+ this.$store
+ .dispatch('system/changeIdentifyLedState', state)
+ .catch(({ message }) => this.errorToast(message));
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+.custom-switch {
+ margin: 0;
+}
+</style>
diff --git a/src/views/_sila/HardwareStatus/Inventory/InventoryTableAssembly.vue b/src/views/_sila/HardwareStatus/Inventory/InventoryTableAssembly.vue
new file mode 100644
index 00000000..7683ef93
--- /dev/null
+++ b/src/views/_sila/HardwareStatus/Inventory/InventoryTableAssembly.vue
@@ -0,0 +1,160 @@
+<template>
+ <page-section
+ class="bootstrap-table__section"
+ :section-small-title="$t('pageInventory.assemblies')"
+ >
+ <b-table
+ sort-icon-left
+ no-sort-reset
+ no-border-collapse
+ responsive="md"
+ :items="items"
+ :fields="fields"
+ :fixed="true"
+ show-empty
+ :empty-text="$t('global.table.emptyMessage')"
+ :busy="isBusy"
+ >
+ <!-- Expand chevron icon -->
+ <template #cell(expandRow)="row">
+ <b-button
+ variant="link"
+ data-test-id="hardwareStatus-button-expandAssembly"
+ :title="expandRowLabel"
+ class="btn-icon-only"
+ @click="toggleRowDetails(row)"
+ >
+ <icon-chevron />
+ <span class="sr-only">{{ expandRowLabel }}</span>
+ </b-button>
+ </template>
+
+ <!-- Toggle identify LED -->
+ <template #cell(identifyLed)="row">
+ <b-form-checkbox
+ v-if="hasIdentifyLed(row.item.identifyLed)"
+ v-model="row.item.identifyLed"
+ name="switch"
+ switch
+ @change="toggleIdentifyLedValue(row.item)"
+ >
+ <span v-if="row.item.identifyLed">
+ {{ $t('global.status.on') }}
+ </span>
+ <span v-else> {{ $t('global.status.off') }} </span>
+ </b-form-checkbox>
+ <div v-else>--</div>
+ </template>
+
+ <template #row-details="{ item }">
+ <b-container fluid>
+ <b-row>
+ <b-col class="mt-2" sm="6" xl="6">
+ <!-- Nmae -->
+ <dt>{{ $t('pageInventory.table.name') }}:</dt>
+ <dd>{{ dataFormatter(item.name) }}</dd>
+ <!-- Serial number -->
+ <dt>{{ $t('pageInventory.table.serialNumber') }}:</dt>
+ <dd>{{ dataFormatter(item.serialNumber) }}</dd>
+ </b-col>
+ <b-col class="mt-2" sm="6" xl="6">
+ <!-- Model-->
+ <dt>Model</dt>
+ <dd>{{ dataFormatter(item.model) }}</dd>
+ <!-- Spare Part Number -->
+ <dt>Spare Part Number</dt>
+ <dd>{{ dataFormatter(item.sparePartNumber) }}</dd>
+ </b-col>
+ </b-row>
+ </b-container>
+ </template>
+ </b-table>
+ </page-section>
+</template>
+
+<script>
+import PageSection from '@/components/Global/PageSection';
+import IconChevron from '@carbon/icons-vue/es/chevron--down/20';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import TableRowExpandMixin, {
+ expandRowLabel,
+} from '@/components/Mixins/TableRowExpandMixin';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
+
+export default {
+ components: { IconChevron, PageSection },
+ mixins: [BVToastMixin, TableRowExpandMixin, DataFormatterMixin],
+ data() {
+ return {
+ isBusy: true,
+ fields: [
+ {
+ key: 'expandRow',
+ label: '',
+ thStyle: { width: '4%' },
+ },
+ {
+ key: 'name',
+ label: this.$t('pageInventory.table.id'),
+ formatter: this.dataFormatter,
+ sortable: true,
+ thStyle: { width: '20%' },
+ },
+ {
+ key: 'partNumber',
+ label: this.$t('pageInventory.table.partNumber'),
+ formatter: this.dataFormatter,
+ sortable: true,
+ },
+ {
+ key: 'locationNumber',
+ label: this.$t('pageInventory.table.locationNumber'),
+ formatter: this.dataFormatter,
+ sortable: true,
+ thStyle: { width: '20%' },
+ },
+ {
+ key: 'identifyLed',
+ label: this.$t('pageInventory.table.identifyLed'),
+ formatter: this.dataFormatter,
+ thStyle: { width: '20%' },
+ },
+ ],
+ expandRowLabel: expandRowLabel,
+ };
+ },
+ computed: {
+ assemblies() {
+ return this.$store.getters['assemblies/assemblies'];
+ },
+ items() {
+ if (this.assemblies) {
+ return this.assemblies;
+ } else {
+ return [];
+ }
+ },
+ },
+ created() {
+ this.$store.dispatch('assemblies/getAssemblyInfo').finally(() => {
+ // Emit initial data fetch complete to parent component
+ this.$root.$emit('hardware-status-assembly-complete');
+ this.isBusy = false;
+ });
+ },
+ methods: {
+ toggleIdentifyLedValue(row) {
+ this.$store
+ .dispatch('assemblies/updateIdentifyLedValue', {
+ uri: row.uri,
+ memberId: row.id,
+ identifyLed: row.identifyLed,
+ })
+ .catch(({ message }) => this.errorToast(message));
+ },
+ hasIdentifyLed(identifyLed) {
+ return typeof identifyLed === 'boolean';
+ },
+ },
+};
+</script>
diff --git a/src/views/_sila/HardwareStatus/Inventory/InventoryTableBmcManager.vue b/src/views/_sila/HardwareStatus/Inventory/InventoryTableBmcManager.vue
new file mode 100644
index 00000000..f3cd1f05
--- /dev/null
+++ b/src/views/_sila/HardwareStatus/Inventory/InventoryTableBmcManager.vue
@@ -0,0 +1,254 @@
+<template>
+ <page-section
+ class="bootstrap-table__section"
+ :section-small-title="$t('pageInventory.bmcManager')"
+ >
+ <b-table
+ responsive="md"
+ show-empty
+ no-border-collapse
+ :items="items"
+ :fields="fields"
+ :fixed="true"
+ :empty-text="$t('global.table.emptyMessage')"
+ :busy="isBusy"
+ >
+ <!-- Expand chevron icon -->
+ <template #cell(expandRow)="row">
+ <b-button
+ variant="link"
+ data-test-id="hardwareStatus-button-expandBmc"
+ :title="expandRowLabel"
+ class="btn-icon-only"
+ @click="toggleRowDetails(row)"
+ >
+ <icon-chevron />
+ <span class="sr-only">{{ expandRowLabel }}</span>
+ </b-button>
+ </template>
+
+ <!-- Health -->
+ <template #cell(health)="{ value }">
+ <status-icon :status="statusIcon(value)" />
+ {{ value }}
+ </template>
+
+ <!-- Toggle identify LED -->
+ <template #cell(identifyLed)="row">
+ <b-form-checkbox
+ v-if="hasIdentifyLed(row.item.identifyLed)"
+ v-model="row.item.identifyLed"
+ name="switch"
+ switch
+ @change="toggleIdentifyLedValue(row.item)"
+ >
+ <span v-if="row.item.identifyLed">
+ {{ $t('global.status.on') }}
+ </span>
+ <span v-else> {{ $t('global.status.off') }} </span>
+ </b-form-checkbox>
+ <div v-else>--</div>
+ </template>
+
+ <template #row-details="{ item }">
+ <b-container fluid>
+ <b-row>
+ <b-col class="mt-2" sm="6" xl="6">
+ <dl>
+ <!-- Name -->
+ <dt>{{ $t('pageInventory.table.name') }}:</dt>
+ <dd>{{ dataFormatter(item.name) }}</dd>
+ <!-- Part number -->
+ <dt>{{ $t('pageInventory.table.partNumber') }}:</dt>
+ <dd>{{ dataFormatter(item.partNumber) }}</dd>
+ <!-- Serial number -->
+ <dt>{{ $t('pageInventory.table.serialNumber') }}:</dt>
+ <dd>{{ dataFormatter(item.serialNumber) }}</dd>
+ <!-- Spare part number -->
+ <dt>{{ $t('pageInventory.table.sparePartNumber') }}:</dt>
+ <dd>{{ dataFormatter(item.sparePartNumber) }}</dd>
+ <!-- Model -->
+ <dt>{{ $t('pageInventory.table.model') }}:</dt>
+ <dd>{{ dataFormatter(item.model) }}</dd>
+ <!-- UUID -->
+ <dt>{{ $t('pageInventory.table.uuid') }}:</dt>
+ <dd>{{ dataFormatter(item.uuid) }}</dd>
+ <!-- Service entry point UUID -->
+ <dt>{{ $t('pageInventory.table.serviceEntryPointUuid') }}:</dt>
+ <dd>{{ dataFormatter(item.serviceEntryPointUuid) }}</dd>
+ </dl>
+ </b-col>
+ <b-col class="mt-2" sm="6" xl="6">
+ <dl>
+ <!-- Status state -->
+ <dt>{{ $t('pageInventory.table.statusState') }}:</dt>
+ <dd>{{ dataFormatter(item.statusState) }}</dd>
+ <!-- Power state -->
+ <dt>{{ $t('pageInventory.table.power') }}:</dt>
+ <dd>{{ dataFormatter(item.powerState) }}</dd>
+ <!-- Health rollup -->
+ <dt>{{ $t('pageInventory.table.healthRollup') }}:</dt>
+ <dd>{{ dataFormatter(item.healthRollup) }}</dd>
+ <!-- BMC date and time -->
+ <dt>{{ $t('pageInventory.table.bmcDateTime') }}:</dt>
+ <dd>
+ {{ item.dateTime | formatDate }}
+ {{ item.dateTime | formatTime }}
+ </dd>
+ <!-- Reset date and time -->
+ <dt>{{ $t('pageInventory.table.lastResetTime') }}:</dt>
+ <dd>
+ {{ item.lastResetTime | formatDate }}
+ {{ item.lastResetTime | formatTime }}
+ </dd>
+ </dl>
+ </b-col>
+ </b-row>
+ <div class="section-divider mb-3 mt-3"></div>
+ <b-row>
+ <b-col class="mt-2" sm="6" xl="6">
+ <dl>
+ <!-- Manufacturer -->
+ <dt>{{ $t('pageInventory.table.manufacturer') }}:</dt>
+ <dd>{{ dataFormatter(item.manufacturer) }}</dd>
+ <!-- Description -->
+ <dt>{{ $t('pageInventory.table.description') }}:</dt>
+ <dd>{{ dataFormatter(item.description) }}</dd>
+ <!-- Manager type -->
+ <dt>{{ $t('pageInventory.table.managerType') }}:</dt>
+ <dd>{{ dataFormatter(item.managerType) }}</dd>
+ </dl>
+ </b-col>
+ <b-col class="mt-2" sm="6" xl="6">
+ <!-- Firmware Version -->
+ <dl>
+ <dt>{{ $t('pageInventory.table.firmwareVersion') }}:</dt>
+ <dd>{{ item.firmwareVersion }}</dd>
+ </dl>
+ <!-- Graphical console -->
+ <p class="mt-1 mb-2 h6 float-none m-0">
+ {{ $t('pageInventory.table.graphicalConsole') }}
+ </p>
+ <dl class="ml-4">
+ <dt>{{ $t('pageInventory.table.connectTypesSupported') }}:</dt>
+ <dd>
+ {{ dataFormatterArray(item.graphicalConsoleConnectTypes) }}
+ </dd>
+ <dt>{{ $t('pageInventory.table.maxConcurrentSessions') }}:</dt>
+ <dd>
+ {{ dataFormatter(item.graphicalConsoleMaxSessions) }}
+ </dd>
+ <dt>{{ $t('pageInventory.table.serviceEnabled') }}:</dt>
+ <dd>
+ {{ dataFormatter(item.graphicalConsoleEnabled) }}
+ </dd>
+ </dl>
+ <!-- Serial console -->
+ <p class="mt-1 mb-2 h6 float-none m-0">
+ {{ $t('pageInventory.table.serialConsole') }}
+ </p>
+ <dl class="ml-4">
+ <dt>{{ $t('pageInventory.table.connectTypesSupported') }}:</dt>
+ <dd>
+ {{ dataFormatterArray(item.serialConsoleConnectTypes) }}
+ </dd>
+ <dt>{{ $t('pageInventory.table.maxConcurrentSessions') }}:</dt>
+ <dd>{{ dataFormatter(item.serialConsoleMaxSessions) }}</dd>
+ <dt>{{ $t('pageInventory.table.serviceEnabled') }}:</dt>
+ <dd>{{ dataFormatter(item.serialConsoleEnabled) }}</dd>
+ </dl>
+ </b-col>
+ </b-row>
+ </b-container>
+ </template>
+ </b-table>
+ </page-section>
+</template>
+
+<script>
+import PageSection from '@/components/Global/PageSection';
+import IconChevron from '@carbon/icons-vue/es/chevron--down/20';
+import StatusIcon from '@/components/Global/StatusIcon';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import TableRowExpandMixin, {
+ expandRowLabel,
+} from '@/components/Mixins/TableRowExpandMixin';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
+
+export default {
+ components: { IconChevron, PageSection, StatusIcon },
+ mixins: [BVToastMixin, TableRowExpandMixin, DataFormatterMixin],
+ data() {
+ return {
+ isBusy: true,
+ fields: [
+ {
+ key: 'expandRow',
+ label: '',
+ thStyle: { width: '4%' },
+ tdClass: 'table-row-expand ',
+ },
+ {
+ key: 'id',
+ label: this.$t('pageInventory.table.id'),
+ formatter: this.dataFormatter,
+ thStyle: { width: '20%' },
+ tdClass: 'regular-12px ',
+ },
+ {
+ key: 'health',
+ label: this.$t('pageInventory.table.health'),
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'locationNumber',
+ label: this.$t('pageInventory.table.locationNumber'),
+ formatter: this.dataFormatter,
+ thStyle: { width: '20%' },
+ },
+ {
+ key: 'identifyLed',
+ label: this.$t('pageInventory.table.identifyLed'),
+ formatter: this.dataFormatter,
+ thStyle: { width: '20%' },
+ },
+ ],
+ expandRowLabel: expandRowLabel,
+ };
+ },
+ computed: {
+ bmc() {
+ return this.$store.getters['bmc/bmc'];
+ },
+ items() {
+ if (this.bmc) {
+ return [this.bmc];
+ } else {
+ return [];
+ }
+ },
+ },
+ created() {
+ this.$store.dispatch('bmc/getBmcInfo').finally(() => {
+ // Emit initial data fetch complete to parent component
+ this.$root.$emit('hardware-status-bmc-manager-complete');
+ this.isBusy = false;
+ });
+ },
+ methods: {
+ toggleIdentifyLedValue(row) {
+ this.$store
+ .dispatch('bmc/updateIdentifyLedValue', {
+ uri: row.uri,
+ identifyLed: row.identifyLed,
+ })
+ .catch(({ message }) => this.errorToast(message));
+ },
+ // TO DO: remove hasIdentifyLed method once the following story is merged:
+ // https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/43179
+ hasIdentifyLed(identifyLed) {
+ return typeof identifyLed === 'boolean';
+ },
+ },
+};
+</script>
diff --git a/src/views/_sila/HardwareStatus/Inventory/InventoryTableChassis.vue b/src/views/_sila/HardwareStatus/Inventory/InventoryTableChassis.vue
new file mode 100644
index 00000000..ed8787f9
--- /dev/null
+++ b/src/views/_sila/HardwareStatus/Inventory/InventoryTableChassis.vue
@@ -0,0 +1,199 @@
+<template>
+ <page-section
+ class="bootstrap-table__section"
+ :section-small-title="$t('pageInventory.chassis')"
+ >
+ <b-table
+ responsive="md"
+ show-empty
+ no-border-collapse
+ :items="chassis"
+ :fields="fields"
+ :fixed="true"
+ :empty-text="$t('global.table.emptyMessage')"
+ :busy="isBusy"
+ >
+ <!-- Expand chevron icon -->
+ <template #cell(expandRow)="row">
+ <b-button
+ variant="link"
+ data-test-id="hardwareStatus-button-expandChassis"
+ :title="expandRowLabel"
+ class="btn-icon-only"
+ @click="toggleRowDetails(row)"
+ >
+ <icon-chevron />
+ <span class="sr-only">{{ expandRowLabel }}</span>
+ </b-button>
+ </template>
+
+ <!-- Health -->
+ <template #cell(health)="{ value }">
+ <status-icon :status="statusIcon(value)" />
+ {{ value }}
+ </template>
+ <!-- Toggle identify LED -->
+ <template #cell(identifyLed)="row">
+ <b-form-checkbox
+ v-if="hasIdentifyLed(row.item.identifyLed)"
+ v-model="row.item.identifyLed"
+ name="switch"
+ switch
+ @change="toggleIdentifyLedValue(row.item)"
+ >
+ <span v-if="row.item.identifyLed">
+ {{ $t('global.status.on') }}
+ </span>
+ <span v-else> {{ $t('global.status.off') }} </span>
+ </b-form-checkbox>
+ <div v-else>--</div>
+ </template>
+ <template #row-details="{ item }">
+ <b-container fluid>
+ <b-row>
+ <b-col class="mt-2" sm="6" xl="6">
+ <dl>
+ <!-- Name -->
+ <dt>{{ $t('pageInventory.table.name') }}:</dt>
+ <dd>{{ dataFormatter(item.name) }}</dd>
+ <!-- Part number -->
+ <dt>{{ $t('pageInventory.table.partNumber') }}:</dt>
+ <dd>{{ dataFormatter(item.partNumber) }}</dd>
+ <!-- Serial Number -->
+ <dt>{{ $t('pageInventory.table.serialNumber') }}:</dt>
+ <dd>{{ dataFormatter(item.serialNumber) }}</dd>
+ <!-- Model -->
+ <dt>{{ $t('pageInventory.table.model') }}:</dt>
+ <dd class="mb-2">
+ {{ dataFormatter(item.model) }}
+ </dd>
+ <!-- Asset tag -->
+ <dt>{{ $t('pageInventory.table.assetTag') }}:</dt>
+ <dd class="mb-2">
+ {{ dataFormatter(item.assetTag) }}
+ </dd>
+ </dl>
+ </b-col>
+ <b-col class="mt-2" sm="6" xl="6">
+ <dl>
+ <!-- Status state -->
+ <dt>{{ $t('pageInventory.table.statusState') }}:</dt>
+ <dd>{{ dataFormatter(item.statusState) }}</dd>
+ <!-- Power state -->
+ <dt>{{ $t('pageInventory.table.power') }}:</dt>
+ <dd>{{ dataFormatter(item.power) }}</dd>
+ <!-- Health rollup -->
+ <dt>{{ $t('pageInventory.table.healthRollup') }}:</dt>
+ <dd>{{ dataFormatter(item.healthRollup) }}</dd>
+ </dl>
+ </b-col>
+ </b-row>
+ <div class="section-divider mb-3 mt-3"></div>
+ <b-row>
+ <b-col class="mt-2" sm="6" xl="6">
+ <dl>
+ <!-- Manufacturer -->
+ <dt>{{ $t('pageInventory.table.manufacturer') }}:</dt>
+ <dd>{{ dataFormatter(item.manufacturer) }}</dd>
+ <!-- Chassis Type -->
+ <dt>{{ $t('pageInventory.table.chassisType') }}:</dt>
+ <dd>{{ dataFormatter(item.chassisType) }}</dd>
+ </dl>
+ </b-col>
+ <b-col class="mt-2" sm="6" xl="6">
+ <dl>
+ <!-- Min power -->
+ <dt>{{ $t('pageInventory.table.minPowerWatts') }}:</dt>
+ <dd>{{ dataFormatter(item.minPowerWatts) }}</dd>
+ <!-- Max power -->
+ <dt>{{ $t('pageInventory.table.maxPowerWatts') }}:</dt>
+ <dd>{{ dataFormatter(item.maxPowerWatts) }}</dd>
+ </dl>
+ </b-col>
+ </b-row>
+ </b-container>
+ </template>
+ </b-table>
+ </page-section>
+</template>
+
+<script>
+import PageSection from '@/components/Global/PageSection';
+import IconChevron from '@carbon/icons-vue/es/chevron--down/20';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import StatusIcon from '@/components/Global/StatusIcon';
+
+import TableRowExpandMixin, {
+ expandRowLabel,
+} from '@/components/Mixins/TableRowExpandMixin';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
+
+export default {
+ components: { IconChevron, PageSection, StatusIcon },
+ mixins: [BVToastMixin, TableRowExpandMixin, DataFormatterMixin],
+ data() {
+ return {
+ isBusy: true,
+ fields: [
+ {
+ key: 'expandRow',
+ label: '',
+ thStyle: { width: '4%' },
+ tdClass: 'table-row-expand',
+ },
+ {
+ key: 'id',
+ label: this.$t('pageInventory.table.id'),
+ formatter: this.dataFormatter,
+ thStyle: { width: '20%' },
+ },
+ {
+ key: 'health',
+ label: this.$t('pageInventory.table.health'),
+ formatter: this.dataFormatter,
+ tdClass: 'text-nowrap',
+ },
+ {
+ key: 'locationNumber',
+ label: this.$t('pageInventory.table.locationNumber'),
+ formatter: this.dataFormatter,
+ thStyle: { width: '20%' },
+ },
+ {
+ key: 'identifyLed',
+ label: this.$t('pageInventory.table.identifyLed'),
+ formatter: this.dataFormatter,
+ thStyle: { width: '20%' },
+ },
+ ],
+ expandRowLabel: expandRowLabel,
+ };
+ },
+ computed: {
+ chassis() {
+ return this.$store.getters['chassis/chassis'];
+ },
+ },
+ created() {
+ this.$store.dispatch('chassis/getChassisInfo').finally(() => {
+ // Emit initial data fetch complete to parent component
+ this.$root.$emit('hardware-status-chassis-complete');
+ this.isBusy = false;
+ });
+ },
+ methods: {
+ toggleIdentifyLedValue(row) {
+ this.$store
+ .dispatch('chassis/updateIdentifyLedValue', {
+ uri: row.uri,
+ identifyLed: row.identifyLed,
+ })
+ .catch(({ message }) => this.errorToast(message));
+ },
+ // TO DO: Remove this method when the LocationIndicatorActive is added from backend.
+ hasIdentifyLed(identifyLed) {
+ return typeof identifyLed === 'boolean';
+ },
+ },
+};
+</script>
diff --git a/src/views/_sila/HardwareStatus/Inventory/InventoryTableDimmSlot.vue b/src/views/_sila/HardwareStatus/Inventory/InventoryTableDimmSlot.vue
new file mode 100644
index 00000000..fa25919f
--- /dev/null
+++ b/src/views/_sila/HardwareStatus/Inventory/InventoryTableDimmSlot.vue
@@ -0,0 +1,263 @@
+<template>
+ <page-section
+ class="bootstrap-table__section"
+ :section-small-title="$t('pageInventory.dimmSlot')"
+ >
+ <b-row class="align-items-end">
+ <b-col sm="6" md="5" xl="4">
+ <search
+ @change-search="onChangeSearchInput"
+ @clear-search="onClearSearchInput"
+ />
+ </b-col>
+ <b-col sm="6" md="3" xl="2">
+ <table-cell-count
+ :filtered-items-count="filteredRows"
+ :total-number-of-cells="dimms.length"
+ ></table-cell-count>
+ </b-col>
+ </b-row>
+ <b-table
+ sort-icon-left
+ no-sort-reset
+ sort-by="health"
+ responsive="md"
+ show-empty
+ no-border-collapse
+ :items="dimms"
+ :fields="fields"
+ :sort-desc="true"
+ :fixed="true"
+ :sort-compare="sortCompare"
+ :filter="searchFilter"
+ :empty-text="$t('global.table.emptyMessage')"
+ :empty-filtered-text="$t('global.table.emptySearchMessage')"
+ :busy="isBusy"
+ @filtered="onFiltered"
+ >
+ <!-- Expand chevron icon -->
+ <template #cell(expandRow)="row">
+ <b-button
+ variant="link"
+ data-test-id="hardwareStatus-button-expandDimms"
+ :title="expandRowLabel"
+ class="btn-icon-only"
+ @click="toggleRowDetails(row)"
+ >
+ <icon-chevron />
+ <span class="sr-only">{{ expandRowLabel }}</span>
+ </b-button>
+ </template>
+
+ <!-- Health -->
+ <template #cell(health)="{ value }">
+ <status-icon :status="statusIcon(value)" />
+ {{ value }}
+ </template>
+ <!-- Toggle identify LED -->
+ <template #cell(identifyLed)="row">
+ <b-form-checkbox
+ v-model="row.item.identifyLed"
+ name="switch"
+ switch
+ @change="toggleIdentifyLedValue(row.item)"
+ >
+ <span v-if="row.item.identifyLed">
+ {{ $t('global.status.on') }}
+ </span>
+ <span v-else> {{ $t('global.status.off') }} </span>
+ </b-form-checkbox>
+ </template>
+ <template #row-details="{ item }">
+ <b-container fluid>
+ <b-row>
+ <b-col sm="6" xl="6">
+ <dl>
+ <!-- Part Number -->
+ <dt>{{ $t('pageInventory.table.partNumber') }}:</dt>
+ <dd>{{ dataFormatter(item.partNumber) }}</dd>
+ </dl>
+ <dl>
+ <!-- Serial Number -->
+ <dt>{{ $t('pageInventory.table.serialNumber') }}:</dt>
+ <dd>{{ dataFormatter(item.serialNumber) }}</dd>
+ </dl>
+ <dl>
+ <!-- Spare Part Number -->
+ <dt>{{ $t('pageInventory.table.sparePartNumber') }}:</dt>
+ <dd>{{ dataFormatter(item.sparePartNumber) }}</dd>
+ </dl>
+ <dl>
+ <!-- Model -->
+ <dt>{{ $t('pageInventory.table.model') }}:</dt>
+ <dd>{{ dataFormatter(item.model) }}</dd>
+ </dl>
+ </b-col>
+ <b-col sm="6" xl="6">
+ <dl>
+ <!-- Memory Size in kb -->
+ <dt>{{ $t('pageInventory.table.memorySize') }}:</dt>
+ <dd>{{ dataFormatter(item.memorySize) }} KB</dd>
+ </dl>
+ <dl>
+ <!-- Status-->
+ <dt>{{ $t('pageInventory.table.statusState') }}:</dt>
+ <dd>{{ dataFormatter(item.statusState) }}</dd>
+ </dl>
+ <dl>
+ <!-- Enabled-->
+ <dt>{{ $t('pageInventory.table.enabled') }}:</dt>
+ <dd>{{ dataFormatter(item.enabled) }}</dd>
+ </dl>
+ </b-col>
+ </b-row>
+ <div class="section-divider mb-3 mt-3"></div>
+ <b-row>
+ <b-col sm="6" xl="6">
+ <dl>
+ <!-- Description -->
+ <dt>{{ $t('pageInventory.table.description') }}:</dt>
+ <dd>{{ dataFormatter(item.description) }}</dd>
+ </dl>
+ <dl>
+ <!-- Memory Type -->
+ <dt>{{ $t('pageInventory.table.memoryType') }}:</dt>
+ <dd>{{ dataFormatter(item.memoryType) }}</dd>
+ </dl>
+ <dl>
+ <!-- Base Module Type -->
+ <dt>{{ $t('pageInventory.table.baseModuleType') }}:</dt>
+ <dd>{{ dataFormatter(item.baseModuleType) }}</dd>
+ </dl>
+ <dl>
+ <!-- Capacity MiB -->
+ <dt>{{ $t('pageInventory.table.capacityMiB') }}:</dt>
+ <dd>{{ dataFormatter(item.capacityMiB) }}</dd>
+ </dl>
+ </b-col>
+ <b-col sm="6" xl="6">
+ <dl>
+ <!-- Bus Width Bits -->
+ <dt>{{ $t('pageInventory.table.busWidthBits') }}:</dt>
+ <dd>{{ dataFormatter(item.busWidthBits) }}</dd>
+ </dl>
+ <dl>
+ <!-- Data Width Bits -->
+ <dt>{{ $t('pageInventory.table.dataWidthBits') }}:</dt>
+ <dd>{{ dataFormatter(item.dataWidthBits) }}</dd>
+ </dl>
+ <dl>
+ <!-- Operating Speed Mhz -->
+ <dt>{{ $t('pageInventory.table.operatingSpeedMhz') }}:</dt>
+ <dd>{{ dataFormatter(item.operatingSpeedMhz) }} MHz</dd>
+ </dl>
+ </b-col>
+ </b-row>
+ </b-container>
+ </template>
+ </b-table>
+ </page-section>
+</template>
+
+<script>
+import PageSection from '@/components/Global/PageSection';
+import IconChevron from '@carbon/icons-vue/es/chevron--down/20';
+
+import StatusIcon from '@/components/Global/StatusIcon';
+import TableCellCount from '@/components/Global/TableCellCount';
+
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
+import TableSortMixin from '@/components/Mixins/TableSortMixin';
+import Search from '@/components/Global/Search';
+import SearchFilterMixin, {
+ searchFilter,
+} from '@/components/Mixins/SearchFilterMixin';
+import TableRowExpandMixin, {
+ expandRowLabel,
+} from '@/components/Mixins/TableRowExpandMixin';
+
+export default {
+ components: { IconChevron, PageSection, StatusIcon, Search, TableCellCount },
+ mixins: [
+ TableRowExpandMixin,
+ DataFormatterMixin,
+ TableSortMixin,
+ SearchFilterMixin,
+ ],
+ data() {
+ return {
+ isBusy: true,
+ fields: [
+ {
+ key: 'expandRow',
+ label: '',
+ thStyle: { width: '4%' },
+ tdClass: 'table-row-expand',
+ },
+ {
+ key: 'id',
+ label: this.$t('pageInventory.table.id'),
+ formatter: this.dataFormatter,
+ thStyle: { width: '20%' },
+ },
+ {
+ key: 'health',
+ label: this.$t('pageInventory.table.health'),
+ formatter: this.dataFormatter,
+ tdClass: 'text-nowrap ',
+ },
+ {
+ key: 'locationNumber',
+ label: this.$t('pageInventory.table.locationNumber'),
+ formatter: this.dataFormatter,
+ thStyle: { width: '20%' },
+ },
+ {
+ key: 'identifyLed',
+ label: this.$t('pageInventory.table.identifyLed'),
+ formatter: this.dataFormatter,
+ thStyle: { width: '20%' },
+ },
+ ],
+ searchFilter: searchFilter,
+ searchTotalFilteredRows: 0,
+ expandRowLabel: expandRowLabel,
+ };
+ },
+ computed: {
+ filteredRows() {
+ return this.searchFilter
+ ? this.searchTotalFilteredRows
+ : this.dimms.length;
+ },
+ dimms() {
+ return this.$store.getters['memory/dimms'];
+ },
+ },
+ created() {
+ this.$store.dispatch('memory/getDimms').finally(() => {
+ // Emit initial data fetch complete to parent component
+ this.$root.$emit('hardware-status-dimm-slot-complete');
+ this.isBusy = false;
+ });
+ },
+ methods: {
+ sortCompare(a, b, key) {
+ if (key === 'health') {
+ return this.sortStatus(a, b, key);
+ }
+ },
+ onFiltered(filteredItems) {
+ this.searchTotalFilteredRows = filteredItems.length;
+ },
+ toggleIdentifyLedValue(row) {
+ this.$store
+ .dispatch('memory/updateIdentifyLedValue', {
+ uri: row.uri,
+ identifyLed: row.identifyLed,
+ })
+ .catch(({ message }) => this.errorToast(message));
+ },
+ },
+};
+</script>
diff --git a/src/views/_sila/HardwareStatus/Inventory/InventoryTableFans.vue b/src/views/_sila/HardwareStatus/Inventory/InventoryTableFans.vue
new file mode 100644
index 00000000..d110ad3f
--- /dev/null
+++ b/src/views/_sila/HardwareStatus/Inventory/InventoryTableFans.vue
@@ -0,0 +1,198 @@
+<template>
+ <page-section
+ class="bootstrap-table__section"
+ :section-small-title="$t('pageInventory.fans')"
+ >
+ <b-row class="align-items-end">
+ <b-col sm="6" md="5" xl="4">
+ <search
+ @change-search="onChangeSearchInput"
+ @clear-search="onClearSearchInput"
+ />
+ </b-col>
+ <b-col sm="6" md="3" xl="2">
+ <table-cell-count
+ :filtered-items-count="filteredRows"
+ :total-number-of-cells="fans.length"
+ ></table-cell-count>
+ </b-col>
+ </b-row>
+ <b-table
+ sort-icon-left
+ no-sort-reset
+ responsive="md"
+ sort-by="health"
+ show-empty
+ no-border-collapse
+ :items="fans"
+ :fields="fields"
+ :sort-desc="true"
+ :fixed="true"
+ :sort-compare="sortCompare"
+ :filter="searchFilter"
+ :empty-text="$t('global.table.emptyMessage')"
+ :empty-filtered-text="$t('global.table.emptySearchMessage')"
+ :busy="isBusy"
+ @filtered="onFiltered"
+ >
+ <!-- Expand chevron icon -->
+ <template #cell(expandRow)="row">
+ <b-button
+ variant="link"
+ data-test-id="hardwareStatus-button-expandFans"
+ :title="expandRowLabel"
+ class="btn-icon-only"
+ @click="toggleRowDetails(row)"
+ >
+ <icon-chevron />
+ <span class="sr-only">{{ expandRowLabel }}</span>
+ </b-button>
+ </template>
+
+ <!-- Health -->
+ <template #cell(health)="{ value }">
+ <status-icon :status="statusIcon(value)" />
+ {{ value }}
+ </template>
+
+ <template #row-details="{ item }">
+ <b-container fluid>
+ <b-row>
+ <b-col sm="6" xl="4">
+ <dl>
+ <!-- Name -->
+ <dt>{{ $t('pageInventory.table.name') }}:</dt>
+ <dd>{{ dataFormatter(item.name) }}</dd>
+ </dl>
+ <dl>
+ <!-- Serial number -->
+ <dt>{{ $t('pageInventory.table.serialNumber') }}:</dt>
+ <dd>{{ dataFormatter(item.serialNumber) }}</dd>
+ </dl>
+ <dl>
+ <!-- Part number -->
+ <dt>{{ $t('pageInventory.table.partNumber') }}:</dt>
+ <dd>{{ dataFormatter(item.partNumber) }}</dd>
+ </dl>
+ <dl>
+ <!-- Fan speed -->
+ <dt>{{ $t('pageInventory.table.fanSpeed') }}:</dt>
+ <dd>{{ dataFormatter(item.speed) }}</dd>
+ </dl>
+ </b-col>
+ <b-col sm="6" xl="4">
+ <dl>
+ <!-- Status state -->
+ <dt>{{ $t('pageInventory.table.statusState') }}:</dt>
+ <dd>{{ dataFormatter(item.statusState) }}</dd>
+ </dl>
+ <dl>
+ <!-- Health Rollup state -->
+ <dt>{{ $t('pageInventory.table.statusHealthRollup') }}:</dt>
+ <dd>{{ dataFormatter(item.healthRollup) }}</dd>
+ </dl>
+ </b-col>
+ </b-row>
+ </b-container>
+ </template>
+ </b-table>
+ </page-section>
+</template>
+
+<script>
+import PageSection from '@/components/Global/PageSection';
+import IconChevron from '@carbon/icons-vue/es/chevron--down/20';
+import TableCellCount from '@/components/Global/TableCellCount';
+
+import StatusIcon from '@/components/Global/StatusIcon';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
+import TableSortMixin from '@/components/Mixins/TableSortMixin';
+import Search from '@/components/Global/Search';
+import SearchFilterMixin, {
+ searchFilter,
+} from '@/components/Mixins/SearchFilterMixin';
+import TableRowExpandMixin, {
+ expandRowLabel,
+} from '@/components/Mixins/TableRowExpandMixin';
+
+export default {
+ components: { IconChevron, PageSection, StatusIcon, Search, TableCellCount },
+ mixins: [
+ TableRowExpandMixin,
+ DataFormatterMixin,
+ TableSortMixin,
+ SearchFilterMixin,
+ ],
+ data() {
+ return {
+ isBusy: true,
+ fields: [
+ {
+ key: 'expandRow',
+ label: '',
+ sortable: false,
+ thStyle: { width: '4%' },
+ tdClass: 'table-row-expand',
+ },
+ {
+ key: 'id',
+ label: this.$t('pageInventory.table.id'),
+ formatter: this.dataFormatter,
+ sortable: true,
+ thStyle: { width: '20%' },
+ },
+ {
+ key: 'health',
+ label: this.$t('pageInventory.table.health'),
+ formatter: this.dataFormatter,
+ sortable: true,
+ tdClass: 'text-nowrap',
+ },
+ {
+ key: 'partNumber',
+ label: this.$t('pageInventory.table.partNumber'),
+ formatter: this.dataFormatter,
+ sortable: true,
+ thStyle: { width: '20%' },
+ },
+ {
+ key: 'serialNumber',
+ label: this.$t('pageInventory.table.serialNumber'),
+ formatter: this.dataFormatter,
+ thStyle: { width: '20%' },
+ },
+ ],
+ searchFilter: searchFilter,
+ searchTotalFilteredRows: 0,
+ expandRowLabel: expandRowLabel,
+ };
+ },
+ computed: {
+ filteredRows() {
+ return this.searchFilter
+ ? this.searchTotalFilteredRows
+ : this.fans.length;
+ },
+ fans() {
+ return this.$store.getters['fan/fans'];
+ },
+ },
+ created() {
+ this.$store.dispatch('fan/getFanInfo').finally(() => {
+ // Emit initial data fetch complete to parent component
+ this.$root.$emit('hardware-status-fans-complete');
+ this.isBusy = false;
+ });
+ },
+ methods: {
+ sortCompare(a, b, key) {
+ if (key === 'health') {
+ return this.sortStatus(a, b, key);
+ }
+ },
+ onFiltered(filteredItems) {
+ this.searchTotalFilteredRows = filteredItems.length;
+ },
+ },
+};
+</script>
diff --git a/src/views/_sila/HardwareStatus/Inventory/InventoryTablePowerSupplies.vue b/src/views/_sila/HardwareStatus/Inventory/InventoryTablePowerSupplies.vue
new file mode 100644
index 00000000..35e6e14d
--- /dev/null
+++ b/src/views/_sila/HardwareStatus/Inventory/InventoryTablePowerSupplies.vue
@@ -0,0 +1,216 @@
+<template>
+ <page-section
+ class="bootstrap-table__section"
+ :section-small-title="$t('pageInventory.powerSupplies')"
+ >
+ <b-row class="align-items-end">
+ <b-col sm="6" md="5" xl="4">
+ <search
+ @change-search="onChangeSearchInput"
+ @clear-search="onClearSearchInput"
+ />
+ </b-col>
+ <b-col sm="6" md="3" xl="2">
+ <table-cell-count
+ :filtered-items-count="filteredRows"
+ :total-number-of-cells="powerSupplies.length"
+ ></table-cell-count>
+ </b-col>
+ </b-row>
+ <b-table
+ sort-icon-left
+ no-sort-reset
+ hover
+ responsive="md"
+ sort-by="health"
+ show-empty
+ no-border-collapse
+ :items="powerSupplies"
+ :fields="fields"
+ :sort-desc="true"
+ :sort-compare="sortCompare"
+ :filter="searchFilter"
+ :empty-text="$t('global.table.emptyMessage')"
+ :empty-filtered-text="$t('global.table.emptySearchMessage')"
+ :busy="isBusy"
+ @filtered="onFiltered"
+ >
+ <!-- Expand chevron icon -->
+ <template #cell(expandRow)="row">
+ <b-button
+ variant="link"
+ data-test-id="hardwareStatus-button-expandPowerSupplies"
+ :title="expandRowLabel"
+ class="btn-icon-only"
+ @click="toggleRowDetails(row)"
+ >
+ <icon-chevron />
+ <span class="sr-only">{{ expandRowLabel }}</span>
+ </b-button>
+ </template>
+
+ <!-- Health -->
+ <template #cell(health)="{ value }">
+ <status-icon :status="statusIcon(value)" />
+ {{ value }}
+ </template>
+
+ <template #row-details="{ item }">
+ <b-container fluid>
+ <b-row>
+ <b-col sm="6" xl="4">
+ <dl>
+ <!-- Name -->
+ <dt>{{ $t('pageInventory.table.name') }}:</dt>
+ <dd>{{ dataFormatter(item.name) }}</dd>
+ <!-- Part number -->
+ <dt>{{ $t('pageInventory.table.partNumber') }}:</dt>
+ <dd>{{ dataFormatter(item.partNumber) }}</dd>
+ <!-- Serial number -->
+ <dt>{{ $t('pageInventory.table.serialNumber') }}:</dt>
+ <dd>{{ dataFormatter(item.serialNumber) }}</dd>
+ <!-- Spare part number -->
+ <dt>{{ $t('pageInventory.table.sparePartNumber') }}:</dt>
+ <dd>{{ dataFormatter(item.sparePartNumber) }}</dd>
+ <!-- Model -->
+ <dt>{{ $t('pageInventory.table.model') }}:</dt>
+ <dd>{{ dataFormatter(item.model) }}</dd>
+ </dl>
+ </b-col>
+ <b-col sm="6" xl="4">
+ <dl>
+ <!-- Status state -->
+ <dt>{{ $t('pageInventory.table.statusState') }}:</dt>
+ <dd>{{ dataFormatter(item.statusState) }}</dd>
+ <!-- Status Health rollup state -->
+ <dt>{{ $t('pageInventory.table.statusHealthRollup') }}:</dt>
+ <dd>{{ dataFormatter(item.statusHealth) }}</dd>
+ <!-- Efficiency percent -->
+ <dt>{{ $t('pageInventory.table.efficiencyPercent') }}:</dt>
+ <dd>{{ dataFormatter(item.efficiencyPercent) }}</dd>
+ <!-- Power input watts -->
+ <dt>{{ $t('pageInventory.table.powerInputWatts') }}:</dt>
+ <dd>{{ dataFormatter(item.powerInputWatts) }}</dd>
+ </dl>
+ </b-col>
+ </b-row>
+ <div class="section-divider mb-3 mt-3"></div>
+ <b-row>
+ <b-col sm="6" xl="4">
+ <dl>
+ <!-- Manufacturer -->
+ <dt>{{ $t('pageInventory.table.manufacturer') }}:</dt>
+ <dd>{{ dataFormatter(item.manufacturer) }}</dd>
+ </dl>
+ </b-col>
+ <b-col sm="6" xl="4">
+ <dl>
+ <!-- Firmware version -->
+ <dt>{{ $t('pageInventory.table.firmwareVersion') }}:</dt>
+ <dd>{{ dataFormatter(item.firmwareVersion) }}</dd>
+ </dl>
+ </b-col>
+ </b-row>
+ </b-container>
+ </template>
+ </b-table>
+ </page-section>
+</template>
+
+<script>
+import PageSection from '@/components/Global/PageSection';
+import IconChevron from '@carbon/icons-vue/es/chevron--down/20';
+
+import StatusIcon from '@/components/Global/StatusIcon';
+import TableCellCount from '@/components/Global/TableCellCount';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
+import TableSortMixin from '@/components/Mixins/TableSortMixin';
+import Search from '@/components/Global/Search';
+import SearchFilterMixin, {
+ searchFilter,
+} from '@/components/Mixins/SearchFilterMixin';
+import TableRowExpandMixin, {
+ expandRowLabel,
+} from '@/components/Mixins/TableRowExpandMixin';
+
+export default {
+ components: { IconChevron, PageSection, StatusIcon, Search, TableCellCount },
+ mixins: [
+ TableRowExpandMixin,
+ DataFormatterMixin,
+ TableSortMixin,
+ SearchFilterMixin,
+ ],
+ data() {
+ return {
+ isBusy: true,
+ fields: [
+ {
+ key: 'expandRow',
+ label: '',
+ sortable: false,
+ thStyle: { width: '4%' },
+ tdClass: 'table-row-expand',
+ },
+ {
+ key: 'id',
+ label: this.$t('pageInventory.table.id'),
+ formatter: this.dataFormatter,
+ sortable: true,
+ thStyle: { width: '20%' },
+ },
+ {
+ key: 'health',
+ label: this.$t('pageInventory.table.health'),
+ formatter: this.dataFormatter,
+ sortable: true,
+ tdClass: 'text-nowrap',
+ },
+ {
+ key: 'locationNumber',
+ label: this.$t('pageInventory.table.locationNumber'),
+ formatter: this.dataFormatter,
+ sortable: true,
+ thStyle: { width: '20%' },
+ },
+ {
+ key: 'identifyLed',
+ label: this.$t('pageInventory.table.identifyLed'),
+ formatter: this.dataFormatter,
+ thStyle: { width: '20%' },
+ },
+ ],
+ searchFilter: searchFilter,
+ searchTotalFilteredRows: 0,
+ expandRowLabel: expandRowLabel,
+ };
+ },
+ computed: {
+ filteredRows() {
+ return this.searchFilter
+ ? this.searchTotalFilteredRows
+ : this.powerSupplies.length;
+ },
+ powerSupplies() {
+ return this.$store.getters['powerSupply/powerSupplies'];
+ },
+ },
+ created() {
+ this.$store.dispatch('powerSupply/getAllPowerSupplies').finally(() => {
+ // Emit initial data fetch complete to parent component
+ this.$root.$emit('hardware-status-power-supplies-complete');
+ this.isBusy = false;
+ });
+ },
+ methods: {
+ sortCompare(a, b, key) {
+ if (key === 'health') {
+ return this.sortStatus(a, b, key);
+ }
+ },
+ onFiltered(filteredItems) {
+ this.searchTotalFilteredRows = filteredItems.length;
+ },
+ },
+};
+</script>
diff --git a/src/views/_sila/HardwareStatus/Inventory/InventoryTableProcessors.vue b/src/views/_sila/HardwareStatus/Inventory/InventoryTableProcessors.vue
new file mode 100644
index 00000000..08128da4
--- /dev/null
+++ b/src/views/_sila/HardwareStatus/Inventory/InventoryTableProcessors.vue
@@ -0,0 +1,275 @@
+<template>
+ <page-section
+ class="bootstrap-table__section"
+ :section-small-title="$t('pageInventory.processors')"
+ >
+ <!-- Search -->
+ <b-row class="align-items-end">
+ <b-col sm="6" md="5" xl="4">
+ <search
+ @change-search="onChangeSearchInput"
+ @clear-search="onClearSearchInput"
+ />
+ </b-col>
+ <b-col sm="6" md="3" xl="2">
+ <table-cell-count
+ :filtered-items-count="filteredRows"
+ :total-number-of-cells="processors.length"
+ >
+ </table-cell-count>
+ </b-col>
+ </b-row>
+ <b-table
+ sort-icon-left
+ no-sort-reset
+ hover
+ responsive="md"
+ show-empty
+ no-border-collapse
+ :items="processors"
+ :fields="fields"
+ :sort-desc="true"
+ :fixed="true"
+ :filter="searchFilter"
+ :empty-text="$t('global.table.emptyMessage')"
+ :empty-filtered-text="$t('global.table.emptySearchMessage')"
+ :busy="isBusy"
+ @filtered="onFiltered"
+ >
+ <!-- Expand button -->
+ <template #cell(expandRow)="row">
+ <b-button
+ variant="link"
+ data-test-id="hardwareStatus-button-expandProcessors"
+ :title="expandRowLabel"
+ class="btn-icon-only"
+ @click="toggleRowDetails(row)"
+ >
+ <icon-chevron />
+ <span class="sr-only">{{ expandRowLabel }}</span>
+ </b-button>
+ </template>
+ <!-- Health -->
+ <template #cell(health)="{ value }">
+ <status-icon :status="statusIcon(value)" />
+ {{ value }}
+ </template>
+
+ <!-- Toggle identify LED -->
+ <template #cell(identifyLed)="row">
+ <b-form-checkbox
+ v-if="hasIdentifyLed(row.item.identifyLed)"
+ v-model="row.item.identifyLed"
+ name="switch"
+ switch
+ @change="toggleIdentifyLedValue(row.item)"
+ >
+ <span v-if="row.item.identifyLed">
+ {{ $t('global.status.on') }}
+ </span>
+ <span v-else> {{ $t('global.status.off') }} </span>
+ </b-form-checkbox>
+ <div v-else>--</div>
+ </template>
+
+ <template #row-details="{ item }">
+ <b-container fluid>
+ <b-row>
+ <b-col class="mt-2" sm="6" xl="6">
+ <dl>
+ <!-- Name -->
+ <dt>{{ $t('pageInventory.table.name') }}:</dt>
+ <dd>{{ dataFormatter(item.name) }}</dd>
+ <!-- Part Number -->
+ <dt>{{ $t('pageInventory.table.partNumber') }}:</dt>
+ <dd>{{ dataFormatter(item.partNumber) }}</dd>
+ <!-- Serial Number -->
+ <dt>{{ $t('pageInventory.table.serialNumber') }}:</dt>
+ <dd>{{ dataFormatter(item.serialNumber) }}</dd>
+ <!-- Spare Part Number -->
+ <dt>{{ $t('pageInventory.table.sparePartNumber') }}:</dt>
+ <dd>{{ dataFormatter(item.sparePartNumber) }}</dd>
+ <!-- Model -->
+ <dt>{{ $t('pageInventory.table.model') }}:</dt>
+ <dd>{{ dataFormatter(item.model) }}</dd>
+ <!-- Asset Tag -->
+ <dt>{{ $t('pageInventory.table.assetTag') }}:</dt>
+ <dd>{{ dataFormatter(item.assetTag) }}</dd>
+ </dl>
+ </b-col>
+ <b-col class="mt-2" sm="6" xl="6">
+ <dl>
+ <!-- Status state -->
+ <dt>{{ $t('pageInventory.table.statusState') }}:</dt>
+ <dd>{{ dataFormatter(item.statusState) }}</dd>
+ <!-- Health Rollup -->
+ <dt>{{ $t('pageInventory.table.healthRollup') }}:</dt>
+ <dd>{{ dataFormatter(item.healthRollup) }}</dd>
+ </dl>
+ </b-col>
+ </b-row>
+ <div class="section-divider mb-3 mt-3"></div>
+ <b-row>
+ <b-col class="mt-1" sm="6" xl="6">
+ <dl>
+ <!-- Manufacturer -->
+ <dt>{{ $t('pageInventory.table.manufacturer') }}:</dt>
+ <dd>{{ dataFormatter(item.manufacturer) }}</dd>
+ <!-- Processor Type -->
+ <dt>{{ $t('pageInventory.table.processorType') }}:</dt>
+ <dd>{{ dataFormatter(item.processorType) }}</dd>
+ <!-- Processor Architecture -->
+ <dt>{{ $t('pageInventory.table.processorArchitecture') }}:</dt>
+ <dd>{{ dataFormatter(item.processorArchitecture) }}</dd>
+ <!-- Instruction Set -->
+ <dt>{{ $t('pageInventory.table.instructionSet') }}:</dt>
+ <dd>{{ dataFormatter(item.instructionSet) }}</dd>
+ <!-- Version -->
+ <dt>{{ $t('pageInventory.table.version') }}:</dt>
+ <dd>{{ dataFormatter(item.version) }}</dd>
+ </dl>
+ </b-col>
+ <b-col class="mt-1" sm="6" xl="6">
+ <dl>
+ <!-- Min Speed MHz -->
+ <dt>{{ $t('pageInventory.table.minSpeedMHz') }}:</dt>
+ <dd>{{ dataFormatter(item.minSpeedMHz) }}</dd>
+ <!-- Max Speed MHz -->
+ <dt>{{ $t('pageInventory.table.maxSpeedMHz') }}:</dt>
+ <dd>{{ dataFormatter(item.maxSpeedMHz) }}</dd>
+ <!-- Total Cores -->
+ <dt>{{ $t('pageInventory.table.totalCores') }}:</dt>
+ <dd>{{ dataFormatter(item.totalCores) }}</dd>
+ <!-- Total Threads -->
+ <dt>{{ $t('pageInventory.table.totalThreads') }}:</dt>
+ <dd>{{ dataFormatter(item.totalThreads) }}</dd>
+ </dl>
+ </b-col>
+ </b-row>
+ </b-container>
+ </template>
+ </b-table>
+ </page-section>
+</template>
+
+<script>
+import PageSection from '@/components/Global/PageSection';
+import IconChevron from '@carbon/icons-vue/es/chevron--down/20';
+import StatusIcon from '@/components/Global/StatusIcon';
+import TableCellCount from '@/components/Global/TableCellCount';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import TableSortMixin from '@/components/Mixins/TableSortMixin';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
+import Search from '@/components/Global/Search';
+import SearchFilterMixin, {
+ searchFilter,
+} from '@/components/Mixins/SearchFilterMixin';
+import TableRowExpandMixin, {
+ expandRowLabel,
+} from '@/components/Mixins/TableRowExpandMixin';
+
+export default {
+ components: { IconChevron, PageSection, StatusIcon, Search, TableCellCount },
+ mixins: [
+ BVToastMixin,
+ TableRowExpandMixin,
+ DataFormatterMixin,
+ TableSortMixin,
+ SearchFilterMixin,
+ ],
+ data() {
+ return {
+ isBusy: true,
+ fields: [
+ {
+ key: 'expandRow',
+ label: '',
+ sortable: false,
+ thStyle: { width: '4%' },
+ tdClass: 'table-row-expand ',
+ },
+ {
+ key: 'id',
+ label: this.$t('pageInventory.table.id'),
+ formatter: this.dataFormatter,
+ sortable: true,
+ thStyle: { width: '20%' },
+ },
+ {
+ key: 'health',
+ label: this.$t('pageInventory.table.health'),
+ formatter: this.dataFormatter,
+ sortable: true,
+ tdClass: 'text-nowrap',
+ },
+ {
+ key: 'locationNumber',
+ label: this.$t('pageInventory.table.locationNumber'),
+ formatter: this.dataFormatter,
+ sortable: true,
+ thStyle: { width: '20%' },
+ },
+ {
+ key: 'identifyLed',
+ label: this.$t('pageInventory.table.identifyLed'),
+ formatter: this.dataFormatter,
+ sortable: false,
+ thStyle: { width: '20%' },
+ },
+ ],
+ processors: [
+ {
+ id: 'Процессор №1',
+ health: 'v3.1.5',
+ locationNumber: '2.4',
+ identifyLed: '4',
+ },
+ {
+ id: 'Процессор №1',
+ health: 'v3.1.5',
+ locationNumber: '2.4',
+ identifyLed: '4',
+ },
+ ],
+ searchFilter: searchFilter,
+ searchTotalFilteredRows: 0,
+ expandRowLabel: expandRowLabel,
+ };
+ },
+ computed: {
+ filteredRows() {
+ return this.searchFilter
+ ? this.searchTotalFilteredRows
+ : this.processors.length;
+ },
+ // processors() {
+ // return this.$store.getters['processors/processors'];
+ // },
+ },
+ created() {
+ this.$store.dispatch('processors/getProcessorsInfo').finally(() => {
+ // Emit initial data fetch complete to parent component
+ this.$root.$emit('hardware-status-processors-complete');
+ this.isBusy = false;
+ });
+ },
+ methods: {
+ onFiltered(filteredItems) {
+ this.searchTotalFilteredRows = filteredItems.length;
+ },
+ toggleIdentifyLedValue(row) {
+ this.$store
+ .dispatch('processors/updateIdentifyLedValue', {
+ uri: row.uri,
+ identifyLed: row.identifyLed,
+ })
+ .catch(({ message }) => this.errorToast(message));
+ },
+ // TO DO: remove hasIdentifyLed when the following is merged:
+ // https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/37045
+ hasIdentifyLed(identifyLed) {
+ return typeof identifyLed === 'boolean';
+ },
+ },
+};
+</script>
diff --git a/src/views/_sila/HardwareStatus/Inventory/InventoryTableSystem.vue b/src/views/_sila/HardwareStatus/Inventory/InventoryTableSystem.vue
new file mode 100644
index 00000000..c3b7bd87
--- /dev/null
+++ b/src/views/_sila/HardwareStatus/Inventory/InventoryTableSystem.vue
@@ -0,0 +1,236 @@
+<template>
+ <page-section
+ class="bootstrap-table__section"
+ :section-small-title="$t('pageInventory.system')"
+ >
+ <b-table
+ responsive="md"
+ show-empty
+ no-border-collapse
+ :items="systems"
+ :fields="fields"
+ :fixed="true"
+ :empty-text="$t('global.table.emptyMessage')"
+ :busy="isBusy"
+ >
+ <!-- Expand chevron icon -->
+ <template #cell(expandRow)="row">
+ <b-button
+ variant="link"
+ data-test-id="hardwareStatus-button-expandSystem"
+ :title="expandRowLabel"
+ class="btn-icon-only"
+ @click="toggleRowDetails(row)"
+ >
+ <icon-chevron />
+ <span class="sr-only">{{ expandRowLabel }}</span>
+ </b-button>
+ </template>
+
+ <!-- Health -->
+ <template #cell(health)="{ value }">
+ <status-icon :status="statusIcon(value)" />
+ {{ statusIcon(value) }}
+ </template>
+
+ <template #cell(locationIndicatorActive)="{ item }">
+ <b-form-checkbox
+ id="identifyLedSwitchSystem"
+ v-model="item.locationIndicatorActive"
+ data-test-id="inventorySystem-toggle-identifyLed"
+ switch
+ @change="toggleIdentifyLedSwitch"
+ >
+ <span v-if="item.locationIndicatorActive">
+ {{ $t('global.status.on') }}
+ </span>
+ <span v-else>{{ $t('global.status.off') }}</span>
+ </b-form-checkbox>
+ </template>
+
+ <template #row-details="{ item }">
+ <b-container fluid>
+ <b-row>
+ <b-col class="mt-2" sm="6">
+ <dl>
+ <!-- Serial number -->
+ <dt>{{ $t('pageInventory.table.serialNumber') }}:</dt>
+ <dd>{{ dataFormatter(item.serialNumber) }}</dd>
+ <!-- Model -->
+ <dt>{{ $t('pageInventory.table.model') }}:</dt>
+ <dd>{{ dataFormatter(item.model) }}</dd>
+ <!-- Asset tag -->
+ <dt>{{ $t('pageInventory.table.assetTag') }}:</dt>
+ <dd class="mb-2">
+ {{ dataFormatter(item.assetTag) }}
+ </dd>
+ </dl>
+ </b-col>
+ <b-col class="mt-2" sm="6">
+ <dl>
+ <!-- Status state -->
+ <dt>{{ $t('pageInventory.table.statusState') }}:</dt>
+ <dd>{{ dataFormatter(item.statusState) }}</dd>
+ <!-- Power state -->
+ <dt>{{ $t('pageInventory.table.power') }}:</dt>
+ <dd>{{ dataFormatter(item.powerState) }}</dd>
+ <!-- Health rollup -->
+ <dt>{{ $t('pageInventory.table.healthRollup') }}:</dt>
+ <dd>{{ dataFormatter(item.healthRollup) }}</dd>
+ </dl>
+ </b-col>
+ </b-row>
+ <div class="section-divider mb-3 mt-3"></div>
+ <b-row>
+ <b-col class="mt-1" sm="6">
+ <dl>
+ <!-- Manufacturer -->
+ <dt>{{ $t('pageInventory.table.manufacturer') }}:</dt>
+ <dd>{{ dataFormatter(item.manufacturer) }}</dd>
+ <!-- Description -->
+ <dt>{{ $t('pageInventory.table.description') }}:</dt>
+ <dd>{{ dataFormatter(item.description) }}</dd>
+ <!-- Sub Model -->
+ <dt>{{ $t('pageInventory.table.subModel') }}:</dt>
+ <dd>
+ {{ dataFormatter(item.subModel) }}
+ </dd>
+ <!-- System Type -->
+ <dt>{{ $t('pageInventory.table.systemType') }}:</dt>
+ <dd>
+ {{ dataFormatter(item.systemType) }}
+ </dd>
+ </dl>
+ </b-col>
+ <b-col sm="6">
+ <!-- Memory Summary -->
+ <p class="mt-1 mb-2 h6 float-none m-0">
+ {{ $t('pageInventory.table.memorySummary') }}
+ </p>
+ <dl class="ml-4">
+ <!-- Status state -->
+ <dt>{{ $t('pageInventory.table.statusState') }}:</dt>
+ <dd>{{ dataFormatter(item.memorySummaryState) }}</dd>
+ <!-- Health -->
+ <dt>{{ $t('pageInventory.table.health') }}:</dt>
+ <dd>{{ dataFormatter(item.memorySummaryHealth) }}</dd>
+ <!-- Health Roll -->
+ <dt>{{ $t('pageInventory.table.healthRollup') }}:</dt>
+ <dd>{{ dataFormatter(item.memorySummaryHealthRollup) }}</dd>
+ <!-- Total system memory -->
+ <dt>{{ $t('pageInventory.table.totalSystemMemoryGiB') }}:</dt>
+ <dd>{{ dataFormatter(item.totalSystemMemoryGiB) }}GB</dd>
+ </dl>
+ <!-- Processor Summary -->
+ <p class="mt-1 mb-2 h6 float-none m-0">
+ {{ $t('pageInventory.table.processorSummary') }}
+ </p>
+ <dl class="ml-4">
+ <!-- Status state -->
+ <dt>{{ $t('pageInventory.table.statusState') }}:</dt>
+ <dd>{{ dataFormatter(item.processorSummaryState) }}</dd>
+ <!-- Health -->
+ <dt>{{ $t('pageInventory.table.health') }}:</dt>
+ <dd>{{ dataFormatter(item.processorSummaryHealth) }}</dd>
+ <!-- Health Rollup -->
+ <dt>{{ $t('pageInventory.table.healthRollup') }}:</dt>
+ <dd>{{ dataFormatter(item.processorSummaryHealthRoll) }}</dd>
+ <!-- Count -->
+ <dt>{{ $t('pageInventory.table.count') }}:</dt>
+ <dd>{{ dataFormatter(item.processorSummaryCount) }}</dd>
+ <!-- Core Count -->
+ <dt>{{ $t('pageInventory.table.coreCount') }}:</dt>
+ <dd>{{ dataFormatter(item.processorSummaryCoreCount) }}</dd>
+ </dl>
+ </b-col>
+ </b-row>
+ </b-container>
+ </template>
+ </b-table>
+ </page-section>
+</template>
+
+<script>
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import PageSection from '@/components/Global/PageSection';
+import IconChevron from '@carbon/icons-vue/es/chevron--down/20';
+
+import StatusIcon from '@/components/Global/StatusIcon';
+
+import TableRowExpandMixin, {
+ expandRowLabel,
+} from '@/components/Mixins/TableRowExpandMixin';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
+
+export default {
+ components: { IconChevron, PageSection, StatusIcon },
+ mixins: [BVToastMixin, TableRowExpandMixin, DataFormatterMixin],
+ data() {
+ return {
+ isBusy: true,
+ fields: [
+ {
+ key: 'expandRow',
+ label: '',
+ thStyle: { width: '4%' },
+ tdClass: 'table-row-expand',
+ },
+ {
+ key: 'id',
+ label: this.$t('pageInventory.table.id'),
+ formatter: this.dataFormatter,
+ thStyle: { width: '20%' },
+ },
+ {
+ key: 'hardwareType',
+ label: this.$t('pageInventory.table.hardwareType'),
+ formatter: this.dataFormatter,
+ tdClass: 'text-nowrap ',
+ },
+ {
+ key: 'health',
+ label: this.$t('pageInventory.table.health'),
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'locationNumber',
+ label: this.$t('pageInventory.table.locationNumber'),
+ formatter: this.dataFormatter,
+ thStyle: { width: '20%' },
+ },
+ {
+ key: 'locationIndicatorActive',
+ label: this.$t('pageInventory.table.identifyLed'),
+ formatter: this.dataFormatter,
+ thStyle: { width: '20%' },
+ },
+ ],
+ expandRowLabel: expandRowLabel,
+ };
+ },
+ computed: {
+ systems() {
+ return this.$store.getters['system/systems'];
+ },
+ },
+ created() {
+ this.$store.dispatch('system/getSystem').finally(() => {
+ // Emit initial data fetch complete to parent component
+ this.$root.$emit('hardware-status-system-complete');
+ this.isBusy = false;
+ });
+ },
+ methods: {
+ toggleIdentifyLedSwitch(state) {
+ this.$store
+ .dispatch('system/changeIdentifyLedState', state)
+ .catch(({ message }) => this.errorToast(message));
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+.custom-switch {
+ margin: 0;
+}
+</style>
diff --git a/src/views/_sila/HardwareStatus/Inventory/index.js b/src/views/_sila/HardwareStatus/Inventory/index.js
new file mode 100644
index 00000000..c9fde8d2
--- /dev/null
+++ b/src/views/_sila/HardwareStatus/Inventory/index.js
@@ -0,0 +1,2 @@
+import Inventory from './Inventory.vue';
+export default Inventory;
diff --git a/src/views/_sila/HardwareStatus/Sensors/Sensors.vue b/src/views/_sila/HardwareStatus/Sensors/Sensors.vue
index 347efd6c..b98e023d 100644
--- a/src/views/_sila/HardwareStatus/Sensors/Sensors.vue
+++ b/src/views/_sila/HardwareStatus/Sensors/Sensors.vue
@@ -1,5 +1,5 @@
<template>
- <b-container fluid="xl">
+ <b-container>
<page-title />
<b-row class="align-items-end">
<b-col sm="6" md="5" xl="4">
@@ -254,3 +254,8 @@ export default {
},
};
</script>
+<style lang="scss">
+.container > .page-title > .text-title {
+ margin-left: 0 !important;
+}
+</style>
diff --git a/src/views/_sila/InformationAndFAQ/InformationAndFAQ.vue b/src/views/_sila/InformationAndFAQ/InformationAndFAQ.vue
new file mode 100644
index 00000000..ede7b3d8
--- /dev/null
+++ b/src/views/_sila/InformationAndFAQ/InformationAndFAQ.vue
@@ -0,0 +1,9 @@
+<template>
+ <span>This Page (Information And FAQ) In develop</span>
+</template>
+
+<script>
+export default {
+ name: 'InformationAndFAQ',
+};
+</script>
diff --git a/src/views/_sila/InformationAndFAQ/index.js b/src/views/_sila/InformationAndFAQ/index.js
new file mode 100644
index 00000000..6bbeaba6
--- /dev/null
+++ b/src/views/_sila/InformationAndFAQ/index.js
@@ -0,0 +1 @@
+export { default } from './InformationAndFAQ.vue';
diff --git a/src/views/_sila/Login/Login.vue b/src/views/_sila/Login/Login.vue
index 3c330362..1b8715c9 100644
--- a/src/views/_sila/Login/Login.vue
+++ b/src/views/_sila/Login/Login.vue
@@ -5,15 +5,30 @@
{{ $t('pageLogin.alert.message') }}
</p>
</alert>
- <b-form-group label-for="language" :label="$t('pageLogin.language')">
+ <!-- <b-form-group label-for="language" :label="$t('pageLogin.language')">
<b-form-select
id="language"
v-model="$i18n.locale"
:options="languages"
data-test-id="login-select-language"
></b-form-select>
- </b-form-group>
- <b-form-group label-for="username" :label="$t('pageLogin.username')">
+ </b-form-group> -->
+ <b-form-group
+ class="bold-24px"
+ label-for="auth"
+ :label="$t('pageLogin.auth')"
+ ></b-form-group>
+
+ <b-form-group
+ label-for="auth"
+ class="auth-description"
+ :label="$t('pageLogin.authDescription')"
+ ></b-form-group>
+
+ <b-form-group>
+ <label class="regular-12px tretiatry" for="username">{{
+ $t('pageLogin.username')
+ }}</label>
<b-form-input
id="username"
v-model="userInfo.username"
@@ -22,6 +37,7 @@
type="text"
autofocus="autofocus"
data-test-id="login-input-username"
+ class="form-control-with-button username-input"
@input="$v.userInfo.username.$touch()"
>
</b-form-input>
@@ -31,9 +47,12 @@
</template>
</b-form-invalid-feedback>
</b-form-group>
- <div class="login-form__section mb-3">
- <label for="password">{{ $t('pageLogin.password') }}</label>
+
+ <b-form-group>
<input-password-toggle>
+ <label class="regular-12px tretiatry" for="password">{{
+ $t('pageLogin.password')
+ }}</label>
<b-form-input
id="password"
v-model="userInfo.password"
@@ -41,19 +60,20 @@
:state="getValidationState($v.userInfo.password)"
type="password"
data-test-id="login-input-password"
- class="form-control-with-button"
+ class="form-control-with-button password-input"
@input="$v.userInfo.password.$touch()"
>
</b-form-input>
+ <b-form-invalid-feedback id="password-required" role="alert">
+ <template v-if="!$v.userInfo.password.required">
+ {{ $t('global.form.fieldRequired') }}
+ </template>
+ </b-form-invalid-feedback>
</input-password-toggle>
- <b-form-invalid-feedback id="password-required" role="alert">
- <template v-if="!$v.userInfo.password.required">
- {{ $t('global.form.fieldRequired') }}
- </template>
- </b-form-invalid-feedback>
- </div>
+ </b-form-group>
+
<b-button
- class="mt-3"
+ class="login-button"
type="submit"
variant="primary"
data-test-id="login-button-submit"
@@ -83,6 +103,10 @@ export default {
disableSubmitButton: false,
languages: [
{
+ value: 'ru-RU',
+ text: 'Русский',
+ },
+ {
value: 'en-US',
text: 'English',
},
@@ -90,10 +114,6 @@ export default {
value: 'es',
text: 'Español',
},
- {
- value: 'ru-RU',
- text: 'Русский',
- },
],
};
},
@@ -144,3 +164,35 @@ export default {
},
};
</script>
+<style scoped>
+.regular-12px {
+ margin-left: 10px;
+}
+.username-input,
+.password-input {
+ height: 56px;
+ margin: -30px 0 0 0;
+ padding-top: 30px;
+ font-family: 'Inter', sans-serif;
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 20px;
+ letter-spacing: 0em;
+}
+
+.text-input {
+ margin: 0 0 0 50px;
+ padding: 0 0 0 5px;
+}
+
+.login-button {
+ height: 36px;
+ width: 380px;
+}
+
+@media (max-width: 576px) {
+ .login-button {
+ width: 100%;
+ }
+}
+</style>
diff --git a/src/views/_sila/Login/index.js b/src/views/_sila/Login/index.js
index 8fe0250d..3eac6cc0 100644
--- a/src/views/_sila/Login/index.js
+++ b/src/views/_sila/Login/index.js
@@ -1,2 +1 @@
-import Login from './Login.vue';
-export default Login;
+export { default } from './Login.vue';
diff --git a/src/views/_sila/Logs/Dumps/DumpsForm.vue b/src/views/_sila/Logs/Dumps/DumpsForm.vue
index acd755c7..07f4a060 100644
--- a/src/views/_sila/Logs/Dumps/DumpsForm.vue
+++ b/src/views/_sila/Logs/Dumps/DumpsForm.vue
@@ -35,9 +35,9 @@
<script>
import { required } from 'vuelidate/lib/validators';
import ModalConfirmation from './DumpsModalConfirmation';
-import Alert from '@/components/_sila/Global/Alert';
-import BVToastMixin from '@/components/_sila/Mixins/BVToastMixin';
-import VuelidateMixin from '@/components/_sila/Mixins/VuelidateMixin.js';
+import Alert from '@/components/Global/Alert';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
export default {
components: { Alert, ModalConfirmation },
diff --git a/src/views/_sila/Logs/Dumps/DumpsModalConfirmation.vue b/src/views/_sila/Logs/Dumps/DumpsModalConfirmation.vue
index 49ef960e..f8e20cfd 100644
--- a/src/views/_sila/Logs/Dumps/DumpsModalConfirmation.vue
+++ b/src/views/_sila/Logs/Dumps/DumpsModalConfirmation.vue
@@ -38,8 +38,8 @@
</template>
<script>
-import StatusIcon from '@/components/_sila/Global/StatusIcon';
-import VuelidateMixin from '@/components/_sila/Mixins/VuelidateMixin.js';
+import StatusIcon from '@/components/Global/StatusIcon';
+import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
export default {
components: { StatusIcon },
diff --git a/src/views/_sila/Logs/EventLogs/EventLogs.vue b/src/views/_sila/Logs/EventLogs/EventLogs.vue
index adaa2e9e..dda42c6c 100644
--- a/src/views/_sila/Logs/EventLogs/EventLogs.vue
+++ b/src/views/_sila/Logs/EventLogs/EventLogs.vue
@@ -1,63 +1,93 @@
<template>
- <b-container fluid="xl">
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ class="logs-section"
+ >
<page-title />
+ <div class="logs-head-container">
+ <table-cell-count
+ :filtered-items-count="filteredRows"
+ :total-number-of-cells="allLogs.length"
+ ></table-cell-count>
+ <search
+ :placeholder="$t('pageEventLogs.table.searchLogs')"
+ data-test-id="eventLogs-input-searchLogs"
+ style="margin: 13px; width: 35%"
+ @change-search="onChangeSearchInput"
+ @clear-search="onClearSearchInput"
+ />
+ </div>
<b-row class="align-items-start">
- <b-col sm="8" xl="6" class="d-sm-flex align-items-end mb-4">
- <search
- :placeholder="$t('pageEventLogs.table.searchLogs')"
- data-test-id="eventLogs-input-searchLogs"
- @change-search="onChangeSearchInput"
- @clear-search="onClearSearchInput"
- />
- <div class="ml-sm-4">
- <table-cell-count
- :filtered-items-count="filteredRows"
- :total-number-of-cells="allLogs.length"
- ></table-cell-count>
- </div>
- </b-col>
- <b-col sm="8" md="7" xl="6">
+ <b-col md="12" xl="6">
<table-date-filter @change="onChangeDateTimeFilter" />
</b-col>
- </b-row>
- <b-row>
- <b-col class="text-right">
+ <b-col
+ md="12"
+ xl="6"
+ class="d-flex align-items-end justify-content-between mt-3"
+ >
<table-filter :filters="tableFilters" @filter-change="onFilterChange" />
- <b-button
- variant="link"
- :disabled="allLogs.length === 0"
- @click="deleteAllLogs"
+ <popover-with-slot
+ id="popover-delete"
+ :button-label="$t('pageEventLogs.clear')"
+ :popup-label="$t('pageEventLogs.clearLogs_popup')"
+ placement="left"
+ :action="deleteAllLogs"
>
- <icon-delete /> {{ $t('global.action.deleteAll') }}
- </b-button>
+ <b-button
+ id="popover-delete"
+ ref="button"
+ variant="link"
+ style="color: $red-brand-primary"
+ :disabled="allLogs.length === 0"
+ >
+ <icon-delete /> {{ $t('pageEventLogs.clearLogs') }}
+ </b-button>
+ </popover-with-slot>
<b-button
variant="primary"
+ size="md"
:class="{ disabled: allLogs.length === 0 }"
:download="exportFileNameByDate()"
:href="href"
>
- <icon-export /> {{ $t('global.action.exportAll') }}
+ <icon-download /> {{ $t('global.action.exportAll') }}
</b-button>
</b-col>
</b-row>
<b-row>
- <b-col>
+ <b-col id="logs-table-wrapper" class="m-0 p-0">
<table-toolbar
ref="toolbar"
:selected-items-count="selectedRows.length"
:actions="batchActions"
@clear-selected="clearSelectedRows($refs.table)"
- @batch-action="onBatchAction"
>
<template #toolbar-buttons>
- <b-button variant="primary" @click="resolveLogs">
+ <b-button
+ size="md"
+ variant="secondary"
+ style="margin-right: 1rem"
+ @click="resolveLogs"
+ >
+ <img
+ class="sourse__img"
+ src="@/assets/images/_sila/event-logs/resolved-button.svg"
+ />
{{ $t('pageEventLogs.resolve') }}
</b-button>
- <b-button variant="primary" @click="unresolveLogs">
+ <b-button
+ size="md"
+ variant="primary"
+ style="margin-right: 1rem"
+ @click="unresolveLogs"
+ >
{{ $t('pageEventLogs.unresolve') }}
</b-button>
<table-toolbar-export
:data="batchExportData"
+ style="margin-right: 1rem"
:file-name="exportFileNameByDate()"
/>
</template>
@@ -66,6 +96,7 @@
id="table-event-logs"
ref="table"
responsive="md"
+ class="logs-table"
selectable
no-select-on-click
sort-icon-left
@@ -73,7 +104,9 @@
no-sort-reset
sort-desc
show-empty
+ no-border-collapse
sort-by="id"
+ :sticky-header="true"
:fields="fields"
:items="filteredLogs"
:sort-compare="onSortCompare"
@@ -106,126 +139,123 @@
<span class="sr-only">{{ $t('global.table.selectItem') }}</span>
</b-form-checkbox>
</template>
-
- <!-- Expand chevron icon -->
- <template #cell(expandRow)="row">
- <b-button
- variant="link"
- :aria-label="expandRowLabel"
- :title="expandRowLabel"
- class="btn-icon-only"
- @click="toggleRowDetails(row)"
+ <!-- Description column -->
+ <template #cell(description)="data">
+ <b-row class="semi-bold-16px tretiatry">
+ {{ filteredLogs[data.index].name }}
+ </b-row>
+ <b-row
+ class="regular-12px tretiatry pointer"
+ @click="toggleRowDetails(data)"
>
- <icon-chevron />
- </b-button>
+ {{ data.value }}
+ </b-row>
</template>
<template #row-details="{ item }">
- <b-container fluid>
+ <b-container
+ fluid
+ style="border-bottom: 1px solid rgba(26, 62, 91, 0.1)"
+ >
<b-row>
- <b-col>
+ <b-col class="mt-1">
<dl>
<!-- Name -->
- <dt>{{ $t('pageEventLogs.table.name') }}:</dt>
- <dd>{{ dataFormatter(item.name) }}</dd>
+ <dt class="semi-bold-12px">
+ {{ $t('pageEventLogs.table.name') }}:
+ </dt>
+ <dd class="regular-12px">{{ dataFormatter(item.name) }}</dd>
</dl>
<dl>
- <!-- Type -->
- <dt>{{ $t('pageEventLogs.table.type') }}:</dt>
- <dd>{{ dataFormatter(item.type) }}</dd>
+ <!-- Description -->
+ <dt class="semi-bold-12px">
+ {{ $t('pageEventLogs.table.description') }}:
+ </dt>
+ <dd class="regular-12px tretiatry">
+ {{ dataFormatter(item.description) }}
+ </dd>
</dl>
- </b-col>
- <b-col>
<dl>
- <!-- Modified date -->
- <dt>{{ $t('pageEventLogs.table.modifiedDate') }}:</dt>
- <dd v-if="item.modifiedDate">
- {{ item.modifiedDate | formatDate }}
- {{ item.modifiedDate | formatTime }}
+ <!-- Type -->
+ <dt class="semi-bold-12px">
+ {{ $t('pageEventLogs.table.type') }}:
+ </dt>
+ <dd class="regular-12px tretiatry">
+ {{ dataFormatter(item.type) }}
</dd>
- <dd v-else>--</dd>
</dl>
</b-col>
- <b-col class="text-nowrap">
- <b-button
- class="btn btn-secondary float-right"
- :href="item.additionalDataUri"
- target="_blank"
- >
- <icon-download />{{ $t('pageEventLogs.additionalDataUri') }}
- </b-button>
- </b-col>
</b-row>
</b-container>
</template>
<!-- Severity column -->
<template #cell(severity)="{ value }">
- <status-icon v-if="value" :status="statusIcon(value)" />
- {{ value }}
+ <span
+ :class="`indicators-${value}`"
+ class="bold-12px__caps"
+ style="text-overflow: ellipsis; white-space: nowrap"
+ >
+ {{ value }}</span
+ >
</template>
<!-- Date column -->
<template #cell(date)="{ value }">
- <p class="mb-0">{{ value | formatDate }}</p>
- <p class="mb-0">{{ value | formatTime }}</p>
+ <img
+ src="@/assets/images/_sila/event-logs/time.svg"
+ class="sourse__img"
+ />
+ <span v-if="value" class="regular-12px quaternary">
+ {{ value | formatDate }}
+ </span>
+ <span v-if="value" class="regular-12px quaternary">
+ в {{ value | formatTimeShort }}
+ </span>
</template>
<!-- Status column -->
- <template #cell(status)="row">
- <b-form-checkbox
- v-model="row.item.status"
- name="switch"
- switch
- @change="changelogStatus(row.item)"
- >
- <span v-if="row.item.status">
+ <template #cell(status)="{ value }">
+ <b-row v-if="value === true">
+ <img
+ class="sourse__img"
+ src="@/assets/images/_sila/event-logs/resolved.svg"
+ />
+ <span class="semi-bold-12px__caps resolved">
{{ $t('pageEventLogs.resolved') }}
</span>
- <span v-else> {{ $t('pageEventLogs.unresolved') }} </span>
- </b-form-checkbox>
- </template>
- <template #cell(filterByStatus)="{ value }">
- {{ value }}
- </template>
-
- <!-- Actions column -->
- <template #cell(actions)="row">
- <table-row-action
- v-for="(action, index) in row.item.actions"
- :key="index"
- :value="action.value"
- :title="action.title"
- :row-data="row.item"
- :export-name="exportFileNameByDate('export')"
- :data-test-id="`eventLogs-button-deleteRow-${row.index}`"
- @click-table-action="onTableRowAction($event, row.item)"
- >
- <template #icon>
- <icon-export v-if="action.value === 'export'" />
- <icon-trashcan v-if="action.value === 'delete'" />
- </template>
- </table-row-action>
+ </b-row>
+ <b-row v-else>
+ <img
+ class="sourse__img"
+ src="@/assets/images/_sila/event-logs/not-resolved.svg"
+ />
+ <span class="semi-bold-12px__caps not-resolved">
+ {{ $t('pageEventLogs.unresolved') }}</span
+ >
+ </b-row>
</template>
</b-table>
</b-col>
</b-row>
-
<!-- Table pagination -->
- <b-row>
- <b-col sm="6">
+ <b-row class="logs-pagination-container">
+ <b-col sm="6" class="d-flex align-items-center justify-content-start">
<b-form-group
class="table-pagination-select"
:label="$t('global.table.itemsPerPage')"
- label-for="pagination-items-per-page"
+ label-class="semi-bold-16px mb-0"
+ label-for="pagination"
>
<b-form-select
- id="pagination-items-per-page"
+ id="pagination"
v-model="perPage"
+ class="select-per-page semi-bold-16px mb-0"
:options="itemsPerPageOptions"
/>
</b-form-group>
</b-col>
- <b-col sm="6">
+ <b-col sm="6" class="d-flex align-items-center justify-content-end">
+ <span class="semi-bold-16px"> Страницы </span>
<b-pagination
v-model="currentPage"
first-number
@@ -241,21 +271,17 @@
<script>
import IconDelete from '@carbon/icons-vue/es/trash-can/20';
-import IconTrashcan from '@carbon/icons-vue/es/trash-can/20';
-import IconExport from '@carbon/icons-vue/es/document--export/20';
-import IconChevron from '@carbon/icons-vue/es/chevron--down/20';
import IconDownload from '@carbon/icons-vue/es/download/20';
import { omit } from 'lodash';
import PageTitle from '@/components/_sila/Global/PageTitle';
-import StatusIcon from '@/components/_sila/Global/StatusIcon';
import Search from '@/components/_sila/Global/Search';
import TableCellCount from '@/components/_sila/Global/TableCellCount';
import TableDateFilter from '@/components/_sila/Global/TableDateFilter';
import TableFilter from '@/components/_sila/Global/TableFilter';
-import TableRowAction from '@/components/_sila/Global/TableRowAction';
import TableToolbar from '@/components/_sila/Global/TableToolbar';
import TableToolbarExport from '@/components/_sila/Global/TableToolbarExport';
+import PopoverWithSlot from '@/components/_sila/Global/SilaComponents/PopoverWithSlot';
import LoadingBarMixin from '@/components/_sila/Mixins/LoadingBarMixin';
import TableFilterMixin from '@/components/_sila/Mixins/TableFilterMixin';
@@ -282,19 +308,15 @@ import SearchFilterMixin, {
export default {
components: {
IconDelete,
- IconExport,
- IconTrashcan,
- IconChevron,
IconDownload,
PageTitle,
Search,
- StatusIcon,
TableCellCount,
TableFilter,
- TableRowAction,
TableToolbar,
TableToolbarExport,
TableDateFilter,
+ PopoverWithSlot,
},
mixins: [
BVPaginationMixin,
@@ -316,47 +338,52 @@ export default {
data() {
return {
isBusy: true,
+ sortDesc: true,
fields: [
{
- key: 'expandRow',
- label: '',
- tdClass: 'table-row-expand',
- },
- {
key: 'checkbox',
sortable: false,
+ thClass: ' logs-table__th',
+ tdClass: 'logs-table__td',
},
{
key: 'id',
label: this.$t('pageEventLogs.table.id'),
sortable: true,
+ thClass: 'bold-12px__caps logs-table__th',
+ tdClass: 'semi-bold-12px logs-table__td',
+ },
+ {
+ key: 'description',
+ label: this.$t('pageEventLogs.table.about_event'),
+ thClass: 'bold-12px__caps logs-table__th',
+ tdClass: 'logs-table__td',
},
{
key: 'severity',
label: this.$t('pageEventLogs.table.severity'),
- sortable: true,
- tdClass: 'text-nowrap',
+ thClass: 'bold-12px__caps logs-table__th',
+ tdClass: 'logs-table__td',
+ },
+ {
+ key: 'source',
+ label: this.$t('pageEventLogs.table.source'),
+ thClass: 'bold-12px__caps logs-table__th',
+ tdClass: 'logs-table__td semi-bold-12px__caps tretiatry ',
},
{
key: 'date',
label: this.$t('pageEventLogs.table.date'),
sortable: true,
- tdClass: 'text-nowrap',
- },
- {
- key: 'description',
- label: this.$t('pageEventLogs.table.description'),
- tdClass: 'text-break',
+ thClass: `bold-12px__caps logs-table__th`,
+ tdClass: 'logs-table__td',
},
{
key: 'status',
+ sortable: true,
label: this.$t('pageEventLogs.table.status'),
- },
- {
- key: 'actions',
- sortable: false,
- label: '',
- tdClass: 'text-right text-nowrap',
+ thClass: 'bold-12px__caps logs-table__th',
+ tdClass: 'logs-table__td',
},
],
tableFilters: [
@@ -431,7 +458,7 @@ export default {
return this.getFilteredTableData(
this.filteredLogsByDate,
this.activeFilters
- );
+ ).filter((el) => el.description);
},
},
created() {
@@ -454,21 +481,10 @@ export default {
.catch(({ message }) => this.errorToast(message));
},
deleteAllLogs() {
- this.$bvModal
- .msgBoxConfirm(this.$t('pageEventLogs.modal.deleteAllMessage'), {
- title: this.$t('pageEventLogs.modal.deleteAllTitle'),
- okTitle: this.$t('global.action.delete'),
- okVariant: 'danger',
- cancelTitle: this.$t('global.action.cancel'),
- })
- .then((deleteConfirmed) => {
- if (deleteConfirmed) {
- this.$store
- .dispatch('eventLog/deleteAllEventLogs', this.allLogs)
- .then((message) => this.successToast(message))
- .catch(({ message }) => this.errorToast(message));
- }
- });
+ this.$store
+ .dispatch('eventLog/deleteAllEventLogs', this.allLogs)
+ .then((message) => this.successToast(message))
+ .catch(({ message }) => this.errorToast(message));
},
deleteLogs(uris) {
this.$store
@@ -602,3 +618,20 @@ export default {
},
};
</script>
+<style lang="scss" scoped>
+.semi-bold-14px {
+ margin: auto 0;
+}
+.row {
+ margin: 0px;
+}
+
+.not-resolved {
+ color: $text-quaternary;
+}
+
+.form-group,
+.b-pagination {
+ margin: 0px !important;
+}
+</style>
diff --git a/src/views/_sila/Logs/PostCodeLogs/PostCodeLogs.vue b/src/views/_sila/Logs/PostCodeLogs/PostCodeLogs.vue
index e05ef639..14359dfb 100644
--- a/src/views/_sila/Logs/PostCodeLogs/PostCodeLogs.vue
+++ b/src/views/_sila/Logs/PostCodeLogs/PostCodeLogs.vue
@@ -1,26 +1,27 @@
<template>
- <b-container fluid="xl">
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ class="logs-section"
+ >
<page-title />
- <b-row class="align-items-start">
- <b-col sm="8" xl="6" class="d-sm-flex align-items-end mb-4">
- <search
- :placeholder="$t('pagePostCodeLogs.table.searchLogs')"
- @change-search="onChangeSearchInput"
- @clear-search="onClearSearchInput"
- />
- <div class="ml-sm-4">
- <table-cell-count
- :filtered-items-count="filteredRows"
- :total-number-of-cells="allLogs.length"
- ></table-cell-count>
- </div>
- </b-col>
- <b-col sm="8" md="7" xl="6">
+ <div class="logs-head-container">
+ <table-cell-count
+ :filtered-items-count="filteredRows"
+ :total-number-of-cells="allLogs.length"
+ ></table-cell-count>
+ <search
+ :placeholder="$t('pagePostCodeLogs.table.searchLogs')"
+ style="margin: 13px; width: 35%"
+ @change-search="onChangeSearchInput"
+ @clear-search="onClearSearchInput"
+ />
+ </div>
+ <b-row class="align-items-start m-0 p-0">
+ <b-col sm="7" md="6" xl="5">
<table-date-filter @change="onChangeDateTimeFilter" />
</b-col>
- </b-row>
- <b-row>
- <b-col xl="12" class="text-right">
+ <b-col class="d-flex justify-content-end mt-3">
<b-button
variant="primary"
:disabled="allLogs.length === 0"
@@ -31,8 +32,8 @@
</b-button>
</b-col>
</b-row>
- <b-row>
- <b-col>
+ <b-row class="m-0 p-0">
+ <b-col class="p-0">
<table-toolbar
ref="toolbar"
:selected-items-count="selectedRows.length"
@@ -40,107 +41,116 @@
>
<template #toolbar-buttons>
<table-toolbar-export
+ style="margin-right: 1rem"
:data="batchExportData"
:file-name="exportFileNameByDate()"
/>
</template>
</table-toolbar>
- <b-table
- id="table-post-code-logs"
- ref="table"
- responsive="md"
- selectable
- no-select-on-click
- sort-icon-left
- hover
- no-sort-reset
- sort-desc
- show-empty
- sort-by="id"
- :fields="fields"
- :items="filteredLogs"
- :empty-text="$t('global.table.emptyMessage')"
- :empty-filtered-text="$t('global.table.emptySearchMessage')"
- :per-page="perPage"
- :current-page="currentPage"
- :filter="searchFilter"
- :busy="isBusy"
- @filtered="onFiltered"
- @row-selected="onRowSelected($event, filteredLogs.length)"
- >
- <!-- Checkbox column -->
- <template #head(checkbox)>
- <b-form-checkbox
- v-model="tableHeaderCheckboxModel"
- data-test-id="postCode-checkbox-selectAll"
- :indeterminate="tableHeaderCheckboxIndeterminate"
- @change="onChangeHeaderCheckbox($refs.table)"
- >
- <span class="sr-only">{{ $t('global.table.selectAll') }}</span>
- </b-form-checkbox>
- </template>
- <template #cell(checkbox)="row">
- <b-form-checkbox
- v-model="row.rowSelected"
- :data-test-id="`postCode-checkbox-selectRow-${row.index}`"
- @change="toggleSelectRow($refs.table, row.index)"
- >
- <span class="sr-only">{{ $t('global.table.selectItem') }}</span>
- </b-form-checkbox>
- </template>
- <!-- Date column -->
- <template #cell(date)="{ value }">
- <p class="mb-0">{{ value | formatDate }}</p>
- <p class="mb-0">{{ value | formatTime }}</p>
- </template>
+ <div id="logs-table-wrapper">
+ <b-table
+ id="logs-table"
+ ref="table"
+ responsive="md"
+ class="logs-table"
+ selectable
+ no-select-on-click
+ sort-icon-left
+ hover
+ no-sort-reset
+ sort-desc
+ show-empty
+ sort-by="id"
+ :no-border-collapse="true"
+ :sticky-header="true"
+ :fields="fields"
+ :items="filteredLogs"
+ :empty-text="$t('global.table.emptyMessage')"
+ :empty-filtered-text="$t('global.table.emptySearchMessage')"
+ :per-page="perPage"
+ :current-page="currentPage"
+ :filter="searchFilter"
+ :busy="isBusy"
+ @filtered="onFiltered"
+ @row-selected="onRowSelected($event, filteredLogs.length)"
+ >
+ <!-- Checkbox column -->
+ <template #head(checkbox)>
+ <b-form-checkbox
+ v-model="tableHeaderCheckboxModel"
+ data-test-id="postCode-checkbox-selectAll"
+ :indeterminate="tableHeaderCheckboxIndeterminate"
+ @change="onChangeHeaderCheckbox($refs.table)"
+ >
+ <span class="sr-only">{{ $t('global.table.selectAll') }}</span>
+ </b-form-checkbox>
+ </template>
+ <template #cell(checkbox)="row">
+ <b-form-checkbox
+ v-model="row.rowSelected"
+ :data-test-id="`postCode-checkbox-selectRow-${row.index}`"
+ @change="toggleSelectRow($refs.table, row.index)"
+ >
+ <span class="sr-only">{{ $t('global.table.selectItem') }}</span>
+ </b-form-checkbox>
+ </template>
+ <!-- Date column -->
+ <template #cell(date)="{ value }">
+ <p class="mb-0">{{ value | formatDate }}</p>
+ <p class="mb-0">{{ value | formatTime }}</p>
+ </template>
- <!-- Actions column -->
- <template #cell(actions)="row">
- <table-row-action
- v-for="(action, index) in row.item.actions"
- :key="index"
- :value="action.value"
- :title="action.title"
- :row-data="row.item"
- :btn-icon-only="true"
- :export-name="exportFileNameByDate(action.value)"
- :download-location="row.item.uri"
- :download-in-new-tab="true"
- :show-button="false"
- >
- <template #icon>
- <icon-export v-if="action.value === 'export'" />
- <icon-download v-if="action.value === 'download'" />
- </template>
- </table-row-action>
- </template>
- </b-table>
+ <!-- Actions column -->
+ <template #cell(actions)="row">
+ <table-row-action
+ v-for="(action, index) in row.item.actions"
+ :key="index"
+ :value="action.value"
+ :title="action.title"
+ :row-data="row.item"
+ :btn-icon-only="true"
+ :export-name="exportFileNameByDate(action.value)"
+ :download-location="row.item.uri"
+ :download-in-new-tab="true"
+ :show-button="false"
+ >
+ <template #icon>
+ <icon-export v-if="action.value === 'export'" />
+ <icon-download v-if="action.value === 'download'" />
+ </template>
+ </table-row-action>
+ </template>
+ </b-table>
+ </div>
</b-col>
</b-row>
<!-- Table pagination -->
- <b-row>
- <b-col sm="6">
+ <b-row class="logs-pagination-container m-0">
+ <b-col sm="6" class="d-flex align-items-center justify-content-start">
<b-form-group
class="table-pagination-select"
:label="$t('global.table.itemsPerPage')"
+ label-class="semi-bold-16px mb-0"
label-for="pagination-items-per-page"
>
<b-form-select
id="pagination-items-per-page"
v-model="perPage"
+ class="select-per-page semi-bold-16px mb-0"
:options="itemsPerPageOptions"
/>
</b-form-group>
</b-col>
- <b-col sm="6">
+ <b-col sm="6" class="d-flex align-items-center justify-content-end">
+ <span class="semi-bold-16px"> Страницы </span>
<b-pagination
v-model="currentPage"
first-number
last-number
:per-page="perPage"
:total-rows="getTotalRowCount(filteredRows)"
- aria-controls="table-post-code-logs"
+ aria-controls="table-event-logs"
/>
</b-col>
</b-row>
@@ -151,33 +161,33 @@
import IconDownload from '@carbon/icons-vue/es/download/20';
import IconExport from '@carbon/icons-vue/es/document--export/20';
import { omit } from 'lodash';
-import PageTitle from '@/components/_sila/Global/PageTitle';
-import Search from '@/components/_sila/Global/Search';
-import TableCellCount from '@/components/_sila/Global/TableCellCount';
-import TableDateFilter from '@/components/_sila/Global/TableDateFilter';
-import TableRowAction from '@/components/_sila/Global/TableRowAction';
-import TableToolbar from '@/components/_sila/Global/TableToolbar';
-import TableToolbarExport from '@/components/_sila/Global/TableToolbarExport';
-import LoadingBarMixin from '@/components/_sila/Mixins/LoadingBarMixin';
-import TableFilterMixin from '@/components/_sila/Mixins/TableFilterMixin';
+import PageTitle from '@/components/Global/PageTitle';
+import Search from '@/components/Global/Search';
+import TableCellCount from '@/components/Global/TableCellCount';
+import TableDateFilter from '@/components/Global/TableDateFilter';
+import TableRowAction from '@/components/Global/TableRowAction';
+import TableToolbar from '@/components/Global/TableToolbar';
+import TableToolbarExport from '@/components/Global/TableToolbarExport';
+import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
+import TableFilterMixin from '@/components/Mixins/TableFilterMixin';
import BVPaginationMixin, {
currentPage,
perPage,
itemsPerPageOptions,
-} from '@/components/_sila/Mixins/BVPaginationMixin';
+} from '@/components/Mixins/BVPaginationMixin';
import BVTableSelectableMixin, {
selectedRows,
tableHeaderCheckboxModel,
tableHeaderCheckboxIndeterminate,
-} from '@/components/_sila/Mixins/BVTableSelectableMixin';
-import BVToastMixin from '@/components/_sila/Mixins/BVToastMixin';
-import TableSortMixin from '@/components/_sila/Mixins/TableSortMixin';
+} from '@/components/Mixins/BVTableSelectableMixin';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import TableSortMixin from '@/components/Mixins/TableSortMixin';
import TableRowExpandMixin, {
expandRowLabel,
-} from '@/components/_sila/Mixins/TableRowExpandMixin';
+} from '@/components/Mixins/TableRowExpandMixin';
import SearchFilterMixin, {
searchFilter,
-} from '@/components/_sila/Mixins/SearchFilterMixin';
+} from '@/components/Mixins/SearchFilterMixin';
export default {
components: {
@@ -210,32 +220,44 @@ export default {
data() {
return {
isBusy: true,
+ // stickyHeader: 'calc(100vh - 307px)',
fields: [
{
key: 'checkbox',
sortable: false,
+ thClass: ' logs-table__th',
+ tdClass: 'logs-table__td',
},
{
key: 'date',
label: this.$t('pagePostCodeLogs.table.created'),
sortable: true,
+ thClass: 'bold-12px__caps logs-table__th',
+ tdClass: 'semi-bold-12px logs-table__td',
},
{
key: 'timeStampOffset',
label: this.$t('pagePostCodeLogs.table.timeStampOffset'),
+ thClass: 'bold-12px__caps logs-table__th',
+ tdClass: 'logs-table__td',
},
{
key: 'bootCount',
label: this.$t('pagePostCodeLogs.table.bootCount'),
+ thClass: 'bold-12px__caps logs-table__th',
+ tdClass: 'logs-table__td',
},
{
key: 'postCode',
label: this.$t('pagePostCodeLogs.table.postCode'),
+ thClass: 'bold-12px__caps logs-table__th',
+ tdClass: 'logs-table__td semi-bold-12px__caps',
},
{
key: 'actions',
label: '',
- tdClass: 'text-right text-nowrap',
+ thClass: 'bold-12px__caps logs-table__th',
+ tdClass: 'text-right logs-table__td',
},
],
expandRowLabel,
@@ -345,3 +367,17 @@ export default {
},
};
</script>
+<style lang="scss" scoped>
+.form-group,
+.b-pagination {
+ margin: 0px !important;
+}
+.items-per-page {
+ padding: 0 0 0 5px;
+ width: 55px;
+ height: 24px;
+ background-color: transparent;
+ border: 1px solid $on-surface-tretiatry;
+ border-radius: 4px;
+}
+</style>
diff --git a/src/views/_sila/MemoryModules/DynamicInfo/MemoryDynamicPage.vue b/src/views/_sila/MemoryModules/DynamicInfo/MemoryDynamicPage.vue
new file mode 100644
index 00000000..489784e2
--- /dev/null
+++ b/src/views/_sila/MemoryModules/DynamicInfo/MemoryDynamicPage.vue
@@ -0,0 +1,224 @@
+<template>
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title :description="$t('appNavigation.analyticalPanel')" />
+ <div class="notification__container">
+ <span class="semi-bold-12px">{{
+ $t('global.ariaLabel.notificationTime')
+ }}</span>
+ <div class="form-control notification">
+ <b-form-input
+ v-model="notificationInput"
+ type="number"
+ class="notification__input"
+ >
+ </b-form-input>
+ <button class="notification_button">
+ <img class="notification__icon" src="@/assets/images/refresh.svg" />
+ </button>
+ </div>
+ </div>
+ <date-switch :switch-time-scale="switchTimeScale" :time-scale="timeScale" />
+ <div class="limit-container">
+ <div class="trmperature-limt">
+ <img src="@/assets/images/labels/non-normal.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.nonNormalMode')
+ }}</span>
+ <b-form-input
+ v-model="temperatureNonNormalInput"
+ type="number"
+ :min="0"
+ :max="temperatureCritical"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <div class="trmperature-limt">
+ <img src="@/assets/images/labels/critical.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.criticalMode')
+ }}</span>
+ <b-form-input
+ v-model="temperatureCritical"
+ type="number"
+ :min="temperatureNonNormalInput"
+ :max="temperatureWarningInput"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <div class="trmperature-limt">
+ <img src="@/assets/images/labels/warning.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.temperatureWarning')
+ }}</span>
+ <b-form-input
+ v-model="temperatureWarningInput"
+ type="number"
+ :min="temperatureCritical"
+ :max="100"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <b-button
+ class="save-button"
+ variant="primary"
+ @click="updateTemperatureLimits"
+ >
+ {{ $t('global.action.save') }}
+ </b-button>
+ </div>
+ <!-- Temperature Table -->
+ <temperature-table
+ :time-scale="timeScale"
+ :warning="temperatureWarning"
+ :non-normal="temperatureNonNormal"
+ :critical-start="temperatureCriticalStart"
+ />
+ <accessory-table :records="accessoryData.temperatureTable" />
+ </b-container>
+</template>
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import DateSwitch from '@/components/Global/SilaComponents/DateSwitch';
+import TemperatureTable from './TemperatureTable';
+import AccessoryTable from '@/components/Global/SilaComponents/Tables/AccessoryTableWithLabel';
+import iconChevronUp from '@carbon/icons-vue/es/chevron--up/16';
+
+import TableFilterMixin from '@/components/Mixins/TableFilterMixin';
+import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
+
+import { AccessoryData } from './helpers';
+
+export default {
+ components: {
+ PageTitle,
+ DateSwitch,
+ TemperatureTable,
+ AccessoryTable,
+ },
+ mixins: [TableFilterMixin, LoadingBarMixin],
+ data() {
+ return {
+ isBusy: true,
+ timeScale: 'hour',
+ temperatureWarning: 72,
+ temperatureWarningInput: 72,
+ temperatureNonNormal: 44,
+ temperatureNonNormalInput: 44,
+ temperatureCriticalStart: 55,
+ temperatureCritical: 55,
+ notificationInput: 42,
+ accessoryData: AccessoryData,
+ iconChevronUp: iconChevronUp,
+ activeFilters: [],
+ };
+ },
+ computed: {
+ allSensors() {
+ let sensors = this.$store.getters['sensors/memorySensors'];
+ return sensors;
+ },
+ },
+ created() {
+ this.startLoader();
+ this.$store.dispatch('sensors/getMemorySensors').finally(() => {
+ this.endLoader();
+ this.accessoryData.temperatureTable.items = this.getFilteredTableData(
+ this.allSensors,
+ this.activeFilters
+ );
+ this.isBusy = false;
+ });
+ },
+ methods: {
+ switchTimeScale(period) {
+ this.timeScale = period;
+ },
+ updateTemperatureLimits() {
+ this.temperatureWarning = +this.temperatureWarningInput;
+ this.temperatureNonNormal = +this.temperatureNonNormalInput;
+ this.temperatureCriticalStart = +this.temperatureCritical;
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+.notification__container {
+ position: absolute;
+ top: calc(#{$header-height});
+ right: 0px;
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: flex-start;
+ align-items: center;
+}
+
+.notification {
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: flex-start;
+ align-items: center;
+ border: none;
+ box-shadow: none;
+ border-radius: 8px;
+ margin: 12px 32px 12px 8px;
+ width: 236px;
+ height: 40px;
+ z-index: 1001;
+}
+
+.notification__icon {
+ width: 20px;
+ height: 20px;
+}
+
+.notification__input {
+ border: none;
+ background: none;
+ box-shadow: none;
+}
+
+.notification_button {
+ border: none;
+ background: none;
+}
+
+.semi-bold-12px {
+ z-index: 1001;
+}
+
+// temperature limit comtainer
+.limit-container {
+ height: 85px;
+ width: 100%;
+ padding: 0 32px 10px 32px;
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: flex-start;
+ align-items: flex-end;
+ gap: 24px;
+}
+
+.trmperature-limt {
+ height: 60px;
+ width: 100%;
+ max-width: 270px;
+ display: flex;
+ align-items: baseline;
+ flex-flow: row wrap;
+ gap: 8px;
+}
+
+.form-control {
+ height: 36px;
+}
+.save-button {
+ width: 151px;
+ height: 36px;
+}
+</style>
diff --git a/src/views/_sila/MemoryModules/DynamicInfo/TemperatureTable.vue b/src/views/_sila/MemoryModules/DynamicInfo/TemperatureTable.vue
new file mode 100644
index 00000000..f9c149c3
--- /dev/null
+++ b/src/views/_sila/MemoryModules/DynamicInfo/TemperatureTable.vue
@@ -0,0 +1,126 @@
+<template>
+ <div>
+ <highcharts :options="chartOptions.line" />
+ </div>
+</template>
+
+<script>
+import { setTime, Series, setCategories } from './helpers';
+import { Chart } from 'highcharts-vue';
+
+export default {
+ components: {
+ highcharts: Chart,
+ },
+ props: {
+ timeScale: {
+ type: String,
+ default: 'hour',
+ },
+ warning: {
+ type: Number,
+ default: 70,
+ },
+ nonNormal: {
+ type: Number,
+ default: 70,
+ },
+ criticalStart: {
+ type: Number,
+ default: 70,
+ },
+ },
+ computed: {
+ chartOptions() {
+ return {
+ line: {
+ chart: {
+ type: 'line',
+ margin: [12, 50, 32, 60],
+ height: '320px',
+ },
+ title: null,
+ xAxis: {
+ categories: setTime(60, 'hour'),
+ title: null,
+ labels: {
+ step: 6,
+ },
+ minorGridLineColor: '#1A3E5B1A',
+ },
+ yAxis: {
+ categories: setCategories(101, 'С°'),
+ min: 0,
+ max: 100,
+ title: null,
+ minTickInterval: 25,
+ minorGridLineColor: '#1A3E5B1A',
+ plotLines: [
+ {
+ color: '#E11717',
+ dashStyle: 'solid',
+ value: this.warning,
+ zIndex: '1000',
+ width: 2,
+ label: {
+ text: 'Пороговое значение предупреждения, С°',
+ align: 'right',
+ style: {
+ fontFamily: 'Inter, sans-serif',
+ fontSize: '12px',
+ fontStyle: 'normal',
+ fontWeight: '400',
+ lineHeight: '16px',
+ color: '#0C1C2999',
+ },
+ },
+ },
+ ],
+ plotBands: [
+ {
+ color: '#F0AC0C1A',
+ dashStyle: 'solid',
+ from: this.nonNormal,
+ to: this.criticalStart,
+ },
+ {
+ color: '#FF41411A',
+ dashStyle: 'solid',
+ from: this.criticalStart,
+ to: this.warning,
+ },
+ ],
+ },
+ series: Series['temperature'].map((item) => ({
+ ...item,
+ marker: {
+ enabled: false,
+ },
+ })),
+ legend: {
+ enabled: false,
+ },
+ tooltip: {
+ enabled: false,
+ crosshairs: false,
+ },
+ plotOptions: {
+ series: {
+ showInLegend: true,
+ },
+ },
+ },
+ };
+ },
+ },
+};
+</script>
+<style lang="scss">
+.highcharts-credits {
+ display: none;
+}
+
+.highcharts-plot-line-label {
+ transform: translate(-15px, 0) !important;
+}
+</style>
diff --git a/src/views/_sila/MemoryModules/DynamicInfo/helpers.js b/src/views/_sila/MemoryModules/DynamicInfo/helpers.js
new file mode 100644
index 00000000..3cbca867
--- /dev/null
+++ b/src/views/_sila/MemoryModules/DynamicInfo/helpers.js
@@ -0,0 +1,458 @@
+export const colors = [
+ '#CB32F1',
+ '#F18638',
+ '#139BB9',
+ '#E1AB17',
+ '#175AE1',
+ '#13B937',
+];
+
+export const Series = {
+ temperature: [
+ {
+ name: 'Sean',
+ data: [
+ 15,
+ 15,
+ 45,
+ 15,
+ 65,
+ 15,
+ 75,
+ 15,
+ 15,
+ 15,
+ 55,
+ 15,
+ 25,
+ 15,
+ 45,
+ 15,
+ 55,
+ 15,
+ 75,
+ 15,
+ 35,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 65,
+ 15,
+ 45,
+ 15,
+ 25,
+ 15,
+ 45,
+ 15,
+ 65,
+ 15,
+ 35,
+ 35,
+ 35,
+ 15,
+ 55,
+ 15,
+ 15,
+ 35,
+ 15,
+ 25,
+ 15,
+ 35,
+ 15,
+ ],
+ color: '#CB32F1',
+ },
+ {
+ name: 'Ivan',
+ data: [
+ 62,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 22,
+ 12,
+ 42,
+ 12,
+ 52,
+ 12,
+ 72,
+ 12,
+ 52,
+ 12,
+ 62,
+ 12,
+ 72,
+ 12,
+ 82,
+ 12,
+ 12,
+ 42,
+ 12,
+ 12,
+ 52,
+ 12,
+ 42,
+ 12,
+ 12,
+ 62,
+ 12,
+ 42,
+ 12,
+ 22,
+ 12,
+ 42,
+ 12,
+ 62,
+ 12,
+ 12,
+ 32,
+ 12,
+ 62,
+ 12,
+ 52,
+ 12,
+ 32,
+ 12,
+ 22,
+ 12,
+ 32,
+ 12,
+ ],
+ color: '#175AE1',
+ },
+ {
+ name: 'Brendan',
+ data: [
+ 13,
+ 13,
+ 33,
+ 13,
+ 23,
+ 13,
+ 33,
+ 13,
+ 63,
+ 13,
+ 63,
+ 13,
+ 13,
+ 13,
+ 43,
+ 13,
+ 13,
+ 13,
+ 53,
+ 13,
+ 23,
+ 13,
+ 43,
+ 13,
+ 53,
+ 13,
+ 63,
+ 13,
+ 53,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 53,
+ 13,
+ 43,
+ 13,
+ 13,
+ 63,
+ 13,
+ 43,
+ 13,
+ 23,
+ 13,
+ 43,
+ 13,
+ 63,
+ 13,
+ 13,
+ 13,
+ 53,
+ 13,
+ 53,
+ ],
+ color: '#B98D13',
+ },
+ {
+ name: 'Matteo',
+ data: [
+ 24,
+ 14,
+ 44,
+ 14,
+ 64,
+ 14,
+ 64,
+ 14,
+ 34,
+ 14,
+ 54,
+ 14,
+ 14,
+ 34,
+ 14,
+ 24,
+ 14,
+ 34,
+ 14,
+ 64,
+ 14,
+ 64,
+ 14,
+ 14,
+ 14,
+ 44,
+ 14,
+ 14,
+ 14,
+ 54,
+ 14,
+ 14,
+ 14,
+ 44,
+ 14,
+ 54,
+ 14,
+ 14,
+ 14,
+ 54,
+ 14,
+ 64,
+ 14,
+ 14,
+ 14,
+ 84,
+ 14,
+ 94,
+ 14,
+ 54,
+ 4,
+ 54,
+ 14,
+ 44,
+ 14,
+ 44,
+ 64,
+ 14,
+ 44,
+ 14,
+ ],
+ color: '#13B937',
+ },
+ {
+ name: 'Joan',
+ data: [
+ 16,
+ 46,
+ 16,
+ 26,
+ 16,
+ 46,
+ 16,
+ 66,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 56,
+ 16,
+ 16,
+ 36,
+ 16,
+ 26,
+ 16,
+ 36,
+ 16,
+ 66,
+ 16,
+ 76,
+ 16,
+ 16,
+ 16,
+ 46,
+ 16,
+ 16,
+ 16,
+ 56,
+ 16,
+ 26,
+ 16,
+ 46,
+ 16,
+ 56,
+ 16,
+ 76,
+ 16,
+ 56,
+ 16,
+ 66,
+ 16,
+ 76,
+ 16,
+ 16,
+ 16,
+ 96,
+ 16,
+ 16,
+ 16,
+ 56,
+ 16,
+ 46,
+ 16,
+ 46,
+ 16,
+ ],
+ color: '#F18638',
+ },
+ {
+ name: 'Avinash',
+ data: [
+ 49,
+ 19,
+ 19,
+ 69,
+ 19,
+ 49,
+ 19,
+ 29,
+ 19,
+ 49,
+ 19,
+ 69,
+ 19,
+ 39,
+ 39,
+ 39,
+ 19,
+ 59,
+ 19,
+ 19,
+ 39,
+ 19,
+ 29,
+ 19,
+ 39,
+ 19,
+ 69,
+ 19,
+ 69,
+ 19,
+ 19,
+ 19,
+ 49,
+ 19,
+ 19,
+ 19,
+ 59,
+ 19,
+ 29,
+ 19,
+ 49,
+ 19,
+ 59,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ ],
+ color: '#139BB9',
+ },
+ ],
+};
+
+export const setTime = (count) => {
+ const arr = [...new Array(count)].map(() => '');
+ for (let i = 0; i < arr.length; i++) {
+ arr[i] = `15:${String(i).padStart(2, '0')}`;
+ }
+ return arr;
+};
+
+export const setCategories = (count, desc) => {
+ const arr = [...new Array(count)].map((i, k) => `${k} ${desc}`);
+ return arr;
+};
+
+export const AccessoryData = {
+ temperatureTable: {
+ fields: [
+ {
+ key: 'name',
+ label: 'Имя модуля',
+ },
+ {
+ key: 'currentValue',
+ label: 'Текущее, С°',
+ },
+ {
+ key: 'middleTemperature',
+ label: 'Среднее, С°',
+ },
+ {
+ key: 'lowerCaution',
+ label: 'Минимальное, С°',
+ },
+ {
+ key: 'minDate',
+ label: 'Дата минимального',
+ },
+ {
+ key: 'upperCaution',
+ label: 'Максимальное, С°',
+ },
+ {
+ key: 'maxDate',
+ label: 'Дата максимального',
+ },
+ ],
+ items: [],
+ },
+};
diff --git a/src/views/_sila/MemoryModules/DynamicInfo/index.js b/src/views/_sila/MemoryModules/DynamicInfo/index.js
new file mode 100644
index 00000000..b840772c
--- /dev/null
+++ b/src/views/_sila/MemoryModules/DynamicInfo/index.js
@@ -0,0 +1,2 @@
+import MemoryDynamicPage from './MemoryDynamicPage.vue';
+export default MemoryDynamicPage;
diff --git a/src/views/_sila/MemoryModules/Specification/MemoryStaticPage.vue b/src/views/_sila/MemoryModules/Specification/MemoryStaticPage.vue
new file mode 100644
index 00000000..5e544868
--- /dev/null
+++ b/src/views/_sila/MemoryModules/Specification/MemoryStaticPage.vue
@@ -0,0 +1,228 @@
+<template>
+ <b-container
+ id="page-memory-specification"
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title :description="$t('appNavigation.specification')" />
+ <page-section class="bootstrap-table__section info_section">
+ <span class="bold-16px">{{ $t('global.table.info') }}</span>
+ <b-table
+ responsive="md"
+ show-empty
+ no-border-collapse
+ :items="items"
+ :fields="fields"
+ :empty-text="$t('global.table.emptyMessage')"
+ >
+ </b-table>
+ <span class="bold-16px">{{ $t('global.table.memorySlots') }}</span>
+ </page-section>
+ <data-tabs
+ :slots="memorySlots"
+ :switch-tab="switchMemorySlot"
+ :current-tab="currentMemorySlot"
+ :slot-width="120"
+ :slider-width="97"
+ />
+ <page-section class="bootstrap-table__section">
+ <b-table
+ responsive="md"
+ show-empty
+ no-border-collapse
+ :items="items_slots"
+ :fields="fields"
+ :empty-text="$t('global.table.emptyMessage')"
+ >
+ <template #cell(value)="{ index, value }">
+ <b-row v-if="index === 0">
+ <b-col cols="11">
+ <span>
+ {{ 'Работоспособность' }}
+ </span>
+ </b-col>
+ <b-col cols="1">
+ <img src="@/assets/images/status/on.svg" class="icon-chevron" />
+ </b-col>
+ </b-row>
+ <b-row v-else>
+ <b-col>
+ <span>{{ value }}</span>
+ </b-col>
+ </b-row>
+ </template>
+ </b-table>
+ </page-section>
+ <page-section class="bootstrap-table__section">
+ <span class="bold-16px">{{ $t('global.table.memoryModules') }}</span>
+ <b-table
+ responsive="md"
+ show-empty
+ no-border-collapse
+ :items="items_modules"
+ :fields="fields"
+ :empty-text="$t('global.table.emptyMessage')"
+ >
+ <template #cell(value)="{ index, value }">
+ <b-row v-if="index === 0">
+ <b-col cols="11">
+ <span>
+ {{ 'Работоспособность' }}
+ </span>
+ </b-col>
+ <b-col cols="1">
+ <img src="@/assets/images/status/on.svg" class="icon-chevron" />
+ </b-col>
+ </b-row>
+ <b-row v-else>
+ <b-col>
+ <span>{{ value }}</span>
+ </b-col>
+ </b-row>
+ </template>
+ </b-table>
+ </page-section>
+ </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import PageSection from '@/components/Global/PageSection';
+import DataTabs from '@/components/Global/SilaComponents/DataTabs';
+
+export default {
+ components: { PageTitle, PageSection, DataTabs },
+ data() {
+ return {
+ currentMemorySlot: 1,
+ memorySlots: [
+ { id: 1, name: 'CPU_1-DIMM_A1' },
+ { id: 2, name: 'CPU_1-DIMM_A2' },
+ { id: 3, name: 'CPU_1-DIMM_A3' },
+ { id: 4, name: 'CPU_1-DIMM_B1' },
+ { id: 5, name: 'CPU_1-DIMM_B2' },
+ { id: 6, name: 'CPU_1-DIMM_B3' },
+ { id: 7, name: 'CPU_1-DIMM_C1' },
+ { id: 8, name: 'CPU_1-DIMM_C2' },
+ { id: 9, name: 'CPU_1-DIMM_C3' },
+ { id: 10, name: 'CPU_1-DIMM_D1' },
+ { id: 11, name: 'CPU_1-DIMM_D2' },
+ { id: 12, name: 'CPU_1-DIMM_D3' },
+ { id: 13, name: 'CPU_1-DIMM_E1' },
+ { id: 14, name: 'CPU_1-DIMM_E2' },
+ { id: 15, name: 'CPU_1-DIMM_E3' },
+ ],
+ fields: [
+ {
+ key: 'parametr',
+ label: 'Статус',
+ formatter: this.dataFormatter,
+ thStyle: { width: '50%' },
+ },
+ {
+ key: 'value',
+ label: 'Значение',
+ formatter: this.dataFormatter,
+ },
+ ],
+ items: [
+ {
+ parametr: 'Установленный объем памяти',
+ value: '8096 мб',
+ },
+ {
+ parametr: 'Максимальный объем',
+ value: '4048 мб',
+ },
+ {
+ parametr: 'Общее количество слотов',
+ value: '10',
+ },
+ {
+ parametr: 'Используемое количество слотов',
+ value: '10',
+ },
+ ],
+ items_slots: [
+ {
+ parametr: 'Статус',
+ value: true,
+ },
+ {
+ parametr: 'Имя слота',
+ value: 'Cлот 2',
+ },
+ {
+ parametr: 'Технология',
+ value: 'Название технологии',
+ },
+ {
+ parametr: 'Тип памяти',
+ value: 'Оперативная',
+ },
+ {
+ parametr: 'Объем',
+ value: '2024',
+ },
+ {
+ parametr: 'Состояние',
+ value: 'Отлично',
+ },
+ {
+ parametr: 'Класс',
+ value: '1',
+ },
+ {
+ parametr: 'Скорость',
+ value: '2000 МТ/сек',
+ },
+ ],
+ items_modules: [
+ {
+ parametr: 'Статус',
+ value: true,
+ },
+ {
+ parametr: 'Имя коннектора',
+ value: 'DIMM A2',
+ },
+ {
+ parametr: 'Тип памяти',
+ value: 'DDR-4',
+ },
+ {
+ parametr: 'Объем',
+ value: '32 GB',
+ },
+ {
+ parametr: 'Состояние',
+ value: 'Presence Detected',
+ },
+ {
+ parametr: 'Ранг',
+ value: 'Dual Rank',
+ },
+ {
+ parametr: 'Скорость',
+ value: '2400 MHz',
+ },
+ ],
+ };
+ },
+ methods: {
+ switchMemorySlot(period) {
+ this.currentMemorySlot = period;
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+.info_section {
+ margin-bottom: 0px;
+}
+
+.bold-16px {
+ display: block;
+ margin: 25px 0 16px 0;
+}
+</style>
diff --git a/src/views/_sila/MemoryModules/Specification/index.js b/src/views/_sila/MemoryModules/Specification/index.js
new file mode 100644
index 00000000..4916f58a
--- /dev/null
+++ b/src/views/_sila/MemoryModules/Specification/index.js
@@ -0,0 +1,2 @@
+import MemoryStaticPage from './MemoryStaticPage.vue';
+export default MemoryStaticPage;
diff --git a/src/views/_sila/Motherboard/DynamicInfo/MotherboardDynamicPage.vue b/src/views/_sila/Motherboard/DynamicInfo/MotherboardDynamicPage.vue
new file mode 100644
index 00000000..c2c88ab6
--- /dev/null
+++ b/src/views/_sila/Motherboard/DynamicInfo/MotherboardDynamicPage.vue
@@ -0,0 +1,159 @@
+<template>
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title />
+ <date-switch :switch-time-scale="switchTimeScale" :time-scale="timeScale" />
+ <div class="limit-container">
+ <div class="trmperature-limt">
+ <img src="@/assets/images/labels/warning.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.temperatureWarning')
+ }}</span>
+ <b-form-input
+ v-model="temperatureWarningInput"
+ type="number"
+ :min="0"
+ :max="100"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <b-button
+ class="save-button"
+ variant="primary"
+ @click="updateTemperature"
+ >
+ {{ $t('global.action.save') }}
+ </b-button>
+ </div>
+ <!-- Temperature Table -->
+ <temperature-table
+ :time-scale="timeScale"
+ :warning="temperatureWarning"
+ :non-normal="temperatureNonNormal"
+ :critical-start="temperatureCriticalStart"
+ />
+ <accessory-table :records="accessoryData.temperatureTable" />
+ </b-container>
+</template>
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import DateSwitch from '@/components/Global/SilaComponents/DateSwitch';
+import TemperatureTable from './TemperatureTable';
+import AccessoryTable from '@/components/Global/SilaComponents/Tables/AccessoryTableWithLabel';
+import iconChevronUp from '@carbon/icons-vue/es/chevron--up/16';
+
+import TableFilterMixin from '@/components/Mixins/TableFilterMixin';
+import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
+
+import { AccessoryData } from './helpers';
+
+export default {
+ components: {
+ PageTitle,
+ DateSwitch,
+ TemperatureTable,
+ AccessoryTable,
+ },
+ mixins: [TableFilterMixin, LoadingBarMixin],
+ data() {
+ return {
+ isBusy: true,
+ timeScale: 'hour',
+ temperatureWarning: 72,
+ temperatureWarningInput: 72,
+ notificationInput: 42,
+ accessoryData: AccessoryData,
+ iconChevronUp: iconChevronUp,
+ activeFilters: [],
+ };
+ },
+
+ computed: {
+ allSensors() {
+ let sensors = this.$store.getters['sensors/tempSensors'];
+ return sensors;
+ },
+ },
+ created() {
+ this.startLoader();
+ this.$store.dispatch('sensors/getTempSensors').finally(() => {
+ this.endLoader();
+ this.accessoryData.temperatureTable.items = this.getFilteredTableData(
+ this.allSensors,
+ this.activeFilters
+ );
+ this.isBusy = false;
+ });
+ },
+ methods: {
+ switchTimeScale(period) {
+ this.timeScale = period;
+ },
+ updateTemperature() {
+ this.temperatureWarning = +this.temperatureWarningInput;
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+//nav items style
+.nav-item,
+.nav-link {
+ padding: 0;
+}
+.nav-item {
+ list-style-type: none;
+}
+
+a {
+ color: $text-primary !important;
+ &:hover {
+ color: $text-primary !important;
+ }
+}
+
+.notification-button {
+ border: none;
+ background: none;
+}
+
+.semi-bold-12px {
+ z-index: 1001;
+}
+
+// temperature limit comtainer
+.limit-container {
+ height: 85px;
+ width: 100%;
+ padding: 0 32px 10px 32px;
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: flex-start;
+ align-items: flex-end;
+ gap: 24px;
+}
+
+.trmperature-limt {
+ height: 60px;
+ width: 100%;
+ max-width: 270px;
+ display: flex;
+ align-items: baseline;
+ flex-flow: row wrap;
+ gap: 8px;
+}
+
+.form-control {
+ height: 36px;
+ &.non-normal {
+ width: 125px;
+ }
+}
+.save-button {
+ width: 151px;
+ height: 36px;
+}
+</style>
diff --git a/src/views/_sila/Motherboard/DynamicInfo/TemperatureTable.vue b/src/views/_sila/Motherboard/DynamicInfo/TemperatureTable.vue
new file mode 100644
index 00000000..1bbf7e08
--- /dev/null
+++ b/src/views/_sila/Motherboard/DynamicInfo/TemperatureTable.vue
@@ -0,0 +1,112 @@
+<template>
+ <div>
+ <highcharts :options="chartOptions.line" />
+ </div>
+</template>
+
+<script>
+import { setTime, Series, setCategories } from './helpers';
+import { Chart } from 'highcharts-vue';
+
+export default {
+ components: {
+ highcharts: Chart,
+ },
+ props: {
+ timeScale: {
+ type: String,
+ default: 'hour',
+ },
+ warning: {
+ type: Number,
+ default: 70,
+ },
+ nonNormal: {
+ type: Number,
+ default: 70,
+ },
+ criticalStart: {
+ type: Number,
+ default: 70,
+ },
+ },
+ computed: {
+ chartOptions() {
+ return {
+ line: {
+ chart: {
+ type: 'line',
+ margin: [12, 50, 32, 60],
+ height: '320px',
+ },
+ title: null,
+ xAxis: {
+ categories: setTime(60, 'hour'),
+ title: null,
+ labels: {
+ step: 6,
+ },
+ minorGridLineColor: '#1A3E5B1A',
+ },
+ yAxis: {
+ categories: setCategories(101, 'С°'),
+ min: 0,
+ max: 100,
+ title: null,
+ minTickInterval: 25,
+ minorGridLineColor: '#1A3E5B1A',
+ plotLines: [
+ {
+ color: '#E11717',
+ dashStyle: 'solid',
+ value: this.warning,
+ zIndex: '1000',
+ width: 2,
+ label: {
+ text: 'Пороговое значение предупреждения, С°',
+ align: 'right',
+ style: {
+ fontFamily: 'Inter, sans-serif',
+ fontSize: '12px',
+ fontStyle: 'normal',
+ fontWeight: '400',
+ lineHeight: '16px',
+ color: '#0C1C2999',
+ },
+ },
+ },
+ ],
+ },
+ series: Series['temperature'].map((item) => ({
+ ...item,
+ marker: {
+ enabled: false,
+ },
+ })),
+ legend: {
+ enabled: false,
+ },
+ tooltip: {
+ enabled: false,
+ crosshairs: false,
+ },
+ plotOptions: {
+ series: {
+ showInLegend: true,
+ },
+ },
+ },
+ };
+ },
+ },
+};
+</script>
+<style lang="scss">
+.highcharts-credits {
+ display: none;
+}
+
+.highcharts-plot-line-label {
+ transform: translate(-15px, 0) !important;
+}
+</style>
diff --git a/src/views/_sila/Motherboard/DynamicInfo/helpers.js b/src/views/_sila/Motherboard/DynamicInfo/helpers.js
new file mode 100644
index 00000000..890482ee
--- /dev/null
+++ b/src/views/_sila/Motherboard/DynamicInfo/helpers.js
@@ -0,0 +1,458 @@
+export const colors = [
+ '#CB32F1',
+ '#F18638',
+ '#139BB9',
+ '#E1AB17',
+ '#175AE1',
+ '#13B937',
+];
+
+export const Series = {
+ temperature: [
+ {
+ name: 'Sean',
+ data: [
+ 7,
+ 7,
+ 7,
+ 17,
+ 7,
+ 27,
+ 7,
+ 7,
+ 47,
+ 7,
+ 7,
+ 7,
+ 37,
+ 7,
+ 7,
+ 7,
+ 27,
+ 7,
+ 7,
+ 7,
+ 27,
+ 7,
+ 7,
+ 7,
+ 47,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 27,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 27,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 37,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ ],
+ color: '#CB32F1',
+ },
+ {
+ name: 'Ivan',
+ data: [
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 20,
+ 10,
+ 10,
+ 30,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 50,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 20,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 30,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 19,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ ],
+ color: '#175AE1',
+ },
+ {
+ name: 'Brendan',
+ data: [
+ 13,
+ 13,
+ 13,
+ 13,
+ 23,
+ 13,
+ 33,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 23,
+ 13,
+ 43,
+ 13,
+ 53,
+ 13,
+ 13,
+ 13,
+ 53,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 53,
+ 13,
+ 43,
+ 13,
+ 13,
+ 63,
+ 13,
+ 43,
+ 13,
+ 23,
+ 13,
+ 43,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ ],
+ color: '#B98D13',
+ },
+ {
+ name: 'Matteo',
+ data: [
+ 24,
+ 14,
+ 44,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 34,
+ 14,
+ 14,
+ 14,
+ 14,
+ 34,
+ 14,
+ 24,
+ 14,
+ 34,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 44,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 44,
+ 14,
+ 54,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 84,
+ 14,
+ 94,
+ 14,
+ 14,
+ 14,
+ 54,
+ 14,
+ 44,
+ 14,
+ 44,
+ 14,
+ 14,
+ 44,
+ 14,
+ ],
+ color: '#13B937',
+ },
+ {
+ name: 'Joan',
+ data: [
+ 16,
+ 16,
+ 16,
+ 26,
+ 16,
+ 46,
+ 16,
+ 66,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 26,
+ 16,
+ 36,
+ 16,
+ 66,
+ 16,
+ 76,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 26,
+ 16,
+ 16,
+ 16,
+ 56,
+ 16,
+ 16,
+ 16,
+ 56,
+ 16,
+ 66,
+ 16,
+ 76,
+ 16,
+ 16,
+ 16,
+ 96,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ ],
+ color: '#F18638',
+ },
+ {
+ name: 'Avinash',
+ data: [
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 29,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 39,
+ 39,
+ 39,
+ 19,
+ 59,
+ 19,
+ 19,
+ 39,
+ 19,
+ 29,
+ 19,
+ 39,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 29,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ ],
+ color: '#139BB9',
+ },
+ ],
+};
+
+export const setTime = (count) => {
+ const arr = [...new Array(count)].map(() => '');
+ for (let i = 0; i < arr.length; i++) {
+ arr[i] = `15:${String(i).padStart(2, '0')}`;
+ }
+ return arr;
+};
+
+export const setCategories = (count, desc) => {
+ const arr = [...new Array(count)].map((i, k) => `${k} ${desc}`);
+ return arr;
+};
+
+export const AccessoryData = {
+ temperatureTable: {
+ fields: [
+ {
+ key: 'name',
+ label: 'Имя модуля',
+ },
+ {
+ key: 'currentValue',
+ label: 'Текущее, С°',
+ },
+ {
+ key: 'middleTemperature',
+ label: 'Среднее, С°',
+ },
+ {
+ key: 'lowerCaution',
+ label: 'Минимальное, С°',
+ },
+ {
+ key: 'minDate',
+ label: 'Дата минимального',
+ },
+ {
+ key: 'upperCaution',
+ label: 'Максимальное, С°',
+ },
+ {
+ key: 'maxDate',
+ label: 'Дата максимального',
+ },
+ ],
+ items: [],
+ },
+};
diff --git a/src/views/_sila/Motherboard/DynamicInfo/index.js b/src/views/_sila/Motherboard/DynamicInfo/index.js
new file mode 100644
index 00000000..bd155997
--- /dev/null
+++ b/src/views/_sila/Motherboard/DynamicInfo/index.js
@@ -0,0 +1,2 @@
+import MotherboardDynamicPage from './MotherboardDynamicPage.vue';
+export default MotherboardDynamicPage;
diff --git a/src/views/_sila/Motherboard/Specification/MotherboardSpecificationPage.vue b/src/views/_sila/Motherboard/Specification/MotherboardSpecificationPage.vue
new file mode 100644
index 00000000..56586dcf
--- /dev/null
+++ b/src/views/_sila/Motherboard/Specification/MotherboardSpecificationPage.vue
@@ -0,0 +1,83 @@
+<template>
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title :description="$t('appNavigation.specification')" />
+ <page-section class="bootstrap-table__section">
+ <span class="bold-16px">{{ $t('global.table.info') }}</span>
+ <b-table
+ responsive="md"
+ show-empty
+ class="table-rounded"
+ no-border-collapse
+ :items="items"
+ :fields="fields"
+ :empty-text="$t('global.table.emptyMessage')"
+ >
+ </b-table>
+ <span class="bold-16px">{{ $t('appNavigation.motherboardParam') }}</span>
+ <popover
+ id="popover-reactive-1"
+ description="SystemDescription.onBootRom"
+ popup="SystemDescription.onBootRom_popup"
+ button="global.action.refresh"
+ />
+ <popover
+ id="popover-reactive-2"
+ description="SystemDescription.offBootRom"
+ popup="SystemDescription.offBootRom_popup"
+ button="global.action.refresh"
+ />
+ </page-section>
+ </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import PageSection from '@/components/Global/PageSection';
+
+import Popover from '@/components/Global/Popover';
+
+export default {
+ components: { PageTitle, PageSection, Popover },
+ data() {
+ return {
+ fields: [
+ {
+ key: 'parametr',
+ label: 'Параметр',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'value',
+ label: 'Значение',
+ formatter: this.dataFormatter,
+ },
+ ],
+ items: [
+ {
+ parametr: 'Модель',
+ value: 'R2132',
+ },
+ {
+ parametr: 'Производитель',
+ value: 'Asus',
+ },
+ {
+ parametr: 'Версия',
+ value: '4.2',
+ },
+ {
+ parametr: 'Серийный номер',
+ value: '231232132133',
+ },
+ {
+ parametr: 'Версия BIOS',
+ value: '2',
+ },
+ ],
+ };
+ },
+};
+</script>
diff --git a/src/views/_sila/Motherboard/Specification/index.js b/src/views/_sila/Motherboard/Specification/index.js
new file mode 100644
index 00000000..5458039a
--- /dev/null
+++ b/src/views/_sila/Motherboard/Specification/index.js
@@ -0,0 +1,2 @@
+import MotherboardSpecificationPage from './MotherboardSpecificationPage.vue';
+export default MotherboardSpecificationPage;
diff --git a/src/views/_sila/Operations/ConsoleSettings/ConsoleSettings.vue b/src/views/_sila/Operations/ConsoleSettings/ConsoleSettings.vue
new file mode 100644
index 00000000..ecc2150f
--- /dev/null
+++ b/src/views/_sila/Operations/ConsoleSettings/ConsoleSettings.vue
@@ -0,0 +1,154 @@
+<template>
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title />
+ <page-section class="bootstrap-table__section">
+ <b-table
+ responsive="md"
+ show-empty
+ class="table-rounded"
+ no-border-collapse
+ :items="systems"
+ :fields="fields"
+ :empty-text="$t('global.table.emptyMessage')"
+ >
+ <template #cell(value)="data">
+ <b-row v-if="typeof data.value === 'boolean'">
+ <b-col>
+ <span v-if="systems[data.index].value">
+ {{ $t('global.status.enabled') }}
+ </span>
+ <span v-else>
+ {{ $t('global.status.disabled') }}
+ </span>
+ </b-col>
+ <b-col>
+ <b-form-checkbox v-model="systems[data.index].value" switch>
+ </b-form-checkbox>
+ </b-col>
+ </b-row>
+ <b-row
+ v-else-if="data.index === 1 || data.index === 6 || data.index === 8"
+ >
+ <b-col>
+ <span>
+ {{ data.value }}
+ </span>
+ </b-col>
+ <b-col>
+ <img :is="iconChevron" class="icon-chevron" />
+ </b-col>
+ </b-row>
+ <b-row v-else-if="data.index === 3">
+ <b-col>
+ <span>
+ {{ data.value }}
+ </span>
+ </b-col>
+ <b-col>
+ <img src="@/assets/images/icon-edit.svg" class="icon-chevron" />
+ </b-col>
+ </b-row>
+ <b-row v-else>
+ <span>{{ data.value }}</span></b-row
+ >
+ </template>
+ </b-table>
+ <div class="save-button">
+ <b-button variant="primary" class="console-settings__save-button">
+ {{ $t('global.action.saveChanges') }}
+ </b-button>
+ </div>
+ </page-section>
+ </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import PageSection from '@/components/Global/PageSection';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import TableRowExpandMixin, {
+ expandRowLabel,
+} from '@/components/Mixins/TableRowExpandMixin';
+import iconChevron from '@carbon/icons-vue/es/chevron--down/16';
+
+export default {
+ components: {
+ PageTitle,
+ PageSection,
+ },
+ mixins: [BVToastMixin, TableRowExpandMixin],
+ data() {
+ return {
+ text: '',
+ isBusy: true,
+ fields: [
+ {
+ key: 'attributes',
+ label: 'Атрибуты',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'value',
+ label: 'Значение',
+ formatter: this.dataFormatter,
+ thStyle: { width: '30%' },
+ },
+ ],
+ iconChevron,
+ expandRowLabel: expandRowLabel,
+ systems: [
+ { attributes: 'Состояние', value: true },
+ { attributes: 'Максимальное количество сеансов', value: '6' },
+ { attributes: 'Активные сеансы', value: '0' },
+ { attributes: 'Порт удаленного доступа', value: '5900' },
+ { attributes: 'Статус шифрования видео', value: true },
+ { attributes: 'Видео с локального сервера', value: true },
+ {
+ attributes:
+ 'Действие по умолчанию при истечении времени ожидания запроса на общий доступ к сеансу',
+ value: 'Полный доступ',
+ },
+ {
+ attributes: 'Автоматическая блокировка системы',
+ value: false,
+ },
+ {
+ attributes: 'Состояние подключения клавиатуры/мыши',
+ value: 'Автоматическое',
+ },
+ ],
+ // iconChevronUp: iconChevronUp,
+ };
+ },
+};
+</script>
+<style lang="scss" scoped>
+.row {
+ margin: 0px;
+ height: 15px;
+ flex-wrap: nowrap;
+ align-items: center;
+}
+.col {
+ padding: 0;
+}
+
+.icon-chevron {
+ margin: 0 0 0 85%;
+ cursor: pointer;
+}
+
+.save-button {
+ display: flex;
+ justify-content: flex-end;
+}
+
+.console-settings__save-button {
+ width: 241px;
+ height: 36px;
+ margin-right: 0.5rem;
+}
+</style>
diff --git a/src/views/_sila/Operations/ConsoleSettings/index.js b/src/views/_sila/Operations/ConsoleSettings/index.js
new file mode 100644
index 00000000..860ee595
--- /dev/null
+++ b/src/views/_sila/Operations/ConsoleSettings/index.js
@@ -0,0 +1,2 @@
+import ConsoleSettings from './ConsoleSettings.vue';
+export default ConsoleSettings;
diff --git a/src/views/_sila/Operations/FactoryReset/FactoryReset.vue b/src/views/_sila/Operations/FactoryReset/FactoryReset.vue
index 4e315619..d1ab187e 100644
--- a/src/views/_sila/Operations/FactoryReset/FactoryReset.vue
+++ b/src/views/_sila/Operations/FactoryReset/FactoryReset.vue
@@ -1,12 +1,19 @@
<template>
- <b-container fluid="xl">
+ <b-container fluid class="m-0 p-0">
<page-title :description="$t('pageFactoryReset.description')" />
<!-- Reset Form -->
- <b-form id="factory-reset" @submit.prevent="onResetSubmit">
+ <b-form
+ id="factory-reset"
+ class="bootstrap-table__section"
+ @submit.prevent="onResetSubmit"
+ >
<b-row>
<b-col md="8">
- <b-form-group :label="$t('pageFactoryReset.form.resetOptionsLabel')">
+ <b-form-group
+ :label="$t('pageFactoryReset.form.resetOptionsLabel')"
+ label-class="semi-bold-16px"
+ >
<b-form-radio-group
id="factory-reset-options"
v-model="resetOption"
diff --git a/src/views/_sila/Operations/Firmware/Firmware.vue b/src/views/_sila/Operations/Firmware/Firmware.vue
index 0497376d..c4006b7f 100644
--- a/src/views/_sila/Operations/Firmware/Firmware.vue
+++ b/src/views/_sila/Operations/Firmware/Firmware.vue
@@ -1,5 +1,5 @@
<template>
- <b-container fluid="xl">
+ <b-container fluid class="m-0 p-0">
<page-title />
<alerts-server-power
v-if="isServerPowerOffRequired"
@@ -7,7 +7,7 @@
/>
<!-- Firmware cards -->
- <b-row>
+ <b-row class="bootstrap-table__section">
<b-col xl="10">
<!-- BMC Firmware -->
<bmc-cards :is-page-disabled="isPageDisabled" />
@@ -19,6 +19,7 @@
<!-- Update firmware-->
<page-section
+ class="bootstrap-table__section"
:section-title="$t('pageFirmware.sectionTitleUpdateFirmware')"
>
<b-row>
@@ -39,12 +40,10 @@ import AlertsServerPower from './FirmwareAlertServerPower';
import BmcCards from './FirmwareCardsBmc';
import FormUpdate from './FirmwareFormUpdate';
import HostCards from './FirmwareCardsHost';
-import PageSection from '@/components/_sila/Global/PageSection';
-import PageTitle from '@/components/_sila/Global/PageTitle';
+import PageSection from '@/components/Global/PageSection';
+import PageTitle from '@/components/Global/PageTitle';
-import LoadingBarMixin, {
- loading,
-} from '@/components/_sila/Mixins/LoadingBarMixin';
+import LoadingBarMixin, { loading } from '@/components/Mixins/LoadingBarMixin';
export default {
name: 'FirmwareSingleImage',
diff --git a/src/views/_sila/Operations/Firmware/FirmwareAlertServerPower.vue b/src/views/_sila/Operations/Firmware/FirmwareAlertServerPower.vue
index 471ccfac..24aa1d69 100644
--- a/src/views/_sila/Operations/Firmware/FirmwareAlertServerPower.vue
+++ b/src/views/_sila/Operations/Firmware/FirmwareAlertServerPower.vue
@@ -31,7 +31,7 @@
</template>
<script>
-import Alert from '@/components/_sila/Global/Alert';
+import Alert from '@/components/Global/Alert';
export default {
components: { Alert },
diff --git a/src/views/_sila/Operations/Firmware/FirmwareCardsBmc.vue b/src/views/_sila/Operations/Firmware/FirmwareCardsBmc.vue
index 23c263d9..d79a8769 100644
--- a/src/views/_sila/Operations/Firmware/FirmwareCardsBmc.vue
+++ b/src/views/_sila/Operations/Firmware/FirmwareCardsBmc.vue
@@ -53,11 +53,9 @@
<script>
import IconSwitch from '@carbon/icons-vue/es/arrows--horizontal/20';
-import PageSection from '@/components/_sila/Global/PageSection';
-import LoadingBarMixin, {
- loading,
-} from '@/components/_sila/Mixins/LoadingBarMixin';
-import BVToastMixin from '@/components/_sila/Mixins/BVToastMixin';
+import PageSection from '@/components/Global/PageSection';
+import LoadingBarMixin, { loading } from '@/components/Mixins/LoadingBarMixin';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
import ModalSwitchToRunning from './FirmwareModalSwitchToRunning';
diff --git a/src/views/_sila/Operations/Firmware/FirmwareCardsHost.vue b/src/views/_sila/Operations/Firmware/FirmwareCardsHost.vue
index 03a25ee5..b4a8e90d 100644
--- a/src/views/_sila/Operations/Firmware/FirmwareCardsHost.vue
+++ b/src/views/_sila/Operations/Firmware/FirmwareCardsHost.vue
@@ -37,7 +37,7 @@
</template>
<script>
-import PageSection from '@/components/_sila/Global/PageSection';
+import PageSection from '@/components/Global/PageSection';
export default {
components: { PageSection },
diff --git a/src/views/_sila/Operations/Firmware/FirmwareFormUpdate.vue b/src/views/_sila/Operations/Firmware/FirmwareFormUpdate.vue
index 23fe90f2..a5e5ba97 100644
--- a/src/views/_sila/Operations/Firmware/FirmwareFormUpdate.vue
+++ b/src/views/_sila/Operations/Firmware/FirmwareFormUpdate.vue
@@ -59,6 +59,7 @@
<b-btn
data-test-id="firmware-button-startUpdate"
type="submit"
+ size="md"
variant="primary"
:disabled="isPageDisabled"
>
@@ -75,13 +76,11 @@
<script>
import { requiredIf } from 'vuelidate/lib/validators';
-import BVToastMixin from '@/components/_sila/Mixins/BVToastMixin';
-import LoadingBarMixin, {
- loading,
-} from '@/components/_sila/Mixins/LoadingBarMixin';
-import VuelidateMixin from '@/components/_sila/Mixins/VuelidateMixin.js';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import LoadingBarMixin, { loading } from '@/components/Mixins/LoadingBarMixin';
+import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
-import FormFile from '@/components/_sila/Global/FormFile';
+import FormFile from '@/components/Global/FormFile';
import ModalUpdateFirmware from './FirmwareModalUpdateFirmware';
export default {
diff --git a/src/views/_sila/Operations/KeyClear/KeyClear.vue b/src/views/_sila/Operations/KeyClear/KeyClear.vue
index 8955f6cd..fd6468fa 100644
--- a/src/views/_sila/Operations/KeyClear/KeyClear.vue
+++ b/src/views/_sila/Operations/KeyClear/KeyClear.vue
@@ -1,9 +1,9 @@
<template>
- <b-container fluid="xl">
+ <b-container fluid class="m-0 p-0">
<page-title :description="$t('pageKeyClear.description')" />
- <b-row>
+ <b-row class="bootstrap-table__section">
<b-col md="8" xl="6">
- <alert variant="info" class="mb-4">
+ <alert variant="info" class="mb-0">
<div class="font-weight-bold">
{{ $t('pageKeyClear.alert.title') }}
</div>
@@ -14,10 +14,17 @@
</b-col>
</b-row>
<!-- Reset Form -->
- <b-form id="key-clear" @submit.prevent="onKeyClearSubmit(keyOption)">
+ <b-form
+ id="key-clear"
+ class="bootstrap-table__section"
+ @submit.prevent="onKeyClearSubmit(keyOption)"
+ >
<b-row>
<b-col md="8">
- <b-form-group :label="$t('pageKeyClear.form.keyClearOptionsLabel')">
+ <b-form-group
+ :label="$t('pageKeyClear.form.keyClearOptionsLabel')"
+ label-class="semi-bold-16px"
+ >
<b-form-radio-group
id="key-clear-options"
v-model="keyOption"
diff --git a/src/views/_sila/Operations/Kvm/Kvm.vue b/src/views/_sila/Operations/Kvm/Kvm.vue
index ede24608..a3103453 100644
--- a/src/views/_sila/Operations/Kvm/Kvm.vue
+++ b/src/views/_sila/Operations/Kvm/Kvm.vue
@@ -1,5 +1,5 @@
<template>
- <b-container fluid="xl">
+ <b-container fluid>
<page-title />
<div class="terminal-container">
<kvm-console :is-full-window="false" />
@@ -8,7 +8,7 @@
</template>
<script>
-import PageTitle from '@/components/_sila/Global/PageTitle';
+import PageTitle from '@/components/Global/PageTitle';
import KvmConsole from './KvmConsole';
export default {
diff --git a/src/views/_sila/Operations/Kvm/KvmConsole.vue b/src/views/_sila/Operations/Kvm/KvmConsole.vue
index 50cbff7f..d06e2824 100644
--- a/src/views/_sila/Operations/Kvm/KvmConsole.vue
+++ b/src/views/_sila/Operations/Kvm/KvmConsole.vue
@@ -1,8 +1,12 @@
<template>
<div :class="marginClass">
<div ref="toolbar" class="kvm-toolbar">
- <b-row class="d-flex">
- <b-col class="d-flex flex-column justify-content-end" cols="4">
+ <b-row class="d-flex flex-column flex-sm-row">
+ <b-col
+ class="d-flex flex-column justify-content-end console-title"
+ style="min-width: 105px"
+ cols="3"
+ >
<dl class="mb-2" sm="2" md="2">
<dt class="d-inline font-weight-bold mr-1">
{{ $t('pageKvm.status') }}:
@@ -14,9 +18,10 @@
</dl>
</b-col>
- <b-col class="d-flex justify-content-end pr-1">
+ <b-col class="d-flex justify-content-end pr-1 flex-column flex-sm-row">
<b-button
v-if="isConnected"
+ class="console-title console-button"
variant="link"
type="button"
@click="sendCtrlAltDel"
@@ -26,6 +31,7 @@
</b-button>
<b-button
v-if="!isFullWindow"
+ class="console-title console-button"
variant="link"
type="button"
@click="openConsoleWindow()"
@@ -42,7 +48,7 @@
<script>
import RFB from '@novnc/novnc/core/rfb';
-import StatusIcon from '@/components/_sila/Global/StatusIcon';
+import StatusIcon from '@/components/Global/StatusIcon';
import IconLaunch from '@carbon/icons-vue/es/launch/20';
import IconArrowDown from '@carbon/icons-vue/es/arrow--down/16';
import { throttle } from 'lodash';
@@ -167,4 +173,16 @@ export default {
.margin-left-full-window {
margin-left: 5px;
}
+
+@media (max-width: 1200px) {
+ .console-title {
+ font-size: 0.7rem;
+ }
+}
+
+@media (max-width: 576px) {
+ .console-button {
+ justify-content: flex-end;
+ }
+}
</style>
diff --git a/src/views/_sila/Operations/RebootBmc/RebootBmc.vue b/src/views/_sila/Operations/RebootBmc/RebootBmc.vue
index fa16f55e..71b9b123 100644
--- a/src/views/_sila/Operations/RebootBmc/RebootBmc.vue
+++ b/src/views/_sila/Operations/RebootBmc/RebootBmc.vue
@@ -1,7 +1,7 @@
<template>
- <b-container fluid="xl">
+ <b-container fluid class="m-0 p-0">
<page-title />
- <b-row>
+ <b-row class="bootstrap-table__section">
<b-col md="8" lg="8" xl="6">
<page-section>
<b-row>
@@ -19,14 +19,22 @@
</b-col>
</b-row>
{{ $t('pageRebootBmc.rebootInformation') }}
- <b-button
- variant="primary"
- class="d-block mt-5"
- data-test-id="rebootBmc-button-reboot"
- @click="onClick"
+ <popover-with-slot
+ id="popover-reboot"
+ :button-label="$t('global.action.reload')"
+ :popup-label="$t('BMC.ReloadBmc_popup')"
+ placement="left"
+ :action="rebootBmc"
>
- {{ $t('pageRebootBmc.rebootBmc') }}
- </b-button>
+ <b-button
+ id="popover-reboot"
+ variant="primary"
+ class="d-block mt-5"
+ data-test-id="rebootBmc-button-reboot"
+ >
+ {{ $t('pageRebootBmc.rebootBmc') }}
+ </b-button>
+ </popover-with-slot>
</page-section>
</b-col>
</b-row>
@@ -38,10 +46,11 @@ import PageTitle from '@/components/_sila/Global/PageTitle';
import PageSection from '@/components/_sila/Global/PageSection';
import BVToastMixin from '@/components/_sila/Mixins/BVToastMixin';
import LoadingBarMixin from '@/components/_sila/Mixins/LoadingBarMixin';
+import PopoverWithSlot from '@/components/_sila/Global/SilaComponents/PopoverWithSlot';
export default {
name: 'RebootBmc',
- components: { PageTitle, PageSection },
+ components: { PageTitle, PageSection, PopoverWithSlot },
mixins: [BVToastMixin, LoadingBarMixin],
beforeRouteLeave(to, from, next) {
this.hideLoader();
@@ -59,17 +68,6 @@ export default {
.finally(() => this.endLoader());
},
methods: {
- onClick() {
- this.$bvModal
- .msgBoxConfirm(this.$t('pageRebootBmc.modal.confirmMessage'), {
- title: this.$t('pageRebootBmc.modal.confirmTitle'),
- okTitle: this.$t('global.action.confirm'),
- cancelTitle: this.$t('global.action.cancel'),
- })
- .then((confirmed) => {
- if (confirmed) this.rebootBmc();
- });
- },
rebootBmc() {
this.$store
.dispatch('controls/rebootBmc')
diff --git a/src/views/_sila/Operations/SerialOverLan/SerialOverLanConsole.vue b/src/views/_sila/Operations/SerialOverLan/SerialOverLanConsole.vue
index bf974b51..2a9a2f4a 100644
--- a/src/views/_sila/Operations/SerialOverLan/SerialOverLanConsole.vue
+++ b/src/views/_sila/Operations/SerialOverLan/SerialOverLanConsole.vue
@@ -9,7 +9,7 @@
class="mt-4"
>
<p class="col-form-label">
- {{ $t('pageSerialOverLan.alert.disconnectedAlertMessage') }}
+ {{ $t('pageSerialOverLan.disconnectedAlertMessage') }}
</p>
</alert>
</b-col>
diff --git a/src/views/_sila/Operations/ServerPowerOperations/BootSettings.vue b/src/views/_sila/Operations/ServerPowerOperations/BootSettings.vue
index 8d74e381..7f56c36a 100644
--- a/src/views/_sila/Operations/ServerPowerOperations/BootSettings.vue
+++ b/src/views/_sila/Operations/ServerPowerOperations/BootSettings.vue
@@ -1,16 +1,14 @@
<template>
- <div class="form-background p-3">
+ <page-section class="m-0">
<b-form novalidate @submit.prevent="handleSubmit">
- <b-form-group
- :label="
+ <b-form-group label-for="boot-option" class="mb-3 regular-12px">
+ <label class="semi-bold-12px">{{
$t('pageServerPowerOperations.bootSettings.bootSettingsOverride')
- "
- label-for="boot-option"
- class="mb-3"
- >
+ }}</label>
<b-form-select
id="boot-option"
v-model="form.bootOption"
+ class="boot-select regular-14px"
:disabled="bootSourceOptions.length === 0"
:options="bootSourceOptions"
@change="onChangeSelect"
@@ -19,43 +17,47 @@
</b-form-group>
<b-form-checkbox
v-model="form.oneTimeBoot"
- class="mb-4"
+ class="mb-4 regular-12px cb"
:disabled="form.bootOption === 'None'"
@change="$v.form.oneTimeBoot.$touch()"
>
{{ $t('pageServerPowerOperations.bootSettings.enableOneTimeBoot') }}
</b-form-checkbox>
- <b-form-group
- :label="$t('pageServerPowerOperations.bootSettings.tpmRequiredPolicy')"
- >
- <b-form-text id="tpm-required-policy-help-block">
+ <b-form-group>
+ <label class="semi-bold-12px">{{
+ $t('pageServerPowerOperations.bootSettings.tpmRequiredPolicy')
+ }}</label>
+ <label id="tpm-required-policy-help-block" class="regular-12px">
{{
$t('pageServerPowerOperations.bootSettings.tpmRequiredPolicyHelper')
}}
- </b-form-text>
+ </label>
<b-form-checkbox
id="tpm-required-policy"
v-model="form.tpmPolicyOn"
+ class="regular-12px cb"
aria-describedby="tpm-required-policy-help-block"
@change="$v.form.tpmPolicyOn.$touch()"
>
{{ $t('global.status.enabled') }}
</b-form-checkbox>
</b-form-group>
- <b-button variant="primary" type="submit" class="mb-3">
+ <b-button variant="primary" size="md" type="submit" class="mb-3">
{{ $t('global.action.save') }}
</b-button>
</b-form>
- </div>
+ </page-section>
</template>
<script>
import { mapState } from 'vuex';
import BVToastMixin from '@/components/_sila/Mixins/BVToastMixin';
import LoadingBarMixin from '@/components/_sila/Mixins/LoadingBarMixin';
+import PageSection from '@/components/_sila/Global/PageSection';
export default {
name: 'BootSettings',
+ components: { PageSection },
mixins: [BVToastMixin, LoadingBarMixin],
data() {
return {
@@ -130,3 +132,12 @@ export default {
},
};
</script>
+<style lang="scss" scoped>
+.boot-select {
+ height: 40px;
+ max-width: 270px;
+ border: none;
+ border-radius: 8px;
+ background-image: url('../../../../assets/images/_sila/icon-chevron.svg');
+}
+</style>
diff --git a/src/views/_sila/Operations/ServerPowerOperations/ServerPowerOperations.vue b/src/views/_sila/Operations/ServerPowerOperations/ServerPowerOperations.vue
index e848215f..1ba90b83 100644
--- a/src/views/_sila/Operations/ServerPowerOperations/ServerPowerOperations.vue
+++ b/src/views/_sila/Operations/ServerPowerOperations/ServerPowerOperations.vue
@@ -1,28 +1,40 @@
<template>
- <b-container fluid="xl">
+ <b-container fluid="xxl pt-0 m-0">
<page-title />
- <b-row class="mb-4">
+ <page-section
+ :section-title="$t('pageServerPowerOperations.serverStatus')"
+ class="m-4"
+ >
<b-col md="8" xl="6">
- <page-section
- :section-title="$t('pageServerPowerOperations.currentStatus')"
- >
+ <page-section class="pt-2 mb-0">
<b-row>
<b-col>
<dl>
- <dt>{{ $t('pageServerPowerOperations.serverStatus') }}</dt>
<dd
v-if="serverStatus === 'on'"
+ style="margin-top: 10px"
+ class="regular-12px"
data-test-id="powerServerOps-text-hostStatus"
>
- {{ $t('global.status.on') }}
+ <img
+ style="margin-right: 5px"
+ src="@/assets/images/_sila/status/on.svg"
+ />
+ {{ $t('global.status.on_full') }}
</dd>
<dd
v-else-if="serverStatus === 'off'"
+ style="margin-top: 10px"
+ class="regular-12px"
data-test-id="powerServerOps-text-hostStatus"
>
- {{ $t('global.status.off') }}
+ <img
+ style="margin-right: 5px"
+ src="@/assets/images/_sila/status/off.svg"
+ />
+ {{ $t('global.status.off_full') }}
</dd>
- <dd v-else>
+ <dd v-else class="regular-12px">
{{ $t('global.status.notAvailable') }}
</dd>
</dl>
@@ -31,11 +43,12 @@
<b-row>
<b-col>
<dl>
- <dt>
+ <dt class="semi-bold-12px">
{{ $t('pageServerPowerOperations.lastPowerOperation') }}
</dt>
<dd
v-if="lastPowerOperationTime"
+ class="regular-12px"
data-test-id="powerServerOps-text-lastPowerOp"
>
{{ lastPowerOperationTime | formatDate }}
@@ -47,19 +60,13 @@
</b-row>
</page-section>
</b-col>
- </b-row>
- <b-row>
- <b-col v-if="hasBootSourceOptions" sm="8" md="6" xl="4">
- <page-section
- :section-title="$t('pageServerPowerOperations.serverBootSettings')"
- >
- <boot-settings />
- </page-section>
- </b-col>
+ </page-section>
+ <page-section
+ :section-title="$t('SystemDescription.title.Control')"
+ class="ml-4 mb-0"
+ >
<b-col sm="8" md="6" xl="7">
- <page-section
- :section-title="$t('pageServerPowerOperations.operations')"
- >
+ <page-section>
<alert :show="oneTimeBootEnabled" variant="warning">
{{ $t('pageServerPowerOperations.oneTimeBootWarning') }}
</alert>
@@ -69,20 +76,30 @@
</alert>
</template>
<template v-else-if="serverStatus === 'off'">
- <b-button
- variant="primary"
- data-test-id="serverPowerOperations-button-powerOn"
- @click="powerOn"
+ <popover-with-slot
+ id="popover-powerOn"
+ :button-label="$t('pageServerPowerOperations.powerOn')"
+ :popup-label="$t('pageServerPowerOperations.powerOnServer')"
+ placement="right"
+ :action="powerOn"
>
- {{ $t('pageServerPowerOperations.powerOn') }}
- </b-button>
+ <b-button
+ id="popover-powerOn"
+ ref="button"
+ size="md"
+ variant="primary"
+ >
+ {{ $t('pageServerPowerOperations.powerOn') }}
+ </b-button>
+ </popover-with-slot>
</template>
<template v-else>
<!-- Reboot server options -->
- <b-form novalidate class="mb-5" @submit.prevent="rebootServer">
- <b-form-group
- :label="$t('pageServerPowerOperations.rebootServer')"
- >
+ <b-form novalidate class="mb-2">
+ <b-form-group class="regular-12px cb">
+ <label class="semi-bold-12px">{{
+ $t('pageServerPowerOperations.rebootServer')
+ }}</label>
<b-form-radio
v-model="form.rebootOption"
name="reboot-option"
@@ -100,19 +117,29 @@
{{ $t('pageServerPowerOperations.immediateReboot') }}
</b-form-radio>
</b-form-group>
- <b-button
- variant="primary"
- type="submit"
- data-test-id="serverPowerOperations-button-reboot"
+ <popover-with-slot
+ id="popover-reboot"
+ :button-label="$t('pageServerPowerOperations.reboot')"
+ :popup-label="$t('pageServerPowerOperations.rebootServer')"
+ placement="right"
+ :action="rebootServer"
>
- {{ $t('pageServerPowerOperations.reboot') }}
- </b-button>
+ <b-button
+ id="popover-reboot"
+ ref="button"
+ size="md"
+ variant="primary"
+ >
+ {{ $t('pageServerPowerOperations.reboot') }}
+ </b-button>
+ </popover-with-slot>
</b-form>
<!-- Shutdown server options -->
- <b-form novalidate @submit.prevent="shutdownServer">
- <b-form-group
- :label="$t('pageServerPowerOperations.shutdownServer')"
- >
+ <b-form>
+ <b-form-group class="regular-12px cb">
+ <label class="semi-bold-12px">{{
+ $t('pageServerPowerOperations.shutdownServer')
+ }}</label>
<b-form-radio
v-model="form.shutdownOption"
name="shutdown-option"
@@ -130,18 +157,35 @@
{{ $t('pageServerPowerOperations.immediateShutdown') }}
</b-form-radio>
</b-form-group>
- <b-button
- variant="primary"
- type="submit"
- data-test-id="serverPowerOperations-button-shutDown"
+ <popover-with-slot
+ id="popover-shutDown"
+ :button-label="$t('pageServerPowerOperations.shutDown')"
+ :popup-label="$t('pageServerPowerOperations.shutdownServer')"
+ placement="right"
+ :action="shutdownServer"
>
- {{ $t('pageServerPowerOperations.shutDown') }}
- </b-button>
+ <b-button
+ id="popover-shutDown"
+ ref="button"
+ size="md"
+ variant="secondary"
+ >
+ {{ $t('pageServerPowerOperations.shutDown') }}
+ </b-button>
+ </popover-with-slot>
</b-form>
</template>
</page-section>
</b-col>
- </b-row>
+ </page-section>
+ <page-section
+ :section-title="$t('pageServerPowerOperations.serverBootSettings')"
+ class="m-4"
+ >
+ <b-col v-if="hasBootSourceOptions" sm="8" md="6" xl="4">
+ <boot-settings />
+ </b-col>
+ </page-section>
</b-container>
</template>
@@ -152,10 +196,17 @@ import BVToastMixin from '@/components/_sila/Mixins/BVToastMixin';
import BootSettings from './BootSettings';
import LoadingBarMixin from '@/components/_sila/Mixins/LoadingBarMixin';
import Alert from '@/components/_sila/Global/Alert';
+import PopoverWithSlot from '@/components/_sila/Global/SilaComponents/PopoverWithSlot';
export default {
name: 'ServerPowerOperations',
- components: { PageTitle, PageSection, BootSettings, Alert },
+ components: {
+ PageTitle,
+ PageSection,
+ BootSettings,
+ Alert,
+ PopoverWithSlot,
+ },
mixins: [BVToastMixin, LoadingBarMixin],
beforeRouteLeave(to, from, next) {
this.hideLoader();
@@ -207,52 +258,18 @@ export default {
this.$store.dispatch('controls/serverPowerOn');
},
rebootServer() {
- const modalMessage = this.$t(
- 'pageServerPowerOperations.modal.confirmRebootMessage'
- );
- const modalOptions = {
- title: this.$t('pageServerPowerOperations.modal.confirmRebootTitle'),
- okTitle: this.$t('global.action.confirm'),
- cancelTitle: this.$t('global.action.cancel'),
- };
-
if (this.form.rebootOption === 'orderly') {
- this.$bvModal
- .msgBoxConfirm(modalMessage, modalOptions)
- .then((confirmed) => {
- if (confirmed) this.$store.dispatch('controls/serverSoftReboot');
- });
+ this.$store.dispatch('controls/serverSoftReboot');
} else if (this.form.rebootOption === 'immediate') {
- this.$bvModal
- .msgBoxConfirm(modalMessage, modalOptions)
- .then((confirmed) => {
- if (confirmed) this.$store.dispatch('controls/serverHardReboot');
- });
+ this.$store.dispatch('controls/serverHardReboot');
}
},
shutdownServer() {
- const modalMessage = this.$t(
- 'pageServerPowerOperations.modal.confirmShutdownMessage'
- );
- const modalOptions = {
- title: this.$t('pageServerPowerOperations.modal.confirmShutdownTitle'),
- okTitle: this.$t('global.action.confirm'),
- cancelTitle: this.$t('global.action.cancel'),
- };
-
if (this.form.shutdownOption === 'orderly') {
- this.$bvModal
- .msgBoxConfirm(modalMessage, modalOptions)
- .then((confirmed) => {
- if (confirmed) this.$store.dispatch('controls/serverSoftPowerOff');
- });
+ this.$store.dispatch('controls/serverSoftPowerOff');
}
if (this.form.shutdownOption === 'immediate') {
- this.$bvModal
- .msgBoxConfirm(modalMessage, modalOptions)
- .then((confirmed) => {
- if (confirmed) this.$store.dispatch('controls/serverHardPowerOff');
- });
+ this.$store.dispatch('controls/serverHardPowerOff');
}
},
},
diff --git a/src/views/_sila/Operations/VirtualMedia/ModalConfigureConnection.vue b/src/views/_sila/Operations/VirtualMedia/ModalConfigureConnection.vue
index 9886eff5..9ba90d57 100644
--- a/src/views/_sila/Operations/VirtualMedia/ModalConfigureConnection.vue
+++ b/src/views/_sila/Operations/VirtualMedia/ModalConfigureConnection.vue
@@ -9,14 +9,17 @@
<template #modal-title>
{{ $t('pageVirtualMedia.modal.title') }}
</template>
- <b-form>
+ <b-form style="width: 100%">
<b-form-group
- :label="$t('pageVirtualMedia.modal.serverUri')"
+ :label="
+ $t('pageVirtualMedia.modal.serverUri') + ' (http, ftp, smb, nfs)'
+ "
label-for="serverUri"
>
<b-form-input
id="serverUri"
v-model="form.serverUri"
+ placeholder="https://"
type="text"
:state="getValidationState($v.form.serverUri)"
data-test-id="configureConnection-input-serverUri"
@@ -43,12 +46,14 @@
:label="$t('pageVirtualMedia.modal.password')"
label-for="password"
>
- <b-form-input
- id="password"
- v-model="form.password"
- type="password"
- data-test-id="configureConnection-input-password"
- />
+ <input-password-toggle>
+ <b-form-input
+ id="password"
+ v-model="form.password"
+ type="password"
+ data-test-id="configureConnection-input-password"
+ />
+ </input-password-toggle>
</b-form-group>
<b-form-group>
<b-form-checkbox
@@ -72,8 +77,12 @@
<script>
import { required } from 'vuelidate/lib/validators';
import VuelidateMixin from '@/components/_sila/Mixins/VuelidateMixin.js';
+import InputPasswordToggle from '@/components/_sila/Global/InputPasswordToggle';
export default {
+ components: {
+ InputPasswordToggle,
+ },
mixins: [VuelidateMixin],
props: {
connection: {
diff --git a/src/views/_sila/Operations/VirtualMedia/VirtualMedia.vue b/src/views/_sila/Operations/VirtualMedia/VirtualMedia.vue
index 0f75bbd7..e508e06f 100644
--- a/src/views/_sila/Operations/VirtualMedia/VirtualMedia.vue
+++ b/src/views/_sila/Operations/VirtualMedia/VirtualMedia.vue
@@ -1,14 +1,18 @@
<template>
- <b-container fluid="xl">
+ <b-container fluid class="m-0 p-0">
<page-title />
- <b-row class="mb-4">
+ <b-row class="bootstrap-table__section">
<b-col md="12">
<page-section
:section-title="$t('pageVirtualMedia.virtualMediaSubTitleFirst')"
>
<b-row>
<b-col v-for="(dev, $index) in proxyDevices" :key="$index" md="6">
- <b-form-group :label="dev.id" label-class="bold">
+ <b-form-group
+ :label="dev.id"
+ label-class="regular-14px"
+ :style="{ 'margin-bottom': dev.isActive ? '0' : '1rem' }"
+ >
<form-file
v-if="!dev.isActive"
:id="concatId(dev.id)"
@@ -21,8 +25,18 @@
</template>
</form-file>
</b-form-group>
+
+ <div
+ v-if="dev.isActive && dev.file && dev.file.name"
+ class="clear-selected-file px-3"
+ :style="{ 'margin-bottom': '1rem' }"
+ >
+ {{ dev.file.name }}
+ </div>
+
<b-button
v-if="!dev.isActive"
+ size="md"
variant="primary"
:disabled="!dev.file"
@click="startVM(dev)"
@@ -42,7 +56,7 @@
</page-section>
</b-col>
</b-row>
- <b-row v-if="loadImageFromExternalServer" class="mb-4">
+ <b-row v-if="loadImageFromExternalServer" class="bootstrap-table__section">
<b-col md="12">
<page-section
:section-title="$t('pageVirtualMedia.virtualMediaSubTitleSecond')"
@@ -56,34 +70,35 @@
<b-form-group
:label="device.id"
:label-for="device.id"
- label-class="bold"
+ label-class="regular-14px"
>
<b-button
variant="primary"
+ size="lg"
:disabled="device.isActive"
@click="configureConnection(device)"
>
{{ $t('pageVirtualMedia.configureConnection') }}
</b-button>
-
- <b-button
- v-if="!device.isActive"
- variant="primary"
- class="float-right"
- :disabled="!device.serverUri"
- @click="startLegacy(device)"
- >
- {{ $t('pageVirtualMedia.start') }}
- </b-button>
- <b-button
- v-if="device.isActive"
- variant="primary"
- class="float-right"
- @click="stopLegacy(device)"
- >
- {{ $t('pageVirtualMedia.stop') }}
- </b-button>
</b-form-group>
+
+ <b-button
+ v-if="!device.isActive"
+ variant="primary"
+ size="md"
+ :disabled="!device.serverUri"
+ @click="startLegacy(device)"
+ >
+ {{ $t('pageVirtualMedia.start') }}
+ </b-button>
+ <b-button
+ v-if="device.isActive"
+ size="md"
+ variant="primary"
+ @click="stopLegacy(device)"
+ >
+ {{ $t('pageVirtualMedia.stop') }}
+ </b-button>
</b-col>
</b-row>
</page-section>
@@ -107,7 +122,12 @@ import FormFile from '@/components/_sila/Global/FormFile';
export default {
name: 'VirtualMedia',
- components: { PageTitle, PageSection, ModalConfigureConnection, FormFile },
+ components: {
+ PageTitle,
+ PageSection,
+ ModalConfigureConnection,
+ FormFile,
+ },
mixins: [BVToastMixin, LoadingBarMixin],
data() {
return {
diff --git a/src/views/_sila/Overview/Inventory/index.js b/src/views/_sila/Overview/Inventory/index.js
index c9fde8d2..e69de29b 100644
--- a/src/views/_sila/Overview/Inventory/index.js
+++ b/src/views/_sila/Overview/Inventory/index.js
@@ -1,2 +0,0 @@
-import Inventory from './Inventory.vue';
-export default Inventory;
diff --git a/src/views/_sila/Overview/Network/index.js b/src/views/_sila/Overview/Network/index.js
index 97bf0397..e69de29b 100644
--- a/src/views/_sila/Overview/Network/index.js
+++ b/src/views/_sila/Overview/Network/index.js
@@ -1,2 +0,0 @@
-import Network from './Network.vue';
-export default Network;
diff --git a/src/views/_sila/Overview/Overview.vue b/src/views/_sila/Overview/Overview.vue
index 9f97fb3e..9960f373 100644
--- a/src/views/_sila/Overview/Overview.vue
+++ b/src/views/_sila/Overview/Overview.vue
@@ -26,7 +26,7 @@
</template>
<script>
-import LoadingBarMixin from '@/components/_sila/Mixins/LoadingBarMixin';
+import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
import OverviewDumps from './OverviewDumps.vue';
import OverviewEvents from './OverviewEvents.vue';
import OverviewFirmware from './OverviewFirmware.vue';
@@ -35,8 +35,8 @@ import OverviewNetwork from './OverviewNetwork';
import OverviewPower from './OverviewPower';
import OverviewQuickLinks from './OverviewQuickLinks';
import OverviewServer from './OverviewServer';
-import PageSection from '@/components/_sila/Global/PageSection';
-import PageTitle from '@/components/_sila/Global/PageTitle';
+import PageSection from '@/components/Global/PageSection';
+import PageTitle from '@/components/Global/PageTitle';
export default {
name: 'Overview',
diff --git a/src/views/_sila/Overview/OverviewDumps.vue b/src/views/_sila/Overview/OverviewDumps.vue
index 27f5067d..a2ae4e4e 100644
--- a/src/views/_sila/Overview/OverviewDumps.vue
+++ b/src/views/_sila/Overview/OverviewDumps.vue
@@ -20,7 +20,7 @@
<script>
import OverviewCard from './OverviewCard';
-import DataFormatterMixin from '@/components/_sila/Mixins/DataFormatterMixin';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
export default {
name: 'Dumps',
diff --git a/src/views/_sila/Overview/OverviewEvents.vue b/src/views/_sila/Overview/OverviewEvents.vue
index c54bc5b9..b73c0b48 100644
--- a/src/views/_sila/Overview/OverviewEvents.vue
+++ b/src/views/_sila/Overview/OverviewEvents.vue
@@ -32,8 +32,8 @@
<script>
import OverviewCard from './OverviewCard';
-import StatusIcon from '@/components/_sila/Global/StatusIcon';
-import DataFormatterMixin from '@/components/_sila/Mixins/DataFormatterMixin';
+import StatusIcon from '@/components/Global/StatusIcon';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
export default {
name: 'Events',
diff --git a/src/views/_sila/Overview/OverviewFirmware.vue b/src/views/_sila/Overview/OverviewFirmware.vue
index 9167c75c..f1f9ce53 100644
--- a/src/views/_sila/Overview/OverviewFirmware.vue
+++ b/src/views/_sila/Overview/OverviewFirmware.vue
@@ -18,7 +18,7 @@
<script>
import OverviewCard from './OverviewCard';
-import DataFormatterMixin from '@/components/_sila/Mixins/DataFormatterMixin';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
export default {
name: 'Firmware',
diff --git a/src/views/_sila/Overview/OverviewNetwork.vue b/src/views/_sila/Overview/OverviewNetwork.vue
index 7010b991..b81e5c73 100644
--- a/src/views/_sila/Overview/OverviewNetwork.vue
+++ b/src/views/_sila/Overview/OverviewNetwork.vue
@@ -49,7 +49,7 @@
<script>
import OverviewCard from './OverviewCard';
-import DataFormatterMixin from '@/components/_sila/Mixins/DataFormatterMixin';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
export default {
name: 'Network',
diff --git a/src/views/_sila/Overview/OverviewPower.vue b/src/views/_sila/Overview/OverviewPower.vue
index ffda495f..0d84c76c 100644
--- a/src/views/_sila/Overview/OverviewPower.vue
+++ b/src/views/_sila/Overview/OverviewPower.vue
@@ -24,7 +24,7 @@
<script>
import OverviewCard from './OverviewCard';
-import DataFormatterMixin from '@/components/_sila/Mixins/DataFormatterMixin';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
import { mapGetters } from 'vuex';
export default {
diff --git a/src/views/_sila/Overview/OverviewQuickLinks.vue b/src/views/_sila/Overview/OverviewQuickLinks.vue
index 6f74fd91..bc579b03 100644
--- a/src/views/_sila/Overview/OverviewQuickLinks.vue
+++ b/src/views/_sila/Overview/OverviewQuickLinks.vue
@@ -27,7 +27,7 @@
<script>
import ArrowRight16 from '@carbon/icons-vue/es/arrow--right/16';
-import BVToastMixin from '@/components/_sila/Mixins/BVToastMixin';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
export default {
name: 'QuickLinks',
diff --git a/src/views/_sila/Overview/OverviewServer.vue b/src/views/_sila/Overview/OverviewServer.vue
index 7dded5ba..d066d391 100644
--- a/src/views/_sila/Overview/OverviewServer.vue
+++ b/src/views/_sila/Overview/OverviewServer.vue
@@ -1,7 +1,7 @@
<template>
<overview-card
:title="$t('pageOverview.serverInformation')"
- :to="`/hardware-inventory`"
+ :to="`/hardware-status/inventory`"
>
<b-row class="mt-3">
<b-col lg="6">
@@ -18,7 +18,7 @@
<script>
import OverviewCard from './OverviewCard';
-import DataFormatterMixin from '@/components/_sila/Mixins/DataFormatterMixin';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
import { mapState } from 'vuex';
export default {
diff --git a/src/views/_sila/PowerSupplies/DynamicInfo/PowerDynamicPage.vue b/src/views/_sila/PowerSupplies/DynamicInfo/PowerDynamicPage.vue
new file mode 100644
index 00000000..223570bf
--- /dev/null
+++ b/src/views/_sila/PowerSupplies/DynamicInfo/PowerDynamicPage.vue
@@ -0,0 +1,592 @@
+<template>
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title :description="$t('appNavigation.analyticalPanel')" />
+ <div class="notification-time__container">
+ <span class="semi-bold-12px">{{
+ $t('global.ariaLabel.notificationTime')
+ }}</span>
+ <div class="form-control notification-time">
+ <b-form-input
+ v-model="notificationInput"
+ type="number"
+ class="notification-time__input"
+ >
+ </b-form-input>
+ <button class="notification-button">
+ <img
+ class="notification-time__icon"
+ src="@/assets/images/refresh.svg"
+ />
+ </button>
+ </div>
+ </div>
+ <date-switch :switch-time-scale="switchTimeScale" :time-scale="timeScale" />
+ <!-- Temperature Section -->
+ <div class="page-collapse-decorator">
+ <b-button
+ v-b-toggle.toggle-collapse_1
+ variant="link"
+ class="collapse-button semi-bold-16px"
+ >
+ <img src="@/assets/images/temperature-icon.svg" />
+ <span class="bold-16px">{{ $t('subHeader.temperature') }}</span>
+ <component :is="iconChevronUp" class="icon-expand" />
+ </b-button>
+ <b-collapse id="toggle-collapse_1" class="nav-item__nav">
+ <!-- Temperature Limit Inputs -->
+ <div class="limit-container">
+ <div class="trmperature-limt">
+ <img src="@/assets/images/labels/non-normal.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.nonNormalMode')
+ }}</span>
+ <b-form-input
+ v-model="temperatureNonNormalInput"
+ type="number"
+ :min="0"
+ :max="temperatureCritical"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <div class="trmperature-limt">
+ <img src="@/assets/images/labels/critical.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.criticalMode')
+ }}</span>
+ <b-form-input
+ v-model="temperatureCritical"
+ type="number"
+ :min="temperatureNonNormalInput"
+ :max="temperatureWarningInput"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <div class="trmperature-limt">
+ <img src="@/assets/images/labels/warning.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.temperatureWarning')
+ }}</span>
+ <b-form-input
+ v-model="temperatureWarningInput"
+ type="number"
+ :min="temperatureCritical"
+ :max="100"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <b-button
+ class="save-button"
+ variant="primary"
+ @click="updateTemperature"
+ >
+ {{ $t('global.action.save') }}
+ </b-button>
+ </div>
+ <!-- Temperature Tables -->
+ <temperature-table
+ :time-scale="timeScale"
+ :warning="temperatureWarning"
+ :non-normal="temperatureNonNormal"
+ :critical="temperatureCritical"
+ />
+ <accessory-table :records="accessoryData.temperatureTable" />
+ </b-collapse>
+ </div>
+ <!-- using Section -->
+ <div class="page-collapse-decorator">
+ <b-button
+ v-b-toggle.toggle-collapse_2
+ variant="link"
+ class="collapse-button semi-bold-16px"
+ >
+ <img src="@/assets/images/usage-icon.svg" />
+ <span class="bold-16px">{{ $t('pagePower.usingPercent') }}</span>
+ <component :is="iconChevronUp" class="icon-expand" />
+ </b-button>
+ <b-collapse id="toggle-collapse_2" class="nav-item__nav">
+ <!-- using Limit Inputs -->
+ <div class="limit-container">
+ <div class="trmperature-limt">
+ <img src="@/assets/images/labels/warning.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.warningPercent')
+ }}</span>
+ <b-form-input
+ v-model="usingNonNormalInput"
+ type="number"
+ :min="0"
+ :max="usingCritical"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <div class="trmperature-limt">
+ <img src="@/assets/images/labels/non-normal.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.nonNormalModePercent')
+ }}</span>
+ <b-form-input
+ v-model="usingCritical"
+ type="number"
+ :min="usingNonNormalInput"
+ :max="usingWarningInput"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <div class="trmperature-limt">
+ <img src="@/assets/images/labels/critical.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.criticalModePercent')
+ }}</span>
+ <b-form-input
+ v-model="usingWarningInput"
+ type="number"
+ :min="usingCritical"
+ :max="100"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <b-button class="save-button" variant="primary" @click="updateUsage">
+ {{ $t('global.action.save') }}
+ </b-button>
+ </div>
+ <!-- using Tables -->
+ <using-table
+ :time-scale="timeScale"
+ :warning="usingWarning"
+ :non-normal="usingNonNormal"
+ :critical-start="usingCritical"
+ />
+ <accessory-table :records="accessoryData.usingTable" />
+ </b-collapse>
+ </div>
+ <!-- Input Voltage Section -->
+ <div class="page-collapse-decorator">
+ <b-button
+ v-b-toggle.toggle-collapse_3
+ variant="link"
+ class="collapse-button semi-bold-16px"
+ >
+ <img src="@/assets/images/voltage-icon.svg" />
+ <span class="bold-16px">{{
+ $t('tablesDescription.inputVoltage')
+ }}</span>
+ <component :is="iconChevronUp" class="icon-expand" />
+ </b-button>
+ <b-collapse id="toggle-collapse_3" class="nav-item__nav">
+ <div class="limit-container">
+ <div class="frequency-limt">
+ <img src="@/assets/images/labels/warning.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.voltageWarning')
+ }}</span>
+ <b-form-input
+ v-model="powerWarningInput"
+ type="number"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <div class="frequency-limt">
+ <img src="@/assets/images/labels/shutdown.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.voltageShutdown')
+ }}</span>
+ <b-form-input
+ v-model="powerShutdownInput"
+ type="number"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <b-button class="save-button" variant="primary" @click="updatePower">
+ {{ $t('global.action.save') }}
+ </b-button>
+ </div>
+ <!-- Input Voltage Tables -->
+ <voltage-table :time-scale="timeScale" :warning="frequencyWarning" />
+ <accessory-table :records="accessoryData.voltageTable" />
+ </b-collapse>
+ </div>
+ <!-- Input Power Section -->
+ <div class="page-collapse-decorator">
+ <b-button
+ v-b-toggle.toggle-collapse_4
+ variant="link"
+ class="collapse-button semi-bold-16px"
+ >
+ <img src="@/assets/images/power-icon.svg" />
+ <span class="bold-16px">{{ $t('tablesDescription.inputPower') }}</span>
+ <component :is="iconChevronUp" class="icon-expand" />
+ </b-button>
+ <b-collapse id="toggle-collapse_4" class="nav-item__nav">
+ <div class="limit-container">
+ <div class="frequency-limt">
+ <img src="@/assets/images/labels/warning.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.powerWarning')
+ }}</span>
+ <b-form-input
+ v-model="powerWarningInput"
+ type="number"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <div class="frequency-limt">
+ <img src="@/assets/images/labels/shutdown.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.powerShutdown')
+ }}</span>
+ <b-form-input
+ v-model="powerShutdownInput"
+ type="number"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <b-button class="save-button" variant="primary" @click="updatePower">
+ {{ $t('global.action.save') }}
+ </b-button>
+ </div>
+ <!-- Input Power Table -->
+ <power-table
+ :time-scale="timeScale"
+ :warning="powerWarning"
+ :shutdown="powerShutdown"
+ />
+ <accessory-table :records="accessoryData.powerTable" />
+ </b-collapse>
+ </div>
+ <!-- Output Voltage Section -->
+ <div class="page-collapse-decorator">
+ <b-button
+ v-b-toggle.toggle-collapse_5
+ variant="link"
+ class="collapse-button semi-bold-16px"
+ >
+ <img src="@/assets/images/voltage-icon.svg" />
+ <span class="bold-16px">{{
+ $t('tablesDescription.outputVoltage')
+ }}</span>
+ <component :is="iconChevronUp" class="icon-expand" />
+ </b-button>
+ <b-collapse id="toggle-collapse_5" class="nav-item__nav">
+ <div class="limit-container">
+ <div class="frequency-limt">
+ <img src="@/assets/images/labels/warning.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.voltageWarning')
+ }}</span>
+ <b-form-input
+ v-model="powerWarningInput"
+ type="number"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <div class="frequency-limt">
+ <img src="@/assets/images/labels/shutdown.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.voltageShutdown')
+ }}</span>
+ <b-form-input
+ v-model="powerShutdownInput"
+ type="number"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <b-button class="save-button" variant="primary" @click="updatePower">
+ {{ $t('global.action.save') }}
+ </b-button>
+ </div>
+ <!-- Output Voltage Tables -->
+ <voltage-table :time-scale="timeScale" :warning="frequencyWarning" />
+ <accessory-table :records="accessoryData.voltageTable" />
+ </b-collapse>
+ </div>
+ <!-- Output Power Section -->
+ <div class="page-collapse-decorator">
+ <b-button
+ v-b-toggle.toggle-collapse_6
+ variant="link"
+ class="collapse-button semi-bold-16px"
+ >
+ <img src="@/assets/images/power-icon.svg" />
+ <span class="bold-16px">{{ $t('tablesDescription.outputPower') }}</span>
+ <component :is="iconChevronUp" class="icon-expand" />
+ </b-button>
+ <b-collapse id="toggle-collapse_6" class="nav-item__nav">
+ <div class="limit-container">
+ <div class="frequency-limt">
+ <img src="@/assets/images/labels/warning.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.powerWarning')
+ }}</span>
+ <b-form-input
+ v-model="powerWarningInput"
+ type="number"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <div class="frequency-limt">
+ <img src="@/assets/images/labels/shutdown.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.powerShutdown')
+ }}</span>
+ <b-form-input
+ v-model="powerShutdownInput"
+ type="number"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <b-button class="save-button" variant="primary" @click="updatePower">
+ {{ $t('global.action.save') }}
+ </b-button>
+ </div>
+ <!-- Output Power Table -->
+ <power-table
+ :time-scale="timeScale"
+ :warning="powerWarning"
+ :shutdown="powerShutdown"
+ />
+ <accessory-table :records="accessoryData.powerTable" />
+ </b-collapse>
+ </div>
+ <!-- Amperage Section -->
+ <div class="page-collapse-decorator">
+ <b-button
+ v-b-toggle.toggle-collapse_7
+ variant="link"
+ class="collapse-button semi-bold-16px"
+ >
+ <img src="@/assets/images/amperage-icon.svg" />
+ <span class="bold-16px">{{ $t('tablesDescription.amperage') }}</span>
+ <component :is="iconChevronUp" class="icon-expand" />
+ </b-button>
+ <b-collapse id="toggle-collapse_7" class="nav-item__nav">
+ <div class="limit-container">
+ <div class="frequency-limt">
+ <img src="@/assets/images/labels/warning.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.voltageWarning')
+ }}</span>
+ <b-form-input
+ v-model="powerWarningInput"
+ type="number"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <div class="frequency-limt">
+ <img src="@/assets/images/labels/shutdown.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.voltageShutdown')
+ }}</span>
+ <b-form-input
+ v-model="powerShutdownInput"
+ type="number"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <b-button class="save-button" variant="primary" @click="updatePower">
+ {{ $t('global.action.save') }}
+ </b-button>
+ </div>
+ <!-- Amperage Table -->
+ <voltage-table :time-scale="timeScale" :warning="frequencyWarning" />
+ <accessory-table :records="accessoryData.voltageTable" />
+ </b-collapse>
+ </div>
+ </b-container>
+</template>
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import PageSection from '@/components/Global/PageSection';
+import DateSwitch from '@/components/Global/SilaComponents/DateSwitch';
+
+import TemperatureTable from './TemperatureTable';
+import UsingTable from './UsingTable';
+import PowerTable from './PowerTable';
+import VoltageTable from './VoltageTable';
+import AccessoryTable from '@/components/Global/SilaComponents/Tables/AccessoryTablePower';
+import iconChevronUp from '@carbon/icons-vue/es/chevron--up/16';
+
+import { AccessoryData } from './helpers';
+
+export default {
+ components: {
+ PageTitle,
+ PageSection,
+ DateSwitch,
+ TemperatureTable,
+ UsingTable,
+ PowerTable,
+ VoltageTable,
+ AccessoryTable,
+ },
+ data() {
+ return {
+ timeScale: 'hour',
+ temperatureNonNormalInput: 44,
+ temperatureNonNormal: 44,
+ temperatureCriticalInput: 55,
+ temperatureCritical: 55,
+ temperatureWarningInput: 72,
+ temperatureWarning: 72,
+ usingNonNormalInput: 50,
+ usingNonNormal: 50,
+ usingCriticalInput: 55,
+ usingCritical: 55,
+ usingWarningInput: 72,
+ usingWarning: 72,
+ // frequencyWarning: 660,
+ // frequencyWarningInput: 660,
+ powerWarning: 66,
+ powerWarningInput: 66,
+ powerShutdown: 88,
+ powerShutdownInput: 88,
+ notificationInput: 42,
+ accessoryData: AccessoryData,
+ iconChevronUp: iconChevronUp,
+ };
+ },
+ methods: {
+ switchTimeScale(period) {
+ this.timeScale = period;
+ },
+ updateTemperature() {
+ this.temperatureNonNormal = +this.temperatureNonNormalInput;
+ this.temperatureCritical = +this.temperatureCriticalInput;
+ this.temperatureWarning = +this.temperatureWarningInput;
+ },
+ updateUsage() {
+ this.usingNonNormal = +this.usingNonNormalInput;
+ this.usingCritical = +this.usingCriticalInput;
+ this.usingWarning = +this.usingWarningInput;
+ },
+ updateFrequency() {
+ this.frequencyWarning = +this.frequencyWarningInput;
+ },
+ updatePower() {
+ this.powerWarning = +this.powerWarningInput;
+ this.powerShutdown = +this.powerShutdownInput;
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+//nav items style
+.nav-item,
+.nav-link {
+ padding: 0;
+}
+.nav-item {
+ list-style-type: none;
+}
+
+a {
+ color: $text-primary !important;
+ &:hover {
+ color: $text-primary !important;
+ }
+}
+
+.notification-time__container {
+ position: absolute;
+ top: calc(#{$header-height});
+ right: 0px;
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: flex-start;
+ align-items: center;
+}
+
+.notification-time {
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: flex-start;
+ align-items: center;
+ border: none;
+ box-shadow: none;
+ border-radius: 8px;
+ margin: 12px 32px 12px 8px;
+ width: 236px;
+ height: 40px;
+ z-index: 1001;
+}
+
+.notification-time__icon {
+ width: 20px;
+ height: 20px;
+}
+
+.notification-time__input {
+ border: none;
+ background: none;
+ box-shadow: none;
+}
+
+.notification-button {
+ border: none;
+ background: none;
+}
+
+.semi-bold-12px {
+ z-index: 1001;
+}
+// temperature limit comtainer
+.limit-container {
+ height: 85px;
+ width: 100%;
+ padding: 0 32px 10px 32px;
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: flex-start;
+ align-items: flex-end;
+ gap: 24px;
+}
+
+.trmperature-limt {
+ height: 60px;
+ width: 100%;
+ max-width: 270px;
+ display: flex;
+ align-items: baseline;
+ flex-flow: row wrap;
+ gap: 8px;
+}
+
+.form-control {
+ height: 36px;
+ &.non-normal {
+ width: 125px;
+ }
+}
+.save-button {
+ width: 151px;
+ height: 36px;
+}
+
+.frequency-limt {
+ height: 60px;
+ width: 100%;
+ max-width: 288px;
+ display: flex;
+ align-items: baseline;
+ flex-flow: row wrap;
+ gap: 8px;
+}
+</style>
diff --git a/src/views/_sila/PowerSupplies/DynamicInfo/PowerTable.vue b/src/views/_sila/PowerSupplies/DynamicInfo/PowerTable.vue
new file mode 100644
index 00000000..4ccb8aac
--- /dev/null
+++ b/src/views/_sila/PowerSupplies/DynamicInfo/PowerTable.vue
@@ -0,0 +1,126 @@
+<template>
+ <div>
+ <highcharts :options="chartOptions.line" />
+ </div>
+</template>
+
+<script>
+import { setTime, Series, setCategories } from './helpers';
+import { Chart } from 'highcharts-vue';
+
+export default {
+ components: {
+ highcharts: Chart,
+ },
+ props: {
+ timeScale: {
+ type: String,
+ default: 'hour',
+ },
+ warning: {
+ type: Number,
+ default: 66,
+ },
+ shutdown: {
+ type: Number,
+ default: 88,
+ },
+ },
+ computed: {
+ chartOptions() {
+ return {
+ line: {
+ chart: {
+ type: 'line',
+ margin: [12, 50, 32, 60],
+ height: '320px',
+ },
+ title: null,
+ xAxis: {
+ categories: setTime(60, this.timeScale),
+ title: null,
+ labels: {
+ step: 6,
+ },
+ minorGridLineColor: '#1A3E5B1A',
+ },
+ yAxis: {
+ categories: setCategories(101, 'Вт'),
+ min: 0,
+ max: 100,
+ title: null,
+ minTickInterval: 25,
+ minorGridLineColor: '#1A3E5B1A',
+ plotLines: [
+ {
+ color: '#E11717',
+ dashStyle: 'solid',
+ value: this.warning,
+ zIndex: '1000',
+ width: 2,
+ label: {
+ text: 'Пороговое значения предупреждение',
+ align: 'right',
+ style: {
+ fontFamily: 'Inter',
+ fontSize: '12px',
+ fontStyle: 'normal',
+ fontWeight: '400',
+ lineHeight: '16px',
+ color: '#0C1C2999',
+ },
+ },
+ },
+ {
+ color: '#1A3E5B',
+ dashStyle: 'solid',
+ value: this.shutdown,
+ width: 2,
+ label: {
+ text: 'Пороговое значения отказ',
+ align: 'right',
+ style: {
+ fontFamily: 'Inter',
+ fontSize: '12px',
+ fontStyle: 'normal',
+ fontWeight: '400',
+ lineHeight: '16px',
+ color: '#0C1C2999',
+ },
+ },
+ },
+ ],
+ },
+ series: Series['power'].map((item) => ({
+ ...item,
+ marker: {
+ enabled: false,
+ },
+ })),
+ legend: {
+ enabled: false,
+ },
+ tooltip: {
+ enabled: false,
+ crosshairs: false,
+ },
+ plotOptions: {
+ series: {
+ showInLegend: true,
+ },
+ },
+ },
+ };
+ },
+ },
+};
+</script>
+<style lang="scss">
+.highcharts-credits {
+ display: none;
+}
+
+.highcharts-plot-line-label {
+ transform: translate(-15px, 0) !important;
+}
+</style>
diff --git a/src/views/_sila/PowerSupplies/DynamicInfo/TemperatureTable.vue b/src/views/_sila/PowerSupplies/DynamicInfo/TemperatureTable.vue
new file mode 100644
index 00000000..9ae92c06
--- /dev/null
+++ b/src/views/_sila/PowerSupplies/DynamicInfo/TemperatureTable.vue
@@ -0,0 +1,126 @@
+<template>
+ <div>
+ <highcharts :options="chartOptions.line" />
+ </div>
+</template>
+
+<script>
+import { setTime, Series, setCategories } from './helpers';
+import { Chart } from 'highcharts-vue';
+
+export default {
+ components: {
+ highcharts: Chart,
+ },
+ props: {
+ timeScale: {
+ type: String,
+ default: 'hour',
+ },
+ warning: {
+ type: Number,
+ default: 70,
+ },
+ nonNormal: {
+ type: Number,
+ default: 70,
+ },
+ critical: {
+ type: Number,
+ default: 70,
+ },
+ },
+ computed: {
+ chartOptions() {
+ return {
+ line: {
+ chart: {
+ type: 'line',
+ margin: [12, 50, 32, 60],
+ height: '320px',
+ },
+ title: null,
+ xAxis: {
+ categories: setTime(60, 'hour'),
+ title: null,
+ labels: {
+ step: 6,
+ },
+ minorGridLineColor: '#1A3E5B1A',
+ },
+ yAxis: {
+ categories: setCategories(101, 'С°'),
+ min: 0,
+ max: 100,
+ title: null,
+ minTickInterval: 25,
+ minorGridLineColor: '#1A3E5B1A',
+ plotLines: [
+ {
+ color: '#E11717',
+ dashStyle: 'solid',
+ value: this.warning,
+ zIndex: '1000',
+ width: 2,
+ label: {
+ text: 'Пороговое значение предупреждения, С°',
+ align: 'right',
+ style: {
+ fontFamily: 'Inter, sans-serif',
+ fontSize: '12px',
+ fontStyle: 'normal',
+ fontWeight: '400',
+ lineHeight: '16px',
+ color: '#0C1C2999',
+ },
+ },
+ },
+ ],
+ plotBands: [
+ {
+ color: '#F0AC0C1A',
+ dashStyle: 'solid',
+ from: this.nonNormal,
+ to: this.criticalStart,
+ },
+ {
+ color: '#FF41411A',
+ dashStyle: 'solid',
+ from: this.criticalStart,
+ to: this.warning,
+ },
+ ],
+ },
+ series: Series['temperature'].map((item) => ({
+ ...item,
+ marker: {
+ enabled: false,
+ },
+ })),
+ legend: {
+ enabled: false,
+ },
+ tooltip: {
+ enabled: false,
+ crosshairs: false,
+ },
+ plotOptions: {
+ series: {
+ showInLegend: true,
+ },
+ },
+ },
+ };
+ },
+ },
+};
+</script>
+<style lang="scss">
+.highcharts-credits {
+ display: none;
+}
+
+.highcharts-plot-line-label {
+ transform: translate(-15px, 0) !important;
+}
+</style>
diff --git a/src/views/_sila/PowerSupplies/DynamicInfo/UsingTable.vue b/src/views/_sila/PowerSupplies/DynamicInfo/UsingTable.vue
new file mode 100644
index 00000000..322a7f7b
--- /dev/null
+++ b/src/views/_sila/PowerSupplies/DynamicInfo/UsingTable.vue
@@ -0,0 +1,126 @@
+<template>
+ <div>
+ <highcharts :options="chartOptions.line" />
+ </div>
+</template>
+
+<script>
+import { setTime, Series, setCategories } from './helpers';
+import { Chart } from 'highcharts-vue';
+
+export default {
+ components: {
+ highcharts: Chart,
+ },
+ props: {
+ timeScale: {
+ type: String,
+ default: 'hour',
+ },
+ warning: {
+ type: Number,
+ default: 70,
+ },
+ nonNormal: {
+ type: Number,
+ default: 70,
+ },
+ criticalStart: {
+ type: Number,
+ default: 70,
+ },
+ },
+ computed: {
+ chartOptions() {
+ return {
+ line: {
+ chart: {
+ type: 'line',
+ margin: [12, 50, 32, 60],
+ height: '320px',
+ },
+ title: null,
+ xAxis: {
+ categories: setTime(60, 'hour'),
+ title: null,
+ labels: {
+ step: 6,
+ },
+ minorGridLineColor: '#1A3E5B1A',
+ },
+ yAxis: {
+ categories: setCategories(101, '%'),
+ min: 0,
+ max: 100,
+ title: null,
+ minTickInterval: 25,
+ minorGridLineColor: '#1A3E5B1A',
+ plotLines: [
+ {
+ color: '#E11717',
+ dashStyle: 'solid',
+ value: this.warning,
+ zIndex: '1000',
+ width: 2,
+ label: {
+ text: 'Пороговое значение предупреждения, %',
+ align: 'right',
+ style: {
+ fontFamily: 'Inter, sans-serif',
+ fontSize: '12px',
+ fontStyle: 'normal',
+ fontWeight: '400',
+ lineHeight: '16px',
+ color: '#0C1C2999',
+ },
+ },
+ },
+ ],
+ plotBands: [
+ {
+ color: '#F0AC0C1A',
+ dashStyle: 'solid',
+ from: this.nonNormal,
+ to: this.criticalStart,
+ },
+ {
+ color: '#FF41411A',
+ dashStyle: 'solid',
+ from: this.criticalStart,
+ to: this.warning,
+ },
+ ],
+ },
+ series: Series['temperature'].map((item) => ({
+ ...item,
+ marker: {
+ enabled: false,
+ },
+ })),
+ legend: {
+ enabled: false,
+ },
+ tooltip: {
+ enabled: false,
+ crosshairs: false,
+ },
+ plotOptions: {
+ series: {
+ showInLegend: true,
+ },
+ },
+ },
+ };
+ },
+ },
+};
+</script>
+<style lang="scss">
+.highcharts-credits {
+ display: none;
+}
+
+.highcharts-plot-line-label {
+ transform: translate(-15px, 0) !important;
+}
+</style>
diff --git a/src/views/_sila/PowerSupplies/DynamicInfo/VoltageTable.vue b/src/views/_sila/PowerSupplies/DynamicInfo/VoltageTable.vue
new file mode 100644
index 00000000..b7b2a973
--- /dev/null
+++ b/src/views/_sila/PowerSupplies/DynamicInfo/VoltageTable.vue
@@ -0,0 +1,126 @@
+<template>
+ <div>
+ <highcharts :options="chartOptions.line" />
+ </div>
+</template>
+
+<script>
+import { setTime, Series, setCategories } from './helpers';
+import { Chart } from 'highcharts-vue';
+
+export default {
+ components: {
+ highcharts: Chart,
+ },
+ props: {
+ timeScale: {
+ type: String,
+ default: 'hour',
+ },
+ warning: {
+ type: Number,
+ default: 66,
+ },
+ shutdown: {
+ type: Number,
+ default: 88,
+ },
+ },
+ computed: {
+ chartOptions() {
+ return {
+ line: {
+ chart: {
+ type: 'line',
+ margin: [12, 50, 32, 60],
+ height: '320px',
+ },
+ title: null,
+ xAxis: {
+ categories: setTime(60, this.timeScale),
+ title: null,
+ labels: {
+ step: 6,
+ },
+ minorGridLineColor: '#1A3E5B1A',
+ },
+ yAxis: {
+ categories: setCategories(101, 'В'),
+ min: 0,
+ max: 100,
+ title: null,
+ minTickInterval: 25,
+ minorGridLineColor: '#1A3E5B1A',
+ plotLines: [
+ {
+ color: '#E11717',
+ dashStyle: 'solid',
+ value: this.warning,
+ zIndex: '1000',
+ width: 2,
+ label: {
+ text: 'Пороговое значения предупреждение',
+ align: 'right',
+ style: {
+ fontFamily: 'Inter',
+ fontSize: '12px',
+ fontStyle: 'normal',
+ fontWeight: '400',
+ lineHeight: '16px',
+ color: '#0C1C2999',
+ },
+ },
+ },
+ {
+ color: '#1A3E5B',
+ dashStyle: 'solid',
+ value: this.shutdown,
+ width: 2,
+ label: {
+ text: 'Пороговое значения отказ',
+ align: 'right',
+ style: {
+ fontFamily: 'Inter',
+ fontSize: '12px',
+ fontStyle: 'normal',
+ fontWeight: '400',
+ lineHeight: '16px',
+ color: '#0C1C2999',
+ },
+ },
+ },
+ ],
+ },
+ series: Series['voltage'].map((item) => ({
+ ...item,
+ marker: {
+ enabled: false,
+ },
+ })),
+ legend: {
+ enabled: false,
+ },
+ tooltip: {
+ enabled: false,
+ crosshairs: false,
+ },
+ plotOptions: {
+ series: {
+ showInLegend: true,
+ },
+ },
+ },
+ };
+ },
+ },
+};
+</script>
+<style lang="scss">
+.highcharts-credits {
+ display: none;
+}
+
+.highcharts-plot-line-label {
+ transform: translate(-15px, 0) !important;
+}
+</style>
diff --git a/src/views/_sila/PowerSupplies/DynamicInfo/helpers.js b/src/views/_sila/PowerSupplies/DynamicInfo/helpers.js
new file mode 100644
index 00000000..1418411a
--- /dev/null
+++ b/src/views/_sila/PowerSupplies/DynamicInfo/helpers.js
@@ -0,0 +1,1526 @@
+export const colors = [
+ '#CB32F1',
+ '#F18638',
+ '#139BB9',
+ '#E1AB17',
+ '#175AE1',
+ '#13B937',
+];
+
+export const Series = {
+ temperature: [
+ {
+ name: 'Sean',
+ data: [
+ 10,
+ 10,
+ 10,
+ 30,
+ 10,
+ 10,
+ 10,
+ 37,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 25,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 35,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 45,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 50,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ ],
+ color: '#CB32F1',
+ },
+ {
+ name: 'Ivan',
+ data: [
+ 11,
+ 11,
+ 11,
+ 30,
+ 11,
+ 11,
+ 11,
+ 11,
+ 57,
+ 11,
+ 11,
+ 11,
+ 11,
+ 25,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 61,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 31,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 21,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 51,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ ],
+ color: '#175AE1',
+ },
+ {
+ name: 'Brendan',
+ data: [
+ 15,
+ 15,
+ 15,
+ 35,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 25,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 45,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 35,
+ 15,
+ 15,
+ 55,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ ],
+ color: '#B98D13',
+ },
+ {
+ name: 'Matteo',
+ data: [
+ 21,
+ 21,
+ 21,
+ 51,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 40,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 35,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 53,
+ 21,
+ 21,
+ 30,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ ],
+ color: '#13B937',
+ },
+ {
+ name: 'Joan',
+ data: [
+ 19,
+ 19,
+ 19,
+ 39,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 29,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 39,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 39,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 59,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ ],
+ color: '#F18638',
+ },
+ {
+ name: 'Avinash',
+ data: [
+ 16,
+ 16,
+ 16,
+ 56,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 26,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 26,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 76,
+ 16,
+ 16,
+ 16,
+ 16,
+ 46,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 46,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ ],
+ color: '#139BB9',
+ },
+ ],
+ //////////////////////////////voltage////////////////
+ voltage: [
+ {
+ name: 'Sean',
+ data: [
+ 16,
+ 16,
+ 16,
+ 46,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 26,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 26,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 56,
+ 16,
+ 26,
+ 16,
+ 16,
+ 36,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 46,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 36,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ ],
+ color: '#CB32F1',
+ },
+ {
+ name: 'Ivan',
+ data: [
+ 11,
+ 11,
+ 11,
+ 44,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 21,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 21,
+ 11,
+ 31,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 55,
+ 11,
+ 21,
+ 11,
+ 11,
+ 31,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 31,
+ 11,
+ 11,
+ 41,
+ 11,
+ 11,
+ 11,
+ 21,
+ 11,
+ 11,
+ 11,
+ 35,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ ],
+ color: '#175AE1',
+ },
+ {
+ name: 'Brendan',
+ data: [
+ 31,
+ 31,
+ 31,
+ 51,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 90,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 50,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 35,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 40,
+ 31,
+ 31,
+ 31,
+ 31,
+ 53,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ 31,
+ ],
+ color: '#B98D13',
+ },
+ {
+ name: 'Matteo',
+ data: [
+ 21,
+ 21,
+ 21,
+ 51,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 40,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 50,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 35,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 60,
+ 21,
+ 21,
+ 21,
+ 10,
+ 53,
+ 21,
+ 21,
+ 30,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ ],
+ color: '#13B937',
+ },
+ {
+ name: 'Joan',
+ data: [
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 39,
+ 19,
+ 19,
+ 39,
+ 19,
+ 19,
+ 19,
+ 29,
+ 19,
+ 19,
+ 59,
+ 19,
+ 19,
+ 69,
+ 19,
+ 19,
+ 19,
+ 19,
+ 29,
+ 19,
+ 19,
+ 49,
+ 19,
+ 19,
+ 59,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ ],
+ color: '#F18638',
+ },
+ {
+ name: 'Avinash',
+ data: [
+ 17,
+ 17,
+ 17,
+ 15,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 27,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 21,
+ 17,
+ 17,
+ 17,
+ 59,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 59,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 57,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 77,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ ],
+ color: '#139BB9',
+ },
+ ],
+ //////////////////////////////power////////////////
+ power: [
+ {
+ name: 'Sean',
+ data: [
+ 15,
+ 15,
+ 45,
+ 15,
+ 65,
+ 15,
+ 75,
+ 15,
+ 15,
+ 15,
+ 55,
+ 15,
+ 25,
+ 15,
+ 45,
+ 15,
+ 55,
+ 15,
+ 75,
+ 15,
+ 35,
+ 15,
+ 55,
+ 15,
+ 75,
+ 15,
+ 85,
+ 15,
+ 15,
+ 45,
+ 15,
+ 15,
+ 45,
+ 15,
+ 45,
+ 15,
+ 15,
+ 65,
+ 15,
+ 45,
+ 15,
+ 25,
+ 15,
+ 45,
+ 15,
+ 65,
+ 15,
+ 35,
+ 35,
+ 35,
+ 15,
+ 55,
+ 15,
+ 15,
+ 35,
+ 15,
+ 25,
+ 15,
+ 35,
+ 15,
+ ],
+ color: '#CB32F1',
+ },
+ {
+ name: 'Ivan',
+ data: [
+ 62,
+ 12,
+ 72,
+ 12,
+ 12,
+ 12,
+ 42,
+ 12,
+ 12,
+ 12,
+ 52,
+ 12,
+ 22,
+ 12,
+ 42,
+ 12,
+ 52,
+ 12,
+ 72,
+ 12,
+ 52,
+ 12,
+ 62,
+ 12,
+ 72,
+ 12,
+ 82,
+ 12,
+ 12,
+ 42,
+ 12,
+ 12,
+ 52,
+ 12,
+ 42,
+ 12,
+ 12,
+ 62,
+ 12,
+ 42,
+ 12,
+ 22,
+ 12,
+ 42,
+ 12,
+ 62,
+ 12,
+ 12,
+ 32,
+ 12,
+ 62,
+ 12,
+ 52,
+ 12,
+ 32,
+ 12,
+ 22,
+ 12,
+ 32,
+ 12,
+ ],
+ color: '#175AE1',
+ },
+ {
+ name: 'Brendan',
+ data: [
+ 14,
+ 14,
+ 34,
+ 14,
+ 24,
+ 14,
+ 34,
+ 14,
+ 64,
+ 14,
+ 74,
+ 14,
+ 14,
+ 14,
+ 44,
+ 14,
+ 14,
+ 14,
+ 54,
+ 14,
+ 24,
+ 14,
+ 44,
+ 14,
+ 54,
+ 14,
+ 74,
+ 14,
+ 54,
+ 14,
+ 64,
+ 14,
+ 74,
+ 14,
+ 84,
+ 14,
+ 14,
+ 44,
+ 14,
+ 14,
+ 54,
+ 14,
+ 44,
+ 14,
+ 14,
+ 64,
+ 14,
+ 44,
+ 14,
+ 24,
+ 14,
+ 44,
+ 14,
+ 64,
+ 14,
+ 14,
+ 14,
+ 54,
+ 14,
+ 54,
+ ],
+ color: '#B98D13',
+ },
+ {
+ name: 'Matteo',
+ data: [
+ 24,
+ 14,
+ 44,
+ 14,
+ 64,
+ 14,
+ 64,
+ 14,
+ 34,
+ 14,
+ 54,
+ 14,
+ 14,
+ 34,
+ 14,
+ 24,
+ 14,
+ 34,
+ 14,
+ 64,
+ 14,
+ 74,
+ 14,
+ 14,
+ 14,
+ 44,
+ 14,
+ 14,
+ 14,
+ 54,
+ 14,
+ 14,
+ 14,
+ 44,
+ 14,
+ 54,
+ 14,
+ 74,
+ 14,
+ 54,
+ 14,
+ 64,
+ 14,
+ 74,
+ 14,
+ 84,
+ 14,
+ 94,
+ 14,
+ 54,
+ 4,
+ 54,
+ 14,
+ 44,
+ 14,
+ 44,
+ 64,
+ 14,
+ 44,
+ 14,
+ ],
+ color: '#13B937',
+ },
+ {
+ name: 'Joan',
+ data: [
+ 16,
+ 46,
+ 16,
+ 26,
+ 16,
+ 46,
+ 16,
+ 66,
+ 16,
+ 16,
+ 16,
+ 36,
+ 16,
+ 56,
+ 16,
+ 16,
+ 36,
+ 16,
+ 26,
+ 16,
+ 36,
+ 16,
+ 66,
+ 16,
+ 76,
+ 16,
+ 16,
+ 16,
+ 46,
+ 16,
+ 16,
+ 16,
+ 56,
+ 16,
+ 26,
+ 16,
+ 46,
+ 16,
+ 56,
+ 16,
+ 76,
+ 16,
+ 56,
+ 16,
+ 66,
+ 16,
+ 76,
+ 16,
+ 86,
+ 16,
+ 96,
+ 16,
+ 16,
+ 16,
+ 56,
+ 16,
+ 46,
+ 16,
+ 46,
+ 16,
+ ],
+ color: '#F18638',
+ },
+ {
+ name: 'Avinash',
+ data: [
+ 49,
+ 19,
+ 19,
+ 69,
+ 19,
+ 49,
+ 19,
+ 29,
+ 19,
+ 49,
+ 19,
+ 69,
+ 19,
+ 39,
+ 39,
+ 39,
+ 19,
+ 59,
+ 19,
+ 19,
+ 39,
+ 19,
+ 29,
+ 19,
+ 39,
+ 19,
+ 69,
+ 19,
+ 79,
+ 19,
+ 19,
+ 19,
+ 49,
+ 19,
+ 19,
+ 19,
+ 59,
+ 19,
+ 29,
+ 19,
+ 49,
+ 19,
+ 59,
+ 19,
+ 79,
+ 19,
+ 59,
+ 19,
+ 69,
+ 19,
+ 79,
+ 19,
+ 89,
+ 19,
+ 99,
+ 19,
+ 19,
+ 69,
+ 59,
+ 19,
+ ],
+ color: '#139BB9',
+ },
+ ],
+};
+
+export const setTime = (count) => {
+ const arr = [...new Array(count)].map(() => '');
+ for (let i = 0; i < arr.length; i++) {
+ arr[i] = `15:${String(i).padStart(2, '0')}`;
+ }
+ return arr;
+};
+
+export const setCategories = (count, desc) => {
+ const arr = [...new Array(count)].map((i, k) => `${k} ${desc}`);
+ return arr;
+};
+
+export const AccessoryData = {
+ temperatureTable: {
+ fields: [
+ {
+ key: 'name',
+ label: 'Имя модуля',
+ },
+ {
+ key: 'currentTemperature',
+ label: 'Текущее, С°',
+ },
+ {
+ key: 'middleTemperature',
+ label: 'Среднее, С°',
+ },
+ {
+ key: 'minTemperature',
+ label: 'Минимальное, С°',
+ },
+ {
+ key: 'minDate',
+ label: 'Дата минимального',
+ },
+ {
+ key: 'maxTemperature',
+ label: 'Максимальное, С°',
+ },
+ {
+ key: 'maxDate',
+ label: 'Дата максимального',
+ },
+ ],
+ items: [
+ {
+ name: 'Источник 1',
+ currentTemperature: 19,
+ middleTemperature: 40,
+ minTemperature: 31,
+ minDate: { time: '15:15', date: '11.11.2021' },
+ maxTemperature: 88,
+ maxDate: { time: '10:26', date: '15.11.2021' },
+ },
+ {
+ name: 'Источник 2',
+ currentTemperature: 29,
+ middleTemperature: 40,
+ minTemperature: 20,
+ minDate: { time: '15:45', date: '11.11.2021' },
+ maxTemperature: 76,
+ maxDate: { time: '16:59', date: '16.11.2021' },
+ },
+ {
+ name: 'Источник 3',
+ currentTemperature: 48,
+ middleTemperature: 46,
+ minTemperature: 31,
+ minDate: { time: '15:23', date: '11.11.2021' },
+ maxTemperature: 69,
+ maxDate: { time: '15:26', date: '15.11.2021' },
+ },
+ {
+ name: 'Источник 4',
+ currentTemperature: 48,
+ middleTemperature: 45,
+ minTemperature: 5,
+ minDate: { time: '16:45', date: '25.11.2021' },
+ maxTemperature: 75,
+ maxDate: { time: '11:26', date: '16.11.2021' },
+ },
+ {
+ name: 'Источник 5',
+ currentTemperature: 39,
+ middleTemperature: 44,
+ minTemperature: 30,
+ minDate: { time: '15:23', date: '11.11.2021' },
+ maxTemperature: 80,
+ maxDate: { time: '15:26', date: '17.11.2021' },
+ },
+ {
+ name: 'Источник 6',
+ currentTemperature: 39,
+ middleTemperature: 44,
+ minTemperature: 5,
+ minDate: { time: '16:45', date: '25.11.2021' },
+ maxTemperature: 80,
+ maxDate: { time: '15:26', date: '15.11.2021' },
+ },
+ ],
+ },
+ usingTable: {
+ fields: [
+ {
+ key: 'name',
+ label: 'Имя модуля',
+ },
+ {
+ key: 'currentTemperature',
+ label: 'Текущее, %',
+ },
+ {
+ key: 'middleTemperature',
+ label: 'Среднее, %',
+ },
+ {
+ key: 'minTemperature',
+ label: 'Минимальное, %',
+ },
+ {
+ key: 'minDate',
+ label: 'Дата минимального',
+ },
+ {
+ key: 'maxTemperature',
+ label: 'Максимальное, %',
+ },
+ {
+ key: 'maxDate',
+ label: 'Дата максимального',
+ },
+ ],
+ items: [
+ {
+ name: 'Источник 1',
+ currentTemperature: 19,
+ middleTemperature: 40,
+ minTemperature: 31,
+ minDate: { time: '15:15', date: '11.11.2021' },
+ maxTemperature: 88,
+ maxDate: { time: '10:26', date: '15.11.2021' },
+ },
+ {
+ name: 'Источник 2',
+ currentTemperature: 29,
+ middleTemperature: 40,
+ minTemperature: 20,
+ minDate: { time: '15:45', date: '11.11.2021' },
+ maxTemperature: 76,
+ maxDate: { time: '16:59', date: '16.11.2021' },
+ },
+ {
+ name: 'Источник 3',
+ currentTemperature: 48,
+ middleTemperature: 46,
+ minTemperature: 31,
+ minDate: { time: '15:23', date: '11.11.2021' },
+ maxTemperature: 69,
+ maxDate: { time: '15:26', date: '15.11.2021' },
+ },
+ {
+ name: 'Источник 4',
+ currentTemperature: 48,
+ middleTemperature: 45,
+ minTemperature: 5,
+ minDate: { time: '16:45', date: '25.11.2021' },
+ maxTemperature: 75,
+ maxDate: { time: '11:26', date: '16.11.2021' },
+ },
+ {
+ name: 'Источник 5',
+ currentTemperature: 39,
+ middleTemperature: 44,
+ minTemperature: 30,
+ minDate: { time: '15:23', date: '11.11.2021' },
+ maxTemperature: 80,
+ maxDate: { time: '15:26', date: '17.11.2021' },
+ },
+ {
+ name: 'Источник 6',
+ currentTemperature: 39,
+ middleTemperature: 44,
+ minTemperature: 5,
+ minDate: { time: '16:45', date: '25.11.2021' },
+ maxTemperature: 80,
+ maxDate: { time: '15:26', date: '15.11.2021' },
+ },
+ ],
+ },
+ voltageTable: {
+ fields: [
+ {
+ key: 'name',
+ label: 'Имя модуля',
+ },
+ {
+ key: 'currentTemperature',
+ label: 'Текущее, В',
+ },
+ {
+ key: 'middleTemperature',
+ label: 'Среднее, В',
+ },
+ {
+ key: 'minTemperature',
+ label: 'Минимальное, В',
+ },
+ {
+ key: 'minDate',
+ label: 'Дата минимального',
+ },
+ {
+ key: 'maxTemperature',
+ label: 'Максимальное, В',
+ },
+ {
+ key: 'maxDate',
+ label: 'Дата максимального',
+ },
+ ],
+ items: [
+ {
+ name: 'Источник 1',
+ currentTemperature: 19,
+ middleTemperature: 40,
+ minTemperature: 31,
+ minDate: { time: '15:15', date: '11.11.2021' },
+ maxTemperature: 88,
+ maxDate: { time: '10:26', date: '15.11.2021' },
+ },
+ {
+ name: 'Источник 2',
+ currentTemperature: 29,
+ middleTemperature: 40,
+ minTemperature: 20,
+ minDate: { time: '15:45', date: '11.11.2021' },
+ maxTemperature: 76,
+ maxDate: { time: '16:59', date: '16.11.2021' },
+ },
+ {
+ name: 'Источник 3',
+ currentTemperature: 48,
+ middleTemperature: 46,
+ minTemperature: 31,
+ minDate: { time: '15:23', date: '11.11.2021' },
+ maxTemperature: 69,
+ maxDate: { time: '15:26', date: '15.11.2021' },
+ },
+ {
+ name: 'Источник 4',
+ currentTemperature: 48,
+ middleTemperature: 45,
+ minTemperature: 5,
+ minDate: { time: '16:45', date: '25.11.2021' },
+ maxTemperature: 75,
+ maxDate: { time: '11:26', date: '16.11.2021' },
+ },
+ {
+ name: 'Источник 5',
+ currentTemperature: 39,
+ middleTemperature: 44,
+ minTemperature: 30,
+ minDate: { time: '15:23', date: '11.11.2021' },
+ maxTemperature: 80,
+ maxDate: { time: '15:26', date: '17.11.2021' },
+ },
+ {
+ name: 'Источник 6',
+ currentTemperature: 39,
+ middleTemperature: 44,
+ minTemperature: 5,
+ minDate: { time: '16:45', date: '25.11.2021' },
+ maxTemperature: 80,
+ maxDate: { time: '15:26', date: '15.11.2021' },
+ },
+ ],
+ },
+ powerTable: {
+ fields: [
+ {
+ key: 'name',
+ label: 'Имя модуля',
+ },
+ {
+ key: 'currentPower',
+ label: 'Текущее, Вт',
+ label2: '',
+ },
+ ],
+ items: [
+ {
+ name: 'Источник 1',
+ currentPower: 91,
+ },
+ {
+ name: 'Источник 2',
+ currentPower: 77,
+ },
+ {
+ name: 'Источник 3',
+ currentPower: 76,
+ },
+ {
+ name: 'Источник 4',
+ currentPower: 74,
+ },
+ {
+ name: 'Источник 5',
+ currentPower: 73,
+ },
+ {
+ name: 'Источник 6',
+ currentPower: 71,
+ },
+ ],
+ },
+};
diff --git a/src/views/_sila/PowerSupplies/DynamicInfo/index.js b/src/views/_sila/PowerSupplies/DynamicInfo/index.js
new file mode 100644
index 00000000..c45d5c89
--- /dev/null
+++ b/src/views/_sila/PowerSupplies/DynamicInfo/index.js
@@ -0,0 +1,2 @@
+import PowerDynamicPage from './PowerDynamicPage.vue';
+export default PowerDynamicPage;
diff --git a/src/views/_sila/PowerSupplies/Specification/PowerStaticPage.vue b/src/views/_sila/PowerSupplies/Specification/PowerStaticPage.vue
new file mode 100644
index 00000000..10bf1457
--- /dev/null
+++ b/src/views/_sila/PowerSupplies/Specification/PowerStaticPage.vue
@@ -0,0 +1,137 @@
+<template>
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title :description="$t('appNavigation.specification')" />
+ <page-section class="bootstrap-table__section info_section">
+ <span class="bold-16px">{{ $t('pageInventory.powerSources') }}</span>
+ </page-section>
+ <data-tabs
+ :slots="sourceSlots"
+ :switch-tab="switchSourceSlot"
+ :current-tab="currentSourceSlot"
+ :slot-width="100"
+ :slider-width="68"
+ />
+ <page-section class="bootstrap-table__section">
+ <b-table
+ responsive="md"
+ show-empty
+ class="table-rounded"
+ no-border-collapse
+ :items="items_slots"
+ :fields="fields"
+ :empty-text="$t('global.table.emptyMessage')"
+ >
+ <template #cell(value)="{ index, value }">
+ <b-row v-if="index === 0">
+ <b-col cols="11">
+ <span>
+ {{ 'Работоспособность' }}
+ </span>
+ </b-col>
+ <b-col cols="1">
+ <img src="@/assets/images/status/on.svg" class="icon-chevron" />
+ </b-col>
+ </b-row>
+ <b-row v-else>
+ <b-col>
+ <span>{{ value }}</span>
+ </b-col>
+ </b-row>
+ </template>
+ </b-table>
+ </page-section>
+ </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import PageSection from '@/components/Global/PageSection';
+import DataTabs from '@/components/Global/SilaComponents/DataTabs';
+
+export default {
+ components: { PageTitle, PageSection, DataTabs },
+ data() {
+ return {
+ currentSourceSlot: 1,
+ sourceSlots: [
+ { id: 1, name: 'Источник 1' },
+ { id: 2, name: 'Источник 2' },
+ { id: 3, name: 'Источник 3' },
+ { id: 4, name: 'Источник 4' },
+ { id: 5, name: 'Источник 5' },
+ { id: 6, name: 'Источник 6' },
+ { id: 7, name: 'Источник 7' },
+ { id: 8, name: 'Источник 8' },
+ { id: 9, name: 'Источник 9' },
+ { id: 10, name: 'Источник 10' },
+ { id: 11, name: 'Источник 11' },
+ { id: 12, name: 'Источник 12' },
+ { id: 13, name: 'Источник 13' },
+ { id: 14, name: 'Источник 14' },
+ { id: 15, name: 'Источник 15' },
+ ],
+ fields: [
+ {
+ key: 'parametr',
+ label: 'Параметр',
+ formatter: this.dataFormatter,
+ thStyle: { width: '50%' },
+ },
+ {
+ key: 'value',
+ label: 'Значение',
+ formatter: this.dataFormatter,
+ },
+ ],
+ items_slots: [
+ {
+ parametr: 'Статус',
+ value: true,
+ },
+ {
+ parametr: 'Название',
+ value: 'Источник 1',
+ },
+ {
+ parametr: 'Версия прошивки',
+ value: '1.1.2257',
+ },
+ {
+ parametr: 'Серийный номер',
+ value: '4789564478551',
+ },
+ {
+ parametr: 'Номинальное напряжение',
+ value: '220 В',
+ },
+ {
+ parametr: 'Номинальная мощность',
+ value: '400 Вт',
+ },
+ {
+ parametr: 'Поддержка горячей замены',
+ value: 'Есть',
+ },
+ ],
+ };
+ },
+ methods: {
+ switchSourceSlot(period) {
+ this.currentSourceSlot = period;
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+.info_section {
+ margin-bottom: 0px;
+}
+
+.bold-16px {
+ display: block;
+ margin: 25px 0 16px 0;
+}
+</style>
diff --git a/src/views/_sila/PowerSupplies/Specification/index.js b/src/views/_sila/PowerSupplies/Specification/index.js
new file mode 100644
index 00000000..14c4ef64
--- /dev/null
+++ b/src/views/_sila/PowerSupplies/Specification/index.js
@@ -0,0 +1,2 @@
+import PowerStaticPage from './PowerStaticPage.vue';
+export default PowerStaticPage;
diff --git a/src/views/_sila/Processors/DynamicInfo/FrequencyTable.vue b/src/views/_sila/Processors/DynamicInfo/FrequencyTable.vue
new file mode 100644
index 00000000..c749905d
--- /dev/null
+++ b/src/views/_sila/Processors/DynamicInfo/FrequencyTable.vue
@@ -0,0 +1,107 @@
+<template>
+ <div>
+ <highcharts :options="chartOptions.line" />
+ </div>
+</template>
+
+<script>
+import { setTime, Series, setCategories } from './helpers';
+import { Chart } from 'highcharts-vue';
+
+export default {
+ components: {
+ highcharts: Chart,
+ },
+ props: {
+ timeScale: {
+ type: String,
+ default: 'hour',
+ },
+ warning: {
+ type: Number,
+ default: 70,
+ },
+ },
+ computed: {
+ chartOptions() {
+ return {
+ line: {
+ chart: {
+ type: 'line',
+ margin: [12, 50, 32, 60],
+ height: '320px',
+ },
+ title: null,
+ xAxis: {
+ categories: setTime(60, 'hour'),
+ title: null,
+ labels: {
+ step: 6,
+ },
+ minorGridLineColor: '#1A3E5B1A',
+ },
+ yAxis: {
+ categories: setCategories(1001, 'Hz'),
+ min: 0,
+ max: 1000,
+ title: null,
+ minTickInterval: 250,
+ minorGridLineColor: '#1A3E5B1A',
+ labels: {
+ padding: 4,
+ },
+ plotLines: [
+ {
+ color: '#E11717',
+ dashStyle: 'solid',
+ value: this.warning,
+ zIndex: '1000',
+ width: 2,
+ label: {
+ text: 'Пороговое значение предупреждения',
+ align: 'right',
+ style: {
+ fontFamily: 'Inter, sans-serif',
+ fontSize: '12px',
+ fontStyle: 'normal',
+ fontWeight: '400',
+ lineHeight: '16px',
+ color: '#0C1C2999',
+ },
+ },
+ },
+ ],
+ },
+ series: Series['frequency'].map((item) => ({
+ ...item,
+ marker: {
+ enabled: false,
+ },
+ })),
+ legend: {
+ enabled: false,
+ },
+ tooltip: {
+ enabled: false,
+ crosshairs: false,
+ },
+ plotOptions: {
+ series: {
+ showInLegend: true,
+ },
+ },
+ },
+ };
+ },
+ },
+};
+</script>
+<style lang="scss">
+.highcharts-credits {
+ display: none;
+}
+
+.highcharts-plot-line-label {
+ transform: translate(-15px, 0) !important;
+}
+</style>
diff --git a/src/views/_sila/Processors/DynamicInfo/PowerTable.vue b/src/views/_sila/Processors/DynamicInfo/PowerTable.vue
new file mode 100644
index 00000000..4ccb8aac
--- /dev/null
+++ b/src/views/_sila/Processors/DynamicInfo/PowerTable.vue
@@ -0,0 +1,126 @@
+<template>
+ <div>
+ <highcharts :options="chartOptions.line" />
+ </div>
+</template>
+
+<script>
+import { setTime, Series, setCategories } from './helpers';
+import { Chart } from 'highcharts-vue';
+
+export default {
+ components: {
+ highcharts: Chart,
+ },
+ props: {
+ timeScale: {
+ type: String,
+ default: 'hour',
+ },
+ warning: {
+ type: Number,
+ default: 66,
+ },
+ shutdown: {
+ type: Number,
+ default: 88,
+ },
+ },
+ computed: {
+ chartOptions() {
+ return {
+ line: {
+ chart: {
+ type: 'line',
+ margin: [12, 50, 32, 60],
+ height: '320px',
+ },
+ title: null,
+ xAxis: {
+ categories: setTime(60, this.timeScale),
+ title: null,
+ labels: {
+ step: 6,
+ },
+ minorGridLineColor: '#1A3E5B1A',
+ },
+ yAxis: {
+ categories: setCategories(101, 'Вт'),
+ min: 0,
+ max: 100,
+ title: null,
+ minTickInterval: 25,
+ minorGridLineColor: '#1A3E5B1A',
+ plotLines: [
+ {
+ color: '#E11717',
+ dashStyle: 'solid',
+ value: this.warning,
+ zIndex: '1000',
+ width: 2,
+ label: {
+ text: 'Пороговое значения предупреждение',
+ align: 'right',
+ style: {
+ fontFamily: 'Inter',
+ fontSize: '12px',
+ fontStyle: 'normal',
+ fontWeight: '400',
+ lineHeight: '16px',
+ color: '#0C1C2999',
+ },
+ },
+ },
+ {
+ color: '#1A3E5B',
+ dashStyle: 'solid',
+ value: this.shutdown,
+ width: 2,
+ label: {
+ text: 'Пороговое значения отказ',
+ align: 'right',
+ style: {
+ fontFamily: 'Inter',
+ fontSize: '12px',
+ fontStyle: 'normal',
+ fontWeight: '400',
+ lineHeight: '16px',
+ color: '#0C1C2999',
+ },
+ },
+ },
+ ],
+ },
+ series: Series['power'].map((item) => ({
+ ...item,
+ marker: {
+ enabled: false,
+ },
+ })),
+ legend: {
+ enabled: false,
+ },
+ tooltip: {
+ enabled: false,
+ crosshairs: false,
+ },
+ plotOptions: {
+ series: {
+ showInLegend: true,
+ },
+ },
+ },
+ };
+ },
+ },
+};
+</script>
+<style lang="scss">
+.highcharts-credits {
+ display: none;
+}
+
+.highcharts-plot-line-label {
+ transform: translate(-15px, 0) !important;
+}
+</style>
diff --git a/src/views/_sila/Processors/DynamicInfo/ProcessorsDynamicPage.vue b/src/views/_sila/Processors/DynamicInfo/ProcessorsDynamicPage.vue
new file mode 100644
index 00000000..7e0b16a4
--- /dev/null
+++ b/src/views/_sila/Processors/DynamicInfo/ProcessorsDynamicPage.vue
@@ -0,0 +1,361 @@
+<template>
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title :description="$t('appNavigation.analyticalPanel')" />
+ <div class="notification-time__container">
+ <span class="semi-bold-12px">{{
+ $t('global.ariaLabel.notificationTime')
+ }}</span>
+ <div class="form-control notification-time">
+ <b-form-input
+ v-model="notificationInput"
+ type="number"
+ class="notification-time__input"
+ >
+ </b-form-input>
+ <button class="notification-button">
+ <img
+ class="notification-time__icon"
+ src="@/assets/images/refresh.svg"
+ />
+ </button>
+ </div>
+ </div>
+ <date-switch :switch-time-scale="switchTimeScale" :time-scale="timeScale" />
+ <!-- Temperature Section -->
+ <div class="page-collapse-decorator">
+ <b-button
+ v-b-toggle.toggle-collapse_1
+ variant="link"
+ class="collapse-button semi-bold-16px"
+ >
+ <img src="@/assets/images/temperature-icon.svg" />
+ <span class="bold-16px">{{ $t('subHeader.temperature') }}</span>
+ <component :is="iconChevronUp" class="icon-expand" />
+ </b-button>
+ <b-collapse id="toggle-collapse_1" class="nav-item__nav">
+ <!-- Temperature Limit Inputs -->
+ <div class="limit-container">
+ <div class="trmperature-limt">
+ <img src="@/assets/images/labels/non-normal.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.nonNormalMode')
+ }}</span>
+ <b-form-input
+ v-model="temperatureNonNormalInput"
+ type="number"
+ :min="0"
+ :max="temperatureCriticalInput"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <div class="trmperature-limt">
+ <img src="@/assets/images/labels/critical.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.criticalMode')
+ }}</span>
+ <b-form-input
+ v-model="temperatureCriticalInput"
+ type="number"
+ :min="temperatureNonNormalInput"
+ :max="temperatureWarningInput"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <div class="trmperature-limt">
+ <img src="@/assets/images/labels/warning.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.temperatureWarning')
+ }}</span>
+ <b-form-input
+ v-model="temperatureWarningInput"
+ type="number"
+ :min="temperatureCriticalInput"
+ :max="100"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <b-button
+ class="save-button"
+ variant="primary"
+ @click="updateTemperature"
+ >
+ {{ $t('global.action.save') }}
+ </b-button>
+ </div>
+ <!-- Temperature Tables -->
+ <temperature-table
+ :time-scale="timeScale"
+ :warning="temperatureWarning"
+ :non-normal="temperatureNonNormal"
+ :critical-start="temperatureCritical"
+ />
+ <accessory-table :records="accessoryData.temperatureTable" />
+ </b-collapse>
+ </div>
+ <!-- Frequency Section -->
+ <div class="page-collapse-decorator">
+ <b-button
+ v-b-toggle.toggle-collapse_2
+ variant="link"
+ class="collapse-button semi-bold-16px"
+ >
+ <img src="@/assets/images/frequency-icon.svg" />
+ <span class="bold-16px">{{ $t('subHeader.frequency') }}</span>
+ <component :is="iconChevronUp" class="icon-expand" />
+ </b-button>
+ <b-collapse id="toggle-collapse_2" class="nav-item__nav">
+ <div class="limit-container">
+ <div class="frequency-limt">
+ <img src="@/assets/images/labels/warning.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.frequencyWarning')
+ }}</span>
+ <b-form-input
+ v-model="frequencyWarningInput"
+ :min="0"
+ :max="1000"
+ type="number"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <b-button
+ class="save-button"
+ variant="primary"
+ @click="updateFrequency"
+ >
+ {{ $t('global.action.save') }}
+ </b-button>
+ </div>
+ <!-- Frequency Table -->
+ <frequency-table :time-scale="timeScale" :warning="frequencyWarning" />
+ <accessory-table :records="accessoryData.frequencyTable" />
+ <!-- <frequency-table /> -->
+ </b-collapse>
+ </div>
+ <!-- Power Consumption Section -->
+ <div class="page-collapse-decorator">
+ <b-button
+ v-b-toggle.toggle-collapse_3
+ variant="link"
+ class="collapse-button semi-bold-16px"
+ >
+ <img src="@/assets/images/power-icon.svg" />
+ <span class="bold-16px">{{ $t('subHeader.powerConsumption') }}</span>
+ <component :is="iconChevronUp" class="icon-expand" />
+ </b-button>
+ <b-collapse id="toggle-collapse_3" class="nav-item__nav">
+ <div class="limit-container">
+ <div class="frequency-limt">
+ <img src="@/assets/images/labels/warning.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.powerWarning')
+ }}</span>
+ <b-form-input
+ v-model="powerWarningInput"
+ type="number"
+ :min="0"
+ :max="100"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <div class="frequency-limt">
+ <img src="@/assets/images/labels/shutdown.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.powerShutdown')
+ }}</span>
+ <b-form-input
+ v-model="powerShutdownInput"
+ type="number"
+ :min="0"
+ :max="100"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <b-button class="save-button" variant="primary" @click="updatePower">
+ {{ $t('global.action.save') }}
+ </b-button>
+ </div>
+ <!-- Power Consumption Table -->
+ <power-table
+ :time-scale="timeScale"
+ :warning="powerWarning"
+ :shutdown="powerShutdown"
+ />
+ <!-- <power-table /> -->
+ <accessory-table :records="accessoryData.powerTable" />
+ </b-collapse>
+ </div>
+ <!-- <page-section class="bootstrap-table__section"> </page-section> -->
+ </b-container>
+</template>
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import PageSection from '@/components/Global/PageSection';
+import DateSwitch from '@/components/Global/SilaComponents/DateSwitch';
+import FrequencyTable from './FrequencyTable';
+import PowerTable from './PowerTable';
+import TemperatureTable from './TemperatureTable';
+import AccessoryTable from '@/components/Global/SilaComponents/Tables/AccessoryTablePower';
+
+import iconChevronUp from '@carbon/icons-vue/es/chevron--up/16';
+
+import { AccessoryData } from './helpers';
+
+export default {
+ components: {
+ PageTitle,
+ PageSection,
+ DateSwitch,
+ FrequencyTable,
+ TemperatureTable,
+ PowerTable,
+ AccessoryTable,
+ },
+ data() {
+ return {
+ timeScale: 'hour',
+ temperatureWarning: 72,
+ temperatureWarningInput: 72,
+ temperatureNonNormal: 44,
+ temperatureNonNormalInput: 44,
+ temperatureCritical: 55,
+ temperatureCriticalInput: 55,
+ frequencyWarning: 660,
+ frequencyWarningInput: 660,
+ powerWarning: 66,
+ powerWarningInput: 66,
+ powerShutdown: 88,
+ powerShutdownInput: 88,
+ notificationInput: 42,
+ accessoryData: AccessoryData,
+ iconChevronUp: iconChevronUp,
+ };
+ },
+ methods: {
+ switchTimeScale(period) {
+ this.timeScale = period;
+ },
+ updateTemperature() {
+ this.temperatureWarning = +this.temperatureWarningInput;
+ this.temperatureNonNormal = +this.temperatureNonNormalInput;
+ this.temperatureCritical = +this.temperatureCriticalInput;
+ },
+ updateFrequency() {
+ this.frequencyWarning = +this.frequencyWarningInput;
+ },
+ updatePower() {
+ this.powerWarning = +this.powerWarningInput;
+ this.powerShutdown = +this.powerShutdownInput;
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+//nav items style
+.nav-item,
+.nav-link {
+ padding: 0;
+}
+.nav-item {
+ list-style-type: none;
+}
+
+a {
+ color: $text-primary !important;
+ &:hover {
+ color: $text-primary !important;
+ }
+}
+
+.notification-time__container {
+ position: absolute;
+ top: calc(#{$header-height});
+ right: 0px;
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: flex-start;
+ align-items: center;
+}
+
+.notification-time {
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: flex-start;
+ align-items: center;
+ border: none;
+ box-shadow: none;
+ border-radius: 8px;
+ margin: 12px 32px 12px 8px;
+ width: 236px;
+ height: 40px;
+ z-index: 1001;
+}
+
+.notification-time__icon {
+ width: 20px;
+ height: 20px;
+}
+
+.notification-time__input {
+ border: none;
+ background: none;
+ box-shadow: none;
+}
+
+.notification-button {
+ border: none;
+ background: none;
+}
+
+.semi-bold-12px {
+ z-index: 1001;
+}
+// temperature limit comtainer
+.limit-container {
+ height: 85px;
+ width: 100%;
+ padding: 0 32px 10px 32px;
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: flex-start;
+ align-items: flex-end;
+ gap: 24px;
+}
+
+.trmperature-limt {
+ height: 60px;
+ width: 100%;
+ max-width: 270px;
+ display: flex;
+ align-items: baseline;
+ flex-flow: row wrap;
+ gap: 8px;
+}
+
+.form-control {
+ height: 36px;
+}
+.save-button {
+ width: 151px;
+ height: 36px;
+}
+
+.frequency-limt {
+ height: 60px;
+ width: 100%;
+ max-width: 288px;
+ display: flex;
+ align-items: baseline;
+ flex-flow: row wrap;
+ gap: 8px;
+}
+</style>
diff --git a/src/views/_sila/Processors/DynamicInfo/TemperatureTable.vue b/src/views/_sila/Processors/DynamicInfo/TemperatureTable.vue
new file mode 100644
index 00000000..f9c149c3
--- /dev/null
+++ b/src/views/_sila/Processors/DynamicInfo/TemperatureTable.vue
@@ -0,0 +1,126 @@
+<template>
+ <div>
+ <highcharts :options="chartOptions.line" />
+ </div>
+</template>
+
+<script>
+import { setTime, Series, setCategories } from './helpers';
+import { Chart } from 'highcharts-vue';
+
+export default {
+ components: {
+ highcharts: Chart,
+ },
+ props: {
+ timeScale: {
+ type: String,
+ default: 'hour',
+ },
+ warning: {
+ type: Number,
+ default: 70,
+ },
+ nonNormal: {
+ type: Number,
+ default: 70,
+ },
+ criticalStart: {
+ type: Number,
+ default: 70,
+ },
+ },
+ computed: {
+ chartOptions() {
+ return {
+ line: {
+ chart: {
+ type: 'line',
+ margin: [12, 50, 32, 60],
+ height: '320px',
+ },
+ title: null,
+ xAxis: {
+ categories: setTime(60, 'hour'),
+ title: null,
+ labels: {
+ step: 6,
+ },
+ minorGridLineColor: '#1A3E5B1A',
+ },
+ yAxis: {
+ categories: setCategories(101, 'С°'),
+ min: 0,
+ max: 100,
+ title: null,
+ minTickInterval: 25,
+ minorGridLineColor: '#1A3E5B1A',
+ plotLines: [
+ {
+ color: '#E11717',
+ dashStyle: 'solid',
+ value: this.warning,
+ zIndex: '1000',
+ width: 2,
+ label: {
+ text: 'Пороговое значение предупреждения, С°',
+ align: 'right',
+ style: {
+ fontFamily: 'Inter, sans-serif',
+ fontSize: '12px',
+ fontStyle: 'normal',
+ fontWeight: '400',
+ lineHeight: '16px',
+ color: '#0C1C2999',
+ },
+ },
+ },
+ ],
+ plotBands: [
+ {
+ color: '#F0AC0C1A',
+ dashStyle: 'solid',
+ from: this.nonNormal,
+ to: this.criticalStart,
+ },
+ {
+ color: '#FF41411A',
+ dashStyle: 'solid',
+ from: this.criticalStart,
+ to: this.warning,
+ },
+ ],
+ },
+ series: Series['temperature'].map((item) => ({
+ ...item,
+ marker: {
+ enabled: false,
+ },
+ })),
+ legend: {
+ enabled: false,
+ },
+ tooltip: {
+ enabled: false,
+ crosshairs: false,
+ },
+ plotOptions: {
+ series: {
+ showInLegend: true,
+ },
+ },
+ },
+ };
+ },
+ },
+};
+</script>
+<style lang="scss">
+.highcharts-credits {
+ display: none;
+}
+
+.highcharts-plot-line-label {
+ transform: translate(-15px, 0) !important;
+}
+</style>
diff --git a/src/views/_sila/Processors/DynamicInfo/helpers.js b/src/views/_sila/Processors/DynamicInfo/helpers.js
new file mode 100644
index 00000000..82e23544
--- /dev/null
+++ b/src/views/_sila/Processors/DynamicInfo/helpers.js
@@ -0,0 +1,1398 @@
+export const colors = [
+ '#CB32F1',
+ '#F18638',
+ '#139BB9',
+ '#E1AB17',
+ '#175AE1',
+ '#13B937',
+];
+
+export const Series = {
+ temperature: [
+ {
+ name: 'Sean',
+ data: [
+ 10,
+ 10,
+ 10,
+ 30,
+ 10,
+ 10,
+ 10,
+ 37,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 25,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 35,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 45,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 50,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ ],
+ color: '#CB32F1',
+ },
+ {
+ name: 'Ivan',
+ data: [
+ 11,
+ 11,
+ 11,
+ 30,
+ 11,
+ 11,
+ 11,
+ 11,
+ 57,
+ 11,
+ 11,
+ 11,
+ 11,
+ 25,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 61,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 31,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 21,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 51,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ ],
+ color: '#175AE1',
+ },
+ {
+ name: 'Brendan',
+ data: [
+ 15,
+ 15,
+ 15,
+ 35,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 25,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 45,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 35,
+ 15,
+ 15,
+ 55,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ ],
+ color: '#B98D13',
+ },
+ {
+ name: 'Matteo',
+ data: [
+ 21,
+ 21,
+ 21,
+ 51,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 40,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 35,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 53,
+ 21,
+ 21,
+ 30,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ ],
+ color: '#13B937',
+ },
+ {
+ name: 'Joan',
+ data: [
+ 19,
+ 19,
+ 19,
+ 39,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 29,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 39,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 39,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 59,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ ],
+ color: '#F18638',
+ },
+ {
+ name: 'Avinash',
+ data: [
+ 16,
+ 16,
+ 16,
+ 56,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 26,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 26,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 76,
+ 16,
+ 16,
+ 16,
+ 16,
+ 46,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 46,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ ],
+ color: '#139BB9',
+ },
+ ],
+ //////////////////////////////frequency////////////////
+ frequency: [
+ {
+ name: 'Sean',
+ data: [
+ 100,
+ 100,
+ 450,
+ 100,
+ 100,
+ 100,
+ 100,
+ 137,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 125,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 135,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 145,
+ 100,
+ 100,
+ 360,
+ 100,
+ 100,
+ 450,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 150,
+ 100,
+ ],
+ color: '#CB32F1',
+ },
+ {
+ name: 'Ivan',
+ data: [
+ 120,
+ 120,
+ 120,
+ 140,
+ 120,
+ 157,
+ 120,
+ 120,
+ 120,
+ 210,
+ 120,
+ 125,
+ 120,
+ 120,
+ 120,
+ 350,
+ 120,
+ 120,
+ 120,
+ 120,
+ 120,
+ 590,
+ 120,
+ 120,
+ 120,
+ 120,
+ 450,
+ 120,
+ 120,
+ 120,
+ 120,
+ 120,
+ 125,
+ 120,
+ 120,
+ 120,
+ 120,
+ 120,
+ 162,
+ 120,
+ 120,
+ 120,
+ 120,
+ 120,
+ 220,
+ 120,
+ 120,
+ 120,
+ 120,
+ 120,
+ 360,
+ 120,
+ 210,
+ 120,
+ 200,
+ 120,
+ 120,
+ 120,
+ 120,
+ 120,
+ ],
+ color: '#175AE1',
+ },
+ {
+ name: 'Brendan',
+ data: [
+ 110,
+ 110,
+ 110,
+ 450,
+ 110,
+ 110,
+ 110,
+ 157,
+ 110,
+ 110,
+ 110,
+ 110,
+ 110,
+ 165,
+ 110,
+ 110,
+ 110,
+ 110,
+ 110,
+ 310,
+ 110,
+ 110,
+ 110,
+ 590,
+ 110,
+ 110,
+ 175,
+ 110,
+ 110,
+ 110,
+ 110,
+ 110,
+ 110,
+ 110,
+ 110,
+ 110,
+ 110,
+ 110,
+ 110,
+ 110,
+ 152,
+ 110,
+ 310,
+ 110,
+ 110,
+ 210,
+ 110,
+ 110,
+ 110,
+ 110,
+ 110,
+ 110,
+ 360,
+ 110,
+ 110,
+ 110,
+ 210,
+ 110,
+ 110,
+ 110,
+ ],
+ color: '#B98D13',
+ },
+ {
+ name: 'Matteo',
+ data: [
+ 221,
+ 221,
+ 221,
+ 251,
+ 221,
+ 221,
+ 221,
+ 221,
+ 221,
+ 590,
+ 221,
+ 221,
+ 421,
+ 221,
+ 221,
+ 221,
+ 221,
+ 221,
+ 221,
+ 221,
+ 221,
+ 221,
+ 221,
+ 221,
+ 221,
+ 221,
+ 450,
+ 221,
+ 221,
+ 221,
+ 221,
+ 421,
+ 221,
+ 235,
+ 221,
+ 221,
+ 221,
+ 221,
+ 221,
+ 421,
+ 221,
+ 360,
+ 221,
+ 221,
+ 221,
+ 210,
+ 253,
+ 221,
+ 221,
+ 230,
+ 221,
+ 221,
+ 221,
+ 590,
+ 221,
+ 221,
+ 221,
+ 221,
+ 221,
+ 221,
+ ],
+ color: '#13B937',
+ },
+ {
+ name: 'Joan',
+ data: [
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 590,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 590,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ 159,
+ ],
+ color: '#F18638',
+ },
+ {
+ name: 'Avinash',
+ data: [
+ 176,
+ 176,
+ 176,
+ 156,
+ 176,
+ 176,
+ 176,
+ 176,
+ 176,
+ 176,
+ 176,
+ 176,
+ 176,
+ 176,
+ 176,
+ 176,
+ 276,
+ 176,
+ 176,
+ 176,
+ 176,
+ 176,
+ 176,
+ 210,
+ 176,
+ 176,
+ 176,
+ 590,
+ 176,
+ 176,
+ 176,
+ 176,
+ 176,
+ 590,
+ 176,
+ 176,
+ 176,
+ 176,
+ 176,
+ 176,
+ 176,
+ 176,
+ 176,
+ 570,
+ 176,
+ 176,
+ 176,
+ 176,
+ 176,
+ 770,
+ 176,
+ 176,
+ 176,
+ 176,
+ 176,
+ 176,
+ 176,
+ 176,
+ 176,
+ 176,
+ ],
+ color: '#139BB9',
+ },
+ ],
+ //////////////////////////////power////////////////
+ power: [
+ {
+ name: 'Sean',
+ data: [
+ 15,
+ 15,
+ 45,
+ 15,
+ 65,
+ 15,
+ 75,
+ 15,
+ 15,
+ 15,
+ 55,
+ 15,
+ 25,
+ 15,
+ 45,
+ 15,
+ 55,
+ 15,
+ 75,
+ 15,
+ 35,
+ 15,
+ 55,
+ 15,
+ 75,
+ 15,
+ 85,
+ 15,
+ 15,
+ 45,
+ 15,
+ 15,
+ 45,
+ 15,
+ 45,
+ 15,
+ 15,
+ 65,
+ 15,
+ 45,
+ 15,
+ 25,
+ 15,
+ 45,
+ 15,
+ 65,
+ 15,
+ 35,
+ 35,
+ 35,
+ 15,
+ 55,
+ 15,
+ 15,
+ 35,
+ 15,
+ 25,
+ 15,
+ 35,
+ 15,
+ ],
+ color: '#CB32F1',
+ },
+ {
+ name: 'Ivan',
+ data: [
+ 62,
+ 12,
+ 72,
+ 12,
+ 12,
+ 12,
+ 42,
+ 12,
+ 12,
+ 12,
+ 52,
+ 12,
+ 22,
+ 12,
+ 42,
+ 12,
+ 52,
+ 12,
+ 72,
+ 12,
+ 52,
+ 12,
+ 62,
+ 12,
+ 72,
+ 12,
+ 82,
+ 12,
+ 12,
+ 42,
+ 12,
+ 12,
+ 52,
+ 12,
+ 42,
+ 12,
+ 12,
+ 62,
+ 12,
+ 42,
+ 12,
+ 22,
+ 12,
+ 42,
+ 12,
+ 62,
+ 12,
+ 12,
+ 32,
+ 12,
+ 62,
+ 12,
+ 52,
+ 12,
+ 32,
+ 12,
+ 22,
+ 12,
+ 32,
+ 12,
+ ],
+ color: '#175AE1',
+ },
+ {
+ name: 'Brendan',
+ data: [
+ 14,
+ 14,
+ 34,
+ 14,
+ 24,
+ 14,
+ 34,
+ 14,
+ 64,
+ 14,
+ 74,
+ 14,
+ 14,
+ 14,
+ 44,
+ 14,
+ 14,
+ 14,
+ 54,
+ 14,
+ 24,
+ 14,
+ 44,
+ 14,
+ 54,
+ 14,
+ 74,
+ 14,
+ 54,
+ 14,
+ 64,
+ 14,
+ 74,
+ 14,
+ 84,
+ 14,
+ 14,
+ 44,
+ 14,
+ 14,
+ 54,
+ 14,
+ 44,
+ 14,
+ 14,
+ 64,
+ 14,
+ 44,
+ 14,
+ 24,
+ 14,
+ 44,
+ 14,
+ 64,
+ 14,
+ 14,
+ 14,
+ 54,
+ 14,
+ 54,
+ ],
+ color: '#B98D13',
+ },
+ {
+ name: 'Matteo',
+ data: [
+ 24,
+ 14,
+ 44,
+ 14,
+ 64,
+ 14,
+ 64,
+ 14,
+ 34,
+ 14,
+ 54,
+ 14,
+ 14,
+ 34,
+ 14,
+ 24,
+ 14,
+ 34,
+ 14,
+ 64,
+ 14,
+ 74,
+ 14,
+ 14,
+ 14,
+ 44,
+ 14,
+ 14,
+ 14,
+ 54,
+ 14,
+ 14,
+ 14,
+ 44,
+ 14,
+ 54,
+ 14,
+ 74,
+ 14,
+ 54,
+ 14,
+ 64,
+ 14,
+ 74,
+ 14,
+ 84,
+ 14,
+ 94,
+ 14,
+ 54,
+ 4,
+ 54,
+ 14,
+ 44,
+ 14,
+ 44,
+ 64,
+ 14,
+ 44,
+ 14,
+ ],
+ color: '#13B937',
+ },
+ {
+ name: 'Joan',
+ data: [
+ 16,
+ 46,
+ 16,
+ 26,
+ 16,
+ 46,
+ 16,
+ 66,
+ 16,
+ 16,
+ 16,
+ 36,
+ 16,
+ 56,
+ 16,
+ 16,
+ 36,
+ 16,
+ 26,
+ 16,
+ 36,
+ 16,
+ 66,
+ 16,
+ 76,
+ 16,
+ 16,
+ 16,
+ 46,
+ 16,
+ 16,
+ 16,
+ 56,
+ 16,
+ 26,
+ 16,
+ 46,
+ 16,
+ 56,
+ 16,
+ 76,
+ 16,
+ 56,
+ 16,
+ 66,
+ 16,
+ 76,
+ 16,
+ 86,
+ 16,
+ 96,
+ 16,
+ 16,
+ 16,
+ 56,
+ 16,
+ 46,
+ 16,
+ 46,
+ 16,
+ ],
+ color: '#F18638',
+ },
+ {
+ name: 'Avinash',
+ data: [
+ 49,
+ 19,
+ 19,
+ 69,
+ 19,
+ 49,
+ 19,
+ 29,
+ 19,
+ 49,
+ 19,
+ 69,
+ 19,
+ 39,
+ 39,
+ 39,
+ 19,
+ 59,
+ 19,
+ 19,
+ 39,
+ 19,
+ 29,
+ 19,
+ 39,
+ 19,
+ 69,
+ 19,
+ 79,
+ 19,
+ 19,
+ 19,
+ 49,
+ 19,
+ 19,
+ 19,
+ 59,
+ 19,
+ 29,
+ 19,
+ 49,
+ 19,
+ 59,
+ 19,
+ 79,
+ 19,
+ 59,
+ 19,
+ 69,
+ 19,
+ 79,
+ 19,
+ 89,
+ 19,
+ 99,
+ 19,
+ 19,
+ 69,
+ 59,
+ 19,
+ ],
+ color: '#139BB9',
+ },
+ ],
+};
+
+export const setTime = (count) => {
+ const arr = [...new Array(count)].map(() => '');
+ for (let i = 0; i < arr.length; i++) {
+ arr[i] = `15:${String(i).padStart(2, '0')}`;
+ }
+ return arr;
+};
+
+export const setCategories = (count, desc) => {
+ const arr = [...new Array(count)].map((i, k) => `${k} ${desc}`);
+ return arr;
+};
+
+export const AccessoryData = {
+ temperatureTable: {
+ fields: [
+ {
+ key: 'name',
+ label: 'Имя модуля',
+ },
+ {
+ key: 'currentTemperature',
+ label: 'Текущее, С°',
+ },
+ {
+ key: 'middleTemperature',
+ label: 'Среднее, С°',
+ },
+ {
+ key: 'minTemperature',
+ label: 'Минимальное, С°',
+ },
+ {
+ key: 'minDate',
+ label: 'Дата минимального',
+ },
+ {
+ key: 'maxTemperature',
+ label: 'Максимальное, С°',
+ },
+ {
+ key: 'maxDate',
+ label: 'Дата максимального',
+ },
+ ],
+ items: [
+ {
+ name: 'Процессор 1',
+ currentTemperature: 19,
+ middleTemperature: 40,
+ minTemperature: 31,
+ minDate: { time: '15:15', date: '11.11.2021' },
+ maxTemperature: 88,
+ maxDate: { time: '10:26', date: '15.11.2021' },
+ },
+ {
+ name: 'Процессор 2',
+ currentTemperature: 29,
+ middleTemperature: 40,
+ minTemperature: 20,
+ minDate: { time: '15:45', date: '11.11.2021' },
+ maxTemperature: 76,
+ maxDate: { time: '16:59', date: '16.11.2021' },
+ },
+ {
+ name: 'Процессор 3',
+ currentTemperature: 48,
+ middleTemperature: 46,
+ minTemperature: 31,
+ minDate: { time: '15:23', date: '11.11.2021' },
+ maxTemperature: 69,
+ maxDate: { time: '15:26', date: '15.11.2021' },
+ },
+ {
+ name: 'Процессор 4',
+ currentTemperature: 48,
+ middleTemperature: 45,
+ minTemperature: 5,
+ minDate: { time: '16:45', date: '25.11.2021' },
+ maxTemperature: 75,
+ maxDate: { time: '11:26', date: '16.11.2021' },
+ },
+ {
+ name: 'Процессор 5',
+ currentTemperature: 39,
+ middleTemperature: 44,
+ minTemperature: 30,
+ minDate: { time: '15:23', date: '11.11.2021' },
+ maxTemperature: 80,
+ maxDate: { time: '15:26', date: '17.11.2021' },
+ },
+ {
+ name: 'Процессор 6',
+ currentTemperature: 39,
+ middleTemperature: 44,
+ minTemperature: 5,
+ minDate: { time: '16:45', date: '25.11.2021' },
+ maxTemperature: 80,
+ maxDate: { time: '15:26', date: '15.11.2021' },
+ },
+ ],
+ },
+ frequencyTable: {
+ fields: [
+ {
+ key: 'name',
+ label: 'Имя модуля',
+ },
+ {
+ key: 'currentFrequency',
+ label: 'Текущее, Hz',
+ },
+ {
+ key: 'baseFrequency',
+ label: 'Базовое, Hz',
+ },
+ ],
+ items: [
+ {
+ name: 'Процессор 1',
+ currentFrequency: 600,
+ baseFrequency: 400,
+ },
+ {
+ name: 'Процессор 2',
+ currentFrequency: 500,
+ baseFrequency: 470,
+ },
+ {
+ name: 'Процессор 3',
+ currentFrequency: 500,
+ baseFrequency: 450,
+ },
+ {
+ name: 'Процессор 4',
+ currentFrequency: 500,
+ baseFrequency: 470,
+ },
+ {
+ name: 'Процессор 5',
+ currentFrequency: 600,
+ baseFrequency: 470,
+ },
+ {
+ name: 'Процессор 6',
+ currentFrequency: 500,
+ baseFrequency: 400,
+ },
+ ],
+ },
+ powerTable: {
+ fields: [
+ {
+ key: 'name',
+ label: 'Имя модуля',
+ },
+ {
+ key: 'currentPower',
+ label: 'Текущее, Вт',
+ label2: '',
+ },
+ ],
+ items: [
+ {
+ name: 'Процессор 1',
+ currentPower: 91,
+ },
+ {
+ name: 'Процессор 2',
+ currentPower: 77,
+ },
+ {
+ name: 'Процессор 3',
+ currentPower: 76,
+ },
+ {
+ name: 'Процессор 4',
+ currentPower: 74,
+ },
+ {
+ name: 'Процессор 5',
+ currentPower: 73,
+ },
+ {
+ name: 'Процессор 6',
+ currentPower: 71,
+ },
+ ],
+ },
+};
diff --git a/src/views/_sila/Processors/DynamicInfo/index.js b/src/views/_sila/Processors/DynamicInfo/index.js
new file mode 100644
index 00000000..121c0316
--- /dev/null
+++ b/src/views/_sila/Processors/DynamicInfo/index.js
@@ -0,0 +1,2 @@
+import ProcessorsDynamicPage from './ProcessorsDynamicPage.vue';
+export default ProcessorsDynamicPage;
diff --git a/src/views/_sila/Processors/Specification/AcceleratorSpecificationTable.vue b/src/views/_sila/Processors/Specification/AcceleratorSpecificationTable.vue
new file mode 100644
index 00000000..53b31d8b
--- /dev/null
+++ b/src/views/_sila/Processors/Specification/AcceleratorSpecificationTable.vue
@@ -0,0 +1,146 @@
+<template>
+ <b-table
+ responsive="md"
+ show-empty
+ no-border-collapse
+ :items="accelerators"
+ :fields="fields"
+ >
+ <template #cell(expandRow)="">
+ <b-button
+ variant="link"
+ data-test-id="hardwareStatus-button-expandAccelerators"
+ :title="expandRowLabel"
+ >
+ <icon-chevron />
+ <span class="sr-only">{{ expandRowLabel }}</span>
+ </b-button>
+ </template>
+ <template #cell(status)="{ value }">
+ <div v-if="value" class="fans-table-col-first__cell">
+ <img class="status__img" src="@/assets/images/status/on.svg" />
+ <span>
+ {{ $t('global.status.inWork') }}
+ </span>
+ </div>
+ <div v-else class="fans-table-col-first__cell">
+ <img class="status__img" src="@/assets/images/_sila/status/off.svg" />
+ <span>
+ {{ $t('global.status.outWorking') }}
+ </span>
+ </div>
+ </template>
+ </b-table>
+</template>
+
+<script>
+import TableRowExpandMixin, {
+ expandRowLabel,
+} from '@/components/Mixins/TableRowExpandMixin';
+import IconChevron from '@carbon/icons-vue/es/chevron--down/20';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
+
+import { Accelerators } from './helpers';
+export default {
+ components: { IconChevron },
+ mixins: [BVToastMixin, TableRowExpandMixin, DataFormatterMixin],
+ data() {
+ return {
+ isBusy: true,
+ isAddersСolon: false,
+ accelerators: Accelerators,
+ fields: [
+ {
+ key: 'expandRow',
+ label: '',
+ thStyle: { width: '3%' },
+ sortable: false,
+ },
+ {
+ key: 'status',
+ label: 'Статус',
+ formatter: this.dataFormatter,
+ thStyle: { width: '15%' },
+ },
+ {
+ key: 'name',
+ label: 'Имя',
+ formatter: this.dataFormatter,
+ thStyle: { width: '10%' },
+ },
+ {
+ key: 'slot_number',
+ label: '№ Слота',
+ formatter: this.dataFormatter,
+ thStyle: { width: '8%' },
+ },
+ {
+ key: 'board_number',
+ label: '№ Платы',
+ formatter: this.dataFormatter,
+ thStyle: { width: '8%' },
+ },
+ {
+ key: 'serial_number',
+ label: 'Серийный номер',
+ formatter: this.dataFormatter,
+ thStyle: { width: '15%' },
+ },
+ {
+ key: 'frequency',
+ label: '№ Детали',
+ formatter: this.dataFormatter,
+ thStyle: { width: '8%' },
+ },
+ {
+ key: 'cores',
+ label: 'Версия прошивки',
+ formatter: this.dataFormatter,
+ thStyle: { width: '10%' },
+ },
+ ],
+ expandRowLabel: expandRowLabel,
+ };
+ },
+};
+</script>
+<style lang="scss" scoped>
+.row {
+ margin: 0px;
+ flex-wrap: nowrap;
+}
+.fans-table-col-first__cell {
+ display: flex;
+ flex-flow: row nowrap;
+ align-items: center;
+ justify-content: flex-start;
+}
+
+.status__img {
+ margin-right: 7px;
+}
+
+.bold-16px {
+ margin: 24px 0 0 2rem;
+}
+
+.bold-12px__caps {
+ color: $text-secondary;
+}
+
+.attrib-names {
+ border-bottom: 1px solid $faint-secondary-primary-10;
+ color: $text-secondary !important;
+ font-weight: 600;
+}
+
+.custom-switch {
+ margin: 0;
+}
+
+.btn-link {
+ width: 30px !important;
+ height: 20px !important;
+}
+</style>
diff --git a/src/views/_sila/Processors/Specification/ProcessorsSpecificationPage.vue b/src/views/_sila/Processors/Specification/ProcessorsSpecificationPage.vue
new file mode 100644
index 00000000..50362ac2
--- /dev/null
+++ b/src/views/_sila/Processors/Specification/ProcessorsSpecificationPage.vue
@@ -0,0 +1,117 @@
+<template>
+ <b-container
+ id="page-processors"
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title :description="$t('appNavigation.specification')" />
+ <page-section class="bootstrap-table__section">
+ <span class="bold-16px">{{
+ $t('pageInventory.installedProcessors')
+ }}</span>
+ <!-- Processors Specification Table -->
+ <div class="capability-info">
+ <b-row>
+ <b-col class="mt-0 mb-2 p-0 bold-12px__caps">
+ {{ $t('pageInventory.table.processorCapabilityInfo') }}
+ </b-col>
+ </b-row>
+ <b-row>
+ <b-col class="mt-2 p-0" sm="3" xl="3">
+ <dl class="light-12px">
+ <dd class="attrib-names">
+ {{ $t('global.table.attributes') }}
+ </dd>
+ <dd>{{ 'Многопоточность' }}</dd>
+ <dd>{{ 'Виртуализация' }}</dd>
+ <dd>{{ 'Турбо режим' }}</dd>
+ </dl>
+ </b-col>
+ <b-col class="mt-2 p-0" sm="3" xl="3">
+ <dl class="light-12px">
+ <dd class="attrib-names">{{ 'Состояние присутсвия' }}</dd>
+ <dd
+ v-for="item in processors[0].presence_status"
+ :key="item.presence_status"
+ >
+ {{ item }}
+ </dd>
+ </dl>
+ </b-col>
+ <b-col class="mt-2 p-0" sm="3" xl="3">
+ <dl class="light-12px">
+ <!-- Status state -->
+ <dd class="attrib-names">{{ 'Включен' }}</dd>
+ <dd>
+ <b-form-checkbox
+ v-model="processors[0].statuses.multithreading"
+ switch
+ >
+ </b-form-checkbox>
+ </dd>
+ <dd>
+ <b-form-checkbox
+ v-model="processors[0].statuses.virtualization"
+ switch
+ >
+ </b-form-checkbox>
+ </dd>
+ <dd>
+ <b-form-checkbox v-model="processors[0].statuses.turbo" switch>
+ </b-form-checkbox>
+ </dd>
+ </dl>
+ </b-col>
+ </b-row>
+ </div>
+ <processors-specification-table />
+ <span class="bold-16px">{{
+ $t('pageInventory.installedAccelerator')
+ }}</span>
+ <!-- Accelerators Specification Table -->
+ <accelerator-specification-table />
+ </page-section>
+ </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import PageSection from '@/components/Global/PageSection';
+import { processors } from './helpers';
+
+import ProcessorsSpecificationTable from './ProcessorsSpecificationTable';
+import AcceleratorSpecificationTable from './AcceleratorSpecificationTable';
+export default {
+ components: {
+ PageTitle,
+ PageSection,
+ ProcessorsSpecificationTable,
+ AcceleratorSpecificationTable,
+ },
+ data() {
+ return {
+ processors,
+ };
+ },
+};
+</script>
+<style lang="scss" scoped>
+.bold-16px {
+ display: block;
+ margin: 25px 0 16px 0;
+}
+
+.capability-info {
+ padding-left: 1rem;
+}
+
+.attrib-names {
+ border-bottom: 1px solid $faint-secondary-primary-10;
+ color: $text-secondary !important;
+ font-weight: 600;
+}
+
+.custom-switch {
+ margin: 0;
+}
+</style>
diff --git a/src/views/_sila/Processors/Specification/ProcessorsSpecificationTable.vue b/src/views/_sila/Processors/Specification/ProcessorsSpecificationTable.vue
new file mode 100644
index 00000000..c872eefc
--- /dev/null
+++ b/src/views/_sila/Processors/Specification/ProcessorsSpecificationTable.vue
@@ -0,0 +1,251 @@
+<template>
+ <b-table
+ sort-icon-left
+ no-sort-reset
+ :sort-desc="true"
+ responsive="md"
+ show-empty
+ no-border-collapse
+ :items="processors"
+ :fields="fields"
+ :empty-text="$t('global.table.emptyMessage')"
+ :empty-filtered-text="$t('global.table.emptySearchMessage')"
+ >
+ <template #cell(expandRow)="row">
+ <b-button
+ variant="link"
+ data-test-id="hardwareStatus-button-expandProcessors"
+ :title="expandRowLabel"
+ class="btn-icon-only"
+ @click="toggleRowDetails(row)"
+ >
+ <icon-chevron />
+ <span class="sr-only">{{ expandRowLabel }}</span>
+ </b-button>
+ </template>
+ <template #cell(status)="{ value }">
+ <div v-if="value" class="fans-table-col-first__cell">
+ <img class="status__img" src="@/assets/images/status/on.svg" />
+ <span>
+ {{ $t('global.status.inWork') }}
+ </span>
+ </div>
+ <div v-else class="fans-table-col-first__cell">
+ <img class="status__img" src="@/assets/images/_sila/status/off.svg" />
+ <span>
+ {{ $t('global.status.outWorking') }}
+ </span>
+ </div>
+ </template>
+
+ <template #row-details="{ index }">
+ <b-container fluid>
+ <!-- ProcessorCapabilityInfo -->
+ <b-row>
+ <b-col class="mt-3 mb-2 p-0 bold-12px__caps">
+ {{ $t('pageInventory.table.processorCacheInfo') }}
+ </b-col>
+ </b-row>
+ <b-row>
+ <b-col class="mt-2 p-0" sm="3" xl="3">
+ <dl class="light-12px">
+ <!-- Attributes Names -->
+ <dd class="attrib-names">{{ $t('global.table.attributes') }}</dd>
+ <dd>{{ 'Уровень кеша' }}</dd>
+ <dd>{{ 'Максимальный объем' }}</dd>
+ <dd>{{ 'Установленный объем' }}</dd>
+ <dd>{{ 'Тип кэша' }}</dd>
+ <dd>{{ 'Локализация' }}</dd>
+ <dd>{{ 'Политика записи' }}</dd>
+ <dd>{{ 'Ассоциативность' }}</dd>
+ <dd>{{ 'Тип исправления ошибки' }}</dd>
+ </dl>
+ </b-col>
+ <b-col class="mt-2 p-0" sm="3" xl="3">
+ <dl class="light-12px">
+ <!-- Status КЭШ-1 -->
+ <dd class="attrib-names">{{ 'КЭШ-1' }}</dd>
+ <dd v-for="item in processors[index].cache_1" :key="item.cache_1">
+ {{ dataFormatter(item) }}
+ </dd>
+ </dl>
+ </b-col>
+ <b-col class="mt-2 p-0" sm="3" xl="3">
+ <dl class="light-12px">
+ <!-- Status state -->
+ <dd class="attrib-names">{{ 'КЭШ-2' }}</dd>
+ <dd v-for="item in processors[index].cache_2" :key="item.cache_2">
+ {{ dataFormatter(item) }}
+ </dd>
+ </dl>
+ </b-col>
+ <b-col class="mt-2 p-0" sm="3" xl="3">
+ <dl class="light-12px">
+ <dd class="attrib-names">{{ 'КЭШ-3' }}</dd>
+ <dd v-for="item in processors[index].cache_3" :key="item.cache_3">
+ {{ dataFormatter(item) }}
+ </dd>
+ </dl>
+ </b-col>
+ </b-row>
+ <b-row>
+ <b-col class="mt-3 mb-2 p-0 bold-12px__caps">
+ {{ $t('pageInventory.table.SupportedTechnologies') }}
+ </b-col>
+ </b-row>
+ <b-row>
+ <b-col class="mt-2 p-0" sm="6" xl="6">
+ <dl class="light-12px">
+ <dd class="attrib-names">{{ $t('global.table.attributes') }}</dd>
+ <dd></dd>
+ <dd>{{ 'processor' }}</dd>
+ <dd>{{ 'vendor_id' }}</dd>
+ <dd>{{ 'cpu family' }}</dd>
+ <dd>{{ 'model' }}</dd>
+ <dd>{{ 'model name' }}</dd>
+ <dd>{{ 'stepping' }}</dd>
+ <dd>{{ 'microcode' }}</dd>
+ <dd>{{ 'cpu MHz' }}</dd>
+ <dd>{{ 'cache size' }}</dd>
+ <dd>{{ 'physical id' }}</dd>
+ <dd>{{ 'siblings' }}</dd>
+ <dd>{{ 'core id' }}</dd>
+ <dd>{{ 'cpu cores' }}</dd>
+ <dd>{{ 'apicid' }}</dd>
+ <dd>{{ 'initial apicid' }}</dd>
+ <dd>{{ 'fpu' }}</dd>
+ <dd>{{ 'fpu_exception' }}</dd>
+ <dd>{{ 'cpuid level' }}</dd>
+ <dd>{{ 'wp' }}</dd>
+ <dd>{{ 'flags' }}</dd>
+ <dd>{{ 'bugs' }}</dd>
+ </dl>
+ </b-col>
+ <b-col class="mt-2 p-0" sm="6" xl="6">
+ <dl class="light-12px">
+ <dd class="attrib-names">{{ $t('global.table.value') }}</dd>
+ <dd
+ v-for="item in processors[index].description"
+ :key="item.description"
+ >
+ {{ dataFormatter(item) }}
+ </dd>
+ </dl>
+ </b-col>
+ </b-row>
+ </b-container>
+ </template>
+ </b-table>
+</template>
+
+<script>
+import TableRowExpandMixin, {
+ expandRowLabel,
+} from '@/components/Mixins/TableRowExpandMixin';
+import IconChevron from '@carbon/icons-vue/es/chevron--down/20';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
+
+import { processors } from './helpers';
+export default {
+ components: { IconChevron },
+ mixins: [BVToastMixin, TableRowExpandMixin, DataFormatterMixin],
+ data() {
+ return {
+ isBusy: true,
+ isAddersСolon: false,
+ processors,
+ fields: [
+ {
+ key: 'expandRow',
+ label: '',
+ thStyle: { width: '3%' },
+ sortable: false,
+ },
+ {
+ key: 'status',
+ label: 'Статус',
+ formatter: this.dataFormatter,
+ thStyle: { width: '17%' },
+ },
+ {
+ key: 'name',
+ label: 'Имя',
+ formatter: this.dataFormatter,
+ thStyle: { width: '15%' },
+ },
+ {
+ key: 'model',
+ label: 'Модель',
+ formatter: this.dataFormatter,
+ thStyle: { width: '12%' },
+ },
+ {
+ key: 'serialNumber',
+ label: 'Серийный номер',
+ formatter: this.dataFormatter,
+ thStyle: { width: '15%' },
+ },
+ {
+ key: 'version',
+ label: 'Версия',
+ formatter: this.dataFormatter,
+ thStyle: { width: '10%' },
+ },
+ {
+ key: 'frequency',
+ label: 'Частота',
+ formatter: this.dataFormatter,
+ thStyle: { width: '10%' },
+ },
+ {
+ key: 'cores',
+ label: 'Ядра',
+ formatter: this.dataFormatter,
+ thStyle: { width: '10%' },
+ },
+ ],
+ expandRowLabel: expandRowLabel,
+ };
+ },
+};
+</script>
+<style lang="scss" scoped>
+.row {
+ margin: 0px;
+ flex-wrap: nowrap;
+}
+.fans-table-col-first__cell {
+ display: flex;
+ flex-flow: row nowrap;
+ align-items: center;
+ justify-content: flex-start;
+}
+
+.status__img {
+ margin-right: 7px;
+}
+
+.bold-16px {
+ margin: 24px 0 0 2rem;
+}
+
+.bold-12px__caps {
+ color: $text-secondary;
+}
+
+.attrib-names {
+ border-bottom: 1px solid $faint-secondary-primary-10;
+ color: $text-secondary !important;
+ font-weight: 600;
+}
+
+.custom-switch {
+ margin: 0;
+}
+
+.btn-link {
+ width: 30px !important;
+ height: 20px !important;
+}
+</style>
diff --git a/src/views/_sila/Processors/Specification/helpers.js b/src/views/_sila/Processors/Specification/helpers.js
new file mode 100644
index 00000000..6227e4b8
--- /dev/null
+++ b/src/views/_sila/Processors/Specification/helpers.js
@@ -0,0 +1,254 @@
+export const processors = [
+ {
+ expandRow: false,
+ status: true,
+ name: 'Процессор №1',
+ model: 'Core i5',
+ serialNumber: '789578456698',
+ version: 'v3.1.5',
+ frequency: '2.4',
+ cores: '4',
+ presence_status: {
+ multithreading: 'Нет',
+ virtualization: 'Да',
+ turbo: 'Да',
+ },
+ statuses: {
+ multithreading: false,
+ virtualization: true,
+ turbo: true,
+ },
+ cache_1: {
+ level: 'L1',
+ max_value: '1MB',
+ current_value: '1MB',
+ cache_type: 'Unified',
+ localization: 'Internal',
+ politics: 'Write Back',
+ associativity: '8-Way Set-Associativity',
+ fix_type: 'Parity',
+ },
+ cache_2: {
+ level: 'L2',
+ max_value: '32MB',
+ current_value: '32MB',
+ cache_type: 'Unified',
+ localization: 'Internal',
+ politics: 'Write Back',
+ associativity: '8-Way Set-Associativity',
+ fix_type: 'Multiple-bit ECC',
+ },
+ cache_3: {
+ level: 'L3',
+ max_value: '64MB',
+ current_value: '64MB',
+ cache_type: 'Unified',
+ localization: 'Internal',
+ politics: 'Write Back',
+ associativity: '8-Way Set-Associativity',
+ fix_type: 'Multiple-bit ECC',
+ },
+ description: {
+ processor: '79',
+ vendor_id: 'GenuineIntel',
+ cpu_family: '6',
+ model: '85',
+ model_name: 'Intel(R) Xeon(R) Gold 6242R CPU @ 3.10GHz',
+ stepping: '7',
+ microcode: '0x5002f00',
+ cpu_MHz: '2955.939',
+ cache_size: '36608 KB',
+ physical_id: '1',
+ siblings: '40',
+ core_id: '29',
+ cpu_cores: '20',
+ apicid: '123',
+ initial_apicid: '123',
+ fpu: 'yes',
+ fpu_exception: 'yes',
+ cpuid_level: '22',
+ wp: 'yes',
+ flags: 'fpu, vme, de, pse, tsc, pat, pse36....',
+ bugs: 'spectre_v1 spectre_v2, spec_store_bypass',
+ },
+ },
+ {
+ expandRow: false,
+ status: true,
+ name: 'Процессор №2',
+ model: 'Core i3',
+ serialNumber: '425546788976',
+ version: 'v2.1.5',
+ frequency: '1.4',
+ cores: '2',
+ presence_status: {
+ multithreading: 'Нет',
+ virtualization: 'Да',
+ turbo: 'Да',
+ },
+ statuses: {
+ multithreading: false,
+ virtualization: true,
+ turbo: true,
+ },
+ cache_1: {
+ level: 'L1',
+ max_value: '1MB',
+ current_value: '1MB',
+ cache_type: 'Unified',
+ localization: 'Internal',
+ politics: 'Write Back',
+ associativity: '8-Way Set-Associativity',
+ fix_type: 'Parity',
+ },
+ cache_2: {
+ level: 'L2',
+ max_value: '32MB',
+ current_value: '32MB',
+ cache_type: 'Unified',
+ localization: 'Internal',
+ politics: 'Write Back',
+ associativity: '8-Way Set-Associativity',
+ fix_type: 'Multiple-bit ECC',
+ },
+ cache_3: {
+ level: 'L3',
+ max_value: '64MB',
+ current_value: '64MB',
+ cache_type: 'Unified',
+ localization: 'Internal',
+ politics: 'Write Back',
+ associativity: '8-Way Set-Associativity',
+ fix_type: 'Multiple-bit ECC',
+ },
+ description: {
+ processor: '79',
+ vendor_id: 'GenuineIntel',
+ cpu_family: '6',
+ model: '85',
+ model_name: 'Intel(R) Xeon(R) Gold 6242R CPU @ 3.10GHz',
+ stepping: '7',
+ microcode: '0x5002f00',
+ cpu_MHz: '2955.939',
+ cache_size: '36608 KB',
+ physical_id: '1',
+ siblings: '40',
+ core_id: '29',
+ cpu_cores: '20',
+ apicid: '123',
+ initial_apicid: '123',
+ fpu: 'yes',
+ fpu_exception: 'yes',
+ cpuid_level: '22',
+ wp: 'yes',
+ flags: 'fpu, vme, de, pse, tsc, pat, pse36....',
+ bugs: 'spectre_v1 spectre_v2, spec_store_bypass',
+ },
+ },
+ {
+ expandRow: false,
+ status: false,
+ name: 'Процессор №3',
+ model: 'Core i7',
+ serialNumber: '454555556698',
+ version: 'v6.1.5',
+ frequency: '3.4',
+ cores: '6',
+ presence_status: {
+ multithreading: 'Нет',
+ virtualization: 'Да',
+ turbo: 'Да',
+ },
+ statuses: {
+ multithreading: false,
+ virtualization: true,
+ turbo: true,
+ },
+ cache_1: {
+ level: 'L1',
+ max_value: '1MB',
+ current_value: '1MB',
+ cache_type: 'Unified',
+ localization: 'Internal',
+ politics: 'Write Back',
+ associativity: '8-Way Set-Associativity',
+ fix_type: 'Parity',
+ },
+ cache_2: {
+ level: 'L2',
+ max_value: '32MB',
+ current_value: '32MB',
+ cache_type: 'Unified',
+ localization: 'Internal',
+ politics: 'Write Back',
+ associativity: '8-Way Set-Associativity',
+ fix_type: 'Multiple-bit ECC',
+ },
+ cache_3: {
+ level: 'L3',
+ max_value: '64MB',
+ current_value: '64MB',
+ cache_type: 'Unified',
+ localization: 'Internal',
+ politics: 'Write Back',
+ associativity: '8-Way Set-Associativity',
+ fix_type: 'Multiple-bit ECC',
+ },
+ description: {
+ processor: '79',
+ vendor_id: 'GenuineIntel',
+ cpu_family: '6',
+ model: '85',
+ model_name: 'Intel(R) Xeon(R) Gold 6242R CPU @ 3.10GHz',
+ stepping: '7',
+ microcode: '0x5002f00',
+ cpu_MHz: '2955.939',
+ cache_size: '36608 KB',
+ physical_id: '1',
+ siblings: '40',
+ core_id: '29',
+ cpu_cores: '20',
+ apicid: '123',
+ initial_apicid: '123',
+ fpu: 'yes',
+ fpu_exception: 'yes',
+ cpuid_level: '22',
+ wp: 'yes',
+ flags: 'fpu, vme, de, pse, tsc, pat, pse36....',
+ bugs: 'spectre_v1 spectre_v2, spec_store_bypass',
+ },
+ },
+];
+
+export const Accelerators = [
+ {
+ expandRow: false,
+ status: true,
+ name: 'Процессор №1',
+ slot_number: '789578456698',
+ board_number: '789578456698',
+ serial_number: '425546788976',
+ frequency: '2213',
+ cores: '4',
+ },
+ {
+ expandRow: false,
+ status: true,
+ name: 'Процессор №2',
+ slot_number: '425546788976',
+ board_number: '425546788976',
+ serial_number: '425546788976',
+ frequency: '1332',
+ cores: '2',
+ },
+ {
+ expandRow: false,
+ status: false,
+ name: 'Процессор №3',
+ slot_number: '454555556698',
+ board_number: '454555556698',
+ serial_number: '425546788976',
+ frequency: '3213',
+ cores: '6',
+ },
+];
diff --git a/src/views/_sila/Processors/Specification/index.js b/src/views/_sila/Processors/Specification/index.js
new file mode 100644
index 00000000..93bbbf10
--- /dev/null
+++ b/src/views/_sila/Processors/Specification/index.js
@@ -0,0 +1,2 @@
+import ProcessorsSpecificationPage from './ProcessorsSpecificationPage.vue';
+export default ProcessorsSpecificationPage;
diff --git a/src/views/_sila/SILA/AnalyticalPanel/AnalyticalPanelPage.vue b/src/views/_sila/SILA/AnalyticalPanel/AnalyticalPanelPage.vue
new file mode 100644
index 00000000..533fbfa1
--- /dev/null
+++ b/src/views/_sila/SILA/AnalyticalPanel/AnalyticalPanelPage.vue
@@ -0,0 +1,272 @@
+<template>
+ <b-container fluid="xxl pt-0 m-0">
+ <page-title :description="$t('appNavigation.analyticalPanel')" />
+ <div class="tables-container">
+ <div class="server-table">
+ <span class="semi-bold-16px">{{
+ $t('global.status.serverStatus')
+ }}</span>
+ <b-table
+ show-empty
+ responsive="md"
+ class="table-analytical"
+ no-border-collapse
+ :items="serverItems"
+ :fields="server_fields"
+ >
+ <template #cell(value)="{ value }">
+ <b-col v-if="value">
+ <img
+ src="@/assets/images/icon-ok.svg"
+ class="system-network-table__icon"
+ />
+ </b-col>
+ <b-col v-else>
+ <img
+ src="@/assets/images/icon-no.svg"
+ class="system-network-table__icon"
+ />
+ </b-col>
+ </template>
+ </b-table>
+ </div>
+ <div class="events-table">
+ <span class="semi-bold-16px">{{ $t('global.action.events') }}</span>
+ <div id="events-table-wrapper">
+ <b-table
+ show-empty
+ :sticky-header="stickyHeader"
+ responsive="md"
+ class="table-analytical"
+ no-border-collapse
+ :items="eventsItems"
+ :fields="events_fields"
+ >
+ <template #cell(date)="{ value }">
+ <img
+ src="@/assets/images/_sila/event-logs/time.svg"
+ class="sourse__img"
+ />
+ <span class="regular-12px quaternary"> {{ value }} </span>
+ </template>
+ <template #cell(type)="{ value }">
+ <span
+ v-if="value === 'Критические'"
+ class="bold-12px__caps errors"
+ >{{ value }}</span
+ >
+ <span
+ v-else-if="value === 'Предупреждения'"
+ class="bold-12px__caps warning"
+ >
+ {{ value }}
+ </span>
+ <span v-else class="bold-12px__caps information">{{
+ value
+ }}</span>
+ </template>
+ <template #cell(description)="data">
+ <b-row class="semi-bold-16px tretiatry">
+ {{ data.item.description.name }}
+ </b-row>
+ <b-row
+ class="regular-12px tretiatry pointer"
+ @click="toggleRowDetails(data)"
+ >
+ {{ data.item.description.description }}</b-row
+ >
+ </template>
+ <template #row-details="{ index }">
+ <b-container fluid>
+ <b-col class="mt-1 mb-2 regular-12px tretiatry">
+ <span class="row-details">
+ {{
+ `Краткое описание ошибки или сообщение которое состоит из текста указывающего на предмет ошибки.Краткое описание ошибки или сообщение которое состоит из текста указывающего на предмет ошибки.
+ Краткое описание ошибки или сообщение которое состоит из текста указывающего на предмет ошибки.Краткое описание ошибки или сообщение которое состоит из текста указывающего на предмет ошибки.`
+ }}
+ {{ $t(eventsItems[index].description.description) }}
+ </span>
+ </b-col>
+ </b-container>
+ </template>
+ </b-table>
+ </div>
+ </div>
+ </div>
+ <div class="indicators-container">
+ <span class="bold-16px">{{ $t('global.status.indicators') }}</span>
+ <span class="indicators-units regular-12px tretiatry">
+ {{ $t('global.units.unit') }}</span
+ >
+ <b-button id="popover-choice-1" variant="unstyled">
+ <span class="regular-12px units-label">
+ {{
+ $t(`global.units.${unit === 'Ампераж' ? 'amper' : 'volt'}`)
+ }}</span
+ >
+ <img class="units__icon" src="@/assets/images/_sila/icon-chevron-red.svg" />
+ </b-button>
+ </div>
+ <two-chioce-popover
+ :id="1"
+ fitst-option="Ампераж"
+ second-option="Вольтаж"
+ :chosen-option="unit"
+ :first-action="selectAmper"
+ :second-action="selectVolt"
+ />
+ <date-switch :switch-time-scale="switchTimeScale" :time-scale="timeScale" />
+ <accessory-table :records="accessoryData.power" />
+ <power-table :time-scale="timeScale" />
+ <div class="tables-container">
+ <span class="semi-bold-16px">Управление</span>
+ </div>
+ <control-system />
+ </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import TableRowExpandMixin from '@/components/Mixins/TableRowExpandMixin';
+import DateSwitch from '@/components/Global/SilaComponents/DateSwitch';
+import AccessoryTable from '@/components/Global/SilaComponents/Tables/AccessoryTableWithLabel';
+import ControlSystem from '@/components/Global/SilaComponents/InventoryControlSystem';
+import TwoChiocePopover from '@/components/Global/SilaComponents/TwoChiocePopover';
+
+import PowerTable from './PowerTable';
+import { AccessoryData, ServerItems, EventsItems } from './helpers';
+export default {
+ components: {
+ PageTitle,
+ DateSwitch,
+ AccessoryTable,
+ PowerTable,
+ ControlSystem,
+ TwoChiocePopover,
+ },
+ mixins: [TableRowExpandMixin],
+ data() {
+ return {
+ unit: 'Ампераж',
+ isActive: false,
+ timeScale: 'hour',
+ stickyHeader: '511px',
+ accessoryData: AccessoryData,
+ serverItems: ServerItems,
+ eventsItems: EventsItems,
+ server_fields: [
+ {
+ key: 'param',
+ label: 'Раздел',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'value',
+ label: 'Статус',
+ formatter: this.dataFormatter,
+ thStyle: { width: '10%' },
+ },
+ ],
+ events_fields: [
+ {
+ key: 'date',
+ label: 'Время',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'type',
+ label: 'Тип события',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'description',
+ label: 'О событии',
+ formatter: this.dataFormatter,
+ },
+ ],
+ };
+ },
+ methods: {
+ switchTimeScale(period) {
+ this.timeScale = period;
+ },
+ selectAmper() {
+ this.unit = 'Ампераж';
+ },
+ selectVolt() {
+ this.unit = 'Вольтаж';
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+.tables-container {
+ display: flex;
+ flex-flow: row nowrap;
+ margin: 16px 32px;
+ gap: 24px;
+}
+
+.server-table {
+ width: 35%;
+}
+
+.events-table {
+ width: 65%;
+}
+
+#events-table-wrapper div {
+ overflow-y: overlay;
+ overflow-x: hidden;
+ &::-webkit-scrollbar {
+ position: absolute;
+ width: 10px;
+ }
+ &::-webkit-scrollbar-thumb {
+ border: 4px solid transparent;
+ border-top: 43px solid transparent;
+ background: $faint-secondary-primary-20;
+ border-radius: 16px;
+ background-clip: content-box;
+ }
+}
+
+.row-details {
+ display: block;
+ height: auto;
+ width: 30vw;
+}
+
+.errors {
+ color: $indicators-errors !important;
+}
+
+.warning {
+ color: $indicators-warning !important;
+}
+
+.information {
+ color: $indicators-complementary !important;
+}
+
+.indicators-container {
+ margin-left: 2rem;
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+}
+
+.indicators-units {
+ margin-left: auto;
+}
+
+.units__icon {
+ margin: 0 32px 0 5px;
+ cursor: pointer;
+}
+
+.units-label {
+ cursor: pointer;
+ color: $red-brand-primary;
+}
+</style>
diff --git a/src/views/_sila/SILA/AnalyticalPanel/PowerTable.vue b/src/views/_sila/SILA/AnalyticalPanel/PowerTable.vue
new file mode 100644
index 00000000..27bb4efa
--- /dev/null
+++ b/src/views/_sila/SILA/AnalyticalPanel/PowerTable.vue
@@ -0,0 +1,82 @@
+<template>
+ <div>
+ <highcharts :options="chartOptions.line" />
+ </div>
+</template>
+
+<script>
+import { setTime, Series, setCategories } from './helpers';
+import { Chart } from 'highcharts-vue';
+
+export default {
+ components: {
+ highcharts: Chart,
+ },
+ props: {
+ timeScale: {
+ type: String,
+ default: 'hour',
+ },
+ },
+ computed: {
+ chartOptions() {
+ return {
+ line: {
+ chart: {
+ type: 'areaspline',
+ margin: [12, 50, 32, 60],
+ height: '320px',
+ },
+ title: null,
+ xAxis: {
+ categories: setTime(6, this.timeScale),
+ title: null,
+ labels: {
+ step: 1,
+ },
+ minorGridLineColor: '#1A3E5B1A',
+ },
+ yAxis: {
+ categories: setCategories(2.5, 'A'),
+ min: 0,
+ max: 4,
+ title: null,
+ tickInterval: 1,
+ minorGridLineColor: '#1A3E5B1A',
+ },
+ series: Series['power'].map((item) => ({
+ ...item,
+ marker: {
+ enabled: false,
+ },
+ })),
+ legend: {
+ enabled: false,
+ },
+ tooltip: {
+ enabled: false,
+ crosshairs: false,
+ },
+ plotOptions: {
+ series: {
+ showInLegend: true,
+ },
+ areaspline: {
+ fillOpacity: 0,
+ },
+ },
+ },
+ };
+ },
+ },
+};
+</script>
+<style lang="scss">
+.highcharts-credits {
+ display: none;
+}
+
+.highcharts-plot-line-label {
+ transform: translate(-15px, 0) !important;
+}
+</style>
diff --git a/src/views/_sila/SILA/AnalyticalPanel/TemperatureTable.vue b/src/views/_sila/SILA/AnalyticalPanel/TemperatureTable.vue
new file mode 100644
index 00000000..ae52062a
--- /dev/null
+++ b/src/views/_sila/SILA/AnalyticalPanel/TemperatureTable.vue
@@ -0,0 +1,115 @@
+<template>
+ <div>
+ <highcharts :options="chartOptions.line" />
+ </div>
+</template>
+
+<script>
+import { setTime, Series, setCategories } from './helpers';
+import { Chart } from 'highcharts-vue';
+
+export default {
+ components: {
+ highcharts: Chart,
+ },
+ props: {
+ timeScale: {
+ type: String,
+ default: 'hour',
+ },
+ warning: {
+ type: Number,
+ default: 70,
+ },
+ nonNormal: {
+ type: Number,
+ default: 70,
+ },
+ criticalStart: {
+ type: Number,
+ default: 70,
+ },
+ },
+ computed: {
+ chartOptions() {
+ return {
+ line: {
+ chart: {
+ type: 'areaspline',
+ margin: [12, 50, 32, 60],
+ height: '320px',
+ },
+ title: null,
+ xAxis: {
+ categories: setTime(60, 'hour'),
+ title: null,
+ labels: {
+ step: 6,
+ },
+ minorGridLineColor: '#1A3E5B1A',
+ },
+ yAxis: {
+ categories: setCategories(101, 'С°'),
+ min: 0,
+ max: 100,
+ title: null,
+ minTickInterval: 25,
+ minorGridLineColor: '#1A3E5B1A',
+ plotLines: [
+ {
+ color: '#E11717',
+ dashStyle: 'solid',
+ value: this.warning,
+ zIndex: '1000',
+ width: 2,
+ label: {
+ text: 'Пороговое значение предупреждения, С°',
+ align: 'right',
+ style: {
+ fontFamily: 'Inter, sans-serif',
+ fontSize: '12px',
+ fontStyle: 'normal',
+ fontWeight: '400',
+ lineHeight: '16px',
+ color: '#0C1C2999',
+ },
+ },
+ },
+ ],
+ },
+ series: Series['temperature'].map((item) => ({
+ ...item,
+ marker: {
+ enabled: false,
+ },
+ })),
+ legend: {
+ enabled: false,
+ },
+ tooltip: {
+ enabled: false,
+ crosshairs: false,
+ },
+ plotOptions: {
+ series: {
+ showInLegend: true,
+ },
+ areaspline: {
+ fillOpacity: 0,
+ },
+ },
+ },
+ };
+ },
+ },
+};
+</script>
+<style lang="scss">
+.highcharts-credits {
+ display: none;
+}
+
+.highcharts-plot-line-label {
+ transform: translate(-15px, 0) !important;
+}
+</style>
diff --git a/src/views/_sila/SILA/AnalyticalPanel/helpers.js b/src/views/_sila/SILA/AnalyticalPanel/helpers.js
new file mode 100644
index 00000000..d1ffd728
--- /dev/null
+++ b/src/views/_sila/SILA/AnalyticalPanel/helpers.js
@@ -0,0 +1,196 @@
+export const colors = [
+ '#CB32F1',
+ '#F18638',
+ '#139BB9',
+ '#E1AB17',
+ '#175AE1',
+ '#13B937',
+];
+
+export const Series = {
+ power: [
+ {
+ name: 'Sean',
+ data: [1, 1, 2.7, 0.5, 0.2, 1],
+ color: '#CB32F1',
+ },
+ {
+ name: 'Ivan',
+ data: [0.4, 0.3, 1, 1.4, 2, 0.4],
+ color: '#F18638',
+ },
+ {
+ name: 'Brendan',
+ data: [0.5, 2.5, 1, 0.4, 1, 3],
+ color: '#139BB9',
+ },
+ ],
+};
+
+export const setTime = (count) => {
+ const arr = [...new Array(count)].map(() => '');
+ for (let i = 0; i < arr.length; i++) {
+ arr[i] = `15:${i}0`;
+ }
+ return arr;
+};
+
+export const setCategories = (count, desc) => {
+ const arr = [];
+ for (let i = 0; i < count; i += 0.5) {
+ arr.push(`${i} ${desc}`);
+ }
+ return arr;
+};
+
+export const AccessoryData = {
+ power: {
+ fields: [
+ {
+ key: 'name',
+ label: 'Наименование',
+ },
+ {
+ key: 'power',
+ label: 'Текущее значение тока, А',
+ },
+ ],
+ items: [
+ {
+ name: 'Источникк питания 1',
+ power: '1,3 A',
+ },
+ {
+ name: 'Источникк питания 2',
+ power: '1,8 A',
+ },
+ {
+ name: 'Источникк питания 3',
+ power: '1,6 A',
+ },
+ ],
+ },
+};
+
+export const ServerItems = [
+ { param: 'Сервер №1', value: true },
+ { param: 'ВМС', value: true },
+ { param: 'Аналитическая панель', value: true },
+ { param: 'RAID-контроллеры', value: false },
+ { param: 'Модули памяти', value: true },
+ { param: 'Процессоры', value: true },
+ { param: 'Источники питания', value: true },
+ { param: 'Вентиляторы', value: true },
+ { param: 'Физические накопители', value: true },
+ { param: 'Виртуальные накопители', value: true },
+ { param: 'Материнская плата', value: true },
+ { param: 'Сетевые адаптеры', value: true },
+ { param: 'PCI устройства', value: true },
+];
+
+export const EventsItems = [
+ {
+ date: '23.11.2021 в 13.36',
+ type: 'Критические',
+ description: {
+ name: 'Имя источника событий',
+ description: 'Краткое описание ошибки или сообщени....',
+ },
+ },
+ {
+ date: '23.11.2021 в 13.36',
+ type: 'Критические',
+ description: {
+ name: 'Имя источника событий',
+ description: 'Краткое описание ошибки или сообщени....',
+ },
+ },
+ {
+ date: '23.11.2021 в 13.36',
+ type: 'Критические',
+ description: {
+ name: 'Имя источника событий',
+ description: 'Краткое описание ошибки или сообщени....',
+ },
+ },
+ {
+ date: '23.11.2021 в 13.36',
+ type: 'Критические',
+ description: {
+ name: 'Имя источника событий',
+ description: 'Краткое описание ошибки или сообщени....',
+ },
+ },
+ {
+ date: '23.11.2021 в 13.36',
+ type: 'Критические',
+ description: {
+ name: 'Имя источника событий',
+ description: 'Краткое описание ошибки или сообщени....',
+ },
+ },
+ {
+ date: '23.11.2021 в 13.36',
+ type: 'Критические',
+ description: {
+ name: 'Имя источника событий',
+ description: 'Краткое описание ошибки или сообщени....',
+ },
+ },
+ {
+ date: '23.11.2021 в 13.36',
+ type: 'Критические',
+ description: {
+ name: 'Имя источника событий',
+ description: 'Краткое описание ошибки или сообщени....',
+ },
+ },
+ {
+ date: '23.11.2021 в 13.36',
+ type: 'Критические',
+ description: {
+ name: 'Имя источника событий',
+ description: 'Краткое описание ошибки или сообщени....',
+ },
+ },
+ {
+ date: '23.11.2021 в 13.36',
+ type: 'Критические',
+ description: {
+ name: 'Имя источника событий',
+ description: 'Краткое описание ошибки или сообщени....',
+ },
+ },
+ {
+ date: '23.11.2021 в 13.36',
+ type: 'Критические',
+ description: {
+ name: 'Имя источника событий',
+ description: 'Краткое описание ошибки или сообщени....',
+ },
+ },
+ {
+ date: '23.11.2021 в 13.36',
+ type: 'Критические',
+ description: {
+ name: 'Имя источника событий',
+ description: 'Краткое описание ошибки или сообщени....',
+ },
+ },
+ {
+ date: '23.11.2021 в 13.36',
+ type: 'Критические',
+ description: {
+ name: 'Имя источника событий',
+ description: 'Краткое описание ошибки или сообщени....',
+ },
+ },
+ {
+ date: '23.11.2021 в 13.36',
+ type: 'Критические',
+ description: {
+ name: 'Имя источника событий',
+ description: 'Краткое описание ошибки или сообщени....',
+ },
+ },
+];
diff --git a/src/views/_sila/SILA/AnalyticalPanel/index.js b/src/views/_sila/SILA/AnalyticalPanel/index.js
new file mode 100644
index 00000000..7da2938e
--- /dev/null
+++ b/src/views/_sila/SILA/AnalyticalPanel/index.js
@@ -0,0 +1,2 @@
+import AnalyticalPanelPage from './AnalyticalPanelPage.vue';
+export default AnalyticalPanelPage;
diff --git a/src/views/_sila/SILA/NetworkAdapters/Dynamic/NetworkDynamicPage.vue b/src/views/_sila/SILA/NetworkAdapters/Dynamic/NetworkDynamicPage.vue
new file mode 100644
index 00000000..3745a71f
--- /dev/null
+++ b/src/views/_sila/SILA/NetworkAdapters/Dynamic/NetworkDynamicPage.vue
@@ -0,0 +1,135 @@
+<template>
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title :description="$t('appNavigation.analyticalPanel')" />
+ <date-switch :switch-time-scale="switchTimeScale" :time-scale="timeScale" />
+ <div class="limit-container">
+ <div class="trmperature-limt">
+ <img src="@/assets/images/labels/warning.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.temperatureWarning')
+ }}</span>
+ <b-form-input
+ v-model="temperatureWarningInput"
+ type="number"
+ :min="0"
+ :max="100"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <b-button
+ class="save-button"
+ variant="primary"
+ @click="updateTemperature"
+ >
+ {{ $t('global.action.save') }}
+ </b-button>
+ </div>
+ <!-- Temperature Table -->
+ <temperature-table
+ :time-scale="timeScale"
+ :warning="temperatureWarning"
+ :non-normal="temperatureNonNormal"
+ :critical-start="temperatureCriticalStart"
+ />
+ <accessory-table :records="accessoryData.temperatureTable" />
+ </b-container>
+</template>
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import DateSwitch from '@/components/Global/SilaComponents/DateSwitch';
+import TemperatureTable from './TemperatureTable';
+import AccessoryTable from '@/components/Global/SilaComponents/Tables/AccessoryTableWithLabel';
+import iconChevronUp from '@carbon/icons-vue/es/chevron--up/16';
+
+import { AccessoryData } from './helpers';
+
+export default {
+ components: {
+ PageTitle,
+ DateSwitch,
+ TemperatureTable,
+ AccessoryTable,
+ },
+ data() {
+ return {
+ timeScale: 'hour',
+ temperatureWarning: 72,
+ temperatureWarningInput: 72,
+ notificationInput: 42,
+ accessoryData: AccessoryData,
+ iconChevronUp: iconChevronUp,
+ };
+ },
+ methods: {
+ switchTimeScale(period) {
+ this.timeScale = period;
+ },
+ updateTemperature() {
+ this.temperatureWarning = +this.temperatureWarningInput;
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+//nav items style
+.nav-item,
+.nav-link {
+ padding: 0;
+}
+.nav-item {
+ list-style-type: none;
+}
+
+a {
+ color: $text-primary !important;
+ &:hover {
+ color: $text-primary !important;
+ }
+}
+
+.notification-button {
+ border: none;
+ background: none;
+}
+
+.semi-bold-12px {
+ z-index: 1001;
+}
+
+// temperature limit comtainer
+.limit-container {
+ height: 85px;
+ width: 100%;
+ padding: 0 32px 10px 32px;
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: flex-start;
+ align-items: flex-end;
+ gap: 24px;
+}
+
+.trmperature-limt {
+ height: 60px;
+ width: 100%;
+ max-width: 270px;
+ display: flex;
+ align-items: baseline;
+ flex-flow: row wrap;
+ gap: 8px;
+}
+
+.form-control {
+ height: 36px;
+ &.non-normal {
+ width: 125px;
+ }
+}
+.save-button {
+ width: 151px;
+ height: 36px;
+}
+</style>
diff --git a/src/views/_sila/SILA/NetworkAdapters/Dynamic/TemperatureTable.vue b/src/views/_sila/SILA/NetworkAdapters/Dynamic/TemperatureTable.vue
new file mode 100644
index 00000000..1bbf7e08
--- /dev/null
+++ b/src/views/_sila/SILA/NetworkAdapters/Dynamic/TemperatureTable.vue
@@ -0,0 +1,112 @@
+<template>
+ <div>
+ <highcharts :options="chartOptions.line" />
+ </div>
+</template>
+
+<script>
+import { setTime, Series, setCategories } from './helpers';
+import { Chart } from 'highcharts-vue';
+
+export default {
+ components: {
+ highcharts: Chart,
+ },
+ props: {
+ timeScale: {
+ type: String,
+ default: 'hour',
+ },
+ warning: {
+ type: Number,
+ default: 70,
+ },
+ nonNormal: {
+ type: Number,
+ default: 70,
+ },
+ criticalStart: {
+ type: Number,
+ default: 70,
+ },
+ },
+ computed: {
+ chartOptions() {
+ return {
+ line: {
+ chart: {
+ type: 'line',
+ margin: [12, 50, 32, 60],
+ height: '320px',
+ },
+ title: null,
+ xAxis: {
+ categories: setTime(60, 'hour'),
+ title: null,
+ labels: {
+ step: 6,
+ },
+ minorGridLineColor: '#1A3E5B1A',
+ },
+ yAxis: {
+ categories: setCategories(101, 'С°'),
+ min: 0,
+ max: 100,
+ title: null,
+ minTickInterval: 25,
+ minorGridLineColor: '#1A3E5B1A',
+ plotLines: [
+ {
+ color: '#E11717',
+ dashStyle: 'solid',
+ value: this.warning,
+ zIndex: '1000',
+ width: 2,
+ label: {
+ text: 'Пороговое значение предупреждения, С°',
+ align: 'right',
+ style: {
+ fontFamily: 'Inter, sans-serif',
+ fontSize: '12px',
+ fontStyle: 'normal',
+ fontWeight: '400',
+ lineHeight: '16px',
+ color: '#0C1C2999',
+ },
+ },
+ },
+ ],
+ },
+ series: Series['temperature'].map((item) => ({
+ ...item,
+ marker: {
+ enabled: false,
+ },
+ })),
+ legend: {
+ enabled: false,
+ },
+ tooltip: {
+ enabled: false,
+ crosshairs: false,
+ },
+ plotOptions: {
+ series: {
+ showInLegend: true,
+ },
+ },
+ },
+ };
+ },
+ },
+};
+</script>
+<style lang="scss">
+.highcharts-credits {
+ display: none;
+}
+
+.highcharts-plot-line-label {
+ transform: translate(-15px, 0) !important;
+}
+</style>
diff --git a/src/views/_sila/SILA/NetworkAdapters/Dynamic/helpers.js b/src/views/_sila/SILA/NetworkAdapters/Dynamic/helpers.js
new file mode 100644
index 00000000..65046d01
--- /dev/null
+++ b/src/views/_sila/SILA/NetworkAdapters/Dynamic/helpers.js
@@ -0,0 +1,356 @@
+export const colors = ['#CB32F1', '#F18638', '#139BB9', '#E1AB17'];
+
+export const Series = {
+ temperature: [
+ {
+ name: 'Sean',
+ data: [
+ 7,
+ 7,
+ 7,
+ 17,
+ 7,
+ 27,
+ 7,
+ 7,
+ 47,
+ 7,
+ 7,
+ 7,
+ 37,
+ 7,
+ 7,
+ 7,
+ 27,
+ 7,
+ 7,
+ 7,
+ 27,
+ 7,
+ 7,
+ 7,
+ 47,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 27,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 27,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 37,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ 7,
+ ],
+ color: '#CB32F1',
+ },
+ {
+ name: 'Ivan',
+ data: [
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 20,
+ 10,
+ 10,
+ 30,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 50,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 20,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 30,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 19,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ ],
+ color: '#F18638',
+ },
+ {
+ name: 'Brendan',
+ data: [
+ 13,
+ 13,
+ 13,
+ 13,
+ 23,
+ 13,
+ 33,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 23,
+ 13,
+ 43,
+ 13,
+ 53,
+ 13,
+ 13,
+ 13,
+ 53,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 53,
+ 13,
+ 43,
+ 13,
+ 13,
+ 63,
+ 13,
+ 43,
+ 13,
+ 23,
+ 13,
+ 43,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ ],
+ color: '#139BB9',
+ },
+ {
+ name: 'Matteo',
+ data: [
+ 24,
+ 14,
+ 44,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 34,
+ 14,
+ 14,
+ 14,
+ 14,
+ 34,
+ 14,
+ 24,
+ 14,
+ 34,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 44,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 44,
+ 14,
+ 54,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 84,
+ 14,
+ 94,
+ 14,
+ 14,
+ 14,
+ 54,
+ 14,
+ 44,
+ 14,
+ 44,
+ 14,
+ 14,
+ 44,
+ 14,
+ ],
+ color: '#E1AB17',
+ },
+ ],
+};
+
+export const setTime = (count) => {
+ const arr = [...new Array(count)].map(() => '');
+ for (let i = 0; i < arr.length; i++) {
+ arr[i] = `15:${String(i).padStart(2, '0')}`;
+ }
+ return arr;
+};
+
+export const setCategories = (count, desc) => {
+ const arr = [...new Array(count)].map((i, k) => `${k} ${desc}`);
+ return arr;
+};
+
+export const AccessoryData = {
+ temperatureTable: {
+ fields: [
+ {
+ key: 'name',
+ label: 'Имя модуля',
+ },
+ {
+ key: 'currentTemperature',
+ label: 'Текущее, С°',
+ },
+ {
+ key: 'middleTemperature',
+ label: 'Среднее, С°',
+ },
+ {
+ key: 'minTemperature',
+ label: 'Минимальное, С°',
+ },
+ {
+ key: 'minDate',
+ label: 'Дата минимального',
+ },
+ {
+ key: 'maxTemperature',
+ label: 'Максимальное, С°',
+ },
+ {
+ key: 'maxDate',
+ label: 'Дата максимального',
+ },
+ ],
+ items: [
+ {
+ name: 'Приемопередитчик 1',
+ currentTemperature: 19,
+ middleTemperature: 40,
+ minTemperature: 31,
+ minDate: { time: '15:15', date: '11.11.2021' },
+ maxTemperature: 88,
+ maxDate: { time: '10:26', date: '15.11.2021' },
+ },
+ {
+ name: 'Приемопередитчик 2',
+ currentTemperature: 29,
+ middleTemperature: 40,
+ minTemperature: 20,
+ minDate: { time: '15:45', date: '11.11.2021' },
+ maxTemperature: 76,
+ maxDate: { time: '16:59', date: '16.11.2021' },
+ },
+ {
+ name: 'Приемопередитчик 3',
+ currentTemperature: 48,
+ middleTemperature: 46,
+ minTemperature: 31,
+ minDate: { time: '15:23', date: '11.11.2021' },
+ maxTemperature: 69,
+ maxDate: { time: '15:26', date: '15.11.2021' },
+ },
+ {
+ name: 'Приемопередитчик 4',
+ currentTemperature: 48,
+ middleTemperature: 45,
+ minTemperature: 5,
+ minDate: { time: '16:45', date: '25.11.2021' },
+ maxTemperature: 75,
+ maxDate: { time: '11:26', date: '16.11.2021' },
+ },
+ ],
+ },
+};
diff --git a/src/views/_sila/SILA/NetworkAdapters/Dynamic/index.js b/src/views/_sila/SILA/NetworkAdapters/Dynamic/index.js
new file mode 100644
index 00000000..081b5560
--- /dev/null
+++ b/src/views/_sila/SILA/NetworkAdapters/Dynamic/index.js
@@ -0,0 +1 @@
+export { default } from './NetworkDynamicPage.vue';
diff --git a/src/views/_sila/SILA/NetworkAdapters/EthernetAdapters/EthernetAdaptersPage.vue b/src/views/_sila/SILA/NetworkAdapters/EthernetAdapters/EthernetAdaptersPage.vue
new file mode 100644
index 00000000..62a4bcab
--- /dev/null
+++ b/src/views/_sila/SILA/NetworkAdapters/EthernetAdapters/EthernetAdaptersPage.vue
@@ -0,0 +1,399 @@
+<template>
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title :description="$t('appNavigation.ethernetAdapters')" />
+ <data-tabs
+ :slots="adaptersSlots"
+ :switch-tab="switchAdapterSlot"
+ :current-tab="currentAdapterSlot"
+ :slot-width="85"
+ :slider-width="60"
+ style="margin-top: 16px"
+ />
+ <page-section class="bootstrap-table__section">
+ <div class="settings-container">
+ <span class="bold-16px">{{ $t('appNavigation.settings') }}</span>
+ <apply-settings-popover
+ :appaly-on-reload="appalyOnReload"
+ :appaly-option1="appalyOption1"
+ :appaly-option2="appalyOption2"
+ :apply-type="applyType"
+ />
+ <b-button variant="primary" class="apply-button">
+ {{ $t('global.action.acceptChanges') }}
+ </b-button>
+ </div>
+ <span class="bold-12px__caps">
+ {{ $t('pageNetwork.macAddress') }}
+ </span>
+ <b-table
+ responsive="md"
+ class="table-stripes"
+ no-border-collapse
+ :items="items"
+ :fields="fields"
+ >
+ <template #cell(value)="data">
+ <b-row>
+ <b-col>
+ <span>
+ {{ data.value }}
+ </span>
+ </b-col>
+ <b-col>
+ <img
+ src="@/assets/images/icon-edit.svg"
+ class="icon-chevron icon-edit"
+ />
+ </b-col>
+ </b-row>
+ </template>
+ </b-table>
+ <span class="bold-12px__caps">
+ {{ $t('adapters.settings') }}
+ </span>
+ <b-table
+ responsive="md"
+ class="table-stripes"
+ no-border-collapse
+ :items="items_2"
+ :fields="fields"
+ >
+ <template #cell(value)="data">
+ <b-row v-if="data.index === 3" class="multiple-select-container">
+ <b-col v-if="selected.length" class="chip-column">
+ <b-row class="chip-container">
+ <div
+ v-for="item in selected"
+ :key="item.value"
+ class="custom-chip"
+ >
+ <span> {{ item.text }} </span>
+ <img
+ class="clear-icon"
+ src="@/assets/images/_sila/popups/x-icon.svg"
+ @click="optionRemove(item.value)"
+ />
+ </div>
+ </b-row>
+ </b-col>
+ <b-col v-else>
+ {{ 'Не выбрано ' }}
+ </b-col>
+ <b-col class="icon-container">
+ <b-button id="popover-boot" variant="toogle-popover">
+ <img :is="iconChevron" class="icon-chevron" />
+ </b-button>
+ <b-popover
+ placement="left"
+ triggers="focus"
+ :show.sync="show"
+ custom-class="boot-popover"
+ target="popover-boot"
+ >
+ <b-form-group
+ v-slot="{ ariaDescribedby }"
+ class="checkbox-group"
+ >
+ <b-form-checkbox-group
+ v-model="selected"
+ :options="options"
+ :aria-describedby="ariaDescribedby"
+ class="regular-14px checkbox-container"
+ stacked
+ ></b-form-checkbox-group>
+ </b-form-group>
+ </b-popover>
+ </b-col>
+ </b-row>
+ <b-row v-else>
+ <b-col>
+ <span>
+ {{ data.value ? 'Возможно' : 'Не возможно' }}
+ </span>
+ </b-col>
+ <b-col>
+ <img :is="iconChevron" class="icon-chevron icon-options" />
+ </b-col>
+ </b-row>
+ </template>
+ </b-table>
+ <span class="bold-12px__caps">
+ {{ $t('adapters.propherties') }}
+ </span>
+ <b-table
+ responsive="md"
+ class="table-stripes"
+ no-border-collapse
+ :items="items_3"
+ :fields="fields"
+ >
+ </b-table>
+ <div class="settings-container">
+ <span class="bold-16px">{{ $t('adapters.PXE') }}</span>
+ <apply-settings-popover
+ :id="2"
+ :appaly-on-reload="appalyOnReload"
+ :appaly-option1="appalyOption1"
+ :appaly-option2="appalyOption2"
+ :apply-type="applyType"
+ />
+ </div>
+ <b-table
+ responsive="md"
+ class="table-stripes"
+ no-border-collapse
+ :items="items_4"
+ :fields="fields"
+ >
+ <template #cell(value)="data">
+ <b-row class="flex-row">
+ <b-col>
+ <span>
+ {{ data.value ? 'Включено' : 'Выключено' }}
+ </span>
+ </b-col>
+ <b-col>
+ <b-form-checkbox v-model="items_4[data.index].value" switch>
+ </b-form-checkbox>
+ </b-col>
+ </b-row>
+ </template>
+ </b-table>
+ <div class="settings-container">
+ <span class="bold-16px">{{ $t('adapters.links') }}</span>
+ </div>
+ <b-table
+ responsive="md"
+ class="table-stripes"
+ no-border-collapse
+ :items="items_5"
+ :fields="fields"
+ >
+ </b-table>
+ <div class="settings-container">
+ <span class="bold-16px">{{ $t('adapters.transceivers') }}</span>
+ </div>
+ <b-table
+ responsive="md"
+ show-empty
+ class="table-rounded"
+ no-border-collapse
+ :items="items_6"
+ :fields="fields_2"
+ :empty-text="$t('global.table.emptyMessage')"
+ >
+ </b-table>
+ <div class="microcode-container">
+ <span class="bold-16px">{{
+ $t('SystemDescription.microcodeAdapter')
+ }}</span>
+ <popover
+ id="popover-reactive-1"
+ description="adapters.microcodeUpdate"
+ popup="adapters.microcodeUpdate_popup"
+ button="global.action.refresh"
+ :is-microcode-drivers="true"
+ />
+ </div>
+ </page-section>
+ </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import PageSection from '@/components/Global/PageSection';
+import Popover from '@/components/Global/Popover';
+import ApplySettingsPopover from '@/components/Global/SilaComponents/ApplySettingsPopover';
+import DataTabs from '@/components/Global/SilaComponents/DataTabs';
+
+import iconChevron from '@carbon/icons-vue/es/chevron--down/16';
+import { items, items_2, items_3, items_4, items_5, items_6 } from './helpers';
+
+export default {
+ components: {
+ PageTitle,
+ PageSection,
+ DataTabs,
+ Popover,
+ ApplySettingsPopover,
+ },
+ data() {
+ return {
+ items,
+ items_2,
+ items_3,
+ items_4,
+ items_5,
+ items_6,
+ iconChevron,
+ selected: [],
+ show: false,
+ options: [
+ { text: 'PXE', value: { text: 'PXE', value: 'pxe' } },
+ { text: 'ISCSI-PXE', value: { text: 'ISCSI-PXE', value: 'iscsi-pxe' } },
+ { text: 'ISCSI', value: { text: 'ISCSI', value: 'iscsi' } },
+ { text: 'PXE2', value: { text: 'PXE2', value: 'pxe2' } },
+ { text: 'ISCSI 2', value: { text: 'ISCSI 2', value: 'iscsi2' } },
+ {
+ text: 'ISCSI-PXE 2',
+ value: { text: 'ISCSI-PXE 2', value: 'iscsi-pxe2' },
+ },
+ ],
+ applyType: 'reload',
+ currentAdapterSlot: 1,
+ adaptersSlots: [
+ { id: 1, name: 'Адаптер 1' },
+ { id: 2, name: 'Адаптер 2' },
+ { id: 3, name: 'Адаптер 3' },
+ ],
+ fields: [
+ {
+ key: 'param',
+ label: '',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'value',
+ label: '',
+ formatter: this.dataFormatter,
+ },
+ ],
+ fields_2: [
+ {
+ key: 'name',
+ label: 'Параметр',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'model',
+ label: 'Модель',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'number',
+ label: 'Серийный номер',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'type',
+ label: 'Тип устройства',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'firmware',
+ label: 'Прошивка',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'status',
+ label: 'Статус',
+ formatter: this.dataFormatter,
+ },
+ ],
+ };
+ },
+ methods: {
+ switchAdapterSlot(period) {
+ this.currentAdapterSlot = period;
+ },
+ appalyOnReload() {
+ this.applyType = 'reload';
+ },
+ appalyOption1() {
+ this.applyType = 'option1';
+ },
+ appalyOption2() {
+ this.applyType = 'option2';
+ },
+ optionRemove(value) {
+ this.selected.splice(
+ this.selected.findIndex((el) => el.value === value),
+ 1
+ );
+ console.log(value);
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+.bold-16px {
+ display: block;
+ margin: 25px 0 16px 0;
+}
+
+.settings-container {
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+}
+
+.apply-button {
+ width: 245px;
+ height: 36px;
+}
+
+.microcode-container {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ align-items: baseline;
+ justify-content: space-between;
+}
+
+.bold-12px__caps {
+ display: block;
+ margin: 20px 0 8px 0;
+}
+
+.flex-row {
+ align-items: center;
+}
+
+.multiple-select-container {
+ justify-content: flex-end;
+}
+
+.chip-column {
+ padding-right: 0px;
+}
+
+.chip-container {
+ margin-left: -5px;
+}
+
+.custom-chip {
+ display: flex;
+ align-items: center;
+ height: 24px;
+ margin: 2px 3px;
+ padding: 0 10px;
+ background-color: $faint-secondary-primary-10;
+ border-radius: 94px;
+}
+
+.icon-container {
+ flex-grow: 0;
+ padding: 0px;
+ margin: 0 11px 0 5px;
+}
+
+.clear-icon {
+ width: 10px;
+ margin-left: 6px;
+ cursor: pointer;
+}
+
+.checkbox-group {
+ margin: 0;
+}
+
+.checkbox-container {
+ display: flex;
+ flex-direction: column;
+ flex-wrap: nowrap;
+ gap: 7px;
+}
+</style>
diff --git a/src/views/_sila/SILA/NetworkAdapters/EthernetAdapters/helpers.js b/src/views/_sila/SILA/NetworkAdapters/EthernetAdapters/helpers.js
new file mode 100644
index 00000000..918f5b4e
--- /dev/null
+++ b/src/views/_sila/SILA/NetworkAdapters/EthernetAdapters/helpers.js
@@ -0,0 +1,99 @@
+export const items = [
+ {
+ param: 'MAC адрес',
+ value: 'D0:94:66:2A:77:33',
+ },
+ {
+ param: 'Виртуальный MAC адрес',
+ value: 'D0:94:66:2A:77:33',
+ },
+];
+export const items_2 = [
+ {
+ param: 'Пробуждение по локальной сети',
+ value: true,
+ },
+ {
+ param: 'Менеджмент проходит через',
+ value: true,
+ },
+ {
+ param: 'Энергоэффективный Ethernet',
+ value: true,
+ },
+ {
+ param: 'Поддерживаемый boot протокол',
+ value: true,
+ },
+ {
+ param: 'Способность политики сохранения',
+ value: true,
+ },
+];
+export const items_3 = [
+ {
+ param: 'Версия прошивки',
+ value: '20.6.6.2',
+ },
+ {
+ param: 'Версия драйвера',
+ value: '3.134',
+ },
+ {
+ param: 'PCI device ID',
+ value: '165F',
+ },
+];
+
+export const items_4 = [
+ {
+ param: 'Встроенные порты PXE',
+ value: true,
+ },
+];
+
+export const items_5 = [
+ {
+ param: 'Статус',
+ value: 'Подключено',
+ },
+ {
+ param: 'Скорость',
+ value: '1000 Mbps',
+ },
+];
+
+export const items_6 = [
+ {
+ name: 'Приемопередатчик 1',
+ model: 'A0507',
+ number: '789578456698',
+ type: 'Плата',
+ firmware: 'v 21.6.0',
+ status: 'Link',
+ },
+ {
+ name: 'Приемопередатчик 2',
+ model: 'A0507',
+ number: '543636577755',
+ type: 'Плата',
+ firmware: 'v 21.6.0',
+ status: 'Receiver Signal Averange Optical Power',
+ },
+ {
+ name: 'Приемопередатчик 3',
+ model: 'A0408',
+ number: '789578456698',
+ type: 'Плата',
+ firmware: 'v 21.6.0',
+ status: 'Laser Output Power',
+ },
+ {
+ name: 'Приемопередатчик 4',
+ model: 'A0408',
+ number: '123456789087',
+ type: 'Плата',
+ firmware: 'v 21.6.0',
+ status: 'Laser Output Power',
+ },
+];
diff --git a/src/views/_sila/SILA/NetworkAdapters/EthernetAdapters/index.js b/src/views/_sila/SILA/NetworkAdapters/EthernetAdapters/index.js
new file mode 100644
index 00000000..47f49789
--- /dev/null
+++ b/src/views/_sila/SILA/NetworkAdapters/EthernetAdapters/index.js
@@ -0,0 +1 @@
+export { default } from './EthernetAdaptersPage.vue';
diff --git a/src/views/_sila/SILA/NetworkAdapters/FcHbaAdapters/FcHbaAdaptersPage.vue b/src/views/_sila/SILA/NetworkAdapters/FcHbaAdapters/FcHbaAdaptersPage.vue
new file mode 100644
index 00000000..9ccc0509
--- /dev/null
+++ b/src/views/_sila/SILA/NetworkAdapters/FcHbaAdapters/FcHbaAdaptersPage.vue
@@ -0,0 +1,211 @@
+<template>
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title :description="$t('appNavigation.fcHbaAdapters')" />
+ <data-tabs
+ :slots="adaptersSlots"
+ :switch-tab="switchAdapterSlot"
+ :current-tab="currentAdapterSlot"
+ :slot-width="85"
+ :slider-width="60"
+ style="margin-top: 16px"
+ />
+ <page-section class="bootstrap-table__section">
+ <div class="settings-container">
+ <span class="bold-16px">{{ $t('appNavigation.settings') }}</span>
+ <apply-settings-popover
+ :appaly-on-reload="appalyOnReload"
+ :appaly-option1="appalyOption1"
+ :appaly-option2="appalyOption2"
+ :apply-type="applyType"
+ />
+ <b-button variant="primary" class="apply-button">
+ {{ $t('global.action.acceptChanges') }}
+ </b-button>
+ </div>
+ <span class="bold-12px__caps">
+ {{ $t('adapters.wwnAddres') }}
+ </span>
+ <b-table
+ responsive="md"
+ class="table-stripes"
+ no-border-collapse
+ :items="items"
+ :fields="fields"
+ >
+ <template #cell(value)="data">
+ <b-row>
+ <b-col>
+ <span>
+ {{ data.value }}
+ </span>
+ </b-col>
+ <b-col>
+ <img
+ src="@/assets/images/icon-edit.svg"
+ class="icon-chevron icon-edit"
+ />
+ </b-col>
+ </b-row>
+ </template>
+ </b-table>
+ <span class="bold-12px__caps">
+ {{ $t('adapters.settings') }}
+ </span>
+ <b-table
+ responsive="md"
+ class="table-stripes"
+ no-border-collapse
+ :items="items_2"
+ :fields="fields"
+ >
+ <template #cell(value)="data">
+ <b-row v-if="data.index === 0 || data.index === 3">
+ <b-col>
+ <span>
+ {{ data.value }}
+ </span>
+ </b-col>
+ </b-row>
+ <b-row v-else-if="data.index === 4">
+ <b-col>
+ <span>
+ {{ data.value ? 'Включено' : 'Выключено' }}
+ </span>
+ </b-col>
+ <b-col>
+ <img :is="iconChevron" class="icon-chevron icon-options" />
+ </b-col>
+ </b-row>
+ <b-row v-else>
+ <b-col>
+ <span>
+ {{ data.value }}
+ </span>
+ </b-col>
+ <b-col>
+ <img :is="iconChevron" class="icon-chevron icon-options" />
+ </b-col>
+ </b-row>
+ </template>
+ </b-table>
+ <span class="bold-12px__caps">
+ {{ $t('adapters.propherties') }}
+ </span>
+ <b-table
+ responsive="md"
+ class="table-stripes"
+ no-border-collapse
+ :items="items_3"
+ :fields="fields"
+ >
+ </b-table>
+ <div class="microcode-container">
+ <span class="bold-16px">{{
+ $t('SystemDescription.microcodeAdapter')
+ }}</span>
+ <popover
+ id="popover-reactive-1"
+ description="adapters.microcodeUpdate"
+ popup="adapters.microcodeUpdate_popup"
+ button="global.action.refresh"
+ :is-microcode-drivers="true"
+ />
+ </div>
+ </page-section>
+ </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import PageSection from '@/components/Global/PageSection';
+import Popover from '@/components/Global/Popover';
+import ApplySettingsPopover from '@/components/Global/SilaComponents/ApplySettingsPopover';
+import DataTabs from '@/components/Global/SilaComponents/DataTabs';
+
+import iconChevron from '@carbon/icons-vue/es/chevron--down/16';
+import { items, items_2, items_3 } from './helpers';
+
+export default {
+ components: {
+ PageTitle,
+ PageSection,
+ DataTabs,
+ Popover,
+ ApplySettingsPopover,
+ },
+ data() {
+ return {
+ items,
+ items_2,
+ items_3,
+ iconChevron,
+ applyType: 'reload',
+ currentAdapterSlot: 1,
+ adaptersSlots: [
+ { id: 1, name: 'Адаптер 1' },
+ { id: 2, name: 'Адаптер 2' },
+ { id: 3, name: 'Адаптер 3' },
+ ],
+ fields: [
+ {
+ key: 'param',
+ label: '',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'value',
+ label: '',
+ formatter: this.dataFormatter,
+ },
+ ],
+ };
+ },
+ methods: {
+ switchAdapterSlot(period) {
+ this.currentAdapterSlot = period;
+ },
+ appalyOnReload() {
+ this.applyType = 'reload';
+ },
+ appalyOption1() {
+ this.applyType = 'option1';
+ },
+ appalyOption2() {
+ this.applyType = 'option2';
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+.bold-16px {
+ display: block;
+ margin: 25px 0 16px 0;
+}
+
+.settings-container {
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+}
+
+.apply-button {
+ width: 245px;
+ height: 36px;
+}
+
+.microcode-container {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ align-items: baseline;
+ justify-content: space-between;
+}
+
+.bold-12px__caps {
+ display: block;
+ margin: 20px 0 8px 0;
+}
+</style>
diff --git a/src/views/_sila/SILA/NetworkAdapters/FcHbaAdapters/helpers.js b/src/views/_sila/SILA/NetworkAdapters/FcHbaAdapters/helpers.js
new file mode 100644
index 00000000..a2ace22f
--- /dev/null
+++ b/src/views/_sila/SILA/NetworkAdapters/FcHbaAdapters/helpers.js
@@ -0,0 +1,42 @@
+export const items = [
+ {
+ param: 'WWN адрес',
+ value: 'D0:94:66:2A:77:33',
+ },
+];
+export const items_2 = [
+ {
+ param: 'Boot WWPN',
+ value: 'Имя порта контроллера (WWPN)',
+ },
+ {
+ param: 'Select Boot Enable',
+ value: 'Boot Lun',
+ },
+ {
+ param: 'Boot LUN',
+ value: 'Том 1',
+ },
+ {
+ param: 'WWPN',
+ value: 'Имя порта HBA (WWPN)',
+ },
+ {
+ param: 'Host Adapter Bios Enable',
+ value: false,
+ },
+];
+export const items_3 = [
+ {
+ param: 'Версия прошивки',
+ value: '20.6.6.2',
+ },
+ {
+ param: 'Версия драйвера',
+ value: '3.134',
+ },
+ {
+ param: 'PCI device ID',
+ value: '165F',
+ },
+];
diff --git a/src/views/_sila/SILA/NetworkAdapters/FcHbaAdapters/index.js b/src/views/_sila/SILA/NetworkAdapters/FcHbaAdapters/index.js
new file mode 100644
index 00000000..8f5636c3
--- /dev/null
+++ b/src/views/_sila/SILA/NetworkAdapters/FcHbaAdapters/index.js
@@ -0,0 +1 @@
+export { default } from './FcHbaAdaptersPage.vue';
diff --git a/src/views/_sila/SILA/PciDevices/PciDevicesPage.vue b/src/views/_sila/SILA/PciDevices/PciDevicesPage.vue
new file mode 100644
index 00000000..3bc45ca2
--- /dev/null
+++ b/src/views/_sila/SILA/PciDevices/PciDevicesPage.vue
@@ -0,0 +1,115 @@
+<template>
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title />
+ <page-section
+ :section-title="$t('appNavigation.pciDevicesTitle')"
+ class="bootstrap-table__section"
+ >
+ <b-table
+ responsive="md"
+ show-empty
+ class="table-rounded"
+ no-border-collapse
+ :items="items"
+ :fields="fields"
+ :empty-text="$t('global.table.emptyMessage')"
+ >
+ <template #cell(status)>
+ <b-row>
+ <b-col>
+ <img src="@/assets/images/status/on.svg" class="icon-chevron" />
+ <span>
+ {{ 'Работоспособен' }}
+ </span>
+ </b-col>
+ </b-row>
+ </template>
+ </b-table>
+ </page-section>
+ </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import PageSection from '@/components/Global/PageSection';
+
+export default {
+ components: { PageTitle, PageSection },
+ data() {
+ return {
+ fields: [
+ {
+ key: 'status',
+ label: 'Статус',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'name',
+ label: 'Имя',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'type',
+ label: 'Тип устройства',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'model',
+ label: 'Модель',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'serial_number',
+ label: 'Серийный номер',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'producer',
+ label: 'Производитель',
+ formatter: this.dataFormatter,
+ },
+ ],
+ items: [
+ {
+ status: true,
+ name: 'PCI-устройство 1',
+ type: 'Плата',
+ model: 'A0407',
+ serial_number: '789578456698',
+ producer: 'ASUS',
+ },
+ {
+ status: true,
+ name: 'PCI-устройство 2',
+ type: 'Плата',
+ model: 'A4897',
+ serial_number: '758496877563',
+ producer: 'ASUS',
+ },
+ {
+ status: true,
+ name: 'PCI-устройство 3',
+ type: 'Плата',
+ model: 'A0147',
+ serial_number: '247856889654',
+ producer: 'ASUS',
+ },
+ ],
+ };
+ },
+ methods: {
+ switchMemorySlot(period) {
+ this.currentMemorySlot = period;
+ },
+ redirectDrivers() {
+ this.$router.push('/drivers-static');
+ },
+ redirectVirtual() {
+ this.$router.push('/virtual-drivers');
+ },
+ },
+};
+</script>
diff --git a/src/views/_sila/SILA/PciDevices/index.js b/src/views/_sila/SILA/PciDevices/index.js
new file mode 100644
index 00000000..20092914
--- /dev/null
+++ b/src/views/_sila/SILA/PciDevices/index.js
@@ -0,0 +1 @@
+export { default } from './PciDevicesPage.vue';
diff --git a/src/views/_sila/SILA/PhysicalDrivers/DynamicInfo/DriversDynamicPage.vue b/src/views/_sila/SILA/PhysicalDrivers/DynamicInfo/DriversDynamicPage.vue
new file mode 100644
index 00000000..fadbf2b2
--- /dev/null
+++ b/src/views/_sila/SILA/PhysicalDrivers/DynamicInfo/DriversDynamicPage.vue
@@ -0,0 +1,204 @@
+<template>
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title :description="$t('appNavigation.dynamicInformation')" />
+ <div class="notification__container">
+ <span class="semi-bold-12px">{{
+ $t('global.ariaLabel.notificationTime')
+ }}</span>
+ <div class="form-control notification">
+ <b-form-input
+ v-model="notificationInput"
+ type="number"
+ class="notification__input"
+ >
+ </b-form-input>
+ <button class="notification_button">
+ <img class="notification__icon" src="@/assets/images/refresh.svg" />
+ </button>
+ </div>
+ </div>
+ <date-switch :switch-time-scale="switchTimeScale" :time-scale="timeScale" />
+ <div class="limit-container">
+ <div class="trmperature-limt">
+ <img src="@/assets/images/labels/non-normal.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.nonNormalMode')
+ }}</span>
+ <b-form-input
+ v-model="temperatureNonNormalInput"
+ type="number"
+ :min="0"
+ :max="temperatureCritical"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <div class="trmperature-limt">
+ <img src="@/assets/images/labels/critical.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.criticalMode')
+ }}</span>
+ <b-form-input
+ v-model="temperatureCritical"
+ type="number"
+ :min="temperatureNonNormalInput"
+ :max="temperatureWarningInput"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <div class="trmperature-limt">
+ <img src="@/assets/images/labels/warning.svg" />
+ <span class="semi-bold-12px">{{
+ $t('tablesDescription.temperatureWarning')
+ }}</span>
+ <b-form-input
+ v-model="temperatureWarningInput"
+ type="number"
+ :min="temperatureCritical"
+ :max="100"
+ class="form-control medium-12px"
+ >
+ </b-form-input>
+ </div>
+ <b-button
+ class="save-button"
+ variant="primary"
+ @click="updateTemperatureLimits"
+ >
+ {{ $t('global.action.save') }}
+ </b-button>
+ </div>
+ <!-- Temperature Table -->
+ <temperature-table
+ :time-scale="timeScale"
+ :warning="temperatureWarning"
+ :non-normal="temperatureNonNormal"
+ :critical-start="temperatureCriticalStart"
+ />
+ <accessory-table-drivers :records="accessoryData.table" />
+ <accessory-table :records="accessoryData.temperatureTable" />
+ </b-container>
+</template>
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import DateSwitch from '@/components/Global/SilaComponents/DateSwitch';
+import TemperatureTable from './TemperatureTable';
+import AccessoryTable from '@/components/Global/SilaComponents/Tables/AccessoryTable';
+import AccessoryTableDrivers from '@/components/Global/SilaComponents/Tables/AccessoryTableDrivers';
+import iconChevronUp from '@carbon/icons-vue/es/chevron--up/16';
+
+import { AccessoryData } from './helpers';
+
+export default {
+ components: {
+ PageTitle,
+ DateSwitch,
+ TemperatureTable,
+ AccessoryTable,
+ AccessoryTableDrivers,
+ },
+ data() {
+ return {
+ timeScale: 'hour',
+ temperatureWarning: 72,
+ temperatureWarningInput: 72,
+ temperatureNonNormal: 44,
+ temperatureNonNormalInput: 44,
+ temperatureCriticalStart: 55,
+ temperatureCritical: 55,
+ notificationInput: 42,
+ accessoryData: AccessoryData,
+ iconChevronUp: iconChevronUp,
+ };
+ },
+ methods: {
+ switchTimeScale(period) {
+ this.timeScale = period;
+ },
+ updateTemperatureLimits() {
+ this.temperatureWarning = +this.temperatureWarningInput;
+ this.temperatureNonNormal = +this.temperatureNonNormalInput;
+ this.temperatureCriticalStart = +this.temperatureCritical;
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+.notification__container {
+ position: absolute;
+ top: calc(#{$header-height});
+ right: 0px;
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: flex-start;
+ align-items: center;
+}
+
+.notification {
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: flex-start;
+ align-items: center;
+ border: none;
+ box-shadow: none;
+ border-radius: 8px;
+ margin: 12px 32px 12px 8px;
+ width: 236px;
+ height: 40px;
+ z-index: 1001;
+}
+
+.notification__icon {
+ width: 20px;
+ height: 20px;
+}
+
+.notification__input {
+ border: none;
+ background: none;
+ box-shadow: none;
+}
+
+.notification_button {
+ border: none;
+ background: none;
+}
+
+.semi-bold-12px {
+ z-index: 1001;
+}
+
+// temperature limit comtainer
+.limit-container {
+ height: 85px;
+ width: 100%;
+ padding: 0 32px 10px 32px;
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: flex-start;
+ align-items: flex-end;
+ gap: 24px;
+}
+
+.trmperature-limt {
+ height: 60px;
+ width: 100%;
+ max-width: 270px;
+ display: flex;
+ align-items: baseline;
+ flex-flow: row wrap;
+ gap: 8px;
+}
+
+.form-control {
+ height: 36px;
+}
+.save-button {
+ width: 151px;
+ height: 36px;
+}
+</style>
diff --git a/src/views/_sila/SILA/PhysicalDrivers/DynamicInfo/TemperatureTable.vue b/src/views/_sila/SILA/PhysicalDrivers/DynamicInfo/TemperatureTable.vue
new file mode 100644
index 00000000..f9c149c3
--- /dev/null
+++ b/src/views/_sila/SILA/PhysicalDrivers/DynamicInfo/TemperatureTable.vue
@@ -0,0 +1,126 @@
+<template>
+ <div>
+ <highcharts :options="chartOptions.line" />
+ </div>
+</template>
+
+<script>
+import { setTime, Series, setCategories } from './helpers';
+import { Chart } from 'highcharts-vue';
+
+export default {
+ components: {
+ highcharts: Chart,
+ },
+ props: {
+ timeScale: {
+ type: String,
+ default: 'hour',
+ },
+ warning: {
+ type: Number,
+ default: 70,
+ },
+ nonNormal: {
+ type: Number,
+ default: 70,
+ },
+ criticalStart: {
+ type: Number,
+ default: 70,
+ },
+ },
+ computed: {
+ chartOptions() {
+ return {
+ line: {
+ chart: {
+ type: 'line',
+ margin: [12, 50, 32, 60],
+ height: '320px',
+ },
+ title: null,
+ xAxis: {
+ categories: setTime(60, 'hour'),
+ title: null,
+ labels: {
+ step: 6,
+ },
+ minorGridLineColor: '#1A3E5B1A',
+ },
+ yAxis: {
+ categories: setCategories(101, 'С°'),
+ min: 0,
+ max: 100,
+ title: null,
+ minTickInterval: 25,
+ minorGridLineColor: '#1A3E5B1A',
+ plotLines: [
+ {
+ color: '#E11717',
+ dashStyle: 'solid',
+ value: this.warning,
+ zIndex: '1000',
+ width: 2,
+ label: {
+ text: 'Пороговое значение предупреждения, С°',
+ align: 'right',
+ style: {
+ fontFamily: 'Inter, sans-serif',
+ fontSize: '12px',
+ fontStyle: 'normal',
+ fontWeight: '400',
+ lineHeight: '16px',
+ color: '#0C1C2999',
+ },
+ },
+ },
+ ],
+ plotBands: [
+ {
+ color: '#F0AC0C1A',
+ dashStyle: 'solid',
+ from: this.nonNormal,
+ to: this.criticalStart,
+ },
+ {
+ color: '#FF41411A',
+ dashStyle: 'solid',
+ from: this.criticalStart,
+ to: this.warning,
+ },
+ ],
+ },
+ series: Series['temperature'].map((item) => ({
+ ...item,
+ marker: {
+ enabled: false,
+ },
+ })),
+ legend: {
+ enabled: false,
+ },
+ tooltip: {
+ enabled: false,
+ crosshairs: false,
+ },
+ plotOptions: {
+ series: {
+ showInLegend: true,
+ },
+ },
+ },
+ };
+ },
+ },
+};
+</script>
+<style lang="scss">
+.highcharts-credits {
+ display: none;
+}
+
+.highcharts-plot-line-label {
+ transform: translate(-15px, 0) !important;
+}
+</style>
diff --git a/src/views/_sila/SILA/PhysicalDrivers/DynamicInfo/helpers.js b/src/views/_sila/SILA/PhysicalDrivers/DynamicInfo/helpers.js
new file mode 100644
index 00000000..9115f9e5
--- /dev/null
+++ b/src/views/_sila/SILA/PhysicalDrivers/DynamicInfo/helpers.js
@@ -0,0 +1,564 @@
+export const colors = [
+ '#CB32F1',
+ '#F18638',
+ '#139BB9',
+ '#E1AB17',
+ '#175AE1',
+ '#13B937',
+];
+
+export const Series = {
+ temperature: [
+ {
+ name: 'Sean',
+ data: [
+ 15,
+ 15,
+ 45,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 55,
+ 15,
+ 25,
+ 15,
+ 15,
+ 15,
+ 55,
+ 15,
+ 75,
+ 15,
+ 35,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 45,
+ 15,
+ 25,
+ 15,
+ 45,
+ 15,
+ 15,
+ 15,
+ 35,
+ 35,
+ 35,
+ 15,
+ 55,
+ 15,
+ 15,
+ 35,
+ 15,
+ 25,
+ 15,
+ 35,
+ 15,
+ ],
+ color: '#CB32F1',
+ },
+ {
+ name: 'Ivan',
+ data: [
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 22,
+ 12,
+ 42,
+ 12,
+ 12,
+ 12,
+ 72,
+ 12,
+ 52,
+ 12,
+ 62,
+ 12,
+ 72,
+ 12,
+ 12,
+ 12,
+ 12,
+ 42,
+ 12,
+ 12,
+ 52,
+ 12,
+ 42,
+ 12,
+ 12,
+ 62,
+ 12,
+ 12,
+ 12,
+ 22,
+ 12,
+ 42,
+ 12,
+ 62,
+ 12,
+ 12,
+ 32,
+ 12,
+ 12,
+ 12,
+ 52,
+ 12,
+ 32,
+ 12,
+ 22,
+ 12,
+ 12,
+ 12,
+ ],
+ color: '#175AE1',
+ },
+ {
+ name: 'Brendan',
+ data: [
+ 13,
+ 13,
+ 13,
+ 13,
+ 23,
+ 13,
+ 33,
+ 13,
+ 63,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 23,
+ 13,
+ 43,
+ 13,
+ 53,
+ 13,
+ 13,
+ 13,
+ 53,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 53,
+ 13,
+ 43,
+ 13,
+ 13,
+ 63,
+ 13,
+ 13,
+ 13,
+ 23,
+ 13,
+ 43,
+ 13,
+ 63,
+ 13,
+ 13,
+ 13,
+ 53,
+ 13,
+ 53,
+ ],
+ color: '#B98D13',
+ },
+ {
+ name: 'Matteo',
+ data: [
+ 24,
+ 14,
+ 44,
+ 14,
+ 14,
+ 14,
+ 64,
+ 14,
+ 14,
+ 14,
+ 54,
+ 14,
+ 14,
+ 34,
+ 14,
+ 24,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 44,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 44,
+ 14,
+ 54,
+ 14,
+ 14,
+ 14,
+ 54,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 84,
+ 14,
+ 14,
+ 14,
+ 54,
+ 14,
+ 14,
+ 14,
+ 44,
+ 14,
+ 44,
+ 64,
+ 14,
+ 44,
+ 14,
+ ],
+ color: '#13B937',
+ },
+ {
+ name: 'Joan',
+ data: [
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 36,
+ 16,
+ 26,
+ 16,
+ 36,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 26,
+ 16,
+ 46,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 56,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 96,
+ 16,
+ 16,
+ 16,
+ 56,
+ 16,
+ 16,
+ 16,
+ 46,
+ 16,
+ ],
+ color: '#F18638',
+ },
+ {
+ name: 'Avinash',
+ data: [
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 69,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 59,
+ 19,
+ 19,
+ 39,
+ 19,
+ 29,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 49,
+ 19,
+ 19,
+ 19,
+ 59,
+ 19,
+ 29,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ ],
+ color: '#139BB9',
+ },
+ ],
+};
+
+export const setTime = (count) => {
+ const arr = [...new Array(count)].map(() => '');
+ for (let i = 0; i < arr.length; i++) {
+ arr[i] = `15:${String(i).padStart(2, '0')}`;
+ }
+ return arr;
+};
+
+export const setCategories = (count, desc) => {
+ const arr = [...new Array(count)].map((i, k) => `${k} ${desc}`);
+ return arr;
+};
+
+export const AccessoryData = {
+ temperatureTable: {
+ fields: [
+ {
+ key: 'name',
+ label: 'Имя модуля',
+ },
+ {
+ key: 'currentTemperature',
+ label: 'Текущее, С°',
+ },
+ {
+ key: 'middleTemperature',
+ label: 'Среднее, С°',
+ },
+ {
+ key: 'minTemperature',
+ label: 'Минимальное, С°',
+ },
+ {
+ key: 'minDate',
+ label: 'Дата минимального',
+ },
+ {
+ key: 'maxTemperature',
+ label: 'Максимальное, С°',
+ },
+ {
+ key: 'maxDate',
+ label: 'Дата максимального',
+ },
+ ],
+ items: [
+ {
+ name: 'Накопитель 1',
+ currentTemperature: 19,
+ middleTemperature: 40,
+ minTemperature: 31,
+ minDate: { time: '15:15', date: '11.11.2021' },
+ maxTemperature: 88,
+ maxDate: { time: '10:26', date: '15.11.2021' },
+ },
+ {
+ name: 'Накопитель 2',
+ currentTemperature: 29,
+ middleTemperature: 40,
+ minTemperature: 20,
+ minDate: { time: '15:45', date: '11.11.2021' },
+ maxTemperature: 76,
+ maxDate: { time: '16:59', date: '16.11.2021' },
+ },
+ {
+ name: 'Накопитель 3',
+ currentTemperature: 48,
+ middleTemperature: 46,
+ minTemperature: 31,
+ minDate: { time: '15:23', date: '11.11.2021' },
+ maxTemperature: 69,
+ maxDate: { time: '15:26', date: '15.11.2021' },
+ },
+ {
+ name: 'Накопитель 4',
+ currentTemperature: 48,
+ middleTemperature: 45,
+ minTemperature: 5,
+ minDate: { time: '16:45', date: '25.11.2021' },
+ maxTemperature: 75,
+ maxDate: { time: '11:26', date: '16.11.2021' },
+ },
+ {
+ name: 'Накопитель 5',
+ currentTemperature: 39,
+ middleTemperature: 44,
+ minTemperature: 30,
+ minDate: { time: '15:23', date: '11.11.2021' },
+ maxTemperature: 80,
+ maxDate: { time: '15:26', date: '17.11.2021' },
+ },
+ {
+ name: 'Накопитель 6',
+ currentTemperature: 39,
+ middleTemperature: 44,
+ minTemperature: 5,
+ minDate: { time: '16:45', date: '25.11.2021' },
+ maxTemperature: 80,
+ maxDate: { time: '15:26', date: '15.11.2021' },
+ },
+ ],
+ },
+ table: {
+ fields: [
+ {
+ key: 'name',
+ label: 'Имя модуля',
+ thStyle: { width: '34%' },
+ },
+ {
+ key: 'SMART',
+ label: 'Текущие значения атрибутов SMART',
+ thStyle: { width: '32%' },
+ },
+ {
+ key: 'resource',
+ label: 'Оставшийся ресурс для SSD, Мб',
+ thStyle: { width: '39%' },
+ },
+ ],
+ items: [
+ {
+ name: 'Накопитель 1',
+ SMART: 88,
+ resource: '1 024 000',
+ },
+ {
+ name: 'Накопитель 2',
+ SMART: 76,
+ resource: '512 000',
+ },
+ {
+ name: 'Накопитель 3',
+ SMART: 69,
+ resource: '256 000',
+ },
+ {
+ name: 'Накопитель 4',
+ SMART: 75,
+ resource: '128 000',
+ },
+ {
+ name: 'Накопитель 5',
+ SMART: 69,
+ resource: '256 000',
+ },
+ {
+ name: 'Накопитель 6',
+ SMART: 75,
+ resource: '128 000',
+ },
+ ],
+ },
+};
diff --git a/src/views/_sila/SILA/PhysicalDrivers/DynamicInfo/index.js b/src/views/_sila/SILA/PhysicalDrivers/DynamicInfo/index.js
new file mode 100644
index 00000000..ed9033ab
--- /dev/null
+++ b/src/views/_sila/SILA/PhysicalDrivers/DynamicInfo/index.js
@@ -0,0 +1 @@
+export { default } from './DriversDynamicPage.vue';
diff --git a/src/views/_sila/SILA/PhysicalDrivers/StaticInfo/DriversStaticPage.vue b/src/views/_sila/SILA/PhysicalDrivers/StaticInfo/DriversStaticPage.vue
new file mode 100644
index 00000000..d6f31985
--- /dev/null
+++ b/src/views/_sila/SILA/PhysicalDrivers/StaticInfo/DriversStaticPage.vue
@@ -0,0 +1,133 @@
+<template>
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title :description="$t('appNavigation.statisticInformation')" />
+ <page-section class="bootstrap-table__section info_section">
+ <span class="bold-16px">{{ $t('global.table.info') }}</span>
+ </page-section>
+ <data-tabs
+ :slots="memorySlots"
+ :switch-tab="switchMemorySlot"
+ :current-tab="currentMemorySlot"
+ :slot-width="100"
+ :slider-width="81"
+ />
+ <page-section class="bootstrap-table__section info_section">
+ <b-table
+ responsive="md"
+ show-empty
+ class="table-rounded"
+ no-border-collapse
+ :items="items"
+ :fields="fields"
+ :empty-text="$t('global.table.emptyMessage')"
+ >
+ </b-table>
+ <div class="microcode-container">
+ <span class="bold-16px">{{
+ $t('SystemDescription.microcodeDrivers')
+ }}</span>
+ <popover
+ id="popover-reactive-1"
+ description="SystemDescription.reloadMicrocodeDrivers"
+ popup="SystemDescription.reloadMicrocodeDrivers"
+ button="global.action.refresh"
+ :is-microcode-drivers="true"
+ />
+ </div>
+ </page-section>
+ </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import PageSection from '@/components/Global/PageSection';
+import DataTabs from '@/components/Global/SilaComponents/DataTabs';
+import Popover from '@/components/Global/Popover';
+
+export default {
+ components: { PageTitle, PageSection, DataTabs, Popover },
+ data() {
+ return {
+ currentMemorySlot: 1,
+ memorySlots: [
+ { id: 1, name: 'Накопитель 1' },
+ { id: 2, name: 'Накопитель 2' },
+ { id: 3, name: 'Накопитель 3' },
+ { id: 4, name: 'Накопитель 4' },
+ { id: 5, name: 'Накопитель 5' },
+ { id: 6, name: 'Накопитель 6' },
+ { id: 7, name: 'Накопитель 7' },
+ { id: 8, name: 'Накопитель 8' },
+ { id: 9, name: 'Накопитель 9' },
+ { id: 10, name: 'Накопитель 10' },
+ { id: 11, name: 'Накопитель 11' },
+ { id: 12, name: 'Накопитель 12' },
+ { id: 13, name: 'Накопитель 13' },
+ { id: 14, name: 'Накопитель 14' },
+ { id: 15, name: 'Накопитель 15' },
+ ],
+ fields: [
+ {
+ key: 'parametr',
+ label: 'Параметр',
+ formatter: this.dataFormatter,
+ thStyle: { width: '50%' },
+ },
+ {
+ key: 'value',
+ label: 'Значение',
+ formatter: this.dataFormatter,
+ },
+ ],
+ items: [
+ {
+ parametr: 'Протокол',
+ value: '4590',
+ },
+ {
+ parametr: 'Номинальная ёмкость',
+ value: '1 024 000 Мб',
+ },
+ {
+ parametr: 'Номинальная скорость вращения HDD',
+ value: '2000 об./мин.',
+ },
+ {
+ parametr: 'Номинальный ресурс для SDD',
+ value: '10 000',
+ },
+ {
+ parametr: 'Слот в бэкплейне или номер порта',
+ value: '25',
+ },
+ ],
+ };
+ },
+ methods: {
+ switchMemorySlot(period) {
+ this.currentMemorySlot = period;
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+.info_section {
+ margin-bottom: 0px;
+}
+
+.bold-16px {
+ display: block;
+ margin: 25px 0 16px 0;
+}
+
+.microcode-container {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ align-items: baseline;
+ justify-content: space-between;
+}
+</style>
diff --git a/src/views/_sila/SILA/PhysicalDrivers/StaticInfo/index.js b/src/views/_sila/SILA/PhysicalDrivers/StaticInfo/index.js
new file mode 100644
index 00000000..2c06b5a2
--- /dev/null
+++ b/src/views/_sila/SILA/PhysicalDrivers/StaticInfo/index.js
@@ -0,0 +1 @@
+export { default } from './DriversStaticPage.vue';
diff --git a/src/views/_sila/SILA/RAID/Cache/RAIDCachePage.vue b/src/views/_sila/SILA/RAID/Cache/RAIDCachePage.vue
new file mode 100644
index 00000000..54efa48f
--- /dev/null
+++ b/src/views/_sila/SILA/RAID/Cache/RAIDCachePage.vue
@@ -0,0 +1,107 @@
+<template>
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title :description="$t('RAID.cache')" />
+ <data-tabs
+ :slots="raidSlots"
+ :switch-tab="switchRaidSlot"
+ :current-tab="currentRaidSlot"
+ :slot-width="100"
+ :slider-width="79"
+ style="margin-top: 16px"
+ />
+ <page-section class="bootstrap-table__section info_section">
+ <span class="bold-16px">{{ $t('RAID.cache_info') }}</span>
+ <b-table
+ responsive="md"
+ show-empty
+ class="table-rounded"
+ no-border-collapse
+ :items="items"
+ :fields="fields"
+ :empty-text="$t('global.table.emptyMessage')"
+ >
+ </b-table>
+ </page-section>
+ </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import PageSection from '@/components/Global/PageSection';
+import DataTabs from '@/components/Global/SilaComponents/DataTabs';
+
+export default {
+ components: { PageTitle, PageSection, DataTabs },
+ data() {
+ return {
+ currentRaidSlot: 1,
+ raidSlots: [
+ { id: 1, name: 'Контроллер 1' },
+ { id: 2, name: 'Контроллер 2' },
+ { id: 3, name: 'Контроллер 3' },
+ ],
+ fields: [
+ {
+ key: 'parametr',
+ label: 'Параметр',
+ formatter: this.dataFormatter,
+ thStyle: { width: '50%' },
+ },
+ {
+ key: 'value',
+ label: 'Значение',
+ formatter: this.dataFormatter,
+ },
+ ],
+ items: [
+ {
+ parametr: 'Статус наличия',
+ value: 'Есть',
+ },
+ {
+ parametr: 'Текущее значение занятой емкости',
+ value: '1 024 000 Мб',
+ },
+ {
+ parametr: 'Текущее значение свободной емкости',
+ value: '1 004 256 Мб',
+ },
+ {
+ parametr: 'Статус наличия BBU',
+ value: 'Есть',
+ },
+ {
+ parametr: 'Статус наличия FBU',
+ value: 'Нет',
+ },
+ {
+ parametr: 'Состояние BBU',
+ value: 'Готов',
+ },
+ {
+ parametr: 'Состояние FBU',
+ value: 'Заряжается',
+ },
+ {
+ parametr: 'Номинальная емкость',
+ value: '1 004 256 Мб',
+ },
+ ],
+ };
+ },
+ methods: {
+ switchRaidSlot(period) {
+ this.currentRaidSlot = period;
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+.bold-16px {
+ display: block;
+ margin: 0 0 16px 0;
+}
+</style>
diff --git a/src/views/_sila/SILA/RAID/Cache/index.js b/src/views/_sila/SILA/RAID/Cache/index.js
new file mode 100644
index 00000000..76acfcbe
--- /dev/null
+++ b/src/views/_sila/SILA/RAID/Cache/index.js
@@ -0,0 +1 @@
+export { default } from './RAIDCachePage.vue';
diff --git a/src/views/_sila/SILA/RAID/Settings/ActionSettingsPopover.vue b/src/views/_sila/SILA/RAID/Settings/ActionSettingsPopover.vue
new file mode 100644
index 00000000..2f3093ab
--- /dev/null
+++ b/src/views/_sila/SILA/RAID/Settings/ActionSettingsPopover.vue
@@ -0,0 +1,131 @@
+<template>
+ <b-popover
+ placement="left"
+ triggers="focus"
+ :show.sync="show"
+ custom-class="apply-reload-popover"
+ :target="`popover-action-${id}`"
+ @hidden="onHidden"
+ >
+ <b-button
+ id="popover-apply-button"
+ variant="popover"
+ :class="{ 'hovered-apply-button': scale === topPosition }"
+ @mouseover="scale = topPosition"
+ @click="
+ () => {
+ show = false;
+ appalyOnReload();
+ }
+ "
+ >
+ При перезагрузке
+ </b-button>
+ <b-button
+ id="popover-apply-button"
+ variant="popover"
+ :class="{ 'hovered-apply-button': scale === middlePosition }"
+ @mouseover="scale = middlePosition"
+ @click="
+ () => {
+ show = false;
+ appalyOption1();
+ }
+ "
+ >
+ Опция 1
+ </b-button>
+ <b-button
+ id="popover-apply-button"
+ variant="popover"
+ :class="{ 'hovered-apply-button': scale === bottomPosition }"
+ @mouseover="scale = bottomPosition"
+ @click="
+ () => {
+ show = false;
+ appalyOption2();
+ }
+ "
+ >
+ Опция 2
+ </b-button>
+ <div class="slider" :style="`left: 5px; top: ${scale}px;`"></div>
+ </b-popover>
+</template>
+
+<script>
+export default {
+ props: {
+ id: {
+ type: Number,
+ default: null,
+ },
+ appalyOnReload: {
+ type: Function,
+ default: null,
+ },
+ appalyOption1: {
+ type: Function,
+ default: null,
+ },
+ appalyOption2: {
+ type: Function,
+ default: null,
+ },
+ applyType: {
+ type: String,
+ default: 'reload',
+ },
+ },
+ data() {
+ return {
+ topPosition: 5,
+ middlePosition: 33,
+ bottomPosition: 60,
+ show: false,
+ scale: 5,
+ };
+ },
+ methods: {
+ onHidden() {
+ if (this.applyType === 'reload') {
+ this.scale = this.topPosition;
+ } else if (this.applyType === 'option1') {
+ this.scale = this.middlePosition;
+ } else {
+ this.scale = this.bottomPosition;
+ }
+ },
+ },
+};
+</script>
+<style lang="scss">
+.analytical-table__status {
+ width: 10%;
+}
+
+#popover-apply-ractive {
+ padding-left: 5px;
+}
+
+.hovered-apply-button {
+ color: $white;
+}
+</style>
+<style lang="scss" scoped>
+#popover-apply-button {
+ justify-content: flex-start;
+ width: 240px;
+}
+
+.slider {
+ width: 240px;
+ height: 28px;
+ border-radius: 8px;
+ background-color: $red-brand-primary;
+ box-shadow: 1px 2px 4px -1px rgb(79 37 37 / 40%) inset;
+ position: absolute;
+ transition: ease-in 0.2s;
+ z-index: -1;
+}
+</style>
diff --git a/src/views/_sila/SILA/RAID/Settings/OptionsPopover.vue b/src/views/_sila/SILA/RAID/Settings/OptionsPopover.vue
new file mode 100644
index 00000000..d1b85754
--- /dev/null
+++ b/src/views/_sila/SILA/RAID/Settings/OptionsPopover.vue
@@ -0,0 +1,87 @@
+<template>
+ <b-popover
+ placement="left"
+ triggers="focus"
+ :show.sync="show"
+ custom-class="popover-heigth-100"
+ :target="`popover-option-${id}`"
+ >
+ <b-button
+ id="popover-option-button"
+ variant="popover"
+ @click="
+ () => {
+ show = false;
+ openModal();
+ }
+ "
+ >
+ <img
+ src="@/assets/images/icon-settings-red.svg"
+ class="icon-chevron icon-settings"
+ />
+ Настройки
+ </b-button>
+ <b-button
+ id="popover-option-button"
+ class="delete"
+ variant="popover"
+ @click="show = false"
+ >
+ <img
+ src="@/assets/images/icon-clear-red.svg"
+ class="icon-chevron icon-delete"
+ />
+ Удалить
+ </b-button>
+ </b-popover>
+</template>
+
+<script>
+export default {
+ props: {
+ id: {
+ type: Number,
+ default: null,
+ },
+ },
+ data() {
+ return {
+ show: false,
+ };
+ },
+ methods: {
+ openModal() {
+ this.$bvModal.show(`edit-tome${this.id}`);
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+.popover-heigth-100 {
+ max-width: 120px;
+}
+
+#popover-option-button {
+ padding: 0 9px 0 10px;
+ font-size: 12px;
+ &:hover {
+ color: $red-brand-primary;
+ box-shadow: 1px 2px 4px -1px rgb(79 37 37 / 25%) inset;
+ }
+ &:active {
+ box-shadow: 1px 2px 4px -1px rgb(79 37 37 / 50%) inset;
+ }
+ &.delete {
+ padding: 0 26px 0 13px;
+ }
+}
+
+.icon-settings {
+ padding-right: 5px;
+}
+
+.icon-delete {
+ padding-right: 10px;
+}
+</style>
diff --git a/src/views/_sila/SILA/RAID/Settings/RAIDSettingsPage.vue b/src/views/_sila/SILA/RAID/Settings/RAIDSettingsPage.vue
new file mode 100644
index 00000000..19caafe0
--- /dev/null
+++ b/src/views/_sila/SILA/RAID/Settings/RAIDSettingsPage.vue
@@ -0,0 +1,288 @@
+<template>
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title :description="$t('appNavigation.settings')" />
+ <data-tabs
+ :slots="raidSlots"
+ :switch-tab="switchRaidSlot"
+ :current-tab="currentRaidSlot"
+ :slot-width="100"
+ :slider-width="79"
+ style="margin-top: 16px"
+ />
+ <page-section class="bootstrap-table__section" style="margin-top: 0px">
+ <div class="settings-container">
+ <span class="bold-16px">{{ $t('appNavigation.settings') }}</span>
+ <apply-settings-popover
+ :appaly-on-reload="appalyOnReload"
+ :appaly-option1="appalyOption1"
+ :appaly-option2="appalyOption2"
+ :apply-type="applyType"
+ />
+ <b-button variant="primary" class="apply-button">
+ {{ $t('global.action.acceptChanges') }}
+ </b-button>
+ </div>
+ <b-table
+ responsive="md"
+ show-empty
+ class="table-rounded"
+ no-border-collapse
+ :items="items"
+ :fields="fields"
+ :empty-text="$t('global.table.emptyMessage')"
+ >
+ <template #cell(action)="data">
+ <b-row v-if="data.index <= 5">
+ <b-col>
+ <span>
+ {{ data.value }}
+ </span>
+ </b-col>
+ <b-col>
+ <b-button
+ :id="`popover-action-${data.index}`"
+ class="popover-action-ractive"
+ variant="toogle-popover"
+ >
+ <img :is="iconChevron" class="icon-chevron" />
+ </b-button>
+ <action-settings-popover
+ :id="data.index"
+ :appaly-on-reload="appalyOnReload"
+ :appaly-option1="appalyOption1"
+ :appaly-option2="appalyOption2"
+ :apply-type="applyType"
+ />
+ </b-col>
+ </b-row>
+ <b-row v-else>
+ <b-col>
+ <span>
+ {{ data.value }}
+ </span>
+ </b-col>
+ <b-col>
+ <img
+ src="@/assets/images/icon-edit.svg"
+ class="icon-chevron icon-edit"
+ />
+ </b-col>
+ </b-row>
+ </template>
+ </b-table>
+ </page-section>
+ <page-section class="bootstrap-table__section">
+ <div class="settings-container">
+ <span class="bold-16px">{{ $t('RAID.lun') }}</span>
+ <b-button
+ variant="primary"
+ class="apply-button apply-button__lun"
+ @click="$bvModal.show('add-tome-images')"
+ >
+ {{ $t('global.action.addNew') }}
+ </b-button>
+ </div>
+ <b-table
+ id="table-raid-settings"
+ responsive="md"
+ show-empty
+ class="table-rounded"
+ no-border-collapse
+ :items="items_2"
+ :fields="fields_2"
+ :empty-text="$t('global.table.emptyMessage')"
+ >
+ <template #cell(action)="data">
+ <b-row>
+ <b-col>
+ <span>
+ {{ data.value }}
+ </span>
+ </b-col>
+ <b-col>
+ <b-button
+ :id="`popover-option-${data.index}`"
+ class="popover-option-ractive"
+ variant="toogle-popover"
+ >
+ <img
+ src="@/assets/images/icon-options.svg"
+ class="icon-chevron icon-options"
+ />
+ </b-button>
+ <options-popover :id="data.index" />
+ <tome-modal
+ :id="`edit-tome${data.index}`"
+ :title="'Настройка виртуального тома'"
+ :action="editTome"
+ :index="data.index"
+ :item="items_2[data.index]"
+ />
+ </b-col>
+ </b-row>
+ </template>
+ </b-table>
+ <div class="microcode-container">
+ <span class="bold-16px">{{ $t('RAID.microcode') }}</span>
+ <popover
+ id="popover-reactive-1"
+ description="RAID.microcode_update"
+ popup="RAID.microcode_popoveer"
+ button="global.action.refresh"
+ :is-microcode-drivers="true"
+ />
+ </div>
+ </page-section>
+ <tome-modal
+ :id="'add-tome-images'"
+ :title="'Новый виртуальный том'"
+ :action="createTome"
+ />
+ </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import PageSection from '@/components/Global/PageSection';
+import Popover from '@/components/Global/Popover';
+import ApplySettingsPopover from '@/components/Global/SilaComponents/ApplySettingsPopover';
+import DataTabs from '@/components/Global/SilaComponents/DataTabs';
+
+import iconChevron from '@carbon/icons-vue/es/chevron--down/16';
+import ActionSettingsPopover from './ActionSettingsPopover';
+import OptionsPopover from './OptionsPopover';
+import TomeModal from './TomeModal';
+import { items, items_2 } from './helpers';
+
+export default {
+ components: {
+ PageTitle,
+ PageSection,
+ DataTabs,
+ Popover,
+ ApplySettingsPopover,
+ ActionSettingsPopover,
+ OptionsPopover,
+ TomeModal,
+ },
+ data() {
+ return {
+ items,
+ items_2,
+ iconChevron,
+ applyType: 'reload',
+ currentRaidSlot: 1,
+ titleModal: '',
+ editIndex: null,
+ raidSlots: [
+ { id: 1, name: 'Контроллер 1' },
+ { id: 2, name: 'Контроллер 2' },
+ { id: 3, name: 'Контроллер 3' },
+ ],
+ fields: [
+ {
+ key: 'parametr',
+ label: 'Имя',
+ formatter: this.dataFormatter,
+ thStyle: { width: '35%' },
+ },
+ {
+ key: 'value',
+ label: 'Текущее значение',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'action',
+ label: 'Действие',
+ formatter: this.dataFormatter,
+ },
+ ],
+ fields_2: [
+ {
+ key: 'name',
+ label: 'Параметр',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'type',
+ label: 'Значение',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'size',
+ label: 'Значение',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'action',
+ label: 'Значение',
+ formatter: this.dataFormatter,
+ },
+ ],
+ };
+ },
+ methods: {
+ switchRaidSlot(period) {
+ this.currentRaidSlot = period;
+ },
+ appalyOnReload() {
+ this.applyType = 'reload';
+ },
+ appalyOption1() {
+ this.applyType = 'option1';
+ },
+ appalyOption2() {
+ this.applyType = 'option2';
+ },
+ createTome() {
+ console.log('Новый том создан');
+ },
+ editTome(index) {
+ console.log('Том изменен');
+ console.log(index);
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+.bold-16px {
+ display: block;
+ margin: 25px 0 16px 0;
+}
+
+.settings-container {
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+}
+
+.apply-button {
+ width: 245px;
+ height: 36px;
+}
+
+.popover-action-ractive {
+ margin: 0 0 0 83%;
+}
+
+.popover-option-ractive {
+ margin: 0 0 0 70%;
+}
+
+.apply-button__lun {
+ width: 245px;
+ height: 36px;
+ margin-left: auto;
+}
+
+.microcode-container {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ align-items: baseline;
+ justify-content: space-between;
+}
+</style>
diff --git a/src/views/_sila/SILA/RAID/Settings/TomeModal.vue b/src/views/_sila/SILA/RAID/Settings/TomeModal.vue
new file mode 100644
index 00000000..c245bd1b
--- /dev/null
+++ b/src/views/_sila/SILA/RAID/Settings/TomeModal.vue
@@ -0,0 +1,179 @@
+<template>
+ <b-modal :id="id" class="modal-images" hide-footer>
+ <template #modal-title>
+ <span class="semi-bold-20px">{{ title }}</span>
+ </template>
+ <div class="modal-body">
+ <label class="regular-12px tretiatry" for="name"> Имя </label>
+ <b-form-input
+ id="name"
+ v-model="tomeName"
+ placeholder="Название тома"
+ type="text"
+ class="form-control form-input"
+ >
+ </b-form-input>
+
+ <form-control>
+ <label class="regular-12px tretiatry type-select-label" for="type"
+ >Тип</label
+ >
+ <b-form-select
+ id="type"
+ v-model="tomeType"
+ :options="tomeTypes"
+ class="select-connection regular-14px"
+ />
+ </form-control>
+
+ <form-control>
+ <label class="regular-12px tretiatry driver-select-label" for="driver"
+ >Физический накопитель</label
+ >
+ <b-form-select
+ id="driver"
+ v-model="tomeDriver"
+ :options="tomeDrivers"
+ class="select-connection regular-14px"
+ />
+ </form-control>
+
+ <label class="regular-12px tretiatry" for="size"> Размер Мб </label>
+ <b-form-input
+ id="size"
+ v-model="tomeSize"
+ placeholder="Размер Тома"
+ type="text"
+ class="form-control form-input"
+ >
+ </b-form-input>
+ <b-button class="upload-button" variant="primary" @click="action(index)">
+ {{ item ? $t('global.action.save') : $t('global.action.addTome') }}
+ </b-button>
+ </div>
+ </b-modal>
+</template>
+<script>
+import { required } from 'vuelidate/lib/validators';
+import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
+
+export default {
+ mixins: [VuelidateMixin],
+ props: {
+ id: {
+ type: String,
+ default: null,
+ },
+ title: {
+ type: String,
+ default: null,
+ },
+ index: {
+ type: Number,
+ default: null,
+ },
+ action: {
+ type: Function,
+ default: null,
+ },
+ item: {
+ type: Object,
+ default: null,
+ },
+ },
+ data() {
+ return {
+ tomeName: '',
+ tomeSize: '',
+ tomeType: 1,
+ tomeTypes: [
+ { value: 1, text: 'RAID-0' },
+ { value: 2, text: 'RAID-1' },
+ ],
+ tomeDriver: 1,
+ tomeDrivers: [
+ { value: 1, text: 'Накопитель 1' },
+ { value: 2, text: 'Накопитель 2' },
+ ],
+ };
+ },
+ mounted() {
+ this.tomeName = this.item.name;
+ this.tomeSize = this.item.size;
+ },
+ validations: {
+ userInfo: {
+ username: {
+ required,
+ },
+ password: {
+ required,
+ },
+ },
+ },
+};
+</script>
+<style lang="scss">
+.modal-content {
+ border-radius: 16px;
+ width: 480px;
+}
+.modal-header {
+ border-bottom: none;
+}
+</style>
+<style lang="scss" scoped>
+.form-input {
+ height: 56px;
+ padding-top: 30px;
+ font-family: 'Inter', sans-serif;
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 20px;
+ letter-spacing: 0em;
+ margin: -30px 0 20px 0;
+}
+
+.modal-body {
+ width: 446px;
+}
+
+.caption-12px,
+.regular-12px {
+ padding-left: 10px;
+}
+
+.select-connection {
+ height: 56px;
+ padding-top: 30px;
+ border: none;
+ border-radius: 8px;
+ margin: -0px 0 18px 0;
+ background-color: $surface-secondary;
+ background-image: url('../../../../../assets/images/_sila/icon-chevron.svg');
+}
+
+.type-select-label {
+ position: absolute;
+ top: 25%;
+}
+
+.driver-select-label {
+ position: absolute;
+ top: 44%;
+ left: 4%;
+}
+
+.form-background .custom-select,
+.form-background .form-control {
+ border-radius: 8px;
+ border: none;
+ background-color: rgba(26, 62, 91, 0.05);
+}
+
+.upload-button {
+ width: 100%;
+ height: 40px;
+ margin: 0 auto 10px;
+}
+</style>
diff --git a/src/views/_sila/SILA/RAID/Settings/helpers.js b/src/views/_sila/SILA/RAID/Settings/helpers.js
new file mode 100644
index 00000000..5727102a
--- /dev/null
+++ b/src/views/_sila/SILA/RAID/Settings/helpers.js
@@ -0,0 +1,62 @@
+export const items = [
+ {
+ parametr: 'Режим контроллера',
+ value: 'RAID',
+ action: 'Автоматически',
+ },
+ {
+ parametr: 'Режим чтения патруля',
+ value: 'Автоматически',
+ action: 'Действие',
+ },
+ {
+ parametr: 'Действие в режиме ручного патрулирования',
+ value: 'Запущен',
+ action: 'Действие',
+ },
+ {
+ parametr: 'Название атрибута',
+ value: 'Запущен',
+ action: 'Действие',
+ },
+ {
+ parametr: 'Название атрибута',
+ value: 'Запущен',
+ action: 'Действие',
+ },
+ {
+ parametr: 'Название атрибута',
+ value: 'Запущен',
+ action: 'Действие',
+ },
+ {
+ parametr: 'Название атрибута',
+ value: '30%',
+ action: '30',
+ },
+ {
+ parametr: 'Название атрибута',
+ value: '30%',
+ action: '30',
+ },
+ {
+ parametr: 'Название атрибута',
+ value: '30%',
+ action: '30',
+ },
+];
+
+export const items_2 = [
+ {
+ name: 'Том 1',
+ type: 'RAID-0',
+ size: '100 125 Мб',
+ action: 'Загружен',
+ },
+ {
+ name: 'Том 2',
+ type: 'RAID-1',
+ size: '200 250 Мб',
+ action: 'Загружен',
+ },
+];
diff --git a/src/views/_sila/SILA/RAID/Settings/index.js b/src/views/_sila/SILA/RAID/Settings/index.js
new file mode 100644
index 00000000..535dbe3a
--- /dev/null
+++ b/src/views/_sila/SILA/RAID/Settings/index.js
@@ -0,0 +1 @@
+export { default } from './RAIDSettingsPage.vue';
diff --git a/src/views/_sila/SILA/RAID/Specification/RAIDSpecificationPage.vue b/src/views/_sila/SILA/RAID/Specification/RAIDSpecificationPage.vue
new file mode 100644
index 00000000..239a41e4
--- /dev/null
+++ b/src/views/_sila/SILA/RAID/Specification/RAIDSpecificationPage.vue
@@ -0,0 +1,221 @@
+<template>
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title :description="$t('appNavigation.specification')" />
+ <data-tabs
+ :slots="raidSlots"
+ :switch-tab="switchRaidSlot"
+ :current-tab="currentRaidSlot"
+ :slot-width="100"
+ :slider-width="79"
+ style="margin-top: 16px"
+ />
+ <page-section class="bootstrap-table__section">
+ <b-table
+ responsive="md"
+ show-empty
+ class="table-rounded"
+ no-border-collapse
+ :items="items"
+ :fields="fields"
+ :empty-text="$t('global.table.emptyMessage')"
+ >
+ <template #cell(value)="{ index, value }">
+ <b-row v-if="index === 0">
+ <b-col>
+ <img src="@/assets/images/status/on.svg" class="icon-chevron" />
+ <span>
+ {{ 'Работоспособен' }}
+ </span>
+ </b-col>
+ </b-row>
+ <b-row v-else-if="index === 7">
+ <b-col>
+ <span class="regular-12px pointer" @click="redirectDrivers">
+ {{ value }}
+ </span>
+ </b-col>
+ </b-row>
+ <b-row v-else-if="index === 8">
+ <b-col>
+ <span class="regular-12px pointer" @click="redirectVirtual">
+ {{ value }}
+ </span>
+ </b-col>
+ </b-row>
+ <b-row v-else>
+ <b-col>
+ <span>{{ value }}</span>
+ </b-col>
+ </b-row>
+ </template>
+ </b-table>
+ </page-section>
+ <b-button
+ v-b-toggle.toggle-collapse
+ variant="link"
+ class="collapse-button semi-bold-16px"
+ >
+ <component :is="iconChevronUp" class="icon-expand-right" />
+ {{ $t('RAID.extraParam') }}
+ </b-button>
+ <b-collapse id="toggle-collapse" class="nav-item__nav">
+ <page-section class="bootstrap-table__section">
+ <b-table
+ responsive="md"
+ class="table-stripes"
+ :items="items_2"
+ :fields="fields_2"
+ >
+ <template #cell(value)="{ index, value }">
+ <b-row v-if="index === 0">
+ <b-col>
+ <img src="@/assets/images/status/on.svg" class="icon-chevron" />
+ <span>
+ {{ 'Работоспособен' }}
+ </span>
+ </b-col>
+ </b-row>
+ <b-row v-else>
+ <b-col>
+ <span>{{ value }}</span>
+ </b-col>
+ </b-row>
+ </template>
+ </b-table>
+ </page-section>
+ </b-collapse>
+ </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import PageSection from '@/components/Global/PageSection';
+import DataTabs from '@/components/Global/SilaComponents/DataTabs';
+
+import iconChevronUp from '@carbon/icons-vue/es/chevron--up/16';
+
+export default {
+ components: { PageTitle, PageSection, DataTabs },
+ data() {
+ return {
+ iconChevronUp: iconChevronUp,
+ currentRaidSlot: 1,
+ raidSlots: [
+ { id: 1, name: 'Контроллер 1' },
+ { id: 2, name: 'Контроллер 2' },
+ { id: 3, name: 'Контроллер 3' },
+ ],
+ fields: [
+ {
+ key: 'parametr',
+ label: 'Параметр',
+ formatter: this.dataFormatter,
+ thStyle: { width: '50%' },
+ },
+ {
+ key: 'value',
+ label: 'Значение',
+ formatter: this.dataFormatter,
+ },
+ ],
+ items: [
+ {
+ parametr: 'Статус',
+ value: true,
+ },
+ {
+ parametr: 'Имя',
+ value: 'RAID-контроллер 1',
+ },
+ {
+ parametr: 'Описание',
+ value: 'Встроенный',
+ },
+ {
+ parametr: 'PCI слот',
+ value: 'Информация недоступна',
+ },
+ {
+ parametr: 'Версия прошивки',
+ value: 'Информация недоступна',
+ },
+ {
+ parametr: 'Версия драйвера',
+ value: 'Информация недоступна',
+ },
+ {
+ parametr: 'Объем cache памяти, Мб',
+ value: '8 096',
+ },
+ {
+ parametr: 'Виртуальные накопители',
+ value: 'Перейти к накопителям',
+ },
+ {
+ parametr: 'Физические накопители',
+ value: 'Перейти к накопителям',
+ },
+ ],
+ fields_2: [
+ {
+ key: 'param',
+ label: '',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'value',
+ label: '',
+ formatter: this.dataFormatter,
+ },
+ ],
+ items_2: [
+ {
+ param: 'Статус',
+ value: true,
+ },
+ {
+ param: 'Скорость',
+ value: 'Информация недоступна',
+ },
+ {
+ param: 'PCI Vendor ID',
+ value: 'Информация недоступна',
+ },
+ {
+ param: 'Скорость',
+ value: 'Информация недоступна',
+ },
+ {
+ param: 'PCI Vendor ID',
+ value: 'Информация недоступна',
+ },
+ ],
+ };
+ },
+ methods: {
+ switchRaidSlot(period) {
+ this.currentRaidSlot = period;
+ },
+ redirectDrivers() {
+ this.$router.push('/drivers-static');
+ },
+ redirectVirtual() {
+ this.$router.push('/virtual-drivers');
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+.bold-16px {
+ display: block;
+ margin: 25px 0 16px 0;
+}
+
+.pointer {
+ color: $red-brand-primary;
+ cursor: pointer;
+}
+</style>
diff --git a/src/views/_sila/SILA/RAID/Specification/index.js b/src/views/_sila/SILA/RAID/Specification/index.js
new file mode 100644
index 00000000..a040cff4
--- /dev/null
+++ b/src/views/_sila/SILA/RAID/Specification/index.js
@@ -0,0 +1 @@
+export { default } from './RAIDSpecificationPage.vue';
diff --git a/src/views/_sila/SILA/VirtualDrivers/VirtualDriversPage.vue b/src/views/_sila/SILA/VirtualDrivers/VirtualDriversPage.vue
new file mode 100644
index 00000000..73633901
--- /dev/null
+++ b/src/views/_sila/SILA/VirtualDrivers/VirtualDriversPage.vue
@@ -0,0 +1,122 @@
+<template>
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title />
+ <page-section class="bootstrap-table__section info_section">
+ <span class="bold-16px">{{ $t('global.table.info') }}</span>
+ </page-section>
+ <data-tabs
+ :slots="memorySlots"
+ :switch-tab="switchMemorySlot"
+ :current-tab="currentMemorySlot"
+ :slot-width="180"
+ :slider-width="156"
+ />
+ <page-section class="bootstrap-table__section info_section">
+ <b-table
+ responsive="md"
+ show-empty
+ class="table-rounded"
+ no-border-collapse
+ :items="items"
+ :fields="fields"
+ :empty-text="$t('global.table.emptyMessage')"
+ >
+ </b-table>
+ <div class="microcode-container">
+ <span class="bold-16px">{{
+ $t('SystemDescription.microcodeDrivers')
+ }}</span>
+ <popover
+ id="popover-reactive-1"
+ description="SystemDescription.reloadMicrocodeDrivers"
+ popup="SystemDescription.reloadMicrocodeDrivers"
+ button="global.action.refresh"
+ :is-microcode-drivers="true"
+ />
+ </div>
+ </page-section>
+ </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import PageSection from '@/components/Global/PageSection';
+import DataTabs from '@/components/Global/SilaComponents/DataTabs';
+import Popover from '@/components/Global/Popover';
+
+export default {
+ components: { PageTitle, PageSection, DataTabs, Popover },
+ data() {
+ return {
+ currentMemorySlot: 1,
+ memorySlots: [
+ { id: 1, name: 'Виртуальный накопитель 1' },
+ { id: 2, name: 'Виртуальный накопитель 2' },
+ { id: 3, name: 'Виртуальный накопитель 3' },
+ { id: 4, name: 'Виртуальный накопитель 4' },
+ { id: 5, name: 'Виртуальный накопитель 5' },
+ { id: 6, name: 'Виртуальный накопитель 6' },
+ { id: 7, name: 'Виртуальный накопитель 7' },
+ { id: 8, name: 'Виртуальный накопитель 8' },
+ ],
+ fields: [
+ {
+ key: 'parametr',
+ label: 'Параметр',
+ formatter: this.dataFormatter,
+ thStyle: { width: '50%' },
+ },
+ {
+ key: 'value',
+ label: 'Значение',
+ formatter: this.dataFormatter,
+ },
+ ],
+ items: [
+ {
+ parametr: 'Текущий статус',
+ value: 'Готов',
+ },
+ {
+ parametr: 'Номинальная емкость',
+ value: '1 024 000 Мб',
+ },
+ {
+ parametr: 'Тип избыточности',
+ value: 'RAID',
+ },
+ {
+ parametr: 'Входящие в состав физические накопители',
+ value: 'Накопитель 1, Накопитель 2, Накопитель 3',
+ },
+ ],
+ };
+ },
+ methods: {
+ switchMemorySlot(period) {
+ this.currentMemorySlot = period;
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+.info_section {
+ margin-bottom: 0px;
+}
+
+.bold-16px {
+ display: block;
+ margin: 25px 0 16px 0;
+}
+
+.microcode-container {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ align-items: baseline;
+ justify-content: space-between;
+}
+</style>
diff --git a/src/views/_sila/SILA/VirtualDrivers/index.js b/src/views/_sila/SILA/VirtualDrivers/index.js
new file mode 100644
index 00000000..23cd6fe1
--- /dev/null
+++ b/src/views/_sila/SILA/VirtualDrivers/index.js
@@ -0,0 +1 @@
+export { default } from './VirtualDriversPage.vue';
diff --git a/src/views/_sila/SecurityAndAccess/Certificates/Certificates.vue b/src/views/_sila/SecurityAndAccess/Certificates/Certificates.vue
index 27950b76..8aee85cf 100644
--- a/src/views/_sila/SecurityAndAccess/Certificates/Certificates.vue
+++ b/src/views/_sila/SecurityAndAccess/Certificates/Certificates.vue
@@ -1,98 +1,101 @@
<template>
- <b-container fluid="xl">
+ <b-container fluid="pt-0 m-0">
<page-title />
- <b-row>
- <b-col xl="11">
- <!-- Expired certificates banner -->
- <alert :show="expiredCertificateTypes.length > 0" variant="danger">
- <template v-if="expiredCertificateTypes.length > 1">
- {{ $t('pageCertificates.alert.certificatesExpiredMessage') }}
- </template>
- <template v-else>
- {{
- $t('pageCertificates.alert.certificateExpiredMessage', {
- certificate: expiredCertificateTypes[0],
- })
- }}
- </template>
- </alert>
- <!-- Expiring certificates banner -->
- <alert :show="expiringCertificateTypes.length > 0" variant="warning">
- <template v-if="expiringCertificateTypes.length > 1">
- {{ $t('pageCertificates.alert.certificatesExpiringMessage') }}
- </template>
- <template v-else>
- {{
- $t('pageCertificates.alert.certificateExpiringMessage', {
- certificate: expiringCertificateTypes[0],
- })
- }}
- </template>
- </alert>
- </b-col>
- </b-row>
- <b-row>
- <b-col xl="11" class="text-right">
- <b-button
- v-b-modal.generate-csr
- data-test-id="certificates-button-generateCsr"
- variant="link"
- >
- <icon-add />
- {{ $t('pageCertificates.generateCsr') }}
- </b-button>
- <b-button
- variant="primary"
- :disabled="certificatesForUpload.length === 0"
- @click="initModalUploadCertificate(null)"
- >
- <icon-add />
- {{ $t('pageCertificates.addNewCertificate') }}
- </b-button>
- </b-col>
- </b-row>
- <b-row>
- <b-col xl="11">
- <b-table
- responsive="md"
- show-empty
- hover
- :busy="isBusy"
- :fields="fields"
- :items="tableItems"
- :empty-text="$t('global.table.emptyMessage')"
- >
- <template #cell(validFrom)="{ value }">
- {{ value | formatDate }}
- </template>
+ <page-section class="bootstrap-table__section">
+ <b-row class="margin-bottom--16px">
+ <b-col xl="11">
+ <!-- Expired certificates banner -->
+ <alert :show="expiredCertificateTypes.length > 0" variant="danger">
+ <template v-if="expiredCertificateTypes.length > 1">
+ {{ $t('pageCertificates.alert.certificatesExpiredMessage') }}
+ </template>
+ <template v-else>
+ {{
+ $t('pageCertificates.alert.certificateExpiredMessage', {
+ certificate: expiredCertificateTypes[0],
+ })
+ }}
+ </template>
+ </alert>
+ <!-- Expiring certificates banner -->
+ <alert :show="expiringCertificateTypes.length > 0" variant="warning">
+ <template v-if="expiringCertificateTypes.length > 1">
+ {{ $t('pageCertificates.alert.certificatesExpiringMessage') }}
+ </template>
+ <template v-else>
+ {{
+ $t('pageCertificates.alert.certificateExpiringMessage', {
+ certificate: expiringCertificateTypes[0],
+ })
+ }}
+ </template>
+ </alert>
+ </b-col>
+ </b-row>
+ <b-row class="margin-bottom--16px">
+ <b-col xl="11" class="text-right">
+ <b-button
+ v-b-modal.generate-csr
+ data-test-id="certificates-button-generateCsr"
+ variant="link"
+ >
+ <icon-add />
+ {{ $t('pageCertificates.generateCsr') }}
+ </b-button>
+ <b-button
+ variant="primary"
+ :disabled="certificatesForUpload.length === 0"
+ @click="initModalUploadCertificate(null)"
+ >
+ <icon-add />
+ {{ $t('pageCertificates.addNewCertificate') }}
+ </b-button>
+ </b-col>
+ </b-row>
+ <b-row>
+ <b-col xl="11">
+ <b-table
+ responsive="md"
+ show-empty
+ hover
+ class="table-rounded"
+ no-border-collapse
+ :busy="isBusy"
+ :fields="fields"
+ :items="tableItems"
+ :empty-text="$t('global.table.emptyMessage')"
+ >
+ <template #cell(validFrom)="{ value }">
+ {{ value | formatDate }}
+ </template>
- <template #cell(validUntil)="{ value }">
- <status-icon
- v-if="getDaysUntilExpired(value) < 31"
- :status="getIconStatus(value)"
- />
- {{ value | formatDate }}
- </template>
-
- <template #cell(actions)="{ value, item }">
- <table-row-action
- v-for="(action, index) in value"
- :key="index"
- :value="action.value"
- :title="action.title"
- :enabled="action.enabled"
- @click-table-action="onTableRowAction($event, item)"
- >
- <template #icon>
- <icon-replace v-if="action.value === 'replace'" />
- <icon-trashcan v-if="action.value === 'delete'" />
- </template>
- </table-row-action>
- </template>
- </b-table>
- </b-col>
- </b-row>
+ <template #cell(validUntil)="{ value }">
+ <status-icon
+ v-if="getDaysUntilExpired(value) < 31"
+ :status="getIconStatus(value)"
+ />
+ {{ value | formatDate }}
+ </template>
+ <template #cell(actions)="{ value, item }">
+ <table-row-action
+ v-for="(action, index) in value"
+ :key="index"
+ :value="action.value"
+ :title="action.title"
+ :enabled="action.enabled"
+ @click-table-action="onTableRowAction($event, item)"
+ >
+ <template #icon>
+ <icon-replace v-if="action.value === 'replace'" />
+ <icon-trashcan v-if="action.value === 'delete'" />
+ </template>
+ </table-row-action>
+ </template>
+ </b-table>
+ </b-col>
+ </b-row>
+ </page-section>
<!-- Modals -->
<modal-upload-certificate :certificate="modalCertificate" @ok="onModalOk" />
<modal-generate-csr />
@@ -107,6 +110,7 @@ import IconTrashcan from '@carbon/icons-vue/es/trash-can/20';
import ModalGenerateCsr from './ModalGenerateCsr';
import ModalUploadCertificate from './ModalUploadCertificate';
import PageTitle from '@/components/_sila/Global/PageTitle';
+import PageSection from '@/components/_sila/Global/PageSection';
import TableRowAction from '@/components/_sila/Global/TableRowAction';
import StatusIcon from '@/components/_sila/Global/StatusIcon';
import Alert from '@/components/_sila/Global/Alert';
@@ -124,6 +128,7 @@ export default {
ModalGenerateCsr,
ModalUploadCertificate,
PageTitle,
+ PageSection,
StatusIcon,
TableRowAction,
},
@@ -320,3 +325,8 @@ export default {
},
};
</script>
+<style lang="scss" scoped>
+.margin-bottom--16px {
+ margin-bottom: 16px;
+}
+</style>
diff --git a/src/views/_sila/SecurityAndAccess/Certificates/ModalGenerateCsr.vue b/src/views/_sila/SecurityAndAccess/Certificates/ModalGenerateCsr.vue
index 5bfb81b4..63258a40 100644
--- a/src/views/_sila/SecurityAndAccess/Certificates/ModalGenerateCsr.vue
+++ b/src/views/_sila/SecurityAndAccess/Certificates/ModalGenerateCsr.vue
@@ -3,7 +3,6 @@
<b-modal
id="generate-csr"
ref="modal"
- size="lg"
no-stacking
:title="$t('pageCertificates.modal.generateACertificateSigningRequest')"
@ok="onOkGenerateCsrModal"
@@ -13,7 +12,88 @@
<b-form id="generate-csr-form" novalidate @submit.prevent="handleSubmit">
<b-container fluid>
<b-row>
- <b-col lg="9">
+ <b-col lg="12">
+ <b-row>
+ <b-col lg="12">
+ <p class="col-form-label">
+ {{ $t('pageCertificates.modal.privateKey') }}
+ </p>
+ <b-form-group
+ :label="$t('pageCertificates.modal.keyPairAlgorithm')"
+ label-for="key-pair-algorithm"
+ >
+ <b-form-select
+ id="key-pair-algorithm"
+ v-model="form.keyPairAlgorithm"
+ data-test-id="modalGenerateCsr-select-keyPairAlgorithm"
+ :options="keyPairAlgorithmOptions"
+ :state="getValidationState($v.form.keyPairAlgorithm)"
+ @input="$v.form.keyPairAlgorithm.$touch()"
+ >
+ <template #first>
+ <b-form-select-option :value="null" disabled>
+ {{ $t('global.form.selectAnOption') }}
+ </b-form-select-option>
+ </template>
+ </b-form-select>
+ <b-form-invalid-feedback role="alert">
+ {{ $t('global.form.fieldRequired') }}
+ </b-form-invalid-feedback>
+ </b-form-group>
+ </b-col>
+ </b-row>
+ <b-row>
+ <b-col lg="12">
+ <template v-if="$v.form.keyPairAlgorithm.$model === 'EC'">
+ <b-form-group
+ :label="$t('pageCertificates.modal.keyCurveId')"
+ label-for="key-curve-id"
+ >
+ <b-form-select
+ id="key-curve-id"
+ v-model="form.keyCurveId"
+ data-test-id="modalGenerateCsr-select-keyCurveId"
+ :options="keyCurveIdOptions"
+ :state="getValidationState($v.form.keyCurveId)"
+ @input="$v.form.keyCurveId.$touch()"
+ >
+ <template #first>
+ <b-form-select-option :value="null" disabled>
+ {{ $t('global.form.selectAnOption') }}
+ </b-form-select-option>
+ </template>
+ </b-form-select>
+ <b-form-invalid-feedback role="alert">
+ {{ $t('global.form.fieldRequired') }}
+ </b-form-invalid-feedback>
+ </b-form-group>
+ </template>
+ <template v-if="$v.form.keyPairAlgorithm.$model === 'RSA'">
+ <b-form-group
+ :label="$t('pageCertificates.modal.keyBitLength')"
+ label-for="key-bit-length"
+ >
+ <b-form-select
+ id="key-bit-length"
+ v-model="form.keyBitLength"
+ data-test-id="modalGenerateCsr-select-keyBitLength"
+ :options="keyBitLengthOptions"
+ :state="getValidationState($v.form.keyBitLength)"
+ @input="$v.form.keyBitLength.$touch()"
+ >
+ <template #first>
+ <b-form-select-option :value="null" disabled>
+ {{ $t('global.form.selectAnOption') }}
+ </b-form-select-option>
+ </template>
+ </b-form-select>
+ <b-form-invalid-feedback role="alert">
+ {{ $t('global.form.fieldRequired') }}
+ </b-form-invalid-feedback>
+ </b-form-group>
+ </template>
+ </b-col>
+ </b-row>
<b-row>
<b-col lg="6">
<b-form-group
@@ -241,89 +321,6 @@
</b-col>
</b-row>
</b-col>
- <b-col lg="3">
- <b-row>
- <b-col lg="12">
- <p class="col-form-label">
- {{ $t('pageCertificates.modal.privateKey') }}
- </p>
- <b-form-group
- :label="$t('pageCertificates.modal.keyPairAlgorithm')"
- label-for="key-pair-algorithm"
- >
- <b-form-select
- id="key-pair-algorithm"
- v-model="form.keyPairAlgorithm"
- data-test-id="modalGenerateCsr-select-keyPairAlgorithm"
- :options="keyPairAlgorithmOptions"
- :state="getValidationState($v.form.keyPairAlgorithm)"
- @input="$v.form.keyPairAlgorithm.$touch()"
- >
- <template #first>
- <b-form-select-option :value="null" disabled>
- {{ $t('global.form.selectAnOption') }}
- </b-form-select-option>
- </template>
- </b-form-select>
- <b-form-invalid-feedback role="alert">
- {{ $t('global.form.fieldRequired') }}
- </b-form-invalid-feedback>
- </b-form-group>
- </b-col>
- </b-row>
- <b-row>
- <b-col lg="12">
- <template v-if="$v.form.keyPairAlgorithm.$model === 'EC'">
- <b-form-group
- :label="$t('pageCertificates.modal.keyCurveId')"
- label-for="key-curve-id"
- >
- <b-form-select
- id="key-curve-id"
- v-model="form.keyCurveId"
- data-test-id="modalGenerateCsr-select-keyCurveId"
- :options="keyCurveIdOptions"
- :state="getValidationState($v.form.keyCurveId)"
- @input="$v.form.keyCurveId.$touch()"
- >
- <template #first>
- <b-form-select-option :value="null" disabled>
- {{ $t('global.form.selectAnOption') }}
- </b-form-select-option>
- </template>
- </b-form-select>
- <b-form-invalid-feedback role="alert">
- {{ $t('global.form.fieldRequired') }}
- </b-form-invalid-feedback>
- </b-form-group>
- </template>
- <template v-if="$v.form.keyPairAlgorithm.$model === 'RSA'">
- <b-form-group
- :label="$t('pageCertificates.modal.keyBitLength')"
- label-for="key-bit-length"
- >
- <b-form-select
- id="key-bit-length"
- v-model="form.keyBitLength"
- data-test-id="modalGenerateCsr-select-keyBitLength"
- :options="keyBitLengthOptions"
- :state="getValidationState($v.form.keyBitLength)"
- @input="$v.form.keyBitLength.$touch()"
- >
- <template #first>
- <b-form-select-option :value="null" disabled>
- {{ $t('global.form.selectAnOption') }}
- </b-form-select-option>
- </template>
- </b-form-select>
- <b-form-invalid-feedback role="alert">
- {{ $t('global.form.fieldRequired') }}
- </b-form-invalid-feedback>
- </b-form-group>
- </template>
- </b-col>
- </b-row>
- </b-col>
</b-row>
</b-container>
</b-form>
diff --git a/src/views/_sila/SecurityAndAccess/Policies/Policies.vue b/src/views/_sila/SecurityAndAccess/Policies/Policies.vue
index c594bde5..44493882 100644
--- a/src/views/_sila/SecurityAndAccess/Policies/Policies.vue
+++ b/src/views/_sila/SecurityAndAccess/Policies/Policies.vue
@@ -1,122 +1,125 @@
<template>
- <b-container fluid="xl">
+ <b-container fluid="pt-0 m-0">
<page-title />
- <b-row>
- <b-col md="8">
- <b-row v-if="!modifySSHPolicyDisabled" class="setting-section">
- <b-col class="d-flex align-items-center justify-content-between">
- <dl class="mr-3 w-75">
- <dt>{{ $t('pagePolicies.ssh') }}</dt>
- <dd>
- {{ $t('pagePolicies.sshDescription') }}
- </dd>
- </dl>
- <b-form-checkbox
- id="sshSwitch"
- v-model="sshProtocolState"
- data-test-id="policies-toggle-bmcShell"
- switch
- @change="changeSshProtocolState"
- >
- <span class="sr-only">
- {{ $t('pagePolicies.ssh') }}
- </span>
- <span v-if="sshProtocolState">
- {{ $t('global.status.enabled') }}
- </span>
- <span v-else>{{ $t('global.status.disabled') }}</span>
- </b-form-checkbox>
- </b-col>
- </b-row>
- <b-row class="setting-section">
- <b-col class="d-flex align-items-center justify-content-between">
- <dl class="mt-3 mr-3 w-75">
- <dt>{{ $t('pagePolicies.ipmi') }}</dt>
- <dd>
- {{ $t('pagePolicies.ipmiDescription') }}
- </dd>
- </dl>
- <b-form-checkbox
- id="ipmiSwitch"
- v-model="ipmiProtocolState"
- data-test-id="polices-toggle-networkIpmi"
- switch
- @change="changeIpmiProtocolState"
- >
- <span class="sr-only">
- {{ $t('pagePolicies.ipmi') }}
- </span>
- <span v-if="ipmiProtocolState">
- {{ $t('global.status.enabled') }}
- </span>
- <span v-else>{{ $t('global.status.disabled') }}</span>
- </b-form-checkbox>
- </b-col>
- </b-row>
- <b-row class="setting-section">
- <b-col class="d-flex align-items-center justify-content-between">
- <dl class="mt-3 mr-3 w-75">
- <dt>{{ $t('pagePolicies.vtpm') }}</dt>
- <dd>
- {{ $t('pagePolicies.vtpmDescription') }}
- </dd>
- </dl>
- <b-form-checkbox
- id="vtpmSwitch"
- v-model="vtpmState"
- data-test-id="policies-toggle-vtpm"
- switch
- @change="changeVtpmState"
- >
- <span class="sr-only">
- {{ $t('pagePolicies.vtpm') }}
- </span>
- <span v-if="vtpmState">
- {{ $t('global.status.enabled') }}
- </span>
- <span v-else>{{ $t('global.status.disabled') }}</span>
- </b-form-checkbox>
- </b-col>
- </b-row>
- <b-row class="setting-section">
- <b-col class="d-flex align-items-center justify-content-between">
- <dl class="mt-3 mr-3 w-75">
- <dt>{{ $t('pagePolicies.rtad') }}</dt>
- <dd>
- {{ $t('pagePolicies.rtadDescription') }}
- </dd>
- </dl>
- <b-form-checkbox
- id="rtadSwitch"
- v-model="rtadState"
- data-test-id="policies-toggle-rtad"
- switch
- @change="changeRtadState"
- >
- <span class="sr-only">
- {{ $t('pagePolicies.rtad') }}
- </span>
- <span v-if="rtadState">
- {{ $t('global.status.enabled') }}
- </span>
- <span v-else>{{ $t('global.status.disabled') }}</span>
- </b-form-checkbox>
- </b-col>
- </b-row>
- </b-col>
- </b-row>
+ <page-section class="bootstrap-table__section">
+ <b-row>
+ <b-col md="8">
+ <b-row v-if="!modifySSHPolicyDisabled" class="setting-section">
+ <b-col class="d-flex align-items-center justify-content-between">
+ <dl class="mr-3 w-75">
+ <dt>{{ $t('pagePolicies.ssh') }}</dt>
+ <dd>
+ {{ $t('pagePolicies.sshDescription') }}
+ </dd>
+ </dl>
+ <b-form-checkbox
+ id="sshSwitch"
+ v-model="sshProtocolState"
+ data-test-id="policies-toggle-bmcShell"
+ switch
+ @change="changeSshProtocolState"
+ >
+ <span class="sr-only">
+ {{ $t('pagePolicies.ssh') }}
+ </span>
+ <span v-if="sshProtocolState">
+ {{ $t('global.status.enabled') }}
+ </span>
+ <span v-else>{{ $t('global.status.disabled') }}</span>
+ </b-form-checkbox>
+ </b-col>
+ </b-row>
+ <b-row class="setting-section">
+ <b-col class="d-flex align-items-center justify-content-between">
+ <dl class="mt-3 mr-3 w-75">
+ <dt>{{ $t('pagePolicies.ipmi') }}</dt>
+ <dd>
+ {{ $t('pagePolicies.ipmiDescription') }}
+ </dd>
+ </dl>
+ <b-form-checkbox
+ id="ipmiSwitch"
+ v-model="ipmiProtocolState"
+ data-test-id="polices-toggle-networkIpmi"
+ switch
+ @change="changeIpmiProtocolState"
+ >
+ <span class="sr-only">
+ {{ $t('pagePolicies.ipmi') }}
+ </span>
+ <span v-if="ipmiProtocolState">
+ {{ $t('global.status.enabled') }}
+ </span>
+ <span v-else>{{ $t('global.status.disabled') }}</span>
+ </b-form-checkbox>
+ </b-col>
+ </b-row>
+ <b-row class="setting-section">
+ <b-col class="d-flex align-items-center justify-content-between">
+ <dl class="mt-3 mr-3 w-75">
+ <dt>{{ $t('pagePolicies.vtpm') }}</dt>
+ <dd>
+ {{ $t('pagePolicies.vtpmDescription') }}
+ </dd>
+ </dl>
+ <b-form-checkbox
+ id="vtpmSwitch"
+ v-model="vtpmState"
+ data-test-id="policies-toggle-vtpm"
+ switch
+ @change="changeVtpmState"
+ >
+ <span class="sr-only">
+ {{ $t('pagePolicies.vtpm') }}
+ </span>
+ <span v-if="vtpmState">
+ {{ $t('global.status.enabled') }}
+ </span>
+ <span v-else>{{ $t('global.status.disabled') }}</span>
+ </b-form-checkbox>
+ </b-col>
+ </b-row>
+ <b-row class="setting-section">
+ <b-col class="d-flex align-items-center justify-content-between">
+ <dl class="mt-3 mr-3 w-75">
+ <dt>{{ $t('pagePolicies.rtad') }}</dt>
+ <dd>
+ {{ $t('pagePolicies.rtadDescription') }}
+ </dd>
+ </dl>
+ <b-form-checkbox
+ id="rtadSwitch"
+ v-model="rtadState"
+ data-test-id="policies-toggle-rtad"
+ switch
+ @change="changeRtadState"
+ >
+ <span class="sr-only">
+ {{ $t('pagePolicies.rtad') }}
+ </span>
+ <span v-if="rtadState">
+ {{ $t('global.status.enabled') }}
+ </span>
+ <span v-else>{{ $t('global.status.disabled') }}</span>
+ </b-form-checkbox>
+ </b-col>
+ </b-row>
+ </b-col>
+ </b-row>
+ </page-section>
</b-container>
</template>
<script>
import PageTitle from '@/components/_sila/Global/PageTitle';
+import PageSection from '@/components/_sila/Global/PageSection';
import LoadingBarMixin from '@/components/_sila/Mixins/LoadingBarMixin';
import BVToastMixin from '@/components/_sila/Mixins/BVToastMixin';
export default {
name: 'Policies',
- components: { PageTitle },
+ components: { PageTitle, PageSection },
mixins: [LoadingBarMixin, BVToastMixin],
beforeRouteLeave(to, from, next) {
this.hideLoader();
diff --git a/src/views/_sila/SecurityAndAccess/Sessions/Sessions.vue b/src/views/_sila/SecurityAndAccess/Sessions/Sessions.vue
index d922c241..5178b180 100644
--- a/src/views/_sila/SecurityAndAccess/Sessions/Sessions.vue
+++ b/src/views/_sila/SecurityAndAccess/Sessions/Sessions.vue
@@ -35,6 +35,7 @@
no-select-on-click
hover
show-empty
+ class="table-rounded"
no-border-collapse
sort-by="clientID"
:busy="isBusy"
@@ -289,10 +290,3 @@ export default {
},
};
</script>
-<style lang="scss">
-#table-session-logs {
- td .btn-link {
- width: auto !important;
- }
-}
-</style>
diff --git a/src/views/_sila/SecurityAndAccess/UserManagement/UserManagement.vue b/src/views/_sila/SecurityAndAccess/UserManagement/UserManagement.vue
index 423ce4c1..f5179d46 100644
--- a/src/views/_sila/SecurityAndAccess/UserManagement/UserManagement.vue
+++ b/src/views/_sila/SecurityAndAccess/UserManagement/UserManagement.vue
@@ -1,7 +1,7 @@
<template>
- <b-container fluid="xl">
+ <b-container fluid class="m-0 p-0">
<page-title />
- <b-row>
+ <b-row class="bootstrap-table__section">
<b-col xl="9" class="text-right">
<b-button variant="link" @click="initModalSettings">
<icon-settings />
@@ -17,7 +17,7 @@
</b-button>
</b-col>
</b-row>
- <b-row>
+ <b-row class="bootstrap-table__section">
<b-col xl="9">
<table-toolbar
ref="toolbar"
@@ -31,8 +31,10 @@
responsive="md"
selectable
show-empty
+ class="table-rounded"
no-select-on-click
hover
+ no-border-collapse
:busy="isBusy"
:fields="fields"
:items="tableItems"
@@ -85,7 +87,7 @@
</b-table>
</b-col>
</b-row>
- <b-row>
+ <b-row class="bootstrap-table__section">
<b-col xl="8">
<b-button
v-b-toggle.collapse-role-table
@@ -381,7 +383,6 @@ export default {
},
};
</script>
-
<style lang="scss" scoped>
.btn.collapsed {
svg {
diff --git a/src/views/_sila/Settings/DateTime/DateTime.vue b/src/views/_sila/Settings/DateTime/DateTime.vue
new file mode 100644
index 00000000..63570c39
--- /dev/null
+++ b/src/views/_sila/Settings/DateTime/DateTime.vue
@@ -0,0 +1,435 @@
+<template>
+ <b-container id="date-time" fluid="xxl" class="pt-0 m-0">
+ <page-title />
+ <b-row class="bootstrap-table__section">
+ <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 class="bootstrap-table__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
+ class="bootstrap-table__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"
+ label-class="regular-14px"
+ >
+ <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"
+ label-class="regular-14px"
+ >
+ <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"
+ >
+ {{ $t('SystemDescription.GetNtpFromServer') }}
+ </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"
+ label-class="regular-14px"
+ >
+ <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"
+ label-class="regular-14px"
+ >
+ <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"
+ label-class="regular-14px"
+ >
+ <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;
+
+ const ntpArray = [
+ this.form.ntp.firstAddress,
+ this.form.ntp.secondAddress,
+ this.form.ntp.thirdAddress,
+ ];
+
+ // Filter the ntpArray to remove empty strings,
+ // per Redfish spec there should be no empty strings or null on the ntp array.
+ const ntpArrayFiltered = ntpArray.filter((x) => x);
+
+ dateTimeForm.ntpServersArray = [...ntpArrayFiltered];
+
+ [this.ntpServers[0], this.ntpServers[1], this.ntpServers[2]] = [
+ ...dateTimeForm.ntpServersArray,
+ ];
+
+ this.setNtpValues();
+ }
+
+ 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>
+<style lang="scss" scoped>
+.form-control {
+ height: 40px;
+ max-width: 270px;
+}
+
+.input-group {
+ max-width: 270px;
+}
+</style>
diff --git a/src/views/_sila/Settings/DateTime/index.js b/src/views/_sila/Settings/DateTime/index.js
new file mode 100644
index 00000000..2df21eae
--- /dev/null
+++ b/src/views/_sila/Settings/DateTime/index.js
@@ -0,0 +1,2 @@
+import DateTime from './DateTime.vue';
+export default DateTime;
diff --git a/src/views/_sila/Settings/Network/ModalDns.vue b/src/views/_sila/Settings/Network/ModalDns.vue
new file mode 100644
index 00000000..a1dc9cec
--- /dev/null
+++ b/src/views/_sila/Settings/Network/ModalDns.vue
@@ -0,0 +1,92 @@
+<template>
+ <b-modal
+ id="modal-dns"
+ ref="modal"
+ :title="$t('pageNetwork.table.addDnsAddress')"
+ @hidden="resetForm"
+ >
+ <b-form id="form-dns" style="width: 100%" @submit.prevent="handleSubmit">
+ <b-row>
+ <b-col>
+ <b-form-group
+ :label="$t('pageNetwork.modal.staticDns')"
+ label-for="staticDns"
+ >
+ <b-form-input
+ id="staticDns"
+ v-model="form.staticDns"
+ type="text"
+ :state="getValidationState($v.form.staticDns)"
+ @input="$v.form.staticDns.$touch()"
+ />
+ <b-form-invalid-feedback role="alert">
+ <template v-if="!$v.form.staticDns.required">
+ {{ $t('global.form.fieldRequired') }}
+ </template>
+ <template v-if="!$v.form.staticDns.ipAddress">
+ {{ $t('global.form.invalidFormat') }}
+ </template>
+ </b-form-invalid-feedback>
+ </b-form-group>
+ </b-col>
+ </b-row>
+ </b-form>
+ <template #modal-footer="{ cancel }">
+ <b-button variant="secondary" @click="cancel()">
+ {{ $t('global.action.cancel') }}
+ </b-button>
+ <b-button form="form-dns" type="submit" variant="primary" @click="onOk">
+ {{ $t('global.action.add') }}
+ </b-button>
+ </template>
+ </b-modal>
+</template>
+
+<script>
+import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
+import { ipAddress, required } from 'vuelidate/lib/validators';
+
+export default {
+ mixins: [VuelidateMixin],
+ data() {
+ return {
+ form: {
+ staticDns: null,
+ },
+ };
+ },
+ validations() {
+ return {
+ form: {
+ staticDns: {
+ required,
+ ipAddress,
+ },
+ },
+ };
+ },
+ methods: {
+ handleSubmit() {
+ this.$v.$touch();
+ if (this.$v.$invalid) return;
+ this.$emit('ok', [this.form.staticDns]);
+ this.closeModal();
+ },
+ closeModal() {
+ this.$nextTick(() => {
+ this.$refs.modal.hide();
+ });
+ },
+ resetForm() {
+ this.form.staticDns = null;
+ this.$v.$reset();
+ this.$emit('hidden');
+ },
+ onOk(bvModalEvt) {
+ // prevent modal close
+ bvModalEvt.preventDefault();
+ this.handleSubmit();
+ },
+ },
+};
+</script>
diff --git a/src/views/_sila/Settings/Network/ModalHostname.vue b/src/views/_sila/Settings/Network/ModalHostname.vue
new file mode 100644
index 00000000..f3221ec7
--- /dev/null
+++ b/src/views/_sila/Settings/Network/ModalHostname.vue
@@ -0,0 +1,110 @@
+<template>
+ <b-modal
+ id="modal-hostname"
+ ref="modal"
+ :title="$t('pageNetwork.modal.editHostnameTitle')"
+ @hidden="resetForm"
+ >
+ <b-form id="hostname-settings" @submit.prevent="handleSubmit">
+ <b-row>
+ <b-col sm="6">
+ <b-form-group
+ :label="$t('pageNetwork.hostname')"
+ label-for="hostname"
+ >
+ <b-form-input
+ id="hostname"
+ v-model="form.hostname"
+ type="text"
+ :state="getValidationState($v.form.hostname)"
+ @input="$v.form.hostname.$touch()"
+ />
+ <b-form-invalid-feedback role="alert">
+ <template v-if="!$v.form.hostname.required">
+ {{ $t('global.form.fieldRequired') }}
+ </template>
+ <template v-if="!$v.form.hostname.validateHostname">
+ {{ $t('global.form.lengthMustBeBetween', { min: 1, max: 64 }) }}
+ </template>
+ </b-form-invalid-feedback>
+ </b-form-group>
+ </b-col>
+ </b-row>
+ </b-form>
+ <template #modal-footer="{ cancel }">
+ <b-button variant="secondary" @click="cancel()">
+ {{ $t('global.action.cancel') }}
+ </b-button>
+ <b-button
+ form="hostname-settings"
+ type="submit"
+ variant="primary"
+ @click="onOk"
+ >
+ {{ $t('global.action.add') }}
+ </b-button>
+ </template>
+ </b-modal>
+</template>
+
+<script>
+import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
+import { required, helpers } from 'vuelidate/lib/validators';
+
+const validateHostname = helpers.regex('validateHostname', /^\S{0,64}$/);
+
+export default {
+ mixins: [VuelidateMixin],
+ props: {
+ hostname: {
+ type: String,
+ default: '',
+ },
+ },
+ data() {
+ return {
+ form: {
+ hostname: '',
+ },
+ };
+ },
+ watch: {
+ hostname() {
+ this.form.hostname = this.hostname;
+ },
+ },
+ validations() {
+ return {
+ form: {
+ hostname: {
+ required,
+ validateHostname,
+ },
+ },
+ };
+ },
+ methods: {
+ handleSubmit() {
+ this.$v.$touch();
+ if (this.$v.$invalid) return;
+ this.$emit('ok', { HostName: this.form.hostname });
+ this.closeModal();
+ },
+ closeModal() {
+ this.$nextTick(() => {
+ this.$refs.modal.hide();
+ });
+ },
+ resetForm() {
+ this.form.hostname = this.hostname;
+ this.$v.$reset();
+ this.$emit('hidden');
+ },
+ onOk(bvModalEvt) {
+ // prevent modal close
+ bvModalEvt.preventDefault();
+ this.handleSubmit();
+ },
+ },
+};
+</script>
diff --git a/src/views/_sila/Settings/Network/ModalIpv4.vue b/src/views/_sila/Settings/Network/ModalIpv4.vue
new file mode 100644
index 00000000..dcf4a579
--- /dev/null
+++ b/src/views/_sila/Settings/Network/ModalIpv4.vue
@@ -0,0 +1,165 @@
+<template>
+ <b-modal
+ id="modal-add-ipv4"
+ ref="modal"
+ :title="$t('pageNetwork.table.addIpv4Address')"
+ @hidden="resetForm"
+ >
+ <b-form id="form-ipv4" @submit.prevent="handleSubmit">
+ <b-row>
+ <b-col sm="6">
+ <b-form-group
+ :label="$t('pageNetwork.modal.ipAddress')"
+ label-for="ipAddress"
+ >
+ <b-form-input
+ id="ipAddress"
+ v-model="form.ipAddress"
+ type="text"
+ :state="getValidationState($v.form.ipAddress)"
+ @input="$v.form.ipAddress.$touch()"
+ />
+ <b-form-invalid-feedback role="alert">
+ <template v-if="!$v.form.ipAddress.required">
+ {{ $t('global.form.fieldRequired') }}
+ </template>
+ <template v-if="!$v.form.ipAddress.ipAddress">
+ {{ $t('global.form.invalidFormat') }}
+ </template>
+ </b-form-invalid-feedback>
+ </b-form-group>
+ </b-col>
+ <b-col sm="6">
+ <b-form-group
+ :label="$t('pageNetwork.modal.gateway')"
+ label-for="gateway"
+ >
+ <b-form-input
+ id="gateway"
+ v-model="form.gateway"
+ type="text"
+ :state="getValidationState($v.form.gateway)"
+ @input="$v.form.gateway.$touch()"
+ />
+ <b-form-invalid-feedback role="alert">
+ <template v-if="!$v.form.gateway.required">
+ {{ $t('global.form.fieldRequired') }}
+ </template>
+ <template v-if="!$v.form.gateway.ipAddress">
+ {{ $t('global.form.invalidFormat') }}
+ </template>
+ </b-form-invalid-feedback>
+ </b-form-group>
+ </b-col>
+ </b-row>
+ <b-row>
+ <b-col sm="6">
+ <b-form-group
+ :label="$t('pageNetwork.modal.subnetMask')"
+ label-for="subnetMask"
+ >
+ <b-form-input
+ id="subnetMask"
+ v-model="form.subnetMask"
+ type="text"
+ :state="getValidationState($v.form.subnetMask)"
+ @input="$v.form.subnetMask.$touch()"
+ />
+ <b-form-invalid-feedback role="alert">
+ <template v-if="!$v.form.subnetMask.required">
+ {{ $t('global.form.fieldRequired') }}
+ </template>
+ <template v-if="!$v.form.subnetMask.ipAddress">
+ {{ $t('global.form.invalidFormat') }}
+ </template>
+ </b-form-invalid-feedback>
+ </b-form-group>
+ </b-col>
+ </b-row>
+ </b-form>
+ <template #modal-footer="{ cancel }">
+ <b-button variant="secondary" @click="cancel()">
+ {{ $t('global.action.cancel') }}
+ </b-button>
+ <b-button form="form-ipv4" type="submit" variant="primary" @click="onOk">
+ {{ $t('global.action.add') }}
+ </b-button>
+ </template>
+ </b-modal>
+</template>
+
+<script>
+import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
+import { ipAddress, required } from 'vuelidate/lib/validators';
+
+export default {
+ mixins: [VuelidateMixin],
+ props: {
+ defaultGateway: {
+ type: String,
+ default: '',
+ },
+ },
+ data() {
+ return {
+ form: {
+ ipAddress: '',
+ gateway: '',
+ subnetMask: '',
+ },
+ };
+ },
+ watch: {
+ defaultGateway() {
+ this.form.gateway = this.defaultGateway;
+ },
+ },
+ validations() {
+ return {
+ form: {
+ ipAddress: {
+ required,
+ ipAddress,
+ },
+ gateway: {
+ required,
+ ipAddress,
+ },
+ subnetMask: {
+ required,
+ ipAddress,
+ },
+ },
+ };
+ },
+ methods: {
+ handleSubmit() {
+ this.$v.$touch();
+ if (this.$v.$invalid) return;
+ this.$emit('ok', {
+ Address: this.form.ipAddress,
+ Gateway: this.form.gateway,
+ SubnetMask: this.form.subnetMask,
+ });
+ this.closeModal();
+ },
+ closeModal() {
+ this.$nextTick(() => {
+ this.$refs.modal.hide();
+ });
+ },
+ resetForm() {
+ this.form.ipAddress = null;
+ this.form.gateway = this.defaultGateway;
+ this.form.subnetMask = null;
+ this.$v.$reset();
+ this.$emit('hidden');
+ },
+ onOk(bvModalEvt) {
+ // prevent modal close
+ bvModalEvt.preventDefault();
+ this.handleSubmit();
+ },
+ },
+};
+</script>
diff --git a/src/views/_sila/Settings/Network/ModalMacAddress.vue b/src/views/_sila/Settings/Network/ModalMacAddress.vue
new file mode 100644
index 00000000..d563f4ce
--- /dev/null
+++ b/src/views/_sila/Settings/Network/ModalMacAddress.vue
@@ -0,0 +1,109 @@
+<template>
+ <b-modal
+ id="modal-mac-address"
+ ref="modal"
+ :title="$t('pageNetwork.modal.editMacAddressTitle')"
+ @hidden="resetForm"
+ >
+ <b-form id="mac-settings" @submit.prevent="handleSubmit">
+ <b-row>
+ <b-col sm="6">
+ <b-form-group
+ :label="$t('pageNetwork.macAddress')"
+ label-for="macAddress"
+ >
+ <b-form-input
+ id="mac-address"
+ v-model.trim="form.macAddress"
+ data-test-id="network-input-macAddress"
+ type="text"
+ :state="getValidationState($v.form.macAddress)"
+ @change="$v.form.macAddress.$touch()"
+ />
+ <b-form-invalid-feedback role="alert">
+ <div v-if="!$v.form.macAddress.required">
+ {{ $t('global.form.fieldRequired') }}
+ </div>
+ <div v-if="!$v.form.macAddress.macAddress">
+ {{ $t('global.form.invalidFormat') }}
+ </div>
+ </b-form-invalid-feedback>
+ </b-form-group>
+ </b-col>
+ </b-row>
+ </b-form>
+ <template #modal-footer="{ cancel }">
+ <b-button variant="secondary" @click="cancel()">
+ {{ $t('global.action.cancel') }}
+ </b-button>
+ <b-button
+ form="mac-settings"
+ type="submit"
+ variant="primary"
+ @click="onOk"
+ >
+ {{ $t('global.action.add') }}
+ </b-button>
+ </template>
+ </b-modal>
+</template>
+
+<script>
+import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
+import { macAddress, required } from 'vuelidate/lib/validators';
+
+export default {
+ mixins: [VuelidateMixin],
+ props: {
+ macAddress: {
+ type: String,
+ default: '',
+ },
+ },
+ data() {
+ return {
+ form: {
+ macAddress: '',
+ },
+ };
+ },
+ watch: {
+ macAddress() {
+ this.form.macAddress = this.macAddress;
+ },
+ },
+ validations() {
+ return {
+ form: {
+ macAddress: {
+ required,
+ macAddress: macAddress(),
+ },
+ },
+ };
+ },
+ methods: {
+ handleSubmit() {
+ this.$v.$touch();
+ if (this.$v.$invalid) return;
+ this.$emit('ok', { MACAddress: this.form.macAddress });
+ this.closeModal();
+ },
+ closeModal() {
+ this.$nextTick(() => {
+ this.$refs.modal.hide();
+ });
+ },
+ resetForm() {
+ this.form.macAddress = this.macAddress;
+ this.$v.$reset();
+ this.$emit('hidden');
+ },
+ onOk(bvModalEvt) {
+ // prevent modal close
+ bvModalEvt.preventDefault();
+ this.handleSubmit();
+ },
+ },
+};
+</script>
diff --git a/src/views/_sila/Settings/Network/Network.vue b/src/views/_sila/Settings/Network/Network.vue
new file mode 100644
index 00000000..50442be4
--- /dev/null
+++ b/src/views/_sila/Settings/Network/Network.vue
@@ -0,0 +1,166 @@
+<template>
+ <b-container id="page-network" fluid="m-0 p-0">
+ <page-title :description="$t('pageNetwork.pageDescription')" />
+
+ <page-section v-show="ethernetData" class="m-4">
+ <network-global-settings class="m-4" />
+ <b-row>
+ <b-col>
+ <b-card no-body>
+ <b-tabs
+ active-nav-item-class="font-weight-bold"
+ card
+ content-class="mt-3"
+ >
+ <b-tab
+ v-for="(data, index) in ethernetData"
+ :key="data.Id"
+ :title="data.Id"
+ @click="getTabIndex(index)"
+ >
+ <!-- Interface settings -->
+ <network-interface-settings :tab-index="tabIndex" />
+ <!-- IPV4 table -->
+ <table-ipv-4 :tab-index="tabIndex" />
+ <!-- Static DNS table -->
+ <table-dns :tab-index="tabIndex" />
+ </b-tab>
+ </b-tabs>
+ </b-card>
+ </b-col>
+ </b-row>
+ </page-section>
+ <!-- Modals -->
+ <modal-ipv4 :default-gateway="defaultGateway" @ok="saveIpv4Address" />
+ <modal-dns @ok="saveDnsAddress" />
+ <modal-hostname :hostname="currentHostname" @ok="saveSettings" />
+ <modal-mac-address :mac-address="currentMacAddress" @ok="saveSettings" />
+ </b-container>
+</template>
+
+<script>
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
+import LoadingBarMixin, { loading } from '@/components/Mixins/LoadingBarMixin';
+import ModalMacAddress from './ModalMacAddress.vue';
+import ModalHostname from './ModalHostname.vue';
+import ModalIpv4 from './ModalIpv4.vue';
+import ModalDns from './ModalDns.vue';
+import NetworkGlobalSettings from './NetworkGlobalSettings.vue';
+import NetworkInterfaceSettings from './NetworkInterfaceSettings.vue';
+import PageSection from '@/components/Global/PageSection';
+import PageTitle from '@/components/Global/PageTitle';
+import TableIpv4 from './TableIpv4.vue';
+import TableDns from './TableDns.vue';
+import { mapState } from 'vuex';
+
+export default {
+ name: 'Network',
+ components: {
+ ModalHostname,
+ ModalMacAddress,
+ ModalIpv4,
+ ModalDns,
+ NetworkGlobalSettings,
+ NetworkInterfaceSettings,
+ PageSection,
+ PageTitle,
+ TableDns,
+ TableIpv4,
+ },
+ mixins: [BVToastMixin, DataFormatterMixin, LoadingBarMixin],
+ beforeRouteLeave(to, from, next) {
+ this.hideLoader();
+ next();
+ },
+ data() {
+ return {
+ currentHostname: '',
+ currentMacAddress: '',
+ defaultGateway: '',
+ loading,
+ tabIndex: 0,
+ };
+ },
+ computed: {
+ ...mapState('network', ['ethernetData']),
+ },
+ watch: {
+ ethernetData() {
+ this.getModalInfo();
+ },
+ },
+ created() {
+ this.startLoader();
+ const globalSettings = new Promise((resolve) => {
+ this.$root.$on('network-global-settings-complete', () => resolve());
+ });
+ const interfaceSettings = new Promise((resolve) => {
+ this.$root.$on('network-interface-settings-complete', () => resolve());
+ });
+ const networkTableDns = new Promise((resolve) => {
+ this.$root.$on('network-table-dns-complete', () => resolve());
+ });
+ const networkTableIpv4 = new Promise((resolve) => {
+ this.$root.$on('network-table-ipv4-complete', () => resolve());
+ });
+ // Combine all child component Promises to indicate
+ // when page data load complete
+ Promise.all([
+ this.$store.dispatch('network/getEthernetData'),
+ globalSettings,
+ interfaceSettings,
+ networkTableDns,
+ networkTableIpv4,
+ ]).finally(() => this.endLoader());
+ },
+ methods: {
+ getModalInfo() {
+ this.defaultGateway = this.$store.getters[
+ 'network/globalNetworkSettings'
+ ][this.tabIndex].defaultGateway;
+
+ this.currentHostname = this.$store.getters[
+ 'network/globalNetworkSettings'
+ ][this.tabIndex].hostname;
+
+ this.currentMacAddress = this.$store.getters[
+ 'network/globalNetworkSettings'
+ ][this.tabIndex].macAddress;
+ },
+ getTabIndex(selectedIndex) {
+ this.tabIndex = selectedIndex;
+ this.$store.dispatch('network/setSelectedTabIndex', this.tabIndex);
+ this.$store.dispatch(
+ 'network/setSelectedTabId',
+ this.ethernetData[selectedIndex].Id
+ );
+ this.getModalInfo();
+ },
+ saveIpv4Address(modalFormData) {
+ this.startLoader();
+ this.$store
+ .dispatch('network/saveIpv4Address', modalFormData)
+ .then((message) => this.successToast(message))
+ .catch(({ message }) => this.errorToast(message))
+ .finally(() => this.endLoader());
+ },
+ saveDnsAddress(modalFormData) {
+ this.startLoader();
+ this.$store
+ .dispatch('network/saveDnsAddress', modalFormData)
+ .then((message) => this.successToast(message))
+ .catch(({ message }) => this.errorToast(message))
+ .finally(() => this.endLoader());
+ },
+ saveSettings(modalFormData) {
+ this.startLoader();
+ this.$store
+ .dispatch('network/saveSettings', modalFormData)
+ .then((message) => this.successToast(message))
+ .catch(({ message }) => this.errorToast(message))
+ .finally(() => this.endLoader());
+ },
+ },
+};
+</script>
diff --git a/src/views/_sila/Settings/Network/NetworkGlobalSettings.vue b/src/views/_sila/Settings/Network/NetworkGlobalSettings.vue
new file mode 100644
index 00000000..30287673
--- /dev/null
+++ b/src/views/_sila/Settings/Network/NetworkGlobalSettings.vue
@@ -0,0 +1,161 @@
+<template>
+ <page-section
+ v-if="firstInterface"
+ :section-title="$t('pageNetwork.networkSettings')"
+ >
+ <b-row>
+ <b-col md="3">
+ <dl>
+ <dt>
+ {{ $t('pageNetwork.hostname') }}
+ <b-button variant="link" class="p-1" @click="initSettingsModal()">
+ <icon-edit :title="$t('pageNetwork.modal.editHostnameTitle')" />
+ </b-button>
+ </dt>
+ <dd>{{ dataFormatter(firstInterface.hostname) }}</dd>
+ </dl>
+ </b-col>
+ <b-col md="3">
+ <dl>
+ <dt>{{ $t('pageNetwork.useDomainName') }}</dt>
+ <dd>
+ <b-form-checkbox
+ id="useDomainNameSwitch"
+ v-model="useDomainNameState"
+ data-test-id="networkSettings-switch-useDomainName"
+ switch
+ @change="changeDomainNameState"
+ >
+ <span v-if="useDomainNameState">
+ {{ $t('global.status.enabled') }}
+ </span>
+ <span v-else>{{ $t('global.status.disabled') }}</span>
+ </b-form-checkbox>
+ </dd>
+ </dl>
+ </b-col>
+ <b-col md="3">
+ <dl>
+ <dt>{{ $t('pageNetwork.useDns') }}</dt>
+ <dd>
+ <b-form-checkbox
+ id="useDnsSwitch"
+ v-model="useDnsState"
+ data-test-id="networkSettings-switch-useDns"
+ switch
+ @change="changeDnsState"
+ >
+ <span v-if="useDnsState">
+ {{ $t('global.status.enabled') }}
+ </span>
+ <span v-else>{{ $t('global.status.disabled') }}</span>
+ </b-form-checkbox>
+ </dd>
+ </dl>
+ </b-col>
+ <b-col md="3">
+ <dl>
+ <dt>{{ $t('pageNetwork.useNtp') }}</dt>
+ <dd>
+ <b-form-checkbox
+ id="useNtpSwitch"
+ v-model="useNtpState"
+ data-test-id="networkSettings-switch-useNtp"
+ switch
+ @change="changeNtpState"
+ >
+ <span v-if="useNtpState">
+ {{ $t('global.status.enabled') }}
+ </span>
+ <span v-else>{{ $t('global.status.disabled') }}</span>
+ </b-form-checkbox>
+ </dd>
+ </dl>
+ </b-col>
+ </b-row>
+ </page-section>
+</template>
+
+<script>
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import IconEdit from '@carbon/icons-vue/es/edit/16';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
+import PageSection from '@/components/Global/PageSection';
+import { mapState } from 'vuex';
+
+export default {
+ name: 'GlobalNetworkSettings',
+ components: { IconEdit, PageSection },
+ mixins: [BVToastMixin, DataFormatterMixin],
+
+ data() {
+ return {
+ hostname: '',
+ };
+ },
+ computed: {
+ ...mapState('network', ['ethernetData']),
+ firstInterface() {
+ return this.$store.getters['network/globalNetworkSettings'][0];
+ },
+ useDomainNameState: {
+ get() {
+ return this.$store.getters['network/globalNetworkSettings'][0]
+ .useDomainNameEnabled;
+ },
+ set(newValue) {
+ return newValue;
+ },
+ },
+ useDnsState: {
+ get() {
+ return this.$store.getters['network/globalNetworkSettings'][0]
+ .useDnsEnabled;
+ },
+ set(newValue) {
+ return newValue;
+ },
+ },
+ useNtpState: {
+ get() {
+ return this.$store.getters['network/globalNetworkSettings'][0]
+ .useNtpEnabled;
+ },
+ set(newValue) {
+ return newValue;
+ },
+ },
+ },
+ created() {
+ this.$store.dispatch('network/getEthernetData').finally(() => {
+ // Emit initial data fetch complete to parent component
+ this.$root.$emit('network-global-settings-complete');
+ });
+ },
+ methods: {
+ changeDomainNameState(state) {
+ this.$store
+ .dispatch('network/saveDomainNameState', state)
+ .then((success) => {
+ this.successToast(success);
+ })
+ .catch(({ message }) => this.errorToast(message));
+ },
+ changeDnsState(state) {
+ this.$store
+ .dispatch('network/saveDnsState', state)
+ .then((message) => this.successToast(message))
+ .catch(({ message }) => this.errorToast(message));
+ },
+ changeNtpState(state) {
+ this.$store
+ .dispatch('network/saveNtpState', state)
+ .then((message) => this.successToast(message))
+ .catch(({ message }) => this.errorToast(message));
+ },
+ initSettingsModal() {
+ this.$bvModal.show('modal-hostname');
+ },
+ },
+};
+</script>
diff --git a/src/views/_sila/Settings/Network/NetworkInterfaceSettings.vue b/src/views/_sila/Settings/Network/NetworkInterfaceSettings.vue
new file mode 100644
index 00000000..023d29bc
--- /dev/null
+++ b/src/views/_sila/Settings/Network/NetworkInterfaceSettings.vue
@@ -0,0 +1,117 @@
+<template>
+ <div>
+ <page-section>
+ <b-row>
+ <b-col md="3">
+ <dl>
+ <dt>{{ $t('pageNetwork.linkStatus') }}</dt>
+ <dd>
+ {{ dataFormatter(linkStatus) }}
+ </dd>
+ </dl>
+ </b-col>
+ <b-col md="3">
+ <dl>
+ <dt>{{ $t('pageNetwork.speed') }}</dt>
+ <dd>
+ {{ dataFormatter(linkSpeed) }}
+ </dd>
+ </dl>
+ </b-col>
+ </b-row>
+ </page-section>
+ <page-section :section-title="$t('pageNetwork.interfaceSection')">
+ <b-row>
+ <b-col md="3">
+ <dl>
+ <dt>
+ {{ $t('pageNetwork.fqdn') }}
+ </dt>
+ <dd>
+ {{ dataFormatter(fqdn) }}
+ </dd>
+ </dl>
+ </b-col>
+ <b-col md="3">
+ <dl class="text-nowrap">
+ <dt>
+ {{ $t('pageNetwork.macAddress') }}
+ <b-button
+ variant="link"
+ class="p-1"
+ @click="initMacAddressModal()"
+ >
+ <icon-edit
+ :title="$t('pageNetwork.modal.editMacAddressTitle')"
+ />
+ </b-button>
+ </dt>
+ <dd>
+ {{ dataFormatter(macAddress) }}
+ </dd>
+ </dl>
+ </b-col>
+ </b-row>
+ </page-section>
+ </div>
+</template>
+
+<script>
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import IconEdit from '@carbon/icons-vue/es/edit/16';
+import PageSection from '@/components/Global/PageSection';
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
+import { mapState } from 'vuex';
+
+export default {
+ name: 'Ipv4Table',
+ components: {
+ IconEdit,
+ PageSection,
+ },
+ mixins: [BVToastMixin, DataFormatterMixin],
+ props: {
+ tabIndex: {
+ type: Number,
+ default: 0,
+ },
+ },
+ data() {
+ return {
+ selectedInterface: '',
+ linkStatus: '',
+ linkSpeed: '',
+ fqdn: '',
+ macAddress: '',
+ };
+ },
+ computed: {
+ ...mapState('network', ['ethernetData']),
+ },
+ watch: {
+ // Watch for change in tab index
+ tabIndex() {
+ this.getSettings();
+ },
+ },
+ created() {
+ this.getSettings();
+ this.$store.dispatch('network/getEthernetData').finally(() => {
+ // Emit initial data fetch complete to parent component
+ this.$root.$emit('network-interface-settings-complete');
+ });
+ },
+ methods: {
+ getSettings() {
+ this.selectedInterface = this.tabIndex;
+ this.linkStatus = this.ethernetData[this.selectedInterface].LinkStatus;
+ this.linkSpeed = this.ethernetData[this.selectedInterface].SpeedMbps;
+ this.fqdn = this.ethernetData[this.selectedInterface].FQDN;
+ this.macAddress = this.ethernetData[this.selectedInterface].MACAddress;
+ },
+ initMacAddressModal() {
+ this.$bvModal.show('modal-mac-address');
+ },
+ },
+};
+</script>
diff --git a/src/views/_sila/Settings/Network/TableDns.vue b/src/views/_sila/Settings/Network/TableDns.vue
new file mode 100644
index 00000000..c37c6e9f
--- /dev/null
+++ b/src/views/_sila/Settings/Network/TableDns.vue
@@ -0,0 +1,156 @@
+<template>
+ <page-section :section-title="$t('pageNetwork.staticDns')">
+ <b-row>
+ <b-col lg="6">
+ <div class="text-right">
+ <b-button variant="primary" class="mb-2" @click="initDnsModal()">
+ <icon-add />
+ {{ $t('pageNetwork.table.addDnsAddress') }}
+ </b-button>
+ </div>
+ <b-table
+ responsive="md"
+ hover
+ no-border-collapse
+ :fields="dnsTableFields"
+ :items="form.dnsStaticTableItems"
+ :empty-text="$t('global.table.emptyMessage')"
+ class="mb-0"
+ show-empty
+ >
+ <template #cell(actions)="{ item, index }">
+ <table-row-action
+ v-for="(action, actionIndex) in item.actions"
+ :key="actionIndex"
+ :value="action.value"
+ :title="action.title"
+ :enabled="action.enabled"
+ @click-table-action="onDnsTableAction(action, $event, index)"
+ >
+ <template #icon>
+ <icon-edit v-if="action.value === 'edit'" />
+ <icon-trashcan v-if="action.value === 'delete'" />
+ </template>
+ </table-row-action>
+ </template>
+ </b-table>
+ </b-col>
+ </b-row>
+ </page-section>
+</template>
+
+<script>
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import IconAdd from '@carbon/icons-vue/es/add--alt/20';
+import IconEdit from '@carbon/icons-vue/es/edit/20';
+import IconTrashcan from '@carbon/icons-vue/es/trash-can/20';
+import PageSection from '@/components/Global/PageSection';
+import TableRowAction from '@/components/Global/TableRowAction';
+import { mapState } from 'vuex';
+
+export default {
+ name: 'DNSTable',
+ components: {
+ IconAdd,
+ IconEdit,
+ IconTrashcan,
+ PageSection,
+ TableRowAction,
+ },
+ mixins: [BVToastMixin],
+ props: {
+ tabIndex: {
+ type: Number,
+ default: 0,
+ },
+ },
+ data() {
+ return {
+ form: {
+ dnsStaticTableItems: [],
+ },
+ actions: [
+ {
+ value: 'edit',
+ title: this.$t('global.action.edit'),
+ },
+ {
+ value: 'delete',
+ title: this.$t('global.action.delete'),
+ },
+ ],
+ dnsTableFields: [
+ {
+ key: 'address',
+ label: this.$t('pageNetwork.table.ipAddress'),
+ },
+ {
+ key: 'actions',
+ thStyle: { width: '30%' },
+ label: this.$t('pageNetwork.table.actions'),
+ thClass: 'text-right',
+ tdClass: 'text-right',
+ },
+ ],
+ };
+ },
+ computed: {
+ ...mapState('network', ['ethernetData']),
+ },
+ watch: {
+ // Watch for change in tab index
+ tabIndex() {
+ this.getStaticDnsItems();
+ },
+ ethernetData() {
+ this.getStaticDnsItems();
+ },
+ },
+ created() {
+ this.getStaticDnsItems();
+ this.$store.dispatch('network/getEthernetData').finally(() => {
+ // Emit initial data fetch complete to parent component
+ this.$root.$emit('network-table-dns-complete');
+ });
+ },
+ methods: {
+ getStaticDnsItems() {
+ const index = this.tabIndex;
+ const dns = this.ethernetData[index].StaticNameServers || [];
+ this.form.dnsStaticTableItems = dns.map((server) => {
+ return {
+ address: server,
+ actions: [
+ {
+ value: 'edit',
+ title: this.$t('global.action.edit'),
+ },
+ {
+ value: 'delete',
+ title: this.$t('pageNetwork.table.deleteDns'),
+ },
+ ],
+ };
+ });
+ },
+ onDnsTableAction(action, $event, index) {
+ if ($event === 'delete') {
+ this.deleteDnsTableRow(index);
+ }
+ },
+ deleteDnsTableRow(index) {
+ this.form.dnsStaticTableItems.splice(index, 1);
+ const newDnsArray = this.form.dnsStaticTableItems.map((dns) => {
+ return dns.address;
+ });
+ this.$store
+ .dispatch('network/editDnsAddress', newDnsArray)
+ .then((message) => this.successToast(message))
+ .catch(({ message }) => this.errorToast(message));
+ },
+ initDnsModal() {
+ this.$bvModal.show('modal-dns');
+ },
+ },
+};
+</script>
diff --git a/src/views/_sila/Settings/Network/TableIpv4.vue b/src/views/_sila/Settings/Network/TableIpv4.vue
new file mode 100644
index 00000000..6514a59c
--- /dev/null
+++ b/src/views/_sila/Settings/Network/TableIpv4.vue
@@ -0,0 +1,183 @@
+<template>
+ <page-section :section-title="$t('pageNetwork.ipv4')">
+ <b-row>
+ <b-col>
+ <h3 class="h5">
+ {{ $t('pageNetwork.ipv4Addresses') }}
+ </h3>
+ </b-col>
+ <b-col class="text-right">
+ <b-button variant="primary" class="mb-2" @click="initAddIpv4Address()">
+ <icon-add />
+ {{ $t('pageNetwork.table.addIpv4Address') }}
+ </b-button>
+ </b-col>
+ </b-row>
+ <b-table
+ responsive="md"
+ hover
+ class="mb-0"
+ show-empty
+ no-border-collapse
+ :fields="ipv4TableFields"
+ :items="form.ipv4TableItems"
+ :empty-text="$t('global.table.emptyMessage')"
+ >
+ <template #cell(actions)="{ item, index }">
+ <table-row-action
+ v-for="(action, actionIndex) in item.actions"
+ :key="actionIndex"
+ :value="action.value"
+ :title="action.title"
+ :enabled="action.enabled"
+ @click-table-action="onIpv4TableAction(action, $event, index)"
+ >
+ <template #icon>
+ <icon-edit v-if="action.value === 'edit'" />
+ <icon-trashcan v-if="action.value === 'delete'" />
+ </template>
+ </table-row-action>
+ </template>
+ </b-table>
+ </page-section>
+</template>
+
+<script>
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import IconAdd from '@carbon/icons-vue/es/add--alt/20';
+import IconEdit from '@carbon/icons-vue/es/edit/20';
+import IconTrashcan from '@carbon/icons-vue/es/trash-can/20';
+import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
+import PageSection from '@/components/Global/PageSection';
+import TableRowAction from '@/components/Global/TableRowAction';
+import { mapState } from 'vuex';
+
+export default {
+ name: 'Ipv4Table',
+ components: {
+ IconAdd,
+ IconEdit,
+ IconTrashcan,
+ PageSection,
+ TableRowAction,
+ },
+ mixins: [BVToastMixin, LoadingBarMixin],
+ props: {
+ tabIndex: {
+ type: Number,
+ default: 0,
+ },
+ },
+ data() {
+ return {
+ form: {
+ ipv4TableItems: [],
+ },
+ actions: [
+ {
+ value: 'edit',
+ title: this.$t('global.action.edit'),
+ },
+ {
+ value: 'delete',
+ title: this.$t('global.action.delete'),
+ },
+ ],
+ ipv4TableFields: [
+ {
+ key: 'Address',
+ label: this.$t('pageNetwork.table.ipAddress'),
+ thStyle: { width: '20%' },
+ },
+ {
+ key: 'Gateway',
+ label: this.$t('pageNetwork.table.gateway'),
+ thStyle: { width: '20%' },
+ },
+ {
+ key: 'SubnetMask',
+ label: this.$t('pageNetwork.table.subnet'),
+ },
+ {
+ key: 'AddressOrigin',
+ label: this.$t('pageNetwork.table.addressOrigin'),
+ thStyle: { width: '20%' },
+ },
+ {
+ key: 'actions',
+ label: this.$t('pageNetwork.table.actions'),
+ thStyle: { width: '10%' },
+ thClass: 'text-right',
+ tdClass: 'text-right',
+ },
+ ],
+ };
+ },
+ computed: {
+ ...mapState('network', ['ethernetData']),
+ },
+ watch: {
+ // Watch for change in tab index
+ tabIndex() {
+ this.getIpv4TableItems();
+ },
+ ethernetData() {
+ this.getIpv4TableItems();
+ },
+ },
+ created() {
+ this.getIpv4TableItems();
+ this.$store.dispatch('network/getEthernetData').finally(() => {
+ // Emit initial data fetch complete to parent component
+ this.$root.$emit('network-table-ipv4-complete');
+ });
+ },
+ methods: {
+ getIpv4TableItems() {
+ const index = this.tabIndex;
+ const addresses = this.ethernetData[index].IPv4Addresses || [];
+ this.form.ipv4TableItems = addresses.map((ipv4) => {
+ return {
+ Address: ipv4.Address,
+ SubnetMask: ipv4.SubnetMask,
+ Gateway: ipv4.Gateway,
+ AddressOrigin: ipv4.AddressOrigin,
+ actions: [
+ {
+ value: 'edit',
+ title: this.$t('pageNetwork.table.edit'),
+ },
+ {
+ value: 'delete',
+ title: this.$t('pageNetwork.table.deleteIpv4'),
+ },
+ ],
+ };
+ });
+ },
+ onIpv4TableAction(action, $event, index) {
+ if ($event === 'delete') {
+ this.deleteIpv4TableRow(index);
+ }
+ },
+ deleteIpv4TableRow(index) {
+ this.form.ipv4TableItems.splice(index, 1);
+ const newIpv4Array = this.form.ipv4TableItems.map((ipv4) => {
+ const { Address, SubnetMask, Gateway } = ipv4;
+ return {
+ Address,
+ SubnetMask,
+ Gateway,
+ };
+ });
+ this.$store
+ .dispatch('network/editIpv4Address', newIpv4Array)
+ .then((message) => this.successToast(message))
+ .catch(({ message }) => this.errorToast(message));
+ },
+ initAddIpv4Address() {
+ this.$bvModal.show('modal-add-ipv4');
+ },
+ },
+};
+</script>
diff --git a/src/views/_sila/Settings/Network/index.js b/src/views/_sila/Settings/Network/index.js
new file mode 100644
index 00000000..97bf0397
--- /dev/null
+++ b/src/views/_sila/Settings/Network/index.js
@@ -0,0 +1,2 @@
+import Network from './Network.vue';
+export default Network;
diff --git a/src/views/_sila/Settings/PowerRestorePolicy/PowerRestorePolicy.vue b/src/views/_sila/Settings/PowerRestorePolicy/PowerRestorePolicy.vue
index c357d47a..06e30f3e 100644
--- a/src/views/_sila/Settings/PowerRestorePolicy/PowerRestorePolicy.vue
+++ b/src/views/_sila/Settings/PowerRestorePolicy/PowerRestorePolicy.vue
@@ -21,10 +21,10 @@
</template>
<script>
-import PageTitle from '@/components/_sila/Global/PageTitle';
-import LoadingBarMixin from '@/components/_sila/Mixins/LoadingBarMixin';
-import VuelidateMixin from '@/components/_sila/Mixins/VuelidateMixin.js';
-import BVToastMixin from '@/components/_sila/Mixins/BVToastMixin';
+import PageTitle from '@/components/Global/PageTitle';
+import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
+import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
export default {
name: 'PowerRestorePolicy',
diff --git a/src/views/_sila/Support/Support.vue b/src/views/_sila/Support/Support.vue
new file mode 100644
index 00000000..a23ad55f
--- /dev/null
+++ b/src/views/_sila/Support/Support.vue
@@ -0,0 +1,9 @@
+<template>
+ <span>This Page (Support) In develop</span>
+</template>
+
+<script>
+export default {
+ name: 'Support',
+};
+</script>
diff --git a/src/views/_sila/Support/index.js b/src/views/_sila/Support/index.js
new file mode 100644
index 00000000..80b31621
--- /dev/null
+++ b/src/views/_sila/Support/index.js
@@ -0,0 +1 @@
+export { default } from './Support.vue';
diff --git a/src/views/_sila/SystemDescription/Info/InventoryTableSystem.vue b/src/views/_sila/SystemDescription/Info/InventoryTableSystem.vue
new file mode 100644
index 00000000..0c32d2c0
--- /dev/null
+++ b/src/views/_sila/SystemDescription/Info/InventoryTableSystem.vue
@@ -0,0 +1,81 @@
+<template>
+ <page-section class="bootstrap-table__section">
+ <b-table
+ responsive="md"
+ show-empty
+ class="table-rounded"
+ no-border-collapse
+ :items="items"
+ :fields="fields"
+ :empty-text="$t('global.table.emptyMessage')"
+ >
+ </b-table>
+ </page-section>
+</template>
+
+<script>
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import PageSection from '@/components/Global/PageSection';
+import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
+import TableRowExpandMixin, {
+ expandRowLabel,
+} from '@/components/Mixins/TableRowExpandMixin';
+
+export default {
+ components: { PageSection },
+ mixins: [BVToastMixin, TableRowExpandMixin, LoadingBarMixin],
+ data() {
+ return {
+ fields: [
+ {
+ key: 'param',
+ label: 'Параметр',
+ formatter: this.dataFormatter,
+ thStyle: { width: '50%' },
+ },
+ {
+ key: 'value',
+ label: 'Значение',
+ formatter: this.dataFormatter,
+ },
+ ],
+ expandRowLabel: expandRowLabel,
+ items: null,
+ };
+ },
+ computed: {
+ systems() {
+ return this.$store.getters['system/systems'];
+ },
+ },
+ watch: {
+ systems() {
+ this.items = [
+ {
+ param: 'id',
+ value: this.id,
+ },
+ { param: 'Модель', value: this.systems[0].model },
+ { param: 'Производитель', value: '' },
+ { param: 'Операционная система', value: '' },
+ { param: 'Серийный номер', value: this.systems[0].serialNumber },
+ {
+ param: 'Свободное место на Flash-накопителе',
+ value: '1 024 000 Мб',
+ },
+ ];
+ },
+ },
+ created() {
+ this.$store.dispatch('system/getSystem').finally(() => {
+ // Emit initial data fetch complete to parent component
+ this.$root.$emit('hardware-status-system-complete');
+ });
+ this.startLoader();
+ const systemTablePromise = new Promise((resolve) => {
+ this.$root.$on('hardware-status-system-complete', () => resolve());
+ });
+ Promise.all([systemTablePromise]).finally(() => this.endLoader());
+ },
+};
+</script>
diff --git a/src/views/_sila/SystemDescription/Info/SystemDescription.vue b/src/views/_sila/SystemDescription/Info/SystemDescription.vue
new file mode 100644
index 00000000..0a2bb305
--- /dev/null
+++ b/src/views/_sila/SystemDescription/Info/SystemDescription.vue
@@ -0,0 +1,148 @@
+<template>
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title />
+ <!-- System table -->
+ <table-system />
+ <!-- Notes Administration -->
+ <section class="notes-section">
+ <div class="semi-bold-12px textarea-description">
+ <span>{{ $t('SystemDescription.title.Notes') }}</span>
+ </div>
+ <div class="textarea-container">
+ <div class="buttons-container">
+ <button class="notes-button">
+ <img src="@/assets/images/textarea-buttons/button-icon-bold.svg" />
+ </button>
+ <button class="notes-button">
+ <img
+ src="@/assets/images/textarea-buttons/button-icon-cursive.svg"
+ />
+ </button>
+ <button class="notes-button">
+ <img
+ src="@/assets/images/textarea-buttons/button-icon-underline.svg"
+ />
+ </button>
+ <button class="notes-button">
+ <img
+ src="@/assets/images/textarea-buttons/button-icon-crossline.svg"
+ />
+ </button>
+ <button class="notes-button">
+ <img src="@/assets/images/textarea-buttons/button-icon-link.svg" />
+ </button>
+ <div class="line"></div>
+ <button class="notes-button">
+ <img src="@/assets/images/textarea-buttons/button-icon-list.svg" />
+ </button>
+ <button class="notes-button">
+ <img
+ src="@/assets/images/textarea-buttons/button-icon-number-list.svg"
+ />
+ </button>
+ </div>
+ <textarea
+ id=""
+ name="area"
+ placeholder="Тут будет текст который ввел администратор и работать в качестве блокнота"
+ cols="30"
+ rows="10"
+ class="notes-textarea"
+ ></textarea>
+ </div>
+ </section>
+ </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import TableSystem from './InventoryTableSystem';
+import iconChevronUp from '@carbon/icons-vue/es/chevron--up/16';
+
+export default {
+ components: {
+ PageTitle,
+ TableSystem,
+ },
+ data() {
+ return {
+ text: '',
+ iconChevronUp: iconChevronUp,
+ };
+ },
+};
+</script>
+<style lang="scss" scoped>
+//nav items style
+.nav-item,
+.nav-link {
+ padding: 0;
+}
+
+.nav-item {
+ list-style-type: none;
+}
+
+a {
+ color: $text-primary !important;
+ &:hover {
+ color: $text-primary !important;
+ }
+}
+//section style
+.notes-section {
+ display: flex;
+ flex-direction: column;
+}
+
+.textarea-description {
+ margin: 5px 0 10px 2rem;
+}
+
+.buttons-container {
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: flex-start;
+ align-items: center;
+}
+
+.notes-button {
+ width: 2rem;
+ height: 2rem;
+ margin: 22px 0 22px 25px;
+ background-color: $surface-secondary;
+ border: none;
+ &:hover {
+ border-radius: 8px;
+ background-color: $faint-secondary-primary-5-hover;
+ }
+}
+
+.line {
+ display: inline-block;
+ width: 1px;
+ height: 2rem;
+ margin: 22px 0 22px 25px;
+ border-left: 1px solid rgba(26, 62, 91, 0.2);
+}
+
+.textarea-container {
+ display: flex;
+ flex-direction: column;
+ border-radius: 8px;
+ margin: 0 1rem 1rem 1rem;
+ background-color: $surface-secondary;
+}
+
+.notes-textarea {
+ resize: none;
+ border: none;
+ flex: 0 0 auto;
+ margin: 0 1rem 1rem 1rem;
+ border-radius: 8px;
+ background-color: $white;
+}
+</style>
diff --git a/src/views/_sila/SystemDescription/Info/index.js b/src/views/_sila/SystemDescription/Info/index.js
new file mode 100644
index 00000000..8b483f2d
--- /dev/null
+++ b/src/views/_sila/SystemDescription/Info/index.js
@@ -0,0 +1,2 @@
+import SystemDescription from './SystemDescription.vue';
+export default SystemDescription;
diff --git a/src/views/_sila/SystemDescription/Network/InventoryIPv4Settings.vue b/src/views/_sila/SystemDescription/Network/InventoryIPv4Settings.vue
new file mode 100644
index 00000000..980aee5a
--- /dev/null
+++ b/src/views/_sila/SystemDescription/Network/InventoryIPv4Settings.vue
@@ -0,0 +1,277 @@
+<template>
+ <page-section class="bootstrap-table__section">
+ <b-table
+ responsive="md"
+ show-empty
+ no-border-collapse
+ :items="systems"
+ :fields="fields"
+ :empty-text="$t('global.table.emptyMessage')"
+ >
+ <template #cell(value)="data">
+ <b-row v-if="data.index === 0">
+ <b-col>
+ <span>
+ {{ data.value ? 'Включен' : 'Выключен' }}
+ </span>
+ </b-col>
+ <b-col>
+ <b-button
+ :id="`popover-choice-${data.index}`"
+ class="popover-option-ractive"
+ variant="toogle-popover"
+ >
+ <img :is="iconChevron" class="icon-chevron" />
+ </b-button>
+ <two-chioce-popover
+ :id="data.index"
+ fitst-option="Включен"
+ second-option="Выключен"
+ :chosen-option="chosenOption"
+ :first-action="setOn"
+ :second-action="setOff"
+ placement="leftbottom"
+ />
+ </b-col>
+ </b-row>
+ <b-row v-else>
+ <b-form-input
+ v-if="systems[data.index].isEdit"
+ ref="input"
+ v-model="selectedCell"
+ class="regular-12px"
+ :class="{ validateIP: isIpInvalid }"
+ type="text"
+ @keydown.enter="clickOk(data)"
+ @keydown.escape="clickCancel(data)"
+ ></b-form-input>
+ <b-col v-else>{{ data.value }}</b-col>
+ <b-col class="table-network__icon">
+ <b-row v-if="systems[data.index].isEdit">
+ <img
+ src="@/assets/images/edit-ok.svg"
+ class="system-network-table__icon pointer"
+ @click="clickOk(data)"
+ />
+ <img
+ src="@/assets/images/edit-no.svg"
+ class="system-network-table__icon close_icon pointer"
+ @click="clickCancel(data)"
+ />
+ </b-row>
+ <img
+ v-else
+ src="@/assets/images/icon-edit.svg"
+ class="system-network-table__icon icon-edit pointer"
+ @click="editCellHandler(data)"
+ />
+ </b-col>
+ </b-row>
+ </template>
+ </b-table>
+ </page-section>
+</template>
+
+<script>
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import PageSection from '@/components/Global/PageSection';
+import iconChevron from '@carbon/icons-vue/es/chevron--down/16';
+import TwoChiocePopover from '@/components/Global/SilaComponents/TwoChiocePopover';
+import TableRowExpandMixin, {
+ expandRowLabel,
+} from '@/components/Mixins/TableRowExpandMixin';
+
+export default {
+ components: { PageSection, TwoChiocePopover },
+ mixins: [BVToastMixin, TableRowExpandMixin, DataFormatterMixin],
+ data() {
+ return {
+ selectedCell: null,
+ isActive: false,
+ isIpInvalid: false,
+ chosenOption: 'Выключен',
+ fields: [
+ {
+ key: 'param',
+ label: 'Параметр',
+ formatter: this.dataFormatter,
+ thStyle: { width: '30%' },
+ },
+ {
+ key: 'value',
+ label: 'Значение',
+ formatter: this.dataFormatter,
+ thStyle: { width: '20%' },
+ },
+ {
+ key: 'comment',
+ label: 'Комментарий',
+ formatter: this.dataFormatter,
+ },
+ ],
+ expandRowLabel: expandRowLabel,
+ iconChevron,
+ systems: [
+ {
+ param: 'DHCP Server (откуда получен IP)',
+ value: false,
+ comment: 'Когда DHPC Server включен параметры вводятся автоматически',
+ },
+ {
+ param: 'IP-адрес',
+ value: '192.168.1.1',
+ comment: 'Введите IP адрес',
+ },
+ {
+ param: 'Маска',
+ value: '192.168.0.1',
+ comment: 'Введите маску сети',
+ },
+ {
+ param: 'Сетевой шлюз',
+ value: '192.168.0.1',
+ comment: 'Введите сетевой шлюз',
+ },
+ {
+ param: 'DNS',
+ value: '8.8.8.8',
+ comment: 'Введите DNS',
+ },
+ ],
+ };
+ },
+ methods: {
+ editCellHandler(data) {
+ this.systems = this.systems.map((item) => ({ ...item, isEdit: false }));
+ this.systems[data.index].isEdit = true;
+ this.selectedCell = this.systems[data.index].value;
+ this.$nextTick(() => this.$refs.input.focus());
+ },
+ clickOk(data) {
+ const EDIT_VALUE = this.selectedCell.trim();
+ if (this.validateIP(EDIT_VALUE)) {
+ this.systems[data.index].value = EDIT_VALUE;
+ this.isIpInvalid = false;
+ this.selectedCell = null;
+ this.systems[data.index].isEdit = false;
+ } else {
+ this.isIpInvalid = true;
+ }
+ },
+ clickCancel(data) {
+ this.isIpInvalid = false;
+ this.selectedCell = null;
+ this.systems[data.index].isEdit = false;
+ },
+ validateIP(ipCheck) {
+ return /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(
+ ipCheck
+ );
+ },
+ setOn() {
+ this.chosenOption = 'Включен';
+ this.systems[0].value = true;
+ },
+ setOff() {
+ this.chosenOption = 'Выключен';
+ this.systems[0].value = false;
+ },
+ DHCPoff() {
+ this.systems[0].value = false;
+ this.isActive = false;
+ },
+ DHCPon() {
+ this.systems[0].value = true;
+ this.isActive = false;
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+.row {
+ align-items: baseline;
+ flex-wrap: nowrap;
+}
+.icon-expand {
+ margin: 0 !important;
+}
+
+.close_icon {
+ margin-left: 5px;
+}
+
+.form-control {
+ max-height: 16px;
+ width: 60%;
+ background-color: transparent;
+ &:focus {
+ box-shadow: none;
+ }
+ &.validateIP {
+ color: $red-brand-primary;
+ }
+}
+.popup-container {
+ position: relative;
+}
+
+.popup {
+ position: absolute;
+ top: -12px;
+ left: 3px;
+ width: 97%;
+ background: $white;
+ z-index: 1000;
+ border: 1px solid rgba(26, 62, 91, 0.1);
+ box-sizing: border-box;
+ box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.1);
+ border-radius: 8px;
+ visibility: hidden;
+}
+
+.popup-button {
+ width: 96%;
+ height: 50px;
+ margin: 4px;
+ border-radius: 8px;
+ border: none;
+
+ display: flex;
+ align-items: center;
+ &.popup-on {
+ color: $red-brand-primary;
+ border-radius: 8px;
+ &:hover {
+ background-color: $faint-secondary-primary-5-hover;
+ }
+ &:active {
+ background-color: $faint-secondary-primary-20;
+ }
+ }
+
+ &.popup-off {
+ background-color: $red-brand-primary;
+ color: $white;
+ &:hover {
+ background-color: $red-brand-primary-hover;
+ }
+ &:active {
+ background-color: $red-brand-primary-active;
+ }
+ }
+}
+
+.popup-text {
+ margin-left: 20px;
+}
+
+.popup_active {
+ visibility: visible;
+}
+
+.popover-option-ractive {
+ display: block;
+ margin: -6px 9px 0 auto;
+}
+</style>
diff --git a/src/views/_sila/SystemDescription/Network/InventoryIPv6Settings.vue b/src/views/_sila/SystemDescription/Network/InventoryIPv6Settings.vue
new file mode 100644
index 00000000..a8c590b1
--- /dev/null
+++ b/src/views/_sila/SystemDescription/Network/InventoryIPv6Settings.vue
@@ -0,0 +1,263 @@
+<template>
+ <page-section class="bootstrap-table__section">
+ <b-table
+ responsive="md"
+ show-empty
+ no-border-collapse
+ :items="systems"
+ :fields="fields"
+ :empty-text="$t('global.table.emptyMessage')"
+ >
+ <template #cell(value)="data">
+ <b-row v-if="!(typeof data.value === 'boolean')">
+ <b-form-input
+ v-if="systems[data.index].isEdit"
+ ref="input"
+ v-model="selectedCell"
+ class="regular-12px"
+ :class="{ validateIP: isIpInvalid }"
+ type="text"
+ @keydown.enter="clickOk(data)"
+ @keydown.escape="clickCancel(data)"
+ ></b-form-input>
+ <b-col v-else>{{ data.value }}</b-col>
+ <b-col class="table-network__icon">
+ <b-row v-if="systems[data.index].isEdit">
+ <img
+ src="@/assets/images/edit-ok.svg"
+ class="system-network-table__icon pointer"
+ @click="clickOk(data)"
+ />
+ <img
+ src="@/assets/images/edit-no.svg"
+ class="system-network-table__icon close_icon pointer"
+ @click="clickCancel(data)"
+ />
+ </b-row>
+ <img
+ v-else
+ src="@/assets/images/icon-edit.svg"
+ class="system-network-table__icon pointer"
+ @click="editCellHandler(data)"
+ />
+ </b-col>
+ </b-row>
+ <b-row v-else class="popup-container">
+ <b-col v-if="data.value">{{ 'Включен' }}</b-col>
+ <b-col v-else>{{ 'Выключен' }}</b-col>
+ <div
+ v-if="isActive"
+ class="popup"
+ :class="{ popup_active: isActive }"
+ >
+ <button class="popup-button popup-on medium-12px" @click="DHCPon">
+ <span class="popup-text">Включен</span>
+ </button>
+ <button class="popup-button popup-off medium-12px" @click="DHCPoff">
+ <span class="popup-text">Выключен</span>
+ </button>
+ </div>
+ <b-col class="table-network__icon">
+ <img
+ :is="iconChevron"
+ class="pointer"
+ @click="isActive = !isActive"
+ />
+ </b-col>
+ </b-row>
+ </template>
+ </b-table>
+ </page-section>
+</template>
+
+<script>
+import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import PageSection from '@/components/Global/PageSection';
+import iconChevron from '@carbon/icons-vue/es/chevron--down/16';
+import TableRowExpandMixin, {
+ expandRowLabel,
+} from '@/components/Mixins/TableRowExpandMixin';
+
+export default {
+ components: { PageSection },
+ mixins: [BVToastMixin, TableRowExpandMixin, DataFormatterMixin],
+ data() {
+ return {
+ isBusy: true,
+ selectedCell: null,
+ isIpInvalid: false,
+ isActive: false,
+ fields: [
+ {
+ key: 'param',
+ label: 'Параметр',
+ formatter: this.dataFormatter,
+ thStyle: { width: '30%' },
+ },
+ {
+ key: 'value',
+ label: 'Значение',
+ formatter: this.dataFormatter,
+ thStyle: { width: '20%' },
+ },
+ {
+ key: 'comment',
+ label: 'Комментарий',
+ formatter: this.dataFormatter,
+ },
+ ],
+ expandRowLabel: expandRowLabel,
+ iconChevron,
+ systems: [
+ {
+ param: 'DHCP Server (откуда получен IP)',
+ value: false,
+ comment: 'Когда DHPC Server включен параметры вводятся автоматически',
+ },
+ {
+ param: 'IP-адрес',
+ value: 'fe80::1ff:fe23:4567:890a',
+ comment: 'Введите IP адрес',
+ },
+ {
+ param: 'Маска',
+ value: 'fe80::1ff:fe23:4567:890a',
+ comment: 'Введите маску сети',
+ },
+ {
+ param: 'Сетевой шлюз',
+ value: 'fe80::1ff:fe23:4567:890a',
+ comment: 'Введите сетевой шлюз',
+ },
+ {
+ param: 'DNS',
+ value: 'fe80::1ff:fe23:4567:890a',
+ comment: 'Введите DNS',
+ },
+ ],
+ };
+ },
+ methods: {
+ editCellHandler(data) {
+ this.systems = this.systems.map((item) => ({ ...item, isEdit: false }));
+ this.systems[data.index].isEdit = true;
+ this.selectedCell = this.systems[data.index].value;
+ this.$nextTick(() => this.$refs.input.focus());
+ },
+ clickOk(data) {
+ const EDIT_VALUE = this.selectedCell.trim();
+ if (this.validateIP(EDIT_VALUE)) {
+ this.systems[data.index].value = EDIT_VALUE;
+ this.isIpInvalid = false;
+ this.selectedCell = null;
+ this.systems[data.index].isEdit = false;
+ } else {
+ this.isIpInvalid = true;
+ }
+ },
+ clickCancel(data) {
+ this.isIpInvalid = false;
+ this.selectedCell = null;
+ this.systems[data.index].isEdit = false;
+ },
+ validateIP(ipCheck) {
+ return /(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/gi.test(
+ ipCheck
+ );
+ },
+ DHCPoff() {
+ this.systems[0].value = false;
+ this.isActive = false;
+ },
+ DHCPon() {
+ this.systems[0].value = true;
+ this.isActive = false;
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+.row {
+ align-items: baseline;
+ flex-wrap: nowrap;
+}
+.icon-expand {
+ margin: 0 !important;
+}
+
+.close_icon {
+ margin-left: 5px;
+}
+
+.form-control {
+ max-height: 16px;
+ width: 60%;
+ background-color: transparent;
+ &:focus {
+ box-shadow: none;
+ }
+ &.validateIP {
+ color: $red-brand-primary;
+ }
+}
+
+.popup-container {
+ position: relative;
+}
+
+.popup {
+ position: absolute;
+ top: -12px;
+ left: 3px;
+ width: 97%;
+ background: $white;
+ z-index: 1000;
+ border: 1px solid rgba(26, 62, 91, 0.1);
+ box-sizing: border-box;
+ box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.1);
+ border-radius: 8px;
+ visibility: hidden;
+}
+
+.popup-button {
+ width: 96%;
+ height: 50px;
+ margin: 4px;
+ border-radius: 8px;
+ border: none;
+ cursor: pointer;
+
+ display: flex;
+ align-items: center;
+ &.popup-on {
+ color: $red-brand-primary;
+ border-radius: 8px;
+ &:hover {
+ background-color: $faint-secondary-primary-5-hover;
+ }
+ &:active {
+ background-color: $faint-secondary-primary-20;
+ }
+ }
+
+ &.popup-off {
+ background-color: $red-brand-primary;
+ color: $white;
+ &:hover {
+ background-color: $red-brand-primary-hover;
+ }
+ &:active {
+ background-color: $red-brand-primary-active;
+ }
+ }
+}
+
+.popup-text {
+ margin-left: 20px;
+}
+
+.popup_active {
+ visibility: visible;
+}
+</style>
diff --git a/src/views/_sila/SystemDescription/Network/SystemNetwork.vue b/src/views/_sila/SystemDescription/Network/SystemNetwork.vue
new file mode 100644
index 00000000..19243493
--- /dev/null
+++ b/src/views/_sila/SystemDescription/Network/SystemNetwork.vue
@@ -0,0 +1,101 @@
+<template>
+ <b-container
+ id="page-system-network"
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title :description="$t('appNavigation.networkParametrs')" />
+ <!-- IPv4 -->
+ <div class="page-collapse-decorator">
+ <b-button
+ v-b-toggle.toggle-collapse_1
+ variant="link"
+ class="collapse-button semi-bold-16px"
+ @click="ipv4Handler"
+ >
+ {{ $t('SystemDescription.title.Ipv4Settings') }}
+ <b-form-checkbox
+ id="checkbox-1"
+ v-model="ipv4"
+ @click.native.prevent
+ ></b-form-checkbox>
+ </b-button>
+ <b-collapse id="toggle-collapse_1" class="nav-item__nav">
+ <i-pv4-settings ref="system" />
+ </b-collapse>
+ </div>
+ <!-- IPv6 -->
+ <div class="page-collapse-decorator">
+ <b-button
+ v-b-toggle.toggle-collapse_2
+ variant="link"
+ class="collapse-button semi-bold-16px"
+ @click="ipv6Handler"
+ >
+ {{ $t('SystemDescription.title.Ipv6Settings') }}
+ <b-form-checkbox
+ id="checkbox-2"
+ v-model="ipv6"
+ @click.native.prevent
+ ></b-form-checkbox>
+ </b-button>
+ <b-collapse id="toggle-collapse_2" class="nav-item__nav">
+ <i-pv6-settings ref="system" />
+ </b-collapse>
+ </div>
+ </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import IPv4Settings from './InventoryIPv4Settings';
+import IPv6Settings from './InventoryIPv6Settings';
+import iconChevronUp from '@carbon/icons-vue/es/chevron--up/16';
+
+export default {
+ components: {
+ PageTitle,
+ IPv4Settings,
+ IPv6Settings,
+ },
+ data() {
+ return {
+ text: '',
+ iconChevronUp: iconChevronUp,
+ ipv4: false,
+ ipv6: false,
+ };
+ },
+ methods: {
+ ipv4Handler() {
+ this.ipv4 = !this.ipv4;
+ },
+ ipv6Handler() {
+ this.ipv6 = !this.ipv6;
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+//nav items style
+.nav-item,
+.nav-link {
+ padding: 0;
+}
+
+.nav-item {
+ list-style-type: none;
+}
+
+a {
+ color: $text-primary !important;
+ &:hover {
+ color: $text-primary !important;
+ }
+}
+
+.custom-checkbox {
+ background-color: none;
+ margin: 0 20px 0 auto;
+}
+</style>
diff --git a/src/views/_sila/SystemDescription/Network/index.js b/src/views/_sila/SystemDescription/Network/index.js
new file mode 100644
index 00000000..25f85f3c
--- /dev/null
+++ b/src/views/_sila/SystemDescription/Network/index.js
@@ -0,0 +1,2 @@
+import SystemNetwork from './SystemNetwork.vue';
+export default SystemNetwork;
diff --git a/src/views/_sila/SystemDescription/ServerParametrs/ServerParametrs.vue b/src/views/_sila/SystemDescription/ServerParametrs/ServerParametrs.vue
new file mode 100644
index 00000000..9eb57301
--- /dev/null
+++ b/src/views/_sila/SystemDescription/ServerParametrs/ServerParametrs.vue
@@ -0,0 +1,21 @@
+<template>
+ <b-container
+ :style="{ display: 'flex', 'flex-direction': 'column' }"
+ fluid="xxl pt-0 m-0"
+ >
+ <page-title :description="$t('appNavigation.serverParam')" />
+ <servere-parametrs-section />
+ </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import ServereParametrsSection from './ServereParametrsSection';
+
+export default {
+ components: {
+ PageTitle,
+ ServereParametrsSection,
+ },
+};
+</script>
diff --git a/src/views/_sila/SystemDescription/ServerParametrs/ServereParametrsSection.vue b/src/views/_sila/SystemDescription/ServerParametrs/ServereParametrsSection.vue
new file mode 100644
index 00000000..f8aebeb6
--- /dev/null
+++ b/src/views/_sila/SystemDescription/ServerParametrs/ServereParametrsSection.vue
@@ -0,0 +1,128 @@
+<template>
+ <page-section class="bootstrap-table__section">
+ <span class="bold-12px__caps">
+ {{ $t('SystemDescription.LoadingQueue') }}
+ </span>
+ <b-table
+ responsive="md"
+ class="table-stripes"
+ :items="queueItems"
+ :fields="fields"
+ >
+ <template #cell(active)="data">
+ <b-row>
+ <b-col>
+ <span v-if="queueItems[data.index].active">
+ {{ $t('global.status.enabled') }}
+ </span>
+ <span v-else>
+ {{ $t('global.status.disabled') }}
+ </span>
+ </b-col>
+ <b-col>
+ <b-form-checkbox
+ v-model="queueItems[data.index].active"
+ switch
+ @change="toggleLoad"
+ >
+ </b-form-checkbox>
+ </b-col>
+ </b-row>
+ </template>
+ </b-table>
+ <span class="bold-12px__caps">
+ {{ $t('SystemDescription.DiskParametrs') }}
+ </span>
+ <b-table
+ responsive="md"
+ class="table-stripes"
+ :items="diskItems"
+ :fields="fields"
+ >
+ </b-table>
+ </page-section>
+</template>
+
+<script>
+import PageSection from '@/components/Global/PageSection';
+import iconChevron from '@carbon/icons-vue/es/chevron--down/16';
+
+export default {
+ components: { PageSection },
+ data() {
+ return {
+ selectedCell: null,
+ fields: [
+ {
+ key: 'param',
+ label: '',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'active',
+ label: '',
+ formatter: this.dataFormatter,
+ },
+ ],
+ iconChevron,
+ queueItems: [
+ {
+ param: 'Hard Drive C:',
+ active: false,
+ },
+ {
+ param:
+ 'Embedded NIC 2 Port 1 Partition 1: BRCM MBA Slot E101 v21.6.0',
+ active: false,
+ },
+ {
+ param: 'Virtual Floppy Drive',
+ active: false,
+ },
+ {
+ param: 'Virtual Optical Drive',
+ active: false,
+ },
+ ],
+ diskItems: [
+ {
+ param: 'Internal SD',
+ active: 'IDSM',
+ },
+ {
+ param: 'ACHI Controller in SL7',
+ active: 'A0S0 MTFDDAV480TDS',
+ },
+ {
+ param: 'ACHI Controller in SL7',
+ active: 'A0S1 MTFDDAV480TDS',
+ },
+ {
+ param: 'RAID Controller in SL8',
+ active: 'PERC H755 Front (bus 01 dev 00)',
+ },
+ ],
+ };
+ },
+ methods: {
+ toggleLoad(data, value) {
+ this.queueItems[data.index].value = !value;
+ },
+ },
+};
+</script>
+<style lang="scss" scoped>
+.row {
+ align-items: center;
+ flex-wrap: nowrap;
+ justify-content: flex-end;
+}
+.icon-expand {
+ margin: 0 !important;
+}
+
+.bold-12px__caps {
+ display: block;
+ margin: 16px 0 7px 0;
+}
+</style>
diff --git a/src/views/_sila/SystemDescription/ServerParametrs/index.js b/src/views/_sila/SystemDescription/ServerParametrs/index.js
new file mode 100644
index 00000000..5ce6ca74
--- /dev/null
+++ b/src/views/_sila/SystemDescription/ServerParametrs/index.js
@@ -0,0 +1,2 @@
+import ServerParametrs from './ServerParametrs.vue';
+export default ServerParametrs;