Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { css } from '@leafygreen-ui/emotion';
import { palette } from '@leafygreen-ui/palette';
import { spacing } from '@leafygreen-ui/tokens';
import { useDarkMode } from '../../hooks/use-theme';
import { showErrorDetails } from '../../hooks/use-error-details';

type Status =
| 'Initial'
Expand Down Expand Up @@ -81,13 +82,30 @@ function useHadronDocumentStatus(
? 'Deleting'
: 'Initial';
});
const [errorMessage, setErrorMessage] = useState<string | null>(null);
const [error, setError] = useState<{
message: string;
details?: Record<string, unknown>;
} | null>(null);
const invalidElementsRef = useRef(new Set());

const updateStatus = useCallback((newStatus: Status, errorMessage = null) => {
setStatus(newStatus);
setErrorMessage(errorMessage);
}, []);
const updateStatus = useCallback(
(
newStatus: Status,
error: Error | null = null,
errorDetails?: Record<string, unknown>
) => {
setStatus(newStatus);
setError(
error
? {
message: error?.message,
details: errorDetails,
}
: null
);
},
[]
);

useEffect(() => {
if (status !== 'Initial') {
Expand Down Expand Up @@ -128,17 +146,23 @@ function useHadronDocumentStatus(
const onUpdateSuccess = () => {
updateStatus('UpdateSuccess');
};
const onUpdateError = (err: string) => {
updateStatus('UpdateError', err);
const onUpdateError = (
err: Error,
errorDetails?: Record<string, unknown>
) => {
updateStatus('UpdateError', err, errorDetails);
};
const onRemoveStart = () => {
updateStatus('DeleteStart');
};
const onRemoveSuccess = () => {
updateStatus('DeleteSuccess');
};
const onRemoveError = (err: string) => {
updateStatus('DeleteError', err);
const onRemoveError = (
err: Error,
errorDetails?: Record<string, unknown>
) => {
updateStatus('DeleteError', err, errorDetails);
};

doc.on(Element.Events.Added, onUpdate);
Expand Down Expand Up @@ -183,30 +207,30 @@ function useHadronDocumentStatus(
}
}, [status, updateStatus]);

return { status, updateStatus, errorMessage };
return { status, updateStatus, error };
}

const container = css({
display: 'flex',
paddingTop: spacing[2],
paddingRight: spacing[2],
paddingBottom: spacing[2],
paddingLeft: spacing[3],
paddingTop: spacing[200],
paddingRight: spacing[200],
paddingBottom: spacing[200],
paddingLeft: spacing[400],
alignItems: 'center',
gap: spacing[2],
gap: spacing[200],
borderBottomLeftRadius: 'inherit',
borderBottomRightRadius: 'inherit',
});

const message = css({
overflow: 'hidden',
textOverflow: 'ellipsis',
overflow: 'scroll',
});

const buttonGroup = css({
display: 'flex',
marginLeft: 'auto',
gap: spacing[2],
gap: spacing[200],
flexShrink: 0,
});

const button = css({
Expand Down Expand Up @@ -275,7 +299,7 @@ const EditActionsFooter: React.FunctionComponent<{
const {
status: _status,
updateStatus,
errorMessage,
error,
} = useHadronDocumentStatus(doc, editing, deleting);

const darkMode = useDarkMode();
Expand Down Expand Up @@ -303,10 +327,25 @@ const EditActionsFooter: React.FunctionComponent<{
data-status={status}
>
<div className={message} data-testid="document-footer-message">
{errorMessage ?? statusMessage}
{error?.message ?? statusMessage}
</div>
{!isSuccess(status) && (
<div className={buttonGroup}>
{error?.details && (
<Button
className={button}
size="xsmall"
onClick={() =>
showErrorDetails({
details: error.details!,
closeAction: 'close',
})
}
data-testid="edit-actions-footer-error-details-button"
>
VIEW ERROR DETAILS
</Button>
)}
<Button
type="button"
size="xsmall"
Expand Down
26 changes: 25 additions & 1 deletion packages/compass-components/src/hooks/use-confirmation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useContext, useEffect, useRef, useState } from 'react';
import { Variant as ConfirmationModalVariant } from '@leafygreen-ui/confirmation-modal';
import ConfirmationModal from '../components/modals/confirmation-modal';
import { css } from '@leafygreen-ui/emotion';
import type { ButtonProps } from '@leafygreen-ui/button';

export { ConfirmationModalVariant };

Expand All @@ -11,6 +12,7 @@ type ConfirmationProperties = Partial<
Pick<ConfirmationModalProps, 'title' | 'variant' | 'requiredInputText'>
> & {
buttonText?: React.ReactNode;
confirmButtonProps?: Omit<ButtonProps, 'onClick'>;
hideConfirmButton?: boolean;
hideCancelButton?: boolean;
description?: React.ReactNode;
Expand Down Expand Up @@ -100,8 +102,28 @@ export const ConfirmationModalArea: React.FC = ({ children }) => {
});
const callbackRef = useRef<ConfirmationCallback>();

const listenerRef =
useRef<(event: CustomEvent<ShowConfirmationEventDetail>) => void>();

const contextValue = React.useMemo(
() => ({ showConfirmation, isMounted: true }),
() => ({
showConfirmation: (props: ConfirmationProperties) => {
return new Promise<boolean>((resolve, reject) => {
const event = new CustomEvent<ShowConfirmationEventDetail>(
'show-confirmation',
{
detail: {
props: { ...props, confirmationId: ++confirmationId },
resolve,
reject,
},
}
);
listenerRef.current?.(event);
});
},
isMounted: true,
}),
[]
);

Expand All @@ -127,6 +149,7 @@ export const ConfirmationModalArea: React.FC = ({ children }) => {
};
props.signal?.addEventListener('abort', onAbort);
};
listenerRef.current = listener;
globalConfirmation.addEventListener('show-confirmation', listener);
return () => {
globalConfirmation.removeEventListener('show-confirmation', listener);
Expand Down Expand Up @@ -170,6 +193,7 @@ export const ConfirmationModalArea: React.FC = ({ children }) => {
: undefined,
children: confirmationProps.buttonText ?? 'Confirm',
onClick: handleConfirm,
...confirmationProps.confirmButtonProps,
}}
cancelButtonProps={{
className: confirmationProps.hideCancelButton
Expand Down
38 changes: 38 additions & 0 deletions packages/compass-components/src/hooks/use-error-details.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {
type showConfirmation as originalShowConfirmation,
showConfirmation,
} from './use-confirmation';
import { Code } from '../components/leafygreen';
import React from 'react';
import { ButtonVariant } from '..';

const getShowErrorDetails = (
showConfirmation: typeof originalShowConfirmation
) => {
return ({
details,
closeAction,
}: {
details: Record<string, unknown>;
closeAction: 'back' | 'close';
}) =>
void showConfirmation({
title: 'Error details',
description: (
<Code
language="json"
data-testid="error-details-json"
id="error-details-json"
>
{JSON.stringify(details, undefined, 2)}
</Code>
),
hideCancelButton: true,
buttonText: closeAction.replace(/\b\w/g, (c) => c.toUpperCase()),
confirmButtonProps: {
variant: ButtonVariant.Default,
},
});
};

export const showErrorDetails = getShowErrorDetails(showConfirmation);
1 change: 1 addition & 0 deletions packages/compass-components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ export {
ConfirmationModalArea,
showConfirmation,
} from './hooks/use-confirmation';
export { showErrorDetails } from './hooks/use-error-details';
export {
useHotkeys,
formatHotkey,
Expand Down
1 change: 1 addition & 0 deletions packages/compass-crud/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
"jsondiffpatch": "^0.5.0",
"lodash": "^4.17.21",
"mongodb-data-service": "^22.25.6",
"mongodb": "^6.12.0",
"mongodb-ns": "^2.4.2",
"mongodb-query-parser": "^4.3.0",
"numeral": "^2.0.6",
Expand Down
8 changes: 2 additions & 6 deletions packages/compass-crud/src/components/document-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,7 @@ import {
DOCUMENTS_STATUS_FETCHING,
DOCUMENTS_STATUS_FETCHED_INITIAL,
} from '../constants/documents-statuses';
import {
type CrudStore,
type BSONObject,
type DocumentView,
} from '../stores/crud-store';
import type { CrudStore, BSONObject, DocumentView } from '../stores/crud-store';
import { getToolbarSignal } from '../utils/toolbar-signal';
import BulkDeleteModal from './bulk-delete-modal';
import { useTabState } from '@mongodb-js/compass-workspaces/provider';
Expand Down Expand Up @@ -84,7 +80,7 @@ export type DocumentListProps = {
| 'doc'
| 'csfleState'
| 'isOpen'
| 'message'
| 'error'
| 'mode'
| 'jsonDoc'
| 'isCommentNeeded'
Expand Down
Loading
Loading