diff options
-rw-r--r-- | src/components/PluginSettings/PluginModal.tsx | 59 | ||||
-rw-r--r-- | src/utils/types.ts | 7 |
2 files changed, 43 insertions, 23 deletions
diff --git a/src/components/PluginSettings/PluginModal.tsx b/src/components/PluginSettings/PluginModal.tsx index 908876f..970eb52 100644 --- a/src/components/PluginSettings/PluginModal.tsx +++ b/src/components/PluginSettings/PluginModal.tsx @@ -67,6 +67,7 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti const [tempSettings, setTempSettings] = React.useState<Record<string, any>>({}); const [errors, setErrors] = React.useState<Record<string, boolean>>({}); + const [saveError, setSaveError] = React.useState<string | null>(null); const canSubmit = () => Object.values(errors).every(e => !e); @@ -79,11 +80,20 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti })(); }, []); - function saveAndClose() { + async function saveAndClose() { if (!plugin.options) { onClose(); return; } + + if (plugin.beforeSave) { + const result = await Promise.resolve(plugin.beforeSave(tempSettings)); + if (result !== true) { + setSaveError(result); + return; + } + } + let restartNeeded = false; for (const [key, value] of Object.entries(tempSettings)) { const option = plugin.options[key]; @@ -195,28 +205,31 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti </Forms.FormSection> </ModalContent> <ModalFooter> - <Flex> - <Button - onClick={onClose} - size={Button.Sizes.SMALL} - color={Button.Colors.RED} - > - Exit Without Saving - </Button> - <Tooltip text="You must fix all errors before saving" shouldShow={!canSubmit()}> - {({ onMouseEnter, onMouseLeave }) => ( - <Button - size={Button.Sizes.SMALL} - color={Button.Colors.BRAND} - onClick={saveAndClose} - onMouseEnter={onMouseEnter} - onMouseLeave={onMouseLeave} - disabled={!canSubmit()} - > - Save & Exit - </Button> - )} - </Tooltip> + <Flex flexDirection="column" style={{ width: "100%" }}> + <Flex style={{ marginLeft: "auto" }}> + <Button + onClick={onClose} + size={Button.Sizes.SMALL} + color={Button.Colors.RED} + > + Exit Without Saving + </Button> + <Tooltip text="You must fix all errors before saving" shouldShow={!canSubmit()}> + {({ onMouseEnter, onMouseLeave }) => ( + <Button + size={Button.Sizes.SMALL} + color={Button.Colors.BRAND} + onClick={saveAndClose} + onMouseEnter={onMouseEnter} + onMouseLeave={onMouseLeave} + disabled={!canSubmit()} + > + Save & Exit + </Button> + )} + </Tooltip> + </Flex> + {saveError && <Text variant="text-md/semibold" style={{ color: "var(--text-danger)" }}>Error while saving: {saveError}</Text>} </Flex> </ModalFooter> </ModalRoot> diff --git a/src/utils/types.ts b/src/utils/types.ts index 1916f9b..41dd0c1 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -16,6 +16,8 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ +import { Promisable } from "type-fest"; + import { Command } from "../api/Commands"; // exists to export default definePlugin({...}) @@ -76,6 +78,11 @@ interface PluginDef { */ options?: Record<string, PluginOptionsItem>; /** + * Check that this returns true before allowing a save to complete. + * If a string is returned, show the error to the user. + */ + beforeSave?(options: Record<string, any>): Promisable<true | string>; + /** * Allows you to specify a custom Component that will be rendered in your * plugin's settings page */ |