Udostępnij za pośrednictwem


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:

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:

  1. 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
    ];
    
  2. 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);
      }
    };
    
  3. 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);
      }
      //...
    }
    
  4. 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.

  1. 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
      }
    };
    
  2. 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.