diff options
Diffstat (limited to 'src/views')
22 files changed, 2533 insertions, 3 deletions
diff --git a/src/views/BMC/Configuration/BMCConfiguration.vue b/src/views/BMC/Configuration/BMCConfiguration.vue new file mode 100644 index 00000000..92f4f051 --- /dev/null +++ b/src/views/BMC/Configuration/BMCConfiguration.vue @@ -0,0 +1,115 @@ +<template> + <b-container + :style="{ display: 'flex', 'flex-direction': 'column' }" + fluid="xxl pt-0 m-0" + > + <page-title /> + <!-- BMC table --> + <div class="main-container"> + <div class="page-collapse-decorator"> + <b-button + v-b-toggle.toggle-collapse_1 + variant="link" + class="bmc-collapse__button semi-bold-16px" + > + {{ $t('BMC.BmcTitle') }} + <component :is="iconChevronUp" class="icon-expand" /> + </b-button> + <b-collapse id="toggle-collapse_1" 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="bmc-collapse__button semi-bold-16px" + > + {{ $t('BMC.ControlTitle') }} + <component :is="iconChevronUp" class="icon-expand" /> + </b-button> + <b-collapse id="toggle-collapse_2" class="nav-item__nav"> + <b-m-c-configuration-control /> + </b-collapse> + </div> + </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'; + +export default { + components: { + PageTitle, + BMCConfigurationControl, + BMCConfigurationTable, + PageSection, + }, + data() { + return { + text: '', + iconChevronUp: iconChevronUp, + }; + }, +}; +</script> +<style lang="scss" scoped> +//nav items style +.nav-item, +.nav-link { + padding: 0; +} + +.bmc-collapse__button { + height: 56px; + width: 100%; + padding: 0 0 0 2rem; + margin: 0; + display: flex; + flex-flow: row nowrap; + justify-content: flex-start; + &:active, + &:focus { + box-shadow: none; + } + &:hover { + color: $text-primary; + } +} + +.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/BMC/Configuration/BMCConfigurationControl.vue b/src/views/BMC/Configuration/BMCConfigurationControl.vue new file mode 100644 index 00000000..cacd54ed --- /dev/null +++ b/src/views/BMC/Configuration/BMCConfigurationControl.vue @@ -0,0 +1,103 @@ +<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" + /> + <div> + <span class="regular-12px underline">{{ + $t('BMC.ExportImport') + }}</span> + </div> + <div> + <span class="regular-12px underline">{{ $t('BMC.Parametrs') }}</span> + </div> + </div> + + <div class="bmc-control__table__cell"> + <div> + <span class="semi-bold-12px">{{ $t('BMC.microcode') }}</span> + </div> + <popover + id="popover-reactive-2" + description="BMC.ReloadMicrocodeBios" + popup="BMC.ReloadMicrocodeBios" + button="global.action.refresh" + :microcode="true" + /> + <popover + id="popover-reactive-3" + description="BMC.ReloadicrocodeBmc" + popup="BMC.ReloadicrocodeBmc" + button="global.action.refresh" + :microcode="true" + /> + </div> + </div> + </page-section> +</template> + +<script> +import PageSection from '@/components/Global/PageSection'; +import Popover from '@/components/Global/Popover'; + +export default { + components: { PageSection, Popover }, + 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, + }, + }; + }, +}; +</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/BMC/Configuration/BMCConfigurationTable.vue b/src/views/BMC/Configuration/BMCConfigurationTable.vue new file mode 100644 index 00000000..dd0033e7 --- /dev/null +++ b/src/views/BMC/Configuration/BMCConfigurationTable.vue @@ -0,0 +1,67 @@ +<template> + <page-section class="bootstrap-table__section"> + <b-table + responsive="md" + show-empty + class="bootstrap-rounded-table" + :items="systems" + :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 TableRowExpandMixin, { + expandRowLabel, +} from '@/components/Mixins/TableRowExpandMixin'; + +export default { + components: { PageSection }, + mixins: [BVToastMixin, TableRowExpandMixin], + data() { + return { + isBusy: true, + fields: [ + { + key: 'param', + label: 'Параметр', + formatter: this.dataFormatter, + thClass: 'semi-bold-12px__caps bootstrap-rounded-table__head_bg', + class: `bootstrap-rounded-table__column-first + bootstrap-rounded-table__column-first___bmc_conf`, + tdClass: 'regular-12px bootstrap-rounded-table__td', + }, + { + key: 'value', + label: 'Значение', + formatter: this.dataFormatter, + thClass: 'semi-bold-12px__caps bootstrap-rounded-table__head_bg', + class: 'bootstrap-rounded-table__column-last', + tdClass: 'regular-12px bootstrap-rounded-table__td', + }, + ], + expandRowLabel: expandRowLabel, + systems: [ + { + param: 'Время BMC', + value: '14:20', + }, + { param: 'Версия прошивки', value: '1.214.248 beta' }, + { param: 'MAC - адреса', value: '487566947' }, + { param: 'IP - адреса', value: '192.168.48.1' }, + { param: 'Имя ВМС', value: 'ВМС-007' }, + ], + }; + }, +}; +</script> +<style lang="scss"> +.bootstrap-rounded-table__column-first___bmc_conf { + width: 50%; +} +</style> diff --git a/src/views/BMC/Configuration/index.js b/src/views/BMC/Configuration/index.js new file mode 100644 index 00000000..da796489 --- /dev/null +++ b/src/views/BMC/Configuration/index.js @@ -0,0 +1,2 @@ +import BMCConfiguration from './BMCConfiguration.vue'; +export default BMCConfiguration; diff --git a/src/views/Login/Login.vue b/src/views/Login/Login.vue index 877f3891..520daf60 100644 --- a/src/views/Login/Login.vue +++ b/src/views/Login/Login.vue @@ -14,7 +14,7 @@ ></b-form-select> </b-form-group> --> <b-form-group - class="text__h1" + class="bold-24px" label-for="auth" :label="$t('pageLogin.auth')" ></b-form-group> diff --git a/src/views/Operations/ConsoleSettings/ConsoleSettings.vue b/src/views/Operations/ConsoleSettings/ConsoleSettings.vue new file mode 100644 index 00000000..bd95fa46 --- /dev/null +++ b/src/views/Operations/ConsoleSettings/ConsoleSettings.vue @@ -0,0 +1,97 @@ +<template> + <b-container + :style="{ display: 'flex', 'flex-direction': 'column' }" + fluid="xxl pt-0 m-0" + > + <page-title /> + <!-- BMC table --> + <div class="main-container"> + <page-section class="bootstrap-table__section"> + <b-table + responsive="md" + show-empty + class="bootstrap-rounded-table" + :items="systems" + :fields="fields" + :empty-text="$t('global.table.emptyMessage')" + > + </b-table> + </page-section> + </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 BVToastMixin from '@/components/Mixins/BVToastMixin'; +// import iconChevronUp from '@carbon/icons-vue/es/chevron--up/16'; +import TableRowExpandMixin, { + expandRowLabel, +} from '@/components/Mixins/TableRowExpandMixin'; + +export default { + components: { + PageTitle, + // BMCConfigurationControl, + // BMCConfigurationTable, + PageSection, + }, + mixins: [BVToastMixin, TableRowExpandMixin], + data() { + return { + text: '', + isBusy: true, + fields: [ + { + key: 'attributes', + label: 'Атрибуты', + formatter: this.dataFormatter, + thClass: 'semi-bold-12px__caps bootstrap-rounded-table__head_bg', + class: 'bootstrap-rounded-table__column-first', + tdClass: 'regular-12px bootstrap-rounded-table__td', + }, + { + key: 'value', + label: 'Значение', + formatter: this.dataFormatter, + thClass: 'semi-bold-12px__caps bootstrap-rounded-table__head_bg', + class: `bootstrap-rounded-table__column-last + bootstrap-rounded-table__column-last___console`, + tdClass: 'regular-12px bootstrap-rounded-table__td', + }, + ], + expandRowLabel: expandRowLabel, + systems: [ + { attributes: 'Включена', value: 'Включено' }, + { attributes: 'Максимальное количество сеансов', value: '6' }, + { attributes: 'Активные сеансы', value: '0' }, + { attributes: 'Порт удаленного доступа', value: '5900' }, + { attributes: 'Статус шифрования видео', value: 'Включено' }, + { attributes: 'Видео с локального сервера', value: 'Включено' }, + { + attributes: + 'Действие по умолчанию при истечении времени ожидания запроса на общий доступ к сеансу', + value: 'Полный доступ', + }, + { + attributes: 'Автоматическая блокировка системы', + value: 'Не включено', + }, + { + attributes: 'Состояние подключения клавиатуры/мыши', + value: 'Автоматическое', + }, + ], + // iconChevronUp: iconChevronUp, + }; + }, +}; +</script> +<style lang="scss"> +.bootstrap-rounded-table__column-last___console { + width: 30%; +} +</style> diff --git a/src/views/Operations/ConsoleSettings/index.js b/src/views/Operations/ConsoleSettings/index.js new file mode 100644 index 00000000..860ee595 --- /dev/null +++ b/src/views/Operations/ConsoleSettings/index.js @@ -0,0 +1,2 @@ +import ConsoleSettings from './ConsoleSettings.vue'; +export default ConsoleSettings; diff --git a/src/views/Operations/SerialOverLan/SerialOverLan.vue b/src/views/Operations/SerialOverLan/SerialOverLan.vue index 48a68345..08a67d84 100644 --- a/src/views/Operations/SerialOverLan/SerialOverLan.vue +++ b/src/views/Operations/SerialOverLan/SerialOverLan.vue @@ -1,7 +1,6 @@ <template> <b-container fluid="xl"> - <page-title class="mb-4" :description="$t('pageSerialOverLan.subTitle')" /> - + <page-title /> <page-section class="mb-0"> <serial-over-lan-console :is-full-window="false" /> </page-section> diff --git a/src/views/SystemDescription/Info/InventoryControlSystem.vue b/src/views/SystemDescription/Info/InventoryControlSystem.vue new file mode 100644 index 00000000..f47b4868 --- /dev/null +++ b/src/views/SystemDescription/Info/InventoryControlSystem.vue @@ -0,0 +1,228 @@ +<template> + <page-section class="system-control-section"> + <div class="system-control__table"> + <div class="system-control__table__row"> + <div class="system-control__table__cell"> + <div> + <span class="semi-bold-12px"> + {{ $t('SystemDescription.title.ReloadServer') }} + </span> + </div> + <popover + id="popover-reactive-1" + description="SystemDescription.ReloadOSAndServer" + popup="SystemDescription.ReloadOSAndServer_popup" + /> + <popover + id="popover-reactive-2" + description="SystemDescription.ReloadServer" + popup="SystemDescription.ReloadServer_popup" + /> + <div> + <span class="regular-12px underline"> + {{ $t('SystemDescription.ConnectToDesktop') }} + </span> + </div> + </div> + + <div class="system-control__table__cell system-control__table__cell__2"> + <div class="reload-progress__container"> + <span class="regular-12px"> + {{ $t('SystemDescription.status') }} + </span> + <span class="semi-bold-12px progress_bar_percent" + >{{ progress1.value }}%</span + > + <b-progress + class="reload-progress" + :value="progress1.value" + ></b-progress> + </div> + <div class="reload-progress__container"> + <span class="regular-12px"> + {{ $t('SystemDescription.status') }} + </span> + <span + v-if="progress2.value === null" + class="semi-bold-12px progress_bar_percent" + >{{ $t('SystemDescription.NotRunning') }}</span + > + <span v-else class="semi-bold-12px progress_bar_percent" + >{{ progress2.value }}%</span + > + <b-progress + class="reload-progress" + :value="progress2.value" + ></b-progress> + </div> + </div> + + <div class="system-control__table__cell"> + <div> + <span class="semi-bold-12px"> + {{ $t('SystemDescription.title.OnOffServer') }} + </span> + </div> + <div> + <popover + id="popover-reactive-3" + description="SystemDescription.OffOsAndServer" + popup="SystemDescription.OffOsAndServer_popup" + button="global.action.off" + /> + <popover + id="popover-reactive-4" + description="SystemDescription.OffServer" + popup="SystemDescription.OffServer_popup" + button="global.action.off" + /> + </div> + </div> + </div> + <div class="system-control__table__row"> + <div class="system-control__table__cell system-control__table__cell__4"> + <div> + <span class="semi-bold-12px"> + {{ $t('SystemDescription.title.setupDatetime') }} + </span> + </div> + <b-form @submit.prevent="onResetSubmit"> + <b-form-radio-group + v-model="timeOption" + class="system-control__radio regular-12px" + > + <b-form-radio value="NTP"> + {{ $t('SystemDescription.GetNtpFromServer') }} + </b-form-radio> + <b-form-radio value="serverDate"> + {{ $t('SystemDescription.UseServerDatettime') }} + </b-form-radio> + </b-form-radio-group> + </b-form> + <ntp-popover + id="popover-reactive-5" + description="SystemDescription.NtpSettings" + /> + </div> + </div> + </div> + </page-section> +</template> + +<script> +import PageSection from '@/components/Global/PageSection'; +import Popover from '@/components/Global/Popover'; +import NtpPopover from './NtpPopover'; + +export default { + components: { + PageSection, + NtpPopover, + Popover, + }, + 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, + }, + }; + }, +}; +</script> +<style lang="scss" scoped> +a { + list-style-type: none; +} + +.system-control-section { + position: relative; + margin: 16px 2rem 2rem !important; + width: 90%; +} + +.system-control__table__row { + display: flex; + flex-flow: row nowrap; + justify-content: space-between; + width: 85%; +} + +.system-control__table__cell { + display: flex; + flex-flow: column nowrap; + align-items: flex-start; + row-gap: 6px; +} + +.system-control__table__cell__2 { + margin-top: 37px; + row-gap: 14px; +} + +.reload-progress__container { + display: flex; + flex-flow: row nowrap; + align-items: baseline; + justify-content: space-between; + width: 100%; + column-gap: 4px; +} + +.semi-bold-12px { + display: inline-block; +} + +label { + padding-top: 5px; +} +.system-control__table__cell__4 { + margin-top: 26px; +} + +.custom-radio ::before { + border: 1px solid $red-brand-primary; + background-color: #fff; + border-radius: 100%; +} + +.system-control-section::v-deep + .custom-control-input:checked + ~ .custom-control-label::before { + border: 2px solid $red-brand-primary; + background-color: $red-brand-primary; + box-shadow: 0px 0px 0px 2.5px $white inset; + border-radius: 100%; +} + +.system-control-section::v-deep + .custom-control-input:hover + ~ .custom-control-label::before { + background-color: $red-brand-primary-hover !important; + box-shadow: 0px 0px 0px 2.5px $white inset; + border-color: $red-brand-primary-hover; +} + +.system-control-section::v-deep + .custom-control-input:checked + ~ .custom-control-label::after { + background-image: none !important; + border-radius: 100%; +} + +.system-control-section::v-deep + .custom-control-input:active + ~ .custom-control-label::before { + background-color: $red-brand-primary-active !important; + box-shadow: 0px 0px 0px 2.5px $white inset; + border-color: $red-brand-primary-active; +} +</style> diff --git a/src/views/SystemDescription/Info/InventoryTableSystem.vue b/src/views/SystemDescription/Info/InventoryTableSystem.vue new file mode 100644 index 00000000..b022fd6d --- /dev/null +++ b/src/views/SystemDescription/Info/InventoryTableSystem.vue @@ -0,0 +1,86 @@ +<template> + <page-section class="bootstrap-table__section"> + <b-table + responsive="md" + show-empty + class="bootstrap-rounded-table" + :items="systems" + :fields="fields" + :empty-text="$t('global.table.emptyMessage')" + :busy="isBusy" + > + </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, + fields: [ + { + key: 'param', + label: 'Параметр', + formatter: this.dataFormatter, + thClass: 'semi-bold-12px__caps bootstrap-rounded-table__head_bg', + class: `bootstrap-rounded-table__column-first + bootstrap-rounded-table__column-first___system-table`, + tdClass: 'regular-12px bootstrap-rounded-table__td', + }, + { + key: 'value', + label: 'Значение', + formatter: this.dataFormatter, + thClass: 'semi-bold-12px__caps bootstrap-rounded-table__head_bg', + class: 'bootstrap-rounded-table__column-last', + tdClass: 'regular-12px bootstrap-rounded-table__td', + }, + ], + expandRowLabel: expandRowLabel, + systems: [ + { + param: 'UUID сервера', + value: '17583', + }, + { param: 'Модель', value: '1.214.248 beta' }, + { param: 'Производитель', value: 'Asus' }, + { param: 'Операционная система', value: 'Linux' }, + { param: 'Серийный номер', value: '741852963335' }, + { + 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.isBusy = false; + }); + }, + methods: { + toggleIdentifyLedSwitch(state) { + this.$store + .dispatch('system/changeIdentifyLedState', state) + .catch(({ message }) => this.errorToast(message)); + }, + }, +}; +</script> +<style lang="scss"> +.bootstrap-rounded-table__column-first___system-table { + width: 50%; +} +</style> diff --git a/src/views/SystemDescription/Info/NtpPopover.vue b/src/views/SystemDescription/Info/NtpPopover.vue new file mode 100644 index 00000000..81e95e4d --- /dev/null +++ b/src/views/SystemDescription/Info/NtpPopover.vue @@ -0,0 +1,141 @@ +<template> + <div id="my-container"> + <span :id="id" class="regular-12px underline" variant="primary"> + {{ $t(description) }} + </span> + <!-- Our popover title and content render container --> + <b-popover + :target="id" + placement="auto" + container="my-container" + :show.sync="popoverShow" + @show="onShow" + @shown="onShown" + @hidden="onHidden" + > + <template #title> + <div class="popup-title"> + <span class="bold-16px__caps">{{ $t(description) }}</span> + <b-button class="popup-title__button_close" @click="onClose"> + <img src="@/assets/images/popups/x-icon.svg" /> + </b-button> + </div> + </template> + + <div class="popup-body"> + <div class="popup-body__input-container"> + <span class="regular-12px tretiatry" + >Введите адрес сервера (IP, FQDM)</span + > + <b-form-input + id="popover-input-1" + v-model="input1" + class="medium-12px" + ></b-form-input> + </div> + <b-button class="popover-button" variant="primary" @click="onClose"> + {{ $t('global.action.save') }} + </b-button> + </div> + </b-popover> + </div> +</template> + +<script> +export default { + props: { + description: { + type: String, + default: '', + }, + id: { + type: String, + default: '', + }, + button: { + type: String, + default: 'Reload', + }, + }, + data() { + return { + input1: '', + popoverShow: false, + }; + }, + methods: { + onShow() { + this.$root.$emit('bv::hide::popover'); + }, + onClose() { + this.popoverShow = false; + }, + }, +}; +</script> +<style lang="scss" scoped> +.form-group { + margin: 0; +} + +.popup-title { + display: flex; + flex-flow: row nowrap; + align-items: baseline; +} + +.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; +} + +.form-control { + width: 341px; + height: 52px; + background: rgba(26, 62, 91, 0.05); + border-radius: 8px; + border: none; + margin: -25px auto; + padding-top: 30px; +} + +.popover-button { + width: 341px; + height: 40px; + margin: 0 auto 10px; +} + +.popup-body__input-container { + height: 52px; + margin: 24px auto 16px auto; +} + +.tretiatry { + margin-left: 12px; +} + +.underline { + cursor: pointer; +} +</style> diff --git a/src/views/SystemDescription/Info/SystemDescription.vue b/src/views/SystemDescription/Info/SystemDescription.vue new file mode 100644 index 00000000..7322d03e --- /dev/null +++ b/src/views/SystemDescription/Info/SystemDescription.vue @@ -0,0 +1,202 @@ +<template> + <b-container + :style="{ display: 'flex', 'flex-direction': 'column' }" + fluid="xxl pt-0 m-0" + > + <page-title /> + <!-- System table --> + <div class="main-container"> + <div class="page-collapse-decorator"> + <b-button + v-b-toggle.toggle-collapse_1 + variant="link" + class="server-info-collapse__button semi-bold-16px" + > + {{ $t('SystemDescription.title.ServerConfig') }} + <component :is="iconChevronUp" class="icon-expand" /> + </b-button> + <b-collapse id="toggle-collapse_1" class="nav-item__nav"> + <table-system ref="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-collapse> + </div> + <!-- Control --> + <div class="page-collapse-decorator"> + <b-button + v-b-toggle.toggle-collapse_2 + variant="link" + class="server-info-collapse__button semi-bold-16px" + > + {{ $t('SystemDescription.title.Control') }} + <component :is="iconChevronUp" class="icon-expand" /> + </b-button> + <b-collapse id="toggle-collapse_2" class="nav-item__nav"> + <control-system /> + </b-collapse> + </div> + </div> + </b-container> +</template> + +<script> +import PageTitle from '@/components/Global/PageTitle'; +import TableSystem from './InventoryTableSystem'; +import ControlSystem from './InventoryControlSystem'; +// import PageSection from '@/components/Global/PageSection'; +import iconChevronUp from '@carbon/icons-vue/es/chevron--up/16'; + +export default { + components: { + PageTitle, + ControlSystem, + TableSystem, + // PageSection, + }, + data() { + return { + text: '', + iconChevronUp: iconChevronUp, + }; + }, +}; +</script> +<style lang="scss" scoped> +//nav items style +.nav-item, +.nav-link { + padding: 0; +} + +.server-info-collapse__button { + height: 56px; + width: 100%; + padding: 0 0 0 2rem; + margin: 0; + display: flex; + flex-flow: row nowrap; + justify-content: flex-start; + &:active, + &:focus { + box-shadow: none; + } + &:hover { + color: $text-primary; + } +} +.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/SystemDescription/Info/index.js b/src/views/SystemDescription/Info/index.js new file mode 100644 index 00000000..8b483f2d --- /dev/null +++ b/src/views/SystemDescription/Info/index.js @@ -0,0 +1,2 @@ +import SystemDescription from './SystemDescription.vue'; +export default SystemDescription; diff --git a/src/views/SystemDescription/Network/InventoryIPv4Settings.vue b/src/views/SystemDescription/Network/InventoryIPv4Settings.vue new file mode 100644 index 00000000..69807762 --- /dev/null +++ b/src/views/SystemDescription/Network/InventoryIPv4Settings.vue @@ -0,0 +1,275 @@ +<template> + <page-section class="bootstrap-table__section"> + <b-table + responsive="md" + show-empty + class="bootstrap-rounded-table" + :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 && selectedCell === 'value'" + ref="input" + v-model="systems[data.index].value" + class="regular-12px" + type="text" + ></b-form-input> + <b-col v-else>{{ data.value }}</b-col> + <b-col class="system-network-table__icon-col"> + <b-row + v-if="systems[data.index].isEdit && selectedCell === 'value'" + > + <img + src="@/assets/images/edit-ok.svg" + class="system-network-table__icon pointer" + @click="clickOk" + /> + <img + src="@/assets/images/edit-no.svg" + class="system-network-table__icon close_icon pointer" + @click="clickCancel" + /> + </b-row> + <img + v-else + src="@/assets/images/icon-edit.svg" + class="system-network-table__icon pointer" + @click="editCellHandler(data, 'value')" + /> + </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="system-network-table__icon-col"> + <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 { + selectedCell: null, + isActive: false, + fields: [ + { + key: 'param', + label: 'Параметр', + formatter: this.dataFormatter, + thClass: 'semi-bold-12px__caps bootstrap-rounded-table__head_bg', + class: `bootstrap-rounded-table__column-first + bootstrap-rounded-table__column-first___ipv-table`, + tdClass: 'regular-12px bootstrap-rounded-table__td', + }, + { + key: 'value', + label: 'Значение', + formatter: this.dataFormatter, + thClass: 'semi-bold-12px__caps bootstrap-rounded-table__head_bg', + class: `bootstrap-rounded-table__column-center + bootstrap-rounded-table__ipv-table___center`, + tdClass: 'regular-12px bootstrap-rounded-table__td', + }, + { + key: 'comment', + label: 'Комментарий', + formatter: this.dataFormatter, + thClass: 'semi-bold-12px__caps bootstrap-rounded-table__head_bg', + class: 'bootstrap-rounded-table__column-last', + tdClass: 'regular-12px bootstrap-rounded-table__td', + }, + ], + 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', + }, + ], + }; + }, + mounted() { + this.systems = this.systems.map((item) => ({ ...item, isEdit: false })); + }, + methods: { + editCellHandler(data, value) { + this.systems = this.systems.map((item) => ({ ...item, isEdit: false })); + this.systems[data.index].isEdit = true; + this.selectedCell = value; + this.$nextTick(() => this.$refs.input.focus()); + }, + clickOk(data) { + this.selectedCell = null; + this.systems[data.index].value = this.$refs.input.value; + }, + clickCancel() { + this.selectedCell = null; + }, + DHCPoff() { + this.systems[0].value = false; + this.isActive = false; + }, + DHCPon() { + this.systems[0].value = true; + this.isActive = false; + }, + }, +}; +</script> +<style lang="scss"> +.bootstrap-rounded-table__column-first___ipv-table { + width: 30%; +} + +.bootstrap-rounded-table__ipv-table___center { + width: 20%; +} + +.system-network-table__icon-col { + max-width: 20%; + margin: 0 5px 0 auto !important; +} +</style> + +<style lang="scss" scoped> +.row { + align-items: baseline; + flex-wrap: nowrap; +} +.icon-expand { + margin: 0 !important; +} + +.pointer { + cursor: pointer; +} + +.close_icon { + margin-left: 5px; +} + +.form-control { + border: none; + max-height: 16px; + width: 60%; + border: none; + background-color: transparent; + &:focus { + box-shadow: none; + } +} +.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/SystemDescription/Network/InventoryIPv6Settings.vue b/src/views/SystemDescription/Network/InventoryIPv6Settings.vue new file mode 100644 index 00000000..4ff0897a --- /dev/null +++ b/src/views/SystemDescription/Network/InventoryIPv6Settings.vue @@ -0,0 +1,262 @@ +<template> + <page-section class="bootstrap-table__section"> + <b-table + responsive="md" + show-empty + class="bootstrap-rounded-table" + :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 && selectedCell === 'value'" + ref="input" + v-model="systems[data.index].value" + class="regular-12px" + type="text" + ></b-form-input> + <b-col v-else>{{ data.value }}</b-col> + <b-col class="system-network-table__icon-col"> + <b-row + v-if="systems[data.index].isEdit && selectedCell === 'value'" + > + <img + src="@/assets/images/edit-ok.svg" + class="system-network-table__icon pointer" + @click="clickOk" + /> + <img + src="@/assets/images/edit-no.svg" + class="system-network-table__icon close_icon pointer" + @click="clickCancel" + /> + </b-row> + <img + v-else + src="@/assets/images/icon-edit.svg" + class="system-network-table__icon pointer" + @click="editCellHandler(data, 'value')" + /> + </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="system-network-table__icon-col"> + <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, + isActive: false, + fields: [ + { + key: 'param', + label: 'Параметр', + formatter: this.dataFormatter, + thClass: 'semi-bold-12px__caps bootstrap-rounded-table__head_bg', + class: `bootstrap-rounded-table__column-first___ipv-table + bootstrap-rounded-table__column-first`, + tdClass: 'regular-12px bootstrap-rounded-table__td', + }, + { + key: 'value', + label: 'Значение', + formatter: this.dataFormatter, + thClass: 'semi-bold-12px__caps bootstrap-rounded-table__head_bg', + class: `bootstrap-rounded-table__column-center + bootstrap-rounded-table__ipv-table___center`, + tdClass: 'regular-12px bootstrap-rounded-table__td', + }, + { + key: 'comment', + label: 'Комментарий', + formatter: this.dataFormatter, + thClass: 'semi-bold-12px__caps bootstrap-rounded-table__head_bg', + class: 'bootstrap-rounded-table__column-last', + tdClass: 'regular-12px bootstrap-rounded-table__td', + }, + ], + 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', + }, + ], + }; + }, + mounted() { + this.systems = this.systems.map((item) => ({ ...item, isEdit: false })); + }, + methods: { + editCellHandler(data, value) { + this.systems = this.systems.map((item) => ({ ...item, isEdit: false })); + this.systems[data.index].isEdit = true; + this.selectedCell = value; + this.$nextTick(() => this.$refs.input.focus()); + }, + clickOk(data) { + this.selectedCell = null; + this.systems[data.index].value = this.$refs.input.value; + }, + clickCancel() { + this.selectedCell = null; + }, + 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; +} + +.edit { + cursor: pointer; +} + +.close_icon { + margin-left: 5px; +} + +.form-control { + border: none; + max-height: 16px; + width: 60%; + border: none; + background-color: transparent; + &:focus { + box-shadow: none; + } +} + +.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/SystemDescription/Network/SystemNetwork.vue b/src/views/SystemDescription/Network/SystemNetwork.vue new file mode 100644 index 00000000..4cf264cf --- /dev/null +++ b/src/views/SystemDescription/Network/SystemNetwork.vue @@ -0,0 +1,127 @@ +<template> + <b-container + :style="{ display: 'flex', 'flex-direction': 'column' }" + fluid="xxl pt-0 m-0" + > + <page-title /> + <!-- IPv4 --> + <div class="main-container"> + <div class="page-collapse-decorator"> + <b-button + v-b-toggle.toggle-collapse_1 + variant="link" + class="server-info-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="server-info-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> + <modal-user @hidden="activeUser = null" /> + </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; +} + +.server-info-collapse__button { + height: 56px; + width: 100%; + padding: 0 0 0 2rem; + margin: 0; + display: flex; + flex-flow: row nowrap; + justify-content: flex-start; + &:active, + &:focus { + box-shadow: none; + } + &:hover { + color: $text-primary; + } +} + +.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; +} + +.custom-checkbox ::before { + box-shadow: none !important; + border: 2px solid rgba(4, 10, 15, 0.6); + background-color: #fff; + border-radius: 3px; +} +</style> diff --git a/src/views/SystemDescription/Network/index.js b/src/views/SystemDescription/Network/index.js new file mode 100644 index 00000000..25f85f3c --- /dev/null +++ b/src/views/SystemDescription/Network/index.js @@ -0,0 +1,2 @@ +import SystemNetwork from './SystemNetwork.vue'; +export default SystemNetwork; diff --git a/src/views/SystemDescription/ServerParametrs/ServerParametrs.vue b/src/views/SystemDescription/ServerParametrs/ServerParametrs.vue new file mode 100644 index 00000000..bbc461eb --- /dev/null +++ b/src/views/SystemDescription/ServerParametrs/ServerParametrs.vue @@ -0,0 +1,23 @@ +<template> + <b-container + :style="{ display: 'flex', 'flex-direction': 'column' }" + fluid="xxl pt-0 m-0" + > + <page-title /> + <div class="main-container"> + <servere-parametrs-section /> + </div> + </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/SystemDescription/ServerParametrs/ServereParametrsSection.vue b/src/views/SystemDescription/ServerParametrs/ServereParametrsSection.vue new file mode 100644 index 00000000..e9868b05 --- /dev/null +++ b/src/views/SystemDescription/ServerParametrs/ServereParametrsSection.vue @@ -0,0 +1,169 @@ +<template> + <page-section class="bootstrap-table__section"> + <span class="bold-12px__caps"> + {{ $t('SystemDescription.LoadingQueue') }} + </span> + <b-table + responsive="md" + class="bootstrap-table bootstrap-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" + class="switch-input" + 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="bootstrap-table bootstrap-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, + thClass: 'bootstrap-table__head_bg', + class: 'bootstrap-table__column-first', + tdClass: 'regular-12px bootstrap-table__td', + }, + { + key: 'active', + label: '', + formatter: this.dataFormatter, + thClass: 'bootstrap-table__head_bg', + class: `bootstrap-table__column-last + bootstrap-table__server-param`, + tdClass: 'regular-12px bootstrap-table__td', + }, + ], + 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"> +.bootstrap-table__stripes tr:nth-of-type(even) { + background-color: rgb(255 255 255); +} + +.bootstrap-table__head_bg { + border-top: none; + display: none; +} + +.bootstrap-table__column-first { + border-right: 1px solid rgba(26, 62, 91, 0.1); + border-top: none; +} + +.bootstrap-table__column-last { + border-top: none; +} + +.bootstrap-table__td { + border-top: 1px solid rgba(26, 62, 91, 0.1); +} + +.bootstrap-table__server-param { + width: 30%; +} + +.system-network-table__icon-col { + max-width: 20%; + margin: 0 5px 0 auto !important; +} +</style> + +<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/SystemDescription/ServerParametrs/index.js b/src/views/SystemDescription/ServerParametrs/index.js new file mode 100644 index 00000000..5ce6ca74 --- /dev/null +++ b/src/views/SystemDescription/ServerParametrs/index.js @@ -0,0 +1,2 @@ +import ServerParametrs from './ServerParametrs.vue'; +export default ServerParametrs; diff --git a/src/views/SystemDescription/SystemEventLogs/SystemEventLogs.vue b/src/views/SystemDescription/SystemEventLogs/SystemEventLogs.vue new file mode 100644 index 00000000..e84d23db --- /dev/null +++ b/src/views/SystemDescription/SystemEventLogs/SystemEventLogs.vue @@ -0,0 +1,624 @@ +<template> + <b-container + :style="{ display: 'flex', 'flex-direction': 'column' }" + fluid="xxl pt-0 m-0" + > + <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('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"> + <table-date-filter @change="onChangeDateTimeFilter" /> + </b-col> + </b-row> + <b-row> + <b-col class="text-right"> + <table-filter :filters="tableFilters" @filter-change="onFilterChange" /> + <b-button + variant="link" + :disabled="allLogs.length === 0" + @click="deleteAllLogs" + > + <icon-delete /> {{ $t('global.action.deleteAll') }} + </b-button> + <b-button + variant="primary" + :class="{ disabled: allLogs.length === 0 }" + :download="exportFileNameByDate()" + :href="href" + > + <icon-export /> {{ $t('global.action.exportAll') }} + </b-button> + </b-col> + </b-row> + <b-row> + <b-col> + <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"> + {{ $t('pageEventLogs.resolve') }} + </b-button> + <b-button variant="primary" @click="unresolveLogs"> + {{ $t('pageEventLogs.unresolve') }} + </b-button> + <table-toolbar-export + :data="batchExportData" + :file-name="exportFileNameByDate()" + /> + </template> + </table-toolbar> + <b-table + id="table-event-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" + :sort-compare="onSortCompare" + :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="eventLogs-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="`eventLogs-checkbox-selectRow-${row.index}`" + @change="toggleSelectRow($refs.table, row.index)" + > + <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)" + > + <icon-chevron /> + </b-button> + </template> + + <template #row-details="{ item }"> + <b-container fluid> + <b-row> + <b-col> + <dl> + <!-- Name --> + <dt>{{ $t('pageEventLogs.table.name') }}:</dt> + <dd>{{ dataFormatter(item.name) }}</dd> + </dl> + <dl> + <!-- Type --> + <dt>{{ $t('pageEventLogs.table.type') }}:</dt> + <dd>{{ dataFormatter(item.type) }}</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 }} + </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 }} + </template> + <!-- Date column --> + <template #cell(date)="{ value }"> + <p class="mb-0">{{ value | formatDate }}</p> + <p class="mb-0">{{ value | formatTime }}</p> + </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"> + {{ $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> + </template> + </b-table> + </b-col> + </b-row> + + <!-- Table pagination --> + <b-row> + <b-col sm="6"> + <b-form-group + class="table-pagination-select" + :label="$t('global.table.itemsPerPage')" + label-for="pagination-items-per-page" + > + <b-form-select + id="pagination-items-per-page" + v-model="perPage" + :options="itemsPerPageOptions" + /> + </b-form-group> + </b-col> + <b-col sm="6"> + <b-pagination + v-model="currentPage" + first-number + last-number + :per-page="perPage" + :total-rows="getTotalRowCount(filteredRows)" + aria-controls="table-event-logs" + /> + </b-col> + </b-row> + </b-container> +</template> + +<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/Global/PageTitle'; +import StatusIcon from '@/components/Global/StatusIcon'; +import Search from '@/components/Global/Search'; +import TableCellCount from '@/components/Global/TableCellCount'; +import TableDateFilter from '@/components/Global/TableDateFilter'; +import TableFilter from '@/components/Global/TableFilter'; +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/Mixins/BVPaginationMixin'; +import BVTableSelectableMixin, { + selectedRows, + tableHeaderCheckboxModel, + tableHeaderCheckboxIndeterminate, +} from '@/components/Mixins/BVTableSelectableMixin'; +import BVToastMixin from '@/components/Mixins/BVToastMixin'; +import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin'; +import TableSortMixin from '@/components/Mixins/TableSortMixin'; +import TableRowExpandMixin, { + expandRowLabel, +} from '@/components/Mixins/TableRowExpandMixin'; +import SearchFilterMixin, { + searchFilter, +} from '@/components/Mixins/SearchFilterMixin'; + +export default { + components: { + IconDelete, + IconExport, + IconTrashcan, + IconChevron, + IconDownload, + PageTitle, + Search, + StatusIcon, + TableCellCount, + TableFilter, + TableRowAction, + TableToolbar, + TableToolbarExport, + TableDateFilter, + }, + mixins: [ + BVPaginationMixin, + BVTableSelectableMixin, + BVToastMixin, + LoadingBarMixin, + TableFilterMixin, + DataFormatterMixin, + TableSortMixin, + TableRowExpandMixin, + SearchFilterMixin, + ], + beforeRouteLeave(to, from, next) { + // Hide loader if the user navigates to another page + // before request is fulfilled. + this.hideLoader(); + next(); + }, + data() { + return { + isBusy: true, + fields: [ + { + key: 'expandRow', + label: '', + tdClass: 'table-row-expand', + }, + { + key: 'checkbox', + sortable: false, + }, + { + key: 'id', + label: this.$t('pageEventLogs.table.id'), + sortable: true, + }, + { + key: 'severity', + label: this.$t('pageEventLogs.table.severity'), + sortable: true, + tdClass: 'text-nowrap', + }, + { + key: 'date', + label: this.$t('pageEventLogs.table.date'), + sortable: true, + tdClass: 'text-nowrap', + }, + { + key: 'description', + label: this.$t('pageEventLogs.table.description'), + tdClass: 'text-break', + }, + { + key: 'status', + label: this.$t('pageEventLogs.table.status'), + }, + { + key: 'actions', + sortable: false, + label: '', + tdClass: 'text-right text-nowrap', + }, + ], + allLogs: [ + { + expandRow: 'expandRow', + checkbox: false, + id: 1, + severity: 'dfjgsdjlk', + date: '12-23-1220', + status: 'expandRow', + description: 'expandRow', + actions: [ + { + value: 'export', + title: this.$t('global.action.export'), + }, + { + value: 'delete', + title: this.$t('global.action.delete'), + }, + ], + }, + ], + tableFilters: [ + { + key: 'severity', + label: this.$t('pageEventLogs.table.severity'), + values: ['OK', 'Warning', 'Critical'], + }, + { + key: 'filterByStatus', + label: this.$t('pageEventLogs.table.status'), + values: ['Resolved', 'Unresolved'], + }, + ], + expandRowLabel, + activeFilters: [], + batchActions: [ + { + value: 'delete', + label: this.$t('global.action.delete'), + }, + ], + currentPage: currentPage, + filterStartDate: null, + filterEndDate: null, + itemsPerPageOptions: itemsPerPageOptions, + perPage: perPage, + searchFilter: searchFilter, + searchTotalFilteredRows: 0, + selectedRows: selectedRows, + tableHeaderCheckboxModel: tableHeaderCheckboxModel, + tableHeaderCheckboxIndeterminate: tableHeaderCheckboxIndeterminate, + }; + }, + computed: { + href() { + return `data:text/json;charset=utf-8,${this.exportAllLogs()}`; + }, + filteredRows() { + return this.searchFilter + ? this.searchTotalFilteredRows + : this.filteredLogs.length; + }, + // allLogs() { + // return this.$store.getters['eventLog/allEvents'].map((event) => { + // return { + // ...event, + // actions: [ + // { + // value: 'export', + // title: this.$t('global.action.export'), + // }, + // { + // value: 'delete', + // title: this.$t('global.action.delete'), + // }, + // ], + // }; + // }); + // }, + batchExportData() { + return this.selectedRows.map((row) => omit(row, 'actions')); + }, + filteredLogsByDate() { + return this.getFilteredTableDataByDate( + this.allLogs, + this.filterStartDate, + this.filterEndDate + ); + }, + filteredLogs() { + return this.getFilteredTableData( + this.filteredLogsByDate, + this.activeFilters + ); + }, + }, + created() { + this.startLoader(); + this.$store.dispatch('eventLog/getEventLogData').finally(() => { + this.endLoader(); + this.isBusy = false; + }); + }, + methods: { + changelogStatus(row) { + this.$store + .dispatch('eventLog/updateEventLogStatus', { + uri: row.uri, + status: row.status, + }) + .then((success) => { + this.successToast(success); + }) + .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)); + } + }); + }, + deleteLogs(uris) { + this.$store + .dispatch('eventLog/deleteEventLogs', uris) + .then((messages) => { + messages.forEach(({ type, message }) => { + if (type === 'success') { + this.successToast(message); + } else if (type === 'error') { + this.errorToast(message); + } + }); + }); + }, + exportAllLogs() { + { + return this.$store.getters['eventLog/allEvents'].map((eventLogs) => { + const allEventLogsString = JSON.stringify(eventLogs); + return allEventLogsString; + }); + } + }, + onFilterChange({ activeFilters }) { + this.activeFilters = activeFilters; + }, + onSortCompare(a, b, key) { + if (key === 'severity') { + return this.sortStatus(a, b, key); + } + }, + onTableRowAction(action, { uri }) { + if (action === 'delete') { + this.$bvModal + .msgBoxConfirm(this.$tc('pageEventLogs.modal.deleteMessage'), { + title: this.$tc('pageEventLogs.modal.deleteTitle'), + okTitle: this.$t('global.action.delete'), + cancelTitle: this.$t('global.action.cancel'), + }) + .then((deleteConfirmed) => { + if (deleteConfirmed) this.deleteLogs([uri]); + }); + } + }, + onBatchAction(action) { + if (action === 'delete') { + const uris = this.selectedRows.map((row) => row.uri); + this.$bvModal + .msgBoxConfirm( + this.$tc( + 'pageEventLogs.modal.deleteMessage', + this.selectedRows.length + ), + { + title: this.$tc( + 'pageEventLogs.modal.deleteTitle', + this.selectedRows.length + ), + okTitle: this.$t('global.action.delete'), + cancelTitle: this.$t('global.action.cancel'), + } + ) + .then((deleteConfirmed) => { + if (deleteConfirmed) { + if (this.selectedRows.length === this.allLogs.length) { + this.$store + .dispatch( + 'eventLog/deleteAllEventLogs', + this.selectedRows.length + ) + .then((message) => this.successToast(message)) + .catch(({ message }) => this.errorToast(message)); + } else { + this.deleteLogs(uris); + } + } + }); + } + }, + onChangeDateTimeFilter({ fromDate, toDate }) { + this.filterStartDate = fromDate; + this.filterEndDate = toDate; + }, + onFiltered(filteredItems) { + this.searchTotalFilteredRows = filteredItems.length; + }, + // Create export file name based on date + exportFileNameByDate(value) { + let date = new Date(); + date = + date.toISOString().slice(0, 10) + + '_' + + date.toString().split(':').join('-').split(' ')[4]; + let fileName; + if (value === 'export') { + fileName = 'event_log_'; + } else { + fileName = 'all_event_logs_'; + } + return fileName + date; + }, + resolveLogs() { + this.$store + .dispatch('eventLog/resolveEventLogs', this.selectedRows) + .then((messages) => { + messages.forEach(({ type, message }) => { + if (type === 'success') { + this.successToast(message); + } else if (type === 'error') { + this.errorToast(message); + } + }); + }); + }, + unresolveLogs() { + this.$store + .dispatch('eventLog/unresolveEventLogs', this.selectedRows) + .then((messages) => { + messages.forEach(({ type, message }) => { + if (type === 'success') { + this.successToast(message); + } else if (type === 'error') { + this.errorToast(message); + } + }); + }); + }, + }, +}; +</script> diff --git a/src/views/SystemDescription/SystemEventLogs/index.js b/src/views/SystemDescription/SystemEventLogs/index.js new file mode 100644 index 00000000..abe245ae --- /dev/null +++ b/src/views/SystemDescription/SystemEventLogs/index.js @@ -0,0 +1,2 @@ +import SystemEventLogs from './SystemEventLogs.vue'; +export default SystemEventLogs; |