Skip to content

Commit 43f298a

Browse files
committed
feat: Add global watermark using username
1 parent 4bea11f commit 43f298a

3 files changed

Lines changed: 66 additions & 1 deletion

File tree

webapp/packages/core-app/src/Body.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import { observer } from 'mobx-react-lite';
99
import { useLayoutEffect, useRef } from 'react';
1010
import styled, { css } from 'reshadow';
1111

12-
import { Loader, useResource, useStyles } from '@cloudbeaver/core-blocks';
12+
import { AuthInfoService } from '@cloudbeaver/core-authentication';
13+
import { Loader, useResource, useStyles, Watermark } from '@cloudbeaver/core-blocks';
1314
import { useService } from '@cloudbeaver/core-di';
1415
import { DialogsPortal } from '@cloudbeaver/core-dialogs';
1516
import { Notifications } from '@cloudbeaver/core-notifications';
@@ -44,6 +45,8 @@ export const Body = observer(function Body() {
4445
const screenService = useService(ScreenService);
4546
const Screen = screenService.screen?.component;
4647
const { backendVersion } = useAppVersion();
48+
const authInfoService = useService(AuthInfoService);
49+
const userInfo = authInfoService.userInfo;
4750

4851
// TODO: must be loaded in place where it is used
4952
useResource(Body, ProjectInfoResource, CachedMapAllKey, { silent: true });
@@ -64,6 +67,7 @@ export const Body = observer(function Body() {
6467
<DialogsPortal />
6568
<Notifications />
6669
</theme>
70+
{userInfo && <Watermark theme={userInfo?.configurationParameters['app.theme']} text={userInfo?.displayName || userInfo?.userId} />}
6771
</Loader>
6872
</DNDProvider>,
6973
);
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import React, { useEffect, useState } from 'react';
2+
3+
interface WatermarkProps {
4+
text: string;
5+
fontSize?: number;
6+
fontFamily?: string;
7+
textColor?: string;
8+
rotate?: number;
9+
zIndex?: number;
10+
theme?: 'light' | 'dark';
11+
}
12+
13+
const Watermark: React.FC<WatermarkProps> = ({
14+
text,
15+
fontSize = 16,
16+
fontFamily = 'Arial',
17+
textColor = 'rgba(0, 0, 0, 0.1)',
18+
rotate = -45,
19+
zIndex = 9999,
20+
theme = 'light',
21+
}) => {
22+
const [watermarkUrl, setWatermarkUrl] = useState<string>('');
23+
24+
useEffect(() => {
25+
const canvas = document.createElement('canvas');
26+
const context = canvas.getContext('2d');
27+
28+
if (context) {
29+
const scale = window.devicePixelRatio;
30+
canvas.width = 300 * scale;
31+
canvas.height = 150 * scale;
32+
context.scale(scale, scale);
33+
34+
context.font = `${fontSize}px ${fontFamily}`;
35+
context.fillStyle = theme === 'light' ? textColor : 'rgba(255, 255, 255, 0.1)';
36+
context.rotate((rotate * Math.PI) / 180);
37+
context.fillText(text, 0, 100);
38+
39+
setWatermarkUrl(canvas.toDataURL());
40+
}
41+
}, [text, fontSize, fontFamily, textColor, rotate, theme]);
42+
43+
return (
44+
<div
45+
style={{
46+
position: 'fixed',
47+
top: 0,
48+
left: 0,
49+
width: '100%',
50+
height: '100%',
51+
zIndex,
52+
pointerEvents: 'none',
53+
backgroundImage: `url(${watermarkUrl})`,
54+
backgroundRepeat: 'repeat',
55+
}}
56+
/>
57+
);
58+
};
59+
60+
export default Watermark;

webapp/packages/core-blocks/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ export * from './FormControls/BASE_DROPDOWN_STYLES';
120120
export * from './FormControls/FormBox';
121121
export * from './FormControls/Filter';
122122
export * from './Fill';
123+
export { default as Watermark } from './Watermark/Watermark';
123124

124125
export * from './Containers/Container';
125126
export * from './Containers/Group';

0 commit comments

Comments
 (0)