poe-svelte-ui-lib 1.44.0 → 1.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Accordion/AccordionProps.svelte +1 -1
- package/dist/CommonSnippets.svelte +2 -2
- package/dist/Graph/Graph.svelte +12 -15
- package/dist/Graph/GraphProps.svelte +1 -1
- package/dist/Graph/README.md +1 -0
- package/dist/Input/InputProps.svelte +11 -3
- package/dist/Select/SelectProps.svelte +2 -2
- package/dist/Switch/SwitchProps.svelte +1 -1
- package/dist/Table/TableProps.svelte +5 -5
- package/dist/VideoViewer/VideoViewerProps.svelte +1 -1
- package/dist/Widget/WidgetProps.svelte +1 -1
- package/dist/WidgetDeviceInfo/README.md +5 -2
- package/dist/WidgetDeviceInfo/WidgetDeviceInfo.svelte +49 -3
- package/dist/WidgetDeviceInfo/WidgetDeviceInfoProps.svelte +9 -6
- package/dist/locales/translations.js +14 -33
- package/dist/types.d.ts +5 -0
- package/package.json +1 -1
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
label={{ name: $T("constructor.props.open") }}
|
|
90
90
|
value={component.properties.isOpen}
|
|
91
91
|
options={[{ id: crypto.randomUUID(), value: 0, class: "" }]}
|
|
92
|
-
onChange={(value) => updateProperty("isOpen", value, component, onPropertyChange)}
|
|
92
|
+
onChange={(value) => updateProperty("isOpen", value === 1, component, onPropertyChange)}
|
|
93
93
|
/>
|
|
94
94
|
{/snippet}
|
|
95
95
|
|
|
@@ -159,7 +159,7 @@
|
|
|
159
159
|
label={{ name: $T("constructor.props.disabled") }}
|
|
160
160
|
value={(component.properties as UI.IInputProps | UI.ISwitchProps | UI.ISliderProps | UI.IFileAttachProps)?.disabled ? 1 : 0}
|
|
161
161
|
options={[{ id: crypto.randomUUID(), value: 0, class: "" }]}
|
|
162
|
-
onChange={(value) => updateProperty("disabled", value, component, onPropertyChange)}
|
|
162
|
+
onChange={(value) => updateProperty("disabled", value === 1, component, onPropertyChange)}
|
|
163
163
|
/>
|
|
164
164
|
{/snippet}
|
|
165
165
|
|
|
@@ -181,7 +181,7 @@
|
|
|
181
181
|
label={{ name: $T("constructor.props.readonly") }}
|
|
182
182
|
value={Number((component.properties as UI.IInputProps | UI.IJoystickProps | UI.IWidgetProps).readonly)}
|
|
183
183
|
options={[{ id: crypto.randomUUID(), value: 0, class: "" }]}
|
|
184
|
-
onChange={(value) => updateProperty("readonly", value, component, onPropertyChange)}
|
|
184
|
+
onChange={(value) => updateProperty("readonly", value === 1, component, onPropertyChange)}
|
|
185
185
|
/>
|
|
186
186
|
{/snippet}
|
|
187
187
|
|
package/dist/Graph/Graph.svelte
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
</script>
|
|
16
16
|
|
|
17
17
|
<script lang="ts">
|
|
18
|
+
import { T } from "../locales/i18n"
|
|
18
19
|
import { onMount } from "svelte"
|
|
19
20
|
import Select from "../Select/Select.svelte"
|
|
20
21
|
import type { IGraphDataObject, IGraphProps } from "../types"
|
|
@@ -416,27 +417,23 @@
|
|
|
416
417
|
{#if !isHistoryMode}
|
|
417
418
|
<!-- Развертка по горизонтали -->
|
|
418
419
|
<Select
|
|
419
|
-
label={{ name: "
|
|
420
|
+
label={{ name: $T("ui.graph.refresh"), class: "" }}
|
|
420
421
|
options={REFRESH_OPTIONS}
|
|
421
422
|
value={REFRESH_OPTIONS.find((o) => o.value == selectedRefreshRate)}
|
|
422
423
|
onUpdate={(value) => (selectedRefreshRate = (value as IOption).value as number)}
|
|
423
424
|
/>
|
|
424
425
|
{/if}
|
|
425
426
|
|
|
426
|
-
<!-- Переменные и их значение -->
|
|
427
|
-
<div>
|
|
428
|
-
<h5 class="
|
|
429
|
-
<
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
</tr>
|
|
437
|
-
{/each}
|
|
438
|
-
</tbody>
|
|
439
|
-
</table>
|
|
427
|
+
<!-- Переменные и их значение: сетка, а не таблица — имя обрезается «…», значение не переносится -->
|
|
428
|
+
<div class="flex flex-col gap-1">
|
|
429
|
+
<h5 class="text-[12px] font-semibold text-(--muted-color)">{$T("ui.graph.values")}</h5>
|
|
430
|
+
<div class="grid grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-x-2 gap-y-1 text-[13px]">
|
|
431
|
+
{#each graphData as data, i (data.id)}
|
|
432
|
+
<span class="size-2.5 rounded-full" style="background-color: {data.color}"></span>
|
|
433
|
+
<span class="truncate font-semibold" title={data.name}>{data.name}</span>
|
|
434
|
+
<span class="text-right whitespace-nowrap tabular-nums">{currentValues[i]?.toFixed(2)}</span>
|
|
435
|
+
{/each}
|
|
436
|
+
</div>
|
|
440
437
|
</div>
|
|
441
438
|
</div>
|
|
442
439
|
</div>
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
label={{ name: $T("constructor.props.istest") }}
|
|
36
36
|
value={component.properties.isTest}
|
|
37
37
|
options={[{ id: crypto.randomUUID(), value: 0, class: "" }]}
|
|
38
|
-
onChange={(value) => updateProperty("isTest", value, component, onPropertyChange)}
|
|
38
|
+
onChange={(value) => updateProperty("isTest", value === 1, component, onPropertyChange)}
|
|
39
39
|
/>
|
|
40
40
|
{/snippet}
|
|
41
41
|
|
package/dist/Graph/README.md
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
## Особенности
|
|
20
20
|
|
|
21
21
|
- Для накопленных по периодам значений (энергия за час/сутки) лучше «Диаграмма по периодам»
|
|
22
|
+
- Справа от графика — развёртка и текущие значения серий: каждая серия в одну строку (цвет, имя, значение), длинное имя обрезается «…» с полным именем во всплывающей подсказке
|
|
22
23
|
|
|
23
24
|
### Адаптивность
|
|
24
25
|
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
import TextsEditor from "../TextsEditor.svelte"
|
|
3
3
|
import { getContext } from "svelte"
|
|
4
4
|
import { T } from "../locales/i18n"
|
|
5
|
+
import translations from "../locales/translations"
|
|
6
|
+
import { LANGUAGE_CODES } from "../locales/localize"
|
|
5
7
|
import type { IInputProps, UIComponent, IOption, IUIComponentHandler } from "../types"
|
|
6
8
|
import * as UI from ".."
|
|
7
9
|
import { optionsStore, findColorOption } from "../options"
|
|
@@ -34,6 +36,12 @@
|
|
|
34
36
|
)
|
|
35
37
|
|
|
36
38
|
/* Обновление свойства */
|
|
39
|
+
/* Подсказка битового режима «Максимальное число: N» сразу на всех языках — иначе записалась бы на языке интерфейса конструктора */
|
|
40
|
+
const maxNumInfo = (range: { start: number; end: number }) => {
|
|
41
|
+
const max = Math.pow(2, range.end - range.start + 1) - 1
|
|
42
|
+
return Object.fromEntries(LANGUAGE_CODES.map((lang, i) => [lang, `${translations["constructor.props.maxnum"][i]}: ${max}`]))
|
|
43
|
+
}
|
|
44
|
+
|
|
37
45
|
const updateProperty = (path: string, value: string | object | boolean | number | RegExp) => {
|
|
38
46
|
const newProperties = JSON.parse(JSON.stringify(component.properties))
|
|
39
47
|
if (path === "regExp") {
|
|
@@ -138,7 +146,7 @@
|
|
|
138
146
|
updateProperty("number.minNum", 0)
|
|
139
147
|
updateProperty("number.maxNum", Math.pow(2, component.properties.range.end - component.properties.range.start + 1) - 1)
|
|
140
148
|
updateProperty("number.step", 1)
|
|
141
|
-
updateProperty("help.info",
|
|
149
|
+
updateProperty("help.info", maxNumInfo(component.properties.range))
|
|
142
150
|
} else {
|
|
143
151
|
updateProperty("help.info", "")
|
|
144
152
|
}
|
|
@@ -247,7 +255,7 @@
|
|
|
247
255
|
updateProperty("number.minNum", 0)
|
|
248
256
|
updateProperty("number.maxNum", Math.pow(2, component.properties.range.end - component.properties.range.start + 1) - 1)
|
|
249
257
|
updateProperty("number.step", 1)
|
|
250
|
-
updateProperty("help.info",
|
|
258
|
+
updateProperty("help.info", maxNumInfo({ start: value[0] as number, end: value[1] as number }))
|
|
251
259
|
}
|
|
252
260
|
}}
|
|
253
261
|
/>
|
|
@@ -349,7 +357,7 @@
|
|
|
349
357
|
label={{ name: $T("constructor.props.disabled") }}
|
|
350
358
|
value={component.properties.disabled}
|
|
351
359
|
options={[{ id: crypto.randomUUID(), value: 0, class: "" }]}
|
|
352
|
-
onChange={(value) => updateProperty("disabled", value)}
|
|
360
|
+
onChange={(value) => updateProperty("disabled", value === 1)}
|
|
353
361
|
/>
|
|
354
362
|
{/snippet}
|
|
355
363
|
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
value={component.properties.bitMode}
|
|
132
132
|
options={[{ id: crypto.randomUUID(), value: 0, class: "" }]}
|
|
133
133
|
onChange={(value) => {
|
|
134
|
-
updateProperty("bitMode", value, component, onPropertyChange)
|
|
134
|
+
updateProperty("bitMode", value === 1, component, onPropertyChange)
|
|
135
135
|
const options = [...(component.properties?.options || [])]
|
|
136
136
|
const maxNumber = Math.pow(2, component.properties.range.end - component.properties.range.start + 1) - 1
|
|
137
137
|
options.forEach((option) => {
|
|
@@ -147,7 +147,7 @@
|
|
|
147
147
|
value={component.properties.multiSelect}
|
|
148
148
|
options={[{ id: crypto.randomUUID(), value: 0, class: "" }]}
|
|
149
149
|
onChange={(value) => {
|
|
150
|
-
updateProperty("multiSelect", value, component, onPropertyChange)
|
|
150
|
+
updateProperty("multiSelect", value === 1, component, onPropertyChange)
|
|
151
151
|
}}
|
|
152
152
|
/>
|
|
153
153
|
{/if}
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
value={component.properties.bitMode}
|
|
62
62
|
options={[{ id: crypto.randomUUID(), value: 0, class: "" }]}
|
|
63
63
|
onChange={(value) => {
|
|
64
|
-
updateProperty("bitMode", value, component, onPropertyChange)
|
|
64
|
+
updateProperty("bitMode", value === 1, component, onPropertyChange)
|
|
65
65
|
updateProperty("value", 0, component, onPropertyChange)
|
|
66
66
|
// if (!component.properties.bitMode) updateProperty("value", 0, component, onPropertyChange)
|
|
67
67
|
}}
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
label={{ name: $T("constructor.props.outline") }}
|
|
105
105
|
value={component.properties.outline}
|
|
106
106
|
options={[{ id: crypto.randomUUID(), value: 0, class: "" }]}
|
|
107
|
-
onChange={(value) => updateProperty("outline", value, component, onPropertyChange)}
|
|
107
|
+
onChange={(value) => updateProperty("outline", value === 1, component, onPropertyChange)}
|
|
108
108
|
/>
|
|
109
109
|
{/snippet}
|
|
110
110
|
|
|
@@ -493,9 +493,9 @@
|
|
|
493
493
|
value={component.properties.dataBuffer.stashData}
|
|
494
494
|
options={[{ id: crypto.randomUUID(), value: 0, class: "" }]}
|
|
495
495
|
onChange={(value) => {
|
|
496
|
-
updateProperty("dataBuffer.stashData", value, component, onPropertyChange)
|
|
496
|
+
updateProperty("dataBuffer.stashData", value === 1, component, onPropertyChange)
|
|
497
497
|
if (value == 0) {
|
|
498
|
-
updateProperty("dataBuffer.clearButton",
|
|
498
|
+
updateProperty("dataBuffer.clearButton", false, component, onPropertyChange)
|
|
499
499
|
updateProperty("dataBuffer.logger", 0, component, onPropertyChange)
|
|
500
500
|
}
|
|
501
501
|
}}
|
|
@@ -509,7 +509,7 @@
|
|
|
509
509
|
}}
|
|
510
510
|
value={component.properties.dataBuffer.clearButton}
|
|
511
511
|
options={[{ id: crypto.randomUUID(), value: 0, class: "", disabled: !component.properties.dataBuffer.stashData }]}
|
|
512
|
-
onChange={(value) => updateProperty("dataBuffer.clearButton", value, component, onPropertyChange)}
|
|
512
|
+
onChange={(value) => updateProperty("dataBuffer.clearButton", value === 1, component, onPropertyChange)}
|
|
513
513
|
/>
|
|
514
514
|
{/snippet}
|
|
515
515
|
|
|
@@ -518,7 +518,7 @@
|
|
|
518
518
|
label={{ name: $T("constructor.props.table.logger"), captionLeft: $T("constructor.props.info.bottom"), captionRight: $T("constructor.props.info.top") }}
|
|
519
519
|
value={component.properties.dataBuffer.logger}
|
|
520
520
|
options={[{ id: crypto.randomUUID(), value: 0, class: "", disabled: !component.properties.dataBuffer.stashData }]}
|
|
521
|
-
onChange={(value) => updateProperty("dataBuffer.logger", value, component, onPropertyChange)}
|
|
521
|
+
onChange={(value) => updateProperty("dataBuffer.logger", value === 1, component, onPropertyChange)}
|
|
522
522
|
/>
|
|
523
523
|
{/snippet}
|
|
524
524
|
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
label={{ name: $T("constructor.props.showSelect") }}
|
|
25
25
|
value={component.properties?.showSelect ? 1 : 0}
|
|
26
26
|
options={[{ id: crypto.randomUUID(), value: 0, class: "" }]}
|
|
27
|
-
onChange={(value) => updateProperty("showSelect", value, component, onPropertyChange)}
|
|
27
|
+
onChange={(value) => updateProperty("showSelect", value === 1, component, onPropertyChange)}
|
|
28
28
|
/>
|
|
29
29
|
{/snippet}
|
|
30
30
|
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
label={{ name: $T("constructor.props.widget.mode") }}
|
|
63
63
|
value={component.properties.icons.cycling}
|
|
64
64
|
options={[{ id: crypto.randomUUID(), value: 0, class: "" }]}
|
|
65
|
-
onChange={(value) => updateProperty("icons.cycling", value, component, onPropertyChange)}
|
|
65
|
+
onChange={(value) => updateProperty("icons.cycling", value === 1, component, onPropertyChange)}
|
|
66
66
|
/>
|
|
67
67
|
{/snippet}
|
|
68
68
|
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
- Поля группы `CFG` (меняется префиксом в настройках), привязывать переменные не нужно
|
|
12
12
|
- «Сохранить» отправляет изменённые поля одним пакетом `SET ModCfg`
|
|
13
13
|
- 🔌 «Перезагрузить» — команда `SET Restart`
|
|
14
|
+
- ♻️ «Сброс настроек» — после подтверждения команда `SET RstNVS`: прошивка очищает NVS и перезагружается, все настройки возвращаются к заводским
|
|
14
15
|
|
|
15
16
|
## Ключи
|
|
16
17
|
|
|
@@ -27,7 +28,7 @@
|
|
|
27
28
|
|
|
28
29
|
## Особенности
|
|
29
30
|
|
|
30
|
-
Смарт-виджет информации об устройстве. Как и `WidgetWiFi`, не привязывается к одной произвольной переменной устройства — работает с фиксированным набором полей, соответствующих реальной прошивочной конвенции (`main_config.c`, группа `CFG`, ProdFactory-ESP): `DevSN`, `DevID`, `DevFW`, `RunCnt`, `StaIP`, `ApIP` — только чтение; `DevName`, `HostName`, `WebUser`, `WebPsw` — редактируются локально и сохраняются одним пакетом по кнопке "Сохранить". Отдельная кнопка "Перезагрузить" рядом с заголовком вызывает `onRestart` немедленно (не входит в пакет сохранения полей). Реальное имя поля устройства для каждого ключа можно переопределить через `keys` (по умолчанию совпадает с именем ключа). Компонент ничего не знает про DeviceStore/WebSocket — только `value`/`onSave`/`onRestart`.
|
|
31
|
+
Смарт-виджет информации об устройстве. Как и `WidgetWiFi`, не привязывается к одной произвольной переменной устройства — работает с фиксированным набором полей, соответствующих реальной прошивочной конвенции (`main_config.c`, группа `CFG`, ProdFactory-ESP): `DevSN`, `DevID`, `DevFW`, `RunCnt`, `StaIP`, `ApIP` — только чтение; `DevName`, `HostName`, `WebUser`, `WebPsw` — редактируются локально и сохраняются одним пакетом по кнопке "Сохранить". Отдельная кнопка "Перезагрузить" рядом с заголовком вызывает `onRestart` немедленно (не входит в пакет сохранения полей). Реальное имя поля устройства для каждого ключа можно переопределить через `keys` (по умолчанию совпадает с именем ключа). Внизу — «Сброс настроек» (`onFactoryReset`): все настройки к заводским, только после подтверждения в окне поверх виджета; без колбэка кнопка не показывается. Компонент ничего не знает про DeviceStore/WebSocket — только `value`/`onSave`/`onRestart`/`onFactoryReset`.
|
|
31
32
|
|
|
32
33
|
- Серийный номер устройства обычно длинный (например `00.00.000-00_0000AC670000B22B00007428:DBC5`) — в разметке занимает отдельную строку, чтобы не обрезаться в узкой сетке.
|
|
33
34
|
- `WebPsw` в реальном устройстве исторически передаётся обычным текстом; в виджете сделан `type="password"` для консистентности с остальным обликом конструктора.
|
|
@@ -44,6 +45,8 @@
|
|
|
44
45
|
| `persistKey` | `string` | `undefined` | Ключ для сохранения состояния `collapsed` в `localStorage` — при заданном ключе состояние сворачивания переживает перезагрузку страницы |
|
|
45
46
|
| `onSave` | `(info: IWidgetDeviceInfoConfig) => void` | `undefined` | Срабатывает при нажатии "Сохранить" — редактируемые поля одним пакетом |
|
|
46
47
|
| `onRestart` | `() => void` | `undefined` | Срабатывает при нажатии "Перезагрузить" |
|
|
48
|
+
| `onFactoryReset` | `() => void` | `undefined` | Срабатывает после подтверждения «Сброс настроек»; без колбэка кнопки нет |
|
|
49
|
+
| `resetCommand` | `{ header?: string; argument?: string }` | `SET` / `RstNVS` | Команда сброса настроек — для приложения, сам компонент её не отправляет |
|
|
47
50
|
|
|
48
51
|
### IWidgetDeviceInfoConfig
|
|
49
52
|
|
|
@@ -98,7 +101,7 @@
|
|
|
98
101
|
| `component` | `UIComponent & { properties: Partial<IWidgetDeviceInfoProps> }` | Объект компонента с его свойствами |
|
|
99
102
|
| `onPropertyChange` | `(updates: Partial<{ properties?: string \| object; name?: string; access?: string }>) => void` | Коллбэк для обновления свойств компонента |
|
|
100
103
|
|
|
101
|
-
Панель содержит заголовок, мастер-цвет (через общий `WidgetAccentPicker.svelte`), префикс прошивочной группы (ID), переопределение имени поля устройства для каждого ключа `IWidgetDeviceInfoConfig` (по умолчанию совпадает с именем ключа)
|
|
104
|
+
Панель содержит заголовок, мастер-цвет (через общий `WidgetAccentPicker.svelte`), префикс прошивочной группы (ID), переопределение имени поля устройства для каждого ключа `IWidgetDeviceInfoConfig` (по умолчанию совпадает с именем ключа) команду перезагрузки (Header/Argument, по умолчанию `SET`/`Restart`) и команду сброса настроек (по умолчанию `SET`/`RstNVS`).
|
|
102
105
|
|
|
103
106
|
### Что настраивается
|
|
104
107
|
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
Фиксированный набор полей (см. IWidgetDeviceInfoConfig в types.ts), соответствует реальной
|
|
3
3
|
прошивочной конвенции (main_config.c, группа "CFG", ProdFactory-ESP):
|
|
4
4
|
DevSN/DevID/DevFW/RunCnt — только чтение; DevName/HostName/WebUser/WebPsw — сохраняются
|
|
5
|
-
одним
|
|
5
|
+
одним пакетом; «Сброс настроек» — с подтверждением, все настройки к заводским. Ничего не знает про DeviceStore/WebSocket —
|
|
6
|
+
value/onSave/onRestart/onFactoryReset. -->
|
|
6
7
|
<script lang="ts">
|
|
7
8
|
import { T } from "../locales/i18n"
|
|
8
9
|
import { untrack } from "svelte"
|
|
9
|
-
import { slide } from "svelte/transition"
|
|
10
|
+
import { fade, scale, slide } from "svelte/transition"
|
|
10
11
|
import { twMerge } from "tailwind-merge"
|
|
11
12
|
import * as UI from ".."
|
|
12
13
|
import type { IWidgetDeviceInfoConfig, IWidgetDeviceInfoProps } from "../types"
|
|
@@ -25,8 +26,15 @@
|
|
|
25
26
|
persistKey,
|
|
26
27
|
onSave = () => {},
|
|
27
28
|
onRestart = () => {},
|
|
29
|
+
onFactoryReset,
|
|
28
30
|
}: IWidgetDeviceInfoProps = $props()
|
|
29
31
|
|
|
32
|
+
let confirmReset = $state(false)
|
|
33
|
+
const factoryReset = () => {
|
|
34
|
+
confirmReset = false
|
|
35
|
+
onFactoryReset?.()
|
|
36
|
+
}
|
|
37
|
+
|
|
30
38
|
let accentStyle = $derived(widgetAccentStyle(componentClass ?? ""))
|
|
31
39
|
|
|
32
40
|
let info: IWidgetDeviceInfoConfig = $state(
|
|
@@ -80,7 +88,10 @@
|
|
|
80
88
|
}
|
|
81
89
|
</script>
|
|
82
90
|
|
|
83
|
-
<div
|
|
91
|
+
<div
|
|
92
|
+
class={twMerge("relative flex w-full flex-col gap-4 rounded-2xl border border-(--hairline-color) bg-(--container-color) p-4", wrapperClass)}
|
|
93
|
+
style={accentStyle}
|
|
94
|
+
>
|
|
84
95
|
<!-- Заголовок -->
|
|
85
96
|
<WidgetHeader icon={CpuIcon} label={label?.name || $T("widget.info.title")} bind:collapsed>
|
|
86
97
|
{#snippet right()}
|
|
@@ -128,6 +139,41 @@
|
|
|
128
139
|
{/if}
|
|
129
140
|
<UI.Button wrapperClass="w-40" componentClass="bg-accent" content={{ name: $T("widget.common.save") }} disabled={!isDirty} onClick={save} />
|
|
130
141
|
</div>
|
|
142
|
+
|
|
143
|
+
<!-- Сброс всех настроек к заводским — отдельно от сохранения, только с подтверждением -->
|
|
144
|
+
{#if onFactoryReset}
|
|
145
|
+
<div class="flex items-center justify-between gap-3 border-t border-(--hairline-color) pt-3">
|
|
146
|
+
<span class="text-[12px] text-(--muted-color)">{$T("widget.info.factory_reset_hint")}</span>
|
|
147
|
+
<UI.Button
|
|
148
|
+
wrapperClass="w-auto shrink-0"
|
|
149
|
+
componentClass="bg-red px-3"
|
|
150
|
+
content={{ name: $T("widget.info.factory_reset") }}
|
|
151
|
+
onClick={() => (confirmReset = true)}
|
|
152
|
+
/>
|
|
153
|
+
</div>
|
|
154
|
+
{/if}
|
|
155
|
+
</div>
|
|
156
|
+
{/if}
|
|
157
|
+
|
|
158
|
+
{#if confirmReset}
|
|
159
|
+
<!-- Подтверждение локально к виджету, как удаление файла у WidgetFileSystem -->
|
|
160
|
+
<div class="absolute inset-0 z-10 flex items-center justify-center rounded-2xl bg-black/40 backdrop-blur-[2px]" transition:fade={{ duration: 150 }}>
|
|
161
|
+
<div
|
|
162
|
+
class="flex w-full max-w-96 flex-col gap-3 rounded-[16px] border border-(--hairline-color) bg-(--back-color) p-4 shadow-(--elevation-3)"
|
|
163
|
+
transition:scale={{ duration: 150, start: 0.96 }}
|
|
164
|
+
>
|
|
165
|
+
<h4 class="text-[15px] font-semibold">{$T("widget.info.factory_reset_title")}</h4>
|
|
166
|
+
<p class="text-[13px] text-(--muted-color)">{$T("widget.info.factory_reset_text")}</p>
|
|
167
|
+
<div class="flex gap-2">
|
|
168
|
+
<UI.Button
|
|
169
|
+
wrapperClass="flex-1"
|
|
170
|
+
componentClass="bg-transparent"
|
|
171
|
+
content={{ name: $T("widget.common.cancel") }}
|
|
172
|
+
onClick={() => (confirmReset = false)}
|
|
173
|
+
/>
|
|
174
|
+
<UI.Button wrapperClass="flex-1" componentClass="bg-red" content={{ name: $T("widget.info.factory_reset") }} onClick={factoryReset} />
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
131
177
|
</div>
|
|
132
178
|
{/if}
|
|
133
179
|
</div>
|
|
@@ -29,18 +29,18 @@
|
|
|
29
29
|
{/each}
|
|
30
30
|
{/snippet}
|
|
31
31
|
|
|
32
|
-
{#snippet
|
|
32
|
+
{#snippet WidgetCommand(path: "restartCommand" | "resetCommand", defaultArgument: string)}
|
|
33
33
|
<UI.Select
|
|
34
34
|
label={{ name: $T("widget.common.packet_header") }}
|
|
35
35
|
type="buttons"
|
|
36
36
|
options={$optionsStore.HEADER_OPTIONS}
|
|
37
|
-
value={$optionsStore.HEADER_OPTIONS.find((o) => o.value === (component.properties
|
|
38
|
-
onUpdate={(option) => updateProperty(
|
|
37
|
+
value={$optionsStore.HEADER_OPTIONS.find((o) => o.value === (component.properties[path]?.header || "SET"))}
|
|
38
|
+
onUpdate={(option) => updateProperty(`${path}.header`, (option as IOption<string>).value as string, component, onPropertyChange)}
|
|
39
39
|
/>
|
|
40
40
|
<UI.Input
|
|
41
41
|
label={{ name: $T("widget.common.argument") }}
|
|
42
|
-
value={component.properties
|
|
43
|
-
onUpdate={(value) => updateProperty(
|
|
42
|
+
value={component.properties[path]?.argument ?? defaultArgument}
|
|
43
|
+
onUpdate={(value) => updateProperty(`${path}.argument`, value as string, component, onPropertyChange)}
|
|
44
44
|
/>
|
|
45
45
|
{/snippet}
|
|
46
46
|
|
|
@@ -61,6 +61,9 @@
|
|
|
61
61
|
{@render WidgetKeys()}
|
|
62
62
|
</PropsGroup>
|
|
63
63
|
<PropsGroup label={$T("widget.info.restart_command")}>
|
|
64
|
-
{@render
|
|
64
|
+
{@render WidgetCommand("restartCommand", "Restart")}
|
|
65
|
+
</PropsGroup>
|
|
66
|
+
<PropsGroup label={$T("widget.info.reset_command")}>
|
|
67
|
+
{@render WidgetCommand("resetCommand", "RstNVS")}
|
|
65
68
|
</PropsGroup>
|
|
66
69
|
</div>
|
|
@@ -103,9 +103,9 @@ const translations = {
|
|
|
103
103
|
"🎯 **用途**\n设备网络的完整配置:模式、连接路由器、自身接入点。\n\n📦 **数据包**\n- `CFG` 分组的字段(可通过设置中的前缀更改),无需绑定变量\n- 字段在本地编辑,「保存」以一个 `SET ModCfg` 数据包发送已修改的字段\n- 🔍 扫描网络 —— `GET APsList`,找到的网络出现在 SSID 列表中\n\n🔑 **键**\n- `WiFiMode` —— 数字:`0` 关闭、`1` 客户端、`2` 接入点、`3` 两者\n- `StaSSID`、`StaPSK` —— 字符串:路由器网络和密码\n- `StaticIP` —— 数字:`0` DHCP、`1` 静态地址\n- `StaIP`、`StaMS`、`StaGW` —— 字符串:客户端地址、掩码、网关\n- `ApSSID`、`ApPSK` —— 字符串:自身接入点名称和密码\n- `ApIP`、`ApMS`、`ApGW` —— 字符串:接入点地址、掩码、网关\n\n✨ **特点**\n- 仅启用接入点时组件会提醒:设备可能从局域网中消失\n\n⚙️ **设置**\n- 分组前缀(ID)、字段名覆盖、主色",
|
|
104
104
|
],
|
|
105
105
|
"component.info.WidgetDeviceInfo": [
|
|
106
|
-
"🎯 **Назначение**\nПаспорт устройства и его основные настройки.\n\n📦 **Пакет данных**\n- Поля группы `CFG` (меняется префиксом в настройках), привязывать переменные не нужно\n- «Сохранить» отправляет изменённые поля одним пакетом `SET ModCfg`\n- 🔌 «Перезагрузить» — команда `SET Restart`\n\n🔑 **Ключи**\n- `DevSN` — строка: серийный номер, только чтение\n- `DevID` — строка: код изделия, только чтение\n- `DevFW` — число: версия ПО, только чтение\n- `RunCnt` — число: счётчик запусков, только чтение\n- `StaIP`, `ApIP` — строки: текущие адреса клиента и точки доступа, только чтение\n- `DevName` — строка: имя устройства\n- `HostName` — строка: сетевое имя\n- `WebUser`, `WebPsw` — строки: логин и пароль веб-интерфейса\n\n⚙️ **Настройки**\n- Префикс группы (ID), мастер-цвет",
|
|
107
|
-
'🎯 **Purpose**\nDevice passport and its main settings.\n\n📦 **Data packet**\n- Fields of the `CFG` group (changed by the prefix in settings), no variable binding needed\n- "Save" sends the changed fields in one `SET ModCfg` packet\n- 🔌 "Restart" — the `SET Restart` command\n\n🔑 **Keys**\n- `DevSN` — string: serial number, read only\n- `DevID` — string: product code, read only\n- `DevFW` — number: firmware version, read only\n- `RunCnt` — number: boot counter, read only\n- `StaIP`, `ApIP` — strings: current client and access point addresses, read only\n- `DevName` — string: device name\n- `HostName` — string: network host name\n- `WebUser`, `WebPsw` — strings: web interface login and password\n\n⚙️ **Settings**\n- Group prefix (ID), master color',
|
|
108
|
-
"🎯 **用途**\n设备档案及其主要设置。\n\n📦 **数据包**\n- `CFG` 分组的字段(可通过设置中的前缀更改),无需绑定变量\n- 「保存」以一个 `SET ModCfg` 数据包发送已修改的字段\n- 🔌「重启」—— `SET Restart` 命令\n\n🔑 **键**\n- `DevSN` —— 字符串:序列号,只读\n- `DevID` —— 字符串:产品代码,只读\n- `DevFW` —— 数字:固件版本,只读\n- `RunCnt` —— 数字:启动计数,只读\n- `StaIP`、`ApIP` —— 字符串:客户端和接入点的当前地址,只读\n- `DevName` —— 字符串:设备名称\n- `HostName` —— 字符串:网络主机名\n- `WebUser`、`WebPsw` —— 字符串:Web 界面登录名和密码\n\n⚙️ **设置**\n- 分组前缀(ID)、主色",
|
|
106
|
+
"🎯 **Назначение**\nПаспорт устройства и его основные настройки.\n\n📦 **Пакет данных**\n- Поля группы `CFG` (меняется префиксом в настройках), привязывать переменные не нужно\n- «Сохранить» отправляет изменённые поля одним пакетом `SET ModCfg`\n- ♻️ «Сброс настроек» — после подтверждения команда `SET RstNVS`, все настройки к заводским, прибор перезагружается\n- 🔌 «Перезагрузить» — команда `SET Restart`\n\n🔑 **Ключи**\n- `DevSN` — строка: серийный номер, только чтение\n- `DevID` — строка: код изделия, только чтение\n- `DevFW` — число: версия ПО, только чтение\n- `RunCnt` — число: счётчик запусков, только чтение\n- `StaIP`, `ApIP` — строки: текущие адреса клиента и точки доступа, только чтение\n- `DevName` — строка: имя устройства\n- `HostName` — строка: сетевое имя\n- `WebUser`, `WebPsw` — строки: логин и пароль веб-интерфейса\n\n⚙️ **Настройки**\n- Префикс группы (ID), мастер-цвет",
|
|
107
|
+
'🎯 **Purpose**\nDevice passport and its main settings.\n\n📦 **Data packet**\n- Fields of the `CFG` group (changed by the prefix in settings), no variable binding needed\n- "Save" sends the changed fields in one `SET ModCfg` packet\n- ♻️ "Factory reset" — after confirmation the `SET RstNVS` command, all settings return to factory defaults and the device restarts\n- 🔌 "Restart" — the `SET Restart` command\n\n🔑 **Keys**\n- `DevSN` — string: serial number, read only\n- `DevID` — string: product code, read only\n- `DevFW` — number: firmware version, read only\n- `RunCnt` — number: boot counter, read only\n- `StaIP`, `ApIP` — strings: current client and access point addresses, read only\n- `DevName` — string: device name\n- `HostName` — string: network host name\n- `WebUser`, `WebPsw` — strings: web interface login and password\n\n⚙️ **Settings**\n- Group prefix (ID), master color',
|
|
108
|
+
"🎯 **用途**\n设备档案及其主要设置。\n\n📦 **数据包**\n- `CFG` 分组的字段(可通过设置中的前缀更改),无需绑定变量\n- 「保存」以一个 `SET ModCfg` 数据包发送已修改的字段\n- ♻️「恢复出厂设置」—— 确认后发送 `SET RstNVS` 命令,所有设置恢复为出厂默认值,设备重启\n- 🔌「重启」—— `SET Restart` 命令\n\n🔑 **键**\n- `DevSN` —— 字符串:序列号,只读\n- `DevID` —— 字符串:产品代码,只读\n- `DevFW` —— 数字:固件版本,只读\n- `RunCnt` —— 数字:启动计数,只读\n- `StaIP`、`ApIP` —— 字符串:客户端和接入点的当前地址,只读\n- `DevName` —— 字符串:设备名称\n- `HostName` —— 字符串:网络主机名\n- `WebUser`、`WebPsw` —— 字符串:Web 界面登录名和密码\n\n⚙️ **设置**\n- 分组前缀(ID)、主色",
|
|
109
109
|
],
|
|
110
110
|
"component.info.WidgetFileSystem": [
|
|
111
111
|
'🎯 **Назначение**\nПамять устройства, список файлов, удаление и закачка.\n\n📦 **Пакет данных**\n- Один объект `CFG.FS` (префикс и имя поля меняются в настройках), привязывать переменные не нужно\n- 🔄 «Обновить» — `GET FS`\n- «Удалить» — `SET FS` с `Op: Delete` после подтверждения\n- Закачка — `SET FS` с `Op` `UploadStart` → `UploadChunk` → `UploadDone`\n\n🔑 **Ключи**\n- `Total`, `Used`, `Free` — числа, байт: объём, занято, свободно\n- `List` — массив `[{ "Name", "Size" }]`: полный путь файла и размер в байтах\n- `Upload` — объект `{ "Name", "Size", "Progress" }`, есть только во время закачки; `Progress` — 0–100\n\n✨ **Особенности**\n- Полоса занятости оранжевая от 75%, красная от 90%\n- Закачка с другого клиента тоже видна\n- Имя файла — не длиннее 31 символа (ограничение прошивки, задаётся в настройках)\n\n⚙️ **Настройки**\n- Префикс группы (ID), поле состояния ФС, аргумент команд, мастер-цвет\n- Допустимые файлы (фильтр в окне выбора), максимальная длина имени',
|
|
@@ -133,10 +133,8 @@ const translations = {
|
|
|
133
133
|
'🎯 **用途**\n固件调试:空闲内存和任务栈余量。\n\n📦 **数据包**\n- 来自 `GET StackInfo` 响应的一个 `StackInfo` 对象,无需绑定变量\n- 通过「刷新」按钮或自动轮询请求\n\n🔑 **键**\n- `Heap` —— 数组 `[{ "Name", "Total", "Free", "MinFree" }]`,字节:内存堆,`MinFree` —— 启动以来的最小空闲\n- `Tasks` —— 数组 `[{ "Name", "State", "Prio", "Core", "FreeMin" }]`:任务;`State` —— `0` 运行、`1` 就绪、`2` 阻塞、`3` 挂起、`4` 已删除;`Core` —— 内核(仅 ESP32,`-1` 未绑定);`FreeMin` —— 最小栈余量,字节\n\n✨ **特点**\n- 堆条的浅色部分为峰值占用\n- 任务按栈余量排序 —— 风险最高的在上方\n- 折叠的组件不轮询设备\n\n⚙️ **设置**\n- 栈余量阈值:低于阈值 —— 红色,低于两倍 —— 橙色\n- 自动轮询:关 / 1 / 5 / 10 秒;主色',
|
|
134
134
|
],
|
|
135
135
|
/* Опции редактора свойств */
|
|
136
|
-
"constructor.props.action.update": ["Обновить", "Update", "更新"],
|
|
137
136
|
"constructor.props.action.save": ["Сохранить", "Save", "保存"],
|
|
138
137
|
"constructor.props.action.nosend": ["Без отправки", "No send", "不发送"],
|
|
139
|
-
"constructor.props.action.custom": ["Свой аргумент", "Custom argument", "自定义参数"],
|
|
140
138
|
"constructor.props.height.small": ["Авто", "Auto", "自动"],
|
|
141
139
|
"constructor.props.height.medium": ["Средняя", "Medium", "中等"],
|
|
142
140
|
"constructor.props.height.large": ["Большая", "Large", "大"],
|
|
@@ -178,14 +176,10 @@ const translations = {
|
|
|
178
176
|
"constructor.props.switch": ["Переключатель", "Switch", "开关"],
|
|
179
177
|
/* Общие для редактора свойств */
|
|
180
178
|
"constructor.props.id": ["Идентификатор", "Identifier", "标识符"],
|
|
181
|
-
"constructor.props.label": ["Текст надписи", "Label text", "标签文本"],
|
|
182
179
|
"constructor.props.label.class": ["Стили надписи", "Label styles", "标签样式"],
|
|
183
|
-
"constructor.props.settings.label": ["Текст надписи настроек", "Settings label text", "设置标签文本"],
|
|
184
180
|
"constructor.props.wrapperclass": ["Стили обёртки", "Wrapper styles", "容器样式"],
|
|
185
181
|
"constructor.props.componentclass": ["Стили компонента", "Component styles", "组件样式"],
|
|
186
|
-
"constructor.props.svgicon": ["SVG-иконка (строка)", "SVG icon (string)", "SVG 图标(字符串)"],
|
|
187
182
|
"constructor.props.open": ["Разворачивание", "Expand", "展开"],
|
|
188
|
-
"constructor.props.defaultcolor": ["Первоначальный цвет", "Initial color", "初始颜色"],
|
|
189
183
|
"constructor.props.file.accept": ["Допустимые файлы", "Allowed files", "允许的文件"],
|
|
190
184
|
"constructor.props.file.accept.help": [
|
|
191
185
|
"'audio/*', 'video/*', 'image/*' или расширения файлов через пробел в формате '.pdf'",
|
|
@@ -198,15 +192,12 @@ const translations = {
|
|
|
198
192
|
"constructor.props.form": ["Форма", "Shape", "形状"],
|
|
199
193
|
"constructor.props.type": ["Тип", "Type", "类型"],
|
|
200
194
|
"constructor.props.size": ["Размер", "Size", "大小"],
|
|
201
|
-
"constructor.props.footer": ["Нижняя панель", "Footer panel", "底部面板"],
|
|
202
195
|
"constructor.props.group.general": ["Общее", "General", "常规"],
|
|
203
196
|
"constructor.props.group.appearance": ["Оформление", "Appearance", "外观"],
|
|
204
197
|
"constructor.props.group.layout": ["Расположение", "Layout", "布局"],
|
|
205
198
|
"constructor.props.group.value": ["Значение", "Value", "数值"],
|
|
206
199
|
"constructor.props.group.behavior": ["Поведение", "Behavior", "行为"],
|
|
207
|
-
"constructor.props.group.options": ["Варианты", "Options", "选项"],
|
|
208
200
|
"constructor.props.group.content": ["Содержимое", "Content", "内容"],
|
|
209
|
-
"constructor.props.group.icon": ["Значок", "Icon", "图标"],
|
|
210
201
|
"constructor.props.header": ["Заголовок пакета", "Packet header", "数据包头"],
|
|
211
202
|
"constructor.props.argument": ["Аргумент", "Argument", "参数"],
|
|
212
203
|
"constructor.props.argument.info": [
|
|
@@ -228,17 +219,13 @@ const translations = {
|
|
|
228
219
|
"用于以 JSON 格式输入数据包 Value 的字段",
|
|
229
220
|
],
|
|
230
221
|
"constructor.props.align": ["Выравнивание надписи", "Label alignment", "标签对齐"],
|
|
231
|
-
"constructor.props.align.header": ["Выравнивание заголовка", "Header alignment", "标题对齐"],
|
|
232
222
|
"constructor.props.align.content": ["Выравнивание контента", "Content alignment", "内容对齐"],
|
|
233
|
-
"constructor.props.table.content.type": ["Тип контента ", "Content type", "内容类型"],
|
|
234
223
|
"constructor.props.tablecolumn.settings": ["Настройки текста", "Text settings", "文本设置"],
|
|
235
224
|
"constructor.props.textfield.settings": ["Настройки текста", "Text settings", "文本设置"],
|
|
236
225
|
"constructor.props.image": ["Фоновое изображение", "Background image", "背景图片"],
|
|
237
226
|
"constructor.props.labelicon": ["Иконка заголовка", "Header icon", "标题图标"],
|
|
238
227
|
"constructor.props.markerIcon": ["Иконка маркера", "Marker icon", "标记图标"],
|
|
239
228
|
"constructor.props.buttonIcon": ["Иконка кнопки", "Button icon", "按钮图标"],
|
|
240
|
-
"constructor.props.removeimage": ["Удалить изображение", "Remove image", "删除图片"],
|
|
241
|
-
"constructor.props.name": ["Текст", "Text", "文本"],
|
|
242
229
|
"constructor.props.height": ["Высота", "Height", "高度"],
|
|
243
230
|
"constructor.props.colors": ["Цвет фона", "Background color", "背景颜色"],
|
|
244
231
|
"constructor.props.button.colors.hint": [
|
|
@@ -248,8 +235,6 @@ const translations = {
|
|
|
248
235
|
],
|
|
249
236
|
"constructor.props.outline": ["Границы таблицы", "Table borders", "表格边框"],
|
|
250
237
|
"constructor.props.textcolors": ["Цвет текста", "Text color", "文本颜色"],
|
|
251
|
-
"constructor.props.componentcolor": ["Цвет компонентов", "Component color", "组件颜色"],
|
|
252
|
-
"constructor.props.iconcolor": ["Цвет иконки", "Icon color", "图标颜色"],
|
|
253
238
|
"constructor.props.settings.type": ["Тип настроек", "Settings type", "设置类型"],
|
|
254
239
|
"constructor.props.textarea.rows": ["Количество строк", "Number of rows", "行数"],
|
|
255
240
|
"constructor.props.autocomplete": ["Автозаполнение", "Autocomplete", "自动填充"],
|
|
@@ -289,9 +274,6 @@ const translations = {
|
|
|
289
274
|
"constructor.props.maxnum": ["Максимальное число", "Maximum number", "最大数值"],
|
|
290
275
|
"constructor.props.units": ["Единица измерения", "Unit of measurement", "计量单位"],
|
|
291
276
|
"constructor.props.step": ["Шаг", "Step", "步长"],
|
|
292
|
-
"constructor.props.rows": ["Количество строк", "Number of rows", "行数"],
|
|
293
|
-
"constructor.props.placeholder": ["Заполнитель", "Placeholder", "占位符"],
|
|
294
|
-
"constructor.props.info": ["Подсказка", "Hint", "提示"],
|
|
295
277
|
"constructor.props.info.side": ["Положение подсказки", "Hint position", "提示位置"],
|
|
296
278
|
"constructor.props.iconpos.left": ["Иконка слева", "Icon on the left", "图标在左"],
|
|
297
279
|
"constructor.props.iconpos.top": ["Иконка сверху", "Icon on top", "图标在上"],
|
|
@@ -315,7 +297,6 @@ const translations = {
|
|
|
315
297
|
"constructor.props.refreshrate": ["Скорость обновления", "Refresh rate", "刷新速率"],
|
|
316
298
|
"constructor.props.variable": ["Имя переменной", "Variable name", "变量名"],
|
|
317
299
|
"constructor.props.widthMode": ["Ширина кнопок", "Button width", "按钮宽度"],
|
|
318
|
-
"constructor.props.graphdata.title": ["Начальные данные ", "Initial data", "初始数据"],
|
|
319
300
|
"constructor.props.options.title": ["Опции компонента", "Component options", "组件选项"],
|
|
320
301
|
"constructor.props.progressbar.title": ["Полосы прогресса", "Progress bars", "进度条"],
|
|
321
302
|
"constructor.props.bits.title": ["Биты", "Bits", "位"],
|
|
@@ -325,8 +306,6 @@ const translations = {
|
|
|
325
306
|
"constructor.props.periodchart.labels": ["Подписи столбиков (через пробел)", "Bar labels (comma-separated)", "柱标签(逗号分隔)"],
|
|
326
307
|
"constructor.props.valuetype": ["Тип значения", "Value type", "值类型"],
|
|
327
308
|
"constructor.props.action": ["Действие при переключении", "Action on switch", "切换时的操作"],
|
|
328
|
-
"constructor.props.caption.left": ["Надпись слева", "Left caption", "左侧标题"],
|
|
329
|
-
"constructor.props.caption.right": ["Надпись справа", "Right caption", "右侧标题"],
|
|
330
309
|
"constructor.props.bold": ["Жирный", "Bold", "粗体"],
|
|
331
310
|
"constructor.props.italic": ["Курсив", "Italic", "斜体"],
|
|
332
311
|
"constructor.props.background": ["Фон", "Background", "背景"],
|
|
@@ -375,23 +354,16 @@ const translations = {
|
|
|
375
354
|
"constructor.props.table.text.key": ["Ключ текста", "Text key", "文本键"],
|
|
376
355
|
"constructor.props.table.select.key": ["Ключ селектора", "Selector key", "选择器键"],
|
|
377
356
|
"constructor.props.table.progressBar.key": ["Ключ прогресса", "Progress key", "进度键"],
|
|
378
|
-
"constructor.props.table.columns.key": ["Ключ", "Key", "键"],
|
|
379
|
-
"constructor.props.table.columns.label": ["Название колонки", "Column name", "列名"],
|
|
380
357
|
"constructor.props.table.columns.width": ["Ширина, %", "Width, %", "宽度,%"],
|
|
381
358
|
"constructor.props.table.columns.sortable": ["Сортировка", "Sortable", "排序"],
|
|
382
359
|
"constructor.props.table.columns.truncated": ["Сократить контент", "Truncate content", "截断内容"],
|
|
383
360
|
"constructor.props.table.columns.tooltip": ["Всплывающее окно", "Tooltip", "工具提示"],
|
|
384
361
|
"constructor.props.table.fulldata": ["Полные данные", "Full data", "完整数据"],
|
|
385
362
|
"constructor.props.table.columns.modal": ["Модальное окно", "Modal window", "模态窗口"],
|
|
386
|
-
"constructor.props.table.columns.alt": ["Альтернативное название иконок", "Alternative icon name", "图标替代名称"],
|
|
387
363
|
"constructor.props.table.columns.class": ["Стили иконки", "Icon styles", "图标样式"],
|
|
388
364
|
"constructor.props.table.columns.defaultIcon": ["Иконка по умолчанию", "Default icon", "默认图标"],
|
|
389
365
|
"constructor.props.table.columns.image.width": ["Ширина иконки, rem", "Icon width, rem", "图标宽度,rem"],
|
|
390
366
|
"constructor.props.table.columns.image.height": ["Высота иконки, rem", "Icon height, rem", "图标高度,rem"],
|
|
391
|
-
"constructor.props.table.deletecolumn": ["Удалить колонку", "Delete column", "删除列"],
|
|
392
|
-
"constructor.props.table.deletebutton": ["Удалить кнопку", "Delete button", "删除按钮"],
|
|
393
|
-
"constructor.props.table.addaction": ["Добавить действие", "Add action", "添加操作"],
|
|
394
|
-
"constructor.props.table.addbutton": ["Добавить кнопку", "Add button", "添加按钮"],
|
|
395
367
|
"constructor.props.table.keys": ["Перечень ключей", "List of keys", "键列表"],
|
|
396
368
|
"constructor.props.table.keys.info": [
|
|
397
369
|
"Ключи колонок, значения которых будут возвращаться. Перечислить через пробел",
|
|
@@ -412,7 +384,6 @@ const translations = {
|
|
|
412
384
|
"constructor.props.table.type.select": ["Селектор", "Selector", "选择器"],
|
|
413
385
|
"constructor.props.table.type.icon": ["Иконка", "Icon", "图标"],
|
|
414
386
|
"constructor.props.table.type.progressbar": ["Прогресс", "Progress", "进度"],
|
|
415
|
-
"constructor.props.table.timestamp": ["Время", "Time", "时间"],
|
|
416
387
|
"constructor.props.table.visibleRows": ["Видимые строки", "Visible rows", "可见行数"],
|
|
417
388
|
"constructor.props.table.logger": ["Добавление строк", "Row appending", "行添加"],
|
|
418
389
|
"constructor.props.icon.access": ["Доступ", "Access", "访问权限"],
|
|
@@ -463,7 +434,6 @@ const translations = {
|
|
|
463
434
|
"widget.common.kbytes": ["{n} КБ", "{n} KB", "{n} KB"],
|
|
464
435
|
"widget.common.mbytes": ["{n} МБ", "{n} MB", "{n} MB"],
|
|
465
436
|
"widget.common.free": ["Свободно {size}", "Free {size}", "可用 {size}"],
|
|
466
|
-
"widget.common.title": ["Заголовок", "Title", "标题"],
|
|
467
437
|
"widget.common.group_prefix": ["Префикс группы (ID)", "Group prefix (ID)", "组前缀 (ID)"],
|
|
468
438
|
"widget.common.packet_header": ["Заголовок пакета", "Packet header", "数据包头"],
|
|
469
439
|
"widget.common.argument": ["Аргумент", "Argument", "参数"],
|
|
@@ -782,5 +752,16 @@ const translations = {
|
|
|
782
752
|
"constructor.texts.hiddenInfo": ["Скрытая подсказка", "Hidden hint", "隐藏提示"],
|
|
783
753
|
"constructor.texts.progressBars": ["Шкала", "Bar", "进度条"],
|
|
784
754
|
"constructor.texts.buttons": ["Кнопка", "Button", "按钮"],
|
|
755
|
+
"ui.graph.values": ["Значения", "Values", "数值"],
|
|
756
|
+
"ui.graph.refresh": ["Развёртка", "Refresh rate", "刷新率"],
|
|
757
|
+
"widget.info.factory_reset": ["Сброс настроек", "Factory reset", "恢复出厂设置"],
|
|
758
|
+
"widget.info.factory_reset_hint": ["Все настройки к заводским", "All settings to factory defaults", "所有设置恢复为出厂默认值"],
|
|
759
|
+
"widget.info.factory_reset_title": ["Сбросить все настройки?", "Reset all settings?", "重置所有设置?"],
|
|
760
|
+
"widget.info.factory_reset_text": [
|
|
761
|
+
"Все настройки прибора — Wi-Fi, имя, пароль Web, настройки модулей — вернутся к заводским, прибор перезагрузится. Связь по Wi-Fi может пропасть.",
|
|
762
|
+
"All device settings — Wi-Fi, name, Web password, module settings — return to factory defaults and the device restarts. The Wi-Fi connection may be lost.",
|
|
763
|
+
"设备的所有设置(Wi-Fi、名称、Web 密码、模块设置)将恢复为出厂默认值,设备将重启。Wi-Fi 连接可能会断开。",
|
|
764
|
+
],
|
|
765
|
+
"widget.info.reset_command": ["Команда сброса настроек", "Factory reset command", "恢复出厂命令"],
|
|
785
766
|
};
|
|
786
767
|
export default translations;
|
package/dist/types.d.ts
CHANGED
|
@@ -525,10 +525,15 @@ export interface IWidgetDeviceInfoProps {
|
|
|
525
525
|
header?: string;
|
|
526
526
|
argument?: string;
|
|
527
527
|
};
|
|
528
|
+
resetCommand?: {
|
|
529
|
+
header?: string;
|
|
530
|
+
argument?: string;
|
|
531
|
+
};
|
|
528
532
|
collapsed?: boolean;
|
|
529
533
|
persistKey?: string;
|
|
530
534
|
onSave?: (info: IWidgetDeviceInfoConfig) => void;
|
|
531
535
|
onRestart?: () => void;
|
|
536
|
+
onFactoryReset?: () => void;
|
|
532
537
|
}
|
|
533
538
|
export interface IWidgetFileSystemFile {
|
|
534
539
|
Name: string;
|