Replace search button to input field at navbar.
* Search input not rendered at /search path. * Navbar wrapped with withRouter for accessing history props. * Flex-grow/shrink control the width of the input element dynamically.
This commit is contained in:
parent
80bca8610e
commit
e41117c878
3 changed files with 50 additions and 9 deletions
8
ui/assets/css/main.css
vendored
8
ui/assets/css/main.css
vendored
|
@ -249,3 +249,11 @@ pre {
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
word-break: keep-all;
|
word-break: keep-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-bar {
|
||||||
|
flex-basis: 10%;
|
||||||
|
flex-shrink: 3;
|
||||||
|
flex-grow: 0.3;
|
||||||
|
max-width: 33%;
|
||||||
|
min-width: 11em;
|
||||||
|
}
|
49
ui/src/components/navbar.tsx
vendored
49
ui/src/components/navbar.tsx
vendored
|
@ -1,5 +1,5 @@
|
||||||
import { Component, linkEvent } from 'inferno';
|
import { Component, linkEvent } from 'inferno';
|
||||||
import { Link } from 'inferno-router';
|
import { Link, withRouter } from 'inferno-router';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { retryWhen, delay, take } from 'rxjs/operators';
|
import { retryWhen, delay, take } from 'rxjs/operators';
|
||||||
import { WebSocketService, UserService } from '../services';
|
import { WebSocketService, UserService } from '../services';
|
||||||
|
@ -12,6 +12,7 @@ import {
|
||||||
GetPrivateMessagesForm,
|
GetPrivateMessagesForm,
|
||||||
PrivateMessagesResponse,
|
PrivateMessagesResponse,
|
||||||
SortType,
|
SortType,
|
||||||
|
SearchType,
|
||||||
GetSiteResponse,
|
GetSiteResponse,
|
||||||
Comment,
|
Comment,
|
||||||
CommentResponse,
|
CommentResponse,
|
||||||
|
@ -19,6 +20,7 @@ import {
|
||||||
UserView,
|
UserView,
|
||||||
PrivateMessageResponse,
|
PrivateMessageResponse,
|
||||||
WebSocketJsonResponse,
|
WebSocketJsonResponse,
|
||||||
|
SearchForm,
|
||||||
} from '../interfaces';
|
} from '../interfaces';
|
||||||
import {
|
import {
|
||||||
wsJsonToRes,
|
wsJsonToRes,
|
||||||
|
@ -42,9 +44,10 @@ interface NavbarState {
|
||||||
unreadCount: number;
|
unreadCount: number;
|
||||||
siteName: string;
|
siteName: string;
|
||||||
admins: Array<UserView>;
|
admins: Array<UserView>;
|
||||||
|
searchParam: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Navbar extends Component<any, NavbarState> {
|
class Navbar extends Component<any, NavbarState> {
|
||||||
private wsSub: Subscription;
|
private wsSub: Subscription;
|
||||||
private userSub: Subscription;
|
private userSub: Subscription;
|
||||||
emptyState: NavbarState = {
|
emptyState: NavbarState = {
|
||||||
|
@ -56,6 +59,7 @@ export class Navbar extends Component<any, NavbarState> {
|
||||||
expanded: false,
|
expanded: false,
|
||||||
siteName: undefined,
|
siteName: undefined,
|
||||||
admins: [],
|
admins: [],
|
||||||
|
searchParam: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props: any, context: any) {
|
constructor(props: any, context: any) {
|
||||||
|
@ -87,6 +91,25 @@ export class Navbar extends Component<any, NavbarState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
WebSocketService.Instance.getSite();
|
WebSocketService.Instance.getSite();
|
||||||
|
|
||||||
|
this.handleSearchParam = this.handleSearchParam.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSearchParam(i: Navbar, event: any) {
|
||||||
|
i.state.searchParam = event.target.value;
|
||||||
|
i.setState(i.state);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateUrl() {
|
||||||
|
this.props.history.push(
|
||||||
|
`/search/q/${this.state.searchParam}/type/all/sort/topall/page/1`
|
||||||
|
);
|
||||||
|
this.setState({ searchParam: '' });
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSearchSubmit(i: Navbar, event: any) {
|
||||||
|
event.preventDefault();
|
||||||
|
i.updateUrl();
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -143,11 +166,6 @@ export class Navbar extends Component<any, NavbarState> {
|
||||||
{i18n.t('communities')}
|
{i18n.t('communities')}
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
|
||||||
<Link class="nav-link" to="/search" title={i18n.t('search')}>
|
|
||||||
{i18n.t('search')}
|
|
||||||
</Link>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<Link
|
<Link
|
||||||
class="nav-link"
|
class="nav-link"
|
||||||
|
@ -181,7 +199,20 @@ export class Navbar extends Component<any, NavbarState> {
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="navbar-nav ml-auto">
|
{!this.props.history.location.pathname.match(/^\/search/) && (
|
||||||
|
<div class="nav-item search-bar">
|
||||||
|
<form onSubmit={linkEvent(this, this.handleSearchSubmit)}>
|
||||||
|
<input
|
||||||
|
class="form-control mr-sm-2"
|
||||||
|
onInput={linkEvent(this, this.handleSearchParam)}
|
||||||
|
value={this.state.searchParam}
|
||||||
|
type="search"
|
||||||
|
placeholder={i18n.t('search')}
|
||||||
|
></input>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<ul class="navbar-nav ml-2">
|
||||||
{this.canAdmin && (
|
{this.canAdmin && (
|
||||||
<li className="nav-item mt-1">
|
<li className="nav-item mt-1">
|
||||||
<Link
|
<Link
|
||||||
|
@ -426,3 +457,5 @@ export class Navbar extends Component<any, NavbarState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default withRouter(Navbar);
|
||||||
|
|
2
ui/src/index.tsx
vendored
2
ui/src/index.tsx
vendored
|
@ -2,7 +2,7 @@ import { render, Component } from 'inferno';
|
||||||
import { BrowserRouter, Route, Switch } from 'inferno-router';
|
import { BrowserRouter, Route, Switch } from 'inferno-router';
|
||||||
import { Provider } from 'inferno-i18next';
|
import { Provider } from 'inferno-i18next';
|
||||||
import { Main } from './components/main';
|
import { Main } from './components/main';
|
||||||
import { Navbar } from './components/navbar';
|
import Navbar from './components/navbar';
|
||||||
import { Footer } from './components/footer';
|
import { Footer } from './components/footer';
|
||||||
import { Login } from './components/login';
|
import { Login } from './components/login';
|
||||||
import { CreatePost } from './components/create-post';
|
import { CreatePost } from './components/create-post';
|
||||||
|
|
Loading…
Reference in a new issue