HM-133. Рефакторинг (#64)
This commit is contained in:
@ -9,7 +9,9 @@
|
|||||||
"dev": "webpack-dev-server",
|
"dev": "webpack-dev-server",
|
||||||
"docs": "rm -rf out && documentation build src/** -f html -o out",
|
"docs": "rm -rf out && documentation build src/** -f html -o out",
|
||||||
"show:docs": "lite-server --baseDir=\"out\"",
|
"show:docs": "lite-server --baseDir=\"out\"",
|
||||||
"lint": "eslint -c .eslintrc.json src --fix",
|
"prune": "ts-prune -p jsconfig.json",
|
||||||
|
"eslint": "eslint -c .eslintrc.json src --fix",
|
||||||
|
"lint": "npm run eslint && npm run prune",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"master:test": "git fetch && git reset --hard master && git checkout master && git pull && npm i && npm start"
|
"master:test": "git fetch && git reset --hard master && git checkout master && git pull && npm i && npm start"
|
||||||
},
|
},
|
||||||
@ -49,6 +51,7 @@
|
|||||||
"postcss-import": "^12.0.1",
|
"postcss-import": "^12.0.1",
|
||||||
"postcss-loader": "^3.0.0",
|
"postcss-loader": "^3.0.0",
|
||||||
"postcss-preset-env": "^6.7.0",
|
"postcss-preset-env": "^6.7.0",
|
||||||
|
"ts-prune": "^0.7.4",
|
||||||
"url-loader": "^4.1.0",
|
"url-loader": "^4.1.0",
|
||||||
"webpack": "^4.43.0",
|
"webpack": "^4.43.0",
|
||||||
"webpack-cli": "^3.3.12",
|
"webpack-cli": "^3.3.12",
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import {makeUrlWithQuery} from '../utils/urlUtils';
|
|
||||||
import httpAuthApi from './HttpAuthAPI';
|
import httpAuthApi from './HttpAuthAPI';
|
||||||
|
import {makeUrlWithQuery} from '../core/utils';
|
||||||
|
|
||||||
const GET = 'GET';
|
const GET = 'GET';
|
||||||
const POST = 'POST';
|
const POST = 'POST';
|
||||||
|
|||||||
20
src/api/ProfileServiceAPI.js
Normal file
20
src/api/ProfileServiceAPI.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import http from './HttpAPI';
|
||||||
|
|
||||||
|
const ROOT_URL = 'http://api.auth.vigdorov.ru/users';
|
||||||
|
|
||||||
|
const profileServiceApi = {
|
||||||
|
getSelfInfo: async () => {
|
||||||
|
const {data} = await http.get(`${ROOT_URL}/me`);
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
editSelfInfo: async (user) => {
|
||||||
|
const {data} = await http.post(`${ROOT_URL}/edit-me`, user);
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
changePassword: async (old_password, new_password) => {
|
||||||
|
const {data} = await http.post(`${ROOT_URL}/change-password`, {old_password, new_password});
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default profileServiceApi;
|
||||||
@ -1,126 +0,0 @@
|
|||||||
import {v4 as uuidv4} from 'uuid';
|
|
||||||
|
|
||||||
import storageApi from './StorageServiceAPI';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @interface StoreListElement
|
|
||||||
* @type {Object}
|
|
||||||
* @property {string} _id - уникальный id элемента
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Класс создания api для списков данных
|
|
||||||
* @class StorageListApi
|
|
||||||
* @param {string} key - уникальный ключ для api, который будет записан в сервисе
|
|
||||||
* @param {string} description - описание api
|
|
||||||
* @param {string} author - автор api
|
|
||||||
* @param {string} service_name - имя сервиса, для которого используется api
|
|
||||||
*/
|
|
||||||
class StorageListApi {
|
|
||||||
constructor (key, description, author, service_name) {
|
|
||||||
/**
|
|
||||||
* Ключ api
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
this.key = key;
|
|
||||||
/**
|
|
||||||
* @type {StorageServiceApi}
|
|
||||||
*/
|
|
||||||
this.api = storageApi;
|
|
||||||
this.api.create({key, description, author, service_name, value: []});
|
|
||||||
/**
|
|
||||||
* @type {Object}
|
|
||||||
* @property {string} description - описание api
|
|
||||||
* @property {string} author - автор api
|
|
||||||
* @property {string} service_name - имя сервиса, для которого используется api
|
|
||||||
*/
|
|
||||||
this.metaInfo = {
|
|
||||||
description, author, service_name
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {StoreListElement[]} list - список элементов по которым осуществялется поиск
|
|
||||||
* @param {string} _id - _id искомого элемента
|
|
||||||
* @returns {number} - Возвращает индекс искомого эллемента по _id
|
|
||||||
*/
|
|
||||||
_findIndex = (list, _id) => {
|
|
||||||
return list.findIndex((item) => item._id === _id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {StoreListElement[]} list - новый список элементов
|
|
||||||
* @returns {Promise<Array<StoreListElement[]>} - возвращает обновленный список элементов
|
|
||||||
*/
|
|
||||||
_updateList = async (list) => {
|
|
||||||
return await this.api.update(this.key, list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise<StoreListElement[]>} - возвращает все элементы списка
|
|
||||||
*/
|
|
||||||
request = async () => {
|
|
||||||
const data = await this.api.find(this.key);
|
|
||||||
return (data && data.value) || [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} _id - _id искомого элемента списка
|
|
||||||
* @returns {Promise<StoreListElement>} - возвращает элемент списка или генерит ошибку
|
|
||||||
*/
|
|
||||||
find = async (_id) => {
|
|
||||||
const list = await this.request();
|
|
||||||
const findIndex = this._findIndex(list, _id);
|
|
||||||
if (findIndex === -1) {
|
|
||||||
throw new Error(`Not Found _id: ${_id}`);
|
|
||||||
}
|
|
||||||
return list[findIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Object} data - элемент списка
|
|
||||||
* @returns {Promise<StoreListElement>} - Возвращает вновь созданный элемент с уникальным полем _id
|
|
||||||
*/
|
|
||||||
create = async (data) => {
|
|
||||||
const list = await this.request();
|
|
||||||
const _id = uuidv4();
|
|
||||||
const newData = {
|
|
||||||
...data,
|
|
||||||
_id,
|
|
||||||
};
|
|
||||||
await this._updateList(list.concat(newData));
|
|
||||||
return newData;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {StoreListElement} data - элемент списка
|
|
||||||
* @returns {Promise<StoreListElement>} - Возвращает обновленный элемент списка
|
|
||||||
*/
|
|
||||||
update = async (data) => {
|
|
||||||
const list = await this.request();
|
|
||||||
const findIndex = this._findIndex(list, data._id);
|
|
||||||
if (findIndex === -1) {
|
|
||||||
throw new Error(`Not Found _id: ${data._id}`);
|
|
||||||
}
|
|
||||||
list.splice(findIndex, 1, data);
|
|
||||||
await this._updateList(list);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} _id - _id удаляемого элемента
|
|
||||||
* @returns {Promise<string>} - Возвращает _id удаленного элемента или ошибку
|
|
||||||
*/
|
|
||||||
remove = async (_id) => {
|
|
||||||
const list = await this.request();
|
|
||||||
const findIndex = this._findIndex(list, _id);
|
|
||||||
if (findIndex === -1) {
|
|
||||||
throw new Error(`Not Found _id: ${_id}`);
|
|
||||||
}
|
|
||||||
list.splice(findIndex, 1);
|
|
||||||
await this._updateList(list);
|
|
||||||
return _id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default StorageListApi;
|
|
||||||
@ -6,6 +6,8 @@ export const API_NAMES = {
|
|||||||
|
|
||||||
export const LOCALHOST = 'localhost';
|
export const LOCALHOST = 'localhost';
|
||||||
|
|
||||||
|
export const API_NAME_HEADER = 'api-name';
|
||||||
|
|
||||||
export const API_OPTIONS = {
|
export const API_OPTIONS = {
|
||||||
[API_NAMES.PRODUCTION]: {
|
[API_NAMES.PRODUCTION]: {
|
||||||
url: 'http://api.storage.vigdorov.ru',
|
url: 'http://api.storage.vigdorov.ru',
|
||||||
@ -31,10 +33,6 @@ export const ENDPOINTS = {
|
|||||||
SERVER_LOGS: '/logs/server',
|
SERVER_LOGS: '/logs/server',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const TESTING_HEADERS = {
|
|
||||||
'Api-Name': 'store-service-test',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const AUTH_SERVICE = 'http://api.auth.vigdorov.ru';
|
export const AUTH_SERVICE = 'http://api.auth.vigdorov.ru';
|
||||||
|
|
||||||
export const AUTH_ENDPOINTS = {
|
export const AUTH_ENDPOINTS = {
|
||||||
|
|||||||
32
src/app.js
32
src/app.js
@ -3,18 +3,18 @@ import 'bootstrap/dist/css/bootstrap.min.css';
|
|||||||
import 'bootstrap';
|
import 'bootstrap';
|
||||||
|
|
||||||
import './services/AdminConfigsService';
|
import './services/AdminConfigsService';
|
||||||
import ApiPage from './components/api-page';
|
import ApiPage from './pages/storages/components/page/Page';
|
||||||
import MainPage from './components/main-page';
|
import MainPage from './pages/main/components/page/Page';
|
||||||
import MainMenu from './components/main-menu/MainMenu';
|
import MainMenu from './core/components/main-menu/MainMenu';
|
||||||
import routeService from './services/RouteService';
|
import routeService from './services/RouteService';
|
||||||
import RouterPagesContainer from './components/router-pages-container/index';
|
import RouterPagesContainer from './core/components/router-pages-container/RouterPagesContainer';
|
||||||
import LogsPage from './components/logs-page/index';
|
import LogsPage from './pages/logs/components/page/Page';
|
||||||
import LoginPage from './components/login-page';
|
import LoginPage from './pages/login/components/page/Page';
|
||||||
import ProfilePage from './components/profile-page';
|
import ProfilePage from './pages/profile/components/page/Page';
|
||||||
import authServiceApi from './api/AuthServiceAPI';
|
import authServiceApi from './api/AuthServiceAPI';
|
||||||
import userInfoService from './services/UserInfoService';
|
import userInfoService from './services/UserInfoService';
|
||||||
import {EVENTS} from './consts';
|
import {EVENTS, ROUTES} from './core/consts';
|
||||||
import UsersPage from './components/users-page';
|
import UsersPage from './pages/users/components/page/Page';
|
||||||
|
|
||||||
const initAppComponents = () => {
|
const initAppComponents = () => {
|
||||||
const mainMenu = new MainMenu();
|
const mainMenu = new MainMenu();
|
||||||
@ -34,12 +34,12 @@ const initAppComponents = () => {
|
|||||||
* ]);
|
* ]);
|
||||||
*/
|
*/
|
||||||
routerPagesContainer.addRoutes([
|
routerPagesContainer.addRoutes([
|
||||||
{url: '/', pageComponent: MainPage},
|
{url: ROUTES.MAIN, pageComponent: MainPage},
|
||||||
{url: '/api', pageComponent: ApiPage},
|
{url: ROUTES.STORE, pageComponent: ApiPage},
|
||||||
{url: '/logs', pageComponent: LogsPage},
|
{url: ROUTES.LOGS, pageComponent: LogsPage},
|
||||||
{url: '/users', pageComponent: UsersPage},
|
{url: ROUTES.USERS, pageComponent: UsersPage},
|
||||||
{url: '/login', pageComponent: LoginPage},
|
{url: ROUTES.LOGIN, pageComponent: LoginPage},
|
||||||
{url: '/profile', pageComponent: ProfilePage},
|
{url: ROUTES.PROFILE, pageComponent: ProfilePage},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,7 +58,7 @@ const initApp = () => {
|
|||||||
initAppComponents();
|
initAppComponents();
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
history.pushState({}, '', '/login');
|
history.pushState({}, '', ROUTES.LOGIN);
|
||||||
initAppComponents();
|
initAppComponents();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,3 +0,0 @@
|
|||||||
import ApiInfoComponent from './ApiInfoComponent';
|
|
||||||
|
|
||||||
export default ApiInfoComponent;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import ApiPage from './ApiPage';
|
|
||||||
|
|
||||||
export default ApiPage;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import ClientLogsTable from './ClientLogsTable';
|
|
||||||
|
|
||||||
export default ClientLogsTable;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import ClientLogsViewForm from './ClientLogsViewForm';
|
|
||||||
|
|
||||||
export default ClientLogsViewForm;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import Component from './Component';
|
|
||||||
|
|
||||||
export default Component;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import CreateApiComponent from './CreateApiComponent';
|
|
||||||
|
|
||||||
export default CreateApiComponent;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import FilterInputComponent from './FilterInputComponent';
|
|
||||||
|
|
||||||
export default FilterInputComponent;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import FormControl from './FormControl';
|
|
||||||
|
|
||||||
export default FormControl;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import HeadersTable from './HeadersTable';
|
|
||||||
|
|
||||||
export default HeadersTable;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import LoginForm from './LoginForm';
|
|
||||||
|
|
||||||
export default LoginForm;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import LoginPage from './LoginPage';
|
|
||||||
|
|
||||||
export default LoginPage;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import LogsFilters from './LogsFilters';
|
|
||||||
|
|
||||||
export default LogsFilters;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import LogsPage from './LogsPage';
|
|
||||||
|
|
||||||
export default LogsPage;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import MainMenu from './MainMenu';
|
|
||||||
|
|
||||||
export default MainMenu;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import MainPage from './MainPage';
|
|
||||||
|
|
||||||
export default MainPage;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import MainStatistic from './MainStatistic';
|
|
||||||
|
|
||||||
export default MainStatistic;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import ModalSidebar from './ModalSibebar';
|
|
||||||
|
|
||||||
export default ModalSidebar;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import Modal from './Modal';
|
|
||||||
|
|
||||||
export default Modal;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import NotFoundContent from './NotFoundContent';
|
|
||||||
|
|
||||||
export default NotFoundContent;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import NotFoundPage from './NotFoundPage';
|
|
||||||
|
|
||||||
export default NotFoundPage;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import NotifyContainer from './NotifyContainer';
|
|
||||||
|
|
||||||
export default NotifyContainer;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import NotifyMessage from './NotifyMessage';
|
|
||||||
|
|
||||||
export default NotifyMessage;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import Pagination from './Pagination';
|
|
||||||
|
|
||||||
export default Pagination;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import ProfileContent from './ProfileContent';
|
|
||||||
|
|
||||||
export default ProfileContent;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import ProfilePage from './ProfilePage';
|
|
||||||
|
|
||||||
export default ProfilePage;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import RouterPagesContainer from './RouterPagesContainer';
|
|
||||||
|
|
||||||
export default RouterPagesContainer;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import FilterApiComponent from './FilterApiComponent';
|
|
||||||
|
|
||||||
export default FilterApiComponent;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import ServerLogsTable from './ServerLogsTable';
|
|
||||||
|
|
||||||
export default ServerLogsTable;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import ServerLogsViewForm from './ServerLogsViewForm';
|
|
||||||
|
|
||||||
export default ServerLogsViewForm;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import TableCellOverflow from './TableCellOverflow';
|
|
||||||
|
|
||||||
export default TableCellOverflow;
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
import Component from '../component/index';
|
|
||||||
|
|
||||||
class TableColumnComponent extends Component {
|
|
||||||
constructor (tableHeadRow, text) {
|
|
||||||
super('#table-column', tableHeadRow);
|
|
||||||
|
|
||||||
this.row = this.mainNode;
|
|
||||||
this.columnName = {
|
|
||||||
key: 'Название хранилища',
|
|
||||||
description: 'Описание',
|
|
||||||
service_name: 'Имя сервиса',
|
|
||||||
author: 'Автор',
|
|
||||||
value: 'Тип содержимого'
|
|
||||||
};
|
|
||||||
this.row.textContent = this.columnName[text];
|
|
||||||
|
|
||||||
this.addEventListener(this.mainNode, 'click', (evt) => {
|
|
||||||
this.next('click', evt);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
export default TableColumnComponent;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import TableColumnComponent from './TableColumnComponent';
|
|
||||||
|
|
||||||
export default TableColumnComponent;
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
import Component from '../component/index';
|
|
||||||
import TableColumnComponent from '../table-column-component/index';
|
|
||||||
import TableRowComponent from '../table-row-component/TableRowComponent';
|
|
||||||
|
|
||||||
class TableComponent extends Component {
|
|
||||||
constructor (parentNode) {
|
|
||||||
super('#main-table', parentNode);
|
|
||||||
|
|
||||||
this.tableHead = this.mainNode.querySelector('.Table__head');
|
|
||||||
this.tableBody = this.mainNode.querySelector('.Table__body');
|
|
||||||
this.tableHeadRow = this.mainNode.querySelector('.Table__head-row');
|
|
||||||
this.columnArr = [];
|
|
||||||
this.rowArr = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
render = (array) => {
|
|
||||||
this.columnArr.forEach((item) => {
|
|
||||||
item.destroy();
|
|
||||||
});
|
|
||||||
this.rowArr.forEach((item) => {
|
|
||||||
item.destroy();
|
|
||||||
});
|
|
||||||
this.array = array;
|
|
||||||
this.columns = Object.keys(array[0]);
|
|
||||||
this.columns.forEach((item, index) => {
|
|
||||||
const columnElement = this.createComponent(TableColumnComponent, this.tableHeadRow, item, index);
|
|
||||||
columnElement.subscribe('click', () => {
|
|
||||||
this.sort(item, array);
|
|
||||||
});
|
|
||||||
this.columnArr.push(columnElement);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.array.forEach((item, index) => {
|
|
||||||
const newRow = this.createComponent(TableRowComponent, this.tableBody, item, index);
|
|
||||||
newRow.subscribe('dblclick', () => {
|
|
||||||
this.next('showInfo', item);
|
|
||||||
});
|
|
||||||
this.rowArr.push(newRow);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
sort = (item, array) => {
|
|
||||||
this.array.sort((a, b) => a[item] > b[item]);
|
|
||||||
this.render(array);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default TableComponent;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import TableComponent from './TableComponent';
|
|
||||||
|
|
||||||
export default TableComponent;
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
import Component from '../component/index';
|
|
||||||
|
|
||||||
class TableRowComponent extends Component {
|
|
||||||
constructor (container, object, index) {
|
|
||||||
super('#table-row', container);
|
|
||||||
|
|
||||||
this.row = this.mainNode;
|
|
||||||
this.indexPlace = this.mainNode.querySelector('.Body__row-index');
|
|
||||||
this.content = Object.values(object);
|
|
||||||
this.indexPlace.textContent = index + 1;
|
|
||||||
|
|
||||||
this.content.forEach((text) => {
|
|
||||||
const contentPlace = document.createElement('td');
|
|
||||||
if (typeof(text) !== 'string') {
|
|
||||||
contentPlace.textContent = typeof(text);
|
|
||||||
} else if (text.length > 30) {
|
|
||||||
contentPlace.textContent = `${text.substr(0, 30)} ...`;
|
|
||||||
} else {
|
|
||||||
contentPlace.textContent = text;
|
|
||||||
}
|
|
||||||
this.row.appendChild(contentPlace);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.addEventListener(this.mainNode, 'dblclick', (evt) => {
|
|
||||||
this.next('dblclick', evt);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
export default TableRowComponent;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import Table from './Table';
|
|
||||||
|
|
||||||
export default Table;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import UserViewForm from './UserViewForm';
|
|
||||||
|
|
||||||
export default UserViewForm;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import UsersPage from './UsersPage';
|
|
||||||
|
|
||||||
export default UsersPage;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import UsersTable from './UsersTable';
|
|
||||||
|
|
||||||
export default UsersTable;
|
|
||||||
@ -1,98 +0,0 @@
|
|||||||
export const LOG_TYPE = {
|
|
||||||
SERVER: 'server-logs',
|
|
||||||
CLIENT: 'client-logs',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const LOG_LABELS = [
|
|
||||||
{id: LOG_TYPE.SERVER, label: 'Ошибки сервера'},
|
|
||||||
{id: LOG_TYPE.CLIENT, label: 'Ошибки запросов'},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const SERVER_COLS = [
|
|
||||||
{id: '_id', label: 'id', width: '240px'},
|
|
||||||
{id: 'date', label: 'Дата', width: '150px'},
|
|
||||||
{id: 'type', label: 'Тип записи', width: '120px'},
|
|
||||||
{id: 'message', label: 'Сообщение', width: '200px'},
|
|
||||||
{id: 'trace', label: 'Стек', width: '200px'},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const CLIENT_COLS = [
|
|
||||||
{id: 'startTime', label: 'Дата запроса', width: '150px'},
|
|
||||||
{id: 'type', label: 'Результат', width: '100px'},
|
|
||||||
{id: 'data_base', label: 'База данных'},
|
|
||||||
{id: 'url', label: 'URL'},
|
|
||||||
{id: 'method', label: 'Метод'},
|
|
||||||
{id: 'status', label: 'Код ответа'},
|
|
||||||
{id: 'message', label: 'Сообщение'},
|
|
||||||
{id: 'duration', label: 'Скорость ответа'},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const LOG_COLS = {
|
|
||||||
[LOG_TYPE.SERVER]: SERVER_COLS,
|
|
||||||
[LOG_TYPE.CLIENT]: CLIENT_COLS,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const USERS_COLS = [
|
|
||||||
{id: 'login', label: 'Логин'},
|
|
||||||
{id: 'avatar', label: 'Аватар'},
|
|
||||||
{id: 'is_admin', label: 'Админ'},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const API_COLS = [
|
|
||||||
{id: 'index', label: '#'},
|
|
||||||
{id: 'key', label: 'Название хранилища'},
|
|
||||||
{id: 'description', label: 'Описание'},
|
|
||||||
{id: 'service_name', label: 'Имя сервиса'},
|
|
||||||
{id: 'author', label: 'Автор'},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const EVENTS = {
|
|
||||||
ROUTE_CHANGE: 'routeChange',
|
|
||||||
ROUTE_SEARCH_CHANGE: 'routeSearchChange',
|
|
||||||
ROW_CLICK: 'rowClick',
|
|
||||||
ROW_DOUBLE_CLICK: 'rowDoubleClick',
|
|
||||||
CHANGE_USER_INFO: 'changeUserInfo',
|
|
||||||
CHANGE_USER_AVATAR: 'changeUserAvatar',
|
|
||||||
OPEN_MODAL: 'openModal',
|
|
||||||
CLICK: 'click',
|
|
||||||
SUBMIT: 'submit',
|
|
||||||
FOCUS: 'focus',
|
|
||||||
KEYDOWN: 'keydown',
|
|
||||||
INPUT: 'input',
|
|
||||||
CHANGE: 'change',
|
|
||||||
CREATE_USER: 'createUser',
|
|
||||||
SAVE_USER: 'saveUser',
|
|
||||||
DELETE_USER: 'deleteUser',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const FORM_TYPES = {
|
|
||||||
TEXT: 'TEXT',
|
|
||||||
SELECT: 'SELECT',
|
|
||||||
TEXTAREA: 'TEXTAREA',
|
|
||||||
PASSWORD: 'PASSWORD',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const MODES = {
|
|
||||||
Create: 'create',
|
|
||||||
View: 'view',
|
|
||||||
Edit: 'edit',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const TAG_NAME = {
|
|
||||||
OPTION: 'option',
|
|
||||||
DIV: 'div',
|
|
||||||
INPUT: 'input',
|
|
||||||
SELECT: 'select',
|
|
||||||
TEXTAREA: 'textarea',
|
|
||||||
LABEL: 'label',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const TABLE_TYPE = {
|
|
||||||
DEFAULT: 'table table-striped table-hover',
|
|
||||||
BORDERED: 'table table-bordered table-hover',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const CAPTION_POSITION = {
|
|
||||||
TOP: 'caption-top',
|
|
||||||
BOTH: '',
|
|
||||||
};
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import {makeUrlWithQuery} from '../urlUtils';
|
import {makeUrlWithQuery} from '../utils';
|
||||||
|
|
||||||
describe('Проверка функции makeUrlWithQuery', () => {
|
describe('Проверка функции makeUrlWithQuery', () => {
|
||||||
it('Передача корректного маршрута без query', () => {
|
it('Передача корректного маршрута без query', () => {
|
||||||
@ -1,4 +1,5 @@
|
|||||||
import Component from '../component/index';
|
import Component from '../component/Component';
|
||||||
|
import {EVENTS} from '../../consts';
|
||||||
|
|
||||||
class ButtonComponent extends Component {
|
class ButtonComponent extends Component {
|
||||||
constructor (parentNode, text, newStyle) {
|
constructor (parentNode, text, newStyle) {
|
||||||
@ -7,8 +8,8 @@ class ButtonComponent extends Component {
|
|||||||
this.mainNode.textContent = text;
|
this.mainNode.textContent = text;
|
||||||
this.mainNode.className = newStyle;
|
this.mainNode.className = newStyle;
|
||||||
|
|
||||||
this.addEventListener(this.mainNode, 'click', (event) => {
|
this.addEventListener(this.mainNode, EVENTS.CLICK, (event) => {
|
||||||
this.next('click', event);
|
this.next(EVENTS.CLICK, event);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
import EmitService from '../../services/EmitService';
|
import EmitService from '../../../services/EmitService';
|
||||||
import {createElement} from '../../utils/elementUtils';
|
import {createElement} from '../../utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Класс для создания компонентов приложения. Необходим для наследования.
|
* Класс для создания компонентов приложения. Необходим для наследования.
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import Component from '../component';
|
import Component from '../component/Component';
|
||||||
import {FORM_TYPES, EVENTS, TAG_NAME} from '../../consts';
|
import {FORM_TYPES, EVENTS, TAG_NAME} from '../../consts';
|
||||||
|
|
||||||
class FormControl extends Component {
|
class FormControl extends Component {
|
||||||
@ -1,30 +1,30 @@
|
|||||||
import Component from '../component/index';
|
import Component from '../component/Component';
|
||||||
import routeService from '../../services/RouteService';
|
import routeService from '../../../services/RouteService';
|
||||||
|
|
||||||
import './MainMenu.css';
|
import './MainMenu.css';
|
||||||
import {EVENTS} from '../../consts';
|
import {EVENTS, ROUTES, TAG_NAME} from '../../consts';
|
||||||
import tokenApi from '../../api/TokenAPI';
|
import tokenApi from '../../../api/TokenAPI';
|
||||||
|
|
||||||
export const NAV_MENU = [
|
const NAV_MENU = [
|
||||||
{
|
{
|
||||||
title: 'Главная',
|
title: 'Главная',
|
||||||
url: '/',
|
url: ROUTES.MAIN,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Список хранилищ',
|
title: 'Список хранилищ',
|
||||||
url: '/api',
|
url: ROUTES.STORE,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Журнал',
|
title: 'Журнал',
|
||||||
url: '/logs',
|
url: ROUTES.LOGS,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Пользователи',
|
title: 'Пользователи',
|
||||||
url: '/users',
|
url: ROUTES.USERS,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Личный кабинет',
|
title: 'Личный кабинет',
|
||||||
url: '/profile',
|
url: ROUTES.PROFILE,
|
||||||
className: 'MainMenu__profileButton'
|
className: 'MainMenu__profileButton'
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -41,14 +41,14 @@ class MainMenu extends Component {
|
|||||||
this.exitButton = this.mainNode.querySelector('.MainMenu__exitButton');
|
this.exitButton = this.mainNode.querySelector('.MainMenu__exitButton');
|
||||||
this.collapse = this.mainNode.querySelector('.navbar-collapse');
|
this.collapse = this.mainNode.querySelector('.navbar-collapse');
|
||||||
|
|
||||||
this.addEventListener(this.exitButton, 'click', this.exitApp);
|
this.addEventListener(this.exitButton, EVENTS.CLICK, this.exitApp);
|
||||||
|
|
||||||
this.addEventListener(this.logoBox, 'click', () => {
|
this.addEventListener(this.logoBox, EVENTS.CLICK, () => {
|
||||||
routeService.goTo('/');
|
routeService.goTo(ROUTES.MAIN);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.addEventListener(this.avatar, 'click', () => {
|
this.addEventListener(this.avatar, EVENTS.CLICK, () => {
|
||||||
routeService.goTo('/profile');
|
routeService.goTo(ROUTES.PROFILE);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.addSubscribe(routeService, EVENTS.ROUTE_CHANGE, (route) => {
|
this.addSubscribe(routeService, EVENTS.ROUTE_CHANGE, (route) => {
|
||||||
@ -74,21 +74,21 @@ class MainMenu extends Component {
|
|||||||
render = () => {
|
render = () => {
|
||||||
this.menuItems = NAV_MENU.map(({url, title, className = ''}) => {
|
this.menuItems = NAV_MENU.map(({url, title, className = ''}) => {
|
||||||
const li = this.createElement({
|
const li = this.createElement({
|
||||||
tagName: 'li',
|
tagName: TAG_NAME.LI,
|
||||||
parentNode: this.buttonsContainer,
|
parentNode: this.buttonsContainer,
|
||||||
options: {
|
options: {
|
||||||
className: `nav-item ${className}`,
|
className: `nav-item ${className}`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const link = this.createElement({
|
const link = this.createElement({
|
||||||
tagName: 'a',
|
tagName: TAG_NAME.A,
|
||||||
parentNode: li,
|
parentNode: li,
|
||||||
options: {
|
options: {
|
||||||
className: 'nav-link',
|
className: 'nav-link',
|
||||||
textContent: title,
|
textContent: title,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
this.addEventListener(li, 'click', () => {
|
this.addEventListener(li, EVENTS.CLICK, () => {
|
||||||
routeService.goTo(url);
|
routeService.goTo(url);
|
||||||
if (this.collapse.classList.contains('show')) {
|
if (this.collapse.classList.contains('show')) {
|
||||||
this.collapse.classList.remove('show');
|
this.collapse.classList.remove('show');
|
||||||
@ -1,10 +1,14 @@
|
|||||||
import Component from '../component';
|
import Component from '../component/Component';
|
||||||
import './ModalSidebar.css';
|
import './ModalSidebar.css';
|
||||||
|
import {TAG_NAME, EVENTS} from '../../consts';
|
||||||
|
|
||||||
const SHOW_WINDOW_CLASS = 'ModalSidebar__window_show';
|
const SHOW_WINDOW_CLASS = 'ModalSidebar__window_show';
|
||||||
const HIDE_WINDOW_CLASS = 'ModalSidebar__window_hide';
|
const HIDE_WINDOW_CLASS = 'ModalSidebar__window_hide';
|
||||||
const SHOW_SHADOW_CLASS = 'ModalSidebar__shadow_show';
|
const SHOW_SHADOW_CLASS = 'ModalSidebar__shadow_show';
|
||||||
const HIDE_SHADOW_CLASS = 'ModalSidebar__shadow_hide';
|
const HIDE_SHADOW_CLASS = 'ModalSidebar__shadow_hide';
|
||||||
|
const SHADOW_CLASS = 'ModalSidebar__shadow';
|
||||||
|
const CROSS_BUTTON_CLASS = 'ModalSidebar__close';
|
||||||
|
const WINDOW_CLASS = 'ModalSidebar__window';
|
||||||
|
|
||||||
class ModalSidebar extends Component {
|
class ModalSidebar extends Component {
|
||||||
constructor ({
|
constructor ({
|
||||||
@ -15,28 +19,28 @@ class ModalSidebar extends Component {
|
|||||||
super('#modal-sidebar', parentNode);
|
super('#modal-sidebar', parentNode);
|
||||||
|
|
||||||
this.shadow = this.createElement({
|
this.shadow = this.createElement({
|
||||||
tagName: 'div',
|
tagName: TAG_NAME.DIV,
|
||||||
parentNode,
|
parentNode,
|
||||||
options: {
|
options: {
|
||||||
className: 'ModalSidebar__shadow',
|
className: SHADOW_CLASS,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
this.crossButton = this.mainNode.querySelector('.ModalSidebar__close');
|
this.crossButton = this.mainNode.querySelector(`.${CROSS_BUTTON_CLASS}`);
|
||||||
|
|
||||||
this.window = this.mainNode.querySelector('.ModalSidebar__window');
|
this.window = this.mainNode.querySelector(`.${WINDOW_CLASS}`);
|
||||||
|
|
||||||
this.window.appendChild(content);
|
this.window.appendChild(content);
|
||||||
|
|
||||||
if (!disabledShadowClose) {
|
if (!disabledShadowClose) {
|
||||||
this.addEventListener(this.mainNode, 'click', (event) => {
|
this.addEventListener(this.mainNode, EVENTS.CLICK, (event) => {
|
||||||
if (event.target === this.mainNode) {
|
if (event.target === this.mainNode) {
|
||||||
this.hide();
|
this.hide();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.addEventListener(this.crossButton, 'click', this.hide);
|
this.addEventListener(this.crossButton, EVENTS.CLICK, this.hide);
|
||||||
}
|
}
|
||||||
|
|
||||||
isOpen = () => {
|
isOpen = () => {
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import Component from '../component/index';
|
import Component from '../component/Component';
|
||||||
|
|
||||||
import './Modal.css';
|
import './Modal.css';
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import Component from '../component';
|
import Component from '../component/Component';
|
||||||
import './NotifyContainer.css';
|
import './NotifyContainer.css';
|
||||||
|
|
||||||
class NotifyContainer extends Component {
|
class NotifyContainer extends Component {
|
||||||
@ -1,6 +1,7 @@
|
|||||||
import Component from '../component';
|
import Component from '../component/Component';
|
||||||
import notifyContainer from '../notify-container';
|
import notifyContainer from '../notify-container/NotifyContainer';
|
||||||
import './NotifyMessage.css';
|
import './NotifyMessage.css';
|
||||||
|
import {EVENTS} from '../../consts';
|
||||||
|
|
||||||
class NotifyMessage extends Component {
|
class NotifyMessage extends Component {
|
||||||
constructor ({
|
constructor ({
|
||||||
@ -29,7 +30,7 @@ class NotifyMessage extends Component {
|
|||||||
if (autohide) {
|
if (autohide) {
|
||||||
this.closeButton.remove();
|
this.closeButton.remove();
|
||||||
} else {
|
} else {
|
||||||
this.addEventListener(this.closeButton, 'click', () => {
|
this.addEventListener(this.closeButton, EVENTS.CLICK, () => {
|
||||||
this.mainNode.remove();
|
this.mainNode.remove();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import Component from '../component/index';
|
import Component from '../component/Component';
|
||||||
import routeService from '../../services/RouteService';
|
import routeService from '../../../services/RouteService';
|
||||||
import {prepareToNumber} from '../../utils/urlUtils';
|
|
||||||
import {EVENTS} from '../../consts';
|
import {EVENTS} from '../../consts';
|
||||||
|
import {prepareToNumber} from '../../utils';
|
||||||
|
|
||||||
const LEFT_ICON = '«';
|
const LEFT_ICON = '«';
|
||||||
const RIGHT_ICON = '»';
|
const RIGHT_ICON = '»';
|
||||||
@ -44,7 +44,7 @@ class Pagination extends Component {
|
|||||||
if (text === this.currentPage) {
|
if (text === this.currentPage) {
|
||||||
li.classList.add('active');
|
li.classList.add('active');
|
||||||
}
|
}
|
||||||
this.addEventListener(button, 'click', () => {
|
this.addEventListener(button, EVENTS.CLICK, () => {
|
||||||
const nextPage = (() => {
|
const nextPage = (() => {
|
||||||
if (text === LEFT_ICON) {
|
if (text === LEFT_ICON) {
|
||||||
return this.currentPage - 1;
|
return this.currentPage - 1;
|
||||||
@ -1,8 +1,8 @@
|
|||||||
import Component from '../component/index';
|
import Component from '../component/Component';
|
||||||
import routeService from '../../services/RouteService';
|
import routeService from '../../../services/RouteService';
|
||||||
import NotFoundPage from '../not-found-page';
|
import NotFoundPage from '../../../pages/not-found/components/page/Page';
|
||||||
|
|
||||||
import {EVENTS} from '../../consts';
|
import {EVENTS, ROUTES} from '../../consts';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @interface Route
|
* @interface Route
|
||||||
@ -42,7 +42,7 @@ class RouterPagesContainer extends Component {
|
|||||||
}) || {};
|
}) || {};
|
||||||
|
|
||||||
// Показывает или прячет меню в зависимости от роут
|
// Показывает или прячет меню в зависимости от роут
|
||||||
if (['/login'].includes(url)) {
|
if ([ROUTES.LOGIN].includes(url)) {
|
||||||
mainMenu.hideMenu();
|
mainMenu.hideMenu();
|
||||||
} else {
|
} else {
|
||||||
mainMenu.showMenu();
|
mainMenu.showMenu();
|
||||||
@ -1,24 +1,25 @@
|
|||||||
import Component from '../component';
|
import Component from '../component/Component';
|
||||||
import './TableCellOverflow.css';
|
import './TableCellOverflow.css';
|
||||||
|
import {TAG_NAME} from '../../consts';
|
||||||
|
|
||||||
class TableCellOverflow extends Component {
|
class TableCellOverflow extends Component {
|
||||||
constructor (parentNode, text) {
|
constructor (parentNode, text) {
|
||||||
super(null, parentNode);
|
super(null, parentNode);
|
||||||
|
|
||||||
const cell = this.createElement({
|
const cell = this.createElement({
|
||||||
tagName: 'td',
|
tagName: TAG_NAME.TD,
|
||||||
parentNode: this.mainNode,
|
parentNode: this.mainNode,
|
||||||
});
|
});
|
||||||
|
|
||||||
const div = this.createElement({
|
const div = this.createElement({
|
||||||
tagName: 'div',
|
tagName: TAG_NAME.DIV,
|
||||||
parentNode: cell,
|
parentNode: cell,
|
||||||
options: {
|
options: {
|
||||||
className: 'TableCellOverflow__cellWrapper'
|
className: 'TableCellOverflow__cellWrapper'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const span = this.createElement({
|
const span = this.createElement({
|
||||||
tagName: 'span',
|
tagName: TAG_NAME.SPAN,
|
||||||
parentNode: div,
|
parentNode: div,
|
||||||
options: {
|
options: {
|
||||||
className: 'TableCellOverflow__cell',
|
className: 'TableCellOverflow__cell',
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import Component from '../component/index';
|
import Component from '../component/Component';
|
||||||
|
|
||||||
class HeaderCol extends Component {
|
class HeaderCol extends Component {
|
||||||
constructor (parentNode, col) {
|
constructor (parentNode, col) {
|
||||||
@ -1,11 +1,12 @@
|
|||||||
import Component from '../component';
|
import Component from '../component/Component';
|
||||||
|
import {TAG_NAME} from '../../consts';
|
||||||
|
|
||||||
class RowCol extends Component {
|
class RowCol extends Component {
|
||||||
constructor (parentNode, text) {
|
constructor (parentNode, text) {
|
||||||
super(null, parentNode);
|
super(null, parentNode);
|
||||||
|
|
||||||
this.createElement({
|
this.createElement({
|
||||||
tagName: 'td',
|
tagName: TAG_NAME.TD,
|
||||||
parentNode: this.mainNode,
|
parentNode: this.mainNode,
|
||||||
options: {
|
options: {
|
||||||
innerHTML: text,
|
innerHTML: text,
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import Component from '../component/index';
|
import Component from '../component/Component';
|
||||||
import HeaderCol from './HeaderCol';
|
import HeaderCol from './HeaderCol';
|
||||||
import TableRow from './TableRow';
|
import TableRow from './TableRow';
|
||||||
import TableRowWrapper from './TableRowWrapper';
|
import TableRowWrapper from './TableRowWrapper';
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import Component from '../component/index';
|
import Component from '../component/Component';
|
||||||
import RowCol from './RowCol';
|
import RowCol from './RowCol';
|
||||||
|
|
||||||
class TableRow extends Component {
|
class TableRow extends Component {
|
||||||
@ -1,15 +1,15 @@
|
|||||||
import Component from '../component';
|
import Component from '../component/Component';
|
||||||
import {EVENTS} from '../../consts';
|
import {EVENTS} from '../../consts';
|
||||||
|
|
||||||
class TableRowWrapper extends Component {
|
class TableRowWrapper extends Component {
|
||||||
constructor (parentNode) {
|
constructor (parentNode) {
|
||||||
super('#uni-table-row', parentNode);
|
super('#uni-table-row', parentNode);
|
||||||
|
|
||||||
this.addEventListener(this.mainNode, 'click', () => {
|
this.addEventListener(this.mainNode, EVENTS.CLICK, () => {
|
||||||
this.next(EVENTS.ROW_CLICK);
|
this.next(EVENTS.ROW_CLICK);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.addEventListener(this.mainNode, 'dblclick', () => {
|
this.addEventListener(this.mainNode, EVENTS.DBL_CLICK, () => {
|
||||||
this.next(EVENTS.ROW_DOUBLE_CLICK);
|
this.next(EVENTS.ROW_DOUBLE_CLICK);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
64
src/core/consts.js
Normal file
64
src/core/consts.js
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
export const EVENTS = {
|
||||||
|
ROUTE_CHANGE: 'routeChange',
|
||||||
|
ROUTE_SEARCH_CHANGE: 'routeSearchChange',
|
||||||
|
ROW_CLICK: 'rowClick',
|
||||||
|
ROW_DOUBLE_CLICK: 'rowDoubleClick',
|
||||||
|
CHANGE_USER_INFO: 'changeUserInfo',
|
||||||
|
CHANGE_USER_AVATAR: 'changeUserAvatar',
|
||||||
|
OPEN_MODAL: 'openModal',
|
||||||
|
CLICK: 'click',
|
||||||
|
DBL_CLICK: 'dblclick',
|
||||||
|
SUBMIT: 'submit',
|
||||||
|
FOCUS: 'focus',
|
||||||
|
KEYDOWN: 'keydown',
|
||||||
|
INPUT: 'input',
|
||||||
|
CHANGE: 'change',
|
||||||
|
CREATE_USER: 'createUser',
|
||||||
|
SAVE_USER: 'saveUser',
|
||||||
|
DELETE_USER: 'deleteUser',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const FORM_TYPES = {
|
||||||
|
TEXT: 'TEXT',
|
||||||
|
SELECT: 'SELECT',
|
||||||
|
TEXTAREA: 'TEXTAREA',
|
||||||
|
PASSWORD: 'PASSWORD',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const MODES = {
|
||||||
|
Create: 'create',
|
||||||
|
View: 'view',
|
||||||
|
Edit: 'edit',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const TAG_NAME = {
|
||||||
|
OPTION: 'option',
|
||||||
|
DIV: 'div',
|
||||||
|
INPUT: 'input',
|
||||||
|
SELECT: 'select',
|
||||||
|
TEXTAREA: 'textarea',
|
||||||
|
LABEL: 'label',
|
||||||
|
LI: 'li',
|
||||||
|
A: 'a',
|
||||||
|
TD: 'td',
|
||||||
|
SPAN: 'span',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const TABLE_TYPE = {
|
||||||
|
DEFAULT: 'table table-striped table-hover',
|
||||||
|
BORDERED: 'table table-bordered table-hover',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CAPTION_POSITION = {
|
||||||
|
TOP: 'caption-top',
|
||||||
|
BOTH: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ROUTES = {
|
||||||
|
MAIN: '/',
|
||||||
|
STORE: '/store',
|
||||||
|
LOGS: '/logs',
|
||||||
|
USERS: '/users',
|
||||||
|
LOGIN: '/login',
|
||||||
|
PROFILE: '/profile',
|
||||||
|
};
|
||||||
@ -1,5 +1,35 @@
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import toString from 'lodash/toString';
|
import toString from 'lodash/toString';
|
||||||
|
import {stringify} from 'querystring';
|
||||||
|
import toNumber from 'lodash/toNumber';
|
||||||
|
import {API_NAME_HEADER} from '../api/consts';
|
||||||
|
|
||||||
|
export const makeApiName = (headers) => {
|
||||||
|
return headers[API_NAME_HEADER] ? 'testing' : 'production';
|
||||||
|
};
|
||||||
|
|
||||||
|
export const makeDurationMessage = (startTime, endTime, format) => {
|
||||||
|
const duration = moment(endTime, format).millisecond() - moment(startTime, format).millisecond();
|
||||||
|
return `${duration} мс`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const prepareClientLogElement = (client) => {
|
||||||
|
const {request, response} = client;
|
||||||
|
const {headers, method, url} = request;
|
||||||
|
const {status, message} = response;
|
||||||
|
|
||||||
|
const data_base = makeApiName(headers);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...client,
|
||||||
|
data_base,
|
||||||
|
method,
|
||||||
|
url,
|
||||||
|
status: status || 500,
|
||||||
|
message: message || 'Критическая ошибка сервера',
|
||||||
|
duration: makeDurationMessage(client.startTime, client.endTime),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @interface CreateElementProps
|
* @interface CreateElementProps
|
||||||
@ -59,3 +89,30 @@ export const prepareServerDate = (stringDate) => {
|
|||||||
export const prepareObjectToString = (object) => {
|
export const prepareObjectToString = (object) => {
|
||||||
return JSON.stringify(object);
|
return JSON.stringify(object);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Из маршрута и объекта query создает строку для url
|
||||||
|
* @param {string} url - маршрут
|
||||||
|
* @param {Object<string, string>} query - объект с данными
|
||||||
|
*/
|
||||||
|
export const makeUrlWithQuery = (url = '', query = {}) => {
|
||||||
|
const stringQuery = stringify(query);
|
||||||
|
return url + (stringQuery ? `?${stringQuery}` : '');
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Преобразует текстовое значение из url'a в номер страницы. Если не получается, то возвращает 1 страницу.
|
||||||
|
* @param {unknown} number - значение из url'a, которое мы хотим превратить в номер страницы
|
||||||
|
* @param {number} countPages - общее количество страниц
|
||||||
|
*/
|
||||||
|
export const prepareToNumber = (number, countPages) => {
|
||||||
|
const prepare = toNumber(number);
|
||||||
|
const prepareNaN = Number.isNaN(prepare) ? 1 : prepare;
|
||||||
|
if (prepareNaN < 1) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (prepareNaN > countPages) {
|
||||||
|
return countPages;
|
||||||
|
}
|
||||||
|
return prepareNaN;
|
||||||
|
};
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import Component from '../component';
|
import Component from '../../../../core/components/component/Component';
|
||||||
import Image from '../../img/logo.svg';
|
import Image from '../../../../img/logo.svg';
|
||||||
import FormControl from '../form-control';
|
import FormControl from '../../../../core/components/form-control/FormControl';
|
||||||
import {FORM_TYPES} from '../../consts';
|
import {FORM_TYPES} from '../../../../core/consts';
|
||||||
|
|
||||||
class LoginForm extends Component {
|
class LoginForm extends Component {
|
||||||
constructor (parentNode) {
|
constructor (parentNode) {
|
||||||
@ -1,9 +1,10 @@
|
|||||||
import Component from '../component/index';
|
import Component from '../../../../core/components/component/Component';
|
||||||
import './LoginPage.css';
|
import './Page.css';
|
||||||
import LoginForm from '../login-form';
|
import LoginForm from '../login-form/LoginForm';
|
||||||
import authServiceApi from '../../api/AuthServiceAPI';
|
import authServiceApi from '../../../../api/AuthServiceAPI';
|
||||||
import routeService from '../../services/RouteService';
|
import routeService from '../../../../services/RouteService';
|
||||||
import notify from '../../services/NotifyService';
|
import notify from '../../../../services/NotifyService';
|
||||||
|
import {ROUTES, EVENTS} from '../../../../core/consts';
|
||||||
|
|
||||||
class LoginPage extends Component {
|
class LoginPage extends Component {
|
||||||
constructor (mainNodeSelector, parentNode) {
|
constructor (mainNodeSelector, parentNode) {
|
||||||
@ -11,13 +12,13 @@ class LoginPage extends Component {
|
|||||||
|
|
||||||
this.form = this.createComponent(LoginForm, this.mainNode);
|
this.form = this.createComponent(LoginForm, this.mainNode);
|
||||||
|
|
||||||
this.addSubscribe(this.form, 'submit', ({login, password}) => {
|
this.addSubscribe(this.form, EVENTS.SUBMIT, ({login, password}) => {
|
||||||
this.form.disabled(true);
|
this.form.disabled(true);
|
||||||
authServiceApi.auth(login, password)
|
authServiceApi.auth(login, password)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.form.disabled(false);
|
this.form.disabled(false);
|
||||||
notify.success('Вы авторизованы');
|
notify.success('Вы авторизованы');
|
||||||
routeService.goTo('/');
|
routeService.goTo(ROUTES.MAIN);
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
const message = e?.response?.data?.message || 'Неизвестная ошибка';
|
const message = e?.response?.data?.message || 'Неизвестная ошибка';
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import {ENDPOINTS} from './consts';
|
import {ENDPOINTS} from '../../../api/consts';
|
||||||
import adminConfigsService from '../services/AdminConfigsService';
|
import adminConfigsService from '../../../services/AdminConfigsService';
|
||||||
import http from './HttpAPI';
|
import http from '../../../api/HttpAPI';
|
||||||
|
|
||||||
class StorageLogsApi {
|
class StorageLogsApi {
|
||||||
constructor () {
|
constructor () {
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import Table from '../table';
|
import Table from '../../../../core/components/table/Table';
|
||||||
import {LOG_COLS, LOG_TYPE} from '../../consts';
|
|
||||||
import ClientLogsTableRow from './ClientLogsTableRow';
|
import ClientLogsTableRow from './ClientLogsTableRow';
|
||||||
|
import {LOG_COLS, LOG_TYPE} from '../../consts';
|
||||||
|
|
||||||
class ClientLogsTable extends Table {
|
class ClientLogsTable extends Table {
|
||||||
constructor () {
|
constructor () {
|
||||||
@ -1,5 +1,5 @@
|
|||||||
import Component from '../component';
|
import Component from '../../../../core/components/component/Component';
|
||||||
import TableCellOverflow from '../table-cell-overflow';
|
import TableCellOverflow from '../../../../core/components/table-cell-overflow/TableCellOverflow';
|
||||||
|
|
||||||
class ClientLogsTableRow extends Component {
|
class ClientLogsTableRow extends Component {
|
||||||
constructor (parentNode, cols, row) {
|
constructor (parentNode, cols, row) {
|
||||||
@ -1,11 +1,11 @@
|
|||||||
import Component from '../component';
|
import Component from '../../../../core/components/component/Component';
|
||||||
import FormControl from '../form-control';
|
import FormControl from '../../../../core/components/form-control/FormControl';
|
||||||
import {FORM_TYPES, TAG_NAME} from '../../consts';
|
import {FORM_TYPES, TAG_NAME} from '../../../../core/consts';
|
||||||
import ModalSidebar from '../modal-sidebar';
|
import ModalSidebar from '../../../../core/components/modal-sidebar/ModalSibebar';
|
||||||
import './ClientLogsViewForm.css';
|
import './ClientLogsViewForm.css';
|
||||||
import {INPUT_IDS, LABELS, CLASSNAMES} from './consts';
|
import {INPUT_IDS, LABELS, CLASSNAMES} from './consts';
|
||||||
import {makeApiName, makeDurationMessage} from '../../utils/converters';
|
import HeadersTable from '../headers-table/HeadersTable';
|
||||||
import HeadersTable from '../headers-table';
|
import {makeDurationMessage, makeApiName} from '../../../../core/utils';
|
||||||
|
|
||||||
const FORMAT = 'DD/MM/YYYY HH:mm:ss';
|
const FORMAT = 'DD/MM/YYYY HH:mm:ss';
|
||||||
|
|
||||||
@ -1,5 +1,5 @@
|
|||||||
import Component from '../component';
|
import Component from '../../../../core/components/component/Component';
|
||||||
import TableCellOverflow from '../table-cell-overflow';
|
import TableCellOverflow from '../../../../core/components/table-cell-overflow/TableCellOverflow';
|
||||||
|
|
||||||
class HeaderTableRow extends Component {
|
class HeaderTableRow extends Component {
|
||||||
constructor (parentNode, cols, row) {
|
constructor (parentNode, cols, row) {
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import Table from '../table';
|
import Table from '../../../../core/components/table/Table';
|
||||||
import HeaderTableRow from './HeaderTableRow';
|
import HeaderTableRow from './HeaderTableRow';
|
||||||
import {TABLE_TYPE} from '../../consts';
|
import {TABLE_TYPE} from '../../../../core/consts';
|
||||||
|
|
||||||
const COLUMNS = [
|
const COLUMNS = [
|
||||||
{id: 'header', label: 'Заголовок'},
|
{id: 'header', label: 'Заголовок'},
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import Component from '../component/index';
|
import Component from '../../../../core/components/component/Component';
|
||||||
import routeService from '../../services/RouteService';
|
import routeService from '../../../../services/RouteService';
|
||||||
import {LOG_TYPE, LOG_LABELS} from '../../consts';
|
|
||||||
import './LogsFilters.css';
|
import './LogsFilters.css';
|
||||||
|
import {LOG_TYPE, LOG_LABELS} from '../../consts';
|
||||||
|
|
||||||
class LogsFilters extends Component {
|
class LogsFilters extends Component {
|
||||||
constructor (parentNode) {
|
constructor (parentNode) {
|
||||||
@ -1,17 +1,16 @@
|
|||||||
import toString from 'lodash/toString';
|
import toString from 'lodash/toString';
|
||||||
import Component from '../component/index';
|
import Component from '../../../../core/components/component/Component';
|
||||||
import storageLogsApi from '../../api/StorageLogsAPI';
|
import storageLogsApi from '../../api/StorageLogsAPI';
|
||||||
import Pagination from '../pagination';
|
import Pagination from '../../../../core/components/pagination/Pagination';
|
||||||
import LogsFilters from '../logs-filters';
|
import LogsFilters from '../logs-filters/LogsFilters';
|
||||||
import routeService from '../../services/RouteService';
|
import routeService from '../../../../services/RouteService';
|
||||||
import {prepareToNumber} from '../../utils/urlUtils';
|
import {EVENTS} from '../../../../core/consts';
|
||||||
import {LOG_TYPE, EVENTS} from '../../consts';
|
import ServerLogsTable from '../server-logs-table/ServerLogsTable';
|
||||||
import {markText, prepareServerDate, prepareObjectToString} from '../../utils/elementUtils';
|
import ClientLogsTable from '../client-logs-table/ClientLogsTable';
|
||||||
import ServerLogsTable from '../server-logs-table';
|
import ClientLogsViewForm from '../client-logs-view-form/ClientLogsViewForm';
|
||||||
import ClientLogsTable from '../client-logs-table';
|
import ServerLogsViewForm from '../server-logs-view-form/ServerLogsViewForm';
|
||||||
import ClientLogsViewForm from '../client-logs-view-form';
|
import {prepareClientLogElement, markText, prepareToNumber, prepareServerDate, prepareObjectToString} from '../../../../core/utils';
|
||||||
import ServerLogsViewForm from '../server-logs-view-form';
|
import {LOG_TYPE} from '../../consts';
|
||||||
import {prepareClientLogElement} from '../../utils/converters';
|
|
||||||
|
|
||||||
const ELEMENTS_ON_PAGE = 15;
|
const ELEMENTS_ON_PAGE = 15;
|
||||||
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import Table from '../table';
|
import Table from '../../../../core/components/table/Table';
|
||||||
import {LOG_TYPE, LOG_COLS} from '../../consts';
|
|
||||||
import ServerLogsTableRow from './ServerLogsTableRow';
|
import ServerLogsTableRow from './ServerLogsTableRow';
|
||||||
|
import {LOG_COLS, LOG_TYPE} from '../../consts';
|
||||||
|
|
||||||
class ServerLogsTable extends Table {
|
class ServerLogsTable extends Table {
|
||||||
constructor () {
|
constructor () {
|
||||||
@ -1,5 +1,5 @@
|
|||||||
import Component from '../component';
|
import Component from '../../../../core/components/component/Component';
|
||||||
import TableCellOverflow from '../table-cell-overflow';
|
import TableCellOverflow from '../../../../core/components/table-cell-overflow/TableCellOverflow';
|
||||||
|
|
||||||
class ServerLogsTableRow extends Component {
|
class ServerLogsTableRow extends Component {
|
||||||
constructor (parentNode, cols, row) {
|
constructor (parentNode, cols, row) {
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import Component from '../component';
|
import Component from '../../../../core/components/component/Component';
|
||||||
import ModalSidebar from '../modal-sidebar';
|
import ModalSidebar from '../../../../core/components/modal-sidebar/ModalSibebar';
|
||||||
import FormControl from '../form-control';
|
import FormControl from '../../../../core/components/form-control/FormControl';
|
||||||
import {FORM_TYPES} from '../../consts';
|
import {FORM_TYPES} from '../../../../core/consts';
|
||||||
import './ServerLogsViewForm.css';
|
import './ServerLogsViewForm.css';
|
||||||
|
|
||||||
class ServerLogsViewForm extends Component {
|
class ServerLogsViewForm extends Component {
|
||||||
33
src/pages/logs/consts.js
Normal file
33
src/pages/logs/consts.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
export const LOG_TYPE = {
|
||||||
|
SERVER: 'server-logs',
|
||||||
|
CLIENT: 'client-logs',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const LOG_LABELS = [
|
||||||
|
{id: LOG_TYPE.SERVER, label: 'Ошибки сервера'},
|
||||||
|
{id: LOG_TYPE.CLIENT, label: 'Ошибки запросов'},
|
||||||
|
];
|
||||||
|
|
||||||
|
const SERVER_COLS = [
|
||||||
|
{id: '_id', label: 'id', width: '240px'},
|
||||||
|
{id: 'date', label: 'Дата', width: '150px'},
|
||||||
|
{id: 'type', label: 'Тип записи', width: '120px'},
|
||||||
|
{id: 'message', label: 'Сообщение', width: '200px'},
|
||||||
|
{id: 'trace', label: 'Стек', width: '200px'},
|
||||||
|
];
|
||||||
|
|
||||||
|
const CLIENT_COLS = [
|
||||||
|
{id: 'startTime', label: 'Дата запроса', width: '150px'},
|
||||||
|
{id: 'type', label: 'Результат', width: '100px'},
|
||||||
|
{id: 'data_base', label: 'База данных'},
|
||||||
|
{id: 'url', label: 'URL'},
|
||||||
|
{id: 'method', label: 'Метод'},
|
||||||
|
{id: 'status', label: 'Код ответа'},
|
||||||
|
{id: 'message', label: 'Сообщение'},
|
||||||
|
{id: 'duration', label: 'Скорость ответа'},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const LOG_COLS = {
|
||||||
|
[LOG_TYPE.SERVER]: SERVER_COLS,
|
||||||
|
[LOG_TYPE.CLIENT]: CLIENT_COLS,
|
||||||
|
};
|
||||||
@ -1,5 +1,5 @@
|
|||||||
import Component from '../component/index';
|
import Component from '../../../../core/components/component/Component';
|
||||||
import MainStatistic from '../main-statistic';
|
import MainStatistic from '../statistic/Statistic';
|
||||||
|
|
||||||
class MainPage extends Component {
|
class MainPage extends Component {
|
||||||
constructor (mainNodeSelector, parentNode) {
|
constructor (mainNodeSelector, parentNode) {
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import Component from '../component/index';
|
import Component from '../../../../core/components/component/Component';
|
||||||
import './MainStatistic.css';
|
import './Statistic.css';
|
||||||
import storageApi from '../../api/StorageServiceAPI';
|
import storageApi from '../../../storages/api/StorageServiceAPI';
|
||||||
|
|
||||||
class MainStatistic extends Component {
|
class MainStatistic extends Component {
|
||||||
constructor (parentNode) {
|
constructor (parentNode) {
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import Component from '../component/Component';
|
import Component from '../../../../core/components/component/Component';
|
||||||
|
|
||||||
class NotFoundContent extends Component {
|
class NotFoundContent extends Component {
|
||||||
constructor (parentNode) {
|
constructor (parentNode) {
|
||||||
@ -1,7 +1,8 @@
|
|||||||
import Component from '../component/index';
|
import Component from '../../../../core/components/component/Component';
|
||||||
import routeService from '../../services/RouteService';
|
import routeService from '../../../../services/RouteService';
|
||||||
import NotFoundContent from '../not-found-content';
|
import NotFoundContent from '../not-found-content/NotFoundContent';
|
||||||
import './NotFoundPage.css';
|
import './Page.css';
|
||||||
|
import {ROUTES, EVENTS} from '../../../../core/consts';
|
||||||
|
|
||||||
class NotFoundPage extends Component {
|
class NotFoundPage extends Component {
|
||||||
constructor (mainNodeSelector, parentNode) {
|
constructor (mainNodeSelector, parentNode) {
|
||||||
@ -10,8 +11,8 @@ class NotFoundPage extends Component {
|
|||||||
this.mainNodeSelector = this.mainNode.querySelector('.NotFound__text');
|
this.mainNodeSelector = this.mainNode.querySelector('.NotFound__text');
|
||||||
this.mainNodeSelector.textContent = `Запрашиваемая Вами страница ${location.pathname} не найдена`;
|
this.mainNodeSelector.textContent = `Запрашиваемая Вами страница ${location.pathname} не найдена`;
|
||||||
this.redirectButton = this.mainNode.querySelector('.NotFound__redirectButton');
|
this.redirectButton = this.mainNode.querySelector('.NotFound__redirectButton');
|
||||||
this.addEventListener(this.redirectButton, 'click', () => {
|
this.addEventListener(this.redirectButton, EVENTS.CLICK, () => {
|
||||||
routeService.goTo('/');
|
routeService.goTo(ROUTES.MAIN);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,17 +1,16 @@
|
|||||||
import Modal from '../modal/Modal';
|
import Modal from '../../../../core/components/modal/Modal';
|
||||||
import {createElement} from '../../utils/elementUtils';
|
import FormControl from '../../../../core/components/form-control/FormControl';
|
||||||
import FormControl from '../form-control/index';
|
|
||||||
import './AvatarModal.css';
|
import './AvatarModal.css';
|
||||||
import usersServiceApi from '../../api/UsersServiceAPI';
|
import userInfoService from '../../../../services/UserInfoService';
|
||||||
import userInfoService from '../../services/UserInfoService';
|
import {EVENTS} from '../../../../core/consts';
|
||||||
import {EVENTS} from '../../consts';
|
import profileServiceApi from '../../../../api/ProfileServiceAPI';
|
||||||
|
|
||||||
class AvatarModal extends Modal {
|
class AvatarModal extends Modal {
|
||||||
constructor (parentNode) {
|
constructor (parentNode) {
|
||||||
super(parentNode);
|
super(parentNode);
|
||||||
|
|
||||||
this.header.textContent = 'Основное изображение';
|
this.header.textContent = 'Основное изображение';
|
||||||
this.avatar = createElement({
|
this.avatar = this.createElement({
|
||||||
tagName: 'div',
|
tagName: 'div',
|
||||||
options: {
|
options: {
|
||||||
className: 'Avatar__img',
|
className: 'Avatar__img',
|
||||||
@ -28,7 +27,7 @@ class AvatarModal extends Modal {
|
|||||||
className: 'Avatar__url-input'
|
className: 'Avatar__url-input'
|
||||||
});
|
});
|
||||||
|
|
||||||
this.submitBtn = createElement({
|
this.submitBtn = this.createElement({
|
||||||
tagName: 'button',
|
tagName: 'button',
|
||||||
options: {
|
options: {
|
||||||
className: 'Avatar__submit-btn btn btn-outline-primary'
|
className: 'Avatar__submit-btn btn btn-outline-primary'
|
||||||
@ -53,7 +52,7 @@ class AvatarModal extends Modal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init = async () => {
|
init = async () => {
|
||||||
const user = await usersServiceApi.getSelfInfo();
|
const user = await profileServiceApi.getSelfInfo();
|
||||||
this.changeAvatar(this.url || user.avatar);
|
this.changeAvatar(this.url || user.avatar);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +62,7 @@ class AvatarModal extends Modal {
|
|||||||
|
|
||||||
submit = async () => {
|
submit = async () => {
|
||||||
if (this.url) {
|
if (this.url) {
|
||||||
await usersServiceApi.editSelfInfo({avatar: this.url});
|
await profileServiceApi.editSelfInfo({avatar: this.url});
|
||||||
userInfoService.setUserLogin();
|
userInfoService.setUserLogin();
|
||||||
this.hide();
|
this.hide();
|
||||||
} else {
|
} else {
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user