Skip to content

Commit

Permalink
feat: add support of onCopyFulfill prop & extract getPreparedCopyItem…
Browse files Browse the repository at this point in the history
…Options prop from context (#216)

* chore: add support of onCopySuccess & onCopyError methods of DashKit context in OverlayControls

* feat: extract getPreparedCopyItemOptions & onCopyFulfill to Daskkit props

* fix: error typing & readme
  • Loading branch information
DaryaLari authored Nov 14, 2024
1 parent 213c620 commit ee58616
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 7 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ interface DashKitProps {
noOverlay?: boolean;
focusable?: boolean;
draggableHandleClassName?: string;
getPreparedCopyItemOptions?: (options: PreparedCopyItemOptions) => PreparedCopyItemOptions;
onCopyFulfill?: (error: null | Error, data?: PreparedCopyItemOptions) => void;
}
```

Expand All @@ -84,6 +86,8 @@ interface DashKitProps {
- **onResizeStart**: ReactGridLayout called when item resize started
- **onResize**: ReactGridLayout called while item resizing
- **onResizeStop**: ReactGridLayout called when item resize stoped
- **getPreparedCopyItemOptions**: Called for converting copied item to serializable object before saving it to localstorage. It should be used instead of deprecated `context.getPreparedCopyItemOptions` prop
- **onCopyFulfill**: Called when item copy finished with `error=null` and defined `data` on successful operation done and with `error: Error` without `data` otherwise

## Usage

Expand Down
5 changes: 3 additions & 2 deletions src/components/DashKit/DashKit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ import {
import {RegisterManager, UpdateManager, reflowLayout} from '../../utils';
import DashKitView from '../DashKitView/DashKitView';
import GridLayout from '../GridLayout/GridLayout';
import {OverlayControlItem} from '../OverlayControls/OverlayControls';
import {OverlayControlItem, OverlayControlsCtxShape} from '../OverlayControls/OverlayControls';

interface DashKitGeneralProps {
interface DashKitGeneralProps
extends Pick<OverlayControlsCtxShape, 'getPreparedCopyItemOptions' | 'onCopyFulfill'> {
config: Config;
editMode: boolean;
draggableHandleClassName?: string;
Expand Down
3 changes: 3 additions & 0 deletions src/components/DashKit/__stories__/DashKitShowcase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,9 @@ export class DashKitShowcase extends React.Component<{}, DashKitDemoState> {
overlayControls={this.state.enableOverlayControls ? this.controls : null}
overlayMenuItems={this.state.overlayMenuItems}
focusable={true}
onCopyFulfill={(_error, data) =>
console.info('Copied: ' + JSON.stringify(data))
}
/>
</DemoRow>
</Demo>
Expand Down
30 changes: 25 additions & 5 deletions src/components/OverlayControls/OverlayControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export type PreparedCopyItemOptions<C extends object = {}> = PreparedCopyItemOpt
copyContext?: C;
};

type DashKitCtx = React.Context<{
export interface OverlayControlsCtxShape {
overlayControls?: Record<string, OverlayControlItem[]>;
context: Record<string, any>;
menu: MenuItem[];
Expand All @@ -103,7 +103,11 @@ type DashKitCtx = React.Context<{
editItem: (item: ConfigItem) => void;
removeItem: (id: string) => void;
getLayoutItem: (id: string) => ConfigLayout | void;
}>;
getPreparedCopyItemOptions?: (options: PreparedCopyItemOptions) => PreparedCopyItemOptions;
onCopyFulfill?: (error: null | Error, data?: PreparedCopyItemOptions) => void;
}

type OverlayControlsCtx = React.Context<OverlayControlsCtxShape>;

const DEFAULT_DROPDOWN_MENU = [MenuItems.Copy, MenuItems.Delete];

Expand All @@ -114,7 +118,7 @@ class OverlayControls extends React.Component<OverlayControlsProps> {
view: 'flat',
size: 'm',
};
context!: React.ContextType<DashKitCtx>;
context!: React.ContextType<OverlayControlsCtx>;
render() {
const {position} = this.props;
const items = this.getItems();
Expand Down Expand Up @@ -405,11 +409,27 @@ class OverlayControls extends React.Component<OverlayControlsProps> {
targetInnerId,
};

if (typeof this.context.context?.getPreparedCopyItemOptions === 'function') {
if (this.context.context?.getPreparedCopyItemOptions) {
console.warn?.(
'`context.getPreparedCopyItemOptions` is deprecated. Please use `getPreparedCopyItemOptions` prop instead',
);
}

const getPreparedCopyItemOptions =
this.context?.getPreparedCopyItemOptions ??
this.context.context?.getPreparedCopyItemOptions;

if (typeof getPreparedCopyItemOptions === 'function') {
options = this.context.context.getPreparedCopyItemOptions(options);
}

localStorage.setItem(COPIED_WIDGET_STORE_KEY, JSON.stringify(options));
try {
localStorage.setItem(COPIED_WIDGET_STORE_KEY, JSON.stringify(options));
this.context.onCopyFulfill?.(null, options);
} catch (e) {
const error = e instanceof Error ? e : new Error('Unknown error while copying item');
this.context.onCopyFulfill?.(error);
}
// https://stackoverflow.com/questions/35865481/storage-event-not-firing
window.dispatchEvent(new Event('storage'));
this.props.onItemClick?.();
Expand Down
4 changes: 4 additions & 0 deletions src/hocs/withContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -520,12 +520,16 @@ function useMemoStateContext(props) {
editItem: props.onItemEdit,
removeItem: onItemRemove,
getLayoutItem: getLayoutItem,
getPreparedCopyItemOptions: props.getPreparedCopyItemOptions,
onCopyFulfill: props.onCopyFulfill,
}),
[
props.overlayControls,
props.context,
props.itemsStateAndParams,
props.onItemEdit,
props.getPreparedCopyItemOptions,
props.onCopyFulfill,
overlayMenuItems,
itemsParams,
onItemRemove,
Expand Down

0 comments on commit ee58616

Please sign in to comment.