HOT-FIX. Добавлены методы создания компонентов и нод внутри компонентов

This commit is contained in:
2020-08-08 21:56:43 +03:00
parent aeb16d45e5
commit 5b9c6a8f94
28 changed files with 99 additions and 73 deletions

View File

@ -23,7 +23,7 @@ class ApiInfoComponent extends Component {
footerNode: this.infoFooter
};
this.key = null;
this.modal = new Modal(document.body, this.info);
this.modal = this.createComponent(Modal, document.body, this.info);
this.addEventListener(this.btnDelete, 'click', () => {
if (this.key !== null) {

View File

@ -10,15 +10,16 @@ class ApiPage extends Component {
constructor (mainNodeSelector, parentNode) {
super(mainNodeSelector, parentNode);
this.filterBox = new FilterApiComponent(this.mainNode);
this.storageListTable = new TableComponent(this.mainNode);
this.infoBox = new ApiInfoComponent();
this.createWindow = new CreateApiComponent();
this.filterBox = this.createComponent(FilterApiComponent, this.mainNode);
this.storageListTable = this.createComponent(TableComponent, this.mainNode);
this.infoBox = this.createComponent(ApiInfoComponent);
this.createWindow = this.createComponent(CreateApiComponent);
this.addSubscribe(this.storageListTable, 'showInfo', (obj) => {
this.infoBox.render(obj);
});
this.createBtn = new ButtonComponent(this.filterBox.filterButtonBox, '✚', 'btn btn-primary mb-3 Create__btn');
this.createBtn = this.createComponent(ButtonComponent, this.filterBox.filterButtonBox, '✚', 'btn btn-primary mb-3 Create__btn');
this.addSubscribe(this.createBtn, 'click', () => {
this.createWindow.show();
});

View File

@ -8,7 +8,7 @@ class ClientLogsTable extends Table {
}
renderRow = (parentNode, cols, row) => {
return new ClientLogsTableRow(parentNode, cols, row);
return this.createComponent(ClientLogsTableRow, parentNode, cols, row);
}
}

View File

@ -5,7 +5,7 @@ class ClientLogsTableRow extends Component {
constructor (parentNode, cols, row) {
super(null, parentNode);
this.cols = cols.map((col) => new TableCellOverflow(this.mainNode, row[col.id]));
this.cols = cols.map((col) => this.createComponent(TableCellOverflow, this.mainNode, row[col.id]));
}
}

View File

@ -8,7 +8,7 @@ class ClientLogsViewForm extends Component {
constructor (parentNode) {
super('#logs-view-form', parentNode);
this.sidebar = new ModalSidebar({
this.sidebar = this.createComponent(ModalSidebar, {
content: this.mainNode,
});
@ -18,37 +18,37 @@ class ClientLogsViewForm extends Component {
this.title.textContent = 'Просмотр клиентского запроса';
const inputs = [
this.idInput = new FormControl(this.form, {
this.idInput = this.createComponent(FormControl, this.form, {
id: 'client-logs-view-form-id',
label: 'id',
}),
this.resultInput = new FormControl(this.form, {
this.resultInput = this.createComponent(FormControl, this.form, {
id: 'client-logs-view-form-result',
label: 'Результат',
}),
this.startTimeInput = new FormControl(this.form, {
this.startTimeInput = this.createComponent(FormControl, this.form, {
id: 'client-logs-view-form-startTime',
label: 'Время запроса',
}),
this.headersInput = new FormControl(this.form, {
this.headersInput = this.createComponent(FormControl, this.form, {
id: 'client-logs-view-form-headers',
label: 'Заголовки запроса',
type: FORM_TYPES.TEXTAREA,
className: 'ClientLogsViewForm__headersInput',
}),
this.urlInput = new FormControl(this.form, {
this.urlInput = this.createComponent(FormControl, this.form, {
id: 'client-logs-view-form-url',
label: 'URL запроса',
}),
this.methodInput = new FormControl(this.form, {
this.methodInput = this.createComponent(FormControl, this.form, {
id: 'client-logs-view-form-method',
label: 'Метод запроса',
}),
this.endTimeInput = new FormControl(this.form, {
this.endTimeInput = this.createComponent(FormControl, this.form, {
id: 'client-logs-view-form-endTime',
label: 'Время ответа',
}),
this.responseInput = new FormControl(this.form, {
this.responseInput = this.createComponent(FormControl, this.form, {
id: 'client-logs-view-form-response',
label: 'Ответ сервера',
type: FORM_TYPES.TEXTAREA,

View File

@ -1,4 +1,5 @@
import EmitService from '../../services/EmitService';
import {createElement} from '../../utils/elementUtils';
/**
* Класс для создания компонентов приложения. Необходим для наследования.
@ -24,6 +25,10 @@ class Component extends EmitService {
*/
mainNode;
_innerComponents;
_innerNodes;
constructor (mainNodeSelector, parentNode) {
super();
if (!mainNodeSelector && !parentNode) {
@ -46,6 +51,8 @@ class Component extends EmitService {
}
this._listeners = [];
this._innerComponents = [];
this._innerNodes = [];
this._events = {};
this._isAlive = true;
}
@ -81,6 +88,30 @@ class Component extends EmitService {
}
}
createComponent = (ComponentClass, ...args) => {
const component = new ComponentClass(...args);
this._innerComponents.push(component);
return component;
}
createElement = (options) => {
const node = createElement(options);
this._innerNodes.push(node);
return node;
}
destroyInnerComponents = () => {
while (this._innerComponents.length) {
const component = this._innerComponents.pop();
component.destroy();
}
while (this._innerNodes.length) {
const node = this._innerNodes.pop();
node.remove();
}
}
/**
* Метод уничтожения компонента. Удаляет элемент из верстки, снимает обработчики и очищает подписки
*/
@ -89,6 +120,7 @@ class Component extends EmitService {
this.clearListeners();
this.clearSubscribes();
this.clearEvents();
this.destroyInnerComponents();
this.mainNode.remove();
}
}

View File

@ -18,13 +18,13 @@ class CreateApiComponent extends Component {
this.footer = this.mainNode.querySelector('.Create__footer');
this.form = this.mainNode.querySelector('.Create__form');
this.editor = this.mainNode.querySelector('.Create__editor');
this.button = new ButtonComponent(this.footer, 'Создать', 'btn btn-outline-primary Create__send');
this.button = this.createComponent(ButtonComponent, this.footer, 'Создать', 'btn btn-outline-primary Create__send');
this.content = {
headerNode: this.header,
contentNode: this.body,
footerNode: this.footer
};
this.modal = new Modal(document.body, this.content);
this.modal = this.createComponent(Modal, document.body, this.content);
this.modal.container.classList.add('Large__container');
this.modal.content.classList.add('Scroll__body');

View File

@ -1,5 +1,4 @@
import Component from '../component';
import {createElement} from '../../utils/elementUtils';
import {FORM_TYPES} from '../../consts';
class FormControl extends Component {
@ -16,7 +15,7 @@ class FormControl extends Component {
this.label = this.mainNode.querySelector('.form-label');
this.errorText = this.mainNode.querySelector('.form-text');
this.input = createElement({
this.input = this.createElement({
tagName: this.getInputTagName(type),
options: {
className: `form-control ${className}`,

View File

@ -17,13 +17,13 @@ class LoginForm extends Component {
this.title.textContent = 'Storage Service v0.01';
this.loginControl = new FormControl(this.inputContainer, {
this.loginControl = this.createComponent(FormControl, this.inputContainer, {
label: 'Логин:',
id: 'login-form-user-login',
placeholder: 'Введите логин',
required: true,
});
this.passwordControl = new FormControl(this.inputContainer, {
this.passwordControl = this.createComponent(FormControl, this.inputContainer, {
label: 'Пароль:',
id: 'login-form-user-password',
placeholder: 'Введите пароль',

View File

@ -9,7 +9,7 @@ class LoginPage extends Component {
constructor (mainNodeSelector, parentNode) {
super(mainNodeSelector, parentNode);
this.form = new LoginForm(this.mainNode);
this.form = this.createComponent(LoginForm, this.mainNode);
this.addSubscribe(this.form, 'submit', ({login, password}) => {
this.form.disabled(true);

View File

@ -1,6 +1,5 @@
import Component from '../component/index';
import routeService from '../../services/RouteService';
import {createElement} from '../../utils/elementUtils';
import {LOG_TYPE, LOG_LABELS} from '../../consts';
import './LogsFilters.css';
@ -89,7 +88,7 @@ class LogsFilters extends Component {
const {tableType = LOG_TYPE.SERVER} = routeService.getUrlData().query;
this.typeInput = this.mainNode.querySelector('#logs-filter-type');
LOG_LABELS.forEach(({id, label}) => {
createElement({
this.createElement({
tagName: 'option',
parentNode: this.typeInput,
options: {

View File

@ -5,7 +5,7 @@ import LogsFilters from '../logs-filters';
import routeService from '../../services/RouteService';
import {prepareToNumber} from '../../utils/urlUtils';
import {LOG_TYPE, EVENTS} from '../../consts';
import {createElement, markText, prepareServerDate, prepareObjectToString} from '../../utils/elementUtils';
import {markText, prepareServerDate, prepareObjectToString} from '../../utils/elementUtils';
import ServerLogsTable from '../server-logs-table';
import ClientLogsTable from '../client-logs-table';
import ClientLogsViewForm from '../client-logs-view-form';
@ -17,30 +17,30 @@ class LogsPage extends Component {
constructor (mainNodeSelector, parentNode) {
super(mainNodeSelector, parentNode);
this.clientLogsForm = new ClientLogsViewForm();
this.serverLogsForm = new ServerLogsViewForm();
this.clientLogsForm = this.createComponent(ClientLogsViewForm);
this.serverLogsForm = this.createComponent(ServerLogsViewForm);
this.header = createElement({
this.header = this.createElement({
tagName: 'div',
parentNode: this.mainNode,
});
this.body = createElement({
this.body = this.createElement({
tagName: 'div',
parentNode: this.mainNode,
});
this.footer = createElement({
this.footer = this.createElement({
tagName: 'div',
parentNode: this.mainNode,
});
this.filters = new LogsFilters(this.header);
this.filters = this.createComponent(LogsFilters, this.header);
this.tables = {
[LOG_TYPE.SERVER]: new ServerLogsTable(),
[LOG_TYPE.CLIENT]: new ClientLogsTable(),
[LOG_TYPE.SERVER]: this.createComponent(ServerLogsTable),
[LOG_TYPE.CLIENT]: this.createComponent(ClientLogsTable),
};
this.pagination = new Pagination(this.footer);
this.pagination = this.createComponent(Pagination, this.footer);
this.logList = {
[LOG_TYPE.SERVER]: [],

View File

@ -2,7 +2,6 @@ import Component from '../component/index';
import routeService from '../../services/RouteService';
import './MainMenu.css';
import {createElement} from '../../utils/elementUtils';
import {EVENTS} from '../../consts';
import tokenApi from '../../api/TokenAPI';
@ -69,14 +68,14 @@ class MainMenu extends Component {
render = () => {
this.menuItems = NAV_MENU.map(({url, title, className = ''}) => {
const li = createElement({
const li = this.createElement({
tagName: 'li',
parentNode: this.buttonsContainer,
options: {
className: `nav-item ${className}`,
},
});
const link = createElement({
const link = this.createElement({
tagName: 'a',
parentNode: li,
options: {

View File

@ -5,8 +5,8 @@ import MainContent from '../main-content';
class MainPage extends Component {
constructor (mainNodeSelector, parentNode) {
super(mainNodeSelector, parentNode);
this.mainStatistic = new MainStatistic(this.mainNode);
this.mainContent = new MainContent(this.mainNode);
this.mainStatistic = this.createComponent(MainStatistic, this.mainNode);
this.mainContent = this.createComponent(MainContent, this.mainNode);
}
}

View File

@ -1,6 +1,5 @@
import Component from '../component';
import './ModalSidebar.css';
import {createElement} from '../../utils/elementUtils';
const SHOW_WINDOW_CLASS = 'ModalSidebar__window_show';
const HIDE_WINDOW_CLASS = 'ModalSidebar__window_hide';
@ -15,7 +14,7 @@ class ModalSidebar extends Component {
const parentNode = document.body;
super('#modal-sidebar', parentNode);
this.shadow = createElement({
this.shadow = this.createElement({
tagName: 'div',
parentNode,
options: {

View File

@ -6,7 +6,7 @@ import './NotFoundPage.css';
class NotFoundPage extends Component {
constructor (mainNodeSelector, parentNode) {
super(mainNodeSelector, parentNode);
this.notFoundContent = new NotFoundContent(this.mainNode);
this.notFoundContent = this.createComponent(NotFoundContent, this.mainNode);
this.mainNodeSelector = this.mainNode.querySelector('.NotFound__text');
this.mainNodeSelector.textContent = `Запрашиваемая Вами страница ${location.pathname} не найдена`;
this.redirectButton = this.mainNode.querySelector('.NotFound__redirectButton');

View File

@ -1,6 +1,5 @@
import Component from '../component/index';
import routeService from '../../services/RouteService';
import {createElement} from '../../utils/elementUtils';
import {prepareToNumber} from '../../utils/urlUtils';
import {EVENTS} from '../../consts';
@ -22,7 +21,7 @@ class Pagination extends Component {
}
renderOneButton = (text, isDisabled = false) => {
const li = createElement({
const li = this.createElement({
tagName: 'li',
parentNode: this.container,
options: {
@ -30,7 +29,7 @@ class Pagination extends Component {
disabled: isDisabled,
},
});
const button = createElement({
const button = this.createElement({
tagName: 'button',
parentNode: li,
options: {

View File

@ -10,21 +10,21 @@ class ProfileContent extends Component {
this.Password = this.mainNode.querySelector('.Password__inputContainer');
this.profileButton = this.mainNode.querySelector('.Profile__button');
this.title.textContent = 'Смена пароля';
this.oldPassword = new FormControl(this.Password, {
this.oldPassword = this.createComponent(FormControl, this.Password, {
label: 'Старый пароль:',
id: 'oldpass',
placeholder: 'Введите старый пароль',
type: FORM_TYPES.PASSWORD,
required: true,
});
this.newPassword = new FormControl(this.Password, {
this.newPassword = this.createComponent(FormControl, this.Password, {
label: 'Новый пароль:',
id: 'newpass',
placeholder: 'Введите новый пароль',
type: FORM_TYPES.PASSWORD,
required: true,
});
this.newPasswordRepeat = new FormControl(this.Password, {
this.newPasswordRepeat = this.createComponent(FormControl, this.Password, {
label: 'Повторите новый пароль:',
id: 'newpassrepeat',
placeholder: 'Введите новый пароль еще раз',

View File

@ -5,7 +5,7 @@ import './ProfilePage.css';
class ProfilePage extends Component {
constructor (mainNodeSelector, parentNode) {
super(mainNodeSelector, parentNode);
this.form = new ProfileContent(this.mainNode);
this.form = this.createComponent(ProfileContent, this.mainNode);
}
}

View File

@ -11,11 +11,11 @@ class FilterApiComponent extends Component {
this.form = this.mainNode.querySelector('.Filter__form');
this.filterInputsBox = this.mainNode.querySelector('.Filter__inputs-box');
this.filterButtonBox = this.mainNode.querySelector('.Filter__button-box');
this.searchBtn = new ButtonComponent(this.filterButtonBox, 'Найти', 'btn btn-primary mb-3');
this.searchBtn = this.createComponent(ButtonComponent, this.filterButtonBox, 'Найти', 'btn btn-primary mb-3');
this.inputs = FILTER_ROWS.map((item) => {
const {query} = routeService.getUrlData();
const input = new FilterInputComponent(this.filterInputsBox, item);
const input = this.createComponent(FilterInputComponent, this.filterInputsBox, item);
Object.keys(query).forEach((elem) => {
if (elem === item.key) {
input.input.value = query[elem];

View File

@ -8,7 +8,7 @@ class ServerLogsTable extends Table {
}
renderRow = (parentNode, cols, row) => {
return new ServerLogsTableRow(parentNode, cols, row);
return this.createComponent(ServerLogsTableRow, parentNode, cols, row);
}
}

View File

@ -5,7 +5,7 @@ class ServerLogsTableRow extends Component {
constructor (parentNode, cols, row) {
super(null, parentNode);
this.cols = cols.map((col) => new TableCellOverflow(this.mainNode, row[col.id]));
this.cols = cols.map((col) => this.createComponent(TableCellOverflow, this.mainNode, row[col.id]));
}
}

View File

@ -8,7 +8,7 @@ class ServerLogsViewForm extends Component {
constructor (parentNode) {
super('#logs-view-form', parentNode);
this.sidebar = new ModalSidebar({
this.sidebar = this.createComponent(ModalSidebar, {
content: this.mainNode,
});
@ -18,25 +18,25 @@ class ServerLogsViewForm extends Component {
this.title.textContent = 'Просмотр ошибок сервера';
const inputs = [
this.idInput = new FormControl(this.form, {
this.idInput = this.createComponent(FormControl, this.form, {
id: 'server-logs-view-form-id',
label: 'id',
}),
this.dateInput = new FormControl(this.form, {
this.dateInput = this.createComponent(FormControl, this.form, {
id: 'server-logs-view-form-date',
label: 'Дата',
}),
this.typeInput = new FormControl(this.form, {
this.typeInput = this.createComponent(FormControl, this.form, {
id: 'server-logs-view-form-type',
label: 'Тип записи',
}),
this.messageInput = new FormControl(this.form, {
this.messageInput = this.createComponent(FormControl, this.form, {
id: 'server-logs-view-form-message',
label: 'Сообщение',
type: FORM_TYPES.TEXTAREA,
className: 'ServerLogsViewForm__message',
}),
this.stackInput = new FormControl(this.form, {
this.stackInput = this.createComponent(FormControl, this.form, {
id: 'server-logs-view-form-stack',
label: 'Стек',
type: FORM_TYPES.TEXTAREA,

View File

@ -1,24 +1,23 @@
import Component from '../component';
import {createElement} from '../../utils/elementUtils';
import './TableCellOverflow.css';
class TableCellOverflow extends Component {
constructor (parentNode, text) {
super(null, parentNode);
const cell = createElement({
const cell = this.createElement({
tagName: 'td',
parentNode: this.mainNode,
});
const div = createElement({
const div = this.createElement({
tagName: 'div',
parentNode: cell,
options: {
className: 'TableCellOverflow__cellWrapper'
}
});
const span = createElement({
const span = this.createElement({
tagName: 'span',
parentNode: div,
options: {

View File

@ -23,7 +23,7 @@ class TableComponent extends Component {
this.array = array;
this.columns = Object.keys(array[0]);
this.columns.forEach((item, index) => {
const columnElement = new TableColumnComponent(this.tableHeadRow, item, index);
const columnElement = this.createComponent(TableColumnComponent, this.tableHeadRow, item, index);
columnElement.subscribe('click', () => {
this.sort(item, array);
});
@ -31,7 +31,7 @@ class TableComponent extends Component {
});
this.array.forEach((item, index) => {
const newRow = new TableRowComponent(this.tableBody, item, index);
const newRow = this.createComponent(TableRowComponent, this.tableBody, item, index);
newRow.subscribe('dblclick', () => {
this.next('showInfo', item);
});

View File

@ -1,11 +1,10 @@
import Component from '../component';
import {createElement} from '../../utils/elementUtils';
class RowCol extends Component {
constructor (parentNode, text) {
super(null, parentNode);
createElement({
this.createElement({
tagName: 'td',
parentNode: this.mainNode,
options: {

View File

@ -43,11 +43,11 @@ class Table extends Component {
}
renderHeaderCol = (col) => {
return new HeaderCol(this.theadTr, col);
return this.createComponent(HeaderCol, this.theadTr, col);
}
renderRow = (parentNode, cols, row) => {
return new TableRow(parentNode, cols, row);
return this.createComponent(TableRow, parentNode, cols, row);
}
/**
@ -76,7 +76,7 @@ class Table extends Component {
}
this.rows = rows.map((row) => {
const tr = new TableRowWrapper(this.tbody, row);
const tr = this.createComponent(TableRowWrapper, this.tbody, row);
this.addSubscribe(tr, EVENTS.ROW_CLICK, (event) => {
this.next(EVENTS.ROW_CLICK, event, row);
});

View File

@ -5,7 +5,7 @@ class TableRow extends Component {
constructor (parentNode, cols, row) {
super(null, parentNode);
this.cols = cols.map((col) => new RowCol(this.mainNode, row[col.id]));
this.cols = cols.map((col) => this.createComponent(RowCol, this.mainNode, row[col.id]));
}
}