diff --git a/package.json b/package.json index 5837f8ecb..828466332 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "license": "UNLICENSED", "private": false, "devDependencies": { - "@betty-blocks/cli": "^25.93.0", + "@betty-blocks/cli": "^25.98.0", "@commitlint/cli": "^16.1.0", "@commitlint/config-angular": "^16.0.0", "@semantic-release/changelog": "^6.0.1", diff --git a/src/components/dateTimePickerInput.js b/src/components/dateTimePickerInput.js index ea509aa0b..134ed728a 100644 --- a/src/components/dateTimePickerInput.js +++ b/src/components/dateTimePickerInput.js @@ -19,6 +19,7 @@ dateFormat, timeFormat, datetimeFormat, + monthFormat, size, fullWidth, required, @@ -204,6 +205,19 @@ break; } + case 'month': { + const formattedDate = DateFns.parse(parsedValue, monthFormat); + + if (isValidDate(formattedDate)) { + setSelectedDate(formattedDate); + } else { + // convert to slashes because it conflicts with the MUI DateTimeCmp + const parsedValueWithSlashes = parsedValue.replace(/-/g, '/'); + setSelectedDate(new Date(parsedValueWithSlashes)); + } + break; + } + default: } } else { @@ -221,11 +235,13 @@ let use24HourClock = true; let minDate; let maxDate; + let views; switch (type) { case 'date': { DateTimeComponent = KeyboardDatePicker; format = dateFormat || 'dd/MM/yyyy'; + views = ['year', 'date']; minDate = convertToValidDate(minValueText); maxDate = convertToValidDate(maxValueText); @@ -239,6 +255,7 @@ DateTimeComponent = KeyboardDateTimePicker; format = datetimeFormat || 'dd/MM/yyyy HH:mm:ss'; use24HourClock = use24HourClockTime; + views = ['year', 'date', 'hours', 'minutes']; resultString = isValidDate(selectedDate) ? selectedDate.toISOString() @@ -249,12 +266,23 @@ DateTimeComponent = KeyboardTimePicker; format = timeFormat || 'HH:mm:ss'; use24HourClock = use24HourClockTime; + views = ['hours', 'minutes']; resultString = isValidDate(selectedDate) ? DateFns.format(selectedDate, 'HH:mm:ss') : null; break; } + case 'month': { + DateTimeComponent = KeyboardDatePicker; + format = monthFormat || 'MMMM'; + views = ['month']; + + resultString = isValidDate(selectedDate) + ? DateFns.format(selectedDate, 'yyyy-MM') + : null; + break; + } default: } @@ -299,6 +327,7 @@ required={required} disabled={isDisabled} label={!hideLabel && labelText} + views={views} margin={margin} helperText={helper} disableToolbar={disableToolbar} diff --git a/src/prefabs/monthPickerInput.tsx b/src/prefabs/monthPickerInput.tsx new file mode 100644 index 000000000..25290f39b --- /dev/null +++ b/src/prefabs/monthPickerInput.tsx @@ -0,0 +1,338 @@ +import * as React from 'react'; +import { + BeforeCreateArgs, + Icon, + prefab as makePrefab, + PrefabComponentOption, +} from '@betty-blocks/component-sdk'; +import { DateTimePicker } from './structures/DateTimePicker'; + +const beforeCreate = ({ + close, + components: { + Content, + Field, + Footer, + Header, + FormField, + Toggle, + PropertySelector, + Label, + TextInput: Text, + CircleQuestion, + BBTooltip, + }, + prefab: originalPrefab, + save, + helpers, +}: BeforeCreateArgs) => { + const { + BettyPrefabs, + prepareInput, + useModelIdSelector, + useActionIdSelector, + usePrefabSelector, + usePropertyQuery, + setOption, + createUuid, + useModelQuery, + createBlacklist, + useModelRelationQuery, + } = helpers; + + const [propertyPath, setProperty] = React.useState(''); + const [variableInput, setVariableInput] = React.useState(null); + const modelId = useModelIdSelector(); + const actionId = useActionIdSelector(); + const selectedPrefab = usePrefabSelector(); + const [model, setModel] = React.useState(null); + const [propertyBased, setPropertyBased] = React.useState(!!modelId); + const [prefabSaved, setPrefabSaved] = React.useState(false); + + const [validationMessage, setValidationMessage] = React.useState(''); + + const modelRequest = useModelQuery({ + variables: { id: modelId }, + onCompleted: (result) => { + setModel(result.model); + }, + }); + + const validate = () => { + if (modelRequest.loading) { + setValidationMessage( + 'Model details are still loading, please try submitting again.', + ); + return false; + } + + return true; + }; + + let name: string | undefined; + let propertyKind; + let propertyModelId; + const componentId = createUuid(); + + function isProperty(path: string) { + return ( + typeof path !== 'string' && + typeof path === 'object' && + !Array.isArray(path) + ); + } + + let propertyId: string; + if (isProperty(propertyPath)) { + const { id } = propertyPath; + propertyId = Array.isArray(id) ? id[id.length - 1] : id; + } else { + propertyId = propertyPath; + } + + const propertyResponse = usePropertyQuery(propertyId); + + if (!(propertyResponse.loading || propertyResponse.error)) { + if (propertyResponse.data) { + name = propertyResponse.data.property.label; + propertyKind = propertyResponse.data.property.kind; + propertyModelId = propertyResponse.data.property.referenceModel?.id; + } + } + + const modelRelationResponse = useModelRelationQuery(propertyModelId); + + let relationalProperties; + let modelProperty; + if (!(modelRelationResponse.loading || modelRelationResponse.error)) { + if (modelRelationResponse.data) { + relationalProperties = modelRelationResponse.data.model.properties; + modelProperty = relationalProperties.find( + (property) => property.name === 'id', + ); + } + } + + const unsupportedKinds = createBlacklist(['DATE', 'TEXT', 'STRING']); + + const structure = originalPrefab.structure[0]; + + if (structure.type !== 'COMPONENT') + return
expected component prefab, found {structure.type}
; + + const handlePropertyChange = (propertyOrId): void => { + setProperty(propertyOrId); + }; + + if (!actionId && !prefabSaved) { + setPrefabSaved(true); + save(originalPrefab); + } + + const actionVariableOptionType = structure.options.find( + (option: { type: string }) => option.type === 'ACTION_JS_VARIABLE', + ); + + const actionVariableOption = actionVariableOptionType?.key || null; + const labelOptionKey = 'label'; + const nameOptionKey = 'actionVariableId'; + + return ( + <> +
+ + {modelId && ( + + setPropertyBased(!propertyBased)}> + {}} + /> + + + )} + {propertyBased ? ( + {validationMessage} + ) + } + > + + + ) : ( + + + + setVariableInput(e.target.value)} + color="orange" + /> + + )} + +