Skip to content

Commit 0eb1c39

Browse files
committed
fix: Image widget error show blank when initialized
1 parent 04c3908 commit 0eb1c39

File tree

9 files changed

+212
-29
lines changed

9 files changed

+212
-29
lines changed

frontend/public/images/example.png

-171 KB
Binary file not shown.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/**
2+
* Datart
3+
*
4+
* Copyright 2021
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
import { Upload } from 'antd';
20+
import { uploadBoardImage } from 'app/pages/DashBoardPage/pages/BoardEditor/slice/thunk';
21+
import {
22+
forwardRef,
23+
useCallback,
24+
useContext,
25+
useImperativeHandle,
26+
useRef,
27+
} from 'react';
28+
import { useDispatch } from 'react-redux';
29+
import { BoardContext } from '../../BoardProvider/BoardProvider';
30+
31+
interface HiddenUploaderProps {
32+
onChange: (url: string) => void;
33+
}
34+
35+
export const HiddenUploader = forwardRef(
36+
({ onChange }: HiddenUploaderProps, ref) => {
37+
const dispatch = useDispatch();
38+
const uploadRef = useRef<any>();
39+
const { boardId } = useContext(BoardContext);
40+
41+
useImperativeHandle(ref, () => uploadRef.current?.upload.uploader);
42+
43+
const beforeUpload = useCallback(
44+
async info => {
45+
const formData = new FormData();
46+
formData.append('file', info);
47+
dispatch(
48+
uploadBoardImage({
49+
boardId,
50+
fileName: info.name,
51+
formData: formData,
52+
resolve: onChange,
53+
}),
54+
);
55+
return false;
56+
},
57+
[boardId, dispatch, onChange],
58+
);
59+
60+
return (
61+
<Upload
62+
accept=".jpg,.jpeg,.png,.gif,.svg"
63+
beforeUpload={beforeUpload}
64+
multiple={false}
65+
showUploadList={false}
66+
style={{ display: 'none' }}
67+
ref={uploadRef}
68+
/>
69+
);
70+
},
71+
);

frontend/src/app/pages/DashBoardPage/components/Widgets/ImageWidget/ImageWidget.tsx

Lines changed: 87 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,16 @@
1515
* See the License for the specific language governing permissions and
1616
* limitations under the License.
1717
*/
18+
1819
import { Space } from 'antd';
1920
import { WidgetContext } from 'app/pages/DashBoardPage/components/WidgetProvider/WidgetProvider';
20-
import { memo, useContext } from 'react';
21+
import {
22+
editBoardStackActions,
23+
editWidgetInfoActions,
24+
} from 'app/pages/DashBoardPage/pages/BoardEditor/slice';
25+
import { memo, useCallback, useContext, useEffect, useRef } from 'react';
26+
import { useDispatch } from 'react-redux';
27+
import styled from 'styled-components/macro';
2128
import { BoardContext } from '../../BoardProvider/BoardProvider';
2229
import { FlexStyle, ZIndexStyle } from '../../WidgetComponents/constants';
2330
import { EditMask } from '../../WidgetComponents/EditMask';
@@ -30,38 +37,99 @@ import {
3037
getWidgetBaseStyle,
3138
getWidgetTitle,
3239
} from '../../WidgetManager/utils/utils';
40+
import { WidgetInfoContext } from '../../WidgetProvider/WidgetInfoProvider';
41+
import { HiddenUploader } from './HiddenUploader';
3342
import { ImageWidgetCore } from './ImageWidgetCore';
43+
import { Picture } from './Picture';
3444

3545
export const ImageWidget: React.FC<{ hideTitle: boolean }> = memo(
3646
({ hideTitle }) => {
47+
const dispatch = useDispatch();
3748
const widget = useContext(WidgetContext);
49+
const widgetInfo = useContext(WidgetInfoContext);
3850
const { editing } = useContext(BoardContext);
3951
const title = getWidgetTitle(widget.config.customConfig.props);
4052
title.title = widget.config.name;
4153
const { background, border, padding } = getWidgetBaseStyle(
4254
widget.config.customConfig.props,
4355
);
56+
const showBackground =
57+
!background.image && background.color === 'transparent';
58+
const uploaderRef = useRef<any>();
59+
60+
useEffect(() => {
61+
if (widgetInfo.editing) {
62+
uploaderRef.current?.onClick();
63+
}
64+
}, [widgetInfo.editing]);
65+
66+
const uploaderChange = useCallback(
67+
(url: string) => {
68+
dispatch(
69+
editBoardStackActions.updateWidgetStyleConfigByPath({
70+
ancestors: [0, 0],
71+
configItem: {
72+
key: 'background',
73+
comType: 'background',
74+
label: 'background.background',
75+
value: { ...background, image: url },
76+
},
77+
wid: widget.id,
78+
}),
79+
);
80+
dispatch(editWidgetInfoActions.closeWidgetEditing(widget.id));
81+
},
82+
[dispatch, widget.id, background],
83+
);
84+
4485
return (
45-
<WidgetWrapper background={background} border={border} padding={padding}>
46-
<div style={ZIndexStyle}>
47-
{!hideTitle && <WidgetTitle title={title} />}
86+
<>
87+
<WidgetWrapper
88+
background={background}
89+
border={border}
90+
padding={padding}
91+
>
92+
<div style={ZIndexStyle}>
93+
{!hideTitle && <WidgetTitle title={title} />}
4894

49-
<div style={FlexStyle}>
50-
<ImageWidgetCore />
95+
<div style={FlexStyle}>
96+
<ImageWidgetCore />
97+
</div>
5198
</div>
52-
</div>
53-
{editing && <EditMask />}
54-
<StyledWidgetToolBar>
55-
<Space size={0}>
56-
<LockIconFn
57-
boardEditing={editing}
58-
wid={widget.id}
59-
lock={widget.config?.lock}
60-
/>
61-
<WidgetDropdownList widget={widget} />
62-
</Space>
63-
</StyledWidgetToolBar>
64-
</WidgetWrapper>
99+
{editing && <EditMask />}
100+
<StyledWidgetToolBar>
101+
<Space size={0}>
102+
<LockIconFn
103+
boardEditing={editing}
104+
wid={widget.id}
105+
lock={widget.config?.lock}
106+
/>
107+
<WidgetDropdownList widget={widget} />
108+
</Space>
109+
</StyledWidgetToolBar>
110+
</WidgetWrapper>
111+
{editing && (
112+
<HiddenUploader onChange={uploaderChange} ref={uploaderRef} />
113+
)}
114+
{editing && showBackground && (
115+
<ImageWidgetBackground>
116+
<Picture />
117+
</ImageWidgetBackground>
118+
)}
119+
</>
65120
);
66121
},
67122
);
123+
124+
const ImageWidgetBackground = styled.div`
125+
position: absolute;
126+
top: 0;
127+
right: 0;
128+
bottom: 0;
129+
left: 0;
130+
z-index: -1;
131+
display: flex;
132+
flex-direction: column;
133+
align-items: center;
134+
justify-content: center;
135+
`;
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* Datart
3+
*
4+
* Copyright 2021
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
import useI18NPrefix from 'app/hooks/useI18NPrefix';
20+
import styled from 'styled-components/macro';
21+
22+
export function Picture() {
23+
const t = useI18NPrefix(`viz.board.setting`);
24+
25+
return (
26+
<Svg
27+
viewBox="0 0 1029 1128"
28+
version="1.1"
29+
xmlns="http://www.w3.org/2000/svg"
30+
>
31+
<path d="M944.148 94.925H235.336c-46.853 0-84.972 38.118-84.972 84.971v39.87H93.46c-46.064 0-83.537 37.473-83.537 83.538v508.81c0 46.065 37.473 83.538 83.537 83.538h696.07c46.064 0 83.538-37.473 83.538-83.538v-41.298h71.08c46.854 0 84.972-38.113 84.972-84.972V179.896c0-46.858-38.113-84.971-84.972-84.971zM61.61 651.372V303.299c0-17.562 14.29-31.847 31.851-31.847h696.07A31.887 31.887 0 0 1 821.38 303.3v479.098L631.43 619.577 477.932 711.68 255.493 457.482 61.61 651.372zM789.53 843.96H93.46a31.887 31.887 0 0 1-31.85-31.85v-87.65l191.365-191.375 214.508 245.15 158.602-95.15L807.29 838.39a31.135 31.135 0 0 1-17.761 5.57z m154.62-124.84h-71.081V303.298c0-46.065-37.474-83.538-83.538-83.538H202.056v-39.87c0-18.35 14.93-33.28 33.28-33.28h708.812c18.35 0 33.28 14.93 33.28 33.28v505.943a33.321 33.321 0 0 1-33.28 33.285zM644.361 552.34c57.278 0 103.87-46.597 103.87-103.869 0-57.277-46.597-103.87-103.87-103.87s-103.87 46.598-103.87 103.87c-0.004 57.272 46.593 103.87 103.87 103.87z m0-156.047c28.77 0 52.178 23.409 52.178 52.178s-23.408 52.178-52.178 52.178-52.178-23.409-52.178-52.178 23.404-52.178 52.178-52.178z"></path>
32+
<text x="500" y="1096" textAnchor="middle">
33+
{t('dbClickToUpload')}
34+
</text>
35+
</Svg>
36+
);
37+
}
38+
39+
const Svg = styled.svg`
40+
width: 60%;
41+
height: 60%;
42+
43+
path {
44+
fill: ${p => p.theme.borderColorEmphasis};
45+
}
46+
47+
text {
48+
font-size: 120px;
49+
fill: ${p => p.theme.borderColorBase};
50+
}
51+
`;

frontend/src/app/pages/DashBoardPage/components/Widgets/ImageWidget/imageConfig.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,6 @@ export const widgetToolkit: ImageToolkit = {
9696
{ ...initPaddingTpl() },
9797
{ ...initBorderTpl() },
9898
];
99-
widget.config.customConfig.props?.forEach(ele => {
100-
if (ele.key === 'backgroundGroup') {
101-
ele.rows?.forEach(row => {
102-
if (row.key === 'background') {
103-
row.value.image = '/images/example.png';
104-
}
105-
});
106-
}
107-
});
10899

109100
return widget;
110101
},

frontend/src/app/pages/DashBoardPage/pages/BoardEditor/components/SlideSetting/SettingItem/BasicSet/ImageUpload.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ export const UploadDragger: React.FC<{
6363
return (
6464
<StyleUpload
6565
name={'upload-image'}
66+
accept=".jpg,.jpeg,.png,.gif,.svg"
6667
className="datart-ant-upload"
6768
beforeUpload={beforeUpload}
6869
multiple={false}

frontend/src/app/pages/DashBoardPage/pages/BoardEditor/slice/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,6 @@ const widgetInfoRecordSlice = createSlice({
195195
closeWidgetEditing(state, action: PayloadAction<string>) {
196196
const id = action.payload;
197197
if (id) {
198-
state[id].selected = false;
199198
state[id].editing = false;
200199
} else {
201200
for (let key of Object.keys(state)) {

frontend/src/locales/en/translation.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,7 @@
999999
"color": "Color",
10001000
"image": "Image",
10011001
"uploadTip": "Click to Upload",
1002+
"dbClickToUpload": "Double Click To Upload",
10021003
"padding": "Padding",
10031004
"paddingTop": "Padding Top",
10041005
"paddingRight": "Padding Right",

frontend/src/locales/zh/translation.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,7 @@
997997
"color": "颜色",
998998
"image": "图片",
999999
"uploadTip": "点击上传",
1000+
"dbClickToUpload": "双击上传图片",
10001001
"padding": "内边距",
10011002
"paddingTop": "上边距",
10021003
"paddingRight": "右边距",

0 commit comments

Comments
 (0)