summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitalii Lysak <v.lysak@dunice.net>2022-09-20 13:35:38 +0300
committerVitalii Lysak <v.lysak@dunice.net>2022-09-20 13:35:38 +0300
commit4d04ae12f310f1bccf1270f1d3a4090b888ecf6e (patch)
tree793e75c70b133a1ddf2dbfe56134ef869ca7fc62
parentab93e8470ddb49f4a522446dfb9c7882ff37daaf (diff)
parent37f6f72ff1ed6d4795c3f67ca2ba92367582e562 (diff)
downloadwebui-vue-4d04ae12f310f1bccf1270f1d3a4090b888ecf6e.tar.xz
merge smtp, snmp, syslog
-rw-r--r--src/assets/styles/bmc/_sila/_modal.scss2
-rw-r--r--src/env/components/AppNavigation/sila.js5
-rw-r--r--src/env/router/sila.js9
-rw-r--r--src/locales/en-US.json31
-rw-r--r--src/locales/ru-RU.json45
-rw-r--r--src/store/index.js6
-rw-r--r--src/store/modules/Settings/SmtpStore.js100
-rw-r--r--src/store/modules/Settings/SnmpStore.js73
-rw-r--r--src/store/modules/Settings/SyslogStore.js36
-rw-r--r--src/views/_sila/Overview/Overview.vue10
-rw-r--r--src/views/_sila/Settings/TransferInfo/ModalSmtp.vue98
-rw-r--r--src/views/_sila/Settings/TransferInfo/ModalSnmp.vue136
-rw-r--r--src/views/_sila/Settings/TransferInfo/Smtp.vue414
-rw-r--r--src/views/_sila/Settings/TransferInfo/Snmp.vue139
-rw-r--r--src/views/_sila/Settings/TransferInfo/Syslog.vue220
-rw-r--r--src/views/_sila/Settings/TransferInfo/Transfer.vue64
-rw-r--r--src/views/_sila/Settings/TransferInfo/WarningSmnp.vue57
-rw-r--r--src/views/_sila/Settings/TransferInfo/index.js2
18 files changed, 1447 insertions, 0 deletions
diff --git a/src/assets/styles/bmc/_sila/_modal.scss b/src/assets/styles/bmc/_sila/_modal.scss
index 79f8313b..e67cb777 100644
--- a/src/assets/styles/bmc/_sila/_modal.scss
+++ b/src/assets/styles/bmc/_sila/_modal.scss
@@ -67,6 +67,8 @@
#modal-ssh,
#modal-ipmi,
+#modal-smtp,
+#modal-snmp,
#modal-dns,
#modal-hostname,
#modal-mac-address,
diff --git a/src/env/components/AppNavigation/sila.js b/src/env/components/AppNavigation/sila.js
index b7b1ca5a..ee3cb840 100644
--- a/src/env/components/AppNavigation/sila.js
+++ b/src/env/components/AppNavigation/sila.js
@@ -181,6 +181,11 @@ const AppNavigationMixin = {
label: this.$t('appNavigation.powerRestorePolicy'),
route: '/settings/power-restore-policy',
},
+ {
+ id: 'settings/transfer',
+ label: this.$t('appPageTitle.transfer'),
+ route: '/settings/transfer',
+ },
],
},
{
diff --git a/src/env/router/sila.js b/src/env/router/sila.js
index 9a3fbc1e..8ba9585f 100644
--- a/src/env/router/sila.js
+++ b/src/env/router/sila.js
@@ -36,6 +36,7 @@ import FansDynamic from '@/views/_sila/Fans/Dynamic';
import MotherboardDynamic from '@/views/_sila/Motherboard/Dynamic';
import PowerStatic from '@/views/_sila/Power/Static';
import PowerDynamic from '@/views/_sila/Power/Dynamic';
+import TransferInfo from '@/views/_sila/Settings/TransferInfo';
import i18n from '@/i18n';
@@ -280,6 +281,14 @@ const routes = [
},
},
{
+ path: '/settings/transfer',
+ name: 'transfer',
+ component: TransferInfo,
+ meta: {
+ title: i18n.t('appPageTitle.transfer'),
+ },
+ },
+ {
path: '/resource-management/power',
name: 'power',
component: Power,
diff --git a/src/locales/en-US.json b/src/locales/en-US.json
index fc6d7bd3..4f95af69 100644
--- a/src/locales/en-US.json
+++ b/src/locales/en-US.json
@@ -209,6 +209,7 @@
"virtualMedia": "Virtual media",
"keyClear": "Key clear",
"specification": "Specification",
+ "transfer": "Communication settings",
"pciDevices": "PCI-devices"
},
"pageChangePassword": {
@@ -1150,6 +1151,36 @@
"deviceClass": "Device Class"
}
},
+ "pageTransfer": {
+ "title": "Setting up information transfer",
+ "description": "Set up SNMP, SMTP and SYSLOG",
+ "saveSmtpSuсcess": "Save SMTP successfully.",
+ "saveSmtpError": "Save SMTP error.",
+ "smtp": {
+ "smtpTitle": "Warning SMTP",
+ "username": "Username",
+ "password": "Password",
+ "host": "SMTP server",
+ "port": "SMTP port",
+ "authorization": "Authorization",
+ "sslEnabled": "SSL Support",
+ "testMessage": "Test message"
+ },
+ "snmp": {
+ "snmpTitle": "SNMP settings",
+ "host": "SNMP server",
+ "port": "SNMP port",
+ "saveSubscriberSuсcess": "Subscriber added successfully",
+ "deleteSubscriberSuсcess": "Subscriber deleted successfully",
+ "saveSubscriberError": "Error adding subscriber",
+ "deleteSubscriberError": "Subscriber deletion error",
+ "delSubscriber": "Delete Subscriber"
+ },
+ "table": {
+ "userName": "User name",
+ "value": "Value"
+ }
+ },
"countries": {
"AF": "Afghanistan",
"AL": "Albania",
diff --git a/src/locales/ru-RU.json b/src/locales/ru-RU.json
index 8bf5e8af..5188a898 100644
--- a/src/locales/ru-RU.json
+++ b/src/locales/ru-RU.json
@@ -209,6 +209,7 @@
"virtualMedia": "Виртуальные носители",
"keyClear": "Удаление ключей",
"specification": "Характеристики",
+ "transfer": "Настройки передачи информации",
"pciDevices": "PCI-устройства"
},
"pageChangePassword": {
@@ -1151,6 +1152,50 @@
"deviceClass": "Класс девайса"
}
},
+ "pageTransfer": {
+ "title": "Настройка передачи информации",
+ "description": "Настройте SNMP, SMTP и SYSLOG",
+ "saveSmtpSuсcess": "Настройки SMTP успешно сохранены.",
+ "saveSmtpError": "Ошибка сохранения настроек SMTP.",
+ "smtp": {
+ "smtpTitle": "Настройки SMTP",
+ "username": "Имя пользователя",
+ "password": "Пароль",
+ "email": "Email",
+ "host": "SMTP сервер",
+ "port": "SMTP порт",
+ "authorization": "Авторизация",
+ "sslEnabled": "Поддержка SSL",
+ "testMessage": "Тестовое сообщение",
+ "saveSubscriberSuсcess": "Подписчик успешно добавлен",
+ "deleteSubscriberSuсcess": "Подписчик успешно удален",
+ "saveSubscriberError": "Ошибка добавления подписчика",
+ "deleteSubscriberError": "Ошибка удаления подписчика",
+ "delSubscriber": "Удалить подписчика"
+ },
+ "snmp": {
+ "snmpTitle": "Настройки SNMP",
+ "host": "SNMP сервер",
+ "port": "SNMP порт",
+ "saveSubscriberSuсcess": "Подписчик успешно добавлен",
+ "deleteSubscriberSuсcess": "Подписчик успешно удален",
+ "saveSubscriberError": "Ошибка добавления подписчика",
+ "deleteSubscriberError": "Ошибка удаления подписчика",
+ "delSubscriber": "Удалить подписчика"
+ },
+ "syslog": {
+ "title": "Настройки SYSLOG",
+ "ip": "IP-адрес syslog сервера",
+ "port": "Syslog - порт",
+ "saveSettingsSuсcess": "Настройки успешно сохранены",
+ "saveSettingsError": "Ошибка сохранения настроек",
+ "status": "Статус"
+ },
+ "table": {
+ "userName": "Имя пользователя",
+ "value": "Значение"
+ }
+ },
"countries": {
"AF": "Афганистан",
"AL": "Албания",
diff --git a/src/store/index.js b/src/store/index.js
index a4dd16ed..a9afa310 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -30,6 +30,9 @@ import PoliciesStore from './modules/SecurityAndAccess/PoliciesStore';
import FactoryResetStore from './modules/Operations/FactoryResetStore';
import KeyClearStore from './modules/Operations/KeyClearStore';
import PciStore from './modules/HardwareStatus/PciStore';
+import SmtpStore from './modules/Settings/SmtpStore';
+import SnmpStore from './modules/Settings/SnmpStore';
+import SyslogStore from './modules/Settings/SyslogStore';
import WebSocketPlugin from './plugins/WebSocketPlugin';
import DateTimeStore from './modules/Settings/DateTimeStore';
@@ -73,6 +76,9 @@ export default new Vuex.Store({
factoryReset: FactoryResetStore,
keyClear: KeyClearStore,
pciStore: PciStore,
+ smtpStore: SmtpStore,
+ snmpStore: SnmpStore,
+ syslogStore: SyslogStore,
},
plugins: [WebSocketPlugin],
});
diff --git a/src/store/modules/Settings/SmtpStore.js b/src/store/modules/Settings/SmtpStore.js
new file mode 100644
index 00000000..195f245a
--- /dev/null
+++ b/src/store/modules/Settings/SmtpStore.js
@@ -0,0 +1,100 @@
+import api from '@/store/api';
+import i18n from '@/i18n';
+
+const SmtpStore = {
+ namespaced: true,
+ state: {
+ settings: {},
+ subscribers: [],
+ },
+ getters: {
+ settings: (state) => state.settings,
+ subscribers: (state) => state.subscribers,
+ },
+ mutations: {
+ saveSettings: (state, data) => (state.settings = data),
+ setSubscribers: (state, data) => (state.subscribers = data),
+ },
+ actions: {
+ async deleteSubscriber({ dispatch }, email) {
+ return await api
+ .get(`/redfish/v1/Smtp/DeleteMails&${email}`)
+ .then(async () => {
+ await dispatch('getSubscribers');
+ return i18n.t('pageTransfer.smtp.deleteSubscriberSuсcess');
+ })
+ .catch((error) => {
+ console.log(error);
+ throw new Error(i18n.t('pageTransfer.smtp.deleteSubscriberError'));
+ });
+ },
+
+ async addSubscriber({ dispatch }, payload) {
+ return await api
+ .get(`/redfish/v1/Smtp/AddMails&${payload.email}`)
+ .then(async () => {
+ await dispatch('getSubscribers');
+ return i18n.t('pageTransfer.smtp.saveSubscriberSuсcess');
+ })
+ .catch((error) => {
+ console.log(error);
+ throw new Error(i18n.t('pageTransfer.smtp.saveSubscriberError'));
+ });
+ },
+
+ async getSubscribers({ commit }) {
+ return await api
+ .get('/redfish/v1/Smtp/GetMails')
+ .then(({ data: { mails = [] } = {} }) =>
+ mails.map((host) => {
+ return {
+ host,
+ };
+ })
+ )
+ .then((subscribers) => commit('setSubscribers', subscribers))
+ .catch((error) => {
+ console.log(error);
+ throw new Error(i18n.t('pageUserManagement.toast.errorLoadUsers'));
+ });
+ },
+
+ async setSettings({ dispatch }, payload) {
+ let url = `/redfish/v1/Smtp/SetSettings`;
+ for (let key in payload) {
+ url += `&${key}=${payload[key]}`;
+ }
+
+ return await api
+ .get(url)
+ .then(async () => {
+ await dispatch('getSettings');
+ return i18n.t('pageTransfer.saveSmtpSuсcess');
+ })
+ .catch((error) => {
+ console.log(error);
+ throw new Error(i18n.t('pageTransfer.saveSmtpError'));
+ });
+ },
+
+ async getSettings({ commit }) {
+ return await api
+ .get('/redfish/v1/Smtp/GetSettings')
+ .then(({ data = {} }) => {
+ commit('saveSettings', data);
+ })
+ .catch((error) => console.log(error));
+ },
+
+ async sendTestMessage(_, payload) {
+ let url = `/redfish/v1/Smtp/SendMail`;
+ for (let key in payload) {
+ url += `&${key}=${payload[key]}`;
+ }
+
+ return await api.get(url);
+ },
+ },
+};
+
+export default SmtpStore;
diff --git a/src/store/modules/Settings/SnmpStore.js b/src/store/modules/Settings/SnmpStore.js
new file mode 100644
index 00000000..3fda494f
--- /dev/null
+++ b/src/store/modules/Settings/SnmpStore.js
@@ -0,0 +1,73 @@
+import api from '@/store/api';
+import i18n from '@/i18n';
+
+const SnmpStore = {
+ namespaced: true,
+ state: { subscribers: [] },
+ getters: { subscribers: (state) => state.subscribers },
+ mutations: {
+ setSubscribers: (state, data) => (state.subscribers = data),
+ },
+ actions: {
+ async deleteSubscriber({ dispatch }, index) {
+ return await api
+ .delete(`/redfish/v1/EventService/Subscriptions/${index}`)
+ .then(async () => {
+ await dispatch('getSubscribers');
+ return i18n.t('pageTransfer.snmp.deleteSubscriberSuсcess');
+ })
+ .catch((error) => {
+ console.log(error);
+ throw new Error(i18n.t('pageTransfer.snmp.deleteSubscriberError'));
+ });
+ },
+ async addSubscriber({ dispatch }, payload) {
+ return await api
+ .post('/redfish/v1/EventService/Subscriptions', payload)
+ .then(async () => {
+ await dispatch('getSubscribers');
+ return i18n.t('pageTransfer.snmp.saveSubscriberSuсcess');
+ })
+ .catch((error) => {
+ console.log(error);
+ throw new Error(i18n.t('pageTransfer.snmp.saveSubscriberError'));
+ });
+ },
+ async getSubscribers({ commit }) {
+ return await api
+ .get('/redfish/v1/EventService/Subscriptions')
+ .then(({ data: { Members } }) => {
+ return Members.filter((member) =>
+ member['@odata.id'].includes('snmp')
+ );
+ })
+ .then((members) => {
+ return api.all(members.map((member) => api.get(member['@odata.id'])));
+ })
+ .then((subscribersRow) => {
+ return subscribersRow.map((subscriberRow) => {
+ return subscriberRow.data;
+ });
+ })
+ .then((data) => {
+ return data.map((subscriber) => {
+ const host = subscriber.Destination.split('/')[2].split(':')[0];
+ const port = subscriber.Destination.split('/')[2].split(':')[1];
+ return {
+ ...subscriber,
+ host,
+ port,
+ };
+ });
+ })
+ .then((subscribers) => commit('setSubscribers', subscribers))
+ .catch((error) => {
+ console.log(error);
+ const message = i18n.t('pageUserManagement.toast.errorLoadUsers');
+ throw new Error(message);
+ });
+ },
+ },
+};
+
+export default SnmpStore;
diff --git a/src/store/modules/Settings/SyslogStore.js b/src/store/modules/Settings/SyslogStore.js
new file mode 100644
index 00000000..f0b0eb59
--- /dev/null
+++ b/src/store/modules/Settings/SyslogStore.js
@@ -0,0 +1,36 @@
+import api from '@/store/api';
+import i18n from '@/i18n';
+
+const SyslogStore = {
+ namespaced: true,
+ state: { settings: {} },
+ getters: { settings: (state) => state.settings },
+ mutations: {
+ saveSettings: (state, data) => (state.settings = data),
+ },
+ actions: {
+ async saveSettings({ dispatch }, payload) {
+ return await api
+ .post('/redfish/v1/Syslog/Actions/Syslog.UpdateConfig', payload)
+ .then(async () => {
+ await dispatch('getSettings');
+ return i18n.t('pageTransfer.syslog.saveSettingsSuсcess');
+ })
+ .catch((error) => {
+ console.log(error);
+ throw new Error(i18n.t('pageTransfer.syslog.saveSettingsError'));
+ });
+ },
+
+ async getSettings({ commit }) {
+ return await api
+ .get('/redfish/v1/Syslog')
+ .then(({ data: { Configuration = {} } = {} }) => {
+ commit('saveSettings', Configuration);
+ })
+ .catch((error) => console.log(error));
+ },
+ },
+};
+
+export default SyslogStore;
diff --git a/src/views/_sila/Overview/Overview.vue b/src/views/_sila/Overview/Overview.vue
index 9f97fb3e..c3928789 100644
--- a/src/views/_sila/Overview/Overview.vue
+++ b/src/views/_sila/Overview/Overview.vue
@@ -5,6 +5,16 @@
<page-section
:section-title="$t('pageOverview.systemInformation')"
class="mb-1"
+ @overviewEventsComplete="
+ () => {
+ console.log('как подключить веб камеру к ноутбуку');
+ }
+ "
+ @overview-firmware-complete="
+ () => {
+ console.log('как подключить веб камеру к ноутбуку');
+ }
+ "
>
<b-card-group deck>
<overview-server />
diff --git a/src/views/_sila/Settings/TransferInfo/ModalSmtp.vue b/src/views/_sila/Settings/TransferInfo/ModalSmtp.vue
new file mode 100644
index 00000000..c3bdc493
--- /dev/null
+++ b/src/views/_sila/Settings/TransferInfo/ModalSmtp.vue
@@ -0,0 +1,98 @@
+<template>
+ <b-modal
+ id="modal-smtp"
+ ref="modal"
+ :title="$t('global.action.add')"
+ @hidden="resetForm"
+ >
+ <b-form id="form-smtp" @submit.prevent="handleSubmit">
+ <b-row>
+ <b-col sm="6">
+ <b-form-group
+ :label="$t('pageTransfer.smtp.email')"
+ label-for="smtpEmail"
+ >
+ <b-form-input
+ id="smtpEmail"
+ v-model="email"
+ type="text"
+ :state="getValidationState($v.email)"
+ data-test-id="smtp-input-email"
+ @input="$v.email.$touch()"
+ />
+ <b-form-invalid-feedback role="alert">
+ <template v-if="!$v.email.required">
+ {{ $t('global.form.fieldRequired') }}
+ </template>
+ <template v-if="!$v.email.email">
+ {{ $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-smtp" type="submit" variant="primary" @click="onOk">
+ {{ $t('global.action.add') }}
+ </b-button>
+ </template>
+ </b-modal>
+</template>
+
+<script>
+import VuelidateMixin from '@/components/_sila/Mixins/VuelidateMixin.js';
+import { email, required } from 'vuelidate/lib/validators';
+
+export default {
+ mixins: [VuelidateMixin],
+ data() {
+ return {
+ email: null,
+ };
+ },
+ validations() {
+ return {
+ email: {
+ required,
+ email,
+ },
+ };
+ },
+ methods: {
+ handleSubmit() {
+ this.$v.$touch();
+ if (this.$v.$invalid) return;
+
+ this.$emit('ok', {
+ email: this.email,
+ });
+ this.closeModal();
+ },
+ closeModal() {
+ this.$nextTick(() => {
+ this.$refs.modal.hide();
+ });
+ },
+ resetForm() {
+ this.email = null;
+ this.$v.$reset();
+ this.$emit('hidden');
+ },
+ onOk(bvModalEvt) {
+ // prevent modal close
+ bvModalEvt.preventDefault();
+ this.handleSubmit();
+ },
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+.input-group-prepend + input {
+ padding-left: 70px !important;
+}
+</style>
diff --git a/src/views/_sila/Settings/TransferInfo/ModalSnmp.vue b/src/views/_sila/Settings/TransferInfo/ModalSnmp.vue
new file mode 100644
index 00000000..c54616a5
--- /dev/null
+++ b/src/views/_sila/Settings/TransferInfo/ModalSnmp.vue
@@ -0,0 +1,136 @@
+<template>
+ <b-modal
+ id="modal-snmp"
+ ref="modal"
+ :title="$t('global.action.add')"
+ @hidden="resetForm"
+ >
+ <b-form id="form-snmp" @submit.prevent="handleSubmit">
+ <b-row>
+ <b-col sm="6">
+ <b-form-group
+ :label="$t('pageTransfer.snmp.host')"
+ label-for="snmpHost"
+ >
+ <b-form-input
+ id="snmpHost"
+ v-model="host"
+ type="text"
+ :state="getValidationState($v.host)"
+ data-test-id="snmp-input-host"
+ @input="$v.host.$touch()"
+ />
+ <b-form-invalid-feedback role="alert">
+ <template v-if="!$v.host.required">
+ {{ $t('global.form.fieldRequired') }}
+ </template>
+ <template v-if="!$v.host.ipAddress">
+ {{ $t('global.form.invalidFormat') }}
+ </template>
+ </b-form-invalid-feedback>
+ </b-form-group>
+ </b-col>
+ <b-col sm="6">
+ <b-form-group
+ :label="$t('pageTransfer.snmp.port')"
+ label-for="snmpPort"
+ >
+ <b-form-input
+ id="snmpPort"
+ v-model="port"
+ type="number"
+ :state="getValidationState($v.port)"
+ data-test-id="snmp-input-port"
+ @input="$v.port.$touch()"
+ />
+ <b-form-invalid-feedback role="alert">
+ <template v-if="!$v.port.required">
+ {{ $t('global.form.fieldRequired') }}
+ </template>
+ <template v-if="!$v.port.pattern">
+ {{ $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-snmp" type="submit" variant="primary" @click="onOk">
+ {{ $t('global.action.add') }}
+ </b-button>
+ </template>
+ </b-modal>
+</template>
+
+<script>
+import VuelidateMixin from '@/components/_sila/Mixins/VuelidateMixin.js';
+import { helpers, ipAddress, required } from 'vuelidate/lib/validators';
+import { isoPortRegex } from '@/utilities/_sila/regexConstants';
+
+export default {
+ mixins: [VuelidateMixin],
+ data() {
+ return {
+ form: {
+ Destination: null,
+ SubscriptionType: 'SNMPTrap',
+ Protocol: 'SNMPv2c',
+ Context: 'testContext',
+ },
+ host: null,
+ port: null,
+ };
+ },
+ validations() {
+ return {
+ host: {
+ required,
+ ipAddress,
+ },
+ port: {
+ required,
+ pattern: helpers.regex('pattern', isoPortRegex),
+ },
+ };
+ },
+ methods: {
+ handleSubmit() {
+ this.$v.$touch();
+ if (this.$v.$invalid) return;
+
+ this.$emit('ok', {
+ ...this.form,
+ Destination: `snmp://${this.host}:${this.port}`,
+ });
+ this.closeModal();
+ },
+ closeModal() {
+ this.$nextTick(() => {
+ this.$refs.modal.hide();
+ });
+ },
+ resetForm() {
+ this.host = null;
+ this.port = null;
+ this.form.Destination = null;
+ this.$v.$reset();
+ this.$emit('hidden');
+ },
+ onOk(bvModalEvt) {
+ // prevent modal close
+ bvModalEvt.preventDefault();
+ this.handleSubmit();
+ },
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+.input-group-prepend + input {
+ padding-left: 70px !important;
+}
+</style>
diff --git a/src/views/_sila/Settings/TransferInfo/Smtp.vue b/src/views/_sila/Settings/TransferInfo/Smtp.vue
new file mode 100644
index 00000000..40a182d8
--- /dev/null
+++ b/src/views/_sila/Settings/TransferInfo/Smtp.vue
@@ -0,0 +1,414 @@
+<template>
+ <page-section :section-title="$t('pageTransfer.smtp.smtpTitle')">
+ <b-row class="smtp-warning mb-5">
+ <b-col xs="12" sm="12">
+ <div class="switch-group">
+ <label for="authenticationSwitch">{{
+ $t('pageTransfer.smtp.authorization')
+ }}</label>
+ <b-form-checkbox
+ id="authenticationSwitch"
+ v-model="form.is_need_auth"
+ data-test-id="checkbox-authorization"
+ switch
+ :disabled="loading || isNotAdmin"
+ @change="onChangeAuthCheckbox($event)"
+ >
+ <span v-if="form.is_need_auth">
+ {{ $t('global.status.enabled') }}
+ </span>
+ <span v-else>{{ $t('global.status.disabled') }}</span>
+ </b-form-checkbox>
+ </div>
+ </b-col>
+ <b-col xs="12" sm="6">
+ <b-form-group
+ :label="$t('pageTransfer.smtp.username')"
+ label-for="smtp-name"
+ >
+ <b-form-input
+ id="smtp-name"
+ v-model="form.username"
+ type="text"
+ :state="getValidationState($v.form.username)"
+ :disabled="loading || isNotAdmin || !form.is_need_auth"
+ @input="$v.form.username.$touch()"
+ />
+ <b-form-invalid-feedback role="alert">
+ <template v-if="!$v.form.username.required">
+ {{ $t('global.form.fieldRequired') }}
+ </template>
+ <template v-else-if="!$v.form.username.maxLength">
+ {{ $t('global.form.lengthMustBeBetween', { min: 1, max: 16 }) }}
+ </template>
+ <template v-else-if="!$v.form.username.pattern">
+ {{ $t('global.form.invalidFormat') }}
+ </template>
+ </b-form-invalid-feedback>
+ </b-form-group></b-col
+ >
+ <b-col xs="12" sm="6">
+ <b-form-group
+ :label="$t('pageTransfer.smtp.password')"
+ label-for="smtp-password"
+ >
+ <input-password-toggle>
+ <b-form-input
+ id="smtp-password"
+ v-model="form.password"
+ type="password"
+ :state="getValidationState($v.form.password)"
+ :disabled="loading || isNotAdmin || !form.is_need_auth"
+ @input="$v.form.password.$touch()"
+ />
+ <b-form-invalid-feedback role="alert">
+ <template v-if="!$v.form.password.required">
+ {{ $t('global.form.fieldRequired') }}
+ </template>
+ <template
+ v-if="
+ !$v.form.password.minLength || !$v.form.password.maxLength
+ "
+ >
+ {{
+ $t('pageUserManagement.modal.passwordMustBeBetween', {
+ min: 8,
+ max: 20,
+ })
+ }}
+ </template>
+ </b-form-invalid-feedback>
+ </input-password-toggle>
+ </b-form-group>
+ </b-col>
+ <b-col xs="12" sm="6">
+ <b-form-group
+ :label="$t('pageTransfer.smtp.host')"
+ label-for="smtp-host"
+ >
+ <b-form-input
+ id="smtp-host"
+ v-model="form.host"
+ :state="getValidationState($v.form.host)"
+ :disabled="loading || isNotAdmin"
+ @input="$v.form.host.$touch()"
+ />
+ <b-form-invalid-feedback role="alert">
+ <template v-if="!$v.form.host.required">
+ {{ $t('global.form.fieldRequired') }}
+ </template>
+ <template v-if="!$v.form.host.ipAddress">
+ {{ $t('global.form.invalidFormat') }}
+ </template>
+ </b-form-invalid-feedback>
+ </b-form-group>
+ </b-col>
+ <b-col xs="12" sm="6">
+ <b-form-group
+ :label="$t('pageTransfer.smtp.port')"
+ label-for="smtp-port"
+ >
+ <b-form-input
+ id="smtp-port"
+ v-model="form.port"
+ type="number"
+ :state="getValidationState($v.form.port)"
+ :disabled="loading || isNotAdmin"
+ @input="$v.form.port.$touch()"
+ />
+ <b-form-invalid-feedback role="alert">
+ <template v-if="!$v.form.port.required">
+ {{ $t('global.form.fieldRequired') }}
+ </template>
+ <template v-if="!$v.form.port.pattern">
+ {{ $t('global.form.invalidFormat') }}
+ </template>
+ </b-form-invalid-feedback>
+ </b-form-group>
+ </b-col>
+ <b-col xs="12" sm="12">
+ <div class="switch-group">
+ <label for="sslSwitch">{{
+ $t('pageTransfer.smtp.sslEnabled')
+ }}</label>
+ <b-form-checkbox
+ id="sslSwitch"
+ v-model="form.is_need_ssl"
+ data-test-id="checkbox-ssl"
+ switch
+ :disabled="isNotAdmin"
+ >
+ <span v-if="form.is_need_ssl">
+ {{ $t('global.status.enabled') }}
+ </span>
+ <span v-else>{{ $t('global.status.disabled') }}</span>
+ </b-form-checkbox>
+ </div>
+ </b-col>
+ <b-col xs="4" class="d-flex justify-content-between align-items-start">
+ <b-button
+ variant="secondary"
+ :disabled="loading || isNotAdmin"
+ @click="sendMail"
+ >
+ {{ $t('pageTransfer.smtp.testMessage') }}
+ </b-button>
+
+ <b-button
+ variant="primary"
+ :disabled="loading || isNotAdmin"
+ @click="saveSmtp"
+ >
+ {{ $t('global.action.save') }}
+ </b-button>
+ </b-col>
+ </b-row>
+ <b-row>
+ <b-col>
+ <div class="text-right">
+ <b-button
+ variant="primary"
+ :disabled="loading || isNotAdmin"
+ @click="initAddModal()"
+ >
+ <icon-add />
+ {{ $t('global.action.add') }}
+ </b-button>
+ </div>
+ <b-table
+ responsive="md"
+ hover
+ :busy="loading"
+ :fields="fields"
+ :items="subscribers"
+ :empty-text="$t('global.table.emptyMessage')"
+ show-empty
+ >
+ <!-- table actions column -->
+ <template #cell(actions)="{ item }">
+ <table-row-action
+ v-for="(action, index) in item.actions"
+ :key="index"
+ :value="action.value"
+ :enabled="action.enabled"
+ :title="action.title"
+ @click-table-action="onTableAction($event, item)"
+ >
+ <template #icon>
+ <icon-trashcan
+ v-if="action.value === 'delete'"
+ :data-test-id="`smtp-tableRowAction-delete-${index}`"
+ />
+ </template>
+ </table-row-action>
+ </template>
+ </b-table>
+ </b-col>
+ </b-row>
+ </page-section>
+</template>
+
+<script>
+import PageSection from '@/components/_sila/Global/PageSection';
+import BVToastMixin from '@/components/_sila/Mixins/BVToastMixin';
+import TableRowAction from '@/components/_sila/Global/TableRowAction';
+import LoadingBarMixin, {
+ loading,
+} from '@/components/_sila/Mixins/LoadingBarMixin';
+
+import IconAdd from '@carbon/icons-vue/es/add--alt/20';
+import IconTrashcan from '@carbon/icons-vue/es/trash-can/20';
+import InputPasswordToggle from '@/components/_sila/Global/InputPasswordToggle';
+import {
+ helpers,
+ ipAddress,
+ maxLength,
+ minLength,
+ required,
+ requiredIf,
+} from 'vuelidate/lib/validators';
+import VuelidateMixin from '@/components/_sila/Mixins/VuelidateMixin.js';
+import { isoPortRegex } from '@/utilities/_sila/regexConstants';
+
+export default {
+ name: 'Smtp',
+ components: {
+ IconAdd,
+ IconTrashcan,
+ PageSection,
+ TableRowAction,
+ InputPasswordToggle,
+ },
+ mixins: [BVToastMixin, LoadingBarMixin, VuelidateMixin],
+
+ data() {
+ return {
+ loading,
+ form: {
+ username: '',
+ password: '',
+ host: '',
+ port: '',
+ is_need_auth: false,
+ is_need_ssl: false,
+ },
+ fields: [
+ {
+ key: 'host',
+ label: this.$t('pageTransfer.table.userName'),
+ },
+ { key: 'actions', label: '', tdClass: 'text-right' },
+ ],
+ };
+ },
+ computed: {
+ settings() {
+ return this.$store.getters['smtpStore/settings'];
+ },
+ subscribers() {
+ return this.$store.getters['smtpStore/subscribers'].map((subscriber) => {
+ return {
+ ...subscriber,
+ actions: [
+ {
+ value: 'delete',
+ title: this.$t('pageTransfer.smtp.delSubscriber'),
+ },
+ ],
+ };
+ });
+ },
+ isNotAdmin() {
+ return (
+ this.$store.getters['authentication/role'] === 'ReadOnly' ||
+ this.$store.getters['authentication/role'] === 'Operator'
+ );
+ },
+ },
+ watch: {
+ settings() {
+ this.setForm();
+ },
+ },
+ created() {
+ this.startLoader();
+ Promise.all([
+ this.$store.dispatch('smtpStore/getSettings'),
+ this.$store.dispatch('smtpStore/getSubscribers'),
+ ]).finally(() => {
+ this.setForm();
+ this.endLoader();
+ });
+ },
+ validations() {
+ return {
+ form: {
+ username: {
+ required: requiredIf(function () {
+ return this.form.is_need_auth;
+ }),
+ maxLength: maxLength(16),
+ pattern: helpers.regex('pattern', /^([a-zA-Z_][a-zA-Z0-9_]*)/),
+ },
+ password: {
+ required: requiredIf(function () {
+ return this.form.is_need_auth;
+ }),
+ minLength: minLength(8),
+ maxLength: maxLength(20),
+ },
+ host: {
+ required,
+ ipAddress,
+ },
+ port: {
+ required,
+ pattern: helpers.regex('pattern', isoPortRegex),
+ },
+ },
+ };
+ },
+ methods: {
+ onChangeAuthCheckbox($event) {
+ if (!$event) {
+ this.resetAuthForm();
+ }
+ },
+ onTableAction($event, { host }) {
+ if ($event === 'delete') {
+ this.deleteSubscriber(host);
+ }
+ },
+ deleteSubscriber(host) {
+ this.startLoader();
+ this.$store
+ .dispatch('smtpStore/deleteSubscriber', host)
+ .then((success) => this.successToast(success))
+ .catch(({ message }) => this.errorToast(message))
+ .finally(() => this.endLoader());
+ },
+ initAddModal() {
+ this.$bvModal.show('modal-smtp');
+ },
+ saveSmtp() {
+ this.$v.$touch();
+ if (this.$v.$invalid) return;
+
+ this.startLoader();
+ if (!this.form.is_need_auth) {
+ // eslint-disable-next-line no-unused-vars
+ const { username, password, ...formWithoutCredits } = this.form;
+ this.form = formWithoutCredits;
+ }
+
+ this.$store
+ .dispatch('smtpStore/setSettings', this.form)
+ .then((message) => this.successToast(message))
+ .catch(({ message }) => this.errorToast(message))
+ .finally(() => this.endLoader());
+ },
+ sendMail() {
+ this.$store
+ .dispatch('smtpStore/sendTestMessage', {
+ from: 'ex@mail.ru',
+ to: 'v.lysak@dunice.net',
+ subject: 'qwerty',
+ text: 'lol',
+ })
+ .then((message) => this.successToast(message))
+ .catch(({ message }) => this.errorToast(message));
+ },
+ setForm() {
+ if (!this.settings) {
+ return;
+ }
+
+ this.form.username = this.settings.username;
+ this.form.password = this.settings.password;
+ this.form.host = this.settings.host;
+ this.form.port = this.settings.port;
+ this.form.is_need_auth = this.settings.is_need_auth;
+ this.form.is_need_ssl = this.settings.is_need_ssl;
+ },
+ resetAuthForm() {
+ this.form.username = null;
+ this.form.password = null;
+ },
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+.switch-group {
+ margin-bottom: 1.5rem;
+}
+.smtp-warning {
+ width: 50%;
+ @media (max-width: 1200px) {
+ width: 75%;
+ }
+ @media (max-width: 576px) {
+ width: 100%;
+ }
+}
+</style>
diff --git a/src/views/_sila/Settings/TransferInfo/Snmp.vue b/src/views/_sila/Settings/TransferInfo/Snmp.vue
new file mode 100644
index 00000000..ef9e18ac
--- /dev/null
+++ b/src/views/_sila/Settings/TransferInfo/Snmp.vue
@@ -0,0 +1,139 @@
+<template>
+ <page-section :section-title="$t('pageTransfer.snmp.snmpTitle')">
+ <b-row>
+ <b-col>
+ <div class="text-right">
+ <b-button
+ variant="primary"
+ :disabled="loading || isNotAdmin"
+ @click="initAddModal()"
+ >
+ <icon-add />
+ {{ $t('global.action.add') }}
+ </b-button>
+ </div>
+ <b-table
+ responsive="md"
+ hover
+ :busy="loading"
+ :fields="fields"
+ :items="subscribers"
+ :empty-text="$t('global.table.emptyMessage')"
+ show-empty
+ >
+ <!-- table actions column -->
+ <template #cell(actions)="{ item }">
+ <table-row-action
+ v-for="(action, index) in item.actions"
+ :key="index"
+ :value="action.value"
+ :enabled="action.enabled"
+ :title="action.title"
+ @click-table-action="onTableAction($event, item)"
+ >
+ <template #icon>
+ <icon-trashcan
+ v-if="action.value === 'delete'"
+ :data-test-id="`snmp-tableRowAction-delete-${index}`"
+ />
+ </template>
+ </table-row-action>
+ </template>
+ </b-table>
+ </b-col>
+ </b-row>
+ </page-section>
+</template>
+
+<script>
+import PageSection from '@/components/_sila/Global/PageSection';
+import BVToastMixin from '@/components/_sila/Mixins/BVToastMixin';
+import TableRowAction from '@/components/_sila/Global/TableRowAction';
+import LoadingBarMixin, {
+ loading,
+} from '@/components/_sila/Mixins/LoadingBarMixin';
+
+import IconAdd from '@carbon/icons-vue/es/add--alt/20';
+import IconTrashcan from '@carbon/icons-vue/es/trash-can/20';
+
+export default {
+ name: 'Snmp',
+ components: {
+ IconAdd,
+ IconTrashcan,
+ PageSection,
+ TableRowAction,
+ },
+ mixins: [BVToastMixin, LoadingBarMixin],
+
+ data() {
+ return {
+ loading,
+ actions: [
+ {
+ value: 'delete',
+ title: this.$t('global.action.delete'),
+ },
+ ],
+ fields: [
+ {
+ key: 'host',
+ label: this.$t('pageTransfer.snmp.host'),
+ },
+ {
+ key: 'port',
+ label: this.$t('pageTransfer.snmp.port'),
+ },
+ { key: 'actions', label: '', tdClass: 'text-right' },
+ ],
+ };
+ },
+ computed: {
+ subscribers() {
+ return this.$store.getters['snmpStore/subscribers'].map((subscriber) => {
+ return {
+ ...subscriber,
+ actions: [
+ {
+ value: 'delete',
+ title: this.$t('pageTransfer.snmp.delSubscriber'),
+ },
+ ],
+ };
+ });
+ },
+ isNotAdmin() {
+ return (
+ this.$store.getters['authentication/role'] === 'ReadOnly' ||
+ this.$store.getters['authentication/role'] === 'Operator'
+ );
+ },
+ },
+
+ created() {
+ this.startLoader();
+ this.$store.dispatch('snmpStore/getSubscribers').finally(() => {
+ this.endLoader();
+ });
+ },
+
+ methods: {
+ onTableAction($event, { Id }) {
+ if ($event === 'delete') {
+ this.deleteSubscriber(Id);
+ }
+ },
+ deleteSubscriber(index) {
+ this.startLoader();
+ this.$store
+ .dispatch('snmpStore/deleteSubscriber', index)
+ .then((success) => this.successToast(success))
+ .catch(({ message }) => this.errorToast(message))
+ .finally(() => this.endLoader());
+ },
+ initAddModal() {
+ this.$bvModal.show('modal-snmp');
+ },
+ },
+};
+</script>
diff --git a/src/views/_sila/Settings/TransferInfo/Syslog.vue b/src/views/_sila/Settings/TransferInfo/Syslog.vue
new file mode 100644
index 00000000..07884de5
--- /dev/null
+++ b/src/views/_sila/Settings/TransferInfo/Syslog.vue
@@ -0,0 +1,220 @@
+<template>
+ <page-section :section-title="$t('pageTransfer.syslog.title')">
+ <b-row class="mt-4 justify-content-end syslog-warning">
+ <b-col xs="12" sm="12">
+ <div class="switch-group">
+ <label for="statusSwitch">{{
+ $t('pageTransfer.syslog.status')
+ }}</label>
+ <b-form-checkbox
+ id="statusSwitch"
+ v-model="syslogStatus"
+ data-test-id="checkbox-status"
+ switch
+ :disabled="loading || isNotAdmin"
+ @change="onChangeStatusCheckbox($event)"
+ >
+ <span v-if="syslogStatus">
+ {{ $t('global.status.enabled') }}
+ </span>
+ <span v-else>{{ $t('global.status.disabled') }}</span>
+ </b-form-checkbox>
+ </div>
+ </b-col>
+ <b-col xs="12" sm="6">
+ <b-form-group
+ :label="$t('pageTransfer.syslog.ip')"
+ label-for="syslog-ip"
+ >
+ <b-form-input
+ id="syslog-ip"
+ v-model="form.Address"
+ :state="getValidationState($v.form.Address)"
+ :disabled="!syslogStatus || loading || isNotAdmin"
+ @input="$v.form.Address.$touch()"
+ />
+ <b-form-invalid-feedback role="alert">
+ <template v-if="!$v.form.Address.required">
+ {{ $t('global.form.fieldRequired') }}
+ </template>
+ <template v-if="!$v.form.Address.ipAddress">
+ {{ $t('global.form.invalidFormat') }}
+ </template>
+ </b-form-invalid-feedback>
+ </b-form-group>
+ </b-col>
+ <b-col xs="12" sm="6">
+ <b-form-group
+ :label="$t('pageTransfer.syslog.port')"
+ label-for="syslog-port"
+ >
+ <b-form-input
+ id="syslog-port"
+ v-model="form.Port"
+ type="number"
+ :state="getValidationState($v.form.Port)"
+ :disabled="!syslogStatus || loading || isNotAdmin"
+ @input="$v.form.Address.$touch()"
+ />
+ <b-form-invalid-feedback role="alert">
+ <template v-if="!$v.form.Port.required">
+ {{ $t('global.form.fieldRequired') }}
+ </template>
+ <template v-if="!$v.form.Port.pattern">
+ {{ $t('global.form.invalidFormat') }}
+ </template>
+ </b-form-invalid-feedback>
+ </b-form-group>
+ </b-col>
+ <b-col xs="4" class="d-flex justify-content-end align-items-start">
+ <b-button
+ variant="primary"
+ :disabled="loading || isNotAdmin"
+ @click="saveSyslog"
+ >
+ {{ $t('global.action.save') }}
+ </b-button>
+ </b-col>
+ </b-row>
+ </page-section>
+</template>
+
+<script>
+import PageSection from '@/components/_sila/Global/PageSection';
+import BVToastMixin from '@/components/_sila/Mixins/BVToastMixin';
+import LoadingBarMixin, {
+ loading,
+} from '@/components/_sila/Mixins/LoadingBarMixin';
+
+import { helpers, ipAddress, requiredIf } from 'vuelidate/lib/validators';
+import VuelidateMixin from '@/components/_sila/Mixins/VuelidateMixin.js';
+import { isoPortRegex } from '@/utilities/_sila/regexConstants';
+
+export default {
+ name: 'Syslog',
+ components: {
+ PageSection,
+ },
+ mixins: [BVToastMixin, LoadingBarMixin, VuelidateMixin],
+
+ data() {
+ return {
+ loading,
+ syslogStatus: false,
+ form: {
+ Address: null,
+ Port: null,
+ },
+ };
+ },
+ computed: {
+ settings() {
+ return this.$store.getters['syslogStore/settings'];
+ },
+ isNotAdmin() {
+ return (
+ this.$store.getters['authentication/role'] === 'ReadOnly' ||
+ this.$store.getters['authentication/role'] === 'Operator'
+ );
+ },
+ },
+
+ watch: {
+ settings() {
+ this.setForm();
+ },
+ },
+
+ created() {
+ this.startLoader();
+ this.$store.dispatch('syslogStore/getSettings').finally(() => {
+ this.setForm();
+ this.endLoader();
+ });
+ },
+
+ validations() {
+ return {
+ form: {
+ Address: {
+ required: requiredIf(function () {
+ return this.syslogStatus;
+ }),
+ ipAddress,
+ },
+ Port: {
+ required: requiredIf(function () {
+ return this.syslogStatus;
+ }),
+ pattern: helpers.regex('pattern', isoPortRegex),
+ },
+ },
+ };
+ },
+
+ methods: {
+ onChangeStatusCheckbox($event) {
+ if (!$event) {
+ this.resetForm();
+ }
+ },
+ saveSyslog() {
+ this.$v.$touch();
+ if (this.$v.$invalid) return;
+
+ this.startLoader();
+ if (!this.syslogStatus) {
+ this.form = {
+ Address: '',
+ Port: 0,
+ };
+ }
+
+ this.form.Port = +this.form.Port;
+ this.$store
+ .dispatch('syslogStore/saveSettings', this.form)
+ .then((success) => this.successToast(success))
+ .catch(({ message }) => this.errorToast(message))
+ .finally(() => this.endLoader());
+ },
+
+ setForm() {
+ if (!this.settings) {
+ return;
+ }
+
+ const isOff = !this.settings.Address && this.settings.Port === 0;
+
+ if (isOff) {
+ this.syslogStatus = false;
+ this.form.Address = null;
+ this.form.Port = null;
+ } else {
+ this.syslogStatus = true;
+ this.form.Address = this.settings.Address;
+ this.form.Port = this.settings.Port;
+ }
+ },
+
+ resetForm() {
+ this.form.Address = null;
+ this.form.Port = null;
+ },
+ },
+};
+</script>
+
+<style lang="scss" scoped>
+.switch-group {
+ margin-bottom: 1.5rem;
+}
+.syslog-warning {
+ width: 50%;
+ @media (max-width: 1200px) {
+ width: 75%;
+ }
+ @media (max-width: 576px) {
+ width: 100%;
+ }
+}
+</style>
diff --git a/src/views/_sila/Settings/TransferInfo/Transfer.vue b/src/views/_sila/Settings/TransferInfo/Transfer.vue
new file mode 100644
index 00000000..4b70778b
--- /dev/null
+++ b/src/views/_sila/Settings/TransferInfo/Transfer.vue
@@ -0,0 +1,64 @@
+<template>
+ <b-container fluid="xl">
+ <page-title :description="$t('pageTransfer.description')" />
+ <snmp />
+ <hr />
+ <smtp />
+ <hr />
+ <syslog />
+ <hr />
+ <modal-snmp @ok="saveSnmp" />
+ <modal-smtp @ok="saveSmtp" />
+ </b-container>
+</template>
+
+<script>
+import BVToastMixin from '@/components/_sila/Mixins/BVToastMixin';
+import LoadingBarMixin, {
+ loading,
+} from '@/components/_sila/Mixins/LoadingBarMixin';
+
+import PageTitle from '@/components/_sila/Global/PageTitle';
+import Snmp from './Snmp';
+import Smtp from './Smtp';
+import ModalSnmp from './ModalSnmp.vue';
+import ModalSmtp from './ModalSmtp.vue';
+import Syslog from './Syslog';
+
+export default {
+ name: 'PowerRestorePolicy',
+ components: {
+ PageTitle,
+ Snmp,
+ ModalSnmp,
+ Smtp,
+ ModalSmtp,
+ Syslog,
+ },
+ mixins: [BVToastMixin, LoadingBarMixin],
+ data() {
+ return {
+ loading,
+ };
+ },
+ methods: {
+ saveSnmp(modalFormData) {
+ this.startLoader();
+ this.$store
+ .dispatch('snmpStore/addSubscriber', modalFormData)
+ .then((message) => this.successToast(message))
+ .catch(({ message }) => this.errorToast(message))
+ .finally(() => this.endLoader());
+ },
+
+ saveSmtp(modalFormData) {
+ this.startLoader();
+ this.$store
+ .dispatch('smtpStore/addSubscriber', modalFormData)
+ .then((message) => this.successToast(message))
+ .catch(({ message }) => this.errorToast(message))
+ .finally(() => this.endLoader());
+ },
+ },
+};
+</script>
diff --git a/src/views/_sila/Settings/TransferInfo/WarningSmnp.vue b/src/views/_sila/Settings/TransferInfo/WarningSmnp.vue
new file mode 100644
index 00000000..df97d1a1
--- /dev/null
+++ b/src/views/_sila/Settings/TransferInfo/WarningSmnp.vue
@@ -0,0 +1,57 @@
+<template>
+ <page-section section-title="Предупреждения SNmP">
+ <b-row>
+ <b-col>
+ <b-table
+ hover
+ responsive="md"
+ show-empty
+ :items="items"
+ :fields="fields"
+ :empty-text="$t('global.table.emptyMessage')"
+ >
+ </b-table>
+ </b-col>
+ </b-row>
+ <b-row>
+ <b-col class="d-flex justify-content-end flex-wrap">
+ <b-button variant="secondary" class="mr-3 mb-3">
+ {{ 'Тестовое сообщение' }}
+ </b-button>
+ <b-button variant="primary" class="mb-3">
+ {{ $t('global.action.save') }}
+ </b-button>
+ </b-col>
+ </b-row>
+ </page-section>
+</template>
+
+<script>
+import PageSection from '@/components/_sila/Global/PageSection';
+
+export default {
+ name: 'WarningSmnp',
+ components: {
+ PageSection,
+ },
+
+ data() {
+ return {
+ fields: [
+ {
+ key: 'id',
+ label: 'Тип предупреждения',
+ formatter: this.dataFormatter,
+ },
+ {
+ key: 'health',
+ label: 'Значение',
+ formatter: this.dataFormatter,
+ tdClass: 'text-nowrap',
+ },
+ ],
+ };
+ },
+ computed: {},
+};
+</script>
diff --git a/src/views/_sila/Settings/TransferInfo/index.js b/src/views/_sila/Settings/TransferInfo/index.js
new file mode 100644
index 00000000..50508f66
--- /dev/null
+++ b/src/views/_sila/Settings/TransferInfo/index.js
@@ -0,0 +1,2 @@
+import Transfer from './Transfer.vue';
+export default Transfer;