From 639d5f2e99e05ce5f8aa5551c57e5598957aa797 Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskyi Date: Tue, 27 Feb 2024 13:33:59 +0100 Subject: [PATCH 1/7] add onClipboardPasteBeforeStart prop --- .../data-grid/clipboard/ClipboardPasteEvents.js | 10 ++++++++++ .../clipboard/ClipboardPasteEvents.tsx | 10 ++++++++++ .../clipboard/ClipboardPasteEvents.tsx.preview | 2 ++ docs/data/data-grid/clipboard/clipboard.md | 5 ++++- .../x/api/data-grid/data-grid-premium.json | 4 ++++ .../data-grid-premium/data-grid-premium.json | 4 ++++ .../src/DataGridPremium/DataGridPremium.tsx | 8 ++++++++ .../clipboard/useGridClipboardImport.ts | 17 +++++++++++++++-- .../src/models/dataGridPremiumProps.ts | 8 ++++++++ 9 files changed, 65 insertions(+), 3 deletions(-) diff --git a/docs/data/data-grid/clipboard/ClipboardPasteEvents.js b/docs/data/data-grid/clipboard/ClipboardPasteEvents.js index 299a2ea33c05..a2429d1b1b11 100644 --- a/docs/data/data-grid/clipboard/ClipboardPasteEvents.js +++ b/docs/data/data-grid/clipboard/ClipboardPasteEvents.js @@ -2,6 +2,14 @@ import * as React from 'react'; import { DataGridPremium } from '@mui/x-data-grid-premium'; import { useDemoData } from '@mui/x-data-grid-generator'; +const confirmPaste = () => { + const confirmed = window.confirm('Are you sure you want to paste?'); + if (!confirmed) { + return Promise.reject(); + } + return undefined; +}; + export default function ClipboardPasteEvents() { const { data } = useDemoData({ dataSet: 'Commodity', @@ -36,9 +44,11 @@ export default function ClipboardPasteEvents() { initialState={initialState} cellSelection processRowUpdate={processRowUpdate} + onClipboardPasteBeforeStart={confirmPaste} onClipboardPasteStart={() => setLoading(true)} onClipboardPasteEnd={() => setLoading(false)} ignoreValueFormatterDuringExport + disableRowSelectionOnClick /> ); diff --git a/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx b/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx index 0139a1fc0429..cb64f70fa4f9 100644 --- a/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx +++ b/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx @@ -2,6 +2,14 @@ import * as React from 'react'; import { DataGridPremium, DataGridPremiumProps } from '@mui/x-data-grid-premium'; import { useDemoData } from '@mui/x-data-grid-generator'; +const confirmPaste = () => { + const confirmed = window.confirm('Are you sure you want to paste?'); + if (!confirmed) { + return Promise.reject(); + } + return undefined; +}; + export default function ClipboardPasteEvents() { const { data } = useDemoData({ dataSet: 'Commodity', @@ -38,9 +46,11 @@ export default function ClipboardPasteEvents() { initialState={initialState} cellSelection processRowUpdate={processRowUpdate} + onClipboardPasteBeforeStart={confirmPaste} onClipboardPasteStart={() => setLoading(true)} onClipboardPasteEnd={() => setLoading(false)} ignoreValueFormatterDuringExport + disableRowSelectionOnClick /> ); diff --git a/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx.preview b/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx.preview index 0c6f364b0155..d4337edf1554 100644 --- a/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx.preview +++ b/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx.preview @@ -4,7 +4,9 @@ initialState={initialState} cellSelection processRowUpdate={processRowUpdate} + onClipboardPasteBeforeStart={confirmPaste} onClipboardPasteStart={() => setLoading(true)} onClipboardPasteEnd={() => setLoading(false)} ignoreValueFormatterDuringExport + disableRowSelectionOnClick /> \ No newline at end of file diff --git a/docs/data/data-grid/clipboard/clipboard.md b/docs/data/data-grid/clipboard/clipboard.md index c9a922c10b10..ad6d87b9295f 100644 --- a/docs/data/data-grid/clipboard/clipboard.md +++ b/docs/data/data-grid/clipboard/clipboard.md @@ -87,7 +87,10 @@ For convenience, you can also listen to these events using their respective prop - `onClipboardPasteStart` - `onClipboardPasteEnd` -The demo below shows how to use these events to display a loading indicator while the clipboard paste operation is in progress: +Additionally, there is the `onClipboardPasteBeforeStart` prop, which is called before the clipboard paste operation starts +and can be used to cancel or confirm the paste operation. + +The demo below calls [`window.confirm()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm) before pasting. If confirmed, it displays a loading indicator during the paste operation. {{"demo": "ClipboardPasteEvents.js", "bg": "inline"}} diff --git a/docs/pages/x/api/data-grid/data-grid-premium.json b/docs/pages/x/api/data-grid/data-grid-premium.json index f6aab9649ea0..9bf8f270824e 100644 --- a/docs/pages/x/api/data-grid/data-grid-premium.json +++ b/docs/pages/x/api/data-grid/data-grid-premium.json @@ -288,6 +288,10 @@ "type": { "name": "func" }, "signature": { "type": "function(data: string) => void", "describedArgs": ["data"] } }, + "onClipboardPasteBeforeStart": { + "type": { "name": "func" }, + "signature": { "type": "function(params: object) => void", "describedArgs": ["params"] } + }, "onClipboardPasteEnd": { "type": { "name": "func" } }, "onClipboardPasteStart": { "type": { "name": "func" } }, "onColumnHeaderClick": { diff --git a/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json b/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json index c7931fb45627..f6ef49744e48 100644 --- a/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json +++ b/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json @@ -305,6 +305,10 @@ "description": "Callback called when the data is copied to the clipboard.", "typeDescriptions": { "data": "The data copied to the clipboard." } }, + "onClipboardPasteBeforeStart": { + "description": "Callback fired before the clipboard paste operation starts. Use it to confirm or cancel the paste operation.", + "typeDescriptions": { "params": "Params passed to the callback." } + }, "onClipboardPasteEnd": { "description": "Callback fired when the clipboard paste operation ends." }, diff --git a/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx b/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx index 17e518486a87..67a47e5ccc2b 100644 --- a/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx +++ b/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx @@ -593,6 +593,14 @@ DataGridPremiumRaw.propTypes = { * @param {string} data The data copied to the clipboard. */ onClipboardCopy: PropTypes.func, + /** + * Callback fired before the clipboard paste operation starts. + * Use it to confirm or cancel the paste operation. + * @param {object} params Params passed to the callback. + * @param {string[][]} params.data The raw pasted data split by rows and cells. + * @returns {Promise | void} A promise that resolves to confirm the paste operation, and rejects to cancel it. + */ + onClipboardPasteBeforeStart: PropTypes.func, /** * Callback fired when the clipboard paste operation ends. */ diff --git a/packages/x-data-grid-premium/src/hooks/features/clipboard/useGridClipboardImport.ts b/packages/x-data-grid-premium/src/hooks/features/clipboard/useGridClipboardImport.ts index fe95b6cc33d9..8cc40c1cdda6 100644 --- a/packages/x-data-grid-premium/src/hooks/features/clipboard/useGridClipboardImport.ts +++ b/packages/x-data-grid-premium/src/hooks/features/clipboard/useGridClipboardImport.ts @@ -318,6 +318,7 @@ export const useGridClipboardImport = ( | 'onClipboardPasteEnd' | 'splitClipboardPastedText' | 'disableClipboardPaste' + | 'onClipboardPasteBeforeStart' >, ): void => { const processRowUpdate = props.processRowUpdate; @@ -328,6 +329,8 @@ export const useGridClipboardImport = ( const splitClipboardPastedText = props.splitClipboardPastedText; + const { pagination, onClipboardPasteBeforeStart } = props; + const handlePaste = React.useCallback>( async (params, event) => { if (!enableClipboardPaste) { @@ -360,6 +363,15 @@ export const useGridClipboardImport = ( return; } + if (onClipboardPasteBeforeStart) { + try { + await onClipboardPasteBeforeStart({ data: pastedData }); + } catch (error) { + // Cancel paste operation + return; + } + } + const cellUpdater = new CellValueUpdater({ apiRef, processRowUpdate, @@ -377,7 +389,7 @@ export const useGridClipboardImport = ( updateCell: (...args) => { cellUpdater.updateCell(...args); }, - pagination: props.pagination, + pagination, }); cellUpdater.applyUpdates(); @@ -390,7 +402,8 @@ export const useGridClipboardImport = ( enableClipboardPaste, rootEl, splitClipboardPastedText, - props.pagination, + pagination, + onClipboardPasteBeforeStart, ], ); diff --git a/packages/x-data-grid-premium/src/models/dataGridPremiumProps.ts b/packages/x-data-grid-premium/src/models/dataGridPremiumProps.ts index add53ef3b59d..50437b4e1ef8 100644 --- a/packages/x-data-grid-premium/src/models/dataGridPremiumProps.ts +++ b/packages/x-data-grid-premium/src/models/dataGridPremiumProps.ts @@ -169,6 +169,14 @@ export interface DataGridPremiumPropsWithoutDefaultValue void; + /** + * Callback fired before the clipboard paste operation starts. + * Use it to confirm or cancel the paste operation. + * @param {object} params Params passed to the callback. + * @param {string[][]} params.data The raw pasted data split by rows and cells. + * @returns {Promise | void} A promise that resolves to confirm the paste operation, and rejects to cancel it. + */ + onClipboardPasteBeforeStart?: (params: { data: string[][] }) => Promise | void; /** * Callback fired when the clipboard paste operation starts. */ From 89d8b0bbafb5b467e1505763a4a4e4d59f586b21 Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskyi Date: Fri, 1 Mar 2024 22:49:06 +0100 Subject: [PATCH 2/7] change signature --- .../data-grid/clipboard/ClipboardPasteEvents.tsx | 5 ++--- docs/data/data-grid/clipboard/clipboard.md | 13 ++++++++++++- .../src/DataGridPremium/DataGridPremium.tsx | 2 +- .../src/models/dataGridPremiumProps.ts | 4 ++-- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx b/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx index cb64f70fa4f9..d6a292ee531f 100644 --- a/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx +++ b/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx @@ -2,12 +2,11 @@ import * as React from 'react'; import { DataGridPremium, DataGridPremiumProps } from '@mui/x-data-grid-premium'; import { useDemoData } from '@mui/x-data-grid-generator'; -const confirmPaste = () => { +const confirmPaste = async () => { const confirmed = window.confirm('Are you sure you want to paste?'); if (!confirmed) { - return Promise.reject(); + throw new Error('The paste was cancelled'); } - return undefined; }; export default function ClipboardPasteEvents() { diff --git a/docs/data/data-grid/clipboard/clipboard.md b/docs/data/data-grid/clipboard/clipboard.md index ad6d87b9295f..714252e6dd20 100644 --- a/docs/data/data-grid/clipboard/clipboard.md +++ b/docs/data/data-grid/clipboard/clipboard.md @@ -88,7 +88,18 @@ For convenience, you can also listen to these events using their respective prop - `onClipboardPasteEnd` Additionally, there is the `onClipboardPasteBeforeStart` prop, which is called before the clipboard paste operation starts -and can be used to cancel or confirm the paste operation. +and can be used to cancel or confirm the paste operation: + +```tsx +const onClipboardPasteBeforeStart = async () => { + const confirmed = window.confirm('Are you sure you want to paste?'); + if (!confirmed) { + throw new Error('Paste operation cancelled'); + } +}; + +; +``` The demo below calls [`window.confirm()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm) before pasting. If confirmed, it displays a loading indicator during the paste operation. diff --git a/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx b/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx index 619d62545477..986029b67bf8 100644 --- a/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx +++ b/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx @@ -599,7 +599,7 @@ DataGridPremiumRaw.propTypes = { * Use it to confirm or cancel the paste operation. * @param {object} params Params passed to the callback. * @param {string[][]} params.data The raw pasted data split by rows and cells. - * @returns {Promise | void} A promise that resolves to confirm the paste operation, and rejects to cancel it. + * @returns {Promise} A promise that resolves to confirm the paste operation, and rejects to cancel it. */ onClipboardPasteBeforeStart: PropTypes.func, /** diff --git a/packages/x-data-grid-premium/src/models/dataGridPremiumProps.ts b/packages/x-data-grid-premium/src/models/dataGridPremiumProps.ts index 50437b4e1ef8..1f05cbcc4124 100644 --- a/packages/x-data-grid-premium/src/models/dataGridPremiumProps.ts +++ b/packages/x-data-grid-premium/src/models/dataGridPremiumProps.ts @@ -174,9 +174,9 @@ export interface DataGridPremiumPropsWithoutDefaultValue | void} A promise that resolves to confirm the paste operation, and rejects to cancel it. + * @returns {Promise} A promise that resolves to confirm the paste operation, and rejects to cancel it. */ - onClipboardPasteBeforeStart?: (params: { data: string[][] }) => Promise | void; + onClipboardPasteBeforeStart?: (params: { data: string[][] }) => Promise; /** * Callback fired when the clipboard paste operation starts. */ From 1b305c611ae6d27b0fa2cda0122f9a02b7c6af24 Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskyi Date: Fri, 1 Mar 2024 22:55:35 +0100 Subject: [PATCH 3/7] rename the fn --- .../data-grid/clipboard/ClipboardPasteEvents.js | 2 +- .../data-grid/clipboard/ClipboardPasteEvents.tsx | 2 +- .../clipboard/ClipboardPasteEvents.tsx.preview | 2 +- docs/data/data-grid/clipboard/clipboard.md | 6 +++--- .../pages/x/api/data-grid/data-grid-premium.json | 8 ++++---- .../data-grid-premium/data-grid-premium.json | 8 ++++---- .../src/DataGridPremium/DataGridPremium.tsx | 16 ++++++++-------- .../features/clipboard/useGridClipboardImport.ts | 10 +++++----- .../src/models/dataGridPremiumProps.ts | 2 +- 9 files changed, 28 insertions(+), 28 deletions(-) diff --git a/docs/data/data-grid/clipboard/ClipboardPasteEvents.js b/docs/data/data-grid/clipboard/ClipboardPasteEvents.js index a2429d1b1b11..46c07db40691 100644 --- a/docs/data/data-grid/clipboard/ClipboardPasteEvents.js +++ b/docs/data/data-grid/clipboard/ClipboardPasteEvents.js @@ -44,7 +44,7 @@ export default function ClipboardPasteEvents() { initialState={initialState} cellSelection processRowUpdate={processRowUpdate} - onClipboardPasteBeforeStart={confirmPaste} + onBeforeClipboardPasteStart={confirmPaste} onClipboardPasteStart={() => setLoading(true)} onClipboardPasteEnd={() => setLoading(false)} ignoreValueFormatterDuringExport diff --git a/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx b/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx index d6a292ee531f..7bf263c97b49 100644 --- a/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx +++ b/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx @@ -45,7 +45,7 @@ export default function ClipboardPasteEvents() { initialState={initialState} cellSelection processRowUpdate={processRowUpdate} - onClipboardPasteBeforeStart={confirmPaste} + onBeforeClipboardPasteStart={confirmPaste} onClipboardPasteStart={() => setLoading(true)} onClipboardPasteEnd={() => setLoading(false)} ignoreValueFormatterDuringExport diff --git a/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx.preview b/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx.preview index d4337edf1554..8a58ed2c391d 100644 --- a/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx.preview +++ b/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx.preview @@ -4,7 +4,7 @@ initialState={initialState} cellSelection processRowUpdate={processRowUpdate} - onClipboardPasteBeforeStart={confirmPaste} + onBeforeClipboardPasteStart={confirmPaste} onClipboardPasteStart={() => setLoading(true)} onClipboardPasteEnd={() => setLoading(false)} ignoreValueFormatterDuringExport diff --git a/docs/data/data-grid/clipboard/clipboard.md b/docs/data/data-grid/clipboard/clipboard.md index 714252e6dd20..158f655da42a 100644 --- a/docs/data/data-grid/clipboard/clipboard.md +++ b/docs/data/data-grid/clipboard/clipboard.md @@ -87,18 +87,18 @@ For convenience, you can also listen to these events using their respective prop - `onClipboardPasteStart` - `onClipboardPasteEnd` -Additionally, there is the `onClipboardPasteBeforeStart` prop, which is called before the clipboard paste operation starts +Additionally, there is the `onBeforeClipboardPasteStart` prop, which is called before the clipboard paste operation starts and can be used to cancel or confirm the paste operation: ```tsx -const onClipboardPasteBeforeStart = async () => { +const onBeforeClipboardPasteStart = async () => { const confirmed = window.confirm('Are you sure you want to paste?'); if (!confirmed) { throw new Error('Paste operation cancelled'); } }; -; +; ``` The demo below calls [`window.confirm()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm) before pasting. If confirmed, it displays a loading indicator during the paste operation. diff --git a/docs/pages/x/api/data-grid/data-grid-premium.json b/docs/pages/x/api/data-grid/data-grid-premium.json index 9bf8f270824e..ec096f93b92b 100644 --- a/docs/pages/x/api/data-grid/data-grid-premium.json +++ b/docs/pages/x/api/data-grid/data-grid-premium.json @@ -235,6 +235,10 @@ "describedArgs": ["model", "details"] } }, + "onBeforeClipboardPasteStart": { + "type": { "name": "func" }, + "signature": { "type": "function(params: object) => void", "describedArgs": ["params"] } + }, "onCellClick": { "type": { "name": "func" }, "signature": { @@ -288,10 +292,6 @@ "type": { "name": "func" }, "signature": { "type": "function(data: string) => void", "describedArgs": ["data"] } }, - "onClipboardPasteBeforeStart": { - "type": { "name": "func" }, - "signature": { "type": "function(params: object) => void", "describedArgs": ["params"] } - }, "onClipboardPasteEnd": { "type": { "name": "func" } }, "onClipboardPasteStart": { "type": { "name": "func" } }, "onColumnHeaderClick": { diff --git a/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json b/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json index f6ef49744e48..5bdd56c6f529 100644 --- a/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json +++ b/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json @@ -249,6 +249,10 @@ "details": "Additional details for this callback." } }, + "onBeforeClipboardPasteStart": { + "description": "Callback fired before the clipboard paste operation starts. Use it to confirm or cancel the paste operation.", + "typeDescriptions": { "params": "Params passed to the callback." } + }, "onCellClick": { "description": "Callback fired when any cell is clicked.", "typeDescriptions": { @@ -305,10 +309,6 @@ "description": "Callback called when the data is copied to the clipboard.", "typeDescriptions": { "data": "The data copied to the clipboard." } }, - "onClipboardPasteBeforeStart": { - "description": "Callback fired before the clipboard paste operation starts. Use it to confirm or cancel the paste operation.", - "typeDescriptions": { "params": "Params passed to the callback." } - }, "onClipboardPasteEnd": { "description": "Callback fired when the clipboard paste operation ends." }, diff --git a/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx b/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx index 986029b67bf8..303c57132e57 100644 --- a/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx +++ b/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx @@ -544,6 +544,14 @@ DataGridPremiumRaw.propTypes = { * @param {GridCallbackDetails} details Additional details for this callback. */ onAggregationModelChange: PropTypes.func, + /** + * Callback fired before the clipboard paste operation starts. + * Use it to confirm or cancel the paste operation. + * @param {object} params Params passed to the callback. + * @param {string[][]} params.data The raw pasted data split by rows and cells. + * @returns {Promise} A promise that resolves to confirm the paste operation, and rejects to cancel it. + */ + onBeforeClipboardPasteStart: PropTypes.func, /** * Callback fired when any cell is clicked. * @param {GridCellParams} params With all properties from [[GridCellParams]]. @@ -594,14 +602,6 @@ DataGridPremiumRaw.propTypes = { * @param {string} data The data copied to the clipboard. */ onClipboardCopy: PropTypes.func, - /** - * Callback fired before the clipboard paste operation starts. - * Use it to confirm or cancel the paste operation. - * @param {object} params Params passed to the callback. - * @param {string[][]} params.data The raw pasted data split by rows and cells. - * @returns {Promise} A promise that resolves to confirm the paste operation, and rejects to cancel it. - */ - onClipboardPasteBeforeStart: PropTypes.func, /** * Callback fired when the clipboard paste operation ends. */ diff --git a/packages/x-data-grid-premium/src/hooks/features/clipboard/useGridClipboardImport.ts b/packages/x-data-grid-premium/src/hooks/features/clipboard/useGridClipboardImport.ts index 8cc40c1cdda6..2ddf1ef70dfd 100644 --- a/packages/x-data-grid-premium/src/hooks/features/clipboard/useGridClipboardImport.ts +++ b/packages/x-data-grid-premium/src/hooks/features/clipboard/useGridClipboardImport.ts @@ -318,7 +318,7 @@ export const useGridClipboardImport = ( | 'onClipboardPasteEnd' | 'splitClipboardPastedText' | 'disableClipboardPaste' - | 'onClipboardPasteBeforeStart' + | 'onBeforeClipboardPasteStart' >, ): void => { const processRowUpdate = props.processRowUpdate; @@ -329,7 +329,7 @@ export const useGridClipboardImport = ( const splitClipboardPastedText = props.splitClipboardPastedText; - const { pagination, onClipboardPasteBeforeStart } = props; + const { pagination, onBeforeClipboardPasteStart } = props; const handlePaste = React.useCallback>( async (params, event) => { @@ -363,9 +363,9 @@ export const useGridClipboardImport = ( return; } - if (onClipboardPasteBeforeStart) { + if (onBeforeClipboardPasteStart) { try { - await onClipboardPasteBeforeStart({ data: pastedData }); + await onBeforeClipboardPasteStart({ data: pastedData }); } catch (error) { // Cancel paste operation return; @@ -403,7 +403,7 @@ export const useGridClipboardImport = ( rootEl, splitClipboardPastedText, pagination, - onClipboardPasteBeforeStart, + onBeforeClipboardPasteStart, ], ); diff --git a/packages/x-data-grid-premium/src/models/dataGridPremiumProps.ts b/packages/x-data-grid-premium/src/models/dataGridPremiumProps.ts index 1f05cbcc4124..ee3b030e670e 100644 --- a/packages/x-data-grid-premium/src/models/dataGridPremiumProps.ts +++ b/packages/x-data-grid-premium/src/models/dataGridPremiumProps.ts @@ -176,7 +176,7 @@ export interface DataGridPremiumPropsWithoutDefaultValue} A promise that resolves to confirm the paste operation, and rejects to cancel it. */ - onClipboardPasteBeforeStart?: (params: { data: string[][] }) => Promise; + onBeforeClipboardPasteStart?: (params: { data: string[][] }) => Promise; /** * Callback fired when the clipboard paste operation starts. */ From 0536d9c577b7e4042ff03aeec95a541d082b7577 Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskyi Date: Sat, 2 Mar 2024 13:04:04 +0100 Subject: [PATCH 4/7] format --- docs/data/data-grid/clipboard/ClipboardPasteEvents.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/data/data-grid/clipboard/ClipboardPasteEvents.js b/docs/data/data-grid/clipboard/ClipboardPasteEvents.js index 46c07db40691..e11c98c115ae 100644 --- a/docs/data/data-grid/clipboard/ClipboardPasteEvents.js +++ b/docs/data/data-grid/clipboard/ClipboardPasteEvents.js @@ -2,12 +2,11 @@ import * as React from 'react'; import { DataGridPremium } from '@mui/x-data-grid-premium'; import { useDemoData } from '@mui/x-data-grid-generator'; -const confirmPaste = () => { +const confirmPaste = async () => { const confirmed = window.confirm('Are you sure you want to paste?'); if (!confirmed) { - return Promise.reject(); + throw new Error('The paste was cancelled'); } - return undefined; }; export default function ClipboardPasteEvents() { From 5846c55e2dc1559daf4c551a17af826610b3217c Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskyi Date: Fri, 15 Mar 2024 22:06:05 +0100 Subject: [PATCH 5/7] add debug log --- .../src/hooks/features/clipboard/useGridClipboardImport.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/x-data-grid-premium/src/hooks/features/clipboard/useGridClipboardImport.ts b/packages/x-data-grid-premium/src/hooks/features/clipboard/useGridClipboardImport.ts index 2ddf1ef70dfd..be1527ee8797 100644 --- a/packages/x-data-grid-premium/src/hooks/features/clipboard/useGridClipboardImport.ts +++ b/packages/x-data-grid-premium/src/hooks/features/clipboard/useGridClipboardImport.ts @@ -21,6 +21,7 @@ import { useGridRegisterPipeProcessor, getPublicApiRef, isPasteShortcut, + useGridLogger, } from '@mui/x-data-grid/internals'; import { GRID_DETAIL_PANEL_TOGGLE_FIELD, GRID_REORDER_COL_DEF } from '@mui/x-data-grid-pro'; import { unstable_debounce as debounce } from '@mui/utils'; @@ -326,6 +327,7 @@ export const useGridClipboardImport = ( const getRowId = props.getRowId; const enableClipboardPaste = !props.disableClipboardPaste; const rootEl = apiRef.current.rootElementRef?.current; + const logger = useGridLogger(apiRef, 'useGridClipboardImport'); const splitClipboardPastedText = props.splitClipboardPastedText; @@ -367,7 +369,7 @@ export const useGridClipboardImport = ( try { await onBeforeClipboardPasteStart({ data: pastedData }); } catch (error) { - // Cancel paste operation + logger.debug('Clipboard paste operation cancelled'); return; } } @@ -404,6 +406,7 @@ export const useGridClipboardImport = ( splitClipboardPastedText, pagination, onBeforeClipboardPasteStart, + logger, ], ); From 563f41000dbed98031d9da4f3887dcd938b3b2bd Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskyi Date: Fri, 15 Mar 2024 22:28:04 +0100 Subject: [PATCH 6/7] use Dialog component instead of window.confirm --- .../clipboard/ClipboardPasteEvents.js | 76 ++++++++++++++++-- .../clipboard/ClipboardPasteEvents.tsx | 77 +++++++++++++++++-- .../ClipboardPasteEvents.tsx.preview | 12 --- 3 files changed, 139 insertions(+), 26 deletions(-) delete mode 100644 docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx.preview diff --git a/docs/data/data-grid/clipboard/ClipboardPasteEvents.js b/docs/data/data-grid/clipboard/ClipboardPasteEvents.js index e11c98c115ae..a755c662bc73 100644 --- a/docs/data/data-grid/clipboard/ClipboardPasteEvents.js +++ b/docs/data/data-grid/clipboard/ClipboardPasteEvents.js @@ -1,13 +1,12 @@ import * as React from 'react'; import { DataGridPremium } from '@mui/x-data-grid-premium'; import { useDemoData } from '@mui/x-data-grid-generator'; - -const confirmPaste = async () => { - const confirmed = window.confirm('Are you sure you want to paste?'); - if (!confirmed) { - throw new Error('The paste was cancelled'); - } -}; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogContentText from '@mui/material/DialogContentText'; +import DialogTitle from '@mui/material/DialogTitle'; +import Button from '@mui/material/Button'; export default function ClipboardPasteEvents() { const { data } = useDemoData({ @@ -35,6 +34,19 @@ export default function ClipboardPasteEvents() { }, }; + const confirm = useConfirm(); + const confirmPaste = React.useCallback(() => { + return new Promise((resolve, reject) => { + confirm.open((confirmed) => { + if (confirmed) { + resolve(); + } else { + reject(); + } + }); + }); + }, [confirm]); + return (
+ + + {'Are you sure you want to paste?'} + + + + This will overwrite the selected cells. + + + + + + +
); } + +const useConfirm = () => { + const [isOpen, setIsOpen] = React.useState(false); + const callbackRef = React.useRef(null); + + const open = React.useCallback((callback) => { + setIsOpen(true); + callbackRef.current = callback; + }, []); + + const cancel = React.useCallback(() => { + setIsOpen(false); + callbackRef.current?.(false); + callbackRef.current = null; + }, []); + + const confirm = React.useCallback(() => { + setIsOpen(false); + callbackRef.current?.(true); + callbackRef.current = null; + }, []); + + return { + open, + isOpen, + cancel, + confirm, + }; +}; diff --git a/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx b/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx index 7bf263c97b49..3c3b16913c61 100644 --- a/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx +++ b/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx @@ -1,13 +1,12 @@ import * as React from 'react'; import { DataGridPremium, DataGridPremiumProps } from '@mui/x-data-grid-premium'; import { useDemoData } from '@mui/x-data-grid-generator'; - -const confirmPaste = async () => { - const confirmed = window.confirm('Are you sure you want to paste?'); - if (!confirmed) { - throw new Error('The paste was cancelled'); - } -}; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogContentText from '@mui/material/DialogContentText'; +import DialogTitle from '@mui/material/DialogTitle'; +import Button from '@mui/material/Button'; export default function ClipboardPasteEvents() { const { data } = useDemoData({ @@ -37,6 +36,19 @@ export default function ClipboardPasteEvents() { }, }; + const confirm = useConfirm(); + const confirmPaste = React.useCallback<() => Promise>(() => { + return new Promise((resolve, reject) => { + confirm.open((confirmed) => { + if (confirmed) { + resolve(); + } else { + reject(); + } + }); + }); + }, [confirm]); + return (
+ + + + {'Are you sure you want to paste?'} + + + + This will overwrite the selected cells. + + + + + + +
); } + +const useConfirm = () => { + const [isOpen, setIsOpen] = React.useState(false); + const callbackRef = React.useRef<((confirmed: boolean) => void) | null>(null); + + const open = React.useCallback((callback: (confirmed: boolean) => void) => { + setIsOpen(true); + callbackRef.current = callback; + }, []); + + const cancel = React.useCallback(() => { + setIsOpen(false); + callbackRef.current?.(false); + callbackRef.current = null; + }, []); + + const confirm = React.useCallback(() => { + setIsOpen(false); + callbackRef.current?.(true); + callbackRef.current = null; + }, []); + + return { + open, + isOpen, + cancel, + confirm, + }; +}; diff --git a/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx.preview b/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx.preview deleted file mode 100644 index 8a58ed2c391d..000000000000 --- a/docs/data/data-grid/clipboard/ClipboardPasteEvents.tsx.preview +++ /dev/null @@ -1,12 +0,0 @@ - setLoading(true)} - onClipboardPasteEnd={() => setLoading(false)} - ignoreValueFormatterDuringExport - disableRowSelectionOnClick -/> \ No newline at end of file From 1d73ede3fc8d5d8ca5164d588cf901946c44ebba Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskyi Date: Fri, 15 Mar 2024 22:30:46 +0100 Subject: [PATCH 7/7] update doc --- docs/data/data-grid/clipboard/clipboard.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/data/data-grid/clipboard/clipboard.md b/docs/data/data-grid/clipboard/clipboard.md index 158f655da42a..78f953a88986 100644 --- a/docs/data/data-grid/clipboard/clipboard.md +++ b/docs/data/data-grid/clipboard/clipboard.md @@ -101,7 +101,8 @@ const onBeforeClipboardPasteStart = async () => { ; ``` -The demo below calls [`window.confirm()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm) before pasting. If confirmed, it displays a loading indicator during the paste operation. +The demo below uses the [`Dialog`](/material-ui/react-dialog/) component for paste confirmation. +If confirmed, the Data Grid displays a loading indicator during the paste operation. {{"demo": "ClipboardPasteEvents.js", "bg": "inline"}}