Skip to content

Build permissions editor UI with add/remove rules and presets #112

@doomspork

Description

@doomspork

Context

The permissions editor UI allows users to view and edit allow/deny permission rules. Supports adding individual rules, applying presets, removing rules, and showing the source (global/shared/local) for merged rules.

This is a detail pane view that renders when the Permissions tab is selected.

Ported from: Fig/Sources/Views/PermissionsEditorView.swift

What to implement

File path

  • fig-ui/src/views/permissions_editor.rs

Rust definitions

use iced::widget::{button, column, container, pick_list, row, scrollable, text, text_input};
use iced::Element;
use fig_core::models::editable_types::*;
use fig_core::models::navigation::EditingTarget;

// Messages for the permissions editor
#[derive(Debug, Clone)]
pub enum PermissionsMessage {
    AddRule,
    RemoveRule(uuid::Uuid),
    UpdateRuleText(uuid::Uuid, String),
    UpdateRuleType(uuid::Uuid, PermissionType),
    ApplyPreset(String), // preset id
    ChangeTarget(EditingTarget),
}

// State for the permissions editor
pub struct PermissionsEditorState {
    pub rules: Vec<EditablePermissionRule>,
    pub editing_target: EditingTarget,
    pub new_rule_text: String,
    pub new_rule_type: PermissionType,
}

impl PermissionsEditorState {
    pub fn new() -> Self { ... }

    pub fn update(&mut self, message: PermissionsMessage) {
        match message {
            PermissionsMessage::AddRule => { /* add new rule from new_rule_text */ }
            PermissionsMessage::RemoveRule(id) => { /* remove by UUID */ }
            PermissionsMessage::UpdateRuleText(id, text) => { /* update rule text */ }
            PermissionsMessage::UpdateRuleType(id, ptype) => { /* toggle allow/deny */ }
            PermissionsMessage::ApplyPreset(preset_id) => { /* add all rules from preset */ }
            PermissionsMessage::ChangeTarget(target) => { /* switch editing target */ }
        }
    }
}

pub fn permissions_editor_view<'a>(
    state: &PermissionsEditorState,
) -> Element<'a, PermissionsMessage> {
    // Layout:
    // 1. Target selector (Global / Project Shared / Project Local)
    // 2. Preset buttons row
    // 3. New rule input row: [text_input] [Allow/Deny picker] [Add button]
    // 4. Scrollable list of existing rules:
    //    Each row: [rule text] [Allow/Deny badge] [Source badge] [Remove button]
}

Key behaviors

  1. Target selector: Dropdown/segmented control to choose which config file to edit
  2. Preset quick-add: Buttons for each preset that add their rules to the list
  3. Add rule: Text input + type picker + add button
  4. Rule list: Scrollable list with each rule showing text, type badge, and remove button
  5. Source badges: Show where each rule originates (when viewing merged rules)

Acceptance criteria

  • Can add new permission rules via text input
  • Can remove rules by clicking remove button
  • Can apply presets to add multiple rules at once
  • Rules display with Allow/Deny visual distinction
  • Target selector switches between Global/Shared/Local editing
  • New rule text field clears after adding

Test requirements

  • test_add_rule — adding rule increases list length
  • test_remove_rule — removing rule by UUID decreases list length
  • test_apply_preset — preset adds all its rules
  • test_change_target — target updates correctly
  • test_duplicate_rule_handling — adding same rule text allowed (different UUIDs)

Dependencies

Requires: #109, #111

Blocks

#115

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions