Dodawanie siatki niestandardowej do internetowego interfejsu użytkownika akceleratora rozwiązania do monitorowania zdalnego
W tym artykule pokazano, jak dodać nową siatkę na stronę w internetowym interfejsie użytkownika akceleratora rozwiązania do monitorowania zdalnego. W tym artykule opisano:
- Jak przygotować lokalne środowisko programistyczne.
- Jak dodać nową siatkę do strony w internetowym interfejsie użytkownika.
Przykładowa siatka w tym artykule zawiera dane z usługi, które zawiera artykuł Dodawanie usługi niestandardowej do internetowego interfejsu użytkownika akceleratora rozwiązania do monitorowania zdalnego , w którym przedstawiono sposób dodawania.
Wymagania wstępne
Aby wykonać kroki opisane w tym przewodniku z instrukcjami, potrzebne jest następujące oprogramowanie zainstalowane na lokalnym komputerze deweloperskim:
Przed rozpoczęciem
Przed kontynuowaniem wykonaj kroki opisane w następujących artykułach:
- Dodaj stronę niestandardową do internetowego interfejsu użytkownika akceleratora rozwiązania do monitorowania zdalnego.
- Dodawanie usługi niestandardowej do internetowego interfejsu użytkownika akceleratora rozwiązania do monitorowania zdalnego
Dodawanie siatki
Aby dodać siatkę do internetowego interfejsu użytkownika, należy dodać pliki źródłowe definiujące siatkę i zmodyfikować niektóre istniejące pliki, aby interfejs użytkownika sieci Web był świadomy nowego składnika.
Dodawanie nowych plików definiujących siatkę
Aby rozpocząć pracę, folder src/walkthrough/components/pages/pageWithGrid/exampleGrid zawiera pliki definiujące siatkę:
exampleGrid.js
import React, { Component } from 'react';
import { Btn, ComponentArray, PcsGrid } from 'components/shared';
import { exampleColumnDefs, defaultExampleGridProps } from './exampleGridConfig';
import { isFunc, svgs, translateColumnDefs } from 'utilities';
import { checkboxColumn } from 'components/shared/pcsGrid/pcsGridConfig';
const initialState = {
softSelectedId: undefined
};
/**
* A grid for displaying example data
*
* Encapsulates the PcsGrid props
*/
export class ExampleGrid extends Component {
constructor(props) {
super(props);
// Set the initial state
this.state = initialState;
// Default device grid columns
this.columnDefs = [
checkboxColumn,
exampleColumnDefs.id,
exampleColumnDefs.description
];
// Set up the available context buttons.
// If these are subject to user permissions, use the Protected component (src/components/shared/protected).
this.contextBtns =
<ComponentArray>
<Btn svg={svgs.reconfigure} onClick={this.clickContextBtn('btn1')}>{props.t('walkthrough.pageWithGrid.grid.btn1')}</Btn>
<Btn svg={svgs.trash} onClick={this.clickContextBtn('btn2')}>{props.t('walkthrough.pageWithGrid.grid.btn2')}</Btn>
</ComponentArray>;
}
/**
* Get the grid api options
*
* @param {Object} gridReadyEvent An object containing access to the grid APIs
*/
onGridReady = gridReadyEvent => {
this.gridApi = gridReadyEvent.api;
// Call the onReady props if it exists
if (isFunc(this.props.onGridReady)) {
this.props.onGridReady(gridReadyEvent);
}
};
clickContextBtn = (input) => () => {
//Just for demo purposes. Don't console log in a real grid.
console.log('Context button clicked', input);
console.log('Hard selected rows', this.gridApi.getSelectedRows());
};
/**
* Handles soft select props method.
* Soft selection happens when the user clicks on the row.
*
* @param rowId The id of the currently soft selected item
* @param rowData The rowData from the underlying grid. MAY BE OUT OF DATE.
*/
onSoftSelectChange = (rowId, rowData) => {
//Note: only the Id is reliable, rowData may be out of date
const { onSoftSelectChange } = this.props;
if (rowId) {
console.log('Soft selected', rowId); //Just for demo purposes. Don't console log a real grid.
this.setState({ softSelectedId: rowId });
}
if (isFunc(onSoftSelectChange)) {
onSoftSelectChange(rowId, rowData);
}
}
/**
* Handles context filter changes and calls any hard select props method.
* Hard selection happens when the user checks the box for the row.
*
* @param {Array} selectedObjs A list of currently selected objects in the grid
*/
onHardSelectChange = (selectedObjs) => {
const { onContextMenuChange, onHardSelectChange } = this.props;
// Show the context buttons when there are rows checked.
if (isFunc(onContextMenuChange)) {
onContextMenuChange(selectedObjs.length > 0 ? this.contextBtns : null);
}
if (isFunc(onHardSelectChange)) {
onHardSelectChange(selectedObjs);
}
}
getSoftSelectId = ({ id } = '') => id;
render() {
const gridProps = {
/* Grid Properties */
...defaultExampleGridProps,
columnDefs: translateColumnDefs(this.props.t, this.columnDefs),
sizeColumnsToFit: true,
getSoftSelectId: this.getSoftSelectId,
softSelectId: (this.state.softSelectedDevice || {}).id,
...this.props, // Allow default property overrides
deltaRowDataMode: true,
enableSorting: true,
unSortIcon: true,
getRowNodeId: ({ id }) => id,
context: {
t: this.props.t
},
/* Grid Events */
onRowClicked: ({ node }) => node.setSelected(!node.isSelected()),
onGridReady: this.onGridReady,
onSoftSelectChange: this.onSoftSelectChange,
onHardSelectChange: this.onHardSelectChange
};
return (
<PcsGrid key="example-grid-key" {...gridProps} />
);
}
}
exampleGridConfig.js
import Config from 'app.config';
import { SoftSelectLinkRenderer } from 'components/shared/cellRenderers';
/** A collection of column definitions for the example grid */
export const exampleColumnDefs = {
id: {
headerName: 'walkthrough.pageWithGrid.grid.name',
field: 'id',
sort: 'asc',
cellRendererFramework: SoftSelectLinkRenderer
},
description: {
headerName: 'walkthrough.pageWithGrid.grid.description',
field: 'descr'
}
};
/** Given an example object, extract and return the device Id */
export const getSoftSelectId = ({ id }) => id;
/** Shared example grid AgGrid properties */
export const defaultExampleGridProps = {
enableColResize: true,
multiSelect: true,
pagination: false,
paginationPageSize: Config.paginationPageSize,
rowSelection: 'multiple'
};
Skopiuj folder src/walkthrough/components/pages/pageWithGrid/exampleGrid do folderu src/components/pages/example .
Dodawanie siatki do strony
Zmodyfikuj src/components/pages/example/basicPage.container.js w następujący sposób, aby zaimportować definicje usługi:
import { connect } from 'react-redux';
import { translate } from 'react-i18next';
import {
epics as exampleEpics,
getExamples,
getExamplesError,
getExamplesLastUpdated,
getExamplesPendingStatus
} from 'store/reducers/exampleReducer';
import { BasicPage } from './basicPage';
// Pass the data
const mapStateToProps = state => ({
data: getExamples(state),
error: getExamplesError(state),
isPending: getExamplesPendingStatus(state),
lastUpdated: getExamplesLastUpdated(state)
});
// Wrap the dispatch method
const mapDispatchToProps = dispatch => ({
fetchData: () => dispatch(exampleEpics.actions.fetchExamples())
});
export const BasicPageContainer = translate()(connect(mapStateToProps, mapDispatchToProps)(BasicPage));
Zmodyfikuj src/components/pages/example/basicPage.js w następujący sposób, aby dodać siatkę:
// Copyright (c) Microsoft. All rights reserved.
import React, { Component } from 'react';
import {
AjaxError,
ContextMenu,
PageContent,
RefreshBar
} from 'components/shared';
import { ExampleGrid } from './exampleGrid';
import './basicPage.css';
export class BasicPage extends Component {
constructor(props) {
super(props);
this.state = { contextBtns: null };
}
componentDidMount() {
const { isPending, lastUpdated, fetchData } = this.props;
if (!lastUpdated && !isPending) fetchData();
}
onGridReady = gridReadyEvent => this.gridApi = gridReadyEvent.api;
onContextMenuChange = contextBtns => this.setState({ contextBtns });
render() {
const { t, data, error, isPending, lastUpdated, fetchData } = this.props;
const gridProps = {
onGridReady: this.onGridReady,
rowData: isPending ? undefined : data || [],
onContextMenuChange: this.onContextMenuChange,
t: this.props.t
};
return [
<ContextMenu key="context-menu">
{this.state.contextBtns}
</ContextMenu>,
<PageContent className="basic-page-container" key="page-content">
<RefreshBar refresh={fetchData} time={lastUpdated} isPending={isPending} t={t} />
{!!error && <AjaxError t={t} error={error} />}
{!error && <ExampleGrid {...gridProps} />}
</PageContent>
];
}
}
Zmodyfikuj src/components/pages/example/basicPage.test.js w następujący sposób, aby zaktualizować testy:
// Copyright (c) Microsoft. All rights reserved.
import React from 'react';
import { shallow } from 'enzyme';
import 'polyfills';
import { BasicPage } from './basicPage';
describe('BasicPage Component', () => {
it('Renders without crashing', () => {
const fakeProps = {
data: undefined,
error: undefined,
isPending: false,
lastUpdated: undefined,
fetchData: () => { },
t: () => { },
};
const wrapper = shallow(
<BasicPage {...fakeProps} />
);
});
});
Testowanie siatki
Jeśli internetowy interfejs użytkownika nie jest jeszcze uruchomiony lokalnie, uruchom następujące polecenie w katalogu głównym lokalnej kopii repozytorium:
npm start
Poprzednie polecenie uruchamia interfejs użytkownika lokalnie pod adresem https://localhost:3000/dashboard
. Przejdź do strony Przykład , aby wyświetlić dane wyświetlane w siatce z usługi.
Wybieranie wierszy
Istnieją dwie opcje umożliwiające użytkownikowi wybieranie wierszy w siatce:
Zaznaczanie wierszy na dysku twardym
Jeśli użytkownik musi jednocześnie wykonywać działania w wielu wierszach, użyj pól wyboru w wierszach:
Włącz twarde zaznaczenie wierszy, dodając pole wyboruKolumn do kolumnyDefs dostarczone do siatki. funkcja checkboxColumn jest zdefiniowana w pliku /src/components/shared/pcsGrid/pcsGrid.js:
this.columnDefs = [ checkboxColumn, exampleColumnDefs.id, exampleColumnDefs.description ];
Aby uzyskać dostęp do wybranych elementów, uzyskasz odwołanie do wewnętrznego interfejsu API siatki:
onGridReady = gridReadyEvent => { this.gridApi = gridReadyEvent.api; // Call the onReady props if it exists if (isFunc(this.props.onGridReady)) { this.props.onGridReady(gridReadyEvent); } };
Podaj przyciski kontekstowe do strony, gdy wiersz w siatce jest zaznaczony trwale:
this.contextBtns = [ <Btn key="context-btn-1" svg={svgs.reconfigure} onClick={this.doSomething()}>Button 1</Btn>, <Btn key="context-btn-2" svg={svgs.trash} onClick={this.doSomethingElse()}>Button 2</Btn> ];
onHardSelectChange = (selectedObjs) => { const { onContextMenuChange, onHardSelectChange } = this.props; // Show the context buttons when there are rows checked. if (isFunc(onContextMenuChange)) { onContextMenuChange(selectedObjs.length > 0 ? this.contextBtns : null); } //... }
Po kliknięciu przycisku kontekstu pobierz ciężko wybrane elementy, aby wykonać swoją pracę:
doSomething = () => { //Just for demo purposes. Don't console log in a real grid. console.log('Hard selected rows', this.gridApi.getSelectedRows()); };
Zaznaczanie nietrwałe wierszy
Jeśli użytkownik musi działać tylko w jednym wierszu, skonfiguruj link wyboru nietrwałego dla co najmniej jednej kolumny w kolumnieDefs.
W exampleGridConfig.jsdodaj element SoftSelectLinkRenderer jako element cellRendererFramework dla elementu columnDef.
export const exampleColumnDefs = { id: { headerName: 'examples.grid.name', field: 'id', sort: 'asc', cellRendererFramework: SoftSelectLinkRenderer } };
Po kliknięciu linku wyboru nietrwałego wyzwala ono zdarzenie onSoftSelectChange . Wykonaj dowolną akcję dla tego wiersza, na przykład otwierając okno wysuwane szczegółów. Ten przykład po prostu zapisuje dane w konsoli:
onSoftSelectChange = (rowId, rowData) => { //Note: only the Id is reliable, rowData may be out of date const { onSoftSelectChange } = this.props; if (rowId) { //Just for demo purposes. Don't console log a real grid. console.log('Soft selected', rowId); this.setState({ softSelectedId: rowId }); } if (isFunc(onSoftSelectChange)) { onSoftSelectChange(rowId, rowData); } }
Następne kroki
W tym artykule przedstawiono informacje o dostępnych zasobach, które ułatwiają dodawanie lub dostosowywanie stron w internetowym interfejsie użytkownika w akceleratorze rozwiązania do monitorowania zdalnego.
Teraz zdefiniowano siatkę, następnym krokiem jest dodanie niestandardowego wysuwania do internetowego interfejsu użytkownika akceleratora rozwiązania do monitorowania zdalnego , który jest wyświetlany na przykładowej stronie.
Aby uzyskać więcej informacji koncepcyjnych na temat akceleratora rozwiązania do monitorowania zdalnego, zobacz Architektura monitorowania zdalnego.