Skip to content

Commit 255d870

Browse files
Merge pull request #1553 from iamfaran/staging
[Feat]: Add Time-Only Column Type to the Table Component
2 parents aa913aa + 2888b68 commit 255d870

File tree

4 files changed

+175
-1
lines changed

4 files changed

+175
-1
lines changed

client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComp.tsx

+7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { CellProps } from "components/table/EditableCell";
22
import { DateTimeComp } from "comps/comps/tableComp/column/columnTypeComps/columnDateTimeComp";
3+
import { TimeComp } from "./columnTypeComps/columnTimeComp";
34
import { ButtonComp } from "comps/comps/tableComp/column/simpleColumnTypeComps";
45
import { withType } from "comps/generators";
56
import { trans } from "i18n";
@@ -67,6 +68,11 @@ const actionOptions = [
6768
label: trans("table.image"),
6869
value: "image",
6970
},
71+
{
72+
label: trans("table.time"),
73+
value: "time",
74+
},
75+
7076
{
7177
label: trans("table.date"),
7278
value: "date",
@@ -116,6 +122,7 @@ export const ColumnTypeCompMap = {
116122
rating: RatingComp,
117123
progress: ProgressComp,
118124
date: DateComp,
125+
time: TimeComp,
119126
};
120127

121128
type ColumnTypeMapType = typeof ColumnTypeCompMap;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
import { default as TimePicker } from "antd/es/time-picker";
2+
import {
3+
ColumnTypeCompBuilder,
4+
ColumnTypeViewFn,
5+
} from "comps/comps/tableComp/column/columnTypeCompBuilder";
6+
import { ColumnValueTooltip } from "comps/comps/tableComp/column/simpleColumnTypeComps";
7+
import { StringControl } from "comps/controls/codeControl";
8+
import { withDefault } from "comps/generators";
9+
import { formatPropertyView } from "comps/utils/propertyUtils";
10+
import { trans } from "i18n";
11+
import dayjs from "dayjs";
12+
import { useEffect, useRef, useState } from "react";
13+
import styled from "styled-components";
14+
import { TIME_FORMAT } from "util/dateTimeUtils";
15+
import { hasIcon } from "comps/utils";
16+
import { IconControl } from "comps/controls/iconControl";
17+
18+
19+
const TimePickerStyled = styled(TimePicker)<{ $open: boolean }>`
20+
width: 100%;
21+
height: 100%;
22+
position: absolute;
23+
top: 0;
24+
padding: 0;
25+
padding-left: 11px;
26+
.ant-picker-input {
27+
height: 100%;
28+
}
29+
input {
30+
padding-right: 18px;
31+
cursor: pointer;
32+
}
33+
&.ant-picker-focused .ant-picker-suffix svg g {
34+
stroke: ${(props) => props.$open && "#315EFB"};
35+
}
36+
.ant-picker-suffix {
37+
height: calc(100% - 1px);
38+
position: absolute;
39+
right: 0;
40+
top: 0.5px;
41+
display: flex;
42+
align-items: center;
43+
padding: 0 3px;
44+
}
45+
`;
46+
47+
const Wrapper = styled.div`
48+
background: transparent !important;
49+
`;
50+
51+
export function formatTime(time: string, format: string) {
52+
const parsedTime = dayjs(time, TIME_FORMAT);
53+
return parsedTime.isValid() ? parsedTime.format(format) : "";
54+
}
55+
56+
const childrenMap = {
57+
text: StringControl,
58+
prefixIcon: IconControl,
59+
suffixIcon: IconControl,
60+
format: withDefault(StringControl, TIME_FORMAT),
61+
inputFormat: withDefault(StringControl, TIME_FORMAT),
62+
};
63+
64+
let inputFormat = TIME_FORMAT;
65+
66+
const getBaseValue: ColumnTypeViewFn<typeof childrenMap, string, string> = (props) => props.text;
67+
68+
type TimeEditProps = {
69+
value: string;
70+
onChange: (value: string) => void;
71+
onChangeEnd: () => void;
72+
inputFormat: string;
73+
};
74+
75+
export const TimeEdit = (props: TimeEditProps) => {
76+
const pickerRef = useRef<any>();
77+
const [panelOpen, setPanelOpen] = useState(true);
78+
let value = dayjs(props.value, TIME_FORMAT);
79+
if (!value.isValid()) {
80+
value = dayjs("00:00:00", TIME_FORMAT);
81+
}
82+
83+
const [tempValue, setTempValue] = useState<dayjs.Dayjs | null>(value);
84+
85+
useEffect(() => {
86+
const value = props.value ? dayjs(props.value, TIME_FORMAT) : null;
87+
setTempValue(value);
88+
}, [props.value]);
89+
90+
return (
91+
<Wrapper
92+
onKeyDown={(e) => {
93+
if (e.key === "Enter" && !panelOpen) {
94+
props.onChangeEnd();
95+
}
96+
}}
97+
onMouseDown={(e) => {
98+
e.stopPropagation();
99+
e.preventDefault();
100+
}}
101+
>
102+
<TimePickerStyled
103+
ref={pickerRef}
104+
$open={panelOpen}
105+
format={props.inputFormat}
106+
allowClear={true}
107+
autoFocus
108+
value={tempValue}
109+
defaultOpen={true}
110+
onOpenChange={(open) => setPanelOpen(open)}
111+
onChange={(value, timeString) => {
112+
props.onChange(timeString as string);
113+
}}
114+
onBlur={() => props.onChangeEnd()}
115+
/>
116+
</Wrapper>
117+
);
118+
};
119+
120+
export const TimeComp = (function () {
121+
return new ColumnTypeCompBuilder(
122+
childrenMap,
123+
(props, dispatch) => {
124+
inputFormat = props.inputFormat;
125+
const value = props.changeValue ?? getBaseValue(props, dispatch);
126+
return(
127+
<>
128+
{hasIcon(props.prefixIcon) && (
129+
<span>{props.prefixIcon}</span>
130+
)}
131+
<span>{value}</span>
132+
{hasIcon(props.suffixIcon) && (
133+
<span>{props.suffixIcon}</span>
134+
)}
135+
</>
136+
);
137+
138+
},
139+
(nodeValue) => formatTime(nodeValue.text.value, nodeValue.format.value),
140+
getBaseValue
141+
)
142+
.setEditViewFn((props) => (
143+
<TimeEdit
144+
value={props.value}
145+
onChange={props.onChange}
146+
onChangeEnd={props.onChangeEnd}
147+
inputFormat={inputFormat}
148+
/>
149+
))
150+
.setPropertyViewFn((children) => (
151+
<>
152+
{children.text.propertyView({
153+
label: trans("table.columnValue"),
154+
tooltip: ColumnValueTooltip,
155+
})}
156+
{children.prefixIcon.propertyView({
157+
label: trans("button.prefixIcon"),
158+
})}
159+
{children.suffixIcon.propertyView({
160+
label: trans("button.suffixIcon"),
161+
})}
162+
{formatPropertyView({ children, placeholder: TIME_FORMAT })}
163+
</>
164+
))
165+
.build();
166+
})();

client/packages/lowcoder/src/i18n/locales/en.ts

+1
Original file line numberDiff line numberDiff line change
@@ -2029,6 +2029,7 @@ export const en = {
20292029
"tag": "Tag",
20302030
"select": "Select",
20312031
"dropdown": "Dropdown",
2032+
"time" : "Time",
20322033
"date": "Date",
20332034
"dateTime": "Date Time",
20342035
"badgeStatus": "Status",

server/api-service/lowcoder-plugins/snowflakePlugin/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
<dependency>
3131
<groupId>net.snowflake</groupId>
3232
<artifactId>snowflake-jdbc</artifactId>
33-
<version>3.13.33</version>
33+
<version>3.22.0</version>
3434
</dependency>
3535
<dependency>
3636
<groupId>org.lowcoder</groupId>

0 commit comments

Comments
 (0)