HM-126. Перенос хранилищ на новую модалку и логику, добавление работы… (#65)
This commit is contained in:
33
src/pages/storages/api/HooksAPI.js
Normal file
33
src/pages/storages/api/HooksAPI.js
Normal file
@ -0,0 +1,33 @@
|
||||
import {ENDPOINTS} from '../../../api/consts';
|
||||
import adminConfigsService from '../../../services/AdminConfigsService';
|
||||
import http from '../../../api/HttpAPI';
|
||||
|
||||
class HooksApi {
|
||||
constructor () {
|
||||
const {url, options} = adminConfigsService.getApi();
|
||||
this.URL = `${url}${ENDPOINTS.HOOKS}`;
|
||||
this.OPTIONS = options;
|
||||
}
|
||||
|
||||
request = async (key) => {
|
||||
const {data} = await http.get(this.URL, {key}, this.OPTIONS);
|
||||
return data;
|
||||
}
|
||||
|
||||
create = async (key, createData) => {
|
||||
const {data} = await http.post(this.URL, createData, {
|
||||
...this.OPTIONS,
|
||||
params: {key},
|
||||
});
|
||||
return data;
|
||||
}
|
||||
|
||||
remove = async (key, id) => {
|
||||
const {data} = await http.delete(this.URL, {key, id}, this.OPTIONS);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
const hooksApi = new HooksApi();
|
||||
|
||||
export default hooksApi;
|
||||
115
src/pages/storages/components/add-hook-modal/AddHookModal.js
Normal file
115
src/pages/storages/components/add-hook-modal/AddHookModal.js
Normal file
@ -0,0 +1,115 @@
|
||||
import Modal from '../../../../core/components/modal/Modal';
|
||||
import {TAG_NAME, EVENTS} from '../../../../core/consts';
|
||||
import FormControl from '../../../../core/components/form-control/FormControl';
|
||||
import {FormCheck} from '../../../../core/components/form-check/FormCheck';
|
||||
import {v4} from 'uuid';
|
||||
import userInfoService from '../../../../services/UserInfoService';
|
||||
import routeService from '../../../../services/RouteService';
|
||||
import hooksApi from '../../api/HooksAPI';
|
||||
|
||||
export class AddHookModal extends Modal {
|
||||
constructor (parentNode) {
|
||||
super(parentNode);
|
||||
|
||||
this.createElement({
|
||||
tagName: TAG_NAME.DIV,
|
||||
parentNode: this.header,
|
||||
options: {
|
||||
textContent: 'Создание хука',
|
||||
},
|
||||
});
|
||||
|
||||
this.form = this.createElement({
|
||||
tagName: TAG_NAME.FORM,
|
||||
parentNode: this.content,
|
||||
});
|
||||
|
||||
this.inputs = [
|
||||
this.holderInput = this.createComponent(FormControl, this.form, {
|
||||
id: 'add-hook-modal-holder',
|
||||
label: 'Название',
|
||||
}),
|
||||
this.descriptionInput = this.createComponent(FormControl, this.form, {
|
||||
id: 'add-hook-modal-description',
|
||||
label: 'Описание'
|
||||
}),
|
||||
this.readCheckbox = this.createComponent(FormCheck, this.form, {
|
||||
id: 'add-hook-modal-read',
|
||||
label: 'Позволяет чтение',
|
||||
}),
|
||||
this.writeCheckbox = this.createComponent(FormCheck, this.form, {
|
||||
id: 'add-hook-modal-write',
|
||||
label: 'Позволяет запись',
|
||||
}),
|
||||
];
|
||||
|
||||
this.alert = this.createElement({
|
||||
tagName: TAG_NAME.DIV,
|
||||
parentNode: this.content,
|
||||
options: {
|
||||
className: 'alert alert-success',
|
||||
},
|
||||
});
|
||||
|
||||
this.saveButton = this.createElement({
|
||||
tagName: TAG_NAME.BUTTON,
|
||||
parentNode: this.footer,
|
||||
options: {
|
||||
textContent: 'Создать',
|
||||
className: 'btn btn-primary',
|
||||
}
|
||||
});
|
||||
|
||||
this.cancelButton = this.createElement({
|
||||
tagName: TAG_NAME.BUTTON,
|
||||
parentNode: this.footer,
|
||||
options: {
|
||||
textContent: 'Отмена',
|
||||
className: 'btn btn-secondary',
|
||||
},
|
||||
});
|
||||
|
||||
this.addEventListener(this.saveButton, EVENTS.CLICK, this.saveHook);
|
||||
this.addEventListener(this.cancelButton, EVENTS.CLICK, this.cancel);
|
||||
}
|
||||
|
||||
openForm = () => {
|
||||
this.inputs.forEach((input) => {
|
||||
input.mainNode.style.display = 'block';
|
||||
input.setValue('');
|
||||
});
|
||||
this.alert.style.display = 'none';
|
||||
this.saveButton.disabled = false;
|
||||
this.cancelButton.textContent = 'Отмена';
|
||||
this.show();
|
||||
}
|
||||
|
||||
saveHook = async () => {
|
||||
const token = v4();
|
||||
const {login} = await userInfoService.getUserInfo();
|
||||
const {query: {key}} = routeService.getUrlData();
|
||||
const hook = {
|
||||
holder: this.holderInput.getValue(),
|
||||
description: this.descriptionInput.getValue(),
|
||||
rights: {
|
||||
write: this.writeCheckbox.getValue(),
|
||||
read: this.readCheckbox.getValue(),
|
||||
},
|
||||
token,
|
||||
author: login,
|
||||
};
|
||||
this.inputs.forEach((input) => {
|
||||
input.mainNode.style.display = 'none';
|
||||
});
|
||||
this.saveButton.disabled = true;
|
||||
await hooksApi.create(key, hook);
|
||||
this.cancelButton.textContent = 'Закрыть';
|
||||
this.alert.textContent = `"${token}" - сохраните ваш хук. Больше его нельзя будет увидеть.`;
|
||||
this.alert.style.display = 'block';
|
||||
this.next(EVENTS.SAVE_HOOK);
|
||||
}
|
||||
|
||||
cancel = () => {
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
@ -1,39 +0,0 @@
|
||||
.Info__body {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.Info__container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
}
|
||||
.Info__title {
|
||||
text-align: center;
|
||||
}
|
||||
.Info__service_name {
|
||||
align-self: center;
|
||||
}
|
||||
.Info__editor {
|
||||
border: 1px solid #F2F2F2;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
height: 40vh;
|
||||
}
|
||||
.Info__controls {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: 5px;
|
||||
font-size: 20px;
|
||||
}
|
||||
.Button__delete {
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
.Button__edit {
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
@ -1,61 +0,0 @@
|
||||
import Component from '../../../../core/components/component/Component';
|
||||
import './ApiInfoComponent.css';
|
||||
import Modal from '../../../../core/components/modal/Modal';
|
||||
import storageApi from '../../api/StorageServiceAPI';
|
||||
|
||||
class ApiInfoComponent extends Component {
|
||||
constructor (container) {
|
||||
super('#api-info', container);
|
||||
|
||||
this.infoTitle = this.mainNode.querySelector('.Info__title');
|
||||
this.infoHeader = this.mainNode.querySelector('.Info__header');
|
||||
this.infoDescription = this.mainNode.querySelector('.Info__description');
|
||||
this.infoServiceName = this.mainNode.querySelector('.Info__service_name');
|
||||
this.infoEditor = this.mainNode.querySelector('.Info__editor');
|
||||
this.infoFooter = this.mainNode.querySelector('.Info__footer');
|
||||
this.infoBody = this.mainNode.querySelector('.Info__body');
|
||||
this.infoControls = this.mainNode.querySelector('.Info__controls');
|
||||
this.btnDelete = this.mainNode.querySelector('.Button__delete');
|
||||
this.btnEdit = this.mainNode.querySelector('.Button__edit');
|
||||
this.info = {
|
||||
headerNode: this.infoHeader,
|
||||
contentNode: this.infoBody,
|
||||
footerNode: this.infoFooter
|
||||
};
|
||||
this.key = null;
|
||||
this.modal = this.createComponent(Modal, document.body, this.info);
|
||||
|
||||
this.addEventListener(this.btnDelete, 'click', () => {
|
||||
if (this.key !== null) {
|
||||
this.deleteApi(this.key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
render = (object, index) => {
|
||||
this.object = object;
|
||||
this.index = index;
|
||||
this.key = object.key;
|
||||
this.modal.show();
|
||||
|
||||
if (this.object) {
|
||||
let title = '';
|
||||
if (this.object.key.length > 20) {
|
||||
title = `${this.object.key.substr(0, 20)} ...`;
|
||||
} else title = this.object.key;
|
||||
this.infoTitle.textContent = title;
|
||||
this.infoServiceName.textContent = this.object.service_name;
|
||||
this.infoEditor.innerHTML = JSON.stringify(this.object.value, false, 4);
|
||||
this.infoFooter.textContent = this.object.author;
|
||||
this.infoDescription.textContent = this.object.description;
|
||||
}
|
||||
}
|
||||
|
||||
deleteApi = async (key) => {
|
||||
await storageApi.remove(key);
|
||||
this.key = null;
|
||||
this.modal.hide();
|
||||
this.next('deleteApi');
|
||||
}
|
||||
}
|
||||
export default ApiInfoComponent;
|
||||
@ -1,111 +1,255 @@
|
||||
import Component from '../../../../core/components/component/Component';
|
||||
import ModalSidebar from '../../../../core/components/modal-sidebar/ModalSibebar';
|
||||
import FormControl from '../../../../core/components/form-control/FormControl';
|
||||
import {FORM_TYPES} from '../../../../core/consts';
|
||||
import {FORM_TYPES, EVENTS, MODES} from '../../../../core/consts';
|
||||
import './ApiTableViewForm.css';
|
||||
import storageApi from '../../api/StorageServiceAPI';
|
||||
import routeService from '../../../../services/RouteService';
|
||||
import {HooksComponent} from '../hooks-component/HooksComponent';
|
||||
|
||||
const TITLE_MODES = {
|
||||
[MODES.Create]: 'Создание нового хранилища',
|
||||
[MODES.Edit]: 'Редактирование хранилища',
|
||||
[MODES.View]: 'Просмотр хранилища',
|
||||
};
|
||||
|
||||
const EDIT_MODES = [MODES.Create, MODES.Edit];
|
||||
|
||||
const FILL_FIELD = 'Заполните поле';
|
||||
|
||||
class ApiTableViewForm extends Component {
|
||||
constructor (parentNode) {
|
||||
super('#api-view-form', parentNode);
|
||||
|
||||
this.sidebar = this.createComponent(ModalSidebar, {
|
||||
content: this.mainNode
|
||||
content: this.mainNode,
|
||||
});
|
||||
this.key = null;
|
||||
this.isEdit = false;
|
||||
|
||||
this.title = this.mainNode.querySelector('.h2');
|
||||
this.form = this.mainNode.querySelector('form');
|
||||
this.deleteBtn = this.mainNode.querySelector('.Button__delete');
|
||||
this.addEventListener(this.deleteBtn, 'click', () => {
|
||||
if (this.key !== null) {
|
||||
this.deleteApi(this.key);
|
||||
}
|
||||
});
|
||||
this.editBtn = this.mainNode.querySelector('.Button__edit');
|
||||
this.addEventListener(this.editBtn, 'click', () => {
|
||||
this.editApi();
|
||||
});
|
||||
this.editIcon = this.mainNode.querySelector('.Edit__icon');
|
||||
this.editBtnText = this.mainNode.querySelector('.Button__edit-text');
|
||||
this.editBtnText.textContent = 'Редактировать';
|
||||
|
||||
this.deleteBtnText = this.mainNode.querySelector('.Button__delete-text');
|
||||
this.deleteBtnText.textContent = 'Удалить';
|
||||
|
||||
this.cancelBtnText = this.mainNode.querySelector('.Button__cancel-text');
|
||||
this.cancelBtnText.textContent = 'Отменить';
|
||||
|
||||
this.title.textContent = 'Информация о хранилище';
|
||||
|
||||
this.inputs = [
|
||||
this.keyInput = this.createComponent(FormControl, this.form, {
|
||||
id: 'api-key-input',
|
||||
label: 'Название хранилища'
|
||||
label: 'Название хранилища',
|
||||
pattern: '^[a-zA-Z][a-zA-Z0-9_-]{3,}$',
|
||||
required: true,
|
||||
}),
|
||||
this.serviceNameInput = this.createComponent(FormControl, this.form, {
|
||||
id: 'api-service-name-input',
|
||||
label: 'Название сервиса'
|
||||
label: 'Название сервиса',
|
||||
required: true,
|
||||
}),
|
||||
this.authorInput = this.createComponent(FormControl, this.form, {
|
||||
id: 'api-author-input',
|
||||
label: 'Автор хранилища'
|
||||
label: 'Автор хранилища',
|
||||
required: true,
|
||||
}),
|
||||
this.descriptionInput = this.createComponent(FormControl, this.form, {
|
||||
id: 'api-description-input',
|
||||
label: 'Краткое описание'
|
||||
label: 'Краткое описание',
|
||||
required: true,
|
||||
}),
|
||||
this.valueInput = this.createComponent(FormControl, this.form, {
|
||||
id: 'api-value-input',
|
||||
type: FORM_TYPES.TEXTAREA,
|
||||
className: 'Api__value-input',
|
||||
label: 'Содержимое хранилища'
|
||||
label: 'Содержимое хранилища',
|
||||
required: true,
|
||||
}),
|
||||
];
|
||||
|
||||
this.buttons = [
|
||||
{
|
||||
button: this.createButton = this.mainNode.querySelector('.ApiViewForm__create'),
|
||||
modes: [MODES.Create],
|
||||
},
|
||||
{
|
||||
button: this.saveButton = this.mainNode.querySelector('.ApiViewForm__save'),
|
||||
modes: [MODES.Edit],
|
||||
},
|
||||
{
|
||||
button: this.editButton = this.mainNode.querySelector('.ApiViewForm__edit'),
|
||||
modes: [MODES.View],
|
||||
},
|
||||
{
|
||||
button: this.cancelButton = this.mainNode.querySelector('.ApiViewForm__cancel'),
|
||||
modes: [MODES.Create, MODES.Edit, MODES.View],
|
||||
},
|
||||
{
|
||||
button: this.deleteButton = this.mainNode.querySelector('.ApiViewForm__delete'),
|
||||
modes: [MODES.View, MODES.Edit],
|
||||
}
|
||||
];
|
||||
|
||||
this.addEventListener(this.createButton, EVENTS.CLICK, this.createStore);
|
||||
this.addEventListener(this.saveButton, EVENTS.CLICK, this.saveStore);
|
||||
this.addEventListener(this.deleteButton, EVENTS.CLICK, this.deleteStore);
|
||||
|
||||
this.addEventListener(this.editButton, EVENTS.CLICK, () => {
|
||||
routeService.pushQuery({
|
||||
mode: MODES.Edit,
|
||||
});
|
||||
});
|
||||
|
||||
this.addEventListener(this.cancelButton, EVENTS.CLICK, this.handleCloseModal);
|
||||
|
||||
this.inputs.forEach((input) => {
|
||||
input.disabled(true);
|
||||
});
|
||||
|
||||
this.hooksContainer = this.createComponent(HooksComponent, this.mainNode);
|
||||
this.form.insertAdjacentElement('afterend', this.hooksContainer.mainNode);
|
||||
|
||||
this.addSubscribe(routeService, EVENTS.ROUTE_SEARCH_CHANGE, ({query}) => {
|
||||
const {mode, key} = query;
|
||||
this.setForm(mode, key);
|
||||
this.setVisibleHooks(mode);
|
||||
});
|
||||
|
||||
const {query: {mode, key}} = routeService.getUrlData();
|
||||
if (mode) {
|
||||
this.setForm(mode, key);
|
||||
}
|
||||
}
|
||||
|
||||
stringifyValue (value) {
|
||||
return JSON.stringify(value, false, 4);
|
||||
handleCloseModal = () => {
|
||||
routeService.pushQuery({}, true);
|
||||
}
|
||||
|
||||
setForm ({key, service_name, author, description, value}) {
|
||||
setVisibleHooks = (mode) => {
|
||||
const method = mode !== MODES.View ? 'add' : 'remove';
|
||||
this.hooksContainer.mainNode.classList[method]('invisible');
|
||||
}
|
||||
|
||||
setSidebarTitle = (mode, storeKey) => {
|
||||
this.title.textContent = [TITLE_MODES[mode], storeKey].filter(Boolean).join(' ');
|
||||
}
|
||||
|
||||
stringifyValue = (value) => {
|
||||
return value ? JSON.stringify(value, false, 4) : '';
|
||||
}
|
||||
|
||||
loadStore = async (key) => {
|
||||
if (key) {
|
||||
return await storageApi.find(key);
|
||||
}
|
||||
return {
|
||||
key: '',
|
||||
value: '',
|
||||
description: '',
|
||||
service_name: '',
|
||||
author: '',
|
||||
};
|
||||
}
|
||||
|
||||
setInputDisabled = (mode) => {
|
||||
const disabled = !EDIT_MODES.includes(mode);
|
||||
this.inputs.forEach((input) => {
|
||||
const disabledLogin = this.keyInput === input && mode === MODES.Edit;
|
||||
input.disabled(disabled ? disabled : disabledLogin);
|
||||
});
|
||||
}
|
||||
|
||||
showButtons = (mode) => {
|
||||
this.buttons.forEach(({button, modes}) => {
|
||||
const isShow = modes.includes(mode);
|
||||
button.style.display = isShow ? 'inline-block' : 'none';
|
||||
});
|
||||
}
|
||||
|
||||
parseJSON = (text) => {
|
||||
return JSON.parse(text);
|
||||
}
|
||||
|
||||
validateInputs = () => {
|
||||
this.form.classList.add('was-validated');
|
||||
|
||||
this.inputs.forEach((input) => {
|
||||
const value = input.getValue();
|
||||
if (!value) {
|
||||
input.setError(FILL_FIELD);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
const value = this.valueInput.getValue();
|
||||
this.parseJSON(value);
|
||||
this.valueInput.setError('');
|
||||
} catch (e) {
|
||||
this.valueInput.setError('Некорректный json');
|
||||
}
|
||||
|
||||
return this.form.checkValidity();
|
||||
}
|
||||
|
||||
clearForm = () => {
|
||||
this.form.classList.remove('was-validated');
|
||||
this.inputs.forEach((input) => {
|
||||
input.setValue('');
|
||||
input.setError('');
|
||||
});
|
||||
}
|
||||
|
||||
createStore = () => {
|
||||
if (this.validateInputs()) {
|
||||
this.next(EVENTS.CREATE_STORE, {
|
||||
key: this.keyInput.getValue(),
|
||||
value: this.parseJSON(this.valueInput.getValue()),
|
||||
service_name: this.serviceNameInput.getValue(),
|
||||
author: this.authorInput.getValue(),
|
||||
description: this.descriptionInput.getValue(),
|
||||
});
|
||||
|
||||
this.clearForm();
|
||||
routeService.pushQuery({}, true);
|
||||
}
|
||||
}
|
||||
|
||||
saveStore = () => {
|
||||
if (this.validateInputs()) {
|
||||
this.next(EVENTS.SAVE_STORE, {
|
||||
key: this.keyInput.getValue(),
|
||||
value: this.parseJSON(this.valueInput.getValue()),
|
||||
service_name: this.serviceNameInput.getValue(),
|
||||
author: this.authorInput.getValue(),
|
||||
description: this.descriptionInput.getValue(),
|
||||
});
|
||||
this.clearForm();
|
||||
routeService.pushQuery({}, true);
|
||||
}
|
||||
}
|
||||
|
||||
deleteStore = () => {
|
||||
const {query: {key}} = routeService.getUrlData();
|
||||
this.next(EVENTS.DELETE_STORE, key);
|
||||
routeService.pushQuery({}, true);
|
||||
}
|
||||
|
||||
setKeyInput = (mode, key) => {
|
||||
const disabled = mode !== MODES.Create;
|
||||
this.keyInput.disabled(disabled);
|
||||
this.keyInput.setValue(key);
|
||||
}
|
||||
|
||||
setForm = async (mode, storeKey) => {
|
||||
const {key, value, description, service_name, author} = await this.loadStore(storeKey);
|
||||
this.setSidebarTitle(mode, storeKey);
|
||||
this.setKeyInput(mode, key);
|
||||
this.serviceNameInput.setValue(service_name);
|
||||
this.authorInput.setValue(author);
|
||||
this.descriptionInput.setValue(description);
|
||||
this.valueInput.setValue(this.stringifyValue(value));
|
||||
this.key = key;
|
||||
|
||||
this.sidebar.show();
|
||||
}
|
||||
this.setInputDisabled(mode);
|
||||
this.showButtons(mode);
|
||||
|
||||
deleteApi = async (key) => {
|
||||
await storageApi.remove(key);
|
||||
this.key = null;
|
||||
this.next('deleteApi');
|
||||
this.sidebar.hide();
|
||||
}
|
||||
|
||||
editApi () {
|
||||
if (!this.isEdit) {
|
||||
this.inputs.forEach((input) => {
|
||||
input.disabled(false);
|
||||
});
|
||||
this.editBtnText.textContent = 'Сохранить';
|
||||
this.editIcon.className = 'fas fa-check Edit__icon';
|
||||
this.isEdit = true;
|
||||
if (mode) {
|
||||
this.sidebar.show();
|
||||
} else {
|
||||
this.inputs.forEach((input) => {
|
||||
input.disabled(true);
|
||||
});
|
||||
this.editBtnText.textContent = 'Редактировать';
|
||||
this.editIcon.className = 'fas fa-pencil-alt Edit__icon';
|
||||
this.isEdit = false;
|
||||
this.sidebar.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,66 +0,0 @@
|
||||
.Create__body {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
|
||||
}
|
||||
.Create__container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
}
|
||||
.Create__title {
|
||||
text-align: center;
|
||||
}
|
||||
.Create__send {
|
||||
align-self: flex-end;
|
||||
}
|
||||
.Create__sidebar {
|
||||
width: 30%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.Create__footer {
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: flex-end;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
.Create__error-container {
|
||||
font-size: 0.8em;
|
||||
color: #F46E42;
|
||||
margin: auto;
|
||||
}
|
||||
.Create__editor {
|
||||
border: 1px solid #F2F2F2;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
min-height: 40vh;
|
||||
margin: 10px 0;
|
||||
}
|
||||
.Create__controls {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 15px;
|
||||
font-size: 20px;
|
||||
}
|
||||
.Create__input {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.Large__container {
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
.Scroll__body {
|
||||
overflow-y: auto;
|
||||
max-height: 60vh;
|
||||
}
|
||||
|
||||
@media (max-width: 800px) {
|
||||
.Create__body {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
@ -1,75 +0,0 @@
|
||||
import Component from '../../../../core/components/component/Component';
|
||||
import ButtonComponent from '../../../../core/components/button-component/ButtonComponent';
|
||||
import './CreateApiComponent.css';
|
||||
import storageApi from '../../api/StorageServiceAPI';
|
||||
import Modal from '../../../../core/components/modal/Modal';
|
||||
|
||||
class CreateApiComponent extends Component {
|
||||
constructor (container) {
|
||||
super('#create-api', container);
|
||||
|
||||
this.inputKey = this.mainNode.querySelector('.Create__key');
|
||||
this.inputServiceName = this.mainNode.querySelector('.Create__serviceName');
|
||||
this.inputDescription = this.mainNode.querySelector('.Create__description');
|
||||
this.inputAuthor = this.mainNode.querySelector('.Create__author');
|
||||
this.createError = this.mainNode.querySelector('.Create__error-container');
|
||||
this.header = this.mainNode.querySelector('.Create__title');
|
||||
this.body = this.mainNode.querySelector('.Create__body');
|
||||
this.footer = this.mainNode.querySelector('.Create__footer');
|
||||
this.form = this.mainNode.querySelector('.Create__form');
|
||||
this.editor = this.mainNode.querySelector('.Create__editor');
|
||||
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 = this.createComponent(Modal, document.body, this.content);
|
||||
this.modal.container.classList.add('Large__container');
|
||||
this.modal.content.classList.add('Scroll__body');
|
||||
|
||||
this.button.subscribe('click', () => {
|
||||
this.send();
|
||||
});
|
||||
}
|
||||
|
||||
show = () => {
|
||||
this.modal.show();
|
||||
}
|
||||
|
||||
parseString = async (text) => {
|
||||
const obj = await JSON.parse(text);
|
||||
return obj;
|
||||
}
|
||||
|
||||
send = async () => {
|
||||
try {
|
||||
const obj = await JSON.parse(this.editor.textContent);
|
||||
this.data = {
|
||||
key: this.inputKey.value,
|
||||
value: obj,
|
||||
description: this.inputDescription.value,
|
||||
service_name: this.inputServiceName.value,
|
||||
author: this.inputAuthor.value
|
||||
};
|
||||
|
||||
try {
|
||||
await storageApi.create(this.data);
|
||||
this.createError.textContent = '';
|
||||
this.modal.hide();
|
||||
this.next('renderTable');
|
||||
} catch (err) {
|
||||
if (err.response.status === 502) {
|
||||
this.createError.textContent = 'Заполните все необходимые поля для создания хранилища';
|
||||
} else if (err.response.status === 404) {
|
||||
this.createError.textContent = 'Не удалось создать хранилище. Возможно Вы используете не уникальное название хранилища';
|
||||
} else {
|
||||
this.createError.textContent = 'Что-то пошло не так';
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
this.createError.textContent = 'Тело хранилища не соответствует требованиям';
|
||||
}
|
||||
}
|
||||
}
|
||||
export default CreateApiComponent;
|
||||
23
src/pages/storages/components/hooks-component/HookRow.js
Normal file
23
src/pages/storages/components/hooks-component/HookRow.js
Normal file
@ -0,0 +1,23 @@
|
||||
import Component from '../../../../core/components/component/Component';
|
||||
import {EVENTS} from '../../../../core/consts';
|
||||
|
||||
export class HooksRow extends Component {
|
||||
constructor (parentNode, hook) {
|
||||
super('#api-hooks-row', parentNode);
|
||||
|
||||
this.holder = this.mainNode.querySelector('.Hook__holder');
|
||||
this.description = this.mainNode.querySelector('.Hook__description');
|
||||
this.read = this.mainNode.querySelector('.Hook__read');
|
||||
this.write = this.mainNode.querySelector('.Hook__write');
|
||||
this.deleteButton = this.mainNode.querySelector('.close');
|
||||
|
||||
this.holder.textContent = hook.holder;
|
||||
this.description.textContent = hook.description;
|
||||
this.read.textContent = hook.rights.read ? 'Да' : 'Нет';
|
||||
this.write.textContent = hook.rights.write ? 'Да' : 'Нет';
|
||||
|
||||
this.addEventListener(this.deleteButton, EVENTS.CLICK, () => {
|
||||
this.next(EVENTS.DELETE_HOOK, hook.id);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
import Component from '../../../../core/components/component/Component';
|
||||
import hooksApi from '../../api/HooksAPI';
|
||||
import routeService from '../../../../services/RouteService';
|
||||
import {EVENTS} from '../../../../core/consts';
|
||||
import {HooksRow} from './HookRow';
|
||||
import {AddHookModal} from '../add-hook-modal/AddHookModal';
|
||||
|
||||
export class HooksComponent extends Component {
|
||||
constructor () {
|
||||
super('#api-hooks', null);
|
||||
|
||||
this.hooks = [];
|
||||
|
||||
this.container = this.mainNode.querySelector('.list-group');
|
||||
|
||||
this.addSubscribe(routeService, EVENTS.ROUTE_SEARCH_CHANGE, ({query}) => {
|
||||
const {mode, key} = query;
|
||||
this.initHooks(mode, key);
|
||||
});
|
||||
|
||||
this.addHookButton = this.mainNode.querySelector('.ApiHooks__addButton');
|
||||
this.addHookModal = this.createComponent(AddHookModal, this.mainNode);
|
||||
|
||||
this.addEventListener(this.addHookButton, EVENTS.CLICK, this.addHookModal.openForm);
|
||||
this.addSubscribe(this.addHookModal, EVENTS.SAVE_HOOK, this.initHooks);
|
||||
|
||||
this.initHooks();
|
||||
}
|
||||
|
||||
initHooks = async () => {
|
||||
const {query: {mode, key}} = routeService.getUrlData();
|
||||
|
||||
this.hooks.forEach((hook) => {
|
||||
hook.destroy();
|
||||
});
|
||||
this.hooks = [];
|
||||
|
||||
if (key && mode) {
|
||||
const hooks = await hooksApi.request(key);
|
||||
this.hooks = hooks.map((hook) => {
|
||||
const component = this.createComponent(HooksRow, this.container, hook);
|
||||
this.addSubscribe(component, EVENTS.DELETE_HOOK, async (id) => {
|
||||
await hooksApi.remove(key, id);
|
||||
this.initHooks(mode, key);
|
||||
});
|
||||
return component;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
import Component from '../../../../core/components/component/Component';
|
||||
import storageApi from '../../api/StorageServiceAPI';
|
||||
import FilterApiComponent from '../filter-api-component/FilterApiComponent';
|
||||
import ApiInfoComponent from '../api-info-component/ApiInfoComponent';
|
||||
import CreateApiComponent from '../create-api-component/CreateApiComponent';
|
||||
import ButtonComponent from '../../../../core/components/button-component/ButtonComponent';
|
||||
import ApiTableComponent from '../api-table-component/ApiTableComponent';
|
||||
import ApiTableViewForm from '../api-table-view-form/ApiTableViewForm';
|
||||
import {EVENTS} from '../../../../core/consts';
|
||||
import {EVENTS, MODES} from '../../../../core/consts';
|
||||
import routeService from '../../../../services/RouteService';
|
||||
|
||||
class ApiPage extends Component {
|
||||
constructor (mainNodeSelector, parentNode) {
|
||||
@ -16,26 +15,31 @@ class ApiPage extends Component {
|
||||
|
||||
this.apiViewForm = this.createComponent(ApiTableViewForm);
|
||||
|
||||
this.infoBox = this.createComponent(ApiInfoComponent);
|
||||
this.createWindow = this.createComponent(CreateApiComponent);
|
||||
|
||||
this.createBtn = this.createComponent(ButtonComponent, this.filterBox.filterButtonBox, '✚', 'btn btn-primary mb-3 Create__btn');
|
||||
this.addSubscribe(this.createBtn, 'click', () => {
|
||||
this.createWindow.show();
|
||||
});
|
||||
this.addSubscribe(this.createWindow, 'renderTable', () => {
|
||||
this.initStorageListTable();
|
||||
this.addSubscribe(this.createBtn, EVENTS.CLICK, () => {
|
||||
routeService.pushQuery({mode: MODES.Create}, true);
|
||||
});
|
||||
|
||||
this.initStorageListTable();
|
||||
|
||||
this.addSubscribe(this.apiViewForm, 'deleteApi', () => {
|
||||
this.addSubscribe(this.apiViewForm, EVENTS.CREATE_STORE, async (store) => {
|
||||
await storageApi.create(store);
|
||||
this.initStorageListTable();
|
||||
});
|
||||
|
||||
this.addSubscribe(this.apiViewForm, EVENTS.SAVE_STORE, async (store) => {
|
||||
await storageApi.update(store);
|
||||
this.initStorageListTable();
|
||||
});
|
||||
|
||||
this.addSubscribe(this.apiViewForm, EVENTS.DELETE_STORE, async (storeKey) => {
|
||||
await storageApi.remove(storeKey);
|
||||
this.initStorageListTable();
|
||||
});
|
||||
|
||||
this.apiTable = this.createComponent(ApiTableComponent, this.mainNode);
|
||||
this.addSubscribe(this.apiTable, EVENTS.ROW_DOUBLE_CLICK, (_, row) => {
|
||||
this.apiViewForm.setForm(row);
|
||||
routeService.pushQuery({mode: MODES.View, key: row.key}, true);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user