From 5c53bf4628fdc2853a8a3057c7a45443a23aaab7 Mon Sep 17 00:00:00 2001 From: manugallegob Date: Sat, 19 Oct 2024 14:13:52 +0200 Subject: [PATCH 1/4] subida inicial de archivos para timepickerinline --- .../mock-components/front-components/index.ts | 2 +- .../front-components/timepickerinput/index.ts | 1 + .../timepickerinput-shape.business.ts | 40 ++++++++++ .../timepickerinput-shape.tsx | 75 +++++++++++++------ .../canvas/model/inline-editable.model.ts | 3 + .../timepickerinput.renderer.tsx | 2 + .../active-element-selector.component.tsx | 2 +- 7 files changed, 100 insertions(+), 25 deletions(-) create mode 100644 src/common/components/mock-components/front-components/timepickerinput/index.ts create mode 100644 src/common/components/mock-components/front-components/timepickerinput/timepickerinput-shape.business.ts rename src/common/components/mock-components/front-components/{ => timepickerinput}/timepickerinput-shape.tsx (52%) diff --git a/src/common/components/mock-components/front-components/index.ts b/src/common/components/mock-components/front-components/index.ts index ae303ff1..fe28a671 100644 --- a/src/common/components/mock-components/front-components/index.ts +++ b/src/common/components/mock-components/front-components/index.ts @@ -7,7 +7,7 @@ export * from './progressbar-shape'; export * from './listbox'; export * from './datepickerinput-shape'; export * from './button-shape'; -export * from './timepickerinput-shape'; +export * from './timepickerinput/timepickerinput-shape'; export * from './radiobutton-shape'; export * from './icon-shape'; export * from './verticalscrollbar-shape'; diff --git a/src/common/components/mock-components/front-components/timepickerinput/index.ts b/src/common/components/mock-components/front-components/timepickerinput/index.ts new file mode 100644 index 00000000..b2663481 --- /dev/null +++ b/src/common/components/mock-components/front-components/timepickerinput/index.ts @@ -0,0 +1 @@ +export * from './timepickerinput-shape.tsx'; diff --git a/src/common/components/mock-components/front-components/timepickerinput/timepickerinput-shape.business.ts b/src/common/components/mock-components/front-components/timepickerinput/timepickerinput-shape.business.ts new file mode 100644 index 00000000..929a53a0 --- /dev/null +++ b/src/common/components/mock-components/front-components/timepickerinput/timepickerinput-shape.business.ts @@ -0,0 +1,40 @@ +export const getCurrentTime = () => { + const currentDate = new Date(); + let hour = currentDate.getHours().toString(); + let minutes = currentDate.getMinutes().toString(); + hour = hour.length < 2 ? '0' + hour : hour; + minutes = minutes.length < 2 ? '0' + minutes : minutes; + return `${hour},${minutes}`; +}; + +export const splitCSVContent = (csvContent: string): string[] => { + const splitedCsvContent = csvContent + .trim() + .split(',') + .map(el => el.trim()) + .map(header => { + const cleanedHeaderText = header.replace(/[^0-9]/g, '').trim(); + return cleanedHeaderText; + }); + return splitedCsvContent; +}; + +export const setTime = (csvData: string[]) => { + if (csvData.length > 2) csvData = csvData.slice(0, 2); + + if (csvData.length === 1) csvData.push('00'); + + let [hora, minutos] = csvData; + + if (hora.length === 1) hora = '0' + hora; + + if (hora.length > 2 || (hora.length === 2 && hora > '23')) hora = '23'; + + if (hora === '') hora = '00'; + + if (minutos.length > 2 || minutos > '59' || minutos === '') minutos = '00'; + + if (minutos.length < 1) minutos = '0' + minutos; + + return [hora, minutos]; +}; diff --git a/src/common/components/mock-components/front-components/timepickerinput-shape.tsx b/src/common/components/mock-components/front-components/timepickerinput/timepickerinput-shape.tsx similarity index 52% rename from src/common/components/mock-components/front-components/timepickerinput-shape.tsx rename to src/common/components/mock-components/front-components/timepickerinput/timepickerinput-shape.tsx index a4b64adc..18d729f2 100644 --- a/src/common/components/mock-components/front-components/timepickerinput-shape.tsx +++ b/src/common/components/mock-components/front-components/timepickerinput/timepickerinput-shape.tsx @@ -1,11 +1,12 @@ import { ShapeSizeRestrictions, ShapeType } from '@/core/model'; import { forwardRef } from 'react'; -import { ShapeProps } from '../shape.model'; +import { ShapeProps } from '../../shape.model'; import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions'; import { Group, Rect, Text } from 'react-konva'; -import { BASIC_SHAPE } from './shape.const'; -import { useShapeProps } from '../../shapes/use-shape-props.hook'; -import { useGroupShapeProps } from '../mock-components.utils'; +import { BASIC_SHAPE } from '../shape.const'; +import { useShapeProps } from '../../../shapes/use-shape-props.hook'; +import { useGroupShapeProps } from '../../mock-components.utils'; +import { splitCSVContent, setTime } from './timepickerinput-shape.business'; const timepickerInputShapeRestrictions: ShapeSizeRestrictions = { minWidth: 100, @@ -23,8 +24,18 @@ export const getTimepickerInputShapeSizeRestrictions = export const TimepickerInputShape = forwardRef( (props, ref) => { - const { x, y, width, height, id, onSelected, otherProps, ...shapeProps } = - props; + const { + x, + y, + width, + height, + id, + text, + onSelected, + otherProps, + ...shapeProps + } = props; + const restrictedSize = fitSizeToShapeSizeRestrictions( timepickerInputShapeRestrictions, width, @@ -32,6 +43,9 @@ export const TimepickerInputShape = forwardRef( ); const { width: restrictedWidth, height: restrictedHeight } = restrictedSize; + const csvData2 = splitCSVContent(text); + const time = setTime(csvData2); + const separatorPadding = 3; // Extra padding for spacers const separator1X = restrictedWidth / 3; const separator2X = (2 * restrictedWidth) / 3; @@ -48,6 +62,8 @@ export const TimepickerInputShape = forwardRef( ref ); + const dynamicTabWidth = restrictedWidth / time.length; + return ( {/* input frame */} @@ -63,23 +79,36 @@ export const TimepickerInputShape = forwardRef( fill={fill} /> - {/* Separators : */} - - + {time.map((time, index) => ( + + + {index < time.length - 1 && ( + + )} + + ))} ); } diff --git a/src/pods/canvas/model/inline-editable.model.ts b/src/pods/canvas/model/inline-editable.model.ts index a32cf96b..f3eeb91e 100644 --- a/src/pods/canvas/model/inline-editable.model.ts +++ b/src/pods/canvas/model/inline-editable.model.ts @@ -30,6 +30,7 @@ const inlineEditableShapes = new Set([ 'buttonBar', 'tabsBar', 'tooltip', + 'timepickerinput', ]); // Check if a shape type allows inline editing @@ -64,6 +65,7 @@ const shapeTypesWithDefaultText = new Set([ 'appBar', 'buttonBar', 'tabsBar', + 'timepickerinput', ]); // Map of ShapeTypes to their default text values @@ -95,6 +97,7 @@ const defaultTextValueMap: Partial> = { appBar: 'AppBar', buttonBar: 'Button 1, Button 2, Button 3', tabsBar: 'Tab 1, Tab 2, Tab 3', + timepickerinput: 'hh, mm', }; export const generateDefaultTextValue = ( diff --git a/src/pods/canvas/shape-renderer/simple-component/timepickerinput.renderer.tsx b/src/pods/canvas/shape-renderer/simple-component/timepickerinput.renderer.tsx index 99bc8425..6476b6b6 100644 --- a/src/pods/canvas/shape-renderer/simple-component/timepickerinput.renderer.tsx +++ b/src/pods/canvas/shape-renderer/simple-component/timepickerinput.renderer.tsx @@ -25,6 +25,8 @@ export const renderTimepickerinput = ( onDragEnd={handleDragEnd(shape.id)} onTransform={handleTransform} onTransformEnd={handleTransform} + isEditable={shape.allowsInlineEdition} + text={shape.text} otherProps={shape.otherProps} /> ); diff --git a/src/pods/properties/components/active-element-selector/active-element-selector.component.tsx b/src/pods/properties/components/active-element-selector/active-element-selector.component.tsx index dd827294..9b0c6b71 100644 --- a/src/pods/properties/components/active-element-selector/active-element-selector.component.tsx +++ b/src/pods/properties/components/active-element-selector/active-element-selector.component.tsx @@ -27,7 +27,7 @@ export const ActiveElementSelector: React.FC = ({ // Checking whether the type is tabsBar and parsing the text const isElementTypeSupported = - type === 'tabsBar' || 'buttonBar' || 'horizontal-menu'; + type === 'tabsBar' || 'buttonBar' || 'horizontal-menu' || 'timepickerinput'; const elementNames = isElementTypeSupported && text ? extractElementNames(text) : []; From dde3c838b639352ec9d00b0d1d7ad46145f5f498 Mon Sep 17 00:00:00 2001 From: manugallegob Date: Sat, 19 Oct 2024 14:15:45 +0200 Subject: [PATCH 2/4] timepickerinput file components --- .../timepickerinput/timepickerinput-shape.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/components/mock-components/front-components/timepickerinput/timepickerinput-shape.tsx b/src/common/components/mock-components/front-components/timepickerinput/timepickerinput-shape.tsx index 18d729f2..64ae9349 100644 --- a/src/common/components/mock-components/front-components/timepickerinput/timepickerinput-shape.tsx +++ b/src/common/components/mock-components/front-components/timepickerinput/timepickerinput-shape.tsx @@ -47,8 +47,8 @@ export const TimepickerInputShape = forwardRef( const time = setTime(csvData2); const separatorPadding = 3; // Extra padding for spacers - const separator1X = restrictedWidth / 3; - const separator2X = (2 * restrictedWidth) / 3; + // const separator1X = restrictedWidth / 3; + // const separator2X = (2 * restrictedWidth) / 3; const { stroke, strokeStyle, fill, borderRadius } = useShapeProps( otherProps, From 108336465caff7f71eddd5d1b8cb84048c8b91f7 Mon Sep 17 00:00:00 2001 From: manugallegob Date: Sun, 20 Oct 2024 13:47:08 +0200 Subject: [PATCH 3/4] refactor timepicker svg and new component behavior --- public/widgets/timepicker.svg | 36 ++++-- .../datepickerinput-shape.tsx | 10 ++ .../timepickerinput-shape.business.ts | 49 +++----- .../timepickerinput/timepickerinput-shape.tsx | 110 +++++++++++------- .../canvas/model/inline-editable.model.ts | 2 +- 5 files changed, 122 insertions(+), 85 deletions(-) diff --git a/public/widgets/timepicker.svg b/public/widgets/timepicker.svg index d71771ce..fe80aecf 100644 --- a/public/widgets/timepicker.svg +++ b/public/widgets/timepicker.svg @@ -1,13 +1,25 @@ - - - - - - - : - - - : - + + + + + + Time + + + + + hh:mm + + + + + + + + + + + + + diff --git a/src/common/components/mock-components/front-components/datepickerinput-shape.tsx b/src/common/components/mock-components/front-components/datepickerinput-shape.tsx index 17d64b21..e3b1d90a 100644 --- a/src/common/components/mock-components/front-components/datepickerinput-shape.tsx +++ b/src/common/components/mock-components/front-components/datepickerinput-shape.tsx @@ -111,6 +111,16 @@ export const DatepickerInputShape = forwardRef( ellipsis={true} wrap="none" /> + + {/* Calendar Icon */} { - const currentDate = new Date(); - let hour = currentDate.getHours().toString(); - let minutes = currentDate.getMinutes().toString(); - hour = hour.length < 2 ? '0' + hour : hour; - minutes = minutes.length < 2 ? '0' + minutes : minutes; - return `${hour},${minutes}`; -}; - export const splitCSVContent = (csvContent: string): string[] => { const splitedCsvContent = csvContent .trim() - .split(',') - .map(el => el.trim()) - .map(header => { - const cleanedHeaderText = header.replace(/[^0-9]/g, '').trim(); - return cleanedHeaderText; - }); + .split(/[:|,]/) + .map(el => el.trim()); return splitedCsvContent; }; export const setTime = (csvData: string[]) => { - if (csvData.length > 2) csvData = csvData.slice(0, 2); - - if (csvData.length === 1) csvData.push('00'); - let [hora, minutos] = csvData; - - if (hora.length === 1) hora = '0' + hora; - - if (hora.length > 2 || (hora.length === 2 && hora > '23')) hora = '23'; - - if (hora === '') hora = '00'; - - if (minutos.length > 2 || minutos > '59' || minutos === '') minutos = '00'; - - if (minutos.length < 1) minutos = '0' + minutos; - - return [hora, minutos]; + if (csvData.length < 2) { + return true; + } + if (csvData[0] !== 'hh' || csvData[1] !== 'mm') { + if ( + csvData.length > 2 || + hora.length !== 2 || + hora === '' || + hora > '23' || + minutos.length !== 2 || + minutos === '' || + minutos > '59' + ) { + return true; + } + } }; diff --git a/src/common/components/mock-components/front-components/timepickerinput/timepickerinput-shape.tsx b/src/common/components/mock-components/front-components/timepickerinput/timepickerinput-shape.tsx index 64ae9349..c40f9f3c 100644 --- a/src/common/components/mock-components/front-components/timepickerinput/timepickerinput-shape.tsx +++ b/src/common/components/mock-components/front-components/timepickerinput/timepickerinput-shape.tsx @@ -2,12 +2,14 @@ import { ShapeSizeRestrictions, ShapeType } from '@/core/model'; import { forwardRef } from 'react'; import { ShapeProps } from '../../shape.model'; import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions'; -import { Group, Rect, Text } from 'react-konva'; +import { Group, Rect, Text, Image } from 'react-konva'; import { BASIC_SHAPE } from '../shape.const'; import { useShapeProps } from '../../../shapes/use-shape-props.hook'; import { useGroupShapeProps } from '../../mock-components.utils'; import { splitCSVContent, setTime } from './timepickerinput-shape.business'; +import clockIconSrc from '/icons/clock.svg'; + const timepickerInputShapeRestrictions: ShapeSizeRestrictions = { minWidth: 100, minHeight: 50, @@ -43,13 +45,6 @@ export const TimepickerInputShape = forwardRef( ); const { width: restrictedWidth, height: restrictedHeight } = restrictedSize; - const csvData2 = splitCSVContent(text); - const time = setTime(csvData2); - - const separatorPadding = 3; // Extra padding for spacers - // const separator1X = restrictedWidth / 3; - // const separator2X = (2 * restrictedWidth) / 3; - const { stroke, strokeStyle, fill, borderRadius } = useShapeProps( otherProps, BASIC_SHAPE @@ -62,11 +57,24 @@ export const TimepickerInputShape = forwardRef( ref ); - const dynamicTabWidth = restrictedWidth / time.length; + const csvData = splitCSVContent(text); + let isError = setTime(csvData); + + const iconWidth = 25; + const availableWidth = restrictedWidth - iconWidth - 20; + const fontSize = Math.min( + availableWidth * 0.2, + restrictedHeight * 0.35, + 20 + ); + const labelFontSize = Math.min(restrictedHeight * 0.3, 12); + + const clockIcon = new window.Image(); + clockIcon.src = clockIconSrc; return ( - {/* input frame */} + {/* External Rectangle */} ( height={restrictedHeight} cornerRadius={borderRadius} stroke={stroke} - strokeWidth={2} dash={strokeStyle} + strokeWidth={2} fill={fill} /> + {/* Background of Date Label */} + + {/* Label "Date" */} + + {/* Main Text */} + + {isError && ( + + )} - {time.map((time, index) => ( - - - {index < time.length - 1 && ( - - )} - - ))} + {/* Calendar Icon */} + ); } diff --git a/src/pods/canvas/model/inline-editable.model.ts b/src/pods/canvas/model/inline-editable.model.ts index 6ae2de79..1508e5db 100644 --- a/src/pods/canvas/model/inline-editable.model.ts +++ b/src/pods/canvas/model/inline-editable.model.ts @@ -99,7 +99,7 @@ const defaultTextValueMap: Partial> = { appBar: 'AppBar', buttonBar: 'Button 1, Button 2, Button 3', tabsBar: 'Tab 1, Tab 2, Tab 3', - timepickerinput: 'hh, mm', + timepickerinput: 'hh:mm', datepickerinput: new Date().toLocaleDateString(), }; From 3378698a3cf858f64e3f1a474ffe0d48bb5d6049 Mon Sep 17 00:00:00 2001 From: manugallegob Date: Sun, 27 Oct 2024 09:23:27 +0100 Subject: [PATCH 4/4] timepicker component modification: svg, const in english and style --- public/widgets/timepicker.svg | 33 +++++++++---------- .../timepickerinput-shape.business.ts | 24 +++++++++----- .../timepickerinput/timepickerinput-shape.tsx | 19 +++++++---- 3 files changed, 43 insertions(+), 33 deletions(-) diff --git a/public/widgets/timepicker.svg b/public/widgets/timepicker.svg index fe80aecf..1a262986 100644 --- a/public/widgets/timepicker.svg +++ b/public/widgets/timepicker.svg @@ -1,25 +1,24 @@ - + - - + + + Time - Time - - - - hh:mm + + hh:mm - - - - - + + + + + + + - + + + - - - diff --git a/src/common/components/mock-components/front-components/timepickerinput/timepickerinput-shape.business.ts b/src/common/components/mock-components/front-components/timepickerinput/timepickerinput-shape.business.ts index 3b0df9e0..a257c096 100644 --- a/src/common/components/mock-components/front-components/timepickerinput/timepickerinput-shape.business.ts +++ b/src/common/components/mock-components/front-components/timepickerinput/timepickerinput-shape.business.ts @@ -1,3 +1,9 @@ +const MAX_DIGITS = 2; +const MAX_HOURS = '23'; +const MAX_MINUTES = '59'; +const HOUR_MASK = 'hh'; +const MINUTES_MASK = 'mm'; + export const splitCSVContent = (csvContent: string): string[] => { const splitedCsvContent = csvContent .trim() @@ -7,19 +13,19 @@ export const splitCSVContent = (csvContent: string): string[] => { }; export const setTime = (csvData: string[]) => { - let [hora, minutos] = csvData; + let [hour, minutes] = csvData; if (csvData.length < 2) { return true; } - if (csvData[0] !== 'hh' || csvData[1] !== 'mm') { + if (csvData[0] !== HOUR_MASK || csvData[1] !== MINUTES_MASK) { if ( - csvData.length > 2 || - hora.length !== 2 || - hora === '' || - hora > '23' || - minutos.length !== 2 || - minutos === '' || - minutos > '59' + csvData.length > MAX_DIGITS || + hour.length !== MAX_DIGITS || + hour === '' || + hour > MAX_HOURS || + minutes.length !== MAX_DIGITS || + minutes === '' || + minutes > MAX_MINUTES ) { return true; } diff --git a/src/common/components/mock-components/front-components/timepickerinput/timepickerinput-shape.tsx b/src/common/components/mock-components/front-components/timepickerinput/timepickerinput-shape.tsx index c40f9f3c..a0ec43c8 100644 --- a/src/common/components/mock-components/front-components/timepickerinput/timepickerinput-shape.tsx +++ b/src/common/components/mock-components/front-components/timepickerinput/timepickerinput-shape.tsx @@ -83,24 +83,26 @@ export const TimepickerInputShape = forwardRef( cornerRadius={borderRadius} stroke={stroke} dash={strokeStyle} - strokeWidth={2} + strokeWidth={BASIC_SHAPE.DEFAULT_STROKE_WIDTH} fill={fill} /> - {/* Background of Date Label */} + {/* Background of Time Label */} - {/* Label "Date" */} + {/* Label "Time" */} ( {/* Main Text */} + {/* Error Text */} {isError && ( ( /> )} - {/* Calendar Icon */} + {/* Clock Icon */}