HM-125. Добавление работы с пользователями (#59)
This commit is contained in:
@ -31,7 +31,7 @@ class UsersService {
|
||||
return data;
|
||||
}
|
||||
|
||||
getMe = async () => {
|
||||
getSelfInfo = async () => {
|
||||
const {data} = await http.get(`${ROOT_URL}/me`);
|
||||
return data;
|
||||
}
|
||||
@ -69,8 +69,8 @@ class UsersService {
|
||||
* @param {string} login - Логин пользователя
|
||||
* @param {UpdateUserOptions} updateOptions - настройки для обновления пользователя
|
||||
*/
|
||||
update = async (login, updateOptions) => {
|
||||
const {data} = await http.put(ROOT_URL, {...updateOptions, login});
|
||||
update = async (user) => {
|
||||
const {data} = await http.put(ROOT_URL, user);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ html, body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.Page > div:not(.Login__page) {
|
||||
.Page > div:first-child:not(.Login__page) {
|
||||
padding-top: 74px;
|
||||
}
|
||||
|
||||
|
||||
15
src/app.html
15
src/app.html
@ -390,6 +390,21 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Шаблоны форм для просмотры логов -->
|
||||
<template id="user-view-form">
|
||||
<div class="h-100 overflow-auto d-flex flex-column">
|
||||
<p class="h2 mb-2 p-3 pr-5 sticky-top border-bottom bg-light"></p>
|
||||
<form class="p-3 h" autocomplete="off"></form>
|
||||
<div class="mt-auto p-3 pr-5 border-top bg-light">
|
||||
<button type="button" class="btn btn-primary UserViewForm__create">Создать</button>
|
||||
<button type="button" class="btn btn-primary UserViewForm__save">Сохранить</button>
|
||||
<button type="button" class="btn btn-warning UserViewForm__edit">Изменить</button>
|
||||
<button type="button" class="btn btn-danger UserViewForm__delete">Удалить</button>
|
||||
<button type="button" class="btn btn-secondary UserViewForm__cancel">Отмена</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Шаблоны форм для просмотры api -->
|
||||
<template id="api-view-form">
|
||||
<div class="h-100 overflow-auto Api__view-container">
|
||||
|
||||
@ -53,7 +53,7 @@ class AvatarModal extends Modal {
|
||||
}
|
||||
|
||||
init = async () => {
|
||||
const user = await usersServiceApi.getMe();
|
||||
const user = await usersServiceApi.getSelfInfo();
|
||||
this.changeAvatar(this.url || user.avatar);
|
||||
}
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ import FormControl from '../form-control';
|
||||
import {FORM_TYPES} from '../../consts';
|
||||
import ModalSidebar from '../modal-sidebar';
|
||||
import './ClientLogsViewForm.css';
|
||||
import {INPUT_IDS, LABELS, CLASSNAMES} from './consts';
|
||||
|
||||
class ClientLogsViewForm extends Component {
|
||||
constructor (parentNode) {
|
||||
@ -15,44 +16,50 @@ class ClientLogsViewForm extends Component {
|
||||
this.title = this.mainNode.querySelector('.h2');
|
||||
this.form = this.mainNode.querySelector('form');
|
||||
|
||||
this.title.textContent = 'Просмотр клиентского запроса';
|
||||
this.title.textContent = LABELS.VIEW_CLIENT_REQUEST;
|
||||
|
||||
const inputs = [
|
||||
this.idInput = this.createComponent(FormControl, this.form, {
|
||||
id: 'client-logs-view-form-id',
|
||||
label: 'id',
|
||||
id: INPUT_IDS.ID,
|
||||
label: LABELS.ID,
|
||||
}),
|
||||
this.resultInput = this.createComponent(FormControl, this.form, {
|
||||
id: 'client-logs-view-form-result',
|
||||
label: 'Результат',
|
||||
id: INPUT_IDS.RESULT,
|
||||
label: LABELS.RESULT,
|
||||
}),
|
||||
this.startTimeInput = this.createComponent(FormControl, this.form, {
|
||||
id: 'client-logs-view-form-startTime',
|
||||
label: 'Время запроса',
|
||||
id: INPUT_IDS.START_TIME,
|
||||
label: LABELS.TIME_REQUEST,
|
||||
}),
|
||||
this.headersInput = this.createComponent(FormControl, this.form, {
|
||||
id: 'client-logs-view-form-headers',
|
||||
label: 'Заголовки запроса',
|
||||
id: INPUT_IDS.HEADERS,
|
||||
label: LABELS.HEADERS_REQUEST,
|
||||
type: FORM_TYPES.TEXTAREA,
|
||||
className: 'ClientLogsViewForm__headersInput',
|
||||
className: CLASSNAMES.HEADERS_INPUT,
|
||||
}),
|
||||
this.bodyRequest = this.createComponent(FormControl, this.form, {
|
||||
id: INPUT_IDS.BODY,
|
||||
label: LABELS.BODY_REQUEST,
|
||||
type: FORM_TYPES.TEXTAREA,
|
||||
className: CLASSNAMES.HEADERS_INPUT,
|
||||
}),
|
||||
this.urlInput = this.createComponent(FormControl, this.form, {
|
||||
id: 'client-logs-view-form-url',
|
||||
label: 'URL запроса',
|
||||
id: INPUT_IDS.URL,
|
||||
label: LABELS.URL_REQUEST,
|
||||
}),
|
||||
this.methodInput = this.createComponent(FormControl, this.form, {
|
||||
id: 'client-logs-view-form-method',
|
||||
label: 'Метод запроса',
|
||||
id: INPUT_IDS.METHOD,
|
||||
label: LABELS.METHOD_REQUEST,
|
||||
}),
|
||||
this.endTimeInput = this.createComponent(FormControl, this.form, {
|
||||
id: 'client-logs-view-form-endTime',
|
||||
label: 'Время ответа',
|
||||
id: INPUT_IDS.END_TIME,
|
||||
label: LABELS.TIME_RESPONSE,
|
||||
}),
|
||||
this.responseInput = this.createComponent(FormControl, this.form, {
|
||||
id: 'client-logs-view-form-response',
|
||||
label: 'Ответ сервера',
|
||||
id: INPUT_IDS.RESPONSE,
|
||||
label: LABELS.SERVER_RESPONSE,
|
||||
type: FORM_TYPES.TEXTAREA,
|
||||
className: 'ClientLogsViewForm__responseInput',
|
||||
className: CLASSNAMES.RESPONSE_INPUT,
|
||||
}),
|
||||
];
|
||||
inputs.forEach((input) => {
|
||||
@ -65,8 +72,13 @@ class ClientLogsViewForm extends Component {
|
||||
return JSON.stringify(object, false, 4);
|
||||
}
|
||||
|
||||
setForm ({_id, type, request, response, startTime, endTime}) {
|
||||
const {headers, url, method} = JSON.parse(request) ?? {};
|
||||
setRequestBody = (body) => {
|
||||
this.bodyRequest.setValue(this.prepareStringJSON(body));
|
||||
this.bodyRequest.mainNode.style.display = body ? 'block' : 'none';
|
||||
}
|
||||
|
||||
setForm = ({_id, type, request, response, startTime, endTime}) => {
|
||||
const {headers, url, method, body} = JSON.parse(request) ?? {};
|
||||
this.idInput.setValue(_id);
|
||||
this.resultInput.setValue(type);
|
||||
this.startTimeInput.setValue(startTime);
|
||||
@ -75,6 +87,7 @@ class ClientLogsViewForm extends Component {
|
||||
this.methodInput.setValue(method);
|
||||
this.endTimeInput.setValue(endTime);
|
||||
this.responseInput.setValue(this.prepareStringJSON(response));
|
||||
this.setRequestBody(body);
|
||||
this.sidebar.show();
|
||||
}
|
||||
}
|
||||
|
||||
29
src/components/client-logs-view-form/consts.js
Normal file
29
src/components/client-logs-view-form/consts.js
Normal file
@ -0,0 +1,29 @@
|
||||
export const INPUT_IDS = {
|
||||
ID: 'client-logs-view-form-id',
|
||||
RESULT: 'client-logs-view-form-result',
|
||||
START_TIME: 'client-logs-view-form-startTime',
|
||||
HEADERS: 'client-logs-view-form-headers',
|
||||
BODY: 'client-logs-view-form-body-request',
|
||||
URL: 'client-logs-view-form-url',
|
||||
METHOD: 'client-logs-view-form-method',
|
||||
END_TIME: 'client-logs-view-form-endTime',
|
||||
RESPONSE: 'client-logs-view-form-response',
|
||||
};
|
||||
|
||||
export const LABELS = {
|
||||
ID: 'id',
|
||||
RESULT: 'Результат',
|
||||
TIME_REQUEST: 'Время запроса',
|
||||
HEADERS_REQUEST: 'Заголовки запроса',
|
||||
BODY_REQUEST: 'Тело запроса',
|
||||
URL_REQUEST: 'URL запроса',
|
||||
METHOD_REQUEST: 'Метод запроса',
|
||||
TIME_RESPONSE: 'Время ответа',
|
||||
SERVER_RESPONSE: 'Ответ сервера',
|
||||
VIEW_CLIENT_REQUEST: 'Просмотр клиентского запроса',
|
||||
};
|
||||
|
||||
export const CLASSNAMES = {
|
||||
HEADERS_INPUT: 'ClientLogsViewForm__headersInput',
|
||||
RESPONSE_INPUT: 'ClientLogsViewForm__responseInput',
|
||||
};
|
||||
@ -1,5 +1,5 @@
|
||||
import Component from '../component';
|
||||
import {FORM_TYPES} from '../../consts';
|
||||
import {FORM_TYPES, EVENTS, TAG_NAME} from '../../consts';
|
||||
|
||||
class FormControl extends Component {
|
||||
constructor (parentNode, {
|
||||
@ -7,9 +7,11 @@ class FormControl extends Component {
|
||||
id,
|
||||
type = FORM_TYPES.TEXT,
|
||||
placeholder = '',
|
||||
pattern,
|
||||
initValue = '',
|
||||
className = '',
|
||||
required = false,
|
||||
options = [],
|
||||
} = {}) {
|
||||
super('#form-control', parentNode);
|
||||
|
||||
@ -18,11 +20,12 @@ class FormControl extends Component {
|
||||
this.input = this.createElement({
|
||||
tagName: this.getInputTagName(type),
|
||||
options: {
|
||||
className: `form-control ${className}`,
|
||||
className: `${this.getInputBaseClassName(type)} ${className}`,
|
||||
},
|
||||
args: {
|
||||
type: type === FORM_TYPES.PASSWORD ? 'password' : 'text',
|
||||
...(required ? {required: ''} : {}),
|
||||
...(pattern ? {pattern} : {}),
|
||||
}
|
||||
});
|
||||
this.input.placeholder = placeholder;
|
||||
@ -33,12 +36,31 @@ class FormControl extends Component {
|
||||
this.label.textContent = label;
|
||||
this.label.setAttribute('for', id);
|
||||
|
||||
this.addEventListener(this.input, 'focus', this.clearError);
|
||||
this.addEventListener(this.input, 'click', this.clearError);
|
||||
this.addEventListener(this.input, 'keydown', this.clearError);
|
||||
this.addEventListener(this.input, 'input', (evt) => {
|
||||
this.next('input', evt);
|
||||
this.addEventListener(this.input, EVENTS.FOCUS, this.clearError);
|
||||
this.addEventListener(this.input, EVENTS.CLICK, this.clearError);
|
||||
this.addEventListener(this.input, EVENTS.KEYDOWN, this.clearError);
|
||||
this.addEventListener(this.input, EVENTS.INPUT, (evt) => {
|
||||
this.next(EVENTS.INPUT, evt);
|
||||
});
|
||||
|
||||
if (type === FORM_TYPES.SELECT) {
|
||||
options.forEach(({value, text}) => {
|
||||
this.createElement({
|
||||
tagName: TAG_NAME.OPTION,
|
||||
parentNode: this.input,
|
||||
options: {
|
||||
textContent: text,
|
||||
},
|
||||
args: {
|
||||
value,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
this.addEventListener(this.input, EVENTS.CHANGE, (evt) => {
|
||||
this.next(EVENTS.CHANGE, evt);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
disabled = (value) => {
|
||||
@ -61,20 +83,29 @@ class FormControl extends Component {
|
||||
this.errorText.textContent = '';
|
||||
}
|
||||
|
||||
getInputTagName (type) {
|
||||
getInputTagName = (type) => {
|
||||
switch (type) {
|
||||
case FORM_TYPES.TEXT:
|
||||
case FORM_TYPES.PASSWORD:
|
||||
return 'input';
|
||||
return TAG_NAME.INPUT;
|
||||
case FORM_TYPES.SELECT:
|
||||
return 'select';
|
||||
return TAG_NAME.SELECT;
|
||||
case FORM_TYPES.TEXTAREA:
|
||||
return 'textarea';
|
||||
return TAG_NAME.TEXTAREA;
|
||||
default: {
|
||||
throw new Error(`Тип формы ${type} не поддерживается`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getInputBaseClassName = (type) => {
|
||||
switch (type) {
|
||||
case FORM_TYPES.SELECT:
|
||||
return 'form-select';
|
||||
default:
|
||||
return 'form-control';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default FormControl;
|
||||
|
||||
@ -23,7 +23,7 @@ class ProfilePage extends Component {
|
||||
}
|
||||
|
||||
init = async () => {
|
||||
this.user = await usersServiceApi.getMe();
|
||||
this.user = await usersServiceApi.getSelfInfo();
|
||||
this.form.initProfile(this.user);
|
||||
}
|
||||
}
|
||||
|
||||
236
src/components/user-view-form/UserViewForm.js
Normal file
236
src/components/user-view-form/UserViewForm.js
Normal file
@ -0,0 +1,236 @@
|
||||
import Component from '../component';
|
||||
import ModalSidebar from '../modal-sidebar';
|
||||
import FormControl from '../form-control';
|
||||
import {FORM_TYPES, EVENTS, MODES} from '../../consts';
|
||||
import routeService from '../../services/RouteService';
|
||||
import usersServiceApi from '../../api/UsersServiceAPI';
|
||||
import userInfoService from '../../services/UserInfoService';
|
||||
|
||||
const TITLE_MODES = {
|
||||
[MODES.Create]: 'Создание пользователя',
|
||||
[MODES.View]: 'Просмотр пользователя',
|
||||
[MODES.Edit]: 'Редактирование пользователя',
|
||||
};
|
||||
|
||||
const EDIT_MODES = [MODES.Create, MODES.Edit];
|
||||
|
||||
const TRUE = 'true';
|
||||
|
||||
class UserViewForm extends Component {
|
||||
constructor (parentNode) {
|
||||
super('#user-view-form', parentNode);
|
||||
|
||||
this.sidebar = this.createComponent(ModalSidebar, {
|
||||
content: this.mainNode,
|
||||
});
|
||||
|
||||
this.title = this.mainNode.querySelector('.h2');
|
||||
this.form = this.mainNode.querySelector('form');
|
||||
|
||||
this.inputs = [
|
||||
this.login = this.createComponent(FormControl, this.form, {
|
||||
id: 'user-view-form-login',
|
||||
label: 'Логин пользователя',
|
||||
pattern: '^[a-zA-Z][a-zA-Z0-9_-]{3,}$',
|
||||
required: true,
|
||||
offComplete: true,
|
||||
}),
|
||||
this.password = this.createComponent(FormControl, this.form, {
|
||||
id: 'user-view-form-password',
|
||||
label: 'Пароль',
|
||||
type: FORM_TYPES.PASSWORD,
|
||||
}),
|
||||
this.avatar = this.createComponent(FormControl, this.form, {
|
||||
id: 'user-view-form-avatar',
|
||||
label: 'Аватар',
|
||||
}),
|
||||
this.isAdmin = this.createComponent(FormControl, this.form, {
|
||||
id: 'user-view-form-is-admin',
|
||||
label: 'Админ',
|
||||
type: FORM_TYPES.SELECT,
|
||||
options: [
|
||||
{value: true, text: 'Да'},
|
||||
{value: false, text: 'Нет'},
|
||||
]
|
||||
}),
|
||||
];
|
||||
|
||||
this.password.input.setAttribute('autocomplete', 'new-password');
|
||||
|
||||
this.buttons = [
|
||||
{
|
||||
button: this.createButton = this.mainNode.querySelector('.UserViewForm__create'),
|
||||
modes: [MODES.Create],
|
||||
onlyAdmin: true,
|
||||
},
|
||||
{
|
||||
button: this.saveButton = this.mainNode.querySelector('.UserViewForm__save'),
|
||||
modes: [MODES.Edit],
|
||||
onlyAdmin: true,
|
||||
},
|
||||
{
|
||||
button: this.editButton = this.mainNode.querySelector('.UserViewForm__edit'),
|
||||
modes: [MODES.View],
|
||||
onlyAdmin: true,
|
||||
},
|
||||
{
|
||||
button: this.cancelButton = this.mainNode.querySelector('.UserViewForm__cancel'),
|
||||
modes: [MODES.Create, MODES.Edit, MODES.View],
|
||||
},
|
||||
{
|
||||
button: this.deleteButton = this.mainNode.querySelector('.UserViewForm__delete'),
|
||||
modes: [MODES.View, MODES.Edit],
|
||||
onlyAdmin: true,
|
||||
}
|
||||
];
|
||||
|
||||
this.addEventListener(this.cancelButton, 'click', () => {
|
||||
routeService.pushQuery({}, true);
|
||||
});
|
||||
|
||||
this.addEventListener(this.editButton, 'click', () => {
|
||||
routeService.pushQuery({mode: MODES.Edit});
|
||||
});
|
||||
|
||||
this.addEventListener(this.form, 'submit', (event) => {
|
||||
event.preventDefault();
|
||||
});
|
||||
this.addEventListener(this.createButton, 'click', this.createUser);
|
||||
this.addEventListener(this.saveButton, 'click', this.saveUser);
|
||||
this.addEventListener(this.deleteButton, 'click', this.deleteUser);
|
||||
|
||||
this.addSubscribe(routeService, EVENTS.ROUTE_SEARCH_CHANGE, ({query}) => {
|
||||
const {mode, login} = query;
|
||||
this.setForm(login, mode);
|
||||
});
|
||||
|
||||
const {query: {mode, login}} = routeService.getUrlData();
|
||||
if (mode) {
|
||||
this.setForm(login, mode);
|
||||
}
|
||||
|
||||
this.addSubscribe(userInfoService, EVENTS.CHANGE_USER_INFO, ({is_admin}) => {
|
||||
this.createButton.disabled = !is_admin;
|
||||
this.createButton.saveButton = !is_admin;
|
||||
});
|
||||
}
|
||||
|
||||
setSidebarTitle = (mode, userName) => {
|
||||
this.title.textContent = [TITLE_MODES[mode], userName].filter(Boolean).join(' ');
|
||||
}
|
||||
|
||||
setInputDisabled = (mode) => {
|
||||
const disabled = !EDIT_MODES.includes(mode);
|
||||
this.inputs.forEach((input) => {
|
||||
const disabledLogin = this.login === input && mode === MODES.Edit;
|
||||
input.disabled(disabled ? disabled : disabledLogin);
|
||||
});
|
||||
}
|
||||
|
||||
validateInputs = () => {
|
||||
this.form.classList.add('was-validated');
|
||||
const login = this.login.getValue();
|
||||
|
||||
const loginErrorMessage = (() => {
|
||||
if (!login) {
|
||||
return 'Заполните логин';
|
||||
}
|
||||
if (login.length < 4) {
|
||||
return 'Длинна логина минимум 4 символа';
|
||||
}
|
||||
|
||||
if (!/^[a-z][a-z0-9_-]*$/.test(login)) {
|
||||
return 'Логин может содержать только латинские буквы, цифры, тире и нижнее подчеркивание';
|
||||
}
|
||||
|
||||
return '';
|
||||
})();
|
||||
|
||||
this.login.setError(loginErrorMessage);
|
||||
|
||||
return this.form.checkValidity();
|
||||
}
|
||||
|
||||
createUser = () => {
|
||||
if (this.validateInputs()) {
|
||||
this.next(EVENTS.CREATE_USER, {
|
||||
login: this.login.getValue(),
|
||||
avatar: this.avatar.getValue(),
|
||||
password: this.password.getValue(),
|
||||
is_admin: this.isAdmin.getValue() === TRUE,
|
||||
});
|
||||
routeService.pushQuery({}, true);
|
||||
}
|
||||
}
|
||||
|
||||
saveUser = () => {
|
||||
if (this.validateInputs()) {
|
||||
this.next(EVENTS.SAVE_USER, {
|
||||
login: this.login.getValue(),
|
||||
avatar: this.avatar.getValue(),
|
||||
is_admin: this.isAdmin.getValue() === TRUE,
|
||||
});
|
||||
routeService.pushQuery({}, true);
|
||||
}
|
||||
}
|
||||
|
||||
deleteUser = () => {
|
||||
const {query: {login}} = routeService.getUrlData();
|
||||
routeService.pushQuery({}, true);
|
||||
this.next(EVENTS.DELETE_USER, login);
|
||||
}
|
||||
|
||||
loadUser = async (login) => {
|
||||
if (login) {
|
||||
return await usersServiceApi.find(login);
|
||||
}
|
||||
return {
|
||||
login: '',
|
||||
avatar: '',
|
||||
is_admin: '',
|
||||
};
|
||||
}
|
||||
|
||||
showButtons = async (mode) => {
|
||||
const user = await userInfoService.getUserInfo();
|
||||
this.buttons.forEach(({button, modes, onlyAdmin}) => {
|
||||
const isShow = modes.includes(mode) && (onlyAdmin ? user.is_admin : true);
|
||||
button.style.display = isShow ? 'inline-block' : 'none';
|
||||
});
|
||||
}
|
||||
|
||||
setPassword = (mode) => {
|
||||
const isShow = mode === MODES.Create;
|
||||
|
||||
this.password.setValue('');
|
||||
|
||||
this.password.mainNode.style.display = isShow ? 'block' : 'none';
|
||||
}
|
||||
|
||||
setLogin = (mode, login) => {
|
||||
const disabled = mode !== MODES.Create;
|
||||
|
||||
this.login.disabled(disabled);
|
||||
|
||||
this.login.setValue(login);
|
||||
}
|
||||
|
||||
setForm = async (userLogin, mode) => {
|
||||
const {login, avatar, is_admin} = await this.loadUser(userLogin);
|
||||
this.setSidebarTitle(mode, login);
|
||||
this.setLogin(mode, login);
|
||||
this.avatar.setValue(avatar);
|
||||
this.isAdmin.setValue(!!is_admin);
|
||||
this.setInputDisabled(mode);
|
||||
this.showButtons(mode);
|
||||
this.setPassword(mode);
|
||||
|
||||
if (mode) {
|
||||
this.sidebar.show();
|
||||
} else {
|
||||
this.sidebar.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default UserViewForm;
|
||||
3
src/components/user-view-form/index.js
Normal file
3
src/components/user-view-form/index.js
Normal file
@ -0,0 +1,3 @@
|
||||
import UserViewForm from './UserViewForm';
|
||||
|
||||
export default UserViewForm;
|
||||
@ -1,16 +1,69 @@
|
||||
import Component from '../component';
|
||||
import UsersTable from '../users-table';
|
||||
import usersServiceApi from '../../api/UsersServiceAPI';
|
||||
import UserViewForm from '../user-view-form';
|
||||
import {EVENTS, MODES} from '../../consts';
|
||||
import routeService from '../../services/RouteService';
|
||||
import userInfoService from '../../services/UserInfoService';
|
||||
|
||||
class UsersPage extends Component {
|
||||
constructor (mainNodeSelector, parentNode) {
|
||||
super(mainNodeSelector, parentNode);
|
||||
|
||||
this.usersForm = this.createComponent(UserViewForm);
|
||||
|
||||
this.createElement({tagName: 'div', parentNode: this.mainNode});
|
||||
|
||||
this.createUserButton = this.createElement({
|
||||
tagName: 'button',
|
||||
parentNode: this.mainNode,
|
||||
options: {
|
||||
className: 'btn btn-primary m-3',
|
||||
textContent: 'Создать пользователя',
|
||||
},
|
||||
args: {
|
||||
type: 'button',
|
||||
},
|
||||
});
|
||||
|
||||
this.addSubscribe(userInfoService, EVENTS.CHANGE_USER_INFO, ({is_admin}) => {
|
||||
this.createUserButton.disabled = !is_admin;
|
||||
});
|
||||
|
||||
this.addEventListener(this.createUserButton, 'click', () => {
|
||||
routeService.pushQuery({mode: MODES.Create}, true);
|
||||
});
|
||||
|
||||
this.addSubscribe(this.usersForm, EVENTS.CREATE_USER, async (user) => {
|
||||
await usersServiceApi.create(user);
|
||||
this.initPage();
|
||||
});
|
||||
|
||||
this.addSubscribe(this.usersForm, EVENTS.SAVE_USER, async (user) => {
|
||||
await usersServiceApi.update(user);
|
||||
this.initPage();
|
||||
});
|
||||
|
||||
this.addSubscribe(this.usersForm, EVENTS.DELETE_USER, async (login) => {
|
||||
await usersServiceApi.remove(login);
|
||||
this.initPage();
|
||||
});
|
||||
|
||||
this.usersTable = this.createComponent(UsersTable, this.mainNode);
|
||||
|
||||
this.addSubscribe(this.usersTable, EVENTS.ROW_DOUBLE_CLICK, (_, row) => {
|
||||
routeService.pushQuery({
|
||||
mode: MODES.View,
|
||||
login: row.login,
|
||||
});
|
||||
});
|
||||
|
||||
this.initPage();
|
||||
}
|
||||
|
||||
initPage = async () => {
|
||||
const user = await userInfoService.getUserInfo();
|
||||
this.createUserButton.disabled = !user.is_admin;
|
||||
this.userList = await usersServiceApi.request();
|
||||
this.renderTable();
|
||||
}
|
||||
|
||||
@ -55,7 +55,14 @@ export const EVENTS = {
|
||||
CHANGE_USER_AVATAR: 'changeUserAvatar',
|
||||
OPEN_MODAL: 'openModal',
|
||||
CLICK: 'click',
|
||||
SUBMIT: 'submit'
|
||||
SUBMIT: 'submit',
|
||||
FOCUS: 'focus',
|
||||
KEYDOWN: 'keydown',
|
||||
INPUT: 'input',
|
||||
CHANGE: 'change',
|
||||
CREATE_USER: 'createUser',
|
||||
SAVE_USER: 'saveUser',
|
||||
DELETE_USER: 'deleteUser',
|
||||
};
|
||||
|
||||
export const FORM_TYPES = {
|
||||
@ -64,3 +71,17 @@ export const FORM_TYPES = {
|
||||
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',
|
||||
};
|
||||
|
||||
@ -2,21 +2,31 @@ import usersServiceApi from '../api/UsersServiceAPI';
|
||||
import {EVENTS} from '../consts';
|
||||
import EmitService from './EmitService';
|
||||
|
||||
const NOT_USER = 'not_user';
|
||||
const DEFAULT_AVATAR = 'https://d5qmjlya0ygtg.cloudfront.net/569/c5295/f9ad/47c8/96a0/66a65609b38d/original/331698.jpg';
|
||||
class UserInfoService extends EmitService {
|
||||
constructor () {
|
||||
super();
|
||||
|
||||
this.userInfo = {
|
||||
login: 'not_user',
|
||||
avatar: 'https://d5qmjlya0ygtg.cloudfront.net/569/c5295/f9ad/47c8/96a0/66a65609b38d/original/331698.jpg',
|
||||
login: NOT_USER,
|
||||
avatar: DEFAULT_AVATAR,
|
||||
};
|
||||
}
|
||||
|
||||
setUserLogin = async () => {
|
||||
this.userInfo = await usersServiceApi.getMe();
|
||||
this.userInfo = await usersServiceApi.getSelfInfo();
|
||||
this.next(EVENTS.CHANGE_USER_INFO, {...this.userInfo});
|
||||
}
|
||||
|
||||
getUserInfo = async () => {
|
||||
if (this.userInfo.login === NOT_USER) {
|
||||
this.userInfo = await usersServiceApi.getSelfInfo();
|
||||
}
|
||||
|
||||
return {...this.userInfo};
|
||||
}
|
||||
|
||||
changeAllAvatars () {
|
||||
this.next(EVENTS.CHANGE_USER_AVATAR);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user