Skip to content

Commit

Permalink
typing extractValue for UIStoreActions #163; support Record value #140
Browse files Browse the repository at this point in the history
  • Loading branch information
elbakerino committed Mar 19, 2022
1 parent 20a49f6 commit 3284b0e
Show file tree
Hide file tree
Showing 10 changed files with 24 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { handleIfElseThen } from '@ui-schema/ui-schema/Plugins/ConditionalHandler'
import { StoreSchemaType } from '@ui-schema/ui-schema/CommonTypings'
import { mergeSchema } from '@ui-schema/ui-schema/Utils/mergeSchema'
import { List, Map, OrderedMap } from 'immutable'
import { List, Record, Map, OrderedMap } from 'immutable'
import React from 'react'

export const handleSchemaCombine = (schema: StoreSchemaType, value: Map<string | number, any> | OrderedMap<string | number, any>): StoreSchemaType => {
Expand All @@ -11,8 +11,7 @@ export const handleSchemaCombine = (schema: StoreSchemaType, value: Map<string |
// removing afterwards-handled keywords, otherwise they would merge wrongly/double evaluate
schema = mergeSchema(schema, subSchema.delete('if').delete('else').delete('then').delete('allOf'))

// todo: `Record` support #140
if (value && Map.isMap(value)) {
if (value && (Map.isMap(value) || Record.isRecord(value))) {
schema = handleIfElseThen(subSchema, value, schema)
}

Expand All @@ -24,8 +23,7 @@ export const handleSchemaCombine = (schema: StoreSchemaType, value: Map<string |
// further on nested `allOf` will be resolved by render flow
schema = mergeSchema(schema, subSchema1.delete('if').delete('else').delete('then'))

// todo: `Record` support #140
if (value && Map.isMap(value)) {
if (value && (Map.isMap(value) || Record.isRecord(value))) {
schema = handleIfElseThen(subSchema1, value, schema)
}
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import {Map} from 'immutable';
import {Map, Record} from 'immutable';
import {NextPluginRendererMemo} from '@ui-schema/ui-schema/PluginStack';
import {handleIfElseThen} from './handleIfElseThen';
import {schemaTypeIs} from '@ui-schema/ui-schema/Utils/schemaTypeIs';
Expand All @@ -14,10 +14,9 @@ export const ConditionalHandler = (props) => {
// when current schema does not have a type, it's a pure combining schema and it's conditionals can not be checked
// this can come from a state where the combining schema has not been resolved (yet)
// also an `if` can only be inside an `Map`/object
// todo: `Record` support #140
// todo: only when `type` object?
schemaTypeIs(schema.get('type'), 'object') &&
Map.isMap(value)
(Map.isMap(value) || Record.isRecord(value))
) {
schema = handleIfElseThen(schema, value, schema);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/ui-schema/src/UIStore/doExtractValues.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { List, Map } from 'immutable'
import { List, Map, Record } from 'immutable'
import { addNestKey, StoreKeys, UIStoreInternalsType, UIStoreType } from '@ui-schema/ui-schema/UIStore'

export type ExtractValueOverwriteProps = { showValidity?: boolean }
Expand All @@ -7,7 +7,7 @@ export function doExtractValues<S extends UIStoreType>(storeKeys: StoreKeys, sto
return {
value:
storeKeys.size ?
(Map.isMap(store.getValues()) || List.isList(store.getValues()) ? store.getValues().getIn(storeKeys) : undefined) :
(Record.isRecord(store.getValues()) || Map.isMap(store.getValues()) || List.isList(store.getValues()) ? store.getValues().getIn(storeKeys) : undefined) :
store.getValues(),
internalValue:
storeKeys.size ?
Expand Down
6 changes: 4 additions & 2 deletions packages/ui-schema/src/UIStore/extractValue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ import { getDisplayName } from '@ui-schema/ui-schema/Utils/memo'
import { StoreKeys, useUIStore, WithValue, ExtractValueOverwriteProps } from '@ui-schema/ui-schema/UIStore'
import { UIStoreActions, useUIStoreActions } from '@ui-schema/ui-schema/UIStoreActions'

export const extractValue = <A extends UIStoreActions = UIStoreActions, P extends Partial<WithValue<A>> & { storeKeys: StoreKeys } = Partial<WithValue<A>> & { storeKeys: StoreKeys }>(Component: React.ComponentType<P>): React.ComponentType<Omit<P, keyof WithValue<A>> & ExtractValueOverwriteProps> => {
export function extractValue<A = UIStoreActions, P extends Partial<WithValue<A>> & { storeKeys: StoreKeys } = Partial<WithValue<A>> & { storeKeys: StoreKeys }>(
Component: React.ComponentType<P>
): React.ComponentType<Omit<P, keyof WithValue<A>> & ExtractValueOverwriteProps> {
const ExtractValue = (p: Omit<P, keyof WithValue<A>> & ExtractValueOverwriteProps) => {
const {store, showValidity} = useUIStore()
const {onChange} = useUIStoreActions()
const values = store?.extractValues(p.storeKeys)
// @ts-ignore
return <Component
// `showValidity` is overridable by render flow, e.g. nested Stepper
{...p}
// `showValidity` is overridable by render flow, e.g. nested Stepper
showValidity={p.showValidity || showValidity}
onChange={onChange}
{...values || {}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {List, Map, Seq} from 'immutable';
import {List, Map, Record, Seq} from 'immutable';

export function isImmutableDeep(maybeImmutable, curr = true) {
if(typeof maybeImmutable !== 'object' || maybeImmutable === null) {
Expand All @@ -13,6 +13,8 @@ export function isImmutableDeep(maybeImmutable, curr = true) {
Seq(maybeImmutable).forEach(e => curr = isImmutableDeep(e, curr))
} else if(Map.isMap(maybeImmutable)) {
Seq(maybeImmutable).forEach(e => curr = isImmutableDeep(e, curr))
} else if(Record.isRecord(maybeImmutable)) {
Seq(maybeImmutable).forEach(e => curr = isImmutableDeep(e, curr))
} else {
if(process.env.NODE_ENV === 'development') {
console.warn('is immutable, not converted found', maybeImmutable)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {List, Map} from 'immutable';
import {List, Map, Record} from 'immutable';
import {createValidatorErrors} from '@ui-schema/ui-schema/ValidatorErrors';
import {schemaTypeIs, schemaTypeIsNumeric} from '@ui-schema/ui-schema/Utils/schemaTypeIs';

Expand Down Expand Up @@ -61,7 +61,7 @@ export const validateMinMax = (schema, value) => {
let maxProperties = schema.get('maxProperties');

if(minProperties) {
if(Map.isMap(value)) {
if(Map.isMap(value) || Record.isRecord(value)) {
if(value.keySeq().size < minProperties) {
errors = errors.addError(ERROR_MIN_LENGTH, Map({min: minProperties}));
}
Expand All @@ -73,7 +73,7 @@ export const validateMinMax = (schema, value) => {
}

if(maxProperties) {
if(Map.isMap(value)) {
if(Map.isMap(value) || Record.isRecord(value)) {
if(value.keySeq().size > maxProperties) {
errors = errors.addError(ERROR_MAX_LENGTH, Map({max: maxProperties}));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const validateObject = (schema, value) => {
}
if(schema.get('additionalProperties') === false && schema.get('properties') && typeof value === 'object') {
let hasAdditional = false;
const keys = Map.isMap(value) ? value.keySeq() : Object.keys(value);
const keys = Map.isMap(value) || Record.isRecord(value) ? value.keySeq() : Object.keys(value);
const schemaKeys = schema.get('properties').keySeq();
keys.forEach(key => {
// todo: add all invalid additional or change to `for key of value` to break after first invalid
Expand All @@ -26,7 +26,7 @@ export const validateObject = (schema, value) => {
}

if(schema.get('propertyNames') && typeof value === 'object') {
const keys = Map.isMap(value) ? value.keySeq() : Object.keys(value);
const keys = Map.isMap(value) || Record.isRecord(value) ? value.keySeq() : Object.keys(value);
keys.forEach(key => {
let tmp_err = validateSchema(schema.get('propertyNames').set('type', 'string'), key);
if(tmp_err.hasError()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ export const validateType = (value, type) => {
}
if(type === 'object') {
return null !== value && (
(typeof value === 'object' || Map.isMap(value)) &&
!(Array.isArray(value) || List.isList(value))
!(Array.isArray(value) || List.isList(value)) &&
(typeof value === 'object' || Map.isMap(value) || Record.isRecord(value))
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
prependKey, shouldDeleteOnEmpty, StoreKeys, UIStoreType,
} from '@ui-schema/ui-schema/UIStore'
import { List, Map } from 'immutable'
import { List, Map, Record } from 'immutable'
import { SchemaTypesType, UIStoreActions } from '@ui-schema/ui-schema'
import { updateStoreScope } from '@ui-schema/ui-schema/storeScopeUpdater/updateStoreScope'
import { storeBuildScopeTree } from '@ui-schema/ui-schema/storeBuildScopeTree'
Expand All @@ -25,7 +25,7 @@ export const scopeUpdaterValues = <S extends UIStoreType = UIStoreType, A extend
// also tests are missing atm.
if (List.isList(parentStore)) {
store = store.setIn(prependKey(storeKeys, 'values'), null)
} else if (Map.isMap(parentStore)) {
} else if (Map.isMap(parentStore) || Record.isRecord(parentStore)) {
store = store.deleteIn(prependKey(storeKeys, 'values'))
}
} else {
Expand Down
2 changes: 1 addition & 1 deletion packages/ui-schema/src/validateSchema/validateSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const validateSchema = (schema, value) => {
* Validating the value, property for property.
*
* @param {Map} schema
* @param {Map} value
* @param {Map|Record} value
* @return {List<*>}
*/
export const validateSchemaObject = (schema, value) => {
Expand Down

0 comments on commit 3284b0e

Please sign in to comment.