| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- import React, { useEffect, useState, useCallback } from 'react';
- import { useTranslation } from 'next-i18next';
- import { toastSuccess, toastError } from '~/client/util/apiNotification';
- import { apiv3Get, apiv3Post, apiv3Put } from '~/client/util/apiv3-client';
- import { SocketEventName } from '~/interfaces/websocket';
- import { useIsSearchServiceReachable } from '~/stores/context';
- import { useAdminSocket } from '~/stores/socket-io';
- import NormalizeIndicesControls from './NormalizeIndicesControls';
- import RebuildIndexControls from './RebuildIndexControls';
- import ReconnectControls from './ReconnectControls';
- import StatusTable from './StatusTable';
- const ElasticsearchManagement = () => {
- const { t } = useTranslation('admin');
- const { data: isSearchServiceReachable } = useIsSearchServiceReachable();
- const { data: socket } = useAdminSocket();
- const [isInitialized, setIsInitialized] = useState(false);
- const [isConnected, setIsConnected] = useState(false);
- const [isConfigured, setIsConfigured] = useState(false);
- const [isReconnectingProcessing, setIsReconnectingProcessing] = useState(false);
- const [isRebuildingProcessing, setIsRebuildingProcessing] = useState(false);
- const [isRebuildingCompleted, setIsRebuildingCompleted] = useState(false);
- const [isNormalized, setIsNormalized] = useState(false);
- const [indicesData, setIndicesData] = useState(null);
- const [aliasesData, setAliasesData] = useState(null);
- const retrieveIndicesStatus = useCallback(async() => {
- try {
- const { data } = await apiv3Get('/search/indices');
- const { info } = data;
- setIsConnected(true);
- setIsConfigured(true);
- setIndicesData(info.indices);
- setAliasesData(info.aliases);
- setIsNormalized(info.isNormalized);
- }
- catch (errors: unknown) {
- setIsConnected(false);
- // evaluate whether configured or not
- if (Array.isArray(errors)) {
- for (const error of errors) {
- if (error.code === 'search-service-unconfigured') {
- setIsConfigured(false);
- }
- }
- }
- toastError(errors);
- }
- finally {
- setIsInitialized(true);
- }
- }, []);
- useEffect(() => {
- const fetchIndicesStatusData = async() => {
- await retrieveIndicesStatus();
- };
- fetchIndicesStatusData();
- }, [retrieveIndicesStatus]);
- useEffect(() => {
- if (socket == null) {
- return;
- }
- socket.on(SocketEventName.AddPageProgress, (data) => {
- setIsRebuildingProcessing(true);
- });
- socket.on(SocketEventName.FinishAddPage, async(data) => {
- await retrieveIndicesStatus();
- setIsRebuildingProcessing(false);
- setIsRebuildingCompleted(true);
- });
- socket.on(SocketEventName.RebuildingFailed, (data) => {
- toastError(new Error(data.error), 'Rebuilding Index has failed.');
- });
- return () => {
- socket.off(SocketEventName.AddPageProgress);
- socket.off(SocketEventName.FinishAddPage);
- socket.off(SocketEventName.RebuildingFailed);
- };
- }, [socket]);
- const reconnect = async() => {
- setIsReconnectingProcessing(true);
- try {
- await apiv3Post('/search/connection');
- }
- catch (e) {
- toastError(e);
- return;
- }
- // reload
- window.location.reload();
- };
- const normalizeIndices = async() => {
- try {
- await apiv3Put('/search/indices', { operation: 'normalize' });
- }
- catch (e) {
- toastError(e);
- }
- await retrieveIndicesStatus();
- toastSuccess('Normalizing has succeeded');
- };
- const rebuildIndices = async() => {
- setIsRebuildingProcessing(true);
- try {
- await apiv3Put('/search/indices', { operation: 'rebuild' });
- toastSuccess('Rebuilding is requested');
- }
- catch (e) {
- toastError(e);
- }
- await retrieveIndicesStatus();
- };
- const isErrorOccuredOnSearchService = !isSearchServiceReachable;
- const isReconnectBtnEnabled = !isReconnectingProcessing && (!isInitialized || !isConnected || isErrorOccuredOnSearchService);
- return (
- <>
- <div className="row">
- <div className="col-md-12">
- <StatusTable
- isInitialized={isInitialized}
- isErrorOccuredOnSearchService={isErrorOccuredOnSearchService}
- isConnected={isConnected}
- isConfigured={isConfigured}
- isNormalized={isNormalized}
- indicesData={indicesData}
- aliasesData={aliasesData}
- />
- </div>
- </div>
- <hr />
- {/* Controls */}
- <div className="row">
- <label className="col-md-3 col-form-label text-left text-md-right">{ t('full_text_search_management.reconnect') }</label>
- <div className="col-md-6">
- <ReconnectControls
- isEnabled={isReconnectBtnEnabled}
- isProcessing={isReconnectingProcessing}
- onReconnectingRequested={reconnect}
- />
- </div>
- </div>
- <hr />
- <div className="row">
- <label className="col-md-3 col-form-label text-left text-md-right">{ t('full_text_search_management.normalize') }</label>
- <div className="col-md-6">
- <NormalizeIndicesControls
- isRebuildingProcessing={isRebuildingProcessing}
- isNormalized={isNormalized}
- onNormalizingRequested={normalizeIndices}
- />
- </div>
- </div>
- <hr />
- <div className="row">
- <label className="col-md-3 col-form-label text-left text-md-right">{ t('full_text_search_management.rebuild') }</label>
- <div className="col-md-6">
- <RebuildIndexControls
- isRebuildingProcessing={isRebuildingProcessing}
- isRebuildingCompleted={isRebuildingCompleted}
- isNormalized={isNormalized}
- onRebuildingRequested={rebuildIndices}
- />
- </div>
- </div>
- </>
- );
- };
- ElasticsearchManagement.propTypes = {
- };
- export default ElasticsearchManagement;
|