Skip to content

Commit

Permalink
feat: add story DashKitUpdateItems
Browse files Browse the repository at this point in the history
  • Loading branch information
imechoim committed Nov 15, 2023
1 parent 3d27707 commit fb499b5
Show file tree
Hide file tree
Showing 6 changed files with 262 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/components/DashKit/__stories__/DashKit.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import pluginTitle from '../../../plugins/Title/Title';
import pluginText from '../../../plugins/Text/Text';
import {DashKitShowcase} from './DashKitShowcase';
import {getConfig} from './utils';
import {DashKitUpdateItems} from './DashKitUpodateItems/DashKitUpodateItems';
import './DashKit.stories.scss';

const b = cn('stories-dashkit');
Expand Down Expand Up @@ -69,3 +70,6 @@ export const Default = DefaultTemplate.bind({});

const ShowcaseTemplate: Story = () => <DashKitShowcase />;
export const Showcase = ShowcaseTemplate.bind({});

const DashKitUpdateItemsTempl = () => <DashKitUpdateItems />;
export const UpdateItems = DashKitUpdateItemsTempl.bind({});
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import React, {useEffect} from 'react';
import {Demo, DemoRow} from '../Demo';
import {DashKit} from '../../DashKit';
import {Plugin} from '../../../../typings';
import {PluginTitleProps} from '../../../../../src/plugins';
import {TitleWithReq, TitleWithReqProps} from './TitleWithReq/TitleWithReq';
import {RadioGroup} from '@gravity-ui/uikit';
import {destroyStore, initStore} from './MockStore/MockStore';
import {StorageWidget} from './StorageWidget/StorageWidget';

const pluginTitle: Plugin<TitleWithReqProps> = {
type: 'TitleWithReq',
renderer(props, forwardedRef) {
return <TitleWithReq {...props} ref={forwardedRef} />;
},
};
const pluginStorageWidget: Plugin<PluginTitleProps> = {
type: 'StorageWidget',
renderer(props) {
return <StorageWidget {...props} />;
},
};

DashKit.registerPlugins(pluginTitle, pluginStorageWidget);

const config = {
salt: '0.46703554571365613',
counter: 5,
aliases: {},
connections: [],
items: [
{
id: 'FastUpdateTitle',
data: {
size: 'm',
text: 'Fast',
reqDelay: 3,
},
type: 'TitleWithReq',
namespace: 'default',
orderId: 1,
},
{
id: 'SlowUpdateTitle',
data: {
size: 'm',
text: 'Slow',
reqDelay: 6,
},
type: 'TitleWithReq',
namespace: 'default',
orderId: 1,
},
{
id: 'Store',
data: {
size: 'm',
text: 'Store',
},
type: 'StorageWidget',
namespace: 'default',
orderId: 1,
},
],
layout: [
{
h: 4,
i: 'FastUpdateTitle',
w: 26,
x: 0,
y: 0,
},
{
h: 4,
i: 'SlowUpdateTitle',
w: 26,
x: 0,
y: 0,
},
{
h: 8,
i: 'Store',
w: 10,
x: 26,
y: 0,
},
],
};

export const DashKitUpdateItems = () => {
const [autoUpdateMode, setAutoUpdateMode] = React.useState('update10s');
const [autoupdateInterval, setAutoupdateInterval] = React.useState(10);
const [realtimeMode, setRealtimeMode] = React.useState(false);

useEffect(() => {
initStore();
return () => {
destroyStore();
};
}, []);

return (
<Demo title="DashKit Update Items">
<DemoRow title="Controls">
<RadioGroup
value={autoUpdateMode}
onUpdate={(value) => {
setAutoUpdateMode(value);
switch (value) {
case 'update10s':
setAutoupdateInterval(10);
break;
case 'update1s':
setAutoupdateInterval(1);
break;
case 'realtime':
setRealtimeMode(true);
break;
}
}}
options={[
{value: 'update10s', content: 'Set autoupdate interval to 10s'},
{value: 'update1s', content: 'Set autoupdate interval to 1s'},
{value: 'realtime', content: 'Set Realtime Mode'},
]}
/>
</DemoRow>
<DashKit
config={config}
editMode={false}
settings={{autoupdateInterval, realtimeMode, silentLoading: false}}
/>
</Demo>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
let store = {
counter: 0,
updateInterval: 1,
};

type StoreUpdateCallback = (state: typeof store) => void;
const onUpdateCallbacks: Array<StoreUpdateCallback> = [];

let interval: NodeJS.Timer | undefined;

export const storeOnUpdateSubscribe = (callback: StoreUpdateCallback) => {
onUpdateCallbacks.push(callback);
};

export const initStore = () => {
if (interval) return;

store.counter = 0;

interval = setInterval(() => {
store = {...store, counter: store.counter + 1};
onUpdateCallbacks.forEach((callback) => {
callback(store);
});
}, store.updateInterval * 1000);
};

export const destroyStore = () => {
clearInterval(interval);
interval = undefined;
};

export const getStore = () => {
return store;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
import {PluginTitleProps} from '../../../../../plugins';

import {getStore, storeOnUpdateSubscribe} from '../MockStore/MockStore';
import {Card, Flex, Text} from '@gravity-ui/uikit';
import '../styles.scss';

export const StorageWidget = (props: PluginTitleProps) => {
const [storeState, setStoreState] = React.useState<any>(getStore());

React.useEffect(() => {
storeOnUpdateSubscribe((store) => {
setStoreState({...store});
});
}, [setStoreState]);

return (
<Card theme="info" view="filled" className="cardLayout">
<div>
<Text variant="display-1">{props.data.text}</Text>
<div>{`counter: ${storeState.counter}`}</div>
</div>
<Flex justifyContent="flex-end">
<span>{`update interval: ${storeState.updateInterval}s`}</span>
</Flex>
</Card>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from 'react';
import {PluginTitleProps} from '../../../../../../src/plugins';

import {getStore} from '../MockStore/MockStore';
import {Card, Flex, Text} from '@gravity-ui/uikit';
import '../styles.scss';

const getData = (timeout = 1000) => {
return new Promise<string | number>((res) => {
const counter = getStore().counter;
setTimeout(() => {
res(counter);
}, timeout);
});
};

export type TitleWithReqProps = {
data: {reqDelay: number} & PluginTitleProps['data'];
} & PluginTitleProps;
type TitleWithReqState = {
isLoading: boolean;
counter?: string | number;
};

export class TitleWithReq extends React.Component<TitleWithReqProps, TitleWithReqState> {
componentDidMount(): void {
this.reload();
}

render() {
return (
<Card theme="normal" view="filled" className="cardLayout">
<div>
<Text variant="display-1">{this.props.data.text}</Text>
<Flex justifyContent="space-between">
<span>{`counter: ${this.state?.counter}`}</span>
{this.state?.isLoading && <span>Loading...</span>}
</Flex>
</div>
<Flex justifyContent="flex-end">
<span>{`update interval: ${this.props.data.reqDelay}s`}</span>
</Flex>
</Card>
);
}

async reload() {
this.setState({isLoading: true});
await getData(this.props.data.reqDelay * 1000).then((counter) => {
this.setState({counter, isLoading: false});
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.cardLayout {
padding: 8px;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}

0 comments on commit fb499b5

Please sign in to comment.