Skip to content

Commit

Permalink
Fix minor issues (#1188)
Browse files Browse the repository at this point in the history
* fix minor issues

* fix findings

Co-authored-by: Zoltan Takacs <[email protected]>
  • Loading branch information
eniko.pusztai and Zoltan Takacs authored Mar 3, 2021
1 parent e7c6641 commit d8e6688
Show file tree
Hide file tree
Showing 7 changed files with 381 additions and 4 deletions.
110 changes: 110 additions & 0 deletions packages/sn-controls-react/src/fieldcontrols/file-size.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/**
* @module FieldControls
*/
import { deepMerge, toNumber } from '@sensenet/client-utils'
import { NumberFieldSetting } from '@sensenet/default-content-types'
import FormHelperText from '@material-ui/core/FormHelperText'
import InputAdornment from '@material-ui/core/InputAdornment'
import TextField from '@material-ui/core/TextField'
import Typography from '@material-ui/core/Typography'
import React, { useState } from 'react'
import { changeTemplatedValue } from '../helpers'
import { ReactClientFieldSetting } from './client-field-setting'
import { defaultLocalization } from './localization'

const units = ['byte', 'KB', 'MB', 'GB', 'TB']

/**
* Field control that represents a Number field. Available values will be populated from the FieldSettings.
*/
export const FileSizeField: React.FC<ReactClientFieldSetting<NumberFieldSetting>> = (props) => {
const localization = deepMerge(defaultLocalization.fileSize, props.localization?.fileSize)

const initialState =
props.fieldValue != null
? props.fieldValue
: (props.actionName === 'new' &&
props.settings.DefaultValue !== undefined &&
Number.parseInt(changeTemplatedValue(props.settings.DefaultValue)!, 10)) ||
undefined
const [value, setValue] = useState(initialState)

const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement | HTMLSelectElement>) => {
setValue(e.target.value)
props.fieldOnChange?.(props.settings.Name, e.target.value)
}

/**
* Returns steps value by decimal and step settings
*/
const defineStepValue = () => {
if (props.settings.Step) {
return props.settings.Step
}
if (!props.fieldValue) {
return 1
}
return Number.isInteger(toNumber(props.fieldValue)!) || props.settings.Type === 'IntegerFieldSetting' ? 1 : 0.1
}

const round = (num: number, precision = 1) => {
const multiplier = Math.pow(10, precision)
return Math.round((num + Number.EPSILON) * multiplier) / multiplier
}

const returnValueWithUnit = (fieldValueNumber: number, index = 0): string => {
const inHigherUnit = round(fieldValueNumber / 1024)
if (inHigherUnit >= 1 && units.length > index + 1) {
return returnValueWithUnit(inHigherUnit, index + 1)
} else {
return `${fieldValueNumber} ${units[index]}`
}
}

switch (props.actionName) {
case 'edit':
case 'new':
return (
<>
<TextField
autoFocus={props.autoFocus}
name={props.settings.Name}
type="number"
label={props.settings.DisplayName}
value={value}
required={props.settings.Compulsory}
disabled={props.settings.ReadOnly}
placeholder={props.settings.DisplayName}
InputProps={{
endAdornment: <InputAdornment position="end">byte</InputAdornment>,
}}
inputProps={{
step: defineStepValue(),
max: props.settings.MaxValue,
min: props.settings.MinValue,
}}
id={props.settings.Name}
fullWidth={true}
onChange={handleChange}
/>
{!props.hideDescription && <FormHelperText>{props.settings.Description}</FormHelperText>}
</>
)
case 'browse':
default:
return (
<div>
<Typography variant="caption" gutterBottom={true}>
{props.settings.DisplayName}
</Typography>
<Typography variant="body1" gutterBottom={true}>
{props.fieldValue && props.fieldValue !== '0' ? (
<>{returnValueWithUnit(toNumber(props.fieldValue)!, 0)}</>
) : (
localization.noValue
)}
</Typography>
</div>
)
}
}
1 change: 1 addition & 0 deletions packages/sn-controls-react/src/fieldcontrols/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ export * from './allowed-child-types'
export * from './client-field-setting'
export * from './icon'
export * from './localization'
export * from './file-size'
3 changes: 3 additions & 0 deletions packages/sn-controls-react/src/fieldcontrols/localization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ export const defaultLocalization = {
timePicker: {
noValue: 'No time selected',
},
fileSize: {
noValue: 'No value set',
},
}

export type FieldLocalization = DeepPartial<typeof defaultLocalization>
4 changes: 2 additions & 2 deletions packages/sn-controls-react/src/fieldcontrols/switcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ export const Switch = withStyles((theme: Theme) => ({
opacity: 1,
'&$checked': {
transform: 'translateX(12px)',
color: theme.palette.type === 'light' ? theme.palette.common.white : theme.palette.common.black,
color: theme.palette.common.white,
'& + $track': {
opacity: 1,
backgroundColor: theme.palette.type === 'light' ? theme.palette.common.black : theme.palette.common.white,
backgroundColor: theme.palette.primary.main,
borderColor: theme.palette.type === 'light' ? theme.palette.common.black : theme.palette.common.white,
},
},
Expand Down
8 changes: 6 additions & 2 deletions packages/sn-controls-react/src/react-control-mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,12 @@ export const reactControlMapper = (repository: Repository) => {
() => null,
)
controlMapper
.setupFieldSettingDefault('NumberFieldSetting', () => {
return FieldControls.NumberField
.setupFieldSettingDefault('NumberFieldSetting', (setting) => {
if (setting.ControlHint === 'sn:FileSize') {
return FieldControls.FileSizeField
} else {
return FieldControls.NumberField
}
})
.setupFieldSettingDefault('CurrencyFieldSetting', () => {
return FieldControls.NumberField
Expand Down
122 changes: 122 additions & 0 deletions packages/sn-controls-react/test/__snapshots__/file-size.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`FileSize field control in browse view should show the displayname and fieldValue with GB unit when fieldValue is provided and between 1 073 741 824 and 1 099 511 627 776 {pow(1024,4)} 1`] = `
<div>
<WithStyles(ForwardRef(Typography))
gutterBottom={true}
variant="caption"
>
Size
</WithStyles(ForwardRef(Typography))>
<WithStyles(ForwardRef(Typography))
gutterBottom={true}
variant="body1"
>
2 GB
</WithStyles(ForwardRef(Typography))>
</div>
`;

exports[`FileSize field control in browse view should show the displayname and fieldValue with KB unit when fieldValue is provided and between 1024 and 1 048 576 {pow(1024,2)} 1`] = `
<div>
<WithStyles(ForwardRef(Typography))
gutterBottom={true}
variant="caption"
>
Size
</WithStyles(ForwardRef(Typography))>
<WithStyles(ForwardRef(Typography))
gutterBottom={true}
variant="body1"
>
1.5 KB
</WithStyles(ForwardRef(Typography))>
</div>
`;

exports[`FileSize field control in browse view should show the displayname and fieldValue with MB unit when fieldValue is provided and between 1 048 576 and 1 073 741 824 {pow(1024,3)} 1`] = `
<div>
<WithStyles(ForwardRef(Typography))
gutterBottom={true}
variant="caption"
>
Size
</WithStyles(ForwardRef(Typography))>
<WithStyles(ForwardRef(Typography))
gutterBottom={true}
variant="body1"
>
1 MB
</WithStyles(ForwardRef(Typography))>
</div>
`;

exports[`FileSize field control in browse view should show the displayname and fieldValue with TB unit when fieldValue is provided and between 1 099 511 627 776 and 1 125 899 906 842 624 {pow(1024,5)} 1`] = `
<div>
<WithStyles(ForwardRef(Typography))
gutterBottom={true}
variant="caption"
>
Size
</WithStyles(ForwardRef(Typography))>
<WithStyles(ForwardRef(Typography))
gutterBottom={true}
variant="body1"
>
653.5 TB
</WithStyles(ForwardRef(Typography))>
</div>
`;

exports[`FileSize field control in browse view should show the displayname and fieldValue with byte unit when fieldValue is provided and less than 1024 1`] = `
<div>
<WithStyles(ForwardRef(Typography))
gutterBottom={true}
variant="caption"
>
Size
</WithStyles(ForwardRef(Typography))>
<WithStyles(ForwardRef(Typography))
gutterBottom={true}
variant="body1"
>
123 byte
</WithStyles(ForwardRef(Typography))>
</div>
`;

exports[`FileSize field control in edit/new view should set all the props 1`] = `
<Fragment>
<WithStyles(ForwardRef(TextField))
InputProps={
Object {
"endAdornment": <WithStyles(ForwardRef(InputAdornment))
position="end"
>
byte
</WithStyles(ForwardRef(InputAdornment))>,
}
}
disabled={true}
fullWidth={true}
id="Size"
inputProps={
Object {
"max": 50,
"min": 4,
"step": 1,
}
}
label="Size"
name="Size"
onChange={[Function]}
placeholder="Size"
required={true}
type="number"
value={7}
/>
<WithStyles(ForwardRef(FormHelperText))>
File size
</WithStyles(ForwardRef(FormHelperText))>
</Fragment>
`;
Loading

0 comments on commit d8e6688

Please sign in to comment.