diff --git a/extension/chrome/manifest.json b/extension/chrome/manifest.json index 7369d6c8..a1b33aba 100644 --- a/extension/chrome/manifest.json +++ b/extension/chrome/manifest.json @@ -61,7 +61,9 @@ "storage", "file:///*", "http://*/*", - "https://*/*" + "https://*/*", + "clipboardWrite", + "clipboardRead" ], "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'; style-src * 'unsafe-inline'; img-src 'self' data:;", "update_url": "https://clients2.google.com/service/update2/crx", diff --git a/extension/edge/manifest.json b/extension/edge/manifest.json index 00fb14e6..097ea2ca 100644 --- a/extension/edge/manifest.json +++ b/extension/edge/manifest.json @@ -61,7 +61,9 @@ "storage", "file:///*", "http://*/*", - "https://*/*" + "https://*/*", + "clipboardWrite", + "clipboardRead" ], "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'; style-src * 'unsafe-inline'; img-src 'self' data:;" } diff --git a/extension/firefox/manifest.json b/extension/firefox/manifest.json index c19b76e8..7bf83536 100644 --- a/extension/firefox/manifest.json +++ b/extension/firefox/manifest.json @@ -57,7 +57,9 @@ "storage", "file:///*", "http://*/*", - "https://*/*" + "https://*/*", + "clipboardWrite", + "clipboardRead" ], "content_security_policy": "script-src 'self'; object-src 'self'; img-src 'self' data:;" } diff --git a/packages/redux-devtools-inspector-monitor/src/ActionPreview.tsx b/packages/redux-devtools-inspector-monitor/src/ActionPreview.tsx index 31632f45..a3837b02 100644 --- a/packages/redux-devtools-inspector-monitor/src/ActionPreview.tsx +++ b/packages/redux-devtools-inspector-monitor/src/ActionPreview.tsx @@ -10,7 +10,8 @@ import ActionPreviewHeader from './ActionPreviewHeader'; import DiffTab from './tabs/DiffTab'; import StateTab from './tabs/StateTab'; import ActionTab from './tabs/ActionTab'; -import cloneDeep from 'lodash.clonedeep'; +import { getValueByPath } from './utils/getValueByPath'; +import { copyToClipboard } from './utils/copyToClipboard'; export interface TabComponentProps> { labelRenderer: LabelRenderer; @@ -81,16 +82,6 @@ class ActionPreview> extends Component< static defaultProps = { tabName: DEFAULT_STATE.tabName, }; - copyToClipboard = (path: (string | number)[]) => { - try { - const objectByPath = path.reduce((obj: any, key) => (obj && obj[key] !== undefined) ? obj[key] : null, this.props.nextState); - const jsonString = JSON.stringify(objectByPath, null, 2); - void navigator.clipboard.writeText(jsonString) - } catch (err) { - console.error('Failed to copy: ', err); - } - }; - render(): JSX.Element { const { @@ -195,7 +186,7 @@ class ActionPreview> extends Component< labelRenderer: LabelRenderer = ([key, ...rest], nodeType, expanded) => { const { onInspectPath, inspectedPath } = this.props; - + const reversedPath = [key, ...rest].reverse(); return ( {key} @@ -213,7 +204,7 @@ class ActionPreview> extends Component< onClick={() => onInspectPath([ ...inspectedPath.slice(0, inspectedPath.length - 1), - ...[key, ...rest].reverse(), + ...reversedPath, ]) } > @@ -231,7 +222,17 @@ class ActionPreview> extends Component< })} onClick={event => { event.stopPropagation(); - this.copyToClipboard([...inspectedPath.slice(0, inspectedPath.length - 1), key]); + let objectForCopying; + if (this.props.tabName === 'Action') { + objectForCopying = getValueByPath(this.props.action, reversedPath); + } else if (this.props.tabName === 'State') { + objectForCopying = getValueByPath(this.props.nextState, reversedPath); + } + if (objectForCopying !== undefined) { + copyToClipboard(objectForCopying); + } else { + console.error('Unable to find the object to copy'); + } }} > {'(copy)'} diff --git a/packages/redux-devtools-inspector-monitor/src/utils/copyToClipboard.ts b/packages/redux-devtools-inspector-monitor/src/utils/copyToClipboard.ts new file mode 100644 index 00000000..62f0a3f0 --- /dev/null +++ b/packages/redux-devtools-inspector-monitor/src/utils/copyToClipboard.ts @@ -0,0 +1,11 @@ +import cloneDeep from 'lodash.clonedeep'; + +export const copyToClipboard = (object: any) => { + try { + const deepCopiedObject = cloneDeep(object); + const jsonString = JSON.stringify(deepCopiedObject, null, 2); + void navigator.clipboard.writeText(jsonString); + } catch (err) { + console.error('Error during copy: ', err); + } +} diff --git a/packages/redux-devtools-inspector-monitor/src/utils/getValueByPath.ts b/packages/redux-devtools-inspector-monitor/src/utils/getValueByPath.ts new file mode 100644 index 00000000..9a77875c --- /dev/null +++ b/packages/redux-devtools-inspector-monitor/src/utils/getValueByPath.ts @@ -0,0 +1,12 @@ +export const getValueByPath = (obj: any, path: (string | number)[]) => { + let current: any = obj; + for (let i = 0; i < path.length; i++) { + const key = path[i]; + const adjustedKey = typeof key === 'string' && !isNaN(Number(key)) ? parseInt(key, 10) : key; + if (current[adjustedKey] === undefined) { + return undefined; + } + current = current[adjustedKey]; + } + return current; +}