diff --git a/package.json b/package.json index b3cfabe..b3db655 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "homepage": "https://redar.com/", "dependencies": { "@types/chrome": "^0.0.56", + "@types/classnames": "^2.2.3", "@types/flux": "^3.1.4", "@types/jest": "^21.1.8", "@types/node": "^8.0.47", @@ -16,6 +17,7 @@ "axios": "^0.17.1", "case-sensitive-paths-webpack-plugin": "2.1.1", "chalk": "1.1.3", + "classnames": "^2.2.5", "copy-webpack-plugin": "^4.3.0", "css-loader": "0.28.4", "dotenv": "4.0.0", diff --git a/scaffold/component/{{Name}}.tsx b/scaffold/component/{{Name}}.tsx index 18152b1..3b22430 100644 --- a/scaffold/component/{{Name}}.tsx +++ b/scaffold/component/{{Name}}.tsx @@ -9,13 +9,13 @@ class {{Name}} extends React.Component { } render() { - const classNames = [ + const className = [ css.{{Name}}, this.props.className ].join(' ') return ( -
+
{{Name}} Component
) diff --git a/src/common/Dispatcher.tsx b/src/common/Dispatcher.ts similarity index 71% rename from src/common/Dispatcher.tsx rename to src/common/Dispatcher.ts index f0acf64..fddd185 100644 --- a/src/common/Dispatcher.tsx +++ b/src/common/Dispatcher.ts @@ -4,16 +4,12 @@ import * as Immutable from 'immutable' const ActionTypes = { UPDATE_RESPONSE: 'UPDATE_RESPONSE', - UPDATE_TABLE: 'UPDATE_TABLE', - UPDATE_COLUMNS: 'UPDATE_COLUMNS', UPDATE_VIEWKEY: 'UPDATE_VIEWKEY', UPDATE_REQ_TYPE: 'UPDATE_REQ_TYPE', } const StoreKeys = { Response: 'RESPONSE', - Table: 'TABLE', - Columns: 'COLUMNS', ViewKey: 'VIEWKEY', RequestType: 'REQ_TYPE' } @@ -40,29 +36,43 @@ class AppStore extends ReduceStore { } getInitialState() { - return Immutable.OrderedMap() + const t = Immutable.OrderedMap([ + [StoreKeys.ViewKey, localStorage.lastViewKey || ''] + ]) + console.debug(t) + return t } reduce(state: IState, action: IAction) { switch (action.name) { - case ActionTypes.UPDATE_COLUMNS: - return state.set(StoreKeys.Columns, action.payload) - case ActionTypes.UPDATE_TABLE: - return state.set(StoreKeys.Table, action.payload) case ActionTypes.UPDATE_RESPONSE: + let viewKey = state.get(StoreKeys.ViewKey) + if (localStorage.lastViewKey !== '' && action.payload && !action.payload.hasOwnProperty(viewKey)) { + viewKey = this.getViewKey(action.payload) + state = state.set(StoreKeys.ViewKey, viewKey) + } return state.set(StoreKeys.Response, action.payload) case ActionTypes.UPDATE_VIEWKEY: + localStorage.lastViewKey = action.payload return state.set(StoreKeys.ViewKey, action.payload) default: return state } } + + private getViewKey(data: any) { + for (const k in data) { + if (data.hasOwnProperty(k) && data[k] && data[k].constructor === Array) { + return k + } + } + + return '' + } } export function dispatch(name: TActionName | string, payload: any) { - AppDispatcher.dispatch({ - name, payload - }) + AppDispatcher.dispatch({ name, payload }) } function register(name: TActionName | string, callback: (payload: any) => void): string { diff --git a/src/common/Utils.ts b/src/common/Utils.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/components/Cell/Cell.css b/src/components/Cell/Cell.css deleted file mode 100644 index 6144889..0000000 --- a/src/components/Cell/Cell.css +++ /dev/null @@ -1,46 +0,0 @@ -@import "../../_variables.css"; - -.Cell { - /* */ -} - -.pre, .pre-alt, .obj-container { - overflow: hidden; - font-family: monospace; - max-width: 150px; - background: #eee; - margin: 4px 3px; - border: 1px solid #aaa; - padding: 4px; -} - -.pre { - overflow-x: auto; - width: 100%; -} - -.pre-alt { - display: inline-block; - vertical-align: top; - width: unset; -} - -.popover { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; -} - -.array { - background: #ffb; -} - -.any { - background: #f1d7ea; -} - -.string { - background: #dfa -} diff --git a/src/components/Cell/Cell.css.d.ts b/src/components/Cell/Cell.css.d.ts deleted file mode 100644 index 9ebf515..0000000 --- a/src/components/Cell/Cell.css.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -export const Cell: string; -export const cell: string; -export const pre: string; -export const preAlt: string; -export const objContainer: string; -export const popover: string; -export const array: string; -export const any: string; -export const string: string; diff --git a/src/components/Cell/Cell.module.d.ts b/src/components/Cell/Cell.module.d.ts deleted file mode 100644 index 27c725f..0000000 --- a/src/components/Cell/Cell.module.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -export interface IProps { - data: any - depth?: number - className?: string -} - -export interface IState { - tableData: any - depth: number - dataVisible: boolean -} diff --git a/src/components/Cell/Cell.tsx b/src/components/Cell/Cell.tsx deleted file mode 100644 index 7e5974c..0000000 --- a/src/components/Cell/Cell.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import * as React from 'react' -import * as css from './Cell.css' -import * as I from './Cell.module' -import DataTable from 'components/DataTable/DataTable' -import * as Repr from './Repr' - -const MAX_DEPTH = 5 - -class Cell extends React.Component { - constructor(props: I.IProps) { - super(props) - this.state = { - tableData: props.data, - dataVisible: false, - depth: props.depth || 0, - } - } - - private isRepresentable(obj?: any) { - return ( - !obj || - obj.constructor === String || - obj.constructor === Boolean || - typeof obj === 'undefined' || - typeof obj === 'boolean' || - typeof obj === 'number' - ) - } - - private expandData() { - this.setState({ dataVisible: true }) - } - - private parse() { - const obj = this.props.data - const className = this.props.className || '' - - if (this.state.depth >= MAX_DEPTH) { - return ( - - ) - } - - if (this.isRepresentable(obj)) { - return ( - - {obj} - - ) - } - - if (obj.constructor === Array && (!obj.length || obj[0].constructor === {}.constructor)) { - const items = obj.slice(0, 3) - - return ( - - {items.map((item, i) => ( - - ))} - - ) - } - - const keys = Object.keys(obj) - - return keys.length ? ( - this.expandData()}> - {keys.map((s, i) => ( - - {s}: {JSON.stringify(obj[s])} - - ))} - - ) : ( - - ) - } - - render() { - const classNames = [ - css.Cell, - ].join(' ') - - return ( -
- {this.parse()} - {this.state.dataVisible ? ( -
- {/* */} -
- ) : ''} -
- ) - } -} - -export default Cell diff --git a/src/components/Cell/Repr.tsx b/src/components/Cell/Repr.tsx deleted file mode 100644 index 5f46181..0000000 --- a/src/components/Cell/Repr.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import * as React from 'react' -import * as css from './Cell.css' - -interface ReprProps { - className?: string - preClassName?: string - children?: any - [prop: string]: any -} - -interface AnyProps { - title?: string -} - -export function Any({children, className, preClassName, title, ...props}: ReprProps & AnyProps) { - return ( -
- {title ? : ''} -
- {children} -
-
- ) -} - -function _JSON({children, className, preClassName, title, ...props}: ReprProps & AnyProps) { - if (!children || children.constructor !== Array) { - children = [children] - } - - return ( -
- {title ? : ''} - {children.map((child, i) => { - let str = JSON.stringify(child, null, '\t').split(`\\`).join('') - const maxLen = 400 - - if (str.length > maxLen) { - str = str.slice(0, maxLen) + '\u2026' - } - - return ( -
- {str} -
- ) - })} -
- ) -} - -export { _JSON as JSON } diff --git a/src/components/DataTable/DataTable.css b/src/components/DataTable/DataTable.css deleted file mode 100644 index 36aeaee..0000000 --- a/src/components/DataTable/DataTable.css +++ /dev/null @@ -1,80 +0,0 @@ -@import "../../_variables.css"; - -.DataTable { - width: 100%; - padding: 5px; - border-spacing: 2px; - border-collapse: separate; - - & thead th { - background: #acf; - padding: 4px; - } - - & tbody td { - padding: 4px; - padding-right: 8px; - } - - & tr:nth-child(even) td { - background: #eee; - - &.col-id { - background: #ddd; - } - } - - & tbody tr:not(:last-child) td, & thead th { - border-bottom: 1px solid #aaa; - } - - & tbody td, & thead th { - vertical-align: top; - - & label { - display: block; - text-transform: uppercase; - color: #555; - margin-bottom: 5px; - font-weight: bold; - font-size: 0.95em; - font-family: $font-family; - } - } -} - -.col-unknown { - min-width: 80px; -} - -.col-name { - color: $text-main; - text-decoration: none; - display: inline-block; - margin-bottom: 5px; - - &:hover { - text-decoration: underline; - } - - &.sorting-by { - font-weight: bold; - } -} - -.filter-input { - width: 100%; - border: 1px solid #ccc; - min-width: 80px; - padding: 7px 4px; -} - -.sort-caret { - vertical-align: middle; - font-size: 1.3em; -} - -.col-id { - min-width: 60px; - background: #eee; -} diff --git a/src/components/DataTable/DataTable.css.d.ts b/src/components/DataTable/DataTable.css.d.ts deleted file mode 100644 index b2aa7bc..0000000 --- a/src/components/DataTable/DataTable.css.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -export const DataTable: string; -export const dataTable: string; -export const colId: string; -export const colUnknown: string; -export const colName: string; -export const sortingBy: string; -export const filterInput: string; -export const sortCaret: string; diff --git a/src/components/DataTable/DataTable.module.d.ts b/src/components/DataTable/DataTable.module.d.ts deleted file mode 100644 index 4a0839c..0000000 --- a/src/components/DataTable/DataTable.module.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -export interface Props { - store: any - className?: string - static?: boolean - data?: any[] -} - -export interface Filters { - [key: string]: string | undefined -} - -export type FilterFunc = (a: any, b: any) => boolean - -export interface State { - columns: string[] - data: any[] - filters: Filters - sortKey: string - sortDesc: boolean -} diff --git a/src/components/DataTable/DataTable.tsx b/src/components/DataTable/DataTable.tsx deleted file mode 100644 index edbdd51..0000000 --- a/src/components/DataTable/DataTable.tsx +++ /dev/null @@ -1,216 +0,0 @@ -import * as React from 'react' -import * as I from './DataTable.module' -import * as css from './DataTable.css' -import Dispatcher, { register, dispatch, ActionTypes, StoreKeys } from 'common/Dispatcher' -import Cell from 'components/Cell/Cell' - -class DataTable extends React.Component { - private columns: string[] - private listeners: string[] - private filterFuncs: { [open: string]: I.FilterFunc } = { - '>': (a, b) => parseFloat(a) > parseFloat(b), - '>=': (a, b) => parseFloat(a) >= parseFloat(b), - '<': (a, b) => parseFloat(a) < parseFloat(b), - '<=': (a, b) => parseFloat(a) <= parseFloat(b), - '=': (a, b) => JSON.stringify(a) === JSON.stringify(b), - - // default: contains - '_': (a, b) => String(a).toLowerCase().indexOf(String(b).toLowerCase()) > -1 - } - - constructor(props: I.Props) { - super(props) - - const columns = props.store.get(StoreKeys.Columns, []) - - this.state = { - columns, - data: props.data || props.store.get(StoreKeys.Table, []), - filters: {}, - sortKey: columns[0], - sortDesc: false - } - } - - public componentWillMount() { - if (this.props.static) { - return - } - - this.listeners = [ - register(ActionTypes.UPDATE_COLUMNS, (columns: any) => { - let { sortKey } = this.state - if (columns.indexOf(sortKey) === -1) { - sortKey = columns[0] - } - - this.setState({ - columns: columns || [], - sortKey, - }) - }), - - register(ActionTypes.UPDATE_TABLE, (table: any) => { - this.setState({ - data: this.parseData(table || []) - }) - }) - ] - } - - public componentWillUnmount() { - if (this.props.static) { - return - } - - this.listeners.forEach(l => Dispatcher.unregister(l)) - } - - private updateData(data: any) { - const parsed = this.parseData(data.data) - this.setState({ - data: parsed, - columns: data.columns - }) - } - - private parseData(data: any) { - let parsed = data - - if (!parsed) { - return [] - } - - parsed = parsed.map((row: any, i: number) => { - row._id = row._id || row.id || i - return row - }) - - return parsed - } - - private getColumnRowData(row: any, i: number) { - return this.state.columns.map((col, j) => { - const s = (css as any) - const camelCase = col - .replace(/([^a-z]+[a-z0-9])/i, ($1) => $1.toUpperCase()) - .replace(/[^a-z]/i, '') - - const asClsName = camelCase[0].toUpperCase() + camelCase.slice(1) - - const cls = [ - s.hasOwnProperty('col' + asClsName) ? s['col' + asClsName] : css.colUnknown, - ['col', j].join('-'), - ['col', col].join('-') - ].join(' ') - - return ( - - - - ) - }) - } - - private setFilter(key: string, value: string) { - this.setState((cur: I.State) => { - const filters = cur.filters - filters[key] = value - return { filters } - }) - } - - private filterAndSortData() { - let { data, filters } = this.state - - for (const key in filters) { - if (filters.hasOwnProperty(key) && filters[key] && filters[key]!.length) { - data = data.filter((value: any) => { - return this.compareFilter(value[key], filters[key]!) - }) - - if (data.length === 0) { - break - } - } - } - - const skey = this.state.sortKey - const cmp = (a, b) => a > b ? 1 : a === b ? 0 : -1 - const sort = (a, b) => !skey ? 1 : this.state.sortDesc ? cmp(b[skey], a[skey]) : cmp(a[skey], b[skey]) - data = data.sort(sort) - - return data - } - - private sortBy(key: string) { - const { sortKey, sortDesc } = this.state - const desc = sortKey === key && !sortDesc - this.setState({ sortKey: key, sortDesc: desc }) - } - - private compareFilter(itemValue: any, filterStr: string) { - const [ filterOper, filterValue ] = filterStr.split(/\b/).map(s => String(s).trim()) - const filterKey = this.filterFuncs.hasOwnProperty(filterOper) ? filterOper : '_' // default: contains - return this.filterFuncs[filterOper](itemValue, filterValue) - } - - public render() { - return ( -
- - - - {this.state.columns.map(col => { - const anchorCls = [ - css.colName, - this.state.sortKey === col ? css.sortingBy : '' - ].join(' ') - - const caretCls = [ - css.sortCaret, - 'material-icons' - ].join(' ') - - return ( - - ) - })} - - - - {this.filterAndSortData().map((row, i) => ( - - {this.getColumnRowData(row, i)} - - ))} - -
- { e.preventDefault(); this.sortBy(col) }} - className={anchorCls}> - {col} - - {this.state.sortKey === col && this.state.sortDesc ? - 'keyboard_arrow_down' : 'keyboard_arrow_up'} - - -
- { - const { value } = e.target - this.setFilter(col, value) - }} - /> -
-
-
- ) - } -} - -export default DataTable diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index d2e2e84..75ce428 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -105,11 +105,18 @@ class Header extends React.Component { } private get requestPayload() { - if (!this.state.requestType || !this.requestTypeMap.hasOwnProperty(this.state.requestType)) { + if (!this.state.requestType + || !this.requestTypeMap.hasOwnProperty(this.state.requestType) + || !this.state.requestPayload.length) { return undefined } - return this.requestTypeMap[this.state.requestType](this.state.requestPayload) + try { + return this.requestTypeMap[this.state.requestType](this.state.requestPayload) + } catch (e) { + console.error(e) + return "Can't parse response" + } } private getDataColumns(data?: any) { diff --git a/src/components/KeyList/KeyList.tsx b/src/components/KeyList/KeyList.tsx index b611c47..afd2410 100644 --- a/src/components/KeyList/KeyList.tsx +++ b/src/components/KeyList/KeyList.tsx @@ -21,16 +21,16 @@ class KeyList extends React.Component { public componentWillMount() { this.listeners = [ register(ActionTypes.UPDATE_RESPONSE, (data: any) => { + const viewKey = this.props.store.get(StoreKeys.ViewKey, '') + this.setState({ keyList: this.keyListFromObject(data || {}), - viewKey: this.getViewKey(data || {}), + viewKey, }) }), register(ActionTypes.UPDATE_VIEWKEY, (data: any) => { - this.setState({ - viewKey: data - }) + this.setState({ viewKey: data }) }) ] } @@ -43,54 +43,21 @@ class KeyList extends React.Component { return [''].concat(Object.keys(data)) } - private getViewKey(data: any) { - let viewKey = this.state.viewKey - - if (viewKey && data.hasOwnProperty(viewKey)) { - return viewKey - } - - for (const k in data) { - if (data.hasOwnProperty(k) && data[k] && data[k].constructor === Array) { - return k - } - } - - return '' - } - private selectItem(key: string) { - const body = this.props.store.get(StoreKeys.Response, {}) - const tableData = key !== '' ? body[key] : [body] - this.setState({ viewKey: key }, () => { dispatch(ActionTypes.UPDATE_VIEWKEY, key) - dispatch(ActionTypes.UPDATE_TABLE, tableData) - dispatch(ActionTypes.UPDATE_COLUMNS, this.columnListFromRow(tableData && tableData.length ? tableData[0] : [])) }) } - private columnListFromRow(row: any) { - const keys = ['_id'] - - Object.keys(row).sort().forEach(k => { - k = k.toLowerCase() - if (k !== '_id' && k !== 'id') { - keys.push(k) - } - }) - - return keys - } - private get keyListElements() { const fullData = this.props.store.get(StoreKeys.Response, {}) + const viewKey = this.state.viewKey return this.state.keyList.map((key: string) => { const className = [ css.item, key === '' || (fullData[key] && fullData[key].constructor === Array) ? css.valid : '', - this.state.viewKey === key ? css.selected : '' + viewKey === key ? css.selected : '' ].join(' ') return ( diff --git a/src/components/RObject/RObject.css b/src/components/RObject/RObject.css index 83f4eba..ad1dfdb 100644 --- a/src/components/RObject/RObject.css +++ b/src/components/RObject/RObject.css @@ -10,6 +10,7 @@ vertical-align: top; border: 1px solid #ccc; border-radius: 4px; + min-width: 120px; & > h3 { font-size: 0.8rem; diff --git a/src/components/RObject/RObject.module.d.ts b/src/components/RObject/RObject.module.d.ts index 24fdb91..9e5538a 100644 --- a/src/components/RObject/RObject.module.d.ts +++ b/src/components/RObject/RObject.module.d.ts @@ -1,5 +1,7 @@ +export type ClassNameFunc = (index?: number, item?: string) => string + export interface IProps { - className?: string + className?: string | ClassNameFunc data: any } diff --git a/src/components/RObject/RObject.tsx b/src/components/RObject/RObject.tsx index 5c68841..4f0db67 100644 --- a/src/components/RObject/RObject.tsx +++ b/src/components/RObject/RObject.tsx @@ -8,7 +8,8 @@ class RObject extends React.Component { this.state = {} } - private getCorrectRepr(obj: any, cls?: string) { + private getCorrectRepr(obj: any) { + let cls = this.props.className try { switch (typeof obj) { case 'number': @@ -19,12 +20,20 @@ class RObject extends React.Component { const isArray = obj && obj.constructor === Array if (!keys.length) { - return {JSON.stringify(obj)} + if (typeof cls === 'function') { + cls = cls() + } + return {JSON.stringify(obj)} } - return keys.map((k: string) => { + return keys.map((k: string, i: number) => { + let tempCls = cls + if (typeof tempCls === 'function') { + tempCls = tempCls(i, k) + } + tempCls += ' ' + css.RObject return ( -
+

{!isArray ? k : typeof obj}

@@ -36,13 +45,8 @@ class RObject extends React.Component { } } - render() { - const classNames = [ - css.RObject, - this.props.className - ].join(' ') - - const repr = this.getCorrectRepr(this.props.data, classNames) + render() { + const repr = this.getCorrectRepr(this.props.data) return repr } } diff --git a/src/components/ResponseRepr/ResponseRepr.css b/src/components/ResponseRepr/ResponseRepr.css index a8a82ec..692d9a3 100644 --- a/src/components/ResponseRepr/ResponseRepr.css +++ b/src/components/ResponseRepr/ResponseRepr.css @@ -4,6 +4,36 @@ /* */ } -.obj { - // max-width: 11vw; +.table { + display: grid; + grid-row-gap: 8px; + padding: 10px; + + & h3 { + font-weight: bold; + text-transform: uppercase; + color: $text-light; + font-size: 0.9em; + } +} + +.cell { + width: 100%; + margin: 0 !important; + border-left-width: 0px !important; + border-radius: 0 !important; + + &.row-start { + border-radius: 5px 0 0 5px !important; + border-left-width: 1px !important; + margin-left: 0 !important; + } + + &.row-end { + border-radius: 0 5px 5px 0 !important; + } + + & > h3 { + display: none; + } } diff --git a/src/components/ResponseRepr/ResponseRepr.css.d.ts b/src/components/ResponseRepr/ResponseRepr.css.d.ts index ce2713f..556d951 100644 --- a/src/components/ResponseRepr/ResponseRepr.css.d.ts +++ b/src/components/ResponseRepr/ResponseRepr.css.d.ts @@ -1,3 +1,6 @@ export const ResponseRepr: string; export const responseRepr: string; -export const obj: string; +export const table: string; +export const cell: string; +export const rowStart: string; +export const rowEnd: string; diff --git a/src/components/ResponseRepr/ResponseRepr.tsx b/src/components/ResponseRepr/ResponseRepr.tsx index 6278741..a119a0c 100644 --- a/src/components/ResponseRepr/ResponseRepr.tsx +++ b/src/components/ResponseRepr/ResponseRepr.tsx @@ -3,6 +3,7 @@ import * as css from './ResponseRepr.css' import * as I from './ResponseRepr.module' import * as D from 'common/Dispatcher' import RObject from 'components/RObject/RObject' +import * as classNames from 'classnames' class ResponseRepr extends React.Component { private listeners: string[] @@ -16,6 +17,10 @@ class ResponseRepr extends React.Component { componentDidMount() { this.listeners = [ D.register(D.ActionTypes.UPDATE_RESPONSE, (response) => { + const viewKey = this.props.store.get(D.StoreKeys.ViewKey) + if (viewKey && Object.keys(response).indexOf(viewKey) > -1) { + response = response[viewKey] + } this.setState({ response }) }), @@ -33,19 +38,45 @@ class ResponseRepr extends React.Component { private getRObjectList() { const { response } = this.state + let colAmt + if (response && response.constructor === Array) { - return response.map((row, i) => { - return () - }) + const keys = Object.keys(response[0] || {}) + colAmt = keys.length + return ( +
+ {keys.map((key) =>

{key}

)} + {response.map((row, i) => { + const cls = (j) => { + return classNames(css.cell, { + [css.rowStart]: j % colAmt === 0, + [css.rowEnd]: j % colAmt === colAmt - 1, + }) + } + + return ( + + ) + })} +
+ ) } + colAmt = Object.keys(response || {}) + return ( - +
+ +
) } render() { - const classNames = [ + const className = [ css.ResponseRepr, this.props.className ].join(' ') @@ -53,7 +84,7 @@ class ResponseRepr extends React.Component { const repr = this.getRObjectList() return ( -
+
{repr}
) diff --git a/src/layouts/App/App.css b/src/layouts/App/App.css index a69b846..34563b5 100644 --- a/src/layouts/App/App.css +++ b/src/layouts/App/App.css @@ -13,16 +13,18 @@ width: 100%; height: 100%; overflow: auto; - display: grid; - grid-template-columns: [sidebar] 20vw [main] 80vw; + display: flex; } .key-list { - grid-column: sidebar; + flex-shrink: 1; + flex-grow: 0; + min-width: 200px; + max-width: 15vw; } .table { - grid-column: main; + flex-grow: 1; } .scrollable { diff --git a/tslint.json b/tslint.json index 1404493..81e151a 100644 --- a/tslint.json +++ b/tslint.json @@ -47,7 +47,7 @@ "check-open-brace", "check-whitespace" ], - "quotemark": [true, "single", "jsx-double"], + "quotemark": [true, "single", "jsx-double", "avoid-escape"], "radix": true, "semicolon": [true, "never"], "switch-default": true, diff --git a/yarn.lock b/yarn.lock index ccc592e..c43e8cb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8,6 +8,10 @@ dependencies: "@types/filesystem" "*" +"@types/classnames@^2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.3.tgz#3f0ff6873da793870e20a260cada55982f38a9e5" + "@types/events@*": version "1.1.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-1.1.0.tgz#93b1be91f63c184450385272c47b6496fd028e02" @@ -910,6 +914,10 @@ clap@^1.0.9: dependencies: chalk "^1.1.3" +classnames@^2.2.5: + version "2.2.5" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d" + clean-css@4.1.x: version "4.1.9" resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.1.9.tgz#35cee8ae7687a49b98034f70de00c4edd3826301"