diff --git a/packages/zapp/console/package.json b/packages/zapp/console/package.json
index fa1706344..aea34695a 100644
--- a/packages/zapp/console/package.json
+++ b/packages/zapp/console/package.json
@@ -48,6 +48,7 @@
"react-chartjs-2": "^4.0.0",
"react-flow-renderer": "10.1.1",
"react-ga4": "^1.4.1",
+ "react-json-view": "^1.21.3",
"react-transition-group": "^2.3.1",
"serve-static": "^1.12.3",
"tslib": "^1.9.0"
diff --git a/packages/zapp/console/src/components/Literals/DeprecatedLiteralMapViewer.tsx b/packages/zapp/console/src/components/Literals/DeprecatedLiteralMapViewer.tsx
new file mode 100644
index 000000000..f8ec614bb
--- /dev/null
+++ b/packages/zapp/console/src/components/Literals/DeprecatedLiteralMapViewer.tsx
@@ -0,0 +1,50 @@
+import classnames from 'classnames';
+import { sortedObjectEntries } from 'common/utils';
+import { useCommonStyles } from 'components/common/styles';
+import { Literal, LiteralMap } from 'models/Common/types';
+import * as React from 'react';
+import { htmlEntities } from './constants';
+import { LiteralValue } from './LiteralValue';
+import { NoneTypeValue } from './Scalar/NoneTypeValue';
+
+export const NoDataIsAvailable = () => {
+ return (
+
+ No data is available.
+
+ );
+};
+
+/** Renders a LiteralMap as a formatted object */
+export const DeprecatedLiteralMapViewer: React.FC<{
+ className?: string;
+ map: LiteralMap | null;
+ showBrackets?: boolean;
+}> = ({ className, map, showBrackets = false }) => {
+ if (!map) {
+ return ;
+ }
+
+ const commonStyles = useCommonStyles();
+ const { literals } = map;
+ const mapContent = Object.keys(literals).length ? (
+
+ {sortedObjectEntries(literals).map(([key, value]) => (
+ -
+
+
+ ))}
+
+ ) : (
+
+
+
+ );
+ return (
+ <>
+ {showBrackets && {htmlEntities.leftCurlyBrace}}
+ {mapContent}
+ {showBrackets && {htmlEntities.rightCurlyBrace}}
+ >
+ );
+};
diff --git a/packages/zapp/console/src/components/Literals/LiteralMapViewer.tsx b/packages/zapp/console/src/components/Literals/LiteralMapViewer.tsx
index 5e594c635..77be18da2 100644
--- a/packages/zapp/console/src/components/Literals/LiteralMapViewer.tsx
+++ b/packages/zapp/console/src/components/Literals/LiteralMapViewer.tsx
@@ -1,10 +1,7 @@
-import classnames from 'classnames';
-import { sortedObjectEntries } from 'common/utils';
-import { useCommonStyles } from 'components/common/styles';
-import { Literal, LiteralMap } from 'models/Common/types';
+import { ReactJsonViewWrapper } from 'components/common/ReactJsonView';
+import { LiteralMap } from 'models/Common/types';
import * as React from 'react';
-import { htmlEntities } from './constants';
-import { LiteralValue } from './LiteralValue';
+import { transformLiterals } from './helpers';
import { NoneTypeValue } from './Scalar/NoneTypeValue';
export const NoDataIsAvailable = () => {
@@ -20,31 +17,18 @@ export const LiteralMapViewer: React.FC<{
className?: string;
map: LiteralMap | null;
showBrackets?: boolean;
-}> = ({ className, map, showBrackets = false }) => {
+}> = ({ map }) => {
if (!map) {
return ;
}
- const commonStyles = useCommonStyles();
const { literals } = map;
- const mapContent = Object.keys(literals).length ? (
-
- {sortedObjectEntries(literals).map(([key, value]) => (
- -
-
-
- ))}
-
- ) : (
-
-
-
- );
- return (
- <>
- {showBrackets && {htmlEntities.leftCurlyBrace}}
- {mapContent}
- {showBrackets && {htmlEntities.rightCurlyBrace}}
- >
- );
+
+ if (!Object.keys(literals).length) {
+ return ;
+ }
+
+ const transformedLiterals = transformLiterals(literals);
+
+ return ;
};
diff --git a/packages/zapp/console/src/components/Literals/LiteralValue.tsx b/packages/zapp/console/src/components/Literals/LiteralValue.tsx
index 302db910e..e4e4756b9 100644
--- a/packages/zapp/console/src/components/Literals/LiteralValue.tsx
+++ b/packages/zapp/console/src/components/Literals/LiteralValue.tsx
@@ -1,7 +1,7 @@
import { Literal, LiteralCollection, LiteralMap, Scalar } from 'models/Common/types';
import * as React from 'react';
import { LiteralCollectionViewer } from './LiteralCollectionViewer';
-import { LiteralMapViewer } from './LiteralMapViewer';
+import { DeprecatedLiteralMapViewer } from './DeprecatedLiteralMapViewer';
import { ScalarValue } from './Scalar/ScalarValue';
import { useLiteralStyles } from './styles';
import { UnsupportedType } from './UnsupportedType';
@@ -27,7 +27,7 @@ export const LiteralValue: React.FC<{
return (
<>
- ;
+ const map = { literals: { [label]: { collection, value: 'collection' } } };
+ return (
+ <>
+
+
+ OLD
+
+
+
+
+
+
+
+ NEW
+
+
+
+
+
+
+
+ >
+ );
}
stories.add('Binary', () =>
diff --git a/packages/zapp/console/src/components/Literals/__stories__/Map.stories.tsx b/packages/zapp/console/src/components/Literals/__stories__/Map.stories.tsx
index 4a4b49cdb..6336fa8e0 100644
--- a/packages/zapp/console/src/components/Literals/__stories__/Map.stories.tsx
+++ b/packages/zapp/console/src/components/Literals/__stories__/Map.stories.tsx
@@ -1,8 +1,7 @@
import { storiesOf } from '@storybook/react';
import { LiteralMap } from 'models/Common/types';
import * as React from 'react';
-import { LiteralValue } from '../LiteralValue';
-import { CardDecorator } from './CardDecorator';
+import { Card, CardContent } from '@material-ui/core';
import {
binaryLiterals,
blobLiterals,
@@ -11,12 +10,35 @@ import {
primitiveLiterals,
schemaLiterals,
} from './literalValues';
+import { LiteralMapViewer } from '../LiteralMapViewer';
+import { DeprecatedLiteralMapViewer } from '../DeprecatedLiteralMapViewer';
const stories = storiesOf('Literals/Map', module);
-stories.addDecorator(CardDecorator);
function renderMap(label: string, map: LiteralMap) {
- return ;
+ const fullMap = { literals: { [label]: { map, value: 'map' } } };
+ return (
+ <>
+
+
+ OLD
+
+
+
+
+
+
+
+ NEW
+
+
+
+
+
+
+
+ >
+ );
}
stories.add('Binary', () =>
diff --git a/packages/zapp/console/src/components/Literals/__stories__/ProtobufStruct.stories.tsx b/packages/zapp/console/src/components/Literals/__stories__/ProtobufStruct.stories.tsx
index 8781df62d..cc84b8386 100644
--- a/packages/zapp/console/src/components/Literals/__stories__/ProtobufStruct.stories.tsx
+++ b/packages/zapp/console/src/components/Literals/__stories__/ProtobufStruct.stories.tsx
@@ -1,23 +1,41 @@
import { storiesOf } from '@storybook/react';
import { ProtobufListValue, ProtobufStruct } from 'models/Common/types';
import * as React from 'react';
-import { LiteralValue } from '../LiteralValue';
-import { CardDecorator } from './CardDecorator';
+import { Card, CardContent } from '@material-ui/core';
import { protobufValues } from './protobufValues';
+import { LiteralMapViewer } from '../LiteralMapViewer';
+
+import { DeprecatedLiteralMapViewer } from '../DeprecatedLiteralMapViewer';
const stories = storiesOf('Literals/ProtobufStruct', module);
-stories.addDecorator(CardDecorator);
function renderStruct(label: string, struct: ProtobufStruct) {
+ const map = {
+ literals: {
+ [label]: { scalar: { value: 'generic', generic: struct }, value: 'scalar' },
+ },
+ };
return (
-
+ <>
+
+
+ OLD
+
+
+
+
+
+
+
+ NEW
+
+
+
+
+
+
+
+ >
);
}
@@ -30,7 +48,6 @@ stories.add('list', () =>
kind: 'listValue',
listValue: {
values: [
- ...Object.values(protobufValues),
{
kind: 'structValue',
structValue: { fields: protobufValues },
diff --git a/packages/zapp/console/src/components/Literals/__stories__/Scalar.stories.tsx b/packages/zapp/console/src/components/Literals/__stories__/Scalar.stories.tsx
index f79996aea..051658e55 100644
--- a/packages/zapp/console/src/components/Literals/__stories__/Scalar.stories.tsx
+++ b/packages/zapp/console/src/components/Literals/__stories__/Scalar.stories.tsx
@@ -1,8 +1,8 @@
import { storiesOf } from '@storybook/react';
import { Scalar } from 'models/Common/types';
import * as React from 'react';
-import { ScalarValue } from '../Scalar/ScalarValue';
-import { CardDecorator } from './CardDecorator';
+import { Card, CardContent } from '@material-ui/core';
+import { LiteralMapViewer } from '../LiteralMapViewer';
import {
binaryScalars,
blobScalars,
@@ -11,22 +11,45 @@ import {
primitiveScalars,
schemaScalars,
} from './scalarValues';
+import { DeprecatedLiteralMapViewer } from '../DeprecatedLiteralMapViewer';
const stories = storiesOf('Literals/Scalar', module);
-stories.addDecorator(CardDecorator);
-const renderScalars = (scalars: Dictionary) =>
+var renderScalars = (scalars: Dictionary) => {
+ const literals = {};
+
Object.entries(scalars).map(([label, value]) => {
- return ;
+ literals[label] = { scalar: value, value: 'scalar' };
});
+ const map = { literals };
+ return (
+ <>
+
+
+ OLD
+
+
+
+
+
+
+
+ NEW
+
+
+
+
+
+
+
+ >
+ );
+};
+
stories.add('Binary', () => <>{renderScalars(binaryScalars)}>);
stories.add('Blob', () => <>{renderScalars(blobScalars)}>);
stories.add('Error', () => <>{renderScalars(errorScalars)}>);
-stories.add('NoneType', () => (
- <>
-
- >
-));
+stories.add('NoneType', () => <>{renderScalars([noneTypeScalar])}>);
stories.add('Primitive', () => <>{renderScalars(primitiveScalars)}>);
stories.add('Schema', () => <>{renderScalars(schemaScalars)}>);
diff --git a/packages/zapp/console/src/components/Literals/__stories__/StructuredDataSet.stories.tsx b/packages/zapp/console/src/components/Literals/__stories__/StructuredDataSet.stories.tsx
new file mode 100644
index 000000000..7f4d6458f
--- /dev/null
+++ b/packages/zapp/console/src/components/Literals/__stories__/StructuredDataSet.stories.tsx
@@ -0,0 +1,176 @@
+import { storiesOf } from '@storybook/react';
+import { Scalar } from 'models/Common/types';
+import { Card, CardContent } from '@material-ui/core';
+import * as React from 'react';
+import { Core } from 'flyteidl';
+import { LiteralMapViewer } from '../LiteralMapViewer';
+import { blobScalars } from './scalarValues';
+import { extractSimpleTypes, extractSchemaTypes, extractBlobTypes } from './helpers/typeGenerators';
+
+const stories = storiesOf('Literals/StructuredDataSet', module);
+
+function generateStructuredDataset(label: string, literalType: Core.ILiteralType) {
+ return {
+ literals: {
+ [label]: {
+ scalar: {
+ structuredDataset: {
+ uri: 's3://random-val',
+ metadata: {
+ structuredDatasetType: {
+ columns: [
+ {
+ name: 'age',
+ literalType,
+ },
+ ],
+ format: 'parquet',
+ },
+ },
+ },
+ value: 'structuredDataset',
+ },
+ value: 'scalar',
+ },
+ },
+ };
+}
+
+function generateSimpleTypes() {
+ const simpleTypes = extractSimpleTypes().map((simpleType) => {
+ return Object.keys(simpleType).map((key) => {
+ return generateStructuredDataset(`simple_${key}`, simpleType[key]);
+ });
+ });
+ return simpleTypes.flat();
+}
+
+function generateSchemaTypes() {
+ const schemaTypes = extractSchemaTypes();
+ const retObj = schemaTypes
+ .map((schemaType) => {
+ return Object.keys(schemaType).map((key) => {
+ const v = schemaType[key];
+ return generateStructuredDataset(`schema${key}`, v);
+ });
+ })
+ .flat();
+
+ return retObj;
+}
+
+function generateBlobTypes() {
+ return Object.keys(blobScalars).map((key) => {
+ const value = blobScalars[key]?.['blob']?.metadata?.type;
+ return generateStructuredDataset(key, {
+ type: 'blob',
+ blob: value,
+ });
+ });
+}
+
+function generateCollectionTypes() {
+ const collectionTypes = [];
+
+ const simpleTypes = extractSimpleTypes()
+ .map((simpleType) => {
+ return Object.keys(simpleType).map((key) => {
+ return generateStructuredDataset(`simple_${key}`, {
+ type: 'collectionType',
+ collectionType: simpleType[key],
+ });
+ });
+ })
+ .flat();
+ collectionTypes.push(...simpleTypes);
+
+ // blobTypes
+ const blobTypes = extractBlobTypes();
+ collectionTypes.push(
+ ...blobTypes
+ .map((value) => {
+ return Object.keys(value).map((key) => {
+ return generateStructuredDataset(key, {
+ type: 'collectionType',
+ collectionType: value[key],
+ });
+ });
+ })
+ .flat(),
+ );
+
+ return collectionTypes;
+}
+
+function generateMapValueypes() {
+ const mapValueTypes = [];
+
+ const simpleTypes = extractSimpleTypes()
+ .map((simpleType) => {
+ return Object.keys(simpleType).map((key) => {
+ return generateStructuredDataset(`simple_${key}`, {
+ type: 'mapValueType',
+ mapValueType: simpleType[key],
+ });
+ });
+ })
+ .flat();
+ mapValueTypes.push(...simpleTypes);
+
+ // blobTypes
+ const blobTypes = extractBlobTypes();
+ mapValueTypes.push(
+ ...blobTypes
+ .map((value) => {
+ return Object.keys(value).map((key) => {
+ return generateStructuredDataset(key, {
+ type: 'mapValueType',
+ mapValueType: value[key],
+ });
+ });
+ })
+ .flat(),
+ );
+
+ return mapValueTypes;
+}
+
+function generateEnumTypes() {
+ const mapValueTypes = [
+ generateStructuredDataset(`With_values`, {
+ type: 'enumType',
+ enumType: { values: ['1', '2', '3'] },
+ }),
+ generateStructuredDataset(`With_no_values`, {
+ type: 'enumType',
+ enumType: { values: [] },
+ }),
+ generateStructuredDataset(`With_null_values`, {
+ type: 'enumType',
+ enumType: { values: null },
+ }),
+ ];
+
+ return mapValueTypes;
+}
+
+const renderScalars = (scalars: Dictionary) => {
+ const items = Object.entries(scalars).map(([_label, value]) => {
+ return (
+
+
+
+
+
+ );
+ });
+
+ return {items}
;
+};
+
+stories.add('Simple types', () => <>{renderScalars(generateSimpleTypes())}>);
+stories.add('Blob Type', () => <>{renderScalars(generateBlobTypes())}>);
+stories.add('Schema types', () => <>{renderScalars(generateSchemaTypes())}>);
+stories.add('Collection Type', () => <>{renderScalars(generateCollectionTypes())}>);
+stories.add('mapValue Type', () => <>{renderScalars(generateMapValueypes())}>);
+stories.add('Enum Type', () => <>{renderScalars(generateEnumTypes())}>);
diff --git a/packages/zapp/console/src/components/Literals/__stories__/helpers/typeGenerators.ts b/packages/zapp/console/src/components/Literals/__stories__/helpers/typeGenerators.ts
new file mode 100644
index 000000000..edf237870
--- /dev/null
+++ b/packages/zapp/console/src/components/Literals/__stories__/helpers/typeGenerators.ts
@@ -0,0 +1,45 @@
+import { Core } from 'flyteidl';
+import {
+ blobScalars,
+ schemaScalars,
+} from '../scalarValues';
+
+// SIMPLE
+type GeneratedSimpleType = {
+ [key in Core.SimpleType]?: Core.LiteralType;
+};
+export function extractSimpleTypes() {
+ const simpleTypes: GeneratedSimpleType[] = Object.keys(Core.SimpleType).map((key) => ({
+ [key]: {
+ type: 'simple',
+ simple: Core.SimpleType[key],
+ },
+ }));
+ return simpleTypes;
+}
+
+// SCHEMA
+export function extractSchemaTypes() {
+ return Object.keys(schemaScalars).map((key) => {
+ const value = schemaScalars[key];
+ return {
+ [key]: {
+ type: 'schema',
+ schema: value?.schema?.type,
+ },
+ };
+ });
+}
+
+// COLLECTION TYPE
+export function extractBlobTypes() {
+ return Object.keys(blobScalars).map((key) => {
+ const value = blobScalars[key]?.['blob']?.metadata?.type;
+ return {
+ [key]: {
+ type: 'blob',
+ blob: value,
+ },
+ };
+ });
+}
diff --git a/packages/zapp/console/src/components/Literals/helpers.ts b/packages/zapp/console/src/components/Literals/helpers.ts
new file mode 100644
index 000000000..f04f6574a
--- /dev/null
+++ b/packages/zapp/console/src/components/Literals/helpers.ts
@@ -0,0 +1,390 @@
+import { formatDateUTC, protobufDurationToHMS } from 'common/formatters';
+import { timestampToDate } from 'common/utils';
+import { Core, Protobuf } from 'flyteidl';
+import * as Long from 'long';
+import { BlobDimensionality, SchemaColumnType } from 'models/Common/types';
+
+const DEFAULT_UNSUPPORTED = 'This type is not yet supported';
+
+// PRIMITIVE
+function processPrimitive(primitive?: (Core.IPrimitive & Pick) | null) {
+ if (!primitive) {
+ return 'invalid primitive';
+ }
+
+ const type = primitive.value;
+
+ switch (type) {
+ case 'datetime':
+ return formatDateUTC(timestampToDate(primitive.datetime as Protobuf.Timestamp));
+ case 'duration':
+ return protobufDurationToHMS(primitive.duration as Protobuf.Duration);
+ case 'integer': {
+ return Long.fromValue(primitive.integer as Long).toNumber();
+ }
+ case 'boolean':
+ return primitive.boolean;
+ case 'floatValue':
+ return primitive.floatValue;
+ case 'stringValue':
+ return `${primitive.stringValue}`;
+ default:
+ return 'unknown';
+ }
+}
+
+// BLOB
+const dimensionalityStrings: Record = {
+ [BlobDimensionality.SINGLE]: 'single',
+ [BlobDimensionality.MULTIPART]: 'multi-part',
+};
+
+function processBlobType(blobType?: Core.IBlobType | null) {
+ if (!blobType) {
+ return 'invalid blob type';
+ }
+
+ const formatString = blobType.format ? ` (${blobType.format})` : '';
+ const dimensionality = blobType.dimensionality;
+ const dimensionalityString =
+ dimensionality !== null && dimensionality !== undefined
+ ? dimensionalityStrings[dimensionality]
+ : '';
+ const typeString = `${dimensionalityString}${formatString}`;
+
+ return `${typeString} blob`;
+}
+
+function processBlob(blob?: Core.IBlob | null) {
+ if (!blob) {
+ return 'invalid blob';
+ }
+
+ const type = blob.metadata?.type;
+
+ return {
+ type: processBlobType(type),
+ uri: blob.uri,
+ };
+}
+
+// BINARY
+function processBinary(binary?: Core.IBinary | null) {
+ const tag = binary?.tag;
+
+ if (!tag) {
+ return 'invalid binary';
+ }
+
+ return {
+ tag: `${tag} (binary data not shown)`,
+ };
+}
+
+// SCHEMA
+export function columnTypeToString(type?: SchemaColumnType | null) {
+ switch (type) {
+ case SchemaColumnType.BOOLEAN:
+ return 'boolean';
+ case SchemaColumnType.DATETIME:
+ return 'datetime';
+ case SchemaColumnType.DURATION:
+ return 'duration';
+ case SchemaColumnType.FLOAT:
+ return 'float';
+ case SchemaColumnType.INTEGER:
+ return 'integer';
+ case SchemaColumnType.STRING:
+ return 'string';
+ default:
+ return 'unknown';
+ }
+}
+
+function processSchemaType(schemaType?: Core.ISchemaType | null, shortString = false) {
+ const columns =
+ schemaType?.columns?.length &&
+ schemaType.columns.map((column) => {
+ return shortString
+ ? `${columnTypeToString(column.type)}`
+ : `${column.name} (${columnTypeToString(column.type)})`;
+ });
+
+ return columns;
+}
+
+function processSchema(schema?: Core.ISchema | null) {
+ if (!schema) {
+ return 'invalid schema';
+ }
+
+ const uri = schema.uri;
+ const columns = processSchemaType(schema.type);
+
+ return {
+ ...(uri && { uri }),
+ ...(columns && { columns }),
+ };
+}
+
+// NONE
+/* eslint-disable @typescript-eslint/no-unused-vars */
+function processNone(none?: Core.IVoid | null) {
+ return '(empty)';
+}
+
+// TODO: FC#450 ass support for union types
+function processUnionType(union?: Core.IUnionType | null, shortString = false) {
+ return DEFAULT_UNSUPPORTED;
+}
+
+function processUnion(union: Core.IUnion) {
+ return DEFAULT_UNSUPPORTED;
+}
+/* eslint-enable @typescript-eslint/no-unused-vars */
+
+// ERROR
+function processError(error?: Core.IError | null) {
+ return {
+ error: error?.message,
+ nodeId: error?.failedNodeId,
+ };
+}
+
+function processProtobufStructValue(struct?: Protobuf.IStruct | null) {
+ if (!struct) {
+ return 'invalid generic struct value';
+ }
+
+ const fields = struct?.fields;
+ const res =
+ fields &&
+ Object.keys(fields)
+ .map((v) => {
+ return { [v]: processGenericValue(fields[v]) };
+ })
+ .reduce((acc, v) => ({ ...acc, ...v }), {});
+
+ return res;
+}
+
+function processGenericValue(value: Protobuf.IValue & Pick) {
+ const kind = value.kind;
+
+ switch (kind) {
+ case 'nullValue':
+ return '(empty)';
+ case 'listValue': {
+ const list = value.listValue;
+ return list?.values?.map((x) => processGenericValue(x));
+ }
+ case 'structValue':
+ return processProtobufStructValue(value?.structValue);
+ case 'numberValue':
+ case 'stringValue':
+ case 'boolValue':
+ return value[kind];
+ default:
+ return 'unknown';
+ }
+}
+
+function processGeneric(struct?: Protobuf.IStruct | null) {
+ if (!struct || !struct?.fields) {
+ return null;
+ }
+
+ const { fields } = struct;
+ const mapContent = Object.keys(fields)
+ .map((key) => {
+ const value = fields[key];
+ return { [key]: processGenericValue(value) };
+ })
+ .reduce((acc, v) => {
+ return { ...acc, ...v };
+ }, {});
+
+ return mapContent;
+}
+
+// SIMPLE
+export function processSimpleType(simpleType?: Core.SimpleType | null) {
+ switch (simpleType) {
+ case Core.SimpleType.NONE:
+ return 'none';
+ case Core.SimpleType.INTEGER:
+ return 'integer';
+ case Core.SimpleType.FLOAT:
+ return 'float';
+ case Core.SimpleType.STRING:
+ return 'string';
+ case Core.SimpleType.BOOLEAN:
+ return 'booleam';
+ case Core.SimpleType.DATETIME:
+ return 'datetime';
+ case Core.SimpleType.DURATION:
+ return 'duration';
+ case Core.SimpleType.BINARY:
+ return 'binary';
+ case Core.SimpleType.ERROR:
+ return 'error';
+ case Core.SimpleType.STRUCT:
+ return 'struct';
+ default:
+ return 'unknown';
+ }
+}
+
+function processEnumType(enumType?: Core.IEnumType | null) {
+ return enumType?.values || [];
+}
+
+function processLiteralType(
+ literalType?: (Core.ILiteralType & Pick) | null,
+) {
+ const type = literalType?.type;
+
+ switch (type) {
+ case 'simple':
+ return processSimpleType(literalType?.simple);
+ case 'schema':
+ return `schema (${processSchemaType(literalType?.schema, true)})`;
+ case 'collectionType':
+ return `collection of ${processLiteralType(literalType?.collectionType)}`;
+ case 'mapValueType':
+ return `map value of ${processLiteralType(literalType?.mapValueType)}`;
+ case 'blob':
+ return processBlobType(literalType?.blob);
+ case 'enumType':
+ return `enum (${processEnumType(literalType?.enumType)})`;
+ case 'structuredDatasetType':
+ return processStructuredDatasetType(literalType?.structuredDatasetType);
+ case 'unionType':
+ return processUnionType(literalType?.unionType, true);
+ default:
+ return DEFAULT_UNSUPPORTED;
+ }
+}
+
+function processStructuredDatasetType(structuredDatasetType?: Core.IStructuredDatasetType | null) {
+ if (!structuredDatasetType) {
+ return {};
+ }
+
+ const { columns, format } = structuredDatasetType;
+ const processedColumns =
+ columns?.length &&
+ columns
+ .map(({ name, literalType }) => [name, processLiteralType(literalType)])
+ .reduce((acc, v) => {
+ acc[v[0]] = v[1];
+ return acc;
+ }, []);
+
+ return {
+ ...(format && { format }),
+ ...(processedColumns && { columns: processedColumns }),
+ };
+}
+
+function processStructuredDataset(structuredDataSet?: Core.IStructuredDataset | null) {
+ if (!structuredDataSet) {
+ return DEFAULT_UNSUPPORTED;
+ }
+
+ const retJson = {} as any;
+ const { uri, metadata } = structuredDataSet;
+
+ if (uri) {
+ retJson.uri = uri;
+ }
+
+ const structuredDatasetType = processStructuredDatasetType(metadata?.structuredDatasetType);
+
+ return {
+ ...(uri && { uri }),
+ ...structuredDatasetType,
+ };
+}
+
+function processScalar(scalar?: (Core.IScalar & Pick) | null) {
+ const type = scalar?.value;
+
+ switch (type) {
+ case 'primitive':
+ return processPrimitive(scalar?.primitive);
+ case 'blob':
+ return processBlob(scalar?.blob);
+ case 'binary':
+ return processBinary(scalar?.binary);
+ case 'schema':
+ return processSchema(scalar?.schema);
+ case 'noneType':
+ return processNone(scalar?.noneType);
+ case 'error':
+ return processError(scalar?.error);
+ case 'generic':
+ return processGeneric(scalar?.generic);
+ case 'structuredDataset':
+ return processStructuredDataset(scalar?.structuredDataset);
+ case 'union':
+ return processUnion(scalar?.union as Core.IUnion);
+ default:
+ return DEFAULT_UNSUPPORTED;
+ }
+}
+
+function processCollection(collection?: Core.ILiteralCollection | null) {
+ const literals = collection?.literals;
+
+ if (!literals) {
+ return 'invalid collection';
+ }
+
+ return literals?.map((literal) => processLiteral(literal));
+}
+
+function processMap(map?: Core.ILiteralMap | null) {
+ const literals = map?.literals;
+
+ if (!literals) {
+ return 'invalid map';
+ }
+
+ return transformLiterals(literals);
+}
+
+function processLiteral(literal?: Core.ILiteral & Pick) {
+ const type = literal?.value;
+
+ if (!literal) {
+ return 'invalid literal';
+ }
+
+ switch (type) {
+ case 'scalar':
+ return processScalar(literal.scalar);
+ case 'collection':
+ return processCollection(literal.collection);
+ case 'map':
+ return processMap(literal.map);
+ default:
+ return DEFAULT_UNSUPPORTED;
+ }
+}
+
+export function transformLiterals(json: { [k: string]: Core.ILiteral }) {
+ const obj = Object.entries(json)
+ .map(([key, literal]) => ({
+ [key]: processLiteral(literal),
+ }))
+ .reduce(
+ (acc, cur) => ({
+ ...acc,
+ ...cur,
+ }),
+ {},
+ );
+
+ return obj;
+}
diff --git a/packages/zapp/console/src/components/Literals/test/helpers/genCollectionTestcase.mock.ts b/packages/zapp/console/src/components/Literals/test/helpers/genCollectionTestcase.mock.ts
new file mode 100644
index 000000000..026d64826
--- /dev/null
+++ b/packages/zapp/console/src/components/Literals/test/helpers/genCollectionTestcase.mock.ts
@@ -0,0 +1,23 @@
+import { Core } from 'flyteidl';
+import { TestCaseList } from '../types';
+import { generateBlobType, getPrimitive, getScalarLiteral } from './literalHelpers';
+
+const collection: TestCaseList = {
+ COL_WITH_SCALARTYPE_PRIMITIVE: {
+ value: {
+ ...getScalarLiteral(getPrimitive('floatValue', 2.1), 'primitive'),
+ },
+ expected: { result_var: [2.1] },
+ },
+ COL_WITH_SCALARTYPE_BLOB: {
+ value: {
+ ...getScalarLiteral(
+ generateBlobType('csv', Core.BlobType.BlobDimensionality.SINGLE, '1'),
+ 'blob',
+ ),
+ },
+ expected: { result_var: [{ type: 'single (csv) blob', uri: '1' }] },
+ },
+};
+
+export default collection;
diff --git a/packages/zapp/console/src/components/Literals/test/helpers/genMapTestCase.mock.ts b/packages/zapp/console/src/components/Literals/test/helpers/genMapTestCase.mock.ts
new file mode 100644
index 000000000..6eef945ee
--- /dev/null
+++ b/packages/zapp/console/src/components/Literals/test/helpers/genMapTestCase.mock.ts
@@ -0,0 +1,23 @@
+import { Core } from 'flyteidl';
+import { TestCaseList } from '../types';
+import { generateBlobType, getPrimitive, getScalarLiteral } from './literalHelpers';
+
+const collection: TestCaseList = {
+ COL_WITH_SCALARTYPE_PRIMITIVE: {
+ value: {
+ ...getScalarLiteral(getPrimitive('floatValue', 2.1), 'primitive'),
+ },
+ expected: { result_var: { value: 2.1 } },
+ },
+ COL_WITH_SCALARTYPE_BLOB: {
+ value: {
+ ...getScalarLiteral(
+ generateBlobType('csv', Core.BlobType.BlobDimensionality.SINGLE, '1'),
+ 'blob',
+ ),
+ },
+ expected: { result_var: { value: { type: 'single (csv) blob', uri: '1' } } },
+ },
+};
+
+export default collection;
diff --git a/packages/zapp/console/src/components/Literals/test/helpers/genScalarBinaryTestCase.mock.ts b/packages/zapp/console/src/components/Literals/test/helpers/genScalarBinaryTestCase.mock.ts
new file mode 100644
index 000000000..9804a0f11
--- /dev/null
+++ b/packages/zapp/console/src/components/Literals/test/helpers/genScalarBinaryTestCase.mock.ts
@@ -0,0 +1,15 @@
+import { Core } from 'flyteidl';
+import { TestCaseList } from '../types';
+
+const scalarBinaryTestCases: TestCaseList = {
+ WITH_VAL: {
+ value: { value: new Uint8Array(), tag: 'tag1' },
+ expected: { result_var: { tag: 'tag1 (binary data not shown)' } },
+ },
+ INT_WITH_SMALL_LOW: {
+ value: { tag: 'tag2' },
+ expected: { result_var: { tag: 'tag2 (binary data not shown)' } },
+ },
+};
+
+export default scalarBinaryTestCases;
diff --git a/packages/zapp/console/src/components/Literals/test/helpers/genScalarBlobCases.mock.ts b/packages/zapp/console/src/components/Literals/test/helpers/genScalarBlobCases.mock.ts
new file mode 100644
index 000000000..28073461f
--- /dev/null
+++ b/packages/zapp/console/src/components/Literals/test/helpers/genScalarBlobCases.mock.ts
@@ -0,0 +1,44 @@
+import { Core } from 'flyteidl';
+import { generateBlobType } from './literalHelpers';
+import { TestCaseList } from '../types';
+
+const blobTestcases: TestCaseList = {
+ single_CSV_BLOB: {
+ value: generateBlobType('csv', Core.BlobType.BlobDimensionality.SINGLE, '1'),
+ expected: {
+ result_var: {
+ type: 'single (csv) blob',
+ uri: '1',
+ },
+ },
+ },
+ multi_part_CSV_BLOB: {
+ value: generateBlobType('csv', Core.BlobType.BlobDimensionality.MULTIPART, '2'),
+ expected: {
+ result_var: {
+ type: 'multi-part (csv) blob',
+ uri: '2',
+ },
+ },
+ },
+ single_blob_BLOB: {
+ value: generateBlobType(undefined, Core.BlobType.BlobDimensionality.SINGLE, '3'),
+ expected: {
+ result_var: {
+ type: 'single blob',
+ uri: '3',
+ },
+ },
+ },
+ single_multi_part_BLOB: {
+ value: generateBlobType(undefined, Core.BlobType.BlobDimensionality.MULTIPART, '4'),
+ expected: {
+ result_var: {
+ type: 'multi-part blob',
+ uri: '4',
+ },
+ },
+ },
+};
+
+export default blobTestcases;
diff --git a/packages/zapp/console/src/components/Literals/test/helpers/genScalarErrorCase.mock.ts b/packages/zapp/console/src/components/Literals/test/helpers/genScalarErrorCase.mock.ts
new file mode 100644
index 000000000..e05e18f65
--- /dev/null
+++ b/packages/zapp/console/src/components/Literals/test/helpers/genScalarErrorCase.mock.ts
@@ -0,0 +1,38 @@
+import { Core } from 'flyteidl';
+import { TestCaseList } from '../types';
+
+const scalarErrorTestCases: TestCaseList = {
+ ERROR_FULL: {
+ value: {
+ failedNodeId: '1',
+ message: 'message 1',
+ },
+ expected: {
+ result_var: { error: 'message 1', nodeId: '1' },
+ },
+ },
+ ERROR_NO_NODE: {
+ value: {
+ message: 'message 2',
+ },
+ expected: {
+ result_var: { error: 'message 2', nodeId: undefined },
+ },
+ },
+ ERROR_NO_MESSAGE: {
+ value: {
+ failedNodeId: '3',
+ },
+ expected: {
+ result_var: { error: undefined, nodeId: '3' },
+ },
+ },
+ ERROR_EMPTY: {
+ value: {},
+ expected: {
+ result_var: { error: undefined, nodeId: undefined },
+ },
+ },
+};
+
+export default scalarErrorTestCases;
diff --git a/packages/zapp/console/src/components/Literals/test/helpers/genScalarGenericCase.mock.ts b/packages/zapp/console/src/components/Literals/test/helpers/genScalarGenericCase.mock.ts
new file mode 100644
index 000000000..3cf04eedc
--- /dev/null
+++ b/packages/zapp/console/src/components/Literals/test/helpers/genScalarGenericCase.mock.ts
@@ -0,0 +1,143 @@
+import { Protobuf } from 'flyteidl';
+import { TestCaseList } from '../types';
+import { getIValue } from './literalHelpers';
+
+const nullValueTestcases: TestCaseList = {
+ WITH_NULL_VAL: {
+ value: {
+ fields: {
+ test_field_name1: getIValue('nullValue', Protobuf.NullValue.NULL_VALUE),
+ },
+ },
+ expected: {
+ result_var: { test_field_name1: '(empty)' },
+ },
+ },
+};
+const numberValueTestCases: TestCaseList = {
+ WITH_NUMBER_VAL: {
+ value: {
+ fields: {
+ test_field_name2: getIValue('numberValue', 1),
+ },
+ },
+ expected: {
+ result_var: { test_field_name2: 1 },
+ },
+ },
+ WITH_NUMBER_VAL_NULL: {
+ value: {
+ fields: {
+ test_field_name3: getIValue('numberValue', null),
+ },
+ },
+ expected: {
+ result_var: { test_field_name3: null },
+ },
+ },
+};
+const stringValueTestCases: TestCaseList = {
+ WITH_STRING_VAL: {
+ value: {
+ fields: {
+ test_field_name4: getIValue('stringValue', 'test val'),
+ },
+ },
+ expected: {
+ result_var: { test_field_name4: 'test val' },
+ },
+ },
+ WITH_STRING_VAL_NULL: {
+ value: {
+ fields: {
+ test_field_name: getIValue('stringValue', null),
+ },
+ },
+ expected: {
+ result_var: { test_field_name: null },
+ },
+ },
+};
+
+const boolValueTestCases: TestCaseList = {
+ WITH_BOOL_VAL: {
+ value: {
+ fields: {
+ test_field_name: getIValue('boolValue', true),
+ },
+ },
+ expected: {
+ result_var: { test_field_name: true },
+ },
+ },
+ WITH_BOOL_VAL_FALSE: {
+ value: {
+ fields: {
+ test_field_name: getIValue('boolValue', false),
+ },
+ },
+ expected: {
+ result_var: { test_field_name: false },
+ },
+ },
+ WITH_BOOL_VAL_NULL: {
+ value: {
+ fields: {
+ test_field_name: getIValue('boolValue', null),
+ },
+ },
+ expected: {
+ result_var: { test_field_name: null },
+ },
+ },
+};
+
+const structValueTestCases: TestCaseList = {
+ WITH_STRUCT_VALUE: {
+ value: {
+ fields: {
+ test_struct_name: getIValue('structValue', {
+ fields: {
+ struct_string_val_copy: stringValueTestCases.WITH_STRING_VAL.value?.fields
+ ?.test_field_name4 as Protobuf.IValue,
+ struct_bool_val_copy: boolValueTestCases.WITH_BOOL_VAL.value?.fields
+ ?.test_field_name as Protobuf.IValue,
+ },
+ }),
+ },
+ },
+ expected: {
+ result_var: {
+ test_struct_name: { struct_string_val_copy: 'test val', struct_bool_val_copy: true },
+ },
+ },
+ },
+};
+
+const listValueTestCases: TestCaseList = {
+ WITH_LIST_VALUE: {
+ value: {
+ fields: {
+ test_list_name: getIValue('listValue', {
+ values: [
+ structValueTestCases.WITH_STRUCT_VALUE.value?.fields
+ ?.test_struct_name as Protobuf.IValue,
+ ],
+ }),
+ },
+ },
+ expected: {
+ result_var: {
+ test_list_name: [{ struct_bool_val_copy: true, struct_string_val_copy: 'test val' }],
+ },
+ },
+ },
+};
+export default {
+ ...nullValueTestcases,
+ ...numberValueTestCases,
+ ...stringValueTestCases,
+ ...boolValueTestCases,
+ ...structValueTestCases,
+ ...listValueTestCases,
+};
diff --git a/packages/zapp/console/src/components/Literals/test/helpers/genScalarNoneCase.mock.ts b/packages/zapp/console/src/components/Literals/test/helpers/genScalarNoneCase.mock.ts
new file mode 100644
index 000000000..140af9bed
--- /dev/null
+++ b/packages/zapp/console/src/components/Literals/test/helpers/genScalarNoneCase.mock.ts
@@ -0,0 +1,13 @@
+import { Core } from 'flyteidl';
+import { TestCaseList } from '../types';
+
+const scalarNoneTestCase: TestCaseList = {
+ VOID_TYPE: {
+ value: {},
+ expected: {
+ result_var: '(empty)',
+ },
+ },
+};
+
+export default scalarNoneTestCase;
diff --git a/packages/zapp/console/src/components/Literals/test/helpers/genScalarPrimitiveCases.mock.ts b/packages/zapp/console/src/components/Literals/test/helpers/genScalarPrimitiveCases.mock.ts
new file mode 100644
index 000000000..5bff19ef4
--- /dev/null
+++ b/packages/zapp/console/src/components/Literals/test/helpers/genScalarPrimitiveCases.mock.ts
@@ -0,0 +1,90 @@
+import { Core } from 'flyteidl';
+import * as Long from 'long';
+import { long } from 'test/utils';
+import { getPrimitive } from './literalHelpers';
+import { TestCaseList } from '../types';
+
+const scalarPrimitiveTestCases: TestCaseList = {
+ INT_WITH_LARGE_LOW: {
+ value: getPrimitive('integer', { low: 1642627611, high: 0, unsigned: false } as Long),
+ expected: { result_var: 1642627611 },
+ },
+ INT_WITH_SMALL_LOW: {
+ value: getPrimitive('integer', { low: 55, high: 0, unsigned: false } as Long),
+ expected: { result_var: 55 },
+ },
+ INT_WITH_ZERO: {
+ value: getPrimitive('integer', { low: 0, high: 0, unsigned: false } as Long),
+ expected: { result_var: 0 },
+ },
+ FLOAT_ZERO: {
+ value: getPrimitive('floatValue', 0),
+ expected: { result_var: 0 },
+ },
+ FLOAT_POSITIVE: {
+ value: getPrimitive('floatValue', 1.5),
+ expected: { result_var: 1.5 },
+ },
+ FLOAT_NEGATIVE: {
+ value: getPrimitive('floatValue', -1.5),
+ expected: { result_var: -1.5 },
+ },
+ FLOAT_LARGE: {
+ value: getPrimitive('floatValue', 1.25e10),
+ expected: { result_var: 1.25e10 },
+ },
+ FLOAT_UNDEF: {
+ value: getPrimitive('floatValue', undefined),
+ expected: { result_var: undefined },
+ },
+ STRING_NULL: {
+ value: getPrimitive('stringValue', null),
+ expected: { result_var: 'null' },
+ },
+ STRING_VALID: {
+ value: getPrimitive('stringValue', 'some val'),
+ expected: { result_var: 'some val' },
+ },
+ STRING_UNDEF: {
+ value: getPrimitive('stringValue', undefined),
+ expected: { result_var: 'undefined' },
+ },
+ STRING_NEG: {
+ value: getPrimitive('stringValue', '-1'),
+ expected: { result_var: '-1' },
+ },
+ BOOL_TRUE: {
+ value: getPrimitive('boolean', true),
+ expected: { result_var: true },
+ },
+ BOOL_FALSE: {
+ value: getPrimitive('boolean', false),
+ expected: { result_var: false },
+ },
+ BOOL_NULL: {
+ value: getPrimitive('boolean', null),
+ expected: { result_var: null },
+ },
+ BOOL_UNDEF: {
+ value: getPrimitive('boolean', undefined),
+ expected: { result_var: undefined },
+ },
+ DT_VALID: {
+ value: getPrimitive('datetime', { seconds: long(3600), nanos: 0 }),
+ expected: { result_var: '1/1/1970 1:00:00 AM UTC' },
+ },
+ DURATION_ZERO: {
+ value: getPrimitive('duration', { seconds: long(0), nanos: 0 }),
+ expected: { result_var: '0s' },
+ },
+ DURATION_1H: {
+ value: getPrimitive('duration', { seconds: long(3600), nanos: 0 }),
+ expected: { result_var: '1h' },
+ },
+ DURATION_LARGE: {
+ value: getPrimitive('duration', { seconds: long(10000), nanos: 0 }),
+ expected: { result_var: '2h 46m 40s' },
+ },
+};
+
+export default scalarPrimitiveTestCases;
diff --git a/packages/zapp/console/src/components/Literals/test/helpers/genScalarSchemaCase.mock.ts b/packages/zapp/console/src/components/Literals/test/helpers/genScalarSchemaCase.mock.ts
new file mode 100644
index 000000000..a51574f9f
--- /dev/null
+++ b/packages/zapp/console/src/components/Literals/test/helpers/genScalarSchemaCase.mock.ts
@@ -0,0 +1,46 @@
+import { Core } from 'flyteidl';
+import { TestCaseList } from '../types';
+
+const schemaColumnTypes: TestCaseList = Object.keys(
+ Core.SchemaType.SchemaColumn.SchemaColumnType,
+)
+ .map((key, index) => ({
+ [`SCHEMA_WITH_${key}`]: {
+ value: {
+ uri: `s3/${index}`,
+ type: {
+ columns: [
+ { name: 'name' + index, type: Core.SchemaType.SchemaColumn.SchemaColumnType[key] },
+ ],
+ },
+ },
+ expected: {
+ result_var: { uri: `s3/${index}`, columns: [`name${index} (${key.toLocaleLowerCase()})`] },
+ },
+ },
+ }))
+ .reduce((acc, v) => {
+ return {
+ ...acc,
+ ...v,
+ };
+ }, {});
+
+const schemaTestCases: TestCaseList = {
+ SCHEMA_WITHOUT_TYPE: {
+ value: {
+ uri: 'test7',
+ type: {
+ columns: [{ name: 'test7' }],
+ },
+ },
+ expected: {
+ result_var: { uri: 'test7', columns: [`test7 (unknown)`] },
+ },
+ },
+};
+
+export default {
+ ...schemaColumnTypes,
+ ...schemaTestCases,
+};
diff --git a/packages/zapp/console/src/components/Literals/test/helpers/genScalarStructuredDsCase.mock.ts b/packages/zapp/console/src/components/Literals/test/helpers/genScalarStructuredDsCase.mock.ts
new file mode 100644
index 000000000..ae6660bf1
--- /dev/null
+++ b/packages/zapp/console/src/components/Literals/test/helpers/genScalarStructuredDsCase.mock.ts
@@ -0,0 +1,131 @@
+import { Core } from 'flyteidl';
+import { TestCaseList } from '../types';
+import { processSimpleType, columnTypeToString } from '../../helpers';
+
+import { simple } from './mock_simpleTypes';
+
+const generateColumnEntry = (columnName: string, literalType) => {
+ return {
+ name: columnName,
+ literalType,
+ };
+};
+
+const generateStructuredDataset = (columnName: string, uri: string, literalType) => {
+ return {
+ uri,
+ metadata: {
+ structuredDatasetType: {
+ format: 'parquet',
+ columns: [generateColumnEntry(columnName, literalType)],
+ },
+ },
+ };
+};
+
+const sasWithMapValueTypeColumns: TestCaseList = Object.keys(simple)
+ .map((simpleTypeKey, index) => {
+ const simpleType = simple[simpleTypeKey];
+
+ const literalType = {
+ mapValueType: {
+ ...simpleType,
+ },
+ type: 'mapValueType',
+ };
+
+ const name = `column_name_${index}`;
+ const columns = [];
+ columns[name] = `map value of ${processSimpleType(simpleType[simpleType.type])}`;
+
+ return {
+ [`STRUCT_SIMPLE_${simpleTypeKey}`]: {
+ value: generateStructuredDataset(name, index.toString(), literalType),
+ expected: {
+ result_var: { columns, format: 'parquet', uri: index.toString() },
+ },
+ },
+ };
+ })
+ .reduce((acc, v) => ({ ...acc, ...v }), {});
+
+const sasWithCollectionTypeColumns: TestCaseList = Object.keys(simple)
+ .map((simpleTypeKey, index) => {
+ const simpleType = simple[simpleTypeKey];
+
+ const literalType = {
+ collectionType: {
+ ...simpleType,
+ },
+ type: 'collectionType',
+ };
+
+ const name = `column_name_${index}`;
+ const columns = [];
+ columns[name] = `collection of ${processSimpleType(simpleType[simpleType.type])}`;
+
+ return {
+ [`STRUCT_SIMPLE_${simpleTypeKey}`]: {
+ value: generateStructuredDataset(name, index.toString(), literalType),
+ expected: {
+ result_var: { columns, format: 'parquet', uri: index.toString() },
+ },
+ },
+ };
+ })
+ .slice(0, 1)
+ .reduce((acc, v) => ({ ...acc, ...v }), {});
+
+const sdsWithSimpleTypeColumns: TestCaseList = Object.keys(simple)
+ .map((simpleTypeKey, index) => {
+ const literalType = simple[simpleTypeKey];
+
+ const name = `column_name_${index}`;
+ const columns = [];
+ columns[name] = processSimpleType(literalType[literalType.type]);
+
+ return {
+ [`STRUCT_SIMPLE_${simpleTypeKey}`]: {
+ value: generateStructuredDataset(name, index.toString(), literalType),
+ expected: {
+ result_var: { columns, format: 'parquet', uri: index.toString() },
+ },
+ },
+ };
+ })
+ .reduce((acc, v) => ({ ...acc, ...v }), {});
+
+const sasWithSchemaColumns: TestCaseList = Object.keys(
+ Core.SchemaType.SchemaColumn.SchemaColumnType,
+)
+ .map((simpleTypeKey, index) => {
+ const literalType = {
+ schema: {
+ columns: [{ type: Core.SchemaType.SchemaColumn.SchemaColumnType[simpleTypeKey] }],
+ },
+ type: 'schema',
+ };
+
+ const name = `schema_column_name_${index}`;
+ const columns = [];
+ columns[name] = `schema (${columnTypeToString(
+ Core.SchemaType.SchemaColumn.SchemaColumnType[simpleTypeKey],
+ )})`;
+
+ return {
+ [`STRUCT_SCHEMA_WITH_COLUMNS_${simpleTypeKey}`]: {
+ value: generateStructuredDataset(name, index.toString(), literalType),
+ expected: {
+ result_var: { columns, format: 'parquet', uri: index.toString() },
+ },
+ },
+ };
+ })
+ .reduce((acc, v) => ({ ...acc, ...v }), {});
+
+export default {
+ ...sdsWithSimpleTypeColumns,
+ ...sasWithSchemaColumns,
+ ...sasWithCollectionTypeColumns,
+ ...sasWithMapValueTypeColumns,
+};
diff --git a/packages/zapp/console/src/components/Literals/test/helpers/index.ts b/packages/zapp/console/src/components/Literals/test/helpers/index.ts
new file mode 100644
index 000000000..e1e2debc6
--- /dev/null
+++ b/packages/zapp/console/src/components/Literals/test/helpers/index.ts
@@ -0,0 +1,23 @@
+import primitive from './genScalarPrimitiveCases.mock';
+import blob from './genScalarBlobCases.mock';
+import binary from './genScalarBinaryTestCase.mock';
+import schema from './genScalarSchemaCase.mock';
+import noneType from './genScalarNoneCase.mock';
+import errorType from './genScalarErrorCase.mock';
+import generic from './genScalarGenericCase.mock';
+import structuredDataset from './genScalarStructuredDsCase.mock';
+import collection from './genCollectionTestcase.mock';
+import map from './genMapTestCase.mock';
+
+export {
+ primitive,
+ blob,
+ binary,
+ schema,
+ noneType,
+ errorType,
+ generic,
+ structuredDataset,
+ collection,
+ map,
+};
diff --git a/packages/zapp/console/src/components/Literals/test/helpers/literalHelpers.ts b/packages/zapp/console/src/components/Literals/test/helpers/literalHelpers.ts
new file mode 100644
index 000000000..67e4da36f
--- /dev/null
+++ b/packages/zapp/console/src/components/Literals/test/helpers/literalHelpers.ts
@@ -0,0 +1,123 @@
+import { Core, Protobuf } from 'flyteidl';
+
+export function getIValue(
+ kind: 'nullValue' | 'numberValue' | 'stringValue' | 'boolValue' | 'structValue' | 'listValue',
+ value?:
+ | Protobuf.NullValue
+ | number
+ | string
+ | boolean
+ | Protobuf.IStruct
+ | Protobuf.IListValue
+ | null,
+): Protobuf.IValue & Pick {
+ return {
+ kind,
+ [kind]: value,
+ };
+}
+
+export function getPrimitive(
+ key: 'integer' | 'floatValue' | 'stringValue' | 'boolean' | 'datetime' | 'duration',
+ value?: Long | number | string | boolean | Protobuf.ITimestamp | Protobuf.IDuration | null,
+): Core.IPrimitive & Pick {
+ return {
+ [key]: value,
+ value: key,
+ };
+}
+
+export function generateBlobType(
+ format?: string,
+ dimensionality?: Core.BlobType.BlobDimensionality,
+ uri?: string,
+): Core.IBlob {
+ return {
+ metadata: {
+ type: {
+ format,
+ dimensionality,
+ },
+ },
+ uri,
+ };
+}
+
+const getScalar = (
+ value:
+ | Core.IPrimitive
+ | Core.IBlob
+ | Core.IBinary
+ | Core.ISchema
+ | Core.IVoid
+ | Core.IError
+ | Protobuf.IStruct
+ | Core.IStructuredDataset
+ | Core.IUnion,
+ scalarType:
+ | 'primitive'
+ | 'blob'
+ | 'binary'
+ | 'schema'
+ | 'noneType'
+ | 'error'
+ | 'generic'
+ | 'structuredDataset'
+ | 'union',
+): Core.IScalar & Pick => {
+ return {
+ [scalarType]: value,
+ value: scalarType,
+ };
+};
+
+// TOP LEVEL SCHEMA GENERATORS:
+export const getScalarLiteral = (
+ value:
+ | Core.IPrimitive
+ | Core.IBlob
+ | Core.IBinary
+ | Core.ISchema
+ | Core.IVoid
+ | Core.IError
+ | Protobuf.IStruct
+ | Core.IStructuredDataset
+ | Core.IUnion,
+ scalarType:
+ | 'primitive'
+ | 'blob'
+ | 'binary'
+ | 'schema'
+ | 'noneType'
+ | 'error'
+ | 'generic'
+ | 'structuredDataset'
+ | 'union',
+): Core.ILiteral & Pick => {
+ return {
+ scalar: getScalar(value, scalarType),
+ value: 'scalar',
+ };
+};
+
+export const getCollection = (
+ literals: Core.ILiteral[],
+): Core.ILiteral & Pick => {
+ return {
+ collection: {
+ literals,
+ },
+ value: 'collection',
+ };
+};
+
+export const getMap = (
+ literals: { [k: string]: Core.ILiteral } | null,
+): Core.ILiteral & Pick => {
+ return {
+ map: {
+ literals,
+ },
+ value: 'map',
+ };
+};
diff --git a/packages/zapp/console/src/components/Literals/test/helpers/mock_simpleTypes.ts b/packages/zapp/console/src/components/Literals/test/helpers/mock_simpleTypes.ts
new file mode 100644
index 000000000..0bd9d543f
--- /dev/null
+++ b/packages/zapp/console/src/components/Literals/test/helpers/mock_simpleTypes.ts
@@ -0,0 +1,17 @@
+import { Core } from 'flyteidl';
+
+export function extractSimpleTypes() {
+ const simpleTypes= Object.keys(Core.SimpleType).map((key) => ({
+ [key]: {
+ type: 'simple',
+ simple: Core.SimpleType[key],
+ },
+ })).reduce((acc, v) => ({...acc, ...v}), {});
+ return simpleTypes;
+}
+
+const simple: Core.SimpleType[] = extractSimpleTypes() as any;
+
+export {
+ simple
+};
diff --git a/packages/zapp/console/src/components/Literals/test/literal.helpers.test.ts b/packages/zapp/console/src/components/Literals/test/literal.helpers.test.ts
new file mode 100644
index 000000000..8ebf97c6d
--- /dev/null
+++ b/packages/zapp/console/src/components/Literals/test/literal.helpers.test.ts
@@ -0,0 +1,83 @@
+import { Core } from 'flyteidl';
+import { transformLiterals } from '../helpers';
+
+import {
+ primitive,
+ blob,
+ binary,
+ schema,
+ noneType,
+ errorType,
+ generic,
+ structuredDataset,
+ collection,
+ map,
+} from './helpers/index';
+import { getCollection, getMap, getScalarLiteral } from './helpers/literalHelpers';
+
+const literalTestCases = {
+ scalar: {
+ primitive,
+ blob,
+ binary,
+ schema,
+ noneType,
+ error: errorType,
+ generic,
+ structuredDataset,
+ union: {} as Core.IPrimitive, // TODO: FC#450 ass support for union types
+ },
+ collection,
+ map,
+};
+
+describe('scalar literal', () => {
+ const scalarTestCases = literalTestCases.scalar;
+ const scalarType = Object.keys(scalarTestCases);
+
+ scalarType.map((scalarTestType) => {
+ describe(scalarTestType, () => {
+ const cases = scalarTestCases[scalarTestType];
+
+ Object.keys(cases || {}).map((testKey) => {
+ const { value, expected } = cases[testKey];
+
+ it(`${testKey}: should return ${expected} for ${value}`, () => {
+ const scalar = { result_var: { ...getScalarLiteral(value, scalarTestType as any) } };
+ const result = transformLiterals(scalar as any);
+ expect(result).toEqual(expected);
+ });
+ });
+ });
+ });
+});
+
+describe('collection literal', () => {
+ const cases = literalTestCases.collection;
+
+ Object.keys(cases).map((testKey) => {
+ const { value, expected } = cases[testKey];
+
+ it(`${testKey}: should return ${expected} for ${value}`, () => {
+ const collection = { result_var: { ...getCollection([value]) } };
+
+ const result = transformLiterals(collection);
+ expect(result).toEqual(expected);
+ });
+ });
+});
+
+describe('map literal', () => {
+ const cases = literalTestCases.map;
+
+ Object.keys(cases).map((testKey) => {
+ const { value, expected } = cases[testKey];
+
+ it(`${testKey}: should return ${expected} for ${value}`, () => {
+ const collection = { result_var: { ...getMap({ value }) } };
+
+ const result = transformLiterals(collection);
+ expect(result).toEqual(expected);
+ });
+ });
+});
diff --git a/packages/zapp/console/src/components/Literals/test/types.d.ts b/packages/zapp/console/src/components/Literals/test/types.d.ts
new file mode 100644
index 000000000..04572a2b5
--- /dev/null
+++ b/packages/zapp/console/src/components/Literals/test/types.d.ts
@@ -0,0 +1,8 @@
+export type TestCase = {
+ value: K;
+ expected: any;
+};
+
+export type TestCaseList = {
+ [key: string]: TestCase;
+};
diff --git a/packages/zapp/console/src/components/common/DumpJSON.tsx b/packages/zapp/console/src/components/common/DumpJSON.tsx
index e20db28c4..57349eefb 100644
--- a/packages/zapp/console/src/components/common/DumpJSON.tsx
+++ b/packages/zapp/console/src/components/common/DumpJSON.tsx
@@ -1,8 +1,8 @@
-import { stringifyValue } from 'common/utils';
-import { useCommonStyles } from 'components/common/styles';
import * as React from 'react';
+import { ReactJsonViewWrapper } from 'components/common/ReactJsonView';
export const DumpJSON: React.FC<{ value: any }> = ({ value }) => {
- const commonStyles = useCommonStyles();
- return {stringifyValue(value)}
;
+ return (
+
+ );
};
diff --git a/packages/zapp/console/src/components/common/PanelSection/index.tsx b/packages/zapp/console/src/components/common/PanelSection/index.tsx
index 23b229699..ace1ab503 100644
--- a/packages/zapp/console/src/components/common/PanelSection/index.tsx
+++ b/packages/zapp/console/src/components/common/PanelSection/index.tsx
@@ -4,6 +4,7 @@ import { makeStyles } from '@material-ui/core/styles';
const useStyle = makeStyles((theme) => ({
detailsPanelCard: {
borderBottom: `1px solid ${theme.palette.divider}`,
+ paddingBottom: '150px', // TODO @FC 454 temporary fix for panel height issue
},
detailsPanelCardContent: {
padding: `${theme.spacing(2)}px ${theme.spacing(3)}px`,
diff --git a/packages/zapp/console/src/components/common/ReactJsonView.tsx b/packages/zapp/console/src/components/common/ReactJsonView.tsx
new file mode 100644
index 000000000..ea7e9d1a1
--- /dev/null
+++ b/packages/zapp/console/src/components/common/ReactJsonView.tsx
@@ -0,0 +1,99 @@
+import * as React from 'react';
+import { makeStyles, Theme } from '@material-ui/core/styles';
+import ReactJsonView, { ReactJsonViewProps } from 'react-json-view';
+import * as copyToClipboard from 'copy-to-clipboard';
+import { primaryTextColor } from 'components/Theme/constants';
+
+const useStyles = makeStyles((theme: Theme) => ({
+ jsonViewer: {
+ marginLeft: '-10px',
+ width: '100%',
+ '& span': {
+ fontWeight: 'normal !important',
+ },
+ '& .object-container': {
+ overflowWrap: 'anywhere !important',
+ },
+ '& .copy-to-clipboard-container': {
+ position: 'absolute',
+ },
+ '& .copy-icon svg': {
+ color: `${theme.palette.primary.main} !important`,
+ },
+ '& .variable-value': {
+ paddingLeft: '5px',
+ },
+ '& .variable-value >*': {
+ color: `${primaryTextColor} !important`,
+ },
+ '& .object-key-val': {
+ padding: '0 0 0 5px !important',
+ },
+ '& .object-key': {
+ color: `${theme.palette.grey[500]} !important`,
+ },
+ },
+}));
+
+/**
+ *
+ * Replacer functionality to pass to the JSON.stringify function that
+ * does proper serialization of arrays that contain non-numeric indexes
+ * @param _ parent element key
+ * @param value the element being serialized
+ * @returns Transformed version of input
+ */
+const replacer = (_, value) => {
+ // Check if associative array
+ if (value instanceof Array && Object.keys(value).some((v) => isNaN(+v))) {
+ // Serialize associative array
+ return Object.keys(value).reduce((acc, arrKey) => {
+ // if:
+ // string key is encountered insert {[key]: value} into transformed array
+ // else:
+ // insert original value
+ acc.push(isNaN(+arrKey) ? { [arrKey]: value[arrKey] } : value[arrKey]);
+
+ return acc;
+ }, [] as any[]);
+ }
+
+ // Non-associative array. return original value to allow default JSON.stringify behavior
+ return value;
+};
+
+/**
+ * Custom implementation for JSON.stringify to allow
+ * proper serialization of arrays that contain non-numeric indexes
+ *
+ * @param json Object to serialize
+ * @returns A string version of the input json
+ */
+const customStringify = (json) => {
+ return JSON.stringify(json, replacer);
+};
+
+export const ReactJsonViewWrapper: React.FC = (props) => {
+ const styles = useStyles();
+
+ return (
+
+ {
+ const objToCopy = options.src;
+ const text = typeof objToCopy === 'object' ? customStringify(objToCopy) : objToCopy;
+ copyToClipboard(text);
+ }}
+ displayDataTypes={false}
+ quotesOnKeys={false}
+ iconStyle="triangle"
+ displayObjectSize={true}
+ name={null}
+ indentWidth={4}
+ collapseStringsAfterLength={80}
+ sortKeys={true}
+ {...props}
+ />
+
+ );
+};
diff --git a/yarn.lock b/yarn.lock
index e04f21af6..0e47e4ccc 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5380,7 +5380,7 @@ arrify@^2.0.1:
resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa"
integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==
-asap@^2.0.0:
+asap@^2.0.0, asap@~2.0.3:
version "2.0.6"
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
@@ -5739,6 +5739,11 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
+base16@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/base16/-/base16-1.0.0.tgz#e297f60d7ec1014a7a971a39ebc8a98c0b681e70"
+ integrity sha1-4pf2DX7BAUp6lxo568ipjAtoHnA=
+
base64-js@^1.0.2, base64-js@^1.3.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
@@ -7398,6 +7403,13 @@ cronstrue@^1.31.0:
resolved "https://registry.yarnpkg.com/cronstrue/-/cronstrue-1.105.0.tgz#57f89468c261d7fa56c69057f42c84eba3a37837"
integrity sha512-Bv8GHi5uJvxtq/9T7lgBwum7UVKMfR+LSPHZXiezP0E5gnODPVRQBAkCwijCIaWEepqmRcxTAxrUFB0UQK2wdw==
+cross-fetch@^3.1.5:
+ version "3.1.5"
+ resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f"
+ integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==
+ dependencies:
+ node-fetch "2.6.7"
+
cross-spawn@^5.0.1:
version "5.1.0"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
@@ -9451,6 +9463,31 @@ fb-watchman@^2.0.0:
dependencies:
bser "2.1.1"
+fbemitter@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/fbemitter/-/fbemitter-3.0.0.tgz#00b2a1af5411254aab416cd75f9e6289bee4bff3"
+ integrity sha512-KWKaceCwKQU0+HPoop6gn4eOHk50bBv/VxjJtGMfwmJt3D29JpN4H4eisCtIPA+a8GVBam+ldMMpMjJUvpDyHw==
+ dependencies:
+ fbjs "^3.0.0"
+
+fbjs-css-vars@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8"
+ integrity sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==
+
+fbjs@^3.0.0, fbjs@^3.0.1:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-3.0.4.tgz#e1871c6bd3083bac71ff2da868ad5067d37716c6"
+ integrity sha512-ucV0tDODnGV3JCnnkmoszb5lf4bNpzjv80K41wd4k798Etq+UYD0y0TIfalLjZoKgjive6/adkRnszwapiDgBQ==
+ dependencies:
+ cross-fetch "^3.1.5"
+ fbjs-css-vars "^1.0.0"
+ loose-envify "^1.0.0"
+ object-assign "^4.1.0"
+ promise "^7.1.1"
+ setimmediate "^1.0.5"
+ ua-parser-js "^0.7.30"
+
figgy-pudding@^3.4.1, figgy-pudding@^3.5.1:
version "3.5.2"
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e"
@@ -9638,6 +9675,14 @@ flush-write-stream@^1.0.0:
inherits "^2.0.3"
readable-stream "^2.3.6"
+flux@^4.0.1:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/flux/-/flux-4.0.3.tgz#573b504a24982c4768fdfb59d8d2ea5637d72ee7"
+ integrity sha512-yKAbrp7JhZhj6uiT1FTuVMlIAT1J4jqEyBpFApi1kxpGZCvacMVc/t1pMQyotqHhAgvoE3bNvAykhCo2CLjnYw==
+ dependencies:
+ fbemitter "^3.0.0"
+ fbjs "^3.0.1"
+
follow-redirects@^1.0.0, follow-redirects@^1.14.0:
version "1.14.8"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc"
@@ -12966,6 +13011,11 @@ lodash.clonedeep@^4.5.0, lodash.clonedeep@~4.5.0:
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
+lodash.curry@^4.0.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/lodash.curry/-/lodash.curry-4.1.1.tgz#248e36072ede906501d75966200a86dab8b23170"
+ integrity sha1-JI42By7ekGUB11lmIAqG2riyMXA=
+
lodash.debounce@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
@@ -12981,6 +13031,11 @@ lodash.escaperegexp@^4.1.2:
resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347"
integrity sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=
+lodash.flow@^3.3.0:
+ version "3.5.0"
+ resolved "https://registry.yarnpkg.com/lodash.flow/-/lodash.flow-3.5.0.tgz#87bf40292b8cf83e4e8ce1a3ae4209e20071675a"
+ integrity sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o=
+
lodash.ismatch@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37"
@@ -13943,7 +13998,7 @@ node-fetch-npm@^2.0.2:
json-parse-better-errors "^1.0.0"
safe-buffer "^5.1.1"
-node-fetch@^2.6.1:
+node-fetch@2.6.7, node-fetch@^2.6.1:
version "2.6.7"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
@@ -15504,6 +15559,13 @@ promise.prototype.finally@^3.1.0:
define-properties "^1.1.3"
es-abstract "^1.19.1"
+promise@^7.1.1:
+ version "7.3.1"
+ resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
+ integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==
+ dependencies:
+ asap "~2.0.3"
+
prompts@^2.0.1:
version "2.4.0"
resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.0.tgz#4aa5de0723a231d1ee9121c40fdf663df73f61d7"
@@ -15666,6 +15728,11 @@ punycode@^2.1.0, punycode@^2.1.1:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
+pure-color@^1.2.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/pure-color/-/pure-color-1.3.0.tgz#1fe064fb0ac851f0de61320a8bf796836422f33e"
+ integrity sha1-H+Bk+wrIUfDeYTIKi/eWg2Qi8z4=
+
q@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
@@ -15807,6 +15874,16 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7, rc@^1.2.8:
minimist "^1.2.0"
strip-json-comments "~2.0.1"
+react-base16-styling@^0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/react-base16-styling/-/react-base16-styling-0.6.0.tgz#ef2156d66cf4139695c8a167886cb69ea660792c"
+ integrity sha1-7yFW1mz0E5aVyKFniGy2nqZgeSw=
+ dependencies:
+ base16 "^1.0.0"
+ lodash.curry "^4.0.1"
+ lodash.flow "^3.3.0"
+ pure-color "^1.2.0"
+
react-chartjs-2@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/react-chartjs-2/-/react-chartjs-2-4.0.0.tgz#a79919c9efe5381b8cb5abfd0ac7a56c9736cdb8"
@@ -15956,6 +16033,16 @@ react-is@^17.0.1:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.1.tgz#5b3531bd76a645a4c9fb6e693ed36419e3301339"
integrity sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==
+react-json-view@^1.21.3:
+ version "1.21.3"
+ resolved "https://registry.yarnpkg.com/react-json-view/-/react-json-view-1.21.3.tgz#f184209ee8f1bf374fb0c41b0813cff54549c475"
+ integrity sha512-13p8IREj9/x/Ye4WI/JpjhoIwuzEgUAtgJZNBJckfzJt1qyh24BdTm6UQNGnyTq9dapQdrqvquZTo3dz1X6Cjw==
+ dependencies:
+ flux "^4.0.1"
+ react-base16-styling "^0.6.0"
+ react-lifecycles-compat "^3.0.4"
+ react-textarea-autosize "^8.3.2"
+
react-lifecycles-compat@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
@@ -16070,7 +16157,7 @@ react-syntax-highlighter@^13.5.3:
prismjs "^1.21.0"
refractor "^3.1.0"
-react-textarea-autosize@^8.3.0:
+react-textarea-autosize@^8.3.0, react-textarea-autosize@^8.3.2:
version "8.3.3"
resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.3.3.tgz#f70913945369da453fd554c168f6baacd1fa04d8"
integrity sha512-2XlHXK2TDxS6vbQaoPbMOfQ8GK7+irc2fVK6QFIcC8GOnH3zI/v481n+j1L0WaPVvKxwesnY93fEfH++sus2rQ==
@@ -17161,7 +17248,7 @@ set-value@^2.0.0, set-value@^2.0.1:
is-plain-object "^2.0.3"
split-string "^3.0.1"
-setimmediate@^1.0.4:
+setimmediate@^1.0.4, setimmediate@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
@@ -18618,6 +18705,11 @@ typescript@^4.6.2:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.2.tgz#fe12d2727b708f4eef40f51598b3398baa9611d4"
integrity sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==
+ua-parser-js@^0.7.30:
+ version "0.7.31"
+ resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6"
+ integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==
+
uc.micro@^1.0.1:
version "1.0.6"
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac"