diff --git a/public/index.html b/public/index.html index 66fb271..03b5590 100644 --- a/public/index.html +++ b/public/index.html @@ -21,7 +21,7 @@ Coded by www.creative-tim.com - QQQ Material Dashboard + diff --git a/src/qqq/components/widgets/DashboardWidgets.tsx b/src/qqq/components/widgets/DashboardWidgets.tsx index c7fb36e..0ee5951 100644 --- a/src/qqq/components/widgets/DashboardWidgets.tsx +++ b/src/qqq/components/widgets/DashboardWidgets.tsx @@ -243,7 +243,7 @@ function DashboardWidgets({widgetMetaDataList, tableName, entityPrimaryKey, omit { widgetMetaData.type === "html" && ( - + { widgetData && widgetData[i] && widgetData[i].html ? ( diff --git a/src/qqq/components/widgets/Widget.tsx b/src/qqq/components/widgets/Widget.tsx index 00e542a..320b916 100644 --- a/src/qqq/components/widgets/Widget.tsx +++ b/src/qqq/components/widgets/Widget.tsx @@ -142,7 +142,7 @@ function Widget(props: React.PropsWithChildren): JSX.Element { const link = component as HeaderLink return ( - + {link.to ? {link.label} : null} ); @@ -153,7 +153,7 @@ function Widget(props: React.PropsWithChildren): JSX.Element const addNewRecordButton = component as AddNewRecordButton return ( - + ); } diff --git a/src/qqq/pages/apps/Home.tsx b/src/qqq/pages/apps/Home.tsx index 6771285..f2bb0ae 100644 --- a/src/qqq/pages/apps/Home.tsx +++ b/src/qqq/pages/apps/Home.tsx @@ -173,7 +173,7 @@ function AppHome({app}: Props): JSX.Element const widgetCount = widgets ? widgets.length : 0; // eslint-disable-next-line no-nested-ternary - const tileSizeLg = (widgetCount === 0 ? 3 : widgetCount === 1 ? 4 : 6); + const tileSizeLg = 3; const handleDropdownOnChange = (value: string, index: number) => { @@ -207,7 +207,7 @@ function AppHome({app}: Props): JSX.Element { app.sections ? ( - + {app.sections.map((section) => ( diff --git a/src/qqq/pages/records/query/GridFilterOperators.tsx b/src/qqq/pages/records/query/GridFilterOperators.tsx index ff36692..d85a2ee 100644 --- a/src/qqq/pages/records/query/GridFilterOperators.tsx +++ b/src/qqq/pages/records/query/GridFilterOperators.tsx @@ -731,6 +731,73 @@ function InputPossibleValueSourceSingle(tableName: string, field: QFieldMetaData } +//////////////////////////////////////////////// +// input element for multiple possible values // +//////////////////////////////////////////////// +function InputPossibleValueSourceMultiple(tableName: string, field: QFieldMetaData, props: GridFilterInputValueProps) +{ + const SUBMIT_FILTER_STROKE_TIME = 500; + const {item, applyValue, focusElementRef = null} = props; + + console.log("Item.value? " + item.value); + + const filterTimeout = useRef(); + const [ selectedPossibleValues, setSelectedPossibleValues ] = useState(item.value as QPossibleValue[]); + const [ applying, setIsApplying ] = useState(false); + + useEffect(() => + { + return () => + { + clearTimeout(filterTimeout.current); + }; + }, []); + + useEffect(() => + { + const itemValue = item.value ?? null; + }, [ item.value ]); + + const updateFilterValue = (value: QPossibleValue) => + { + clearTimeout(filterTimeout.current); + + setIsApplying(true); + filterTimeout.current = setTimeout(() => + { + setIsApplying(false); + applyValue({...item, value: value}); + }, SUBMIT_FILTER_STROKE_TIME); + }; + + const handleChange = (value: QPossibleValue) => + { + updateFilterValue(value); + }; + + return ( + + + + ); +} + + ////////////////////////////////// // possible value set operators // ////////////////////////////////// @@ -749,6 +816,18 @@ export const buildQGridPvsOperators = (tableName: string, field: QFieldMetaData) getApplyFilterFn: () => null, InputComponent: (props: GridFilterInputValueProps) => InputPossibleValueSourceSingle(tableName, field, props) }, + { + label: "is any of", + value: "isAnyOf", + getApplyFilterFn: () => null, + InputComponent: (props: GridFilterInputValueProps) => InputPossibleValueSourceMultiple(tableName, field, props) + }, + { + label: "is none of", + value: "isNone", + getApplyFilterFn: () => null, + InputComponent: (props: GridFilterInputValueProps) => InputPossibleValueSourceMultiple(tableName, field, props) + }, { label: "is empty", value: "isEmpty", diff --git a/src/qqq/utils/qqq/FilterUtils.ts b/src/qqq/utils/qqq/FilterUtils.ts index 8f04970..dbfb055 100644 --- a/src/qqq/utils/qqq/FilterUtils.ts +++ b/src/qqq/utils/qqq/FilterUtils.ts @@ -344,7 +344,8 @@ class FilterUtils { try { - const qQueryFilter = (filterString !== null) ? JSON.parse(filterString) : JSON.parse(searchParams.get("filter")) as QQueryFilter; + const filterJSON = (filterString !== null) ? JSON.parse(filterString) : JSON.parse(searchParams.get("filter")); + const qQueryFilter = filterJSON as QQueryFilter; ////////////////////////////////////////////////////////////////// // translate from a qqq-style filter to one that the grid wants // @@ -377,6 +378,53 @@ class FilterUtils } } + if (field && field.type == "DATE_TIME" && !values) + { + try + { + const criteria = filterJSON.criteria[i]; + if (criteria && criteria.expression) + { + let value = new Date(); + let amount = Number(criteria.expression.amount); + switch (criteria.expression.timeUnit) + { + case "MINUTES": + { + amount = amount * 60; + break; + } + case "HOURS": + { + amount = amount * 60 * 60; + break; + } + case "DAYS": + { + amount = amount * 60 * 60 * 24; + break; + } + default: + { + console.log("Unrecognized time unit: " + criteria.expression.timeUnit); + } + } + + if (criteria.expression.operator == "MINUS") + { + amount = -amount; + } + + value.setTime(value.getTime() + 1000 * amount); + values = [ValueUtils.formatDateTimeISO8601(value)]; + } + } + catch (e) + { + console.log(e); + } + } + defaultFilter.items.push({ columnField: criteria.fieldName, operatorValue: FilterUtils.qqqCriteriaOperatorToGrid(criteria.operator, field, values), diff --git a/src/qqq/utils/qqq/ValueUtils.tsx b/src/qqq/utils/qqq/ValueUtils.tsx index 080ff62..6c3f2ae 100644 --- a/src/qqq/utils/qqq/ValueUtils.tsx +++ b/src/qqq/utils/qqq/ValueUtils.tsx @@ -131,7 +131,7 @@ class ValueUtils if (field.hasAdornment(AdornmentType.RENDER_HTML)) { - return (parse(rawValue)); + return (rawValue ? parse(rawValue) : ""); } if (field.hasAdornment(AdornmentType.CHIP)) @@ -253,6 +253,16 @@ class ValueUtils return (`${date.toString("yyyy-MM-dd hh:mm:ss")} ${date.getHours() < 12 ? "AM" : "PM"} ${date.getTimezone()}`); } + public static formatDateTimeISO8601(date: Date) + { + if(!(date instanceof Date)) + { + date = new Date(date) + } + // @ts-ignore + return (`${date.toString("yyyy-MM-ddThh:mm:ssZ")}`); + } + public static getFullWeekday(date: Date) { if(!(date instanceof Date))