Hone logo
Hone
Problems

Building Dynamic Action Groups in Angular

This challenge focuses on implementing a flexible component in Angular that allows users to dynamically create and manage groups of actions. This is a common pattern in user interfaces where users might need to group related operations, such as a set of buttons for file manipulation (copy, paste, delete) or configuration settings.

Problem Description

Your task is to create an Angular component that can display a collection of "action groups." Each action group should contain a title and a list of individual actions. The component should allow for the dynamic addition and removal of both action groups and individual actions within those groups.

Key Requirements:

  1. Action Group Component: Create a reusable Angular component (e.g., ActionGroupComponent) that accepts an ActionGroup interface as input. This component will render a single action group.
  2. Action Interface: Define an Action interface that includes at least a label (string) and an optional handler (function or method reference) for when the action is triggered.
  3. Action Group Interface: Define an ActionGroup interface that includes a title (string) and an array of Action objects.
  4. Container Component: Create a parent component (e.g., ActionGroupsContainerComponent) that manages an array of ActionGroup objects. This component should:
    • Display multiple ActionGroupComponent instances.
    • Provide functionality to add new, empty action groups.
    • Provide functionality to remove existing action groups.
    • Provide functionality to add new, empty actions to a specific action group.
    • Provide functionality to remove individual actions from a specific action group.
  5. Interactivity: When an action is clicked, its associated handler should be executed. If an action has no handler, nothing should happen when it's clicked.
  6. Dynamic Rendering: The UI should update correctly as action groups and actions are added or removed.

Expected Behavior:

  • The ActionGroupsContainerComponent will hold a list of ActionGroup data.
  • Each ActionGroupComponent will display its title and then list its Action items.
  • Clicking an action button should invoke its handler function if one is defined.
  • Buttons for "Add Action Group," "Remove Action Group," "Add Action," and "Remove Action" should be present and functional.
  • Adding an action group should append a new, empty ActionGroup object to the container's data.
  • Removing an action group should remove the corresponding ActionGroup object from the container's data.
  • Adding an action to a group should append a new, empty Action object to that group's actions array.
  • Removing an action should remove the corresponding Action object from its group's actions array.

Edge Cases:

  • An action group might have no actions.
  • An action might not have a handler.
  • The list of action groups could be empty.
  • Attempting to remove the last action group or action.

Examples

Example 1:

Input (Internal State of ActionGroupsContainerComponent):

actionGroups: ActionGroup[] = [
  {
    title: 'File Operations',
    actions: [
      { label: 'Copy', handler: () => console.log('Copy clicked!') },
      { label: 'Paste', handler: () => console.log('Paste clicked!') }
    ]
  },
  {
    title: 'Settings',
    actions: [
      { label: 'Save', handler: () => console.log('Save clicked!') }
    ]
  }
];

Expected UI Rendering:

File Operations
  [Copy Button] [Paste Button]
Settings
  [Save Button]

[Add Action Group Button]

Explanation: Two action groups are displayed, each with their respective actions rendered as buttons.

Example 2:

Scenario: Adding a new action group and action

Starting State (UI):

File Operations
  [Copy Button]

[Add Action Group Button]

User Action: Clicks "Add Action Group."

Internal State Change: actionGroups now includes a new empty group.

UI Update:

File Operations
  [Copy Button]
[Untitled Group Title]
  [Add Action Button]

[Add Action Group Button]

User Action: Clicks "Add Action" within the new group.

Internal State Change: The new group now has an empty action.

UI Update:

File Operations
  [Copy Button]
[Untitled Group Title]
  [Untitled Action Label] [Remove Action Button]

[Add Action Group Button]

Explanation: The component dynamically updates to reflect the addition of a new group and then a new action within that group.

Example 3:

Scenario: Removing an action and then the last action group

Starting State (UI):

File Operations
  [Copy Button] [Paste Button]
Settings
  [Save Button]

[Add Action Group Button]

User Action: Clicks "Remove Action" for the "Paste" action.

Internal State Change: The "Paste" action is removed from the "File Operations" group.

UI Update:

File Operations
  [Copy Button]
Settings
  [Save Button]

[Add Action Group Button]

User Action: Clicks "Remove Action Group" for the "Settings" group.

Internal State Change: The "Settings" group is removed.

UI Update:

File Operations
  [Copy Button]

[Add Action Group Button]

Explanation: Demonstrates the removal of both an individual action and an entire action group, with the UI updating accordingly.

Constraints

  • The solution should be implemented using Angular and TypeScript.
  • All component logic, data management, and UI rendering should be handled within Angular's framework.
  • Avoid using third-party UI libraries for the core action group and action rendering (you can use them for buttons if desired, but the structure should be your own).
  • The maximum number of initial action groups should be limited to 5 for testing purposes.
  • The maximum number of initial actions per group should be limited to 10.

Notes

  • Consider how to handle the initial state of newly added action groups and actions (e.g., using default labels like "Untitled Group" or "Untitled Action").
  • Think about how you will pass data and events between the parent and child components (e.g., using @Input() and @Output() decorators).
  • The handler for actions can be a simple () => void function.
  • For the "Remove Action" and "Remove Action Group" functionality, you'll need a way to uniquely identify which action or group to remove. An index or a unique ID could be useful.
  • This challenge encourages good component design and state management practices within Angular.
Loading editor...
typescript