diff --git a/web/vtadmin/src/components/routes/Gates.module.scss b/web/vtadmin/src/components/routes/Gates.module.scss new file mode 100644 index 00000000000..c6cd7194d4b --- /dev/null +++ b/web/vtadmin/src/components/routes/Gates.module.scss @@ -0,0 +1,21 @@ +/** + * Copyright 2021 The Vitess Authors. + * + * Licensed 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. + */ +.controls { + display: grid; + grid-gap: 8px; + grid-template-columns: 1fr min-content; + margin-bottom: 24px; +} diff --git a/web/vtadmin/src/components/routes/Gates.tsx b/web/vtadmin/src/components/routes/Gates.tsx index b60aa8347fe..cb34a5d859d 100644 --- a/web/vtadmin/src/components/routes/Gates.tsx +++ b/web/vtadmin/src/components/routes/Gates.tsx @@ -15,32 +15,65 @@ */ import { orderBy } from 'lodash-es'; import * as React from 'react'; + import { useGates } from '../../hooks/api'; import { useDocumentTitle } from '../../hooks/useDocumentTitle'; -import { vtadmin as pb } from '../../proto/vtadmin'; +import { useSyncedURLParam } from '../../hooks/useSyncedURLParam'; +import { filterNouns } from '../../util/filterNouns'; +import { Button } from '../Button'; import { DataCell } from '../dataTable/DataCell'; import { DataTable } from '../dataTable/DataTable'; +import { Icons } from '../Icon'; +import { TextInput } from '../TextInput'; +import style from './Gates.module.scss'; export const Gates = () => { useDocumentTitle('Gates'); + const { data } = useGates(); + const { value: filter, updateValue: updateFilter } = useSyncedURLParam('filter'); const rows = React.useMemo(() => { - return orderBy(data, ['cluster.name', 'hostname']); - }, [data]); + const mapped = (data || []).map((g) => ({ + cell: g.cell, + cluster: g.cluster?.name, + hostname: g.hostname, + keyspaces: g.keyspaces, + pool: g.pool, + })); + const filtered = filterNouns(filter, mapped); + return orderBy(filtered, ['cluster', 'pool', 'hostname', 'cell']); + }, [data, filter]); - const renderRows = (gates: pb.VTGate[]) => + const renderRows = (gates: typeof rows) => gates.map((gate, idx) => ( - {gate.cluster?.name} - {gate.hostname} + +
{gate.pool}
+
{gate.cluster}
+
+ {gate.hostname} + {gate.cell} + {(gate.keyspaces || []).join(', ')} )); return (

Gates

- +
+ updateFilter(e.target.value)} + placeholder="Filter gates" + value={filter || ''} + /> + +
+
); };