Add aria-labels 57/115557/1
authorAijana Schumann <aijana.schumann@highstreet-technologies.com>
Mon, 30 Nov 2020 17:51:52 +0000 (18:51 +0100)
committerAijana Schumann <aijana.schumann@highstreet-technologies.com>
Mon, 30 Nov 2020 17:55:38 +0000 (18:55 +0100)
Add aria-labels to odlux framework and apps

Issue-ID: CCSDK-2886
Signed-off-by: Aijana Schumann <aijana.schumann@highstreet-technologies.com>
Change-Id: If1fdf9f8a805b567dd65bcf2cfb029b71f9235b7

32 files changed:
sdnr/wt/odlux/apps/configurationApp/src/components/ifWhenTextInput.tsx
sdnr/wt/odlux/apps/configurationApp/src/components/uiElementBoolean.tsx
sdnr/wt/odlux/apps/configurationApp/src/components/uiElementReference.tsx
sdnr/wt/odlux/apps/configurationApp/src/components/uiElementSelection.tsx
sdnr/wt/odlux/apps/configurationApp/src/views/networkElementSelector.tsx
sdnr/wt/odlux/apps/connectApp/src/components/connectionStatusLog.tsx
sdnr/wt/odlux/apps/connectApp/src/components/editNetworkElementDialog.tsx
sdnr/wt/odlux/apps/connectApp/src/components/infoNetworkElementDialog.tsx
sdnr/wt/odlux/apps/connectApp/src/views/connectView.tsx
sdnr/wt/odlux/apps/eventLogApp/src/views/eventLog.tsx
sdnr/wt/odlux/apps/faultApp/src/views/faultApplication.tsx
sdnr/wt/odlux/apps/inventoryApp/src/views/dashboard.tsx
sdnr/wt/odlux/apps/inventoryApp/src/views/treeview.tsx
sdnr/wt/odlux/apps/maintenanceApp/src/views/maintenenceView.tsx
sdnr/wt/odlux/apps/networkMapApp/src/components/details/linkDetails.tsx
sdnr/wt/odlux/apps/networkMapApp/src/components/details/siteDetails.tsx
sdnr/wt/odlux/apps/performanceHistoryApp/src/components/adaptiveModulation.tsx
sdnr/wt/odlux/apps/performanceHistoryApp/src/components/chartFilter.tsx
sdnr/wt/odlux/apps/performanceHistoryApp/src/components/crossPolarDiscrimination.tsx
sdnr/wt/odlux/apps/performanceHistoryApp/src/components/ltpSelection.tsx
sdnr/wt/odlux/apps/performanceHistoryApp/src/components/performanceData.tsx
sdnr/wt/odlux/apps/performanceHistoryApp/src/components/receiveLevel.tsx
sdnr/wt/odlux/apps/performanceHistoryApp/src/components/signalToInterference.tsx
sdnr/wt/odlux/apps/performanceHistoryApp/src/components/temperature.tsx
sdnr/wt/odlux/apps/performanceHistoryApp/src/components/transmissionPower.tsx
sdnr/wt/odlux/apps/performanceHistoryApp/src/views/performanceHistoryApplication.tsx
sdnr/wt/odlux/framework/src/app.tsx
sdnr/wt/odlux/framework/src/components/material-table/index.tsx
sdnr/wt/odlux/framework/src/components/material-table/tableFilter.tsx
sdnr/wt/odlux/framework/src/components/material-table/tableToolbar.tsx
sdnr/wt/odlux/framework/src/components/material-ui/treeView.tsx
sdnr/wt/odlux/framework/src/components/objectDump/index.tsx

index 62ddeb2..56ec8df 100644 (file)
@@ -75,7 +75,7 @@ export const IfWhenTextInput = (props: IfwhenProps) => {
   return (
     <FormControl error={error} style={style}>
       <InputLabel htmlFor={id} >{label}</InputLabel>
-      <Input id={id} endAdornment={<div>{ifFeature}{whenFeature}</div>} {...otherProps}  />
+      <Input id={id} inputProps={{'aria-label': label+'-input'}} endAdornment={<div>{ifFeature}{whenFeature}</div>} {...otherProps}  />
       <FormHelperText>{errorText}</FormHelperText>
     </FormControl>
   );
index 2fbbf95..081ec46 100644 (file)
@@ -35,6 +35,7 @@ export const UiElementBoolean = (props: BooleanInputProps) => {
         ? (<FormControl style={{ width: 485, marginLeft: 20, marginRight: 20 }}>
             <InputLabel htmlFor={`select-${element.id}`} >{element.label}</InputLabel>
             <Select
+                aria-label={element.label+'-selection'}
                 required={!!element.mandatory}
                 error={mandetoryError}
                 onChange={(e) => { props.onChange(e.target.value === 'true') }}
@@ -46,8 +47,8 @@ export const UiElementBoolean = (props: BooleanInputProps) => {
                     id: `select-${element.id}`,
                 }}
             >
-                <MenuItem value={'true'}>{element.trueValue || 'True'}</MenuItem>
-                <MenuItem value={'false'}>{element.falseValue || 'False'}</MenuItem>
+                <MenuItem value={'true'} aria-label="true">{element.trueValue || 'True'}</MenuItem>
+                <MenuItem value={'false'} aria-label="false">{element.falseValue || 'False'}</MenuItem>
 
             </Select>
             <FormHelperText>{mandetoryError ? "Value is mandetory" : ""}</FormHelperText>
index 2760eee..b95df1f 100644 (file)
@@ -39,9 +39,9 @@ export const UIElementReference: React.FC<UIElementReferenceProps> = (props) =>
   return (
     <FormControl key={element.id} style={{ width: 485, marginLeft: 20, marginRight: 20 }}>
       <Tooltip title={element.description || ''}>
-        <Button className={classes.button} color="secondary" disabled={props.disabled} onClick={() => {
+        <Button className={classes.button} aria-label={element.label+'-button'} color="secondary" disabled={props.disabled} onClick={() => {
           props.onOpenReference(element);
-        }}>{element.label}</Button>
+        }}>{`${element.label}`}</Button>
       </Tooltip>
     </FormControl>
   );
index 2786051..530b0be 100644 (file)
@@ -19,7 +19,7 @@
 import * as React from 'react';
 import { BaseProps } from './baseProps';
 import { ViewElementSelection } from '../models/uiModels'
-import { FormControl, InputLabel, Select, FormHelperText, MenuItem } from '@material-ui/core';
+import { FormControl, InputLabel, Select, FormHelperText, MenuItem, Tooltip } from '@material-ui/core';
 
 type selectionProps = BaseProps;
 
@@ -37,20 +37,20 @@ export const UiElementSelection = (props: selectionProps) => {
         ? (<FormControl style={{ width: 485, marginLeft: 20, marginRight: 20 }}>
             <InputLabel htmlFor={`select-${element.id}`} >{element.label}</InputLabel>
             <Select
-                title={(element.options.find(o => o.key === value.toString().toLowerCase()) || { description: undefined }).description}
                 required={!!element.mandatory}
                 error={!!error}
                 onChange={(e) => { props.onChange(e.target.value as string) }}
                 readOnly={props.readOnly}
                 disabled={props.disabled}
                 value={value.toString().toLowerCase()}
+                aria-label={element.label+'-selection'}
                 inputProps={{
                     name: element.id,
                     id: `select-${element.id}`,
                 }}
             >
           {element.options.map(option => (
-            <MenuItem key={option.key} title={option.description || ''} value={option.key}>{option.key}</MenuItem>
+            <MenuItem key={option.key} value={option.key} aria-label={option.key}><Tooltip title={option.description || '' }><div style={{width:"100%"}}>{option.key}</div></Tooltip></MenuItem>
           ))}
             </Select>
             <FormHelperText>{error}</FormHelperText>
index 503133b..5d84998 100644 (file)
@@ -55,8 +55,8 @@ class NetworkElementSelectorComponent extends React.Component<NetworkElementSele
   render() {
     return (
       <ConnectedElementTable stickyHeader onHandleClick={(e, row) => { this.props.history.push(`${this.props.match.path}/${row.nodeId}`) }} columns={[
-        { property: "nodeId", title: "Name", type: ColumnType.text },
-        { property: "isRequired", title: "Required ?", type: ColumnType.boolean },
+        { property: "nodeId", title: "Node Name", type: ColumnType.text },
+        { property: "isRequired", title: "Required", type: ColumnType.boolean },
         { property: "host", title: "Host", type: ColumnType.text },
         { property: "port", title: "Port", type: ColumnType.numeric },
         { property: "coreModelCapability", title: "Core Model", type: ColumnType.text },
index 96f6c8a..f2fd293 100644 (file)
@@ -42,9 +42,9 @@ class ConnectionStatusLogComponent extends React.Component<ConnectionStatusLogCo
   render(): JSX.Element {
     return (
       <ConnectionStatusTable stickyHeader tableId="connection-status-table" columns={[
-        { property: "timestamp", title: "Time", type: ColumnType.text },
+        { property: "timestamp", title: "Timestamp", type: ColumnType.text },
         { property: "nodeId", title: "Node Name", type: ColumnType.text },
-        { property: "status", title: "Connection status", type: ColumnType.text },
+        { property: "status", title: "Connection Status", type: ColumnType.text },
       ]} idProperty="id" {...this.props.connectionStatusLogActions} {...this.props.connectionStatusLogProperties} >
       </ConnectionStatusTable>
     );
index 3b4cf3b..97e6647 100644 (file)
@@ -192,11 +192,11 @@ class EditNetworkElementDialogComponent extends React.Component<EditNetworkEleme
           {setting.enableUsernameEditor && <TextField disabled={!setting.enableUsernameEditor} spellCheck={false} margin="dense" id="password" label="Password" aria-label="password" type="password" fullWidth value={this.state.password} onChange={(event) => { this.setState({ password: event.target.value }); }} /> || null}
           <FormControl fullWidth disabled={!setting.enableUsernameEditor}>
             <InputLabel htmlFor="active">Required</InputLabel>
-            <Select value={this.state.isRequired || false} onChange={(event) => {
+            <Select aria-label="required-selection" value={this.state.isRequired || false} onChange={(event) => {
               this.setState({ isRequired: event.target.value as any as boolean });
             }} inputProps={{ name: 'required', id: 'required' }} fullWidth >
-              <MenuItem value={true as any as string} >True</MenuItem>
-              <MenuItem value={false as any as string} >False</MenuItem>
+              <MenuItem value={true as any as string} aria-label="true">True</MenuItem>
+              <MenuItem value={false as any as string} aria-label="false">False</MenuItem>
             </Select>
           </FormControl>
         </DialogContent>
index ea9d419..df8515e 100644 (file)
@@ -56,7 +56,7 @@ const settings: { [key: string]: DialogSettings } = {
   [InfoNetworkElementDialogMode.InfoNetworkElement]: {
     dialogTitle: "Yang capabilities of the network element",
     dialogDescription: "Available capabilities of the network element",
-    cancelButtonText: "Cancel",
+    cancelButtonText: "OK",
   }
 }
 
@@ -97,6 +97,8 @@ class InfoNetworkElementDialogComponent extends React.Component<InfoNetworkEleme
       }
     });
 
+    yangCapabilities = yangCapabilities.sort((a,b) => a.module === b.module ? 0 : a.module > b.module ? 1 : -1);
+
     return (
       <Dialog open={this.props.mode !== InfoNetworkElementDialogMode.None}>
         <DialogTitle id="form-dialog-title">{setting.dialogTitle}</DialogTitle>
@@ -104,7 +106,7 @@ class InfoNetworkElementDialogComponent extends React.Component<InfoNetworkEleme
           <DialogContentText>
             {setting.dialogDescription + " " + this.state.nodeId}
           </DialogContentText>
-          <Table >
+          <Table aria-label="yang-capabilities-table">
             <TableHead>
               <TableRow>
                 <TableCell align="right">S.No</TableCell>
@@ -114,17 +116,17 @@ class InfoNetworkElementDialogComponent extends React.Component<InfoNetworkEleme
             </TableHead>
             <TableBody>
               {yangCapabilities.map((yang, index) => (
-                <TableRow>
+                <TableRow aria-label="yang-capabilities-row">
                   <TableCell>{index + 1}</TableCell>
-                  <TableCell>{yang.module}</TableCell>
-                  <TableCell>{yang.revision}</TableCell>
+                  <TableCell aria-label="yang-module"><a href={`/yang-schema/${yang.module}`} target={"_blank"}> {yang.module} </a></TableCell>
+                  <TableCell aria-label="yang-revision">{yang.revision}</TableCell>
                 </TableRow>
               ))}
             </TableBody>
           </Table>
         </DialogContent>
         <DialogActions>
-          <Button onClick={(event) => {
+          <Button aria-label="ok-button" onClick={(event) => {
             this.onCancel();
             event.preventDefault();
             event.stopPropagation();
index 86861fa..1fa5e19 100644 (file)
@@ -105,9 +105,9 @@ class ConnectApplicationComponent extends React.Component<ConnectApplicationComp
     return (
       <>
         <AppBar position="static">
-          <Tabs value={activePanelId} onChange={this.onHandleTabChange} aria-label="simple tabs example">
-            <Tab aria-lablel="network-elements-list-tab" label="Network Elements" value="NetworkElements" />
-            <Tab aria-lablel="connection-status-log-tab" label="Connection Status Log" value="ConnectionStatusLog" />
+          <Tabs value={activePanelId} onChange={this.onHandleTabChange} aria-label="connect-app-tabs">
+            <Tab aria-label="network-elements-list-tab" label="Network Elements" value="NetworkElements" />
+            <Tab aria-label="connection-status-log-tab" label="Connection Status Log" value="ConnectionStatusLog" />
           </Tabs>
         </AppBar>
         {activePanelId === 'NetworkElements'
index aa90272..3d81e4e 100644 (file)
@@ -39,7 +39,7 @@ let initalSorted = false;
 
 class EventLogComponent extends React.Component<Connect<typeof mapProps, typeof mapDispatch>> {
   render() {
-    return <EventLogTable stickyHeader title="Event Log" idProperty="_id" columns={[
+    return <EventLogTable stickyHeader title="Event Log" tableId="event-log-table" idProperty="_id" columns={[
       { property: "nodeId", title: "Node Name" },
       { property: "counter", title: "Counter" },
       { property: "timestamp", title: "Timestamp" },
index 7c29fec..2c167c5 100644 (file)
@@ -137,16 +137,16 @@ class FaultApplicationComponent extends React.Component<FaultApplicationComponen
     return (
       <>
         <AppBar position="static" >
-          <Tabs value={activePanelId} onChange={this.onHandleTabChange} aria-label="fault tabs">
+          <Tabs value={activePanelId} onChange={this.onHandleTabChange} aria-label="fault-tabs">
             <Tab aria-label="current-problem-list-tab" label="Current Problem List" value="CurrentProblem" />
             <Tab aria-label="alarm-notifications-list-tab" label={`Alarm Notifications (${this.props.faultNotifications.faults.length})`} value="AlarmNotifications" />
             <Tab aria-label="alarm-log-tab" label="Alarm Log" value="AlarmLog" />
           </Tabs>
         </AppBar>
         {
-          activePanelId === 'CurrentProblem' && <FaultTable stickyHeader idProperty={'id'} customActionButtons={customAction} columns={[
+          activePanelId === 'CurrentProblem' && <FaultTable stickyHeader tableId="current-problems-table" idProperty={'id'} customActionButtons={customAction} columns={[
             { property: "icon", title: "", type: ColumnType.custom, customControl: this.renderIcon },
-            { property: "timestamp", type: ColumnType.text, title: "Time Stamp" },
+            { property: "timestamp", type: ColumnType.text, title: "Timestamp" },
             { property: "nodeId", title: "Node Name", type: ColumnType.text },
             { property: "counter", title: "Count", type: ColumnType.numeric, width: "100px" },
             { property: "objectId", title: "Object Id", type: ColumnType.text },
@@ -156,9 +156,9 @@ class FaultApplicationComponent extends React.Component<FaultApplicationComponen
         }
         {activePanelId === 'AlarmNotifications' &&
 
-          <FaultAlarmNotificationTable stickyHeader rows={this.props.faultNotifications.faults} asynchronus columns={[
+          <FaultAlarmNotificationTable tableId="alarm-notifications-table" stickyHeader rows={this.props.faultNotifications.faults} asynchronus columns={[
             { property: "icon", title: "", type: ColumnType.custom, customControl: this.renderIcon },
-            { property: "timeStamp", title: "Time Stamp" },
+            { property: "timeStamp", title: "Timestamp" },
             { property: "nodeName", title: "Node Name" },
             { property: "counter", title: "Count", width: "100px", type: ColumnType.numeric },
             { property: "objectId", title: "Object Id" },
@@ -168,9 +168,11 @@ class FaultApplicationComponent extends React.Component<FaultApplicationComponen
 
         }
 
-        {activePanelId === 'AlarmLog' && <FaultTable stickyHeader idProperty={'id'} columns={[
+        {activePanelId === 'AlarmLog' && 
+        <FaultTable stickyHeader idProperty={'id'} tableId="alarm-log-table"
+          columns={[
           { property: "icon", title: "", type: ColumnType.custom, customControl: this.renderIcon },
-          { property: "timestamp", title: "Time Stamp" },
+          { property: "timestamp", title: "Timestamp" },
           { property: "nodeId", title: "Node Name" },
           { property: "counter", title: "Count", type: ColumnType.numeric, width: "100px" },
           { property: "objectId", title: "Object Id" },
index 14792df..f5ada22 100644 (file)
@@ -115,9 +115,9 @@ class DashboardSelectorComponent extends React.Component<DashboardComponentProps
     return (
       <>
         <AppBar position="static">
-          <Tabs value={activePanelId} onChange={this.onHandleTabChange} aria-label="simple tabs example">
-            <Tab label="Table View" value="InventoryElementsTable" />
-            <Tab label="Tree view" value="TreeviewTable" />
+          <Tabs value={activePanelId} onChange={this.onHandleTabChange} aria-label="inventory-app-tabs">
+            <Tab label="Table View" value="InventoryElementsTable" aria-label="table-tab" />
+            <Tab label="Tree view" value="TreeviewTable" aria-label="treeview-tab" />
           </Tabs>
         </AppBar>
 
@@ -125,7 +125,7 @@ class DashboardSelectorComponent extends React.Component<DashboardComponentProps
 
           activePanelId === "InventoryElementsTable" &&
 
-          <InventoryTable stickyHeader title="Inventory" idProperty="_id" columns={[
+          <InventoryTable stickyHeader title="Inventory" idProperty="_id" tableId="inventory-table" columns={[
             { property: "nodeId", title: "Node Name" },
             { property: "manufacturerIdentifier", title: "Manufacturer" },
             { property: "parentUuid", title: "Parent" },
@@ -149,9 +149,9 @@ class DashboardSelectorComponent extends React.Component<DashboardComponentProps
         {
           activePanelId === "TreeviewTable" &&
 
-          <ConnectedElementTable stickyHeader onHandleClick={(e, row) => { this.props.history.push(`${this.props.match.path}/${row.nodeId}`) }} columns={[
-            { property: "nodeId", title: "Name", type: ColumnType.text },
-            { property: "isRequired", title: "Required ?", type: ColumnType.boolean },
+          <ConnectedElementTable stickyHeader tableId="treeview-networkelement-selection-table" onHandleClick={(e, row) => { this.props.history.push(`${this.props.match.path}/${row.nodeId}`) }} columns={[
+            { property: "nodeId", title: "Node Name", type: ColumnType.text },
+            { property: "isRequired", title: "Required", type: ColumnType.boolean },
             { property: "host", title: "Host", type: ColumnType.text },
             { property: "port", title: "Port", type: ColumnType.numeric },
             { property: "coreModelCapability", title: "Core Model", type: ColumnType.text },
index 5f2c610..5ba82ab 100644 (file)
@@ -112,7 +112,7 @@ class DashboardComponent extends React.Component<TreeviewComponentProps, Treevie
           }}
           onItemClick={(elm) => selectTreeNode(elm.value)} />
         <div className={classes.details}>{
-          selectedNode && renderObject(selectedNode) || null
+          selectedNode && renderObject(selectedNode, "tree-view") || null
         }</div>
       </div>
     );
index f087ed2..f52d46d 100644 (file)
@@ -116,7 +116,7 @@ class MaintenenceViewComponent extends React.Component<MaintenenceViewComponentP
     const now = new Date().valueOf();
     return (
       <>
-        <MaintenenceEntriesTable stickyHeader title={"Maintenance"} customActionButtons={[addMaintenenceEntryAction]} columns={
+        <MaintenenceEntriesTable stickyHeader tableId="maintenance-table" title={"Maintenance"} customActionButtons={[addMaintenenceEntryAction]} columns={
           [
             { property: "nodeId", title: "Node Name", type: ColumnType.text },
             {
index 0c9f603..a8f73f3 100644 (file)
@@ -82,10 +82,10 @@ const LinkDetails: React.FunctionComponent<props> = (props) => {
 
     return (<div style={{ paddingLeft: "15px", paddingRight: "15px", paddingTop: "0px", display: 'flex', flexDirection: 'column' }}>
         <h2>{props.link.name}</h2>
-        <TextField aria-label="operator" disabled style={{ marginTop: "5px" }} value="Unkown" label="Operator" />
-        <TextField aria-label="type" disabled style={{ marginTop: "5px" }} value={props.link.type} label="Type" />
-        <TextField aria-label="planned-distance-in-km" disabled style={{ marginTop: "5px" }} value={props.link.length.toFixed(2)} label="Distance planned in km" />
-        <TextField aria-label="calculated-distance-in-km" disabled style={{ marginTop: "5px" }} value={props.link.calculatedLength.toFixed(2)} label="Distance calculated in km" />
+        <TextField inputProps={{ 'aria-label': 'operator' }} disabled style={{ marginTop: "5px" }} value="Unkown" label="Operator" />
+        <TextField inputProps={{ 'aria-label': 'type' }} disabled style={{ marginTop: "5px" }} value={props.link.type} label="Type" />
+        <TextField inputProps={{ 'aria-label': 'planned-distance-in-km' }} disabled style={{ marginTop: "5px" }} value={props.link.length.toFixed(2)} label="Distance planned in km" />
+        <TextField inputProps={{ 'aria-label': 'calculated-distance-in-km' }} disabled style={{ marginTop: "5px" }} value={props.link.calculatedLength.toFixed(2)} label="Distance calculated in km" />
 
         <AppBar position="static" id="site-tabs" style={{ marginTop: "20px", background: '#2E3B55' }}>
             <Typography aria-label="details-of-link-sites" style={{ margin:"5px"}}>SITE DETAILS</Typography>
index 92643d0..6131661 100644 (file)
@@ -41,7 +41,6 @@ const SiteDetails: React.FunctionComponent<props> = (props) => {
     const [height, setHeight] = React.useState(330);
 
     const handleResize = () =>{
-        //console.log("resize")
         const el = document.getElementById('site-details-panel')?.getBoundingClientRect();
         const el2 = document.getElementById('site-tabs')?.getBoundingClientRect();
 
@@ -81,28 +80,28 @@ const SiteDetails: React.FunctionComponent<props> = (props) => {
         <h2 >{props.site.name}</h2>
         {
             props.site.operator !== '' && props.site.operator !== null ?
-                <TextField aria-label="operator" disabled={true} value={props.site.operator} label="Operator" /> :
-                <TextField aria-label="operator" disabled={true} value="Unkown" label="Operator" style={{ marginTop: "5px" }} />
+                <TextField inputProps={{ 'aria-label': 'operator' }} disabled={true} value={props.site.operator} label="Operator" /> :
+                <TextField inputProps={{ 'aria-label': 'operator' }} disabled={true} value="Unkown" label="Operator" style={{ marginTop: "5px" }} />
         }
         {
             props.site.type !== undefined && props.site.type.length > 0 &&
-            <TextField aria-label="type" disabled={true} value={props.site.type} label="Type" style={{ marginTop: "5px" }} />
+            <TextField inputProps={{ 'aria-label': 'type' }} disabled={true} value={props.site.type} label="Type" style={{ marginTop: "5px" }} />
         }
         {
             props.site.address !== undefined && props.site.address.length > 0 &&
-            <TextField aria-label="adress" disabled={true} value={props.site.address} label="Adress" style={{ marginTop: "5px" }} />
+            <TextField inputProps={{ 'aria-label': 'adress' }} disabled={true} value={props.site.address} label="Adress" style={{ marginTop: "5px" }} />
         }
         {
             props.site.heighAGLInMeters !== undefined && props.site.heighAGLInMeters > 0 &&
-            <TextField aria-label="amsl-in-meters" disabled={true} value={props.site.heighAGLInMeters} label="AMSL in meters" style={{ marginTop: "5px" }} />
+            <TextField inputProps={{ 'aria-label': 'amsl-in-meters' }} disabled={true} value={props.site.heighAGLInMeters} label="AMSL in meters" style={{ marginTop: "5px" }} />
         }
         {
             props.site.antennaHeightAGLInMeters !== undefined && props.site.antennaHeightAGLInMeters > 0 &&
-            <TextField aria-label="antenna-above-ground-in-meters" disabled={true} value={props.site.antennaHeightAGLInMeters} label="Atenna above ground in meters" style={{ marginTop: "5px" }} />
+            <TextField inputProps={{ 'aria-label': 'antenna-above-ground-in-meters' }} disabled={true} value={props.site.antennaHeightAGLInMeters} label="Atenna above ground in meters" style={{ marginTop: "5px" }} />
         }
          
-        <TextField aria-label="latitude" style={{ marginTop: "5px" }} disabled={true} value={LatLonToDMS(props.site.geoLocation.lat)} label="Latitude" />
-        <TextField aria-label="longitude" style={{ marginTop: "5px" }} disabled={true} value={LatLonToDMS(props.site.geoLocation.lon, true)} label="Longitude" />
+        <TextField inputProps={{ 'aria-label': 'latitude' }} style={{ marginTop: "5px" }} disabled={true} value={LatLonToDMS(props.site.geoLocation.lat)} label="Latitude" />
+        <TextField inputProps={{ 'aria-label': 'longitude' }} style={{ marginTop: "5px" }} disabled={true} value={LatLonToDMS(props.site.geoLocation.lon, true)} label="Longitude" />
 
         <AppBar position="static" style={{ marginTop: "5px", background: '#2E3B55' }}>
             <Tabs id="site-tabs" value={value} onChange={onHandleTabChange} aria-label="simple tabs example">
index f0a93f5..17b1374 100644 (file)
@@ -90,7 +90,7 @@ class AdaptiveModulationComponent extends React.Component<AdaptiveModulationComp
       <>
         <ToggleContainer onToggleFilterButton={this.onToggleFilterButton} showFilter={this.props.isFilterVisible} existingFilter={this.props.adaptiveModulationProperties.filter} onFilterChanged={this.onFilterChanged} selectedValue={this.props.currentView} onChange={this.onChange}>
           {lineChart(chartPagedData)}
-          <AdaptiveModulationTable stickyHeader idProperty={"_id"} columns={adaptiveModulationColumns} {...properties} {...actions} />
+          <AdaptiveModulationTable stickyHeader idProperty={"_id"} tableId="adaptive-modulation-table" columns={adaptiveModulationColumns} {...properties} {...actions} />
         </ToggleContainer>
       </>
     );
index e5f540e..e7583de 100644 (file)
@@ -44,22 +44,22 @@ const ChartFilter: React.FunctionComponent<filterProps> = (props) => {
             {
                 props.isVisible &&
                 <div className={classes.filterContainer}>
-                    <TextField className={classes.filterInput} label="Radio Signal" value={props.filters.radioSignalId || ''} onChange={(event) => props.onFilterChanged("radioSignalId", event.target.value)} InputLabelProps={{
+                    <TextField inputProps={{'aria-label': 'radio-signal-filter'}} className={classes.filterInput} label="Radio Signal" value={props.filters.radioSignalId || ''} onChange={(event) => props.onFilterChanged("radioSignalId", event.target.value)} InputLabelProps={{
                         shrink: true,
                     }} />
-                    <TextField className={classes.filterInput} label="Scanner ID" value={props.filters.scannerId || ''} onChange={(event) => props.onFilterChanged("scannerId", event.target.value)} InputLabelProps={{
+                    <TextField inputProps={{'aria-label': 'scanner-id-filter'}} className={classes.filterInput} label="Scanner ID" value={props.filters.scannerId || ''} onChange={(event) => props.onFilterChanged("scannerId", event.target.value)} InputLabelProps={{
                         shrink: true,
                     }} />
-                    <TextField className={classes.filterInput} label="End Time" value={props.filters.timeStamp || ''} onChange={(event) => props.onFilterChanged("timeStamp", event.target.value)} InputLabelProps={{
+                    <TextField inputProps={{'aria-label': 'end-time-filter'}} className={classes.filterInput} label="End Time" value={props.filters.timeStamp || ''} onChange={(event) => props.onFilterChanged("timeStamp", event.target.value)} InputLabelProps={{
                         shrink: true,
                     }} />
                     <FormControl>
                         <InputLabel id="suspect-interval-label" shrink>Suspect Interval</InputLabel>
 
-                        <Select labelId="suspect-interval-label" value={suspectIntervalFlag || ''} onChange={(event) => props.onFilterChanged("suspectIntervalFlag", event.target.value as string)}>
-                            <MenuItem value={undefined}>None</MenuItem>
-                            <MenuItem value={"true"}>true</MenuItem>
-                            <MenuItem value={"false"}>false</MenuItem>
+                        <Select aria-label="suspect-interval-selection" labelId="suspect-interval-label" value={suspectIntervalFlag || ''} onChange={(event) => props.onFilterChanged("suspectIntervalFlag", event.target.value as string)}>
+                            <MenuItem value={undefined} aria-label="none">None</MenuItem>
+                            <MenuItem value={"true"} aria-label="true">true</MenuItem>
+                            <MenuItem value={"false"} aria-label="false">false</MenuItem>
                         </Select>
                     </FormControl>
                 </ div>
index 60051d0..14cc02d 100644 (file)
@@ -93,7 +93,7 @@ class CrossPolarDiscriminationComponent extends React.Component<CrossPolarDiscri
       <>
         <ToggleContainer onToggleFilterButton={this.onToggleFilterButton} showFilter={this.props.isFilterVisible} existingFilter={this.props.crossPolarDiscriminationProperties.filter} onFilterChanged={this.onFilterChanged} selectedValue={this.props.currentView} onChange={this.onChange}>
           {lineChart(chartPagedData)}
-          <CrossPolarDiscriminationTable stickyHeader idProperty={"_id"} columns={cpdColumns} {...properties} {...actions} />
+          <CrossPolarDiscriminationTable stickyHeader idProperty={"_id"} tableId="cross-polar-discrimination-table" columns={cpdColumns} {...properties} {...actions} />
         </ToggleContainer>
       </>
     );
index b0aebd2..61b7813 100644 (file)
@@ -58,15 +58,15 @@ export const LtpSelection = (props: LtpSelectionProps) => {
                 <span>
                     Select LTP
                 </span>
-                <Select className={classes.selectDropdown} value={props.selectedLtp} onChange={props.onChangeLtp}  >
-                    <MenuItem value={"-1"}><em>--Select--</em></MenuItem>
+                <Select className={classes.selectDropdown} value={props.selectedLtp} onChange={props.onChangeLtp} aria-label="ltp-selection" >
+                    <MenuItem value={"-1"} aria-label="none"><em>--Select--</em></MenuItem>
                     {props.availableLtps.map(ltp =>
-                        (<MenuItem value={ltp.key} key={ltp.key}>{ltp.key}</MenuItem>))}
+                        (<MenuItem value={ltp.key} key={ltp.key} aria-label={ltp.key}>{ltp.key}</MenuItem>))}
                 </Select>
                 <span> Time-Period </span>
-                <Select className={classes.selectDropdown} value={props.selectedTimePeriod} onChange={props.onChangeTimePeriod} >
-                    <MenuItem value={"15min"}>15min</MenuItem>
-                    <MenuItem value={"24hours"}>24hours</MenuItem>
+                <Select className={classes.selectDropdown} value={props.selectedTimePeriod} onChange={props.onChangeTimePeriod} aria-label="time-period-selection">
+                    <MenuItem value={"15min"} aria-label="15minutes">15min</MenuItem>
+                    <MenuItem value={"24hours"} aria-label="24hours">24hours</MenuItem>
                 </Select>
             </FormControl>
             {
index 28352cd..6209024 100644 (file)
@@ -85,7 +85,7 @@ class PerformanceDataComponent extends React.Component<PerformanceDataComponentP
       <>
         <ToggleContainer onToggleFilterButton={() => this.props.toggleFilterButton(!this.props.isFilterVisible)} existingFilter={this.props.existingFilter} onFilterChanged={this.onFilterChanged} selectedValue={this.props.currentView} showFilter={this.props.isFilterVisible} onChange={this.props.setSubView}>
           {lineChart(chartPagedData)}
-          <PerformanceDataTable stickyHeader idProperty={"_id"} columns={performanceColumns} {...properties} {...actions} />
+          <PerformanceDataTable stickyHeader idProperty={"_id"} tableId="perfromance-data-table" columns={performanceColumns} {...properties} {...actions} />
         </ToggleContainer>
       </>
     );
index 720fb94..8dc92b8 100644 (file)
@@ -92,7 +92,7 @@ class ReceiveLevelComponent extends React.Component<ReceiveLevelComponentProps>{
       <>
         <ToggleContainer onToggleFilterButton={this.onToggleFilterButton} showFilter={this.props.isFilterVisible} existingFilter={this.props.receiveLevelProperties.filter} onFilterChanged={this.onFilterChanged} selectedValue={this.props.currentView} onChange={this.onChange}>
           {lineChart(chartPagedData)}
-          <ReceiveLevelTable stickyHeader idProperty={"_id"} columns={receiveLevelColumns} {...properties} {...actions} />
+          <ReceiveLevelTable stickyHeader idProperty={"_id"} tableId="receive-level-table" columns={receiveLevelColumns} {...properties} {...actions} />
         </ToggleContainer>
       </>
     );
index 4b34019..ee7fe34 100644 (file)
@@ -91,7 +91,7 @@ class SignalToInterferenceComponent extends React.Component<SignalToInterference
       <>
         <ToggleContainer onToggleFilterButton={this.onToggleFilterButton} showFilter={this.props.isFilterVisible} existingFilter={this.props.signalToInterferenceProperties.filter} onFilterChanged={this.onFilterChanged} selectedValue={this.props.currentView} onChange={this.onChange}>
           {lineChart(chartPagedData)}
-          <SignalToInterferenceTable stickyHeader idProperty={"_id"} columns={sinrColumns} {...properties} {...actions}
+          <SignalToInterferenceTable stickyHeader idProperty={"_id"} tableId="signal-to-interference-table" columns={sinrColumns} {...properties} {...actions}
           />
         </ToggleContainer>
       </>
index 2484a8c..31e1d36 100644 (file)
@@ -93,7 +93,7 @@ class TemperatureComponent extends React.Component<TemperatureComponentProps>{
 
         <ToggleContainer onToggleFilterButton={this.onToggleFilterButton} showFilter={this.props.isFilterVisible} existingFilter={this.props.temperatureProperties.filter} onFilterChanged={this.onFilterChanged} selectedValue={this.props.currentView} onChange={this.onChange}>
           {lineChart(chartPagedData)}
-          <TemperatureTable stickyHeader idProperty={"_id"} columns={temperatureColumns} {...properties} {...actions} />
+          <TemperatureTable stickyHeader idProperty={"_id"} tableId="temperature-table" columns={temperatureColumns} {...properties} {...actions} />
         </ToggleContainer>
       </>
     );
index e44ffe0..97a35da 100644 (file)
@@ -94,7 +94,7 @@ class TransmissionPowerComponent extends React.Component<TransmissionPowerCompon
       <>
         <ToggleContainer onChange={this.onChange} onToggleFilterButton={this.onToggleFilterButton} showFilter={this.props.isFilterVisible} existingFilter={this.props.transmissionPowerProperties.filter} onFilterChanged={this.onFilterChanged} selectedValue={this.props.currentView} >
           {lineChart(chartPagedData)}
-          <TransmissionPowerTable stickyHeader idProperty={"_id"} columns={transmissionColumns} {...properties} {...actions} />
+          <TransmissionPowerTable stickyHeader idProperty={"_id"} tableId="transmission-power-table" columns={transmissionColumns} {...properties} {...actions} />
         </ToggleContainer>
       </>
     );
index f19058c..a0df93f 100644 (file)
@@ -223,7 +223,7 @@ class PerformanceHistoryComponent extends React.Component<PerformanceHistoryComp
     if (nodeId === "") {
       return (
         <>
-          <NetworkElementTable defaultSortColumn={"nodeId"} defaultSortOrder="asc" stickyHeader title={"Please select the network element!"} idProperty={"nodeId"} rows={this.props.networkElements} asynchronus
+          <NetworkElementTable tableId="performance-data-element-selection-table" defaultSortColumn={"nodeId"} defaultSortOrder="asc" stickyHeader title={"Please select the network element!"} idProperty={"nodeId"} rows={this.props.networkElements} asynchronus
             onHandleClick={(event, rowData) => { this.handleNetworkElementSelect(rowData.nodeId) }} columns={
               [{ property: "nodeId", title: "Node Name" }]
             } />
@@ -245,14 +245,14 @@ class PerformanceHistoryComponent extends React.Component<PerformanceHistoryComp
             <>
 
               <AppBar position="static" >
-                <Tabs value={activePanel} onChange={this.onChangeTabs} variant="scrollable" scrollButtons="auto" aria-label="performance data tabs">
-                  <Tab label="Performance Data" value="PerformanceData" />
-                  <Tab label="Receive Level" value="ReceiveLevel" />
-                  <Tab label="Transmission Power" value="TransmissionPower" />
-                  <Tab label="Adaptive Modulation" value="AdaptiveModulation" />
-                  <Tab label="Temperature" value="Temperature" />
-                  <Tab label="Signal-to-interference-plus-noise ratio (SINR)" value="SINR" />
-                  <Tab label="Cross Polar Discrimination" value="CPD" />
+                <Tabs value={activePanel} onChange={this.onChangeTabs} variant="scrollable" scrollButtons="auto" aria-label="performance-data-tabs">
+                  <Tab label="Performance Data" value="PerformanceData" aria-label="performance-data" />
+                  <Tab label="Receive Level" value="ReceiveLevel" aria-label="receive-level" />
+                  <Tab label="Transmission Power" value="TransmissionPower" aria-label="transmission-power" />
+                  <Tab label="Adaptive Modulation" value="AdaptiveModulation" aria-label="adaptive-modulation" />
+                  <Tab label="Temperature" value="Temperature" aria-label="temperature"  />
+                  <Tab label="Signal-to-interference-plus-noise ratio (SINR)" value="SINR" aria-label="snir" />
+                  <Tab label="Cross Polar Discrimination" value="CPD" aria-label="cross-polar-discrimination" />
                 </Tabs>
               </AppBar>
               {
index 85b0dfb..791f46d 100644 (file)
  * the License.\r
  * ============LICENSE_END==========================================================================\r
  */\r
-/******************************************************************************\r
- * Copyright 2018 highstreet technologies GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- *****************************************************************************/\r
 \r
 import * as React from 'react';\r
 import * as ReactDOM from 'react-dom';\r
index c5be819..f6d0b0d 100644 (file)
@@ -118,7 +118,7 @@ type MaterialTableComponentBaseProps<TData> = WithStyles<typeof styles> & {
   disableFilter?: boolean;
   customActionButtons?: { icon: React.ComponentType<SvgIconProps>, tooltip?: string, onClick: () => void }[];
   onHandleClick?(event: React.MouseEvent<HTMLTableRowElement>, rowData: TData): void;
-  createContextMenu?: (row: TData) => React.ReactElement<MenuItemProps | DividerTypeMap<{}, "hr">, React.ComponentType<MenuItemProps | DividerTypeMap<{}, "hr" >>>[];
+  createContextMenu?: (row: TData) => React.ReactElement<MenuItemProps | DividerTypeMap<{}, "hr">, React.ComponentType<MenuItemProps | DividerTypeMap<{}, "hr">>>[];
 };
 
 type MaterialTableComponentPropsWithRows<TData = {}> = MaterialTableComponentBaseProps<TData> & { rows: TData[]; asynchronus?: boolean; };
@@ -162,7 +162,7 @@ class MaterialTableComponent<TData extends {} = {}> extends React.Component<Mate
     const rowsPerPage = isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.rowsPerPage || 10 : 10;
 
     this.state = {
-      contextMenuInfo: {index : -1 },
+      contextMenuInfo: { index: -1 },
       filter: isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.filter || {} : {},
       showFilter: isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.showFilter : false,
       loading: isMaterialTableComponentPropsWithRowsAndRequestData(this.props) ? this.props.loading : false,
@@ -234,7 +234,7 @@ class MaterialTableComponent<TData extends {} = {}> extends React.Component<Mate
                       }}
                       role="checkbox"
                       aria-checked={isSelected}
-                      aria-label={`${(this.props.tableId ? this.props.tableId : 'table')}-row`}
+                      aria-label="table-row"
                       tabIndex={-1}
                       key={entryId}
                       selected={isSelected}
@@ -250,7 +250,7 @@ class MaterialTableComponent<TData extends {} = {}> extends React.Component<Mate
                           col => {
                             const style = col.width ? { width: col.width } : {};
                             return (
-                              <TableCell key={col.property} align={col.type === ColumnType.numeric && !col.align ? "right" : col.align} style={style}>
+                              <TableCell aria-label={col.title? col.title.toLowerCase().replace(/\s/g, "-") : col.property.toLowerCase().replace(/\s/g, "-")} key={col.property} align={col.type === ColumnType.numeric && !col.align ? "right" : col.align} style={style}>
                                 {col.type === ColumnType.custom && col.customControl
                                   ? <col.customControl className={col.className} style={col.style} rowData={entry} />
                                   : col.type === ColumnType.boolean
@@ -283,6 +283,7 @@ class MaterialTableComponent<TData extends {} = {}> extends React.Component<Mate
           count={rowCount}
           rowsPerPage={rowsPerPage}
           page={page}
+          aria-label="table-pagination-footer"
           backIconButtonProps={{
             'aria-label': 'previous-page',
           }}
index 76f778e..5aefac4 100644 (file)
@@ -73,14 +73,14 @@ class EnhancedTableFilterComponent extends React.Component<IEnhancedTableFilterC
               {col.disableFilter || (col.type === ColumnType.custom)
                 ? null
                 : (col.type === ColumnType.boolean)
-                  ? <Select className={classes.input} aria-label={col.title ? (col.title as string).toLowerCase() + ' filter' : `${ind + 1}-filter`} value={filter[col.property] !== undefined ? filter[col.property] : ''} onChange={this.createFilterHandler(col.property)} inputProps={{ name: `${col.property}-bool`, id: `${col.property}-bool` }} >
+                  ? <Select className={classes.input} aria-label={col.title ? (col.title as string).toLowerCase().replace(/\s/g, "-") + '-filter' : `${ind + 1}-filter`} value={filter[col.property] !== undefined ? filter[col.property] : ''} onChange={this.createFilterHandler(col.property)} inputProps={{ name: `${col.property}-bool`, id: `${col.property}-bool` }} >
                     <MenuItem value={undefined} aria-label="none-value" >
                       <em>None</em>
                     </MenuItem>
                     <MenuItem aria-label="true-value" value={true as any as string}>{col.labels ? col.labels["true"] : "true"}</MenuItem>
                     <MenuItem aria-label="false-value" value={false as any as string}>{col.labels ? col.labels["false"] : "false"}</MenuItem>
                   </Select>
-                  : <Input className={classes.input} inputProps={{ 'aria-label': col.title ? (col.title as string).toLowerCase() + ' filter' : `${ind + 1}-filter` }} value={filter[col.property] || ''} onChange={this.createFilterHandler(col.property)} />}
+                  : <Input className={classes.input} inputProps={{ 'aria-label': col.title ? (col.title as string).toLowerCase().replace(/\s/g, "-") + '-filter' : `${ind + 1}-filter` }} value={filter[col.property] || ''} onChange={this.createFilterHandler(col.property)} />}
             </TableCell>
           );
         }, this)}
index 59dc49c..96bcbf3 100644 (file)
@@ -130,6 +130,7 @@ class TableToolbarComponent extends React.Component<ITableToolbarComponentProps,
             )}
           <Tooltip title="Actions">
             <IconButton color="inherit"
+            aria-label={buttonPrefix +"additional-actions-button"}
               aria-owns={open ? 'menu-appbar' : undefined}
               aria-haspopup="true"
               onClick={this.handleMenu} >
@@ -138,7 +139,7 @@ class TableToolbarComponent extends React.Component<ITableToolbarComponentProps,
           </Tooltip>
           <Menu id="menu-appbar" anchorEl={this.state.anchorEl} anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
             transformOrigin={{ vertical: 'top', horizontal: 'right' }} open={open} onClose={this.handleClose} >
-            <MenuItem onClick={this.props.onExportToCsv}>Export as CSV</MenuItem>
+            <MenuItem aria-label="export-table-as-csv" onClick={(e) =>{ this.props.onExportToCsv(); this.handleClose()}}>Export as CSV</MenuItem>
           </Menu>
         </div>
       </Toolbar>
index adf0b8e..e62b424 100644 (file)
@@ -18,7 +18,7 @@
 import * as React from 'react';
 import { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles';
 
-import { List, ListItem, TextField, ListItemText, ListItemIcon, WithTheme, withTheme, Omit } from '@material-ui/core';
+import { List, ListItem, TextField, ListItemText, ListItemIcon, WithTheme, withTheme, Omit, Typography } from '@material-ui/core';
 
 import { SvgIconProps } from '@material-ui/core/SvgIcon';
 import FileIcon from '@material-ui/icons/InsertDriveFile';
@@ -62,7 +62,7 @@ type TreeViewComponentState<TData = { }> = {
   expandedItems: ExternalTreeItem<TData>[];
   /** The index of the active iten or undefined if no item is active. */
   activeItem?: ExternalTreeItem<TData>;
-  /** The search term or undefined if search is corrently not active. */
+  /** The search term or undefined if search is currently not active. */
   searchTerm?: string;
   searchTermValue?: string;
 }
@@ -153,7 +153,8 @@ class TreeViewComponent<TData = { }> extends React.Component<TreeViewComponentPr
     return (
       <div className={this.props.className ? `${this.props.classes.root} ${this.props.className}` : this.props.classes.root} style={this.props.style}>
         {children}
-        {enableSearchBar && <TextField label={"Search"} fullWidth={true} className={this.props.classes.search} value={searchTermValue} onKeyDown={this.onSearchKeyDown} onChange={this.onChangeSearchText} /> || null}
+        {enableSearchBar && <TextField label={"Search"} inputProps={{'aria-label': 'treeview-searchfield'}} fullWidth={true} className={this.props.classes.search} value={searchTermValue} onKeyDown={this.onSearchKeyDown} onChange={this.onChangeSearchText} /> || null}
+        {enableSearchBar && (searchTerm === undefined || searchTerm.length===0 )&& <Typography style={{marginTop:'10px'}}>Please search for an inventory identifier or use *.</Typography>}
         <List>
           {this.renderItems(items, searchTerm && searchTerm.toLowerCase())}
         </List>
@@ -216,7 +217,7 @@ class TreeViewComponent<TData = { }> extends React.Component<TreeViewComponentPr
 
     return ((searchTerm && (matchIndex > -1 || expanded || (!isTreeViewComponentWithExternalStateProps(this.props) && item.isMatch || depth === 1)) || !searchTerm || forceRender)
       ? (
-        <ListItem key={`tree-list-${this.itemIndex++}`} style={styles.item} onClick={handleClickCreator(false)} button >
+        <ListItem key={`tree-list-${this.itemIndex++}`} aria-label="tree-view-item" style={styles.item} onClick={handleClickCreator(false)} button >
 
           { // display the left icon
             (this.props.useFolderIcons && <ListItemIcon>{isFolder ? <FolderIcon /> : <FileIcon />}</ListItemIcon>) ||
index d449f5c..d2de7cc 100644 (file)
@@ -70,20 +70,50 @@ const useSimpleTableStyles = makeStyles({
     color: "white",
     padding: "5px",
     backgroundColor: "#cccccc",
+
   },
   td: {
     verticalAlign: "top",
     padding: "0.5rem 1rem",
-    borderBottom: "2px solid #DDD"
+    border: "2px solid #DDD"
   },
   object: {
   },
   objectTh: {
-    backgroundColor: "#4444cc",
+    backgroundColor: "#cccccc",
   },
   objectTd: {
     padding: "0.5rem 1rem",
-    borderBottom: "2px solid #DDD"
+    border: "2px solid #DDD"
+  },
+  chevron: {
+    '&:before': {
+      borderStyle: 'solid',
+      borderWidth: '0.25em 0.25em 0 0',
+      content: '\'\'',
+      display: 'inline-block',
+      height: '0.45em',
+      left: '0.15em',
+      position: 'relative',
+      top: '0.15em',
+      transform: 'rotate(-45deg)',
+      transition: 'all 0.3s',
+      verticalAlign: 'top',
+      width: '0.45em',
+    }
+
+  },
+    right: {
+    '&:before': {
+      left: '0',
+      transform: 'rotate(45deg)',
+    }
+  },
+  bottom: {
+    '&:before': {
+      left: '0',
+      transform: 'rotate(135deg)',
+    }
   },
 });
 
@@ -93,6 +123,7 @@ type SimpleTableProps = {
   label?: JSX.Element | string | null;
   cols?: number;
   expand?: boolean;
+  ariaLabel?: string;
 }
 
 const SimpleTable: React.FC<SimpleTableProps> = (props) => {
@@ -110,11 +141,11 @@ const SimpleTable: React.FC<SimpleTableProps> = (props) => {
   };
 
   return (
-    <table className={`${classes.root} ${classes.table}`}>
+    <table className={`${classes.root} ${classes.table}`} aria-label={props.ariaLabel? props.ariaLabel+'-table' : 'table'}>
       {label && (<thead>
-        <tr>
+        <tr aria-label={props.ariaLabel? props.ariaLabel+'-title-row' : 'title row'}>
           <th className={`${classes.th} ${classes.label} ${classNameTh ? classNameTh : ''}`} colSpan={cols} onClick={handleClick}>
-            {label}
+            <span className={`${classes.chevron} ${isExpanded ? classes.bottom : classes.right }`}></span> { label }
           </th>
         </tr>
       </thead>) || null
@@ -130,6 +161,7 @@ type ObjectRendererProps = {
   label?: JSX.Element | string | null;
   expand?: boolean;
   object: { [key: string]: any };
+  ariaLabel?: string;
 };
 
 const ObjectRenderer: React.FC<ObjectRendererProps> = (props) => {
@@ -137,13 +169,13 @@ const ObjectRenderer: React.FC<ObjectRendererProps> = (props) => {
   const classes = useSimpleTableStyles();
 
   return (
-    <SimpleTable classNameTh={classes.objectTh} label={getTypeName(object) || label} expand={expand}>
+    <SimpleTable ariaLabel={props.ariaLabel} classNameTh={classes.objectTh} label={getTypeName(object) || label} expand={expand}>
       {
         Object.keys(object).map(key => {
           return (
-            <tr key={String(key)}>
-              <td className={`${classes.td} ${classes.objectTd}`}>{String(key)} </td>
-              <td className={`${classes.td}`}>{renderObject(object[key])}</td>
+            <tr key={String(key)} aria-label={props.ariaLabel? props.ariaLabel+'-row': 'row'}>
+              <td className={`${classes.td} ${classes.objectTd}`} aria-label="object-title">{String(key)} </td>
+              <td className={`${classes.td}`} aria-label="object-details">{renderObject(object[key], "sub-element")}</td>
             </tr>
           );
         })
@@ -165,9 +197,9 @@ const ArrayRenderer: React.FC<ArrayRendererProps> = (props) => {
   return null;
 };
 
-export const renderObject = (object: any): JSX.Element | string => {
+export const renderObject = (object: any, ariaLabel?: string): JSX.Element | string => {
   if (isString(object) || isNumber(object) || isBoolean(object)) {
     return String(object);
   }
-  return <ObjectRenderer object={object} />;
+  return <ObjectRenderer object={object} ariaLabel={ariaLabel} />;
 };