リモート監視ソリューション アクセラレータの Web UI にカスタム ポップアップを追加する
この記事では、リモート監視ソリューション アクセラレータの Web UI のページに新しいポップアップを追加する方法を示します。 この記事では、次の内容について説明します。
- ローカルの開発環境を準備する方法。
- Web UI のページに新しいポップアップを追加する方法。
この記事で使用するポップアップの例では、「Add a custom grid to the Remote Monitoring solution accelerator web UI」(リモート監視ソリューション アクセラレータの Web UI にカスタム グリッドを追加する) ハウツー記事で追加方法が示されているグリッドがページに表示されます。
前提条件
このハウツー ガイドの手順を最後まで行うには、ローカル開発マシンに次のソフトウェアがインストールされている必要があります。
開始する前に
続ける前に、次の記事の手順を完了しておく必要があります。
- リモート監視ソリューション アクセラレータ Web UI にカスタム ページを追加します。
- リモート監視ソリューション アクセラレータの Web UI にカスタム サービスを追加する
- リモート監視ソリューション アクセラレータの Web UI にカスタム グリッドを追加する
ポップアップの追加
Web UI にポップアップを追加するには、ポップアップが定義されているソース ファイルを追加し、既存のファイルをいくつか変更して、Web UI で新しいコンポーネントが認識されるようにする必要があります。
ポップアップが定義されている新しいファイルを追加する
作業を始められるよう、src/walkthrough/components/pages/pageWithFlyout/flyouts/exampleFlyout フォルダーにポップアップを定義したファイルが格納されています。
exampleFlyout.container.js
import { withNamespaces } from 'react-i18next';
import { ExampleFlyout } from './exampleFlyout';
export const ExampleFlyoutContainer = withNamespaces()(ExampleFlyout);
exampleFlyout.js
import React, { Component } from 'react';
import { ExampleService } from 'walkthrough/services';
import { svgs } from 'utilities';
import {
AjaxError,
Btn,
BtnToolbar,
Flyout,
Indicator,
SectionDesc,
SectionHeader,
SummaryBody,
SummaryCount,
SummarySection,
Svg
} from 'components/shared';
import './exampleFlyout.scss';
export class ExampleFlyout extends Component {
constructor(props) {
super(props);
this.state = {
itemCount: 3, //just a fake count; this would often be a list of items that are being acted on
isPending: false,
error: undefined,
successCount: 0,
changesApplied: false
};
}
componentWillUnmount() {
if (this.subscription) this.subscription.unsubscribe();
}
apply = (event) => {
event.preventDefault();
this.setState({ isPending: true, successCount: 0, error: null });
this.subscription = ExampleService.updateExampleItems()
.subscribe(
_ => {
this.setState({ successCount: this.state.successCount + this.state.itemCount });
// Update any global state in the redux store by calling any
// dispatch methods that were mapped in this flyout's container.
},
error => this.setState({ error, isPending: false, changesApplied: true }),
() => this.setState({ isPending: false, changesApplied: true, confirmStatus: false })
);
}
getSummaryMessage() {
const { t } = this.props;
const { isPending, changesApplied } = this.state;
if (isPending) {
return t('walkthrough.pageWithFlyout.flyouts.example.pending');
} else if (changesApplied) {
return t('walkthrough.pageWithFlyout.flyouts.example.applySuccess');
} else {
return t('walkthrough.pageWithFlyout.flyouts.example.affected');
}
}
render() {
const { t, onClose } = this.props;
const {
itemCount,
isPending,
error,
successCount,
changesApplied
} = this.state;
const summaryCount = changesApplied ? successCount : itemCount;
const completedSuccessfully = changesApplied && !error;
const summaryMessage = this.getSummaryMessage();
return (
<Flyout header={t('walkthrough.pageWithFlyout.flyouts.example.header')} t={t} onClose={onClose}>
{
/**
* Really, anything you need could go inside a flyout.
* The following is a simple empty form with buttons to do an action or close the flyout.
* */
}
<form className="example-flyout-container" onSubmit={this.apply}>
<div className="example-flyout-header">{t('walkthrough.pageWithFlyout.flyouts.example.header')}</div>
<div className="example-flyout-descr">{t('walkthrough.pageWithFlyout.flyouts.example.description')}</div>
<div className="form-placeholder">{t('walkthrough.pageWithFlyout.flyouts.example.insertFormHere')}</div>
{/** Sumarizes the action being taken; including count of items affected & status/pending indicator */}
<SummarySection>
<SectionHeader>{t('walkthrough.pageWithFlyout.flyouts.example.summaryHeader')}</SectionHeader>
<SummaryBody>
<SummaryCount>{summaryCount}</SummaryCount>
<SectionDesc>{summaryMessage}</SectionDesc>
{this.state.isPending && <Indicator />}
{completedSuccessfully && <Svg className="summary-icon" path={svgs.apply} />}
</SummaryBody>
</SummarySection>
{/** Displays an error message if one occurs while applying changes. */}
{error && <AjaxError className="example-flyout-error" t={t} error={error} />}
{
/** If changes are not yet applied, show the buttons for applying changes and closing the flyout. */
!changesApplied &&
<BtnToolbar>
<Btn svg={svgs.reconfigure} primary={true} disabled={isPending || itemCount === 0 } type="submit">{t('walkthrough.pageWithFlyout.flyouts.example.apply')}</Btn>
<Btn svg={svgs.cancelX} onClick={onClose}>{t('walkthrough.pageWithFlyout.flyouts.example.cancel')}</Btn>
</BtnToolbar>
}
{
/**
* If changes are applied, show only the close button.
* Other text or component might be included here as well.
* For example, you might provide a link to the detail page for a newly submitted job.
* */
!!changesApplied &&
<BtnToolbar>
<Btn svg={svgs.cancelX} onClick={onClose}>{t('walkthrough.pageWithFlyout.flyouts.example.close')}</Btn>
</BtnToolbar>
}
</form>
</Flyout>
);
}
}
src/walkthrough/components/pages/pageWithFlyout/flyouts フォルダーを src/components/pages/example フォルダーにコピーします。
ポップアップをページに追加する
ポップアップを追加するには、src/components/pages/example/basicPage.js を変更します。
components/shared からのインポートに Btn を追加し、svgs と ExampleFlyoutContainer のインポートを追加します。
import {
AjaxError,
ContextMenu,
PageContent,
RefreshBar,
Btn
} from 'components/shared';
import { ExampleGrid } from './exampleGrid';
import { svgs } from 'utilities';
import { ExampleFlyoutContainer } from './flyouts/exampleFlyout';
closedFlyoutState の const 定義を追加し、それをコンストラクターの state に追加します。
const closedFlyoutState = { openFlyoutName: undefined };
export class BasicPage extends Component {
constructor(props) {
super(props);
this.state = { contextBtns: null, closedFlyoutState };
}
BasicPage クラスに、次の関数を追加します。
closeFlyout = () => this.setState(closedFlyoutState);
openFlyout = (name) => () => this.setState({ openFlyoutName: name });
次の const 定義を、render 関数に追加します。
const { openFlyoutName } = this.state;
const isExampleFlyoutOpen = openFlyoutName === 'example';
ポップアップを開くボタンをコンテキスト メニューに追加します。
<ContextMenu key="context-menu">
{this.state.contextBtns}
<Btn svg={svgs.reconfigure} onClick={this.openFlyout('example')}>{t('walkthrough.pageWithFlyout.open')}</Btn>
</ContextMenu>,
いくつかのテキストとポップアップのコンテナーを、ページのコンテンツに追加します。
<PageContent className="basic-page-container" key="page-content">
{t('walkthrough.pageWithFlyout.pageBody')}
{ isExampleFlyoutOpen && <ExampleFlyoutContainer onClose={this.closeFlyout} /> }
<RefreshBar refresh={fetchData} time={lastUpdated} isPending={isPending} t={t} />
{!!error && <AjaxError t={t} error={error} />}
{!error && <ExampleGrid {...gridProps} />}
</PageContent>
ポップアップをテストする
まだ Web UI をローカルに実行していない場合は、リポジトリのローカル コピーのルートで次のコマンドを実行します。
npm start
前のコマンドは、https://localhost:3000/dashboard
のローカルで UI を実行します。
[Example]\(例\) ページに移動して、[Open Flyout]\(ポップアップを開く\) をクリックします。
次の手順
この記事では、リモート監視ソリューション アクセラレータの Web UI のページの追加またはカスタマイズに使用できるリソースについて説明しました。
ページにポップアップを定義したので、次にリモート監視ソリューション アクセラレータ Web UI のダッシュボードにパネルを追加します。
リモート監視ソリューション アクセラレータの概念の詳細については、「 リモート監視アーキテクチャ」を参照してください。