arcgis-item-browser

A customizeable React component allowing users to filter visible browser data by different data types grouped into Lists.

Usage no npm install needed!

<script type="module">
  import arcgisItemBrowser from 'https://cdn.skypack.dev/arcgis-item-browser';
</script>

README

Netlify Status

ArcGIS Item Browser

A customizeable React component allowing users to filter visible browser data by different data types grouped into Lists.

Documentation

You can preview the ArcGIS Item Browser here in this app's storybook, and find more information on what each of the components and their props.

Demo

You can view a demo of the app here, and find more information on what each of the components and their props.

Installation

npm i arcgis-item-browser

Import Syntax

import {
  ItemFilter,
  ItemTable,
  useItemBrowserState,
} from "arcgis-item-browser";

Basic Usage

The useItemBrowserState hook must be passed a userAccount as its first parameter (see below).

One option is to pass a UserSession object that can be imported from "@esri/arcgis-rest-auth".

The other option is to pass a user account returned from the useAccountManager hook

import { UserSession } from "@esri/arcgis-rest-auth";

const App = () => {
  /* useItemBrowserState manages ItemBrowser state using useReducer.  
  Returns queryResults from interacting with filters, 
  as well as functions to manage query updates 
  and interactions with ItemTable */
  const [userAccount, setUserAccount] = useState(null);
  /* This userAccount state value must either use the UserSession imported above or be set with an active user returned from the useAccountManager hook when a user logs in.*/
  const [browserView, setBrowserView] = useState("content");
  const [queryScope, setQueryScope] = useState("USER");

  /* Pass an optional function as customCellRenderer value to act as a custom renderer for title column in ItemTable. 
  Ex.  */
  const customCellRenderer = ({
    cellData,
    columnData,
    columnIndex,
    dataKey,
    isScrolling,
    rowData,
    rowIndex,
    getTypeImage,
  }) => {
    return <h6 style={{ color: "red" }}>{cellData}</h6>;
  };

  const itemBrowserOptions = {
    showFolderFilter: browserView === "content",
    showUserFilter: browserView === "content",
    queryScope,
    customCellRenderer,
  };

  const {
    queryResults,
    searchTermProps,
    ...itemBrowserProps
  } = useItemBrowserState(userAccount, itemBrowserOptions);

  return (
    <StyledApp>
      <StyledItemFilterWrapper>
        <ItemFilter userSession={userSession} {...itemBrowserProps} />
        <ItemTableWrapper>
          <input
            name={"folder-search"}
            placeholder="Filter items..."
            type="search"
            /* User can use any type of text input of choice.  
            It is necessary to spread the searchTermProps 
            into the search field component. 
            The searchTermProps is an object consisting 
            of the following properties:

              const searchTermProps = {
                value: string,
                onChange: () => {},
                onRequestClear: () => {},
              };
             */
            {...searchTermProps}
          />
          <ItemTable
            queryResults={queryResults}
            onItemClicked={(item) => console.log(item)}
            userSession={userSession}
            {...itemBrowserProps}
          />
        </ItemTableWrapper>
      </StyledItemFilterWrapper>
    </StyledApp>
  );
};

Theme Provider

ArgGIS Item Browser relies on Calcite React components which rely on <CalciteThemeProvider /> to access our theme via React Context. All Calcite React components must be wrapped in this provider component in order to render properly. In most cases, it's recommended to wrap your entire app at the highest level.

import React from "react";
import ReactDOM from "react-dom";

import CalciteThemeProvider from "calcite-react/CalciteThemeProvider";

import App from "path/to/App";

ReactDOM.render(
  <CalciteThemeProvider>
    <App />
  </CalciteThemeProvider>,
  document.getElementById("root")
);

useItemBrowserState Custom React Hook

The useItemBrowserState custom React hook accepts a required userSession prop (ArcGIS UserSession).

Returns an object containing the following props:

const [userAccount, setUserAccount] = useState(null);
const [browserView, setBrowserView] = useState("content");
const [queryScope, setQueryScope] = useState("USER");

const customCellRenderer = ({
  cellData,
  columnData,
  columnIndex,
  dataKey,
  isScrolling,
  rowData,
  rowIndex,
  getTypeImage,
}) => {
  return <h6 style={{ color: "red" }}>{cellData}</h6>;
};

const itemBrowserOptions = {
  showFolderFilter: browserView === "content",
  showUserFilter: browserView === "content",
  queryScope,
  customCellRenderer,
};

const {
  queryResults,
  itemBrowserState,
  dispatchItemBrowser,
  handleStateUpdate,
  currentUsername,
  getUserFolders,
  handleQueryChange,
  sortField,
  sortOrder,
  searchTermProps,
  showFolderFilter,
  showUserFilter,
  portal,
  session,
  addUser,
  resetState,
  customCellRenderer,
} = useItemBrowserState(userAccount, itemBrowserOptions);
// returned properties
queryResults<array>: Array of objects containing query results,

itemBrowserState<object>: Object containing state for ItemFilter,

dispatchItemBrowser<func>: Setter func for itemBrowserState,

handleStateUpdate<func>: Func invoked upon state update,

currentUsername<string>: ArcGIS username for active user,

getUserFolders<func>: Func for getting ArcGIS folders for active user,

handleQueryChange<func>: Func invoked upon query update,

sortField<string>: Field specifying which ItemTable column to sort by,

sortOrder<string>: Direction indicating whether to sort ItemTable columns in ascending or descending order,

searchTermProps<SearchTermProps (see below)>: Object consisting of value, onChange, and onRequestClose for use with text input used to search for items. This prop must be spread onto the component used as search/text input for filtering items in ItemTable.

showFolderFilter<bool>: Boolean that determines whether or not to display Folders component.,

showUserFilter<bool>: Boolean that determines whether or not to display Users component.,

portal<AGOL Portal Object>: See "AGOL Portal Object" below.,

session<AGOL Session Object>: See "AGOL Session Object" below.,

addUser<func>: Function that adds new user to Users component list or sets user as active when clicking between users in Users component list.,

resetState<func>: Func that resets itemBrowserState to default,

customCellRenderer<func>: Func acting as a custom renderer for title column in ItemTable,

SearchTermProps Type

{
  "value": string,
  "onChange": () => {},
  "onRequestClear": () => {}
}

AGOL Portal Object

AGOL Session Object

NOTE: Required additional dependencies

React-Virtualized

The react-virtualized CSS must be added by importing it into your index.js file:

import 'react-virtualized/styles.css'

Calcite Components

ArcGIS Item Browser currently uses Calcite Components as a dependency for various components, including Pagination. This is a temporary dependency that requires some customization in the application using the Item Browser.

To install calcite components, first run:

npm install --save @esri/calcite-components

After calcite-components is installed, import the set up the loader in your index.js file:

import { applyPolyfills, defineCustomElements } from '@esri/calcite-components/dist/loader';

// Apply polyfills and then define the custom elements
// polyfills are not needed if you don't support IE11 or Edge
applyPolyfills().then(() => {
  defineCustomElements(window);
});

Adding the CSS

The global calcite components CSS can be added by importing it into your src/App.js file:

import '@esri/calcite-components/dist/calcite/calcite.css';

Adding the icons

The icon assets must be copied over to the public/assets folder manually. Currently, the only necessary icons are:

chevronLeft16.json
chevronLeft24.json
chevronLeft32.json
chevronRight16.json
chevronRight24.json
chevronRight32.json
ellipsis16.json
ellipsis24.json
ellipsis32.json