Skip to content

PDChat: allow disabling the message input (notifications-only mode) with an optional explanatory message #82

Description

@davidnmbond

Summary

Add a first-class way to disable the interactive message input in PDChat so the component can run in notifications-only ("toast-only") mode, with an optional, developer-configurable message rendered where the input would normally be to explain why sending is unavailable.

Motivation

A consuming application needs to disable the interactive chat for some users/tenants (e.g. governance/opt-out reasons) while still using PDChat/PDChatContainer as the notification/toast surface. Today there is no supported way to do this:

  • The input (<textarea> + Send button) always renders once the chat is opened.
  • The only disabling mechanism is IChatService.IsLive, which merely greys out the input (offline state) and appends " (Offline)" to the title — it doesn't hide the input, and it isn't the right semantic (the service is live; sending is just not permitted).
  • There is no way to show an explanatory message in place of the input.

The input lives in PDMessages.razor (lines ~20-30): <textarea disabled="@(!IsLive)"> and the Send <button disabled="@(!CanSendLocal)">. PDChat binds IsLive/CanSend into PDMessages.

Proposed API

Follow the existing IsXxxPermitted convention on IChatService (IsMaximizePermitted, IsClearPermitted, IsCanvasUsePermitted), added as default-implemented interface members so the change is non-breaking:

// IChatService.cs

/// <summary>
/// Whether the user may type and send messages. When false, the message input
/// (textarea + send button) is not rendered, and the chat acts as a
/// notifications-only ("toast-only") surface.
/// </summary>
bool IsInputPermitted => true;

/// <summary>
/// Optional message shown where the input would normally appear when
/// IsInputPermitted is false, e.g. to explain why sending is unavailable.
/// When null/empty (the default), nothing is rendered in place of the input
/// (pure toast-only mode).
/// </summary>
string? InputDisabledMessage => null;

Behaviour

IsInputPermitted InputDisabledMessage Result
true (default) (ignored) Normal input — unchanged from today
false null/empty (default) Input area not rendered; chat is notifications-only, nothing shown to the user
false non-empty Input area replaced by the given message (a footer/banner where the input would be)

Key point for existing consumers: defaults preserve today's behaviour exactly. Developers using the chat purely as a toast surface set IsInputPermitted = false and leave InputDisabledMessage null so nothing is displayed.

Suggested implementation

  • Add the two members to IChatService (default-implemented) — Interfaces/IChatService.cs.
  • Plumb them from PDChat into PDMessages (alongside the existing IsLive/CanSend).
  • In PDMessages.razor, when !IsInputPermitted: render nothing where InputDisabledMessage is null/empty, or render the message (styled as a disabled footer) when set — instead of the <textarea>/Send button block.
  • Message should be plain text by default (no HTML injection); if HTML is ever wanted it should be an explicit opt-in, consistent with ChatMessage.IsMessageHtml.
  • XML docs on all new public members (per CONTRIBUTING.md); keep TreatWarningsAsErrors clean.

Acceptance criteria

  • IChatService.IsInputPermitted (default true) and IChatService.InputDisabledMessage (default null) added without breaking existing implementers.
  • IsInputPermitted = false hides the textarea + Send button.
  • With a message set, it is shown where the input would be; with no message, nothing is shown.
  • Existing behaviour is unchanged when the new members are left at their defaults.
  • Demo page updated to show a notifications-only example (with and without a message).

Notes

Referenced files: Interfaces/IChatService.cs, PDChat.razor / PDChat.razor.cs, PDMessages.razor / PDMessages.razor.cs. Current version: 10.0.x (net10.0).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions