/** * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except * in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import { cloneDeep, debounce } from "lodash"; import * as React from "react"; import { Form, Grid, Header, Input, List } from "semantic-ui-react"; import { BallerinaExampleCategory } from "./model"; export interface SamplesListState { samples?: BallerinaExampleCategory[]; searchQuery?: string; } export interface SamplesListProps { openSample: (url: string) => void; getSamples: () => Promise; } /** * React component for rendering a list of Ballerina examples. * * @class SamplesList * @extends {Component} */ export class SamplesList extends React.Component { private availableSamples: undefined | BallerinaExampleCategory[]; private searchInput: Input | undefined; private onSearchQueryEdit: () => void; constructor(props: SamplesListProps, context: SamplesListState) { super(props, context); this.onSearchQueryEdit = debounce(() => { const { searchQuery } = this.state; if (searchQuery !== undefined && this.availableSamples) { let samples = cloneDeep(this.availableSamples); samples = samples.filter((sampleCategory) => { if (!sampleCategory.title.toLowerCase().includes(searchQuery)) { sampleCategory.samples = sampleCategory .samples.filter((sample) => sample.name.toLowerCase().includes(searchQuery)); } return sampleCategory.samples.length !== 0; }); this.setState({ samples, }); } }, 500).bind(this); } public componentDidMount() { this.focusOnSearchInput(); this.props.getSamples().then((samples) => { this.availableSamples = samples; this.setState({ samples, }); }); } public componentWillReceiveProps(nextProps: SamplesListProps) { this.props.getSamples().then((samples) => { this.availableSamples = samples; this.setState({ samples, }); }); } public focusOnSearchInput() { if (this.searchInput) { this.searchInput.focus(); } } public getColumnContents() { const columns: BallerinaExampleCategory[][] = []; const { samples } = this.state; if (samples) { samples.forEach((sample: BallerinaExampleCategory) => { columns[sample.column] = columns[sample.column] || []; columns[sample.column].push(sample); }); } return columns; } public renderColumnItem(column: BallerinaExampleCategory) { return ( {column.title} { column.samples.map((sample) => { return ( this.props.openSample(sample.url)} > {sample.name} ); }) } ); } public render() { return (
Ballerina Examples
{ this.searchInput = ref as Input; }} loading={!this.state || !this.state.samples} placeholder="Search" onChange={(event: React.SyntheticEvent) => { this.setState({ searchQuery: event.currentTarget.value, }); this.onSearchQueryEdit(); }} className="search-control" />
{this.state && this.state.samples && { this.getColumnContents().map((column, index) => { return ( {column.map((columnItem) => this.renderColumnItem(columnItem))} ); }) } }
); } }