HM-29 фильтр таблицы апи (#24)
* HM-29 Сделал фильтр по макету + добавил кнопку создания апишки, добавлен так же интерфейс создания апи, но он нуждается в редактировании и будет улучшен в отдельной ветке
This commit is contained in:
55
src/app.html
55
src/app.html
@ -144,8 +144,29 @@
|
|||||||
<th class="Body__row-index"></th>
|
<th class="Body__row-index"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
|
<!-- Шаблон панели фильтрации -->
|
||||||
|
<template id="filter-container">
|
||||||
|
<div class="Filter__container">
|
||||||
|
<form class="Filter__form row p-3 m-0">
|
||||||
|
<div class="col-md-auto">
|
||||||
|
<div class="Filter__inputs-box row">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="Filter__button-box col d-flex align-items-end">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<!-- Шаблон инпута фильтра таблицы -->
|
||||||
|
<template id="filter-input">
|
||||||
|
<div class="Filter__input-box col mb-3">
|
||||||
|
<label for="logs-filter-log-type" class="Filter__label form-label"></label>
|
||||||
|
<input type="text" class="Filter__input form-control" name="" placeholder="Введите текст">
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<!-- Шаблон главной таблицы -->
|
<!-- Шаблон главной таблицы -->
|
||||||
<template id="main-table">
|
<template id="main-table">
|
||||||
|
<div class="table-responsive">
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
<thead class="Table__head">
|
<thead class="Table__head">
|
||||||
<tr class="Table__head-row">
|
<tr class="Table__head-row">
|
||||||
@ -155,6 +176,7 @@
|
|||||||
<tbody class="Table__body">
|
<tbody class="Table__body">
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<!-- Шаблон информации об апи -->
|
<!-- Шаблон информации об апи -->
|
||||||
<template id="api-info">
|
<template id="api-info">
|
||||||
@ -188,6 +210,39 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<!-- Шаблон для создания апи -->
|
||||||
|
<template id="create-api">
|
||||||
|
<div class="card text-center Info__container">
|
||||||
|
<div class="card-header">
|
||||||
|
<h1 class="Create__title">Новая база данных</h1>
|
||||||
|
</div>
|
||||||
|
<div class="Create__body">
|
||||||
|
<div class="Create__sidebar">
|
||||||
|
<form class="Create__form">
|
||||||
|
<div class="form-group Create__input">
|
||||||
|
<label for="key">Api key</label>
|
||||||
|
<input type="text" class="Create__key form-control" name="key" placeholder="Имя базы данных">
|
||||||
|
</div>
|
||||||
|
<div class="form-group Create__input">
|
||||||
|
<label for="serviceName">Service name</label>
|
||||||
|
<input type="text" class="Create__serviceName form-control" name="serviceName" placeholder="Название проекта">
|
||||||
|
</div>
|
||||||
|
<div class="form-group Create__input">
|
||||||
|
<label for="description">description</label>
|
||||||
|
<input type="textarea" class="Create__description form-control" name="description" placeholder="Краткое описание БД">
|
||||||
|
</div>
|
||||||
|
<div class="form-group Create__input">
|
||||||
|
<label for="author">author</label>
|
||||||
|
<input type="text" class="Create__author form-control" name="author" placeholder="Автор базы данных">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<code contenteditable class="Create__editor"></code>
|
||||||
|
</div>
|
||||||
|
<div class="Create__footer card-footer text-muted">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,14 @@
|
|||||||
import Component from '../component/index';
|
import Component from '../component/index';
|
||||||
import TableComponent from '../table-component';
|
import TableComponent from '../table-component';
|
||||||
import storageApi from '../../api/StorageServiceAPI';
|
import storageApi from '../../api/StorageServiceAPI';
|
||||||
|
import FilterApiComponent from '../search-component/index';
|
||||||
|
|
||||||
class ApiPage extends Component {
|
class ApiPage extends Component {
|
||||||
constructor (mainNodeSelector, parentNode) {
|
constructor (mainNodeSelector, parentNode) {
|
||||||
super(mainNodeSelector, parentNode);
|
super(mainNodeSelector, parentNode);
|
||||||
|
|
||||||
|
this.filterBox = new FilterApiComponent(this.mainNode);
|
||||||
|
|
||||||
const initStorageListTable = async () => {
|
const initStorageListTable = async () => {
|
||||||
const list = await storageApi.request();
|
const list = await storageApi.request();
|
||||||
const storageListTable = new TableComponent(this.mainNode);
|
const storageListTable = new TableComponent(this.mainNode);
|
||||||
|
|||||||
33
src/components/create-api-component/CreateApiComponent.css
Normal file
33
src/components/create-api-component/CreateApiComponent.css
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
.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__sidebar {
|
||||||
|
width: 30%;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.Create__editor {
|
||||||
|
border: 1px solid #F2F2F2;
|
||||||
|
text-align: left;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.Create__controls {
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
top: 15px;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
.Create__input {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
39
src/components/create-api-component/CreateApiComponent.js
Normal file
39
src/components/create-api-component/CreateApiComponent.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import Component from '../component/index';
|
||||||
|
import ButtonComponent from '../button-component/ButtonComponent';
|
||||||
|
import './CreateApiComponent.css';
|
||||||
|
import storageApi from '../../api/StorageServiceAPI';
|
||||||
|
import routeService from '../../services/RouteService';
|
||||||
|
|
||||||
|
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.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');
|
||||||
|
|
||||||
|
this.button.subscribe('click', () => {
|
||||||
|
this.send();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
send = () => {
|
||||||
|
const obj = 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
|
||||||
|
};
|
||||||
|
|
||||||
|
storageApi.create(this.data);
|
||||||
|
routeService.goTo('/api');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default CreateApiComponent;
|
||||||
3
src/components/create-api-component/index.js
Normal file
3
src/components/create-api-component/index.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import CreateApiComponent from './CreateApiComponent';
|
||||||
|
|
||||||
|
export default CreateApiComponent;
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
import Component from '../component/index';
|
||||||
|
|
||||||
|
class FilterInputComponent extends Component {
|
||||||
|
constructor (container, content) {
|
||||||
|
super('#filter-input', container);
|
||||||
|
|
||||||
|
this.label = this.mainNode.querySelector('label');
|
||||||
|
this.label.htmlFor = content.id;
|
||||||
|
this.label.textContent = content.title;
|
||||||
|
this.input = this.mainNode.querySelector('input');
|
||||||
|
this.input.placeholder = content.placeholder;
|
||||||
|
this.input.id = content.id;
|
||||||
|
this.input.name = content.key;
|
||||||
|
}
|
||||||
|
|
||||||
|
getValue = () => {
|
||||||
|
return this.input.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default FilterInputComponent;
|
||||||
3
src/components/filter-input-component/index.js
Normal file
3
src/components/filter-input-component/index.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import FilterInputComponent from './FilterInputComponent';
|
||||||
|
|
||||||
|
export default FilterInputComponent;
|
||||||
@ -2,7 +2,6 @@ import Component from '../component/index';
|
|||||||
import routeService from '../../services/RouteService';
|
import routeService from '../../services/RouteService';
|
||||||
import ButtonComponent from '../button-component/ButtonComponent';
|
import ButtonComponent from '../button-component/ButtonComponent';
|
||||||
import Image from '../../img/logo.png';
|
import Image from '../../img/logo.png';
|
||||||
|
|
||||||
import './NavButtonComponent.css';
|
import './NavButtonComponent.css';
|
||||||
|
|
||||||
class NavButtonComponent extends Component {
|
class NavButtonComponent extends Component {
|
||||||
|
|||||||
8
src/components/search-component/FilterApiComponent.css
Normal file
8
src/components/search-component/FilterApiComponent.css
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
.Filter__input {
|
||||||
|
min-width: 200px;
|
||||||
|
}
|
||||||
|
.Create__btn {
|
||||||
|
margin: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
55
src/components/search-component/FilterApiComponent.js
Normal file
55
src/components/search-component/FilterApiComponent.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import Component from '../component/index';
|
||||||
|
import ButtonComponent from '../button-component/ButtonComponent';
|
||||||
|
import './FilterApiComponent.css';
|
||||||
|
import routeService from '../../services/RouteService';
|
||||||
|
import {FILTER_ROWS} from './constants';
|
||||||
|
import FilterInputComponent from '../filter-input-component/index';
|
||||||
|
import TestModal from '../test-modal/index';
|
||||||
|
import CreateApiComponent from '../create-api-component/index';
|
||||||
|
|
||||||
|
class FilterApiComponent extends Component {
|
||||||
|
constructor (container) {
|
||||||
|
super('#filter-container', container);
|
||||||
|
this.form = this.mainNode.querySelector('.Filter__form');
|
||||||
|
this.filterInputsBox = this.mainNode.querySelector('.Filter__inputs-box');
|
||||||
|
this.filterButtonBox = this.mainNode.querySelector('.Filter__button-box');
|
||||||
|
this.modal = new TestModal();
|
||||||
|
this.searchBtn = new ButtonComponent(this.filterButtonBox, 'Найти', 'btn btn-primary mb-3');
|
||||||
|
this.createBtn = new ButtonComponent(this.filterButtonBox, '✚', 'btn btn-primary mb-3 Create__btn');
|
||||||
|
this.createWindow = new CreateApiComponent(this.modal.window);
|
||||||
|
this.createBtn.subscribe('click', () => this.modal.show());
|
||||||
|
|
||||||
|
this.inputs = FILTER_ROWS.map((item) => {
|
||||||
|
const {query} = routeService.getUrlData();
|
||||||
|
const input = new FilterInputComponent(this.filterInputsBox, item);
|
||||||
|
Object.keys(query).forEach((elem) => {
|
||||||
|
if (elem === item.key) {
|
||||||
|
input.input.value = query[elem];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return input;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.searchBtn.subscribe('click', () => {
|
||||||
|
this.send();
|
||||||
|
|
||||||
|
});
|
||||||
|
this.addEventListener(this.form, 'submit', (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
this.send();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
send = () => {
|
||||||
|
const query = this.inputs.reduce((memo, element) => {
|
||||||
|
const name = element.input.name;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...memo,
|
||||||
|
[name]: element.input.value
|
||||||
|
};
|
||||||
|
}, {});
|
||||||
|
routeService.goTo('/api', query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default FilterApiComponent;
|
||||||
6
src/components/search-component/constants.js
Normal file
6
src/components/search-component/constants.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export const FILTER_ROWS = [
|
||||||
|
{title: 'Название хранилища', placeholder: 'Введите текст', key: 'key', id: 'filter-api-input-key'},
|
||||||
|
{title: 'Описание', placeholder: 'Введите текст', key: 'description', id: 'filter-api-input-description'},
|
||||||
|
{title: 'Имя сервиса', placeholder: 'Введите текст', key: 'service_name', id: 'filter-api-input-service-name'},
|
||||||
|
{title: 'Автор', placeholder: 'Введите текст', key: 'author', id: 'filter-api-input-author'},
|
||||||
|
];
|
||||||
3
src/components/search-component/index.js
Normal file
3
src/components/search-component/index.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import FilterApiComponent from './FilterApiComponent';
|
||||||
|
|
||||||
|
export default FilterApiComponent;
|
||||||
@ -53,4 +53,5 @@ class TableComponent extends Component {
|
|||||||
this.infoBox.render(object, index);
|
this.infoBox.render(object, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TableComponent;
|
export default TableComponent;
|
||||||
|
|||||||
@ -11,7 +11,13 @@ class TableRowComponent extends Component {
|
|||||||
|
|
||||||
this.content.forEach((text) => {
|
this.content.forEach((text) => {
|
||||||
const contentPlace = document.createElement('td');
|
const contentPlace = document.createElement('td');
|
||||||
contentPlace.textContent = typeof(text) !== 'string' ? typeof(text) : text;
|
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.row.appendChild(contentPlace);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user