vitess.io/vitess@v0.16.2/web/vtadmin/src/components/routes/Gates.tsx (about)

     1  /**
     2   * Copyright 2021 The Vitess Authors.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  import { orderBy } from 'lodash-es';
    17  import * as React from 'react';
    18  
    19  import { useGates } from '../../hooks/api';
    20  import { useDocumentTitle } from '../../hooks/useDocumentTitle';
    21  import { useSyncedURLParam } from '../../hooks/useSyncedURLParam';
    22  import { filterNouns } from '../../util/filterNouns';
    23  import { DataCell } from '../dataTable/DataCell';
    24  import { DataFilter } from '../dataTable/DataFilter';
    25  import { DataTable } from '../dataTable/DataTable';
    26  import { ContentContainer } from '../layout/ContentContainer';
    27  import { WorkspaceHeader } from '../layout/WorkspaceHeader';
    28  import { WorkspaceTitle } from '../layout/WorkspaceTitle';
    29  import { QueryLoadingPlaceholder } from '../placeholders/QueryLoadingPlaceholder';
    30  
    31  export const Gates = () => {
    32      useDocumentTitle('Gates');
    33  
    34      const gatesQuery = useGates();
    35      const { value: filter, updateValue: updateFilter } = useSyncedURLParam('filter');
    36  
    37      const rows = React.useMemo(() => {
    38          const mapped = (gatesQuery.data || []).map((g) => ({
    39              cell: g.cell,
    40              cluster: g.cluster?.name,
    41              hostname: g.hostname,
    42              keyspaces: g.keyspaces,
    43              pool: g.pool,
    44              fqdn: g.FQDN,
    45          }));
    46          const filtered = filterNouns(filter, mapped);
    47          return orderBy(filtered, ['cluster', 'pool', 'hostname', 'cell']);
    48      }, [gatesQuery.data, filter]);
    49  
    50      const renderRows = (gates: typeof rows) =>
    51          gates.map((gate, idx) => (
    52              <tr key={idx}>
    53                  <DataCell className="whitespace-nowrap">
    54                      <div>{gate.pool}</div>
    55                      <div className="text-sm text-secondary">{gate.cluster}</div>
    56                  </DataCell>
    57                  <DataCell className="whitespace-nowrap">
    58                      {gate.fqdn ? (
    59                          <div className="font-bold">
    60                              <a href={`//${gate.fqdn}`} rel="noopener noreferrer" target="_blank">
    61                                  {gate.hostname}
    62                              </a>
    63                          </div>
    64                      ) : (
    65                          gate.hostname
    66                      )}
    67                  </DataCell>
    68                  <DataCell className="whitespace-nowrap">{gate.cell}</DataCell>
    69                  <DataCell>{(gate.keyspaces || []).join(', ')}</DataCell>
    70              </tr>
    71          ));
    72  
    73      return (
    74          <div>
    75              <WorkspaceHeader>
    76                  <WorkspaceTitle>Gates</WorkspaceTitle>
    77              </WorkspaceHeader>
    78              <ContentContainer>
    79                  <DataFilter
    80                      autoFocus
    81                      onChange={(e) => updateFilter(e.target.value)}
    82                      onClear={() => updateFilter('')}
    83                      placeholder="Filter gates"
    84                      value={filter || ''}
    85                  />
    86                  <DataTable columns={['Pool', 'Hostname', 'Cell', 'Keyspaces']} data={rows} renderRows={renderRows} />
    87                  <QueryLoadingPlaceholder query={gatesQuery} />
    88              </ContentContainer>
    89          </div>
    90      );
    91  };