aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/components/PluginSettings/PluginModal.tsx59
-rw-r--r--src/utils/types.ts7
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
*/