| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- import React from 'react';
- import { useTranslation } from 'next-i18next';
- import PropTypes from 'prop-types';
- class StatusTable extends React.PureComponent {
- renderPreInitializedLabel() {
- return <span className="badge text-bg-default">――</span>;
- }
- renderConnectionStatusLabels() {
- const { t } = this.props;
- const { isErrorOccuredOnSearchService, isConnected, isConfigured } =
- this.props;
- const errorOccuredLabel = isErrorOccuredOnSearchService ? (
- <span className="badge text-bg-danger ms-2">
- {t('full_text_search_management.connection_status_label_erroroccured')}
- </span>
- ) : null;
- let connectionStatusLabel = null;
- if (!isConfigured) {
- connectionStatusLabel = (
- <span className="badge text-bg-default">
- {t(
- 'full_text_search_management.connection_status_label_unconfigured',
- )}
- </span>
- );
- } else {
- connectionStatusLabel = isConnected ? (
- // eslint-disable-next-line max-len
- <span
- data-testid="connection-status-badge-connected"
- className="badge text-bg-success"
- >
- {t('full_text_search_management.connection_status_label_connected')}
- </span>
- ) : (
- <span className="badge text-bg-danger">
- {t(
- 'full_text_search_management.connection_status_label_disconnected',
- )}
- </span>
- );
- }
- return (
- <>
- {connectionStatusLabel}
- {errorOccuredLabel}
- </>
- );
- }
- renderIndicesStatusLabel() {
- const { t, isNormalized } = this.props;
- return isNormalized ? (
- <span className="badge text-bg-info">
- {t('full_text_search_management.indices_status_label_normalized')}
- </span>
- ) : (
- <span className="badge text-bg-warning">
- {t('full_text_search_management.indices_status_label_unnormalized')}
- </span>
- );
- }
- renderIndexInfoPanel(indexName, body = {}, aliases = []) {
- const collapseId = `collapse-${indexName}`;
- const aliasLabels = aliases.map((aliasName) => {
- return (
- <span
- key={`badge-${indexName}-${aliasName}`}
- className="badge text-bg-primary me-2"
- >
- <span className="material-symbols-outlined">sell</span>
- <span>{aliasName}</span>
- </span>
- );
- });
- return (
- <div className="card">
- <div className="card-header">
- <a
- role="button"
- className="text-nowrap me-2"
- data-bs-toggle="collapse"
- href={`#${collapseId}`}
- aria-expanded="true"
- aria-controls={collapseId}
- >
- <span className="material-symbols-outlined">database</span>{' '}
- {indexName}
- </a>
- <span className="ms-md-3">{aliasLabels}</span>
- </div>
- <div id={collapseId} className="collapse">
- <div className="card-body">
- <pre>{JSON.stringify(body, null, 2)}</pre>
- </div>
- </div>
- </div>
- );
- }
- renderIndexInfoPanels() {
- const { indicesData, aliasesData } = this.props;
- // data is null
- if (indicesData == null) {
- return null;
- }
- /*
- "indices": {
- "growi": {
- ...
- }
- },
- */
- const indexNameToDataMap = {};
- for (const [indexName, indexData] of Object.entries(indicesData)) {
- indexNameToDataMap[indexName] = indexData;
- }
- // no indices
- if (indexNameToDataMap.length === 0) {
- return null;
- }
- /*
- "aliases": {
- "growi": {
- "aliases": {
- "growi-alias": {}
- }
- }
- },
- */
- const indexNameToAliasMap = {};
- for (const [indexName, aliasData] of Object.entries(aliasesData)) {
- indexNameToAliasMap[indexName] = Object.keys(aliasData.aliases);
- }
- return (
- <div className="row">
- {Object.keys(indexNameToDataMap).map((indexName) => {
- return (
- <div key={`col-${indexName}`} className="col-md-6">
- {this.renderIndexInfoPanel(
- indexName,
- indexNameToDataMap[indexName],
- indexNameToAliasMap[indexName],
- )}
- </div>
- );
- })}
- </div>
- );
- }
- render() {
- const { t } = this.props;
- const { isInitialized } = this.props;
- return (
- <table className="table table-bordered">
- <tbody>
- <tr>
- <th className="w-25">
- {t('full_text_search_management.connection_status')}
- </th>
- <td className="w-75">
- {isInitialized
- ? this.renderConnectionStatusLabels()
- : this.renderPreInitializedLabel()}
- </td>
- </tr>
- <tr>
- <th className="w-25">
- {t('full_text_search_management.indices_status')}
- </th>
- <td className="w-75">
- {isInitialized
- ? this.renderIndicesStatusLabel()
- : this.renderPreInitializedLabel()}
- </td>
- </tr>
- <tr>
- <th className="w-25">
- {t('full_text_search_management.indices_summary')}
- </th>
- <td className="p-4 w-75">
- {isInitialized && this.renderIndexInfoPanels()}
- </td>
- </tr>
- </tbody>
- </table>
- );
- }
- }
- const StatusTableWrapperFC = (props) => {
- const { t } = useTranslation('admin');
- return <StatusTable t={t} {...props} />;
- };
- StatusTable.propTypes = {
- t: PropTypes.func.isRequired, // i18next
- isInitialized: PropTypes.bool,
- isErrorOccuredOnSearchService: PropTypes.bool,
- isConnected: PropTypes.bool,
- isConfigured: PropTypes.bool,
- isNormalized: PropTypes.bool,
- indicesData: PropTypes.object,
- aliasesData: PropTypes.object,
- };
- export default StatusTableWrapperFC;
|