poe-svelte-ui-lib 1.32.2 → 1.33.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/WidgetFileSystem/README.md +70 -49
- package/dist/WidgetFileSystem/WidgetFileSystem.svelte +19 -16
- package/dist/WidgetFileSystem/WidgetFileSystemProps.svelte +15 -36
- package/dist/index.d.ts +1 -1
- package/dist/locales/translations.js +3 -3
- package/dist/types.d.ts +12 -16
- package/package.json +1 -1
|
@@ -3,55 +3,78 @@
|
|
|
3
3
|
## Описание
|
|
4
4
|
|
|
5
5
|
Смарт-виджет файловой системы устройства: занятость памяти, список файлов с удалением и закачка
|
|
6
|
-
нового файла с прогрессом. Работает с объектом `
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
`GET FSInfo`, таблица `FSList` с кнопкой `DelFile`, `FileAttach`, `ProgressBar` по `UlProg`) —
|
|
14
|
-
одной карточкой в стиле `WidgetWiFi`/`WidgetDeviceInfo`.
|
|
15
|
-
|
|
16
|
-
- **Занятость** — «занято X из Y», процент и полоса; от 75% полоса оранжевая, от 90% — красная.
|
|
17
|
-
Размеры показываются в Б/КБ/МБ.
|
|
6
|
+
нового файла с прогрессом. Работает с одним объектом `CFG.FS` ровно в том виде, в каком его отдаёт
|
|
7
|
+
прошивка (`FS_WriteState`, ProdFactory-ESP), и с одной командой `FS`. Компонент ничего не знает про
|
|
8
|
+
DeviceStore/WebSocket — только `value` и колбэки `onRefresh`/`onDelete`/`onUpload`, вся отправка
|
|
9
|
+
(в том числе протокол закачки) на стороне вызывающего кода.
|
|
10
|
+
|
|
11
|
+
- **Занятость** — «занято X из Y», процент и полоса мастер-цвета; процент оранжевый от 75%,
|
|
12
|
+
красный от 90%. Размеры в Б/КБ/МБ.
|
|
18
13
|
- **Файлы** — таблица «Путь / Размер / Удалить»; длинный путь обрезается «…», удаление
|
|
19
|
-
подтверждается внутри карточки. Пустая ФС — «Файлов нет». Колонка удаления есть, только
|
|
20
|
-
|
|
14
|
+
подтверждается внутри карточки. Пустая ФС — «Файлов нет». Колонка удаления есть, только если
|
|
15
|
+
передан `onDelete`.
|
|
21
16
|
- **Закачка** — блок есть, только если передан `onUpload`. Имя файла проверяется до отправки
|
|
22
|
-
(`maxNameLength`, по умолчанию 31 — ограничение прошивки)
|
|
23
|
-
|
|
17
|
+
(`maxNameLength`, по умолчанию 31 — ограничение прошивки). Прогресс берётся из `value.Upload`
|
|
18
|
+
и виден, пока закачку ведёт этот клиент или пока устройство сообщает `Upload` (закачка с
|
|
19
|
+
другого клиента). Ошибка из `onUpload` выводится под полем.
|
|
20
|
+
|
|
21
|
+
## Протокол устройства
|
|
22
|
+
|
|
23
|
+
Всё состояние ФС — один объект `CFG.FS`:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
"CFG.FS": {
|
|
27
|
+
"Total": 1441792, "Used": 98304, "Free": 1343488,
|
|
28
|
+
"List": [{ "Name": "/storage/cert.pem", "Size": 1834 }],
|
|
29
|
+
"Upload": { "Name": "fw.bin", "Size": 917504, "Progress": 35 }
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`Upload` есть, только пока идёт закачка. Снимок со списком `List` приходит на `GET ModCfg`,
|
|
34
|
+
`GET FS`, после удаления, после завершения или ошибки закачки и в рассылке `OK! Update`; ход
|
|
35
|
+
закачки — только `{"Upload": {...}}` (без списка, раз в 5%). Объект со списком заменяет состояние
|
|
36
|
+
целиком, без списка — дописывается поверх (это делает вызывающий код).
|
|
37
|
+
|
|
38
|
+
Команды — один аргумент `FS`, операция в поле `Op`; ответ всегда `FS` с тем же `Op`:
|
|
39
|
+
|
|
40
|
+
| Запрос | Ответ |
|
|
41
|
+
| ------------------------------------------------------------------------------------ | --------------------------------------------------------- |
|
|
42
|
+
| `GET FS` | `CFG.FS` — снимок |
|
|
43
|
+
| `SET FS {"Op": "Delete", "Name": "/storage/a.bin"}` | `Op`, `CFG.FS` — снимок |
|
|
44
|
+
| `SET FS {"Op": "UploadStart", "FileName", "FileExtension", "FileSize", "CurrentID"}` | `Op`, `CurrentID`, `ChunkSize`, `CFG.FS.Upload` |
|
|
45
|
+
| `SET FS {"Op": "UploadChunk", "ChunkIndex", "Data", "CurrentID"}` | `Op`, `ChunkIndex`, `CurrentID`, раз в 5% `CFG.FS.Upload` |
|
|
46
|
+
| `SET FS {"Op": "UploadDone", "CRC32", "CurrentID"}` | `Op`, `CurrentID`, `CFG.FS` — снимок |
|
|
47
|
+
|
|
48
|
+
Ошибки — `ER! FS` с тем же `Op` (и `CurrentID` у закачки); ошибка закачки несёт снимок `CFG.FS`.
|
|
24
49
|
|
|
25
50
|
## Пропсы
|
|
26
51
|
|
|
27
|
-
| Название | Тип
|
|
28
|
-
| ---------------- |
|
|
29
|
-
| `id` | `string`
|
|
30
|
-
| `wrapperClass` | `string`
|
|
31
|
-
| `componentClass` | `string`
|
|
32
|
-
| `label` | `{ name?: string }`
|
|
33
|
-
| `value` | `IWidgetFileSystemInfo`
|
|
34
|
-
| `
|
|
35
|
-
| `
|
|
36
|
-
| `accept` | `string`
|
|
37
|
-
| `maxNameLength` | `number`
|
|
38
|
-
| `
|
|
39
|
-
| `
|
|
40
|
-
| `
|
|
41
|
-
| `
|
|
42
|
-
| `
|
|
43
|
-
| `onDelete` | `(name: string) => void` | `undefined` | Удаление файла после подтверждения; `name` — полный путь из `FSList` |
|
|
44
|
-
| `onUpload` | `(file: File) => void \| Promise<void>` | `undefined` | Закачка выбранного файла; пока промис не завершён — показывается прогресс, исключение показывается как ошибка под полем |
|
|
52
|
+
| Название | Тип | По умолчанию | Описание |
|
|
53
|
+
| ---------------- | --------------------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------ |
|
|
54
|
+
| `id` | `string` | `undefined` | Префикс прошивочной группы (обычно `"CFG"`), используется вызывающим кодом для чтения `FS` |
|
|
55
|
+
| `wrapperClass` | `string` | `""` | CSS-классы обёртки |
|
|
56
|
+
| `componentClass` | `string` | `""` | «Мастер-цвет» виджета — роль вида `"bg-red"`, перекрашивает весь виджет |
|
|
57
|
+
| `label` | `{ name?: string }` | `{ name: "Файловая система" }` | Заголовок карточки |
|
|
58
|
+
| `value` | `IWidgetFileSystemInfo` | `undefined` | Состояние файловой системы (`CFG.FS`) |
|
|
59
|
+
| `keys` | `{ FS?: string }` | `undefined` | Переопределение имени поля устройства, по умолчанию `FS` |
|
|
60
|
+
| `argument` | `string` | `undefined` | Аргумент команд, по умолчанию `"FS"` (используется вызывающим кодом) |
|
|
61
|
+
| `accept` | `string` | `"*/*"` | Какие файлы можно выбрать (атрибут `accept`), например `".bin, .txt, .pem"` |
|
|
62
|
+
| `maxNameLength` | `number` | `31` | Максимальная длина имени файла |
|
|
63
|
+
| `collapsed` | `boolean` | `false` | Свёрнуто ли тело виджета (`$bindable`) |
|
|
64
|
+
| `persistKey` | `string` | `undefined` | Ключ для сохранения `collapsed` в `localStorage` |
|
|
65
|
+
| `onRefresh` | `() => void` | `undefined` | Кнопка «Обновить» в шапке (`GET FS`); без обработчика кнопка неактивна |
|
|
66
|
+
| `onDelete` | `(name: string) => void` | `undefined` | Удаление файла после подтверждения; `name` — полный путь из `List` |
|
|
67
|
+
| `onUpload` | `(file: File) => void \| Promise<void>` | `undefined` | Закачка выбранного файла; исключение показывается как ошибка под полем |
|
|
45
68
|
|
|
46
69
|
### IWidgetFileSystemInfo
|
|
47
70
|
|
|
48
|
-
| Поле
|
|
49
|
-
|
|
|
50
|
-
| `
|
|
51
|
-
| `
|
|
52
|
-
| `
|
|
53
|
-
| `
|
|
54
|
-
| `
|
|
71
|
+
| Поле | Тип | Описание |
|
|
72
|
+
| -------- | --------------------------------------------------- | ------------------------------------------------------- |
|
|
73
|
+
| `Total` | `number` | Размер файловой системы, байт |
|
|
74
|
+
| `Used` | `number` | Занято, байт |
|
|
75
|
+
| `Free` | `number` | Свободно, байт |
|
|
76
|
+
| `List` | `{ Name: string; Size: number }[]` | Файлы: полный путь (его же принимает `Delete`) и размер |
|
|
77
|
+
| `Upload` | `{ Name: string; Size: number; Progress: number }?` | Текущая закачка, `Progress` 0–100 с шагом 5% |
|
|
55
78
|
|
|
56
79
|
## Примеры
|
|
57
80
|
|
|
@@ -59,17 +82,15 @@
|
|
|
59
82
|
<script>
|
|
60
83
|
import * as UI from "poe-svelte-ui-lib"
|
|
61
84
|
|
|
62
|
-
let
|
|
63
|
-
let progress = 0
|
|
85
|
+
let fs = { Total: 1441792, Used: 98304, Free: 1343488, List: [{ Name: "/storage/cert.pem", Size: 1834 }] }
|
|
64
86
|
</script>
|
|
65
87
|
|
|
66
88
|
<UI.WidgetFileSystem
|
|
67
|
-
value={
|
|
68
|
-
uploadProgress={progress}
|
|
89
|
+
value={fs}
|
|
69
90
|
accept=".bin, .txt, .pem"
|
|
70
|
-
onRefresh={() => console.log("GET
|
|
71
|
-
onDelete={(name) => console.log("SET
|
|
72
|
-
onUpload={async (file) => console.log("
|
|
91
|
+
onRefresh={() => console.log("GET FS")}
|
|
92
|
+
onDelete={(name) => console.log("SET FS", { Op: "Delete", Name: name })}
|
|
93
|
+
onUpload={async (file) => console.log("SET FS UploadStart/UploadChunk/UploadDone", file.name)}
|
|
73
94
|
/>
|
|
74
95
|
```
|
|
75
96
|
|
|
@@ -81,4 +102,4 @@
|
|
|
81
102
|
| `onPropertyChange` | `(updates: Partial<{ properties?: string \| object; name?: string; access?: string }>) => void` | Коллбэк для обновления свойств компонента |
|
|
82
103
|
|
|
83
104
|
Группы панели: общие (заголовок, префикс группы, мастер-цвет), закачка (`accept`,
|
|
84
|
-
`maxNameLength`),
|
|
105
|
+
`maxNameLength`), устройство (поле `FS`, аргумент команд).
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<!-- $lib/WidgetFileSystem/WidgetFileSystem.svelte — смарт-виджет файловой системы устройства.
|
|
2
|
-
Данные — объект CFG.
|
|
3
|
-
|
|
4
|
-
Ничего не знает про DeviceStore/WebSocket — value/
|
|
5
|
-
|
|
2
|
+
Данные — один объект CFG.FS в том виде, в каком его отдаёт прошивка (FS_WriteState, ProdFactory-ESP):
|
|
3
|
+
Total/Used/Free/List[{Name, Size}] и Upload{Name, Size, Progress} — только пока идёт закачка.
|
|
4
|
+
Ничего не знает про DeviceStore/WebSocket — value/onRefresh/onDelete/onUpload, протокол
|
|
5
|
+
закачки (SET FS с Op UploadStart/UploadChunk/UploadDone) и отправка команд на стороне вызывающего. -->
|
|
6
6
|
<script lang="ts">
|
|
7
7
|
import { slide, fade, scale } from "svelte/transition"
|
|
8
8
|
import { twMerge } from "tailwind-merge"
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
componentClass = "",
|
|
20
20
|
label = { name: "Файловая система" },
|
|
21
21
|
value,
|
|
22
|
-
uploadProgress = 0,
|
|
23
22
|
accept = "*/*",
|
|
24
23
|
maxNameLength = 31,
|
|
25
24
|
collapsed = $bindable(false),
|
|
@@ -49,10 +48,10 @@
|
|
|
49
48
|
return `${(bytes / (1024 * 1024)).toFixed(1)} МБ`
|
|
50
49
|
}
|
|
51
50
|
|
|
52
|
-
let total = $derived(value?.
|
|
53
|
-
let used = $derived(value?.
|
|
54
|
-
let free = $derived(value?.
|
|
55
|
-
let files = $derived(value?.
|
|
51
|
+
let total = $derived(value?.Total ?? 0)
|
|
52
|
+
let used = $derived(value?.Used ?? 0)
|
|
53
|
+
let free = $derived(value?.Free ?? Math.max(total - used, 0))
|
|
54
|
+
let files = $derived(value?.List ?? [])
|
|
56
55
|
let usedPercent = $derived(total > 0 ? Math.min(100, Math.round((used / total) * 100)) : 0)
|
|
57
56
|
/* Полоса — мастер-цвет виджета; почти заполненную ФС (закачка скоро начнёт падать) выдаёт только процент */
|
|
58
57
|
let percentColor = $derived(usedPercent >= 90 ? "var(--red-color)" : usedPercent >= 75 ? "var(--orange-color)" : "var(--muted-color)")
|
|
@@ -75,8 +74,10 @@
|
|
|
75
74
|
: []),
|
|
76
75
|
])
|
|
77
76
|
|
|
78
|
-
/*
|
|
79
|
-
|
|
77
|
+
/* Закачка видна, пока её ведёт этот клиент или пока устройство сообщает Upload (закачка с другого клиента);
|
|
78
|
+
прогресс 0..100, нечисло — 0, а не «NaN%» */
|
|
79
|
+
let upload = $derived(value?.Upload)
|
|
80
|
+
let progress = $derived(Number.isFinite(Number(upload?.Progress)) ? Math.min(100, Math.max(0, Number(upload?.Progress))) : 0)
|
|
80
81
|
|
|
81
82
|
let pendingDelete: string | null = $state(null)
|
|
82
83
|
const confirmDelete = () => {
|
|
@@ -84,8 +85,7 @@
|
|
|
84
85
|
pendingDelete = null
|
|
85
86
|
}
|
|
86
87
|
|
|
87
|
-
/* Закачка: имя проверяется до отправки (прошивка отвергнет длинное имя уже после
|
|
88
|
-
из uploadProgress, пока onUpload не завершится */
|
|
88
|
+
/* Закачка: имя проверяется до отправки (прошивка отвергнет длинное имя уже после UploadStart) */
|
|
89
89
|
let uploading = $state(false)
|
|
90
90
|
let uploadError = $state("")
|
|
91
91
|
const handleFile = async (_event: Event, file: File | null) => {
|
|
@@ -136,7 +136,7 @@
|
|
|
136
136
|
</div>
|
|
137
137
|
<div class="flex justify-between gap-2 text-[12px] text-(--muted-color)">
|
|
138
138
|
<span>Свободно {formatBytes(free)}</span>
|
|
139
|
-
<span>Файлов: {
|
|
139
|
+
<span>Файлов: {files.length}</span>
|
|
140
140
|
</div>
|
|
141
141
|
</div>
|
|
142
142
|
|
|
@@ -152,9 +152,12 @@
|
|
|
152
152
|
<!-- Закачка -->
|
|
153
153
|
{#if onUpload}
|
|
154
154
|
<div class="flex flex-col gap-2 rounded-[10px] border border-(--hairline-color) bg-(--back-color) p-3">
|
|
155
|
-
<UI.FileAttach label={{ name: "Закачать файл" }} {accept} disabled={uploading} onChange={handleFile} />
|
|
156
|
-
{#if uploading}
|
|
155
|
+
<UI.FileAttach label={{ name: "Закачать файл" }} {accept} disabled={uploading || !!upload} onChange={handleFile} />
|
|
156
|
+
{#if uploading || upload}
|
|
157
157
|
<div class="flex items-center gap-2 text-[12px]" transition:slide={{ duration: 100 }}>
|
|
158
|
+
{#if upload?.Name}
|
|
159
|
+
<span class="max-w-40 truncate text-(--muted-color)">{upload.Name}</span>
|
|
160
|
+
{/if}
|
|
158
161
|
<div class="h-2 flex-1 overflow-hidden rounded-full bg-(--container-color)">
|
|
159
162
|
<div class="h-full rounded-full bg-(--accent-color) transition-[width] duration-300" style="width: {progress}%"></div>
|
|
160
163
|
</div>
|
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
<!-- $lib/WidgetFileSystem/WidgetFileSystemProps.svelte — панель пропсов конструктора для
|
|
2
|
-
WidgetFileSystem: заголовок/мастер-цвет/префикс группы,
|
|
3
|
-
фильтр закачки и
|
|
4
|
-
|
|
2
|
+
WidgetFileSystem: заголовок/мастер-цвет/префикс группы, имя поля устройства (keys.FS),
|
|
3
|
+
фильтр закачки и аргумент команд — все с дефолтами, равными прошивочной конвенции
|
|
4
|
+
(см. DEFAULT_PROPS.WidgetFileSystem в DevCloud). -->
|
|
5
5
|
<script lang="ts">
|
|
6
6
|
import { T } from "../locales/i18n"
|
|
7
7
|
import * as UI from ".."
|
|
8
|
-
import { updateProperty, type UIComponent, type IWidgetFileSystemProps
|
|
8
|
+
import { updateProperty, type UIComponent, type IWidgetFileSystemProps } from "../types"
|
|
9
9
|
import WidgetAccentPicker from "../WidgetAccentPicker.svelte"
|
|
10
10
|
import PropsGroup from "../PropsGroup.svelte"
|
|
11
|
-
import { optionsStore } from "../options"
|
|
12
|
-
|
|
13
|
-
const FS_KEYS = ["FSInfo", "UlProg"] as const
|
|
14
11
|
|
|
15
12
|
const { component, onPropertyChange } = $props<{
|
|
16
13
|
component: UIComponent & { properties: Partial<IWidgetFileSystemProps> }
|
|
@@ -18,21 +15,6 @@
|
|
|
18
15
|
}>()
|
|
19
16
|
</script>
|
|
20
17
|
|
|
21
|
-
{#snippet Command(key: "infoCommand" | "deleteCommand", header: string, argument: string)}
|
|
22
|
-
<UI.Select
|
|
23
|
-
label={{ name: "Заголовок пакета" }}
|
|
24
|
-
type="buttons"
|
|
25
|
-
options={$optionsStore.HEADER_OPTIONS}
|
|
26
|
-
value={$optionsStore.HEADER_OPTIONS.find((o) => o.value === (component.properties[key]?.header || header))}
|
|
27
|
-
onUpdate={(option) => updateProperty(`${key}.header`, (option as IOption<string>).value as string, component, onPropertyChange)}
|
|
28
|
-
/>
|
|
29
|
-
<UI.Input
|
|
30
|
-
label={{ name: "Аргумент" }}
|
|
31
|
-
value={component.properties[key]?.argument ?? argument}
|
|
32
|
-
onUpdate={(value) => updateProperty(`${key}.argument`, value as string, component, onPropertyChange)}
|
|
33
|
-
/>
|
|
34
|
-
{/snippet}
|
|
35
|
-
|
|
36
18
|
<div class="flex flex-col gap-2">
|
|
37
19
|
<PropsGroup label={$T("constructor.props.group.general")}>
|
|
38
20
|
<UI.Input
|
|
@@ -65,19 +47,16 @@
|
|
|
65
47
|
onUpdate={(value) => updateProperty("maxNameLength", Number(value), component, onPropertyChange)}
|
|
66
48
|
/>
|
|
67
49
|
</PropsGroup>
|
|
68
|
-
<PropsGroup label="
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
</PropsGroup>
|
|
80
|
-
<PropsGroup label="Команда удаления">
|
|
81
|
-
{@render Command("deleteCommand", "SET", "DelFile")}
|
|
50
|
+
<PropsGroup label="Устройство">
|
|
51
|
+
<UI.Input
|
|
52
|
+
label={{ name: "Поле состояния ФС" }}
|
|
53
|
+
value={component.properties.keys?.FS ?? "FS"}
|
|
54
|
+
onUpdate={(value) => updateProperty("keys.FS", value as string, component, onPropertyChange)}
|
|
55
|
+
/>
|
|
56
|
+
<UI.Input
|
|
57
|
+
label={{ name: "Аргумент команд" }}
|
|
58
|
+
value={component.properties.argument ?? "FS"}
|
|
59
|
+
onUpdate={(value) => updateProperty("argument", value as string, component, onPropertyChange)}
|
|
60
|
+
/>
|
|
82
61
|
</PropsGroup>
|
|
83
62
|
</div>
|
package/dist/index.d.ts
CHANGED
|
@@ -48,4 +48,4 @@ export { default as WidgetFileSystemProps } from "./WidgetFileSystem/WidgetFileS
|
|
|
48
48
|
export * from "./locales/i18n";
|
|
49
49
|
export * from "./locales/translations";
|
|
50
50
|
export * from "./ModalStackStore";
|
|
51
|
-
export { type UIComponent, type Position, type IUIComponentHandler, type IButtonProps, type IAccordionProps, type IInputProps, type ISelectProps, type IOption, type ISwitchProps, type IColorPickerProps, type IDividerProps, type ISliderProps, type ITextFieldProps, type IMapProps, type IProgressBarProps, type IWidgetProps, type IWidgetWiFiProps, type IWidgetWiFiConfig, type IWidgetDeviceInfoProps, type IWidgetDeviceInfoConfig, type IWidgetFileSystemProps, type IWidgetFileSystemInfo, type IWidgetFileSystemFile, type IGraphProps, type IGraphDataObject, type IGraphHistoryPoint, type IGraphHistorySeries, type ITableHeader, type ITableText, type ITableSelect, type ITableButton, type ITableProgressBar, type ITableImage, type ITableContent, type ITableProps, type ITabsProps, type IJoystickProps, type IFileAttachProps, type IDeviceGNSS, type ICarouselProps, type IReceivingDataObject, type IVideoViewerProps, type IPeriodChartProps, type IPeriodChartLevel, } from "./types";
|
|
51
|
+
export { type UIComponent, type Position, type IUIComponentHandler, type IButtonProps, type IAccordionProps, type IInputProps, type ISelectProps, type IOption, type ISwitchProps, type IColorPickerProps, type IDividerProps, type ISliderProps, type ITextFieldProps, type IMapProps, type IProgressBarProps, type IWidgetProps, type IWidgetWiFiProps, type IWidgetWiFiConfig, type IWidgetDeviceInfoProps, type IWidgetDeviceInfoConfig, type IWidgetFileSystemProps, type IWidgetFileSystemInfo, type IWidgetFileSystemFile, type IWidgetFileSystemUpload, type IGraphProps, type IGraphDataObject, type IGraphHistoryPoint, type IGraphHistorySeries, type ITableHeader, type ITableText, type ITableSelect, type ITableButton, type ITableProgressBar, type ITableImage, type ITableContent, type ITableProps, type ITabsProps, type IJoystickProps, type IFileAttachProps, type IDeviceGNSS, type ICarouselProps, type IReceivingDataObject, type IVideoViewerProps, type IPeriodChartProps, type IPeriodChartLevel, } from "./types";
|
|
@@ -24,9 +24,9 @@ const translations = {
|
|
|
24
24
|
"ℹ️ 该组件使用设备 `CFG` 分组下的一组固定字段——无需手动绑定变量。\n\n**🔒 只读字段**\n- `DevSN`、`DevID`、`DevFW`、`RunCnt`\n- `StaIP`、`ApIP` —— STA/AP 模式下的当前 IP 地址\n\n**✏️ 可编辑字段**(通过「保存」按钮一次性发送)\n- `DevName`、`HostName`、`WebUser`、`WebPsw`\n\n🔌 「重启」按钮会发送 `Argument: Restart`。\n\n⚙️ 如果设备使用的分组名称不是 `CFG`,请在组件设置中修改前缀(ID)。",
|
|
25
25
|
],
|
|
26
26
|
"component.info.WidgetFileSystem": [
|
|
27
|
-
"🗂️ Виджет работает с объектом `
|
|
28
|
-
"🗂️ The widget works with
|
|
29
|
-
"🗂️ 该组件使用设备 `CFG`
|
|
27
|
+
"🗂️ Виджет работает с одним объектом `FS` группы `CFG` на устройстве — привязка переменных вручную не нужна.\n\n**📊 Занятость**\n- `Total`, `Used`, `Free`\n\n**📄 Файлы**\n- `List` — путь и размер; «Удалить» отправляет `SET FS` с `Op: Delete` и `Name` (после подтверждения)\n\n**⬆️ Закачка**\n- `SET FS` с `Op`: `UploadStart` → `UploadChunk` → `UploadDone`, прогресс — `Upload.Progress`\n- имя файла не длиннее 31 символа (ограничение прошивки)\n\n🔄 «Обновить» отправляет `GET FS`.\n\n⚙️ Если у прошивки другие имена, поменяйте префикс (ID), поле и аргумент в настройках виджета.",
|
|
28
|
+
"🗂️ The widget works with a single `FS` object of the device's `CFG` group — no manual variable binding needed.\n\n**📊 Usage**\n- `Total`, `Used`, `Free`\n\n**📄 Files**\n- `List` — path and size; \"Delete\" sends `SET FS` with `Op: Delete` and `Name` (after confirmation)\n\n**⬆️ Upload**\n- `SET FS` with `Op`: `UploadStart` → `UploadChunk` → `UploadDone`, progress — `Upload.Progress`\n- file name up to 31 characters (firmware limit)\n\n🔄 \"Refresh\" sends `GET FS`.\n\n⚙️ If the firmware uses different names, change the prefix (ID), field and argument in the widget settings.",
|
|
29
|
+
"🗂️ 该组件使用设备 `CFG` 分组下的单个 `FS` 对象——无需手动绑定变量。\n\n**📊 占用**\n- `Total`、`Used`、`Free`\n\n**📄 文件**\n- `List` —— 路径和大小;「删除」在确认后发送带 `Op: Delete` 和 `Name` 的 `SET FS`\n\n**⬆️ 上传**\n- `SET FS`,`Op`:`UploadStart` → `UploadChunk` → `UploadDone`,进度 —— `Upload.Progress`\n- 文件名不超过 31 个字符(固件限制)\n\n🔄 「刷新」发送 `GET FS`。\n\n⚙️ 如果固件使用其他名称,请在组件设置中修改前缀(ID)、字段和参数。",
|
|
30
30
|
],
|
|
31
31
|
"component.info.Tabs": [
|
|
32
32
|
"📑 Ширина и позиция иконки задаются через служебные CSS-классы каждой вкладки, а не отдельными полями.\n\n**↔️ Ширина кнопок** (переключатель «Авто/Равные»)\n- `w-auto` — по содержимому\n- `flex-1` — поровну между всеми вкладками\n\n**🔤 Позиция иконки**\n- `flex-row` / `flex-col` / `flex-row-reverse` / `flex-col-reverse`\n\n⚠️ Максимум 10 вкладок.",
|
package/dist/types.d.ts
CHANGED
|
@@ -564,12 +564,17 @@ export interface IWidgetFileSystemFile {
|
|
|
564
564
|
Name: string;
|
|
565
565
|
Size: number;
|
|
566
566
|
}
|
|
567
|
+
export interface IWidgetFileSystemUpload {
|
|
568
|
+
Name: string;
|
|
569
|
+
Size: number;
|
|
570
|
+
Progress: number;
|
|
571
|
+
}
|
|
567
572
|
export interface IWidgetFileSystemInfo {
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
+
Total: number;
|
|
574
|
+
Used: number;
|
|
575
|
+
Free: number;
|
|
576
|
+
List: IWidgetFileSystemFile[];
|
|
577
|
+
Upload?: IWidgetFileSystemUpload;
|
|
573
578
|
}
|
|
574
579
|
export interface IWidgetFileSystemProps {
|
|
575
580
|
id?: string;
|
|
@@ -579,21 +584,12 @@ export interface IWidgetFileSystemProps {
|
|
|
579
584
|
name?: string;
|
|
580
585
|
};
|
|
581
586
|
value?: IWidgetFileSystemInfo;
|
|
582
|
-
uploadProgress?: number;
|
|
583
587
|
keys?: {
|
|
584
|
-
|
|
585
|
-
UlProg?: string;
|
|
588
|
+
FS?: string;
|
|
586
589
|
};
|
|
590
|
+
argument?: string;
|
|
587
591
|
accept?: string;
|
|
588
592
|
maxNameLength?: number;
|
|
589
|
-
infoCommand?: {
|
|
590
|
-
header?: string;
|
|
591
|
-
argument?: string;
|
|
592
|
-
};
|
|
593
|
-
deleteCommand?: {
|
|
594
|
-
header?: string;
|
|
595
|
-
argument?: string;
|
|
596
|
-
};
|
|
597
593
|
collapsed?: boolean;
|
|
598
594
|
persistKey?: string;
|
|
599
595
|
onRefresh?: () => void;
|