from flask_wtf import FlaskForm from flask_wtf.file import FileAllowed, FileField, FileRequired from wtforms import BooleanField, HiddenField, SelectField, StringField, TextAreaField from wtforms.validators import DataRequired, Optional class WizardStepForm(FlaskForm): server_type = SelectField( "Server Type", choices=[ ("plex", "Plex"), ("jellyfin", "Jellyfin"), ("emby", "Emby"), ("audiobookshelf", "Audiobookshelf"), ("romm", "Romm"), ("komga", "Komga"), ("kavita", "Kavita"), ], validators=[DataRequired()], ) category = SelectField( "Category", choices=[ ("pre_invite", "Before Invite Acceptance"), ("post_invite", "After Invite Acceptance"), ], default="post_invite", validators=[DataRequired()], ) position = HiddenField("Position", default="0") title = StringField("Title", validators=[Optional()]) markdown = TextAreaField("Markdown", validators=[DataRequired()]) # Require explicit user interaction before enabling Next require_interaction = BooleanField( "Require User Interaction", default=False, description="Block the user continuing, until they click a button or link in this step.", ) class WizardPresetForm(FlaskForm): """Form for creating wizard steps from presets.""" server_type = SelectField( "Server Type", choices=[ ("plex", "Plex"), ("jellyfin", "Jellyfin"), ("emby", "Emby"), ("audiobookshelf", "Audiobookshelf"), ("romm", "Romm"), ("komga", "Komga"), ("kavita", "Kavita"), ], validators=[DataRequired()], ) category = SelectField( "Category", choices=[ ("pre_invite", "Before Invite Acceptance"), ("post_invite", "After Invite Acceptance"), ], default="post_invite", validators=[DataRequired()], ) preset_id = SelectField( "Preset", choices=[], # Will be populated dynamically validators=[DataRequired()], ) # Variables for preset templates discord_id = StringField("Discord Server ID", validators=[Optional()]) overseerr_url = StringField("Overseerr/Ombi URL", validators=[Optional()]) class WizardBundleForm(FlaskForm): """Simple form to create / edit a WizardBundle.""" name = StringField("Name", validators=[DataRequired()]) description = StringField("Description", validators=[Optional()]) # optional: Steps selection handled in separate UI; keep form minimal class SimpleWizardStepForm(FlaskForm): """Minimal form for bundle-only steps (no server_type, no requires).""" category = SelectField( "Category", choices=[ ("pre_invite", "Before Invite Acceptance"), ("post_invite", "After Invite Acceptance"), ], default="post_invite", validators=[DataRequired()], ) title = StringField("Title", validators=[Optional()]) markdown = TextAreaField("Markdown", validators=[DataRequired()]) # Allow interaction requirement for custom/bundle steps as well require_interaction = BooleanField( "Require User Interaction", default=False, description="Block the user continuing, until they click a button or link in this step.", ) class WizardImportForm(FlaskForm): """Form for importing wizard steps or bundles from JSON files.""" file = FileField( "JSON File", validators=[ FileRequired("Please select a JSON file to import."), FileAllowed(["json"], "Only JSON files are allowed."), ], ) replace_existing = BooleanField( "Replace Existing", default=False, description="Check to replace existing data, leave unchecked to merge with existing.", )