autocomplete component
This commit is contained in:
parent
3d9e50ea7a
commit
dbdaee0069
10 changed files with 61 additions and 77 deletions
|
@ -4,15 +4,13 @@
|
|||
"description": "frontend for justlog",
|
||||
"repository": "github.com/gempir/justlog",
|
||||
"dependencies": {
|
||||
"material-design-icons": "^3.0.1",
|
||||
"react": "^16.12.0",
|
||||
"react-dom": "^16.12.0",
|
||||
"react-redux": "^7.1.3",
|
||||
"react-string-replace": "^0.4.4",
|
||||
"react-toastify": "^5.5.0",
|
||||
"redux": "^4.0.5",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"whatwg-fetch": "^3.0.0"
|
||||
"redux-thunk": "^2.3.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "webpack-dev-server --mode development --content-base public",
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="theme-color" content="#000000">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
||||
<link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet'>
|
||||
<meta name="theme-color" content="#282828">
|
||||
<title>logsearch</title>
|
||||
</head>
|
||||
<body>
|
||||
|
|
19
web/src/js/components/AutocompleteInput.jsx
Normal file
19
web/src/js/components/AutocompleteInput.jsx
Normal file
|
@ -0,0 +1,19 @@
|
|||
import React, { Component } from "react";
|
||||
|
||||
export default class AutocompleteInput extends Component {
|
||||
render() {
|
||||
return <div className="AutocompleteInput">
|
||||
<input
|
||||
type="text"
|
||||
placeholder={this.props.placeholder}
|
||||
onChange={this.props.onChange}
|
||||
value={this.props.value}
|
||||
/>
|
||||
<ul>
|
||||
{this.props.autocompletions
|
||||
.filter(channel => channel.name.includes(this.props.value))
|
||||
.map(channel => <li key={channel.userID} onClick={() => this.setChannel(channel.name)}>{channel.name}</li>)}
|
||||
</ul>
|
||||
</div>
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import React, { Component } from "react";
|
||||
import {connect} from "react-redux";
|
||||
import { connect } from "react-redux";
|
||||
import setCurrent from "./../actions/setCurrent";
|
||||
import AutocompleteInput from "./AutocompleteInput";
|
||||
|
||||
class Filter extends Component {
|
||||
|
||||
|
@ -22,21 +23,17 @@ class Filter extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const completions = this.props.channels
|
||||
.filter(channel => channel.name.includes(this.props.currentChannel));
|
||||
|
||||
const autocompletions = [];
|
||||
for (const completion of completions) {
|
||||
autocompletions.push(<li key={completion.userID} onClick={() => this.setChannel(completion.name)}>{completion.name}</li>);
|
||||
}
|
||||
|
||||
return (
|
||||
<form className="filter" autoComplete="off" onSubmit={this.onSubmit}>
|
||||
<div className="channel-wrapper">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="pajlada"
|
||||
onChange={this.onChannelChange}
|
||||
value={this.props.currentChannel}
|
||||
/>
|
||||
<ul className="channel-autocomplete">
|
||||
{this.props.channels
|
||||
.filter(channel => channel.name.includes(this.props.currentChannel))
|
||||
.map(channel => <li key={channel.userID} onClick={() => this.setChannel(channel.name)}>{channel.name}</li>)}
|
||||
</ul>
|
||||
</div>
|
||||
<AutocompleteInput placeholder="pajlada" onChange={this.onChannelChange} value={this.props.currentChannel} autocompletions={this.props.channels} />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="gempir"
|
||||
|
@ -48,8 +45,6 @@ class Filter extends Component {
|
|||
)
|
||||
}
|
||||
|
||||
setChannel = channel => this.props.dispatch(setCurrent(channel, this.props.currentUsername));
|
||||
|
||||
onChannelChange = (e) => {
|
||||
this.props.dispatch(setCurrent(e.target.value, this.props.currentUsername));
|
||||
}
|
||||
|
@ -68,6 +63,13 @@ class Filter extends Component {
|
|||
|
||||
onSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const url = new URL(window.location.href);
|
||||
const params = new URLSearchParams(url.search);
|
||||
params.set('channel', this.props.currentChannel);
|
||||
params.set('username', this.props.currentUsername);
|
||||
window.location.search = params.toString();
|
||||
|
||||
this.props.searchLogs(this.props.currentChannel, this.props.currentUsername, this.state.year, this.state.month);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,4 +8,5 @@
|
|||
@import "modules/log-search";
|
||||
@import "modules/filter";
|
||||
@import "modules/log-view";
|
||||
@import "modules/AutocompleteInput";
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ input {
|
|||
background: $grey-dark;
|
||||
outline: none;
|
||||
border: 0;
|
||||
padding: 10px;
|
||||
border-radius: 3px;
|
||||
|
||||
&:focus {
|
||||
|
|
15
web/src/scss/modules/AutocompleteInput.scss
Normal file
15
web/src/scss/modules/AutocompleteInput.scss
Normal file
|
@ -0,0 +1,15 @@
|
|||
.AutocompleteInput {
|
||||
position: relative;
|
||||
|
||||
input {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
ul {
|
||||
position: absolute;
|
||||
background: $grey-medium;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
|
@ -11,54 +11,18 @@
|
|||
|
||||
input {
|
||||
width: 100%;
|
||||
padding: 0 0.5rem;
|
||||
|
||||
&::-webkit-input-placeholder {
|
||||
opacity: 0.25;
|
||||
}
|
||||
}
|
||||
|
||||
.channel-wrapper {
|
||||
.AutocompleteInput {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
margin-right: 0.5rem;
|
||||
|
||||
input:focus {
|
||||
|
||||
& + .channel-autocomplete {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.channel-autocomplete {
|
||||
display: none;
|
||||
position: absolute;
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background: $grey-medium;
|
||||
z-index: 100;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 0;
|
||||
font-size: 0.8rem;
|
||||
@include box-shadow(2);
|
||||
border-bottom-left-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
color: white;
|
||||
|
||||
li {
|
||||
cursor: pointer;
|
||||
padding: 5px;
|
||||
|
||||
&:hover {
|
||||
background: $grey-light;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.show-logs {
|
||||
width: 200px;
|
||||
margin-left: 0.5rem;
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
background: $grey-light;
|
||||
}
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.line {
|
||||
padding: 0.25rem;
|
||||
color: white;
|
||||
|
|
|
@ -4695,13 +4695,6 @@ fsevents@^1.2.7:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"material-design-icons@npm:^3.0.1":
|
||||
version: 3.0.1
|
||||
resolution: "material-design-icons@npm:3.0.1"
|
||||
checksum: 1248effdfb7175ce9ade19224ebe83741142b1668732fddab064083c7c9b70561d42b3e59d770d26c95ac892ceecfe65079ebca31a07ba179a7a8fdf28203af6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"md5.js@npm:^1.3.4":
|
||||
version: 1.3.5
|
||||
resolution: "md5.js@npm:1.3.5"
|
||||
|
@ -7817,7 +7810,6 @@ fsevents@^1.2.7:
|
|||
"@babel/preset-react": ^7.8.3
|
||||
babel-loader: ^8.0.6
|
||||
css-loader: ^3.4.2
|
||||
material-design-icons: ^3.0.1
|
||||
mini-css-extract-plugin: ^0.9.0
|
||||
node-sass: ^4.13.1
|
||||
pnp-webpack-plugin: ^1.6.0
|
||||
|
@ -7833,7 +7825,6 @@ fsevents@^1.2.7:
|
|||
webpack: ^4.41.5
|
||||
webpack-cli: ^3.3.10
|
||||
webpack-dev-server: ^3.10.1
|
||||
whatwg-fetch: ^3.0.0
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
|
@ -7991,13 +7982,6 @@ fsevents@^1.2.7:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"whatwg-fetch@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "whatwg-fetch@npm:3.0.0"
|
||||
checksum: a3033a72d7300f899073ed30fe46e12ff7142ed06221879a610a919c01b8b26d3f82ac7a5c18c397a1cb6a95b3df95a644e45ead93c10872118fc0e961ea9f2c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"which-module@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "which-module@npm:1.0.0"
|
||||
|
|
Loading…
Add table
Reference in a new issue