0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-14 13:58:53 +08:00
discourse/plugins/discourse-assign/config/locales/client.en.yml
Joffrey JAFFEUX 0914b9fb32
FEATURE: discourse-workflows (#40374)
Discourse Workflows is a visual automation plugin for admins. A workflow
is a
versioned graph made of trigger, condition, action, and utility nodes.

## Architecture

The plugin has three main responsibilities:

- Store and version workflow graphs.
- Render an admin editor from node metadata.
- Execute published workflow versions and record their results.

The graph is stored as workflow nodes plus connections. Each node has a
stable
type, a type version, editor position, configuration parameters,
optional
credential references, and direct runtime settings. Published workflows
create immutable versions that executions can safely use even after the
draft changes.

## Runtime Flow

A normal execution follows this path:

1. A trigger produces initial data from a Discourse event, schedule,
webhook, or
   manual run.
2. Trigger data is wrapped as workflow items.
3. The executor queues downstream nodes from the graph connections.
4. Each node receives input items and returns one array per output.
5. The executor records the step, stores node output for expressions,
and routes
   each output array to connected downstream nodes.
6. The execution finishes, fails, or enters a waiting state.

Waiting nodes persist enough execution context to resume later. Resume
requests
continue from the waiting node using the workflow snapshot saved with
the
execution, not the latest draft.

Expressions are resolved at runtime against the current item, node
parameters,
workflow variables, previous node outputs, and execution context. The
editor
stores expression values in parameters; node code should read them
through the
execution context instead of parsing parameter values directly.

## Adding nodes

- Workflow nodes, registered with
`DiscoursePluginRegistry.register_discourse_workflows_node`.

Core nodes live in `lib/discourse_workflows/nodes` and are registered
during
plugin initialization. Other plugins can add their own nodes when
`DiscourseWorkflows` is loaded.

## Node API

Nodes inherit from `DiscourseWorkflows::NodeType`. A node class is
responsible
for two things:

- Declaring its contract with `description(...)`.
- Implementing the runtime entry point for its node kind.

The description is the public contract between the node, editor,
validator, and
runtime. It should include:

- `name`: stable identifier, usually prefixed by `trigger:`, `action:`,
`condition:`, or `flow:`.
- `version`: implementation version used by stored workflow nodes.
- `defaults`: editor metadata such as icon and color.
- `group`: palette category.
- `inputs` and `outputs`: graph ports.
- `properties`: configuration fields rendered by the property engine.
- `credentials`: credential slots the node can use.
- `webhooks`: public or resume webhook declarations.
- `events`: Discourse events that should activate a trigger node.
- `capabilities`: feature flags such as manual triggering, waiting, or
current
  user access.
- `available`: optional availability gate for nodes backed by another
plugin or
  site setting.

Description data should stay declarative. Put business logic in the
runtime
entry point or helper classes.

### Action, Condition, And Flow Nodes

Action-like nodes implement `execute(exec_ctx)`. They receive input
items through
the execution context and return positional output arrays. A one-output
node
returns one outer array; a branching node returns one inner array per
branch.

### Trigger Nodes

Trigger nodes start executions. Event triggers declare `events` and
usually
implement:

- `valid?` to ignore events that should not run workflows.
- `matches?(trigger_ctx)` to compare event data with node configuration.
- `output` to produce the initial workflow item data.

### Webhook And Waiting Nodes

Webhook trigger nodes declare webhook metadata and produce initial data
from the
incoming request. Waiting nodes pause an execution and resume it through
a later
interaction or webhook.

### Dynamic Options

Nodes can provide dynamic property options with
`self.load_options_context(context)`. Use the context object to access
current
parameters, filtered credentials, the search filter, the current user,
guardian,
and shared helpers.

### Errors And Logs

Raise `DiscourseWorkflows::NodeError` for failures admins can act on,
such as
invalid configuration or missing Discourse records. Unexpected
exceptions fail
the current execution.

---------

---------

Co-authored-by: Renato Atilio <3530+renato@users.noreply.github.com>
Co-authored-by: Martin Brennan <martin@discourse.org>
Co-authored-by: Jordan Vidrine <30537603+jordanvidrine@users.noreply.github.com>
2026-05-28 19:44:50 +02:00

214 lines
8.4 KiB
YAML
Vendored
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

en:
admin_js:
admin:
site_settings:
categories:
discourse_assign: "Discourse Assign"
js:
filters:
unassigned:
title: "Unassigned"
help: "Topics that are not assigned"
action_codes:
assigned: "Assigned %{who} %{when}"
assigned_group: "Assigned %{who} %{when}"
assigned_to_post: "Assigned %{who} to <a href='%{path}'>post</a> %{when}"
assigned_group_to_post: "Assigned %{who} to <a href='%{path}'>post</a> %{when}"
unassigned: "Unassigned %{who} %{when}"
unassigned_group: "Unassigned %{who} %{when}"
unassigned_from_post: "Unassigned %{who} from <a href='%{path}'>post</a> %{when}"
unassigned_group_from_post: "Unassigned %{who} from <a href='%{path}'>post</a> %{when}"
reassigned: "Reassigned %{who} %{when}"
reassigned_group: "Reassigned %{who} %{when}"
details_change: "Changed assignment details for %{who} %{when}"
note_change: "Changed assignment note for %{who} %{when}"
status_change: "Changed assignment status for %{who} %{when}"
discourse_assign:
add_unassigned_filter: "Add 'unassigned' filter to category"
cant_act: "You cannot act on flags that have been assigned to other users"
cant_act_unclaimed: "You must claim this topic before acting on flags."
topic_search_placeholder: "Search topics by title or post content"
sidebar_name_filter_placeholder: "Name/Username"
assigned: "Assigned"
group_no_assignments_title: "No assignments"
group_no_assignments_body: "There are currently no active assignments for this group."
group_everyone: "Everyone"
assigned_to: "Assigned to"
assigned_topic_to: "Assigned topic to <a href='%{path}'>%{username}</a>"
assign_post_to: "Assigned #%{post_number} to %{username}"
# assign_post_to_multiple used in list form, example: "Assigned topic to username0, [#2 to username1], [#10 to username2]"
assign_post_to_multiple: "#%{post_number} to %{username}"
unassign:
title: "Unassign"
title_w_ellipsis: "Unassign..."
help: "Unassign %{username} from Topic"
assign:
title: "Assign"
help: "Assign Topic to User"
assign_post:
title: "Assign Post"
unassign_post:
title: "Unassign from Post"
help: "Unassign %{username} from Post"
reassign:
title: "Edit"
title_w_ellipsis: "Edit assignment..."
to_self: "Reassign to me"
to_self_help: "Reassign Topic to me"
help: "Edit assignment details"
reassign_modal:
title: "Reassign Topic"
topic_level_menu:
edit_assignments: "Edit assignments..."
reassign_topic_to_me: "Reassign topic to me"
unassign_with_ellipsis: "Unassign..."
unassign_from_post: "Unassign @%{assignee} from #%{post_number}"
unassign_from_post_help: "Unassign @%{assignee} from post #%{post_number}"
unassign_from_topic: "Unassign @%{username} from topic"
assign_modal:
title: "Assign Topic"
reassign_title: "Reassign Topic"
assign: "Assign"
assignee_label: Assignee
assignment_label: Assignment
choose_assignee: Choose a user to assign.
edit_assignments_title: "Edit Assignments"
note_label: Note
optional_label: "(optional)"
status_label: Status
suggestions: suggestions
assign_post_modal:
title: "Assign Post"
claim:
title: "claim"
help: "Assign topic to yourself"
assign_mailer:
never: "Never"
different_users: "Only if assigner and assignee are different users"
always: "Always"
reminders_frequency:
description: "Frequency for receiving assigned topics reminders"
never: "Never"
daily: "Daily"
weekly: "Weekly"
monthly: "Monthly"
quarterly: "Quarterly"
admin:
groups:
manage:
interaction:
assign: "Assign"
assignable_levels:
title: "Who can assign this group"
user:
notification_level_when_assigned:
label: "When assigned"
watch_topic: "Watch topic"
track_topic: "Track topic"
do_nothing: "Do nothing"
messages:
assigned_title: "Assigned (%{count})"
assigned: "Assigned"
no_assignments_title: "You dont have any assignments yet"
no_assignments_body: >
Your assigned topics and messages will be listed here. You will also receive a periodic reminder notification of your assignments, which you can adjust in your <a href='%{preferencesUrl}'>user preferences</a>.
<br><br>
To assign a topic or message to yourself or to someone else, look for the %{icon} assign button at the bottom.
dismiss_assigned_tooltip: "Mark all unread assign notifications as read"
assigned_to_group:
post: "post assigned to %{group_name}"
topic: "topic assigned to %{group_name}"
assigned_to_you:
post: "post assigned to you"
topic: "topic assigned to you"
assignment_description:
post: "%{topic_title} (#%{post_number})"
topic: "%{topic_title}"
admin:
web_hooks:
assign_event:
group_name: "Assign Events"
assigned: "When a user assigns a topic"
unassigned: "When a user unassigns a topic"
search:
advanced:
in:
assigned: "are assigned"
unassigned: "are unassigned"
assigned:
label: "Assigned to"
topics:
bulk:
unassign: "Unassign topics"
assign: "Assign topics"
assign_description: "Assign the selected topics to the following user:"
unassign_description: "Do you want to unassign the selected topics?"
confirm_assign_topics:
one: "Assign %{count} topic"
other: "Assign %{count} topics"
confirm_unassign_topics:
one: "Unassign %{count} topic"
other: "Unassign %{count} topics"
discourse_automation:
scriptables:
random_assign:
fields:
post_template:
label: Post template
description: If filled, a post with this template will be created and a user assigned to it instead of the topic.
assignees_group:
label: Assignees Group
minimum_time_between_assignments:
label: Minimum hours between assignments
min_recently_assigned_days:
label: Min recently assigned days
description: Defaults to 14 days.
skip_new_users_for_days:
label: Skip new users for days
description: Defaults to 0 days (users can be assigned immediately after signing up).
max_recently_assigned_days:
label: Max recently assigned days
description: First attempt to exclude users assigned in the last `n` days. If no user left, fallbacks to `min_recently_assigned_days`. Defaults to 180 days.
assigned_topic:
label: Assigned Topic ID
in_working_hours:
label: Users in working hours
notification_reason:
user: "You will see a count of new replies because this topic was assigned to you."
notifications:
assigned: "<span>%{username}</span> %{description}"
popup:
assigned: "%{username} assigned you"
titles:
assigned: "Assigned"
dismiss_confirmation:
body:
assigns:
one: "Are you sure? You have %{count} unread assign notification."
other: "Are you sure? You have %{count} unread assign notifications."
user_menu:
view_all_assigned: "view all assigned"
tabs:
assign_list: "Assign list"
assign_list_with_unread:
one: "Assign list - %{count} unread assignment"
other: "Assign list - %{count} unread assignments"
edit_assignments_modal:
title: "Edit assignments"
topic: "Topic"
post: "Post"
discourse_workflows:
node_unavailable:
requires_assign: "Requires the Assign plugin to be enabled"
nodes:
"action:assign_topic": "Assign topic"
node_descriptions:
"action:assign_topic": "Assign or unassign a topic"
assign_topic:
operation: "Operation"
operations:
assign: "Assign"
unassign: "Unassign"
topic_id: "Topic ID"
assignee: "Assignee"
replace_existing: "Replace existing assignment"