Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Phumudzo/fix/1468 #1479

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions shesha-reactjs/src/components/dataTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -219,14 +219,14 @@ export const DataTable: FC<Partial<IIndexTableProps>> = ({
const onNewRowInitialize = useMemo<RowDataInitializer>(() => {
const result: RowDataInitializer = props.onNewRowInitialize
? () => {
// todo: replace formData and globalState with accessors (e.g. refs) and remove hooks to prevent unneeded re-rendering
//return onNewRowInitializeExecuter(formData, globalState);
const result = onNewRowInitializeExecuter(formData ?? {}, globalState, axiosHttp(backendUrl), moment, appContextData);
return Promise.resolve(result);
}
// todo: replace formData and globalState with accessors (e.g. refs) and remove hooks to prevent unneeded re-rendering
//return onNewRowInitializeExecuter(formData, globalState);
const result = onNewRowInitializeExecuter(formData ?? {}, globalState, axiosHttp(backendUrl), moment, appContextData);
return Promise.resolve(result);
}
: () => {
return Promise.resolve({});
};
return Promise.resolve({});
};

return result;
}, [onNewRowInitializeExecuter, formData, globalState]);
Expand Down Expand Up @@ -709,8 +709,8 @@ export const DataTable: FC<Partial<IIndexTableProps>> = ({
<div className={styles.shaChildTableErrorContainer}>
{exportToExcelError && <ValidationErrors error={'Error occurred while exporting to excel'} />}
</div>
{tableProps.columns && tableProps.columns.length > 0 && <ReactTable {...tableProps} />}

{tableProps.columns && tableProps.columns.length > 0 && <ReactTable {...tableProps} />}
</Fragment>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ export const QueryBuilderContent: FC<IQueryBuilderContentProps> = ({
onChange(jsonLogicResult);
}
};

return (
<div className={styles.shaQueryBuilder}>
{tree && qbConfig && <Query {...qbConfig} value={tree} onChange={handleChange} renderBuilder={renderBuilder} />}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,13 @@ export const ReadOnlyDisplayFormItem: FC<IReadOnlyDisplayFormItemProps> = ({
);
}
case 'time': {
return <ValueRenderer value={value} meta={{ dataType: 'time', dataFormat: timeFormat }}/>;
return <ValueRenderer value={value} meta={{ dataType: 'time', dataFormat: timeFormat }} />;
}
case 'datetime': {
if (typeof value === 'string') {
return moment(value).format(dateFormat);
}

return getMoment(value, dateFormat)?.toISOString() || '';
return getMoment(value)?.format(dateFormat) || '';
}
case 'checkbox': {
return <Checkbox checked={checked} defaultChecked={defaultChecked} disabled />;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const NotConfiguredWarning: FC = () => {

export const TableWrapper: FC<ITableComponentProps> = (props) => {
const { id, items, useMultiselect, tableStyle, containerStyle } = props;

const { formMode } = useForm();
const { data: formData } = useFormData();
const { globalState } = useGlobalState();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ const DateField: IToolboxComponent<IDateFieldProps> = {
<Fragment>
<ConfigurableFormItem model={model}>
{(value, onChange) => {
const customEvent = customDateEventHandler(eventProps);
const customEvent = customDateEventHandler(eventProps);
const onChangeInternal = (...args: any[]) => {
customEvent.onChange(args[0], args[1]);
if (typeof onChange === 'function')
if (typeof onChange === 'function')
onChange(...args);
};

return <DatePickerWrapper {...model} {...customEvent} value={value} onChange={onChangeInternal} />;
}}
</ConfigurableFormItem>
Expand Down
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed localValue since it returning the same date as datesString which is simple to manipulate and format
I thought of retaining it for user manipulation but it eventualklly returns the same date as dateString

Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import { DatePicker } from '@/components/antd';
import moment, { isMoment } from 'moment';
import moment, { Moment } from 'moment';
import React, { FC } from 'react';
import ReadOnlyDisplayFormItem from '@/components/readOnlyDisplayFormItem';
import { useForm, useGlobalState, useMetadata } from '@/providers';
import { getStyle } from '@/providers/form/utils';
import { getMoment } from '@/utils/date';
import { getDataProperty } from '@/utils/metadata';
import { IDateFieldProps, RangePickerChangeEvent, TimePickerChangeEvent } from './interfaces';
import {
DATE_TIME_FORMATS,
disabledDate,
getDatePickerValue,
getDefaultFormat,
getFormat,
getRangePickerValues,
getUtcAlignedDate,
} from './utils';
import { asPropertiesArray } from '@/interfaces/metadata';


const MIDNIGHT_MOMENT = moment('00:00:00', 'HH:mm:ss');

const { RangePicker } = DatePicker;
Expand All @@ -36,7 +36,7 @@ export const DatePickerWrapper: FC<IDateFieldProps> = (props) => {
showNow,
showToday,
onChange,
picker = 'date',
picker = "date",
defaultValue,
disabledDateMode,
disabledDateTemplate,
Expand All @@ -47,49 +47,40 @@ export const DatePickerWrapper: FC<IDateFieldProps> = (props) => {
...rest
} = props;

const dateFormat = props?.dateFormat || getDataProperty(properties, name) || DATE_TIME_FORMATS.date;
const timeFormat = props?.timeFormat || DATE_TIME_FORMATS.time;

const defaultFormat = getDefaultFormat(props);

const { formData } = useForm();

const pickerFormat = getFormat(props, properties);
const formattedValue = getMoment(value, pickerFormat);

const handleDatePickerChange = (localValue: any | null, dateString: string) => {
const formattedValue = getMoment(value);

const handleDatePickerChange = (localValue: Moment | any, dateString: string) => {
if (!dateString?.trim()) {
(onChange as TimePickerChangeEvent)(null, '');
return;
}

const newValue = isMoment(localValue) ? localValue.format(pickerFormat) : localValue;

(onChange as TimePickerChangeEvent)(newValue, dateString);
};
(onChange as TimePickerChangeEvent)(getUtcAlignedDate(localValue), dateString);
};

const handleRangePicker = (values: any[], formatString: [string, string]) => {
if (formatString?.includes('')) {
(onChange as RangePickerChangeEvent)(null, null);
return;
}
const dates = (values as []).map((val: any) => {
if (isMoment(val)) return val.format(defaultFormat);

return val;
});
const newUTCValues = values.map((v) => getUtcAlignedDate(v));

(onChange as RangePickerChangeEvent)(dates, formatString);
(onChange as RangePickerChangeEvent)(newUTCValues, formatString);
};

if (readOnly) {
const format = showTime
? `${dateFormat} ${timeFormat}`
: dateFormat;
? `${pickerFormat} ${timeFormat}`
: pickerFormat;

return (
<ReadOnlyDisplayFormItem
value={formattedValue?.toISOString()}
value={formattedValue}
type="datetime"
dateFormat={format}
timeFormat={timeFormat}
Expand Down Expand Up @@ -135,8 +126,8 @@ export const DatePickerWrapper: FC<IDateFieldProps> = (props) => {
format={pickerFormat}
style={evaluatedStyle}
{...rest}
{...getDatePickerValue(props, pickerFormat)}
{...getDatePickerValue(props)}
allowClear
/>
);
};
};
18 changes: 14 additions & 4 deletions shesha-reactjs/src/designer-components/dateField/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,23 @@ import { IDateFieldProps, RangeValue } from './interfaces';

export const DATE_TIME_FORMATS = {
time: 'HH:mm:ss',
week: 'YYYY-wo',
week: 'gggg-[W]ww',
date: 'DD/MM/YYYY',
quarter: 'YYYY-\\QQ',
month: 'YYYY-MM',
year: 'YYYY',
};

export const getDatePickerValue = (props: IDateFieldProps, pickerFormat: string) => {
export const getDatePickerValue = (props: IDateFieldProps) => {
const { value, injectedDefaultValue } = props;

/** Used to changed value/defaultValue based on whether it's rendered on the table **/
if (injectedDefaultValue) {
return { defaultValue: getMoment(value, pickerFormat) };
return { defaultValue: getMoment(value) };
}

/** Used to handle the value based on default date-picker implementation **/
return { value: getMoment(value, pickerFormat) };
return { value: getMoment(value) };
};

export function disabledDate(props: IDateFieldProps, current: Moment, data: object, globalState: object) {
Expand Down Expand Up @@ -82,3 +82,13 @@ export const getRangePickerValues = (valueToUse: any, pickerFormat: string) =>
(Array.isArray(valueToUse) && valueToUse?.length === 2
? valueToUse?.map((v) => moment(new Date(v), pickerFormat))
: [null, null]) as RangeValue;

export const getUtcAlignedDate = (date: Moment) => {
if (date?.isUTC()) {
return date;
};
const offsetHours = date.utcOffset() / 60;

return date.utc().add(offsetHours, 'hours');

};
41 changes: 28 additions & 13 deletions shesha-reactjs/src/designer-components/text/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import moment from 'moment';
import { getNumberFormat } from '@/utils/string';
import {
ContentDisplay,
Expand All @@ -9,6 +8,7 @@ import {
TypographyPaddingSize,
} from './models';
import { DATE_TIME_FORMATS } from '../dateField/utils';
import { getMoment } from '@/utils/date';

export const getFontSizeStyle = (key: TypographyFontSize) => FONT_SIZES[key];
export const getPaddingSizeStyle = (key: TypographyPaddingSize) => PADDING_SIZES[key];
Expand All @@ -25,29 +25,44 @@ export interface IContent {
}

const formatDate = (dateText: string, dateFormat: string) => {
return moment(dateText).isValid() ? moment(dateText).format(dateFormat) : dateText;
return getMoment(dateText).format(dateFormat);
};

export const formatDateStringAndPrefix = (content: string, dateFormat: string = DATE_TIME_FORMATS.date) => {
const dateTimeRegex = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/;
const dateRegex = /\d{4}-\d{2}-\d{2}/;
export const formatDateStringAndPrefix = (content: string, dateFormat: string) => {
const dateTimeRegexes = [
/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z/, // ISO 8601 format: YYYY-MM-DDTHH:mm:ssZ
/[A-Za-z]{3} [A-Za-z]{3} \d{2} \d{4} \d{2}:\d{2}:\d{2} GMT[+-]\d{4}/, // RFC 2822 format: Mon Jan 02 2006 15:04:05 GMT-0700
/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/, // YYYY-MM-DDTHH:mm:ss
/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/, // YYYY-MM-DD HH:mm:ss
/\d{2}-\d{2}-\d{4} \d{2}:\d{2}:\d{2}/, // DD-MM-YYYY HH:mm:ss
/\d{2}\/\d{2}\/\d{4} \d{2}:\d{2}:\d{2}/, // DD/MM/YYYY HH:mm:ss
/\d{4}\/\d{2}\/\d{2} \d{2}:\d{2}:\d{2}/, // YYYY/MM/DD HH:mm:ss
];

const match = dateTimeRegex.exec(content) || dateRegex.exec(content);
const dateRegexes = [
/\d{4}-\d{2}-\d{2}/,
/\d{2}\/\d{2}\/\d{4}/,
/\d{4}\/\d{2}\/\d{2}/,
/\d{2}-\d{2}-\d{4}/,
];

if (match) {
const dateString = match[0];
return content.replace(dateString, formatDate(dateString, dateFormat));
} else {
return content;
}
for (const regex of [...dateTimeRegexes, ...dateRegexes]) {
const match = regex.exec(content);
if (match) {
const dateString = match[0];
return content.replace(dateString, formatDate(dateString, dateFormat));
}
};

return content;
};

export const getContent = (content: string, { dataType = 'string', dateFormat, numberFormat }: IContent = {}) => {
switch (dataType) {
case 'boolean':
return content ? 'Yes' : 'No';
case 'date-time':
return formatDateStringAndPrefix(content, dateFormat);
return formatDateStringAndPrefix(content, dateFormat || DATE_TIME_FORMATS.date);
case 'number':
return getNumberFormat(content, numberFormat || 'round');

Expand Down
2 changes: 1 addition & 1 deletion shesha-reactjs/src/interfaces/formComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export enum StandardNodeTypes {
ConfigurableActionConfig = 'action-config',
};

export interface IFormComponentDataType {}
export interface IFormComponentDataType { }

export type StringValueChange = (key: string, value: string) => void;
export type NumberValueChange = (key: string, value: number) => void;
Expand Down
9 changes: 6 additions & 3 deletions shesha-reactjs/src/providers/crudContext/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ const CrudProvider: FC<PropsWithChildren<ICrudProviderProps>> = (props) => {

useEffect(() => {
//to restore the edit pen when toggling between inLine edit mode(all-at-once/one-by-one)
const modeToUse = mode ==='read'?mode:allowChangeMode ? state.mode : mode;
const modeToUse = mode === 'read' ? mode : allowChangeMode ? state.mode : mode;

if (state.allowChangeMode !== allowChangeMode || state.mode !== modeToUse)
switchModeInternal(modeToUse, allowChangeMode);
Expand Down Expand Up @@ -172,12 +172,15 @@ const CrudProvider: FC<PropsWithChildren<ICrudProviderProps>> = (props) => {
props.editorComponents.allComponents,
toolboxComponents
);

console.log('Data post', postData);
// send data of stored files
if (Boolean(delayedUpdate)) postData._delayedUpdate = delayedUpdate.current;

const finalDataPromise = onSave ? Promise.resolve(onSave(postData)) : Promise.resolve(postData);

return finalDataPromise.then((finalData) => {
console.log('Data final', finalData);
return processor(finalData)
.then(() => {
dispatch(saveSuccessAction());
Expand Down Expand Up @@ -290,8 +293,8 @@ const CrudProvider: FC<PropsWithChildren<ICrudProviderProps>> = (props) => {
mode={state.mode === 'read' ? 'readonly' : 'edit'}
isActionsOwner={false}
>
<ParentProvider model={{readOnly: state.mode === 'read'}} formMode={state.mode === 'read' ? 'readonly' : 'edit'}>
<FormWrapper
<ParentProvider model={{ readOnly: state.mode === 'read' }} formMode={state.mode === 'read' ? 'readonly' : 'edit'}>
<FormWrapper
form={form} initialValues={state.initialValues} onValuesChange={onValuesChange}
formSettings={formSettings} delayedUpdate={delayedUpdate}
>
Expand Down
26 changes: 13 additions & 13 deletions shesha-reactjs/src/providers/dataTable/utils.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
import moment, { Duration, Moment, isDuration, isMoment } from 'moment';
import { ProperyDataType } from '@/interfaces/metadata';
import {
import {
IConfigurableColumnsProps,
IFormColumnsProps,
isActionColumnProps,
isDataColumnProps
isDataColumnProps
} from '@/providers/datatableColumnsConfigurator/models';
import { camelcaseDotNotation } from '@/utils/string';
import { IDataTableStateContext, IDataTableUserConfig, MIN_COLUMN_WIDTH } from './contexts';
import {
ColumnSorting,
import {
ColumnSorting,
DataTableColumnDto,
IColumnSorting,
isDataColumn,
isFormColumn,
IStoredFilter,
ITableActionColumn,
ITableColumn,
ITableDataColumn,
ITableFilter,
ITableFormColumn,
isDataColumn,
isFormColumn,
IStoredFilter,
ITableActionColumn,
ITableColumn,
ITableDataColumn,
ITableFilter,
ITableFormColumn,
SortDirection
} from './interfaces';

Expand Down Expand Up @@ -218,7 +218,7 @@ export const prepareColumn = (
id: column.propertyName,
accessor: camelcaseDotNotation(column?.propertyName),
propertyName: column.propertyName,

propertiesToFetch: column.propertyName,
isEnitty: srvColumn?.dataType === 'entity',

Expand Down
Loading