import Button from '@/Components/Button/Button' import CompoundPredicateBuilder from '@/Components/SmartViewBuilder/CompoundPredicateBuilder' import Icon from '@/Components/Icon/Icon' import IconPicker from '@/Components/Icon/IconPicker' import Popover from '@/Components/Popover/Popover' import ModalDialog from '@/Components/Shared/ModalDialog' import ModalDialogButtons from '@/Components/Shared/ModalDialogButtons' import ModalDialogDescription from '@/Components/Shared/ModalDialogDescription' import ModalDialogLabel from '@/Components/Shared/ModalDialogLabel' import Spinner from '@/Components/Spinner/Spinner' import { Platform } from '@standardnotes/snjs' import { observer } from 'mobx-react-lite' import { useEffect, useRef, useState } from 'react' import { AddSmartViewModalController } from './AddSmartViewModalController' import TabPanel from '../Tabs/TabPanel' import { useTabState } from '../Tabs/useTabState' import TabsContainer from '../Tabs/TabsContainer' import CopyableCodeBlock from '../Shared/CopyableCodeBlock' import { Disclosure, DisclosureButton, DisclosurePanel } from '@reach/disclosure' import { classNames } from '@/Utils/ConcatenateClassNames' type Props = { controller: AddSmartViewModalController platform: Platform } const ConflictedNotesExampleCode = `{ "keypath": "content.conflict_of.length", "operator": ">", "value": 0 }` const ComplexCompoundExampleCode = `{ "operator": "and", "value": [ { "operator": "not", "value": { "keypath": "tags", "operator": "includes", "value": { "keypath": "title", "operator": "=", "value": "completed" } } }, { "keypath": "tags", "operator": "includes", "value": { "keypath": "title", "operator": "=", "value": "todo" } } ] } ` const AddSmartViewModal = ({ controller, platform }: Props) => { const { isSaving, title, setTitle, icon, setIcon, closeModal, saveCurrentSmartView, predicateController, customPredicateJson, setCustomPredicateJson, isCustomJsonValidPredicate, setIsCustomJsonValidPredicate, validateAndPrettifyCustomPredicate, } = controller const titleInputRef = useRef(null) const customJsonInputRef = useRef(null) const [shouldShowIconPicker, setShouldShowIconPicker] = useState(false) const iconPickerButtonRef = useRef(null) const [shouldShowJsonExamples, setShouldShowJsonExamples] = useState(false) const toggleIconPicker = () => { setShouldShowIconPicker((shouldShow) => !shouldShow) } const tabState = useTabState({ defaultTab: 'builder', }) const save = () => { if (!title.length) { titleInputRef.current?.focus() return } if (tabState.activeTab === 'custom' && !isCustomJsonValidPredicate) { validateAndPrettifyCustomPredicate() return } void saveCurrentSmartView() } const canSave = tabState.activeTab === 'builder' || isCustomJsonValidPredicate useEffect(() => { if (!customJsonInputRef.current) { return } if (tabState.activeTab === 'custom' && isCustomJsonValidPredicate === false) { customJsonInputRef.current.focus() } }, [isCustomJsonValidPredicate, tabState.activeTab]) return ( Add Smart View
Title:
{ setTitle(event.target.value) }} ref={titleInputRef} />
Icon:
{ setIcon(value ?? 'restore') toggleIconPicker() }} platform={platform} useIconGrid={true} portalDropdown={false} />
Predicate: