2 * ============LICENSE_START========================================================================
3 * ONAP : ccsdk feature sdnr wt odlux
4 * =================================================================================================
5 * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
6 * =================================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8 * in compliance with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software distributed under the License
13 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14 * or implied. See the License for the specific language governing permissions and limitations under
16 * ============LICENSE_END==========================================================================
19 import * as React from "react";
20 import makeStyles from '@mui/styles/makeStyles';
22 export const getTypeName = (obj: any): string => {
24 return obj === undefined ? "Undefined" : "Null";
26 return Object.prototype.toString.call(obj).slice(8, -1);
29 const isObjectLike = (obj: any) => {
30 return typeof obj === "object" && obj !== null;
33 const isBoolean = (obj: any) => {
34 return obj === true || obj === false ||
35 (isObjectLike(obj) && getTypeName(obj) === "Boolean");
38 const isNumber = (obj: any) => {
39 return typeof obj === "number" ||
40 (isObjectLike(obj) && getTypeName(obj) === "Number");
43 const isString = (obj: any) => {
44 return typeof obj === "string" ||
45 (isObjectLike(obj) && getTypeName(obj) === "String");
48 const isNull = (obj: any) => {
52 const isDate = (obj: any): boolean => {
53 return isObjectLike(obj) && (obj instanceof Date);
56 const useSimpleTableStyles = makeStyles({
60 fontFamily: "verdana, arial, helvetica, sans-serif",
62 borderCollapse: "separate",
72 backgroundColor: "#cccccc",
77 padding: "0.5rem 1rem",
78 border: "2px solid #DDD"
83 backgroundColor: "#cccccc",
86 padding: "0.5rem 1rem",
87 border: "2px solid #DDD"
92 borderWidth: '0.25em 0.25em 0 0',
94 display: 'inline-block',
99 transform: 'rotate(-45deg)',
100 transition: 'all 0.3s',
101 verticalAlign: 'top',
109 transform: 'rotate(45deg)',
115 transform: 'rotate(135deg)',
121 type SimpleTableProps = {
122 classNameTh?: string;
123 label?: JSX.Element | string | null;
129 const SimpleTable: React.FC<SimpleTableProps> = (props) => {
130 const { label = '', cols = 2, expand = true, classNameTh, children } = props;
131 const [isExpanded, setIsExpanded] = React.useState(expand);
133 const classes = useSimpleTableStyles();
135 React.useEffect(() => {
136 setIsExpanded(expand);
139 const handleClick = () => {
140 setIsExpanded(!isExpanded);
144 <table className={`${classes.root} ${classes.table}`} aria-label={props.ariaLabel? props.ariaLabel+'-table' : 'table'}>
146 <tr aria-label={props.ariaLabel? props.ariaLabel+'-title-row' : 'title row'}>
147 <th className={`${classes.th} ${classes.label} ${classNameTh ? classNameTh : ''}`} colSpan={cols} onClick={handleClick}>
148 <span className={`${classes.chevron} ${isExpanded ? classes.bottom : classes.right }`}></span> { label }
153 {isExpanded && <tbody >{children}</tbody> || null}
159 type ObjectRendererProps = {
161 label?: JSX.Element | string | null;
163 object: { [key: string]: any };
167 const ObjectRenderer: React.FC<ObjectRendererProps> = (props) => {
168 const { object, className, label = 'Object', expand = true } = props;
169 const classes = useSimpleTableStyles();
172 <SimpleTable ariaLabel={props.ariaLabel} classNameTh={classes.objectTh} label={getTypeName(object) || label} expand={expand}>
174 Object.keys(object).map(key => {
176 <tr key={String(key)} aria-label={props.ariaLabel? props.ariaLabel+'-row': 'row'}>
177 <td className={`${classes.td} ${classes.objectTd}`} aria-label="object-title">{String(key)} </td>
178 <td className={`${classes.td}`} aria-label="object-details">{renderObject(object[key], "sub-element")}</td>
188 type ArrayRendererProps = {
189 label?: JSX.Element | string | null;
190 extraRenderer?: { [label: string]: React.ComponentType<{ label?: JSX.Element | string | null; object: any; }> };
191 description?: string;
195 const ArrayRenderer: React.FC<ArrayRendererProps> = (props) => {
200 export const renderObject = (object: any, ariaLabel?: string): JSX.Element | string => {
201 if (isString(object) || isNumber(object) || isBoolean(object)) {
202 return String(object);
204 return <ObjectRenderer object={object} ariaLabel={ariaLabel} />;