mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 09:46:36 +00:00
Make automation editor card headers translateable (actions) (#17027)
This commit is contained in:
parent
a477120f13
commit
7dbb419c30
27
src/common/string/format-list.ts
Normal file
27
src/common/string/format-list.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import memoizeOne from "memoize-one";
|
||||
import "../../resources/intl-polyfill";
|
||||
import { FrontendLocaleData } from "../../data/translation";
|
||||
|
||||
export const formatListWithAnds = (
|
||||
locale: FrontendLocaleData,
|
||||
list: string[]
|
||||
) => formatConjunctionList(locale).format(list);
|
||||
|
||||
export const formatListWithOrs = (locale: FrontendLocaleData, list: string[]) =>
|
||||
formatDisjunctionList(locale).format(list);
|
||||
|
||||
const formatConjunctionList = memoizeOne(
|
||||
(locale: FrontendLocaleData) =>
|
||||
new Intl.ListFormat(locale.language, {
|
||||
style: "long",
|
||||
type: "conjunction",
|
||||
})
|
||||
);
|
||||
|
||||
const formatDisjunctionList = memoizeOne(
|
||||
(locale: FrontendLocaleData) =>
|
||||
new Intl.ListFormat(locale.language, {
|
||||
style: "long",
|
||||
type: "disjunction",
|
||||
})
|
||||
);
|
@ -31,6 +31,10 @@ import {
|
||||
VariablesAction,
|
||||
WaitForTriggerAction,
|
||||
} from "./script";
|
||||
import { formatListWithAnds } from "../common/string/format-list";
|
||||
|
||||
const actionTranslationBaseKey =
|
||||
"ui.panel.config.automation.editor.actions.type";
|
||||
|
||||
export const describeAction = <T extends ActionType>(
|
||||
hass: HomeAssistant,
|
||||
@ -75,25 +79,8 @@ const tryDescribeAction = <T extends ActionType>(
|
||||
if (actionType === "service") {
|
||||
const config = action as ActionTypes["service"];
|
||||
|
||||
let base: string | undefined;
|
||||
|
||||
if (
|
||||
config.service_template ||
|
||||
(config.service && isTemplate(config.service))
|
||||
) {
|
||||
base = "Call a service based on a template";
|
||||
} else if (config.service) {
|
||||
const [domain, serviceName] = config.service.split(".", 2);
|
||||
const service = hass.services[domain][serviceName];
|
||||
base = service
|
||||
? `${domainToName(hass.localize, domain)}: ${service.name}`
|
||||
: `Call service: ${config.service}`;
|
||||
} else {
|
||||
return "Call a service";
|
||||
}
|
||||
const targets: string[] = [];
|
||||
if (config.target) {
|
||||
const targets: string[] = [];
|
||||
|
||||
for (const [key, label] of Object.entries({
|
||||
area_id: "areas",
|
||||
device_id: "devices",
|
||||
@ -108,7 +95,12 @@ const tryDescribeAction = <T extends ActionType>(
|
||||
|
||||
for (const targetThing of keyConf) {
|
||||
if (isTemplate(targetThing)) {
|
||||
targets.push(`templated ${label}`);
|
||||
targets.push(
|
||||
hass.localize(
|
||||
`${actionTranslationBaseKey}.service.description.target_template`,
|
||||
{ name: label }
|
||||
)
|
||||
);
|
||||
break;
|
||||
} else if (key === "entity_id") {
|
||||
if (targetThing.includes(".")) {
|
||||
@ -125,7 +117,11 @@ const tryDescribeAction = <T extends ActionType>(
|
||||
computeEntityRegistryName(hass, entityReg) || targetThing
|
||||
);
|
||||
} else {
|
||||
targets.push("unknown entity");
|
||||
targets.push(
|
||||
hass.localize(
|
||||
`${actionTranslationBaseKey}.service.description.target_unknown_entity`
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if (key === "device_id") {
|
||||
@ -133,46 +129,105 @@ const tryDescribeAction = <T extends ActionType>(
|
||||
if (device) {
|
||||
targets.push(computeDeviceName(device, hass));
|
||||
} else {
|
||||
targets.push("unknown device");
|
||||
targets.push(
|
||||
hass.localize(
|
||||
`${actionTranslationBaseKey}.service.description.target_unknown_device`
|
||||
)
|
||||
);
|
||||
}
|
||||
} else if (key === "area_id") {
|
||||
const area = hass.areas[targetThing];
|
||||
if (area?.name) {
|
||||
targets.push(area.name);
|
||||
} else {
|
||||
targets.push("unknown area");
|
||||
targets.push(
|
||||
hass.localize(
|
||||
`${actionTranslationBaseKey}.service.description.target_unknown_area`
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
targets.push(targetThing);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (targets.length > 0) {
|
||||
base += ` ${targets.join(", ")}`;
|
||||
}
|
||||
}
|
||||
|
||||
return base;
|
||||
if (
|
||||
config.service_template ||
|
||||
(config.service && isTemplate(config.service))
|
||||
) {
|
||||
return hass.localize(
|
||||
`${actionTranslationBaseKey}.service.description.service_based_on_template`,
|
||||
{ targets: formatListWithAnds(hass.locale, targets) }
|
||||
);
|
||||
}
|
||||
|
||||
if (config.service) {
|
||||
const [domain, serviceName] = config.service.split(".", 2);
|
||||
const service = hass.services[domain][serviceName];
|
||||
return hass.localize(
|
||||
`${actionTranslationBaseKey}.service.description.service_based_on_name`,
|
||||
{
|
||||
name: service
|
||||
? `${domainToName(hass.localize, domain)}: ${service.name}`
|
||||
: config.service,
|
||||
targets: formatListWithAnds(hass.locale, targets),
|
||||
}
|
||||
);
|
||||
}
|
||||
return hass.localize(
|
||||
`${actionTranslationBaseKey}.service.description.service`
|
||||
);
|
||||
}
|
||||
|
||||
if (actionType === "delay") {
|
||||
const config = action as DelayAction;
|
||||
|
||||
let duration: string;
|
||||
|
||||
if (typeof config.delay === "number") {
|
||||
duration = `for ${secondsToDuration(config.delay)!}`;
|
||||
duration = hass.localize(
|
||||
`${actionTranslationBaseKey}.delay.description.duration_string`,
|
||||
{
|
||||
duration: secondsToDuration(config.delay)!,
|
||||
}
|
||||
);
|
||||
} else if (typeof config.delay === "string") {
|
||||
duration = isTemplate(config.delay)
|
||||
? "based on a template"
|
||||
: `for ${config.delay || "a duration"}`;
|
||||
? hass.localize(
|
||||
`${actionTranslationBaseKey}.delay.description.duration_template`
|
||||
)
|
||||
: hass.localize(
|
||||
`${actionTranslationBaseKey}.delay.description.duration_string`,
|
||||
{
|
||||
duration:
|
||||
config.delay ||
|
||||
hass.localize(
|
||||
`${actionTranslationBaseKey}.delay.description.duration_unknown`
|
||||
),
|
||||
}
|
||||
);
|
||||
} else if (config.delay) {
|
||||
duration = `for ${formatDuration(config.delay)}`;
|
||||
duration = hass.localize(
|
||||
`${actionTranslationBaseKey}.delay.description.duration_string`,
|
||||
{
|
||||
duration: formatDuration(config.delay),
|
||||
}
|
||||
);
|
||||
} else {
|
||||
duration = "for a duration";
|
||||
duration = hass.localize(
|
||||
`${actionTranslationBaseKey}.delay.description.duration_string`,
|
||||
{
|
||||
duration: hass.localize(
|
||||
`${actionTranslationBaseKey}.delay.description.duration_unknown`
|
||||
),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return `Delay ${duration}`;
|
||||
return hass.localize(`${actionTranslationBaseKey}.delay.description.full`, {
|
||||
duration: duration,
|
||||
});
|
||||
}
|
||||
|
||||
if (actionType === "activate_scene") {
|
||||
@ -184,77 +239,139 @@ const tryDescribeAction = <T extends ActionType>(
|
||||
entityId = config.target?.entity_id || config.entity_id;
|
||||
}
|
||||
if (!entityId) {
|
||||
return "Activate a scene";
|
||||
return hass.localize(
|
||||
`${actionTranslationBaseKey}.activate_scene.description.activate_scene`
|
||||
);
|
||||
}
|
||||
const sceneStateObj = entityId ? hass.states[entityId] : undefined;
|
||||
return `Activate scene ${
|
||||
sceneStateObj ? computeStateName(sceneStateObj) : entityId
|
||||
}`;
|
||||
return hass.localize(
|
||||
`${actionTranslationBaseKey}.activate_scene.description.activate_scene_with_name`,
|
||||
{ name: sceneStateObj ? computeStateName(sceneStateObj) : entityId }
|
||||
);
|
||||
}
|
||||
|
||||
if (actionType === "play_media") {
|
||||
const config = action as PlayMediaAction;
|
||||
const entityId = config.target?.entity_id || config.entity_id;
|
||||
const mediaStateObj = entityId ? hass.states[entityId] : undefined;
|
||||
return `Play ${
|
||||
config.metadata.title || config.data.media_content_id || "media"
|
||||
} on ${
|
||||
mediaStateObj
|
||||
? computeStateName(mediaStateObj)
|
||||
: entityId || "a media player"
|
||||
}`;
|
||||
return hass.localize(
|
||||
`${actionTranslationBaseKey}.play_media.description.full`,
|
||||
{
|
||||
hasMedia: config.metadata.title || config.data.media_content_id,
|
||||
media: config.metadata.title || config.data.media_content_id,
|
||||
hasMediaPlayer: mediaStateObj ? true : entityId !== undefined,
|
||||
mediaPlayer: mediaStateObj ? computeStateName(mediaStateObj) : entityId,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (actionType === "wait_for_trigger") {
|
||||
const config = action as WaitForTriggerAction;
|
||||
const triggers = ensureArray(config.wait_for_trigger);
|
||||
if (!triggers || triggers.length === 0) {
|
||||
return "Wait for a trigger";
|
||||
return hass.localize(
|
||||
`${actionTranslationBaseKey}.wait_for_trigger.description.wait_for_a_trigger`
|
||||
);
|
||||
}
|
||||
return `Wait for ${triggers
|
||||
.map((trigger) => describeTrigger(trigger, hass, entityRegistry))
|
||||
.join(", ")}`;
|
||||
const triggerNames = triggers.map((trigger) =>
|
||||
describeTrigger(trigger, hass, entityRegistry)
|
||||
);
|
||||
return hass.localize(
|
||||
`${actionTranslationBaseKey}.wait_for_trigger.description.wait_for_triggers_with_name`,
|
||||
{ triggers: formatListWithAnds(hass.locale, triggerNames) }
|
||||
);
|
||||
}
|
||||
|
||||
if (actionType === "variables") {
|
||||
const config = action as VariablesAction;
|
||||
return `Define variables ${Object.keys(config.variables).join(", ")}`;
|
||||
return hass.localize(
|
||||
`${actionTranslationBaseKey}.variables.description.full`,
|
||||
{
|
||||
names: formatListWithAnds(hass.locale, Object.keys(config.variables)),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (actionType === "fire_event") {
|
||||
const config = action as EventAction;
|
||||
if (isTemplate(config.event)) {
|
||||
return "Fire event based on a template";
|
||||
return hass.localize(
|
||||
`${actionTranslationBaseKey}.event.description.full`,
|
||||
{
|
||||
name: hass.localize(
|
||||
`${actionTranslationBaseKey}.event.description.template`
|
||||
),
|
||||
}
|
||||
);
|
||||
}
|
||||
return `Fire event ${config.event}`;
|
||||
return hass.localize(`${actionTranslationBaseKey}.event.description.full`, {
|
||||
name: config.event,
|
||||
});
|
||||
}
|
||||
|
||||
if (actionType === "wait_template") {
|
||||
return "Wait for a template to render true";
|
||||
}
|
||||
|
||||
if (actionType === "check_condition") {
|
||||
return describeCondition(action as Condition, hass, entityRegistry);
|
||||
return hass.localize(
|
||||
`${actionTranslationBaseKey}.wait_template.description.full`
|
||||
);
|
||||
}
|
||||
|
||||
if (actionType === "stop") {
|
||||
const config = action as StopAction;
|
||||
return `Stop${config.stop ? ` because: ${config.stop}` : ""}`;
|
||||
return hass.localize(`${actionTranslationBaseKey}.stop.description.full`, {
|
||||
hasReason: config.stop !== undefined,
|
||||
reason: config.stop,
|
||||
});
|
||||
}
|
||||
|
||||
if (actionType === "if") {
|
||||
const config = action as IfAction;
|
||||
return `Perform an action if: ${
|
||||
!config.if
|
||||
? ""
|
||||
: typeof config.if === "string"
|
||||
? config.if
|
||||
: ensureArray(config.if).length > 1
|
||||
? `${ensureArray(config.if).length} conditions`
|
||||
: ensureArray(config.if).length
|
||||
? describeCondition(ensureArray(config.if)[0], hass, entityRegistry)
|
||||
: ""
|
||||
}${config.else ? " (or else!)" : ""}`;
|
||||
|
||||
let ifConditions: string[] = [];
|
||||
if (Array.isArray(config.if)) {
|
||||
const conditions = ensureArray(config.if);
|
||||
conditions.forEach((condition) => {
|
||||
ifConditions.push(describeCondition(condition, hass, entityRegistry));
|
||||
});
|
||||
} else {
|
||||
ifConditions = [config.if];
|
||||
}
|
||||
|
||||
let elseActions: string[] = [];
|
||||
if (config.else) {
|
||||
if (Array.isArray(config.else)) {
|
||||
const actions = ensureArray(config.else);
|
||||
actions.forEach((currentAction) => {
|
||||
elseActions.push(
|
||||
describeAction(hass, entityRegistry, currentAction, undefined)
|
||||
);
|
||||
});
|
||||
} else {
|
||||
elseActions = [
|
||||
describeAction(hass, entityRegistry, config.else, undefined),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
let thenActions: string[] = [];
|
||||
if (Array.isArray(config.then)) {
|
||||
const actions = ensureArray(config.then);
|
||||
actions.forEach((currentAction) => {
|
||||
thenActions.push(
|
||||
describeAction(hass, entityRegistry, currentAction, undefined)
|
||||
);
|
||||
});
|
||||
} else {
|
||||
thenActions = [
|
||||
describeAction(hass, entityRegistry, config.then, undefined),
|
||||
];
|
||||
}
|
||||
|
||||
return hass.localize(`${actionTranslationBaseKey}.if.description.full`, {
|
||||
hasElse: config.else !== undefined,
|
||||
action: formatListWithAnds(hass.locale, thenActions),
|
||||
conditions: formatListWithAnds(hass.locale, ifConditions),
|
||||
elseAction: formatListWithAnds(hass.locale, elseActions),
|
||||
});
|
||||
}
|
||||
|
||||
if (actionType === "choose") {
|
||||
@ -262,42 +379,64 @@ const tryDescribeAction = <T extends ActionType>(
|
||||
if (config.choose) {
|
||||
const numActions =
|
||||
ensureArray(config.choose).length + (config.default ? 1 : 0);
|
||||
return `Choose between ${numActions} action${
|
||||
numActions === 1 ? "" : "s"
|
||||
}`;
|
||||
return hass.localize(
|
||||
`${actionTranslationBaseKey}.choose.description.full`,
|
||||
{ number: numActions }
|
||||
);
|
||||
}
|
||||
return "Choose an action";
|
||||
return hass.localize(
|
||||
`${actionTranslationBaseKey}.choose.description.no_action`
|
||||
);
|
||||
}
|
||||
|
||||
if (actionType === "repeat") {
|
||||
const config = action as RepeatAction;
|
||||
|
||||
let base = "Repeat an action";
|
||||
let chosenAction = "";
|
||||
if ("count" in config.repeat) {
|
||||
const count = config.repeat.count;
|
||||
base += ` ${count} time${Number(count) === 1 ? "" : "s"}`;
|
||||
chosenAction = hass.localize(
|
||||
`${actionTranslationBaseKey}.repeat.description.count`,
|
||||
{ count: count }
|
||||
);
|
||||
} else if ("while" in config.repeat) {
|
||||
base += ` while ${ensureArray(config.repeat.while)
|
||||
.map((condition) => describeCondition(condition, hass, entityRegistry))
|
||||
.join(", ")} is true`;
|
||||
const conditions = ensureArray(config.repeat.while).map((condition) =>
|
||||
describeCondition(condition, hass, entityRegistry)
|
||||
);
|
||||
chosenAction = hass.localize(
|
||||
`${actionTranslationBaseKey}.repeat.description.while`,
|
||||
{ conditions: formatListWithAnds(hass.locale, conditions) }
|
||||
);
|
||||
} else if ("until" in config.repeat) {
|
||||
base += ` until ${ensureArray(config.repeat.until)
|
||||
.map((condition) => describeCondition(condition, hass, entityRegistry))
|
||||
.join(", ")} is true`;
|
||||
const conditions = ensureArray(config.repeat.until).map((condition) =>
|
||||
describeCondition(condition, hass, entityRegistry)
|
||||
);
|
||||
chosenAction = hass.localize(
|
||||
`${actionTranslationBaseKey}.repeat.description.until`,
|
||||
{ conditions: formatListWithAnds(hass.locale, conditions) }
|
||||
);
|
||||
} else if ("for_each" in config.repeat) {
|
||||
base += ` for every item: ${ensureArray(config.repeat.for_each)
|
||||
.map((item) => JSON.stringify(item))
|
||||
.join(", ")}`;
|
||||
const items = ensureArray(config.repeat.for_each).map((item) =>
|
||||
JSON.stringify(item)
|
||||
);
|
||||
chosenAction = hass.localize(
|
||||
`${actionTranslationBaseKey}.repeat.description.for_each`,
|
||||
{ items: formatListWithAnds(hass.locale, items) }
|
||||
);
|
||||
}
|
||||
return base;
|
||||
return hass.localize(
|
||||
`${actionTranslationBaseKey}.repeat.description.full`,
|
||||
{ chosenAction: chosenAction }
|
||||
);
|
||||
}
|
||||
|
||||
if (actionType === "check_condition") {
|
||||
return `Test ${describeCondition(
|
||||
action as Condition,
|
||||
hass,
|
||||
entityRegistry
|
||||
)}`;
|
||||
return hass.localize(
|
||||
`${actionTranslationBaseKey}.check_condition.description.full`,
|
||||
{
|
||||
condition: describeCondition(action as Condition, hass, entityRegistry),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (actionType === "device_action") {
|
||||
@ -313,7 +452,7 @@ const tryDescribeAction = <T extends ActionType>(
|
||||
if (localized) {
|
||||
return localized;
|
||||
}
|
||||
const stateObj = hass.states[config.entity_id as string];
|
||||
const stateObj = hass.states[config.entity_id];
|
||||
return `${config.type || "Perform action with"} ${
|
||||
stateObj ? computeStateName(stateObj) : config.entity_id
|
||||
}`;
|
||||
@ -322,7 +461,10 @@ const tryDescribeAction = <T extends ActionType>(
|
||||
if (actionType === "parallel") {
|
||||
const config = action as ParallelAction;
|
||||
const numActions = ensureArray(config.parallel).length;
|
||||
return `Run ${numActions} action${numActions === 1 ? "" : "s"} in parallel`;
|
||||
return hass.localize(
|
||||
`${actionTranslationBaseKey}.parallel.description.full`,
|
||||
{ number: numActions }
|
||||
);
|
||||
}
|
||||
|
||||
return actionType;
|
||||
|
@ -2573,25 +2573,50 @@
|
||||
"label": "Call service",
|
||||
"response_variable": "Response variable",
|
||||
"has_optional_response": "This service can return a response, if you want to use the response, enter the name of a variable the response will be saved in",
|
||||
"has_response": "This service returns a response, enter the name of a variable the response will be saved in"
|
||||
"has_response": "This service returns a response, enter the name of a variable the response will be saved in",
|
||||
"description": {
|
||||
"service_based_on_template": "Call a service based on a template on {targets}",
|
||||
"service_based_on_name": "Call a service ''{name}'' on {targets}",
|
||||
"service": "Call a service",
|
||||
"target_template": "templated {name}",
|
||||
"target_unknown_entity": "unknown entity",
|
||||
"target_unknown_device": "unknown device",
|
||||
"target_unknown_area": "unknown area"
|
||||
}
|
||||
},
|
||||
"play_media": {
|
||||
"label": "Play media"
|
||||
"label": "Play media",
|
||||
"description": {
|
||||
"full": "Play {hasMedia, select, \n true {{media}} \n other {media}\n } on {hasMediaPlayer, select, \n true {{mediaPlayer}} \n other {a media player}\n }"
|
||||
}
|
||||
},
|
||||
"delay": {
|
||||
"label": "Wait for time to pass (delay)",
|
||||
"delay": "Duration"
|
||||
"delay": "Duration",
|
||||
"description": {
|
||||
"full": "Delay {duration}",
|
||||
"duration_string": "for {string}",
|
||||
"duration_template": "based on a template",
|
||||
"duration_unknown": "a duration"
|
||||
}
|
||||
},
|
||||
"wait_template": {
|
||||
"label": "Wait for a template",
|
||||
"wait_template": "Wait Template",
|
||||
"timeout": "Timeout (optional)",
|
||||
"continue_timeout": "Continue on timeout"
|
||||
"continue_timeout": "Continue on timeout",
|
||||
"description": {
|
||||
"full": "Wait for a template to evaluate to true"
|
||||
}
|
||||
},
|
||||
"wait_for_trigger": {
|
||||
"label": "Wait for a trigger",
|
||||
"timeout": "[%key:ui::panel::config::automation::editor::actions::type::wait_template::timeout%]",
|
||||
"continue_timeout": "[%key:ui::panel::config::automation::editor::actions::type::wait_template::continue_timeout%]"
|
||||
"continue_timeout": "[%key:ui::panel::config::automation::editor::actions::type::wait_template::continue_timeout%]",
|
||||
"description": {
|
||||
"wait_for_a_trigger": "Wait for a trigger",
|
||||
"wait_for_triggers_with_name": "Wait for ''{triggers}''"
|
||||
}
|
||||
},
|
||||
"condition": {
|
||||
"label": "Condition"
|
||||
@ -2599,7 +2624,11 @@
|
||||
"event": {
|
||||
"label": "Event",
|
||||
"event": "[%key:ui::panel::config::automation::editor::triggers::type::event::label%]",
|
||||
"event_data": "[%key:ui::panel::config::automation::editor::triggers::type::event::event_data%]"
|
||||
"event_data": "[%key:ui::panel::config::automation::editor::triggers::type::event::event_data%]",
|
||||
"description": {
|
||||
"full": "Fire event {name}",
|
||||
"template": "based on a template"
|
||||
}
|
||||
},
|
||||
"device_id": {
|
||||
"label": "Device",
|
||||
@ -2618,7 +2647,11 @@
|
||||
},
|
||||
"activate_scene": {
|
||||
"label": "Scene",
|
||||
"scene": "Scene"
|
||||
"scene": "Scene",
|
||||
"description": {
|
||||
"activate_scene": "Activate a scene",
|
||||
"activate_scene_with_name": "Activate scene {name}"
|
||||
}
|
||||
},
|
||||
"repeat": {
|
||||
"label": "Repeat",
|
||||
@ -2636,7 +2669,14 @@
|
||||
"conditions": "Until conditions"
|
||||
}
|
||||
},
|
||||
"sequence": "Actions"
|
||||
"sequence": "Actions",
|
||||
"description": {
|
||||
"full": "Repeat an action {chosenAction}",
|
||||
"count": "{count} {count, plural,\n one {time}\n other {times}\n}",
|
||||
"while": "while ''{conditions}'' is true",
|
||||
"until": "until ''{conditions}'' is true",
|
||||
"for_each": "for every item: {items}"
|
||||
}
|
||||
},
|
||||
"choose": {
|
||||
"label": "Choose",
|
||||
@ -2646,26 +2686,47 @@
|
||||
"add_option": "Add option",
|
||||
"remove_option": "Remove option",
|
||||
"conditions": "Conditions",
|
||||
"sequence": "Actions"
|
||||
"sequence": "Actions",
|
||||
"description": {
|
||||
"full": "Choose between {number} {number, plural,\n one {action}\n other{actions}\n}",
|
||||
"no_action": "Choose an action"
|
||||
}
|
||||
},
|
||||
"if": {
|
||||
"label": "If-then",
|
||||
"if": "If",
|
||||
"then": "Then",
|
||||
"else": "Else",
|
||||
"add_else": "Add else"
|
||||
"add_else": "Add else",
|
||||
"description": {
|
||||
"full": "Perform ''{action}'' if ''{conditions}''{hasElse, select, \n true { otherwise ''{elseAction}''} \n other {}\n } "
|
||||
}
|
||||
},
|
||||
"stop": {
|
||||
"label": "Stop",
|
||||
"stop": "Reason for stopping",
|
||||
"response_variable": "The name of the variable to use as response",
|
||||
"error": "Stop because of an unexpected error"
|
||||
"error": "Stop because of an unexpected error",
|
||||
"description": {
|
||||
"full": "Stop {hasReason, select, \n true { because: {reason}} \n other {}\n }"
|
||||
}
|
||||
},
|
||||
"parallel": {
|
||||
"label": "Run in parallel"
|
||||
"label": "Run in parallel",
|
||||
"description": {
|
||||
"full": "Run {number} {number, plural,\n one {action}\n other {actions}\n} in parallel"
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"label": "Define variables"
|
||||
"label": "Define variables",
|
||||
"description": {
|
||||
"full": "Define variables {names}"
|
||||
}
|
||||
},
|
||||
"check_condition": {
|
||||
"description": {
|
||||
"full": "Test {condition}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2782,7 +2843,6 @@
|
||||
},
|
||||
"discover_blueprint_tip": "[%key:ui::panel::config::automation::dialog_new::discover_blueprint_tip%]"
|
||||
},
|
||||
|
||||
"editor": {
|
||||
"alias": "Name",
|
||||
"icon": "Icon",
|
||||
|
Loading…
x
Reference in New Issue
Block a user