import { Button, DialogFooter, Tooltip } from '@blueprintjs/core'; import styled from '@emotion/styled'; import type { ACSExportOptions, Spectrum1D, Spectrum, } from '@zakodium/nmrium-core'; import type { FormEvent } from 'react'; import { FieldGroupSVGTextStyleFields, Form, assert, svgTextStyleFieldsSchema, useForm, } from 'react-science/ui'; import { z } from 'zod'; import { isSpectrum1D } from '../../data/data1d/Spectrum1D/index.js'; import { ClipboardFallbackModal } from '../../utils/clipboard/clipboardComponents.tsx'; import { useClipboard } from '../../utils/clipboard/clipboardHooks.ts'; import { usePreferences } from '../context/PreferencesContext.js'; import { useToaster } from '../context/ToasterContext.tsx'; import { EmptyText } from '../elements/EmptyText.js'; import { StandardDialog } from '../elements/StandardDialog.tsx'; import { StyledDialogBody } from '../elements/StyledDialogBody.js'; import { buildPublicationString } from '../hooks/use_publication_strings.js'; const Body = styled.div` border: 1px solid #e9e9e9; min-height: 180px; padding: 5px; width: 100%; margin-top: 15px; `; interface SelectItem { label: string; value: T; } type ExportFormatType = 'IMJA' | 'IMJ' | 'D'; type ExportSignalKind = ACSExportOptions['signalKind']; const validationSchema = z.object({ acs: z.object({ signalKind: z.enum(['all', 'signal']), ascending: z.boolean(), format: z.string(), couplingFormat: z.string(), deltaFormat: z.string(), textStyle: svgTextStyleFieldsSchema.optional(), }), isPublicationStringShown: z.boolean(), }); const exportOptions: Array> = [ { label: 'All', value: 'all', }, { label: 'Only signals', value: 'signal', }, ]; const exportFormats: Array> = [ { label: 'Delta', value: 'D', }, { label: 'Delta, Intensity, Multiplicity, Couplings, Assignment', value: 'IMJA', }, { label: 'Delta, Intensity, Multiplicity, Couplings', value: 'IMJ', }, ]; interface InnerPublicationStringModalProps { onClose: () => void; acsExportOptions: ACSExportOptions; spectrum: Spectrum; publicationStringVisibility?: { isShown: boolean; toggle: () => void; }; allowTextStyle?: boolean; saveLabel?: string; copyOnSave?: boolean; } interface PublicationStringModalProps extends InnerPublicationStringModalProps { isOpen: boolean; } export function PublicationStringModal(props: PublicationStringModalProps) { const { isOpen, ...otherProps } = props; if (!isOpen) return; return ; } function InnerPublicationStringModal(props: InnerPublicationStringModalProps) { const { onClose, acsExportOptions, spectrum, publicationStringVisibility, allowTextStyle = false, saveLabel = 'Apply', copyOnSave = false, } = props; const { dispatch } = usePreferences(); const toaster = useToaster(); const { rawWriteWithType, shouldFallback, text, cleanShouldFallback } = useClipboard(); function sendToClipboard(value: string) { void rawWriteWithType(value, 'text/html').then(() => toaster.show({ message: 'Data copied to clipboard', intent: 'success' }), ); } const defaultValues = validationSchema.encode({ acs: acsExportOptions, isPublicationStringShown: publicationStringVisibility?.isShown ?? false, }); if ( defaultValues.acs.textStyle && defaultValues.acs.textStyle.fontSize === undefined ) { defaultValues.acs.textStyle.fontSize = '12'; } const form = useForm({ defaultValues, validators: { onChange: validationSchema }, onSubmit: ({ value, formApi }) => { assert(spectrum && isSpectrum1D(spectrum)); const nucleus = spectrum.info.nucleus; const parsedValues = validationSchema.parse(value); if ( !formApi.state.fieldMeta['acs.textStyle.fontSize']?.isTouched && parsedValues.acs.textStyle?.fontSize === 12 ) { parsedValues.acs.textStyle.fontSize = undefined; } // Apply dispatch({ type: 'CHANGE_EXPORT_ACS_SETTINGS', payload: { options: parsedValues.acs, nucleus }, }); if ( publicationStringVisibility && parsedValues.isPublicationStringShown !== publicationStringVisibility.isShown ) { publicationStringVisibility.toggle(); } // Copy if (copyOnSave) { const publicationString = buildPublicationString({ spectrum, acs: parsedValues.acs, }); sendToClipboard(publicationString); } // Close onClose(); }, }); if (!spectrum || !isSpectrum1D(spectrum)) return null; function onSubmit(event: FormEvent) { event.preventDefault(); void form.handleSubmit(event); } return ( {spectrum.info.nucleus} } onClose={onClose} style={{ minWidth: 600 }} >
This configuration is at the nucleus level. {(field) => } {(field) => } {(field) => } {(field) => } {(field) => } {allowTextStyle && ( )} s.values}> {(values) => ( )} {saveLabel} } > {publicationStringVisibility && ( {(field) => ( )} )}
); } const CopyPreviewButton = styled(Button)` margin-left: 5px; margin-bottom: 5px; `; const HelpForm = styled.p` margin: 8px; `; interface PublicationStringPreviewProps { spectrum: Spectrum1D; values: z.input; onCopy: (value: string) => void; } function PublicationStringPreview(props: PublicationStringPreviewProps) { const { spectrum, values, onCopy } = props; const { acs } = validationSchema.parse(values); const value = buildPublicationString({ spectrum, acs }); if (!value) return ; return ( <> onCopy(value)} icon="duplicate" /> {/* eslint-disable-next-line react/no-danger */}
); }