@iobroker/adapter-react-v5 7.2.2 → 7.2.4
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/Components/ComplexCron.js +3 -3
- package/Components/FileBrowser.d.ts +20 -20
- package/Components/FileBrowser.js +28 -16
- package/Components/FileViewer.d.ts +2 -2
- package/Components/ObjectBrowser.d.ts +3 -0
- package/Components/ObjectBrowser.js +32 -18
- package/Components/Schedule.d.ts +1 -1
- package/Components/Schedule.js +33 -15
- package/Components/SimpleCron/index.js +34 -8
- package/Dialogs/SimpleCron.js +1 -1
- package/README.md +7 -2
- package/i18n/de.json +14 -4
- package/i18n/en.json +11 -1
- package/i18n/es.json +11 -1
- package/i18n/fr.json +11 -1
- package/i18n/it.json +11 -1
- package/i18n/nl.json +11 -1
- package/i18n/pl.json +11 -1
- package/i18n/pt.json +11 -1
- package/i18n/ru.json +11 -1
- package/i18n/uk.json +11 -1
- package/i18n/zh-cn.json +11 -1
- package/icons/IconClosed.js +1 -1
- package/icons/IconOpen.js +1 -1
- package/package.json +8 -7
- package/src/Components/ComplexCron.tsx +3 -3
- package/src/Components/FileBrowser.tsx +52 -42
- package/src/Components/FileViewer.tsx +2 -2
- package/src/Components/ObjectBrowser.tsx +32 -20
- package/src/Components/Schedule.tsx +49 -13
- package/src/Dialogs/SimpleCron.tsx +1 -0
- package/src/icons/IconClosed.tsx +1 -1
- package/src/icons/IconOpen.tsx +1 -1
package/i18n/en.json
CHANGED
|
@@ -92,6 +92,7 @@
|
|
|
92
92
|
"sc_date": "Date",
|
|
93
93
|
"sc_dates": "Dates",
|
|
94
94
|
"sc_dows": "Day of week",
|
|
95
|
+
"sc_dow": "Day",
|
|
95
96
|
"sc_every": "Every",
|
|
96
97
|
"sc_everyN_dates": "every N days",
|
|
97
98
|
"sc_everyN_dows": "every N day of week",
|
|
@@ -435,5 +436,14 @@
|
|
|
435
436
|
"ra_warning_every_second": "Warning: The CRON job will run every second during the specified period!",
|
|
436
437
|
"ra_warning_every_minute": "Warning: The CRON job will run every minute during the specified period!",
|
|
437
438
|
"ra_The schedule will be executed every second. Are you sure?": "The schedule will be executed every second. Are you sure?",
|
|
438
|
-
"ra_The schedule will be executed every minute. Are you sure?": "The schedule will be executed every minute. Are you sure?"
|
|
439
|
+
"ra_The schedule will be executed every minute. Are you sure?": "The schedule will be executed every minute. Are you sure?",
|
|
440
|
+
"ra_Define CRON...": "Define CRON...",
|
|
441
|
+
"ra_Sunday": "Sunday",
|
|
442
|
+
"ra_Monday": "Monday",
|
|
443
|
+
"ra_Tuesday": "Tuesday",
|
|
444
|
+
"ra_Wednesday": "Wednesday",
|
|
445
|
+
"ra_Thursday": "Thursday",
|
|
446
|
+
"ra_Friday": "Friday",
|
|
447
|
+
"ra_Saturday": "Saturday",
|
|
448
|
+
"sc_invalid_cron": "Invalid CRON"
|
|
439
449
|
}
|
package/i18n/es.json
CHANGED
|
@@ -435,5 +435,15 @@
|
|
|
435
435
|
"ra_warning_every_second": "Advertencia: ¡El trabajo CRON se ejecutará cada segundo durante el período especificado!",
|
|
436
436
|
"ra_warning_every_minute": "Advertencia: ¡El trabajo CRON se ejecutará cada minuto durante el período especificado!",
|
|
437
437
|
"ra_The schedule will be executed every second. Are you sure?": "El cronograma se ejecutará cada segundo. ¿Estás seguro?",
|
|
438
|
-
"ra_The schedule will be executed every minute. Are you sure?": "El cronograma se ejecutará cada minuto. ¿Estás seguro?"
|
|
438
|
+
"ra_The schedule will be executed every minute. Are you sure?": "El cronograma se ejecutará cada minuto. ¿Estás seguro?",
|
|
439
|
+
"sc_dow": "Día",
|
|
440
|
+
"ra_Define CRON...": "Definir CRON...",
|
|
441
|
+
"ra_Sunday": "Domingo",
|
|
442
|
+
"ra_Monday": "Lunes",
|
|
443
|
+
"ra_Tuesday": "Martes",
|
|
444
|
+
"ra_Wednesday": "Miércoles",
|
|
445
|
+
"ra_Thursday": "Jueves",
|
|
446
|
+
"ra_Friday": "Viernes",
|
|
447
|
+
"ra_Saturday": "Sábado",
|
|
448
|
+
"sc_invalid_cron": "CRON no válido"
|
|
439
449
|
}
|
package/i18n/fr.json
CHANGED
|
@@ -435,5 +435,15 @@
|
|
|
435
435
|
"ra_warning_every_second": "Attention : la tâche CRON s’exécutera toutes les secondes pendant la période spécifiée !",
|
|
436
436
|
"ra_warning_every_minute": "Attention : la tâche CRON s’exécutera toutes les minutes pendant la période spécifiée !",
|
|
437
437
|
"ra_The schedule will be executed every second. Are you sure?": "Le planning sera exécuté toutes les secondes. Êtes-vous sûr ?",
|
|
438
|
-
"ra_The schedule will be executed every minute. Are you sure?": "Le planning sera exécuté toutes les minutes. Êtes-vous sûr ?"
|
|
438
|
+
"ra_The schedule will be executed every minute. Are you sure?": "Le planning sera exécuté toutes les minutes. Êtes-vous sûr ?",
|
|
439
|
+
"sc_dow": "Jour",
|
|
440
|
+
"ra_Define CRON...": "Définir CRON...",
|
|
441
|
+
"ra_Sunday": "Dimanche",
|
|
442
|
+
"ra_Monday": "Lundi",
|
|
443
|
+
"ra_Tuesday": "Mardi",
|
|
444
|
+
"ra_Wednesday": "Mercredi",
|
|
445
|
+
"ra_Thursday": "Jeudi",
|
|
446
|
+
"ra_Friday": "Vendredi",
|
|
447
|
+
"ra_Saturday": "Samedi",
|
|
448
|
+
"sc_invalid_cron": "CRON non valide"
|
|
439
449
|
}
|
package/i18n/it.json
CHANGED
|
@@ -435,5 +435,15 @@
|
|
|
435
435
|
"ra_warning_every_second": "Attenzione: il processo CRON verrà eseguito ogni secondo durante il periodo specificato!",
|
|
436
436
|
"ra_warning_every_minute": "Attenzione: il processo CRON verrà eseguito ogni minuto durante il periodo specificato!",
|
|
437
437
|
"ra_The schedule will be executed every second. Are you sure?": "La pianificazione verrà eseguita ogni secondo. Sei sicuro?",
|
|
438
|
-
"ra_The schedule will be executed every minute. Are you sure?": "La pianificazione verrà eseguita ogni minuto. Sei sicuro?"
|
|
438
|
+
"ra_The schedule will be executed every minute. Are you sure?": "La pianificazione verrà eseguita ogni minuto. Sei sicuro?",
|
|
439
|
+
"sc_dow": "Giorno",
|
|
440
|
+
"ra_Define CRON...": "Definisci CRON...",
|
|
441
|
+
"ra_Sunday": "Domenica",
|
|
442
|
+
"ra_Monday": "Lunedi",
|
|
443
|
+
"ra_Tuesday": "Martedì",
|
|
444
|
+
"ra_Wednesday": "Mercoledì",
|
|
445
|
+
"ra_Thursday": "Giovedì",
|
|
446
|
+
"ra_Friday": "Venerdì",
|
|
447
|
+
"ra_Saturday": "Sabato",
|
|
448
|
+
"sc_invalid_cron": "CRON non valido"
|
|
439
449
|
}
|
package/i18n/nl.json
CHANGED
|
@@ -435,5 +435,15 @@
|
|
|
435
435
|
"ra_warning_every_second": "Waarschuwing: De CRON-taak wordt elke seconde uitgevoerd gedurende de opgegeven periode!",
|
|
436
436
|
"ra_warning_every_minute": "Waarschuwing: De CRON-taak wordt elke minuut uitgevoerd gedurende de opgegeven periode!",
|
|
437
437
|
"ra_The schedule will be executed every second. Are you sure?": "Het schema wordt elke seconde uitgevoerd. Weet je het zeker?",
|
|
438
|
-
"ra_The schedule will be executed every minute. Are you sure?": "Het schema wordt elke minuut uitgevoerd. Weet u het zeker?"
|
|
438
|
+
"ra_The schedule will be executed every minute. Are you sure?": "Het schema wordt elke minuut uitgevoerd. Weet u het zeker?",
|
|
439
|
+
"sc_dow": "Dag",
|
|
440
|
+
"ra_Define CRON...": "Definieer CRON...",
|
|
441
|
+
"ra_Sunday": "Zondag",
|
|
442
|
+
"ra_Monday": "Maandag",
|
|
443
|
+
"ra_Tuesday": "Dinsdag",
|
|
444
|
+
"ra_Wednesday": "Woensdag",
|
|
445
|
+
"ra_Thursday": "Donderdag",
|
|
446
|
+
"ra_Friday": "Vrijdag",
|
|
447
|
+
"ra_Saturday": "Zaterdag",
|
|
448
|
+
"sc_invalid_cron": "Ongeldige CRON"
|
|
439
449
|
}
|
package/i18n/pl.json
CHANGED
|
@@ -435,5 +435,15 @@
|
|
|
435
435
|
"ra_warning_every_second": "Ostrzeżenie: Zadanie CRON będzie uruchamiane co sekundę w określonym przedziale czasowym!",
|
|
436
436
|
"ra_warning_every_minute": "Ostrzeżenie: Zadanie CRON będzie uruchamiane co minutę w określonym przedziale czasowym!",
|
|
437
437
|
"ra_The schedule will be executed every second. Are you sure?": "Harmonogram będzie wykonywany co sekundę. Czy jesteś pewien?",
|
|
438
|
-
"ra_The schedule will be executed every minute. Are you sure?": "Harmonogram będzie wykonywany co minutę. Czy jesteś pewien?"
|
|
438
|
+
"ra_The schedule will be executed every minute. Are you sure?": "Harmonogram będzie wykonywany co minutę. Czy jesteś pewien?",
|
|
439
|
+
"sc_dow": "Dzień",
|
|
440
|
+
"ra_Define CRON...": "Zdefiniuj CRON...",
|
|
441
|
+
"ra_Sunday": "Niedziela",
|
|
442
|
+
"ra_Monday": "Poniedziałek",
|
|
443
|
+
"ra_Tuesday": "Wtorek",
|
|
444
|
+
"ra_Wednesday": "Środa",
|
|
445
|
+
"ra_Thursday": "Czwartek",
|
|
446
|
+
"ra_Friday": "Piątek",
|
|
447
|
+
"ra_Saturday": "Sobota",
|
|
448
|
+
"sc_invalid_cron": "Nieprawidłowy CRON"
|
|
439
449
|
}
|
package/i18n/pt.json
CHANGED
|
@@ -435,5 +435,15 @@
|
|
|
435
435
|
"ra_warning_every_second": "Aviso: O trabalho CRON será executado a cada segundo durante o período especificado!",
|
|
436
436
|
"ra_warning_every_minute": "Aviso: O trabalho CRON será executado a cada minuto durante o período especificado!",
|
|
437
437
|
"ra_The schedule will be executed every second. Are you sure?": "O agendamento será executado a cada segundo. Tem certeza?",
|
|
438
|
-
"ra_The schedule will be executed every minute. Are you sure?": "O agendamento será executado a cada minuto. Tem certeza?"
|
|
438
|
+
"ra_The schedule will be executed every minute. Are you sure?": "O agendamento será executado a cada minuto. Tem certeza?",
|
|
439
|
+
"sc_dow": "Dia",
|
|
440
|
+
"ra_Define CRON...": "Defina CRON...",
|
|
441
|
+
"ra_Sunday": "Domingo",
|
|
442
|
+
"ra_Monday": "Segunda-feira",
|
|
443
|
+
"ra_Tuesday": "Terça-feira",
|
|
444
|
+
"ra_Wednesday": "Quarta-feira",
|
|
445
|
+
"ra_Thursday": "Quinta-feira",
|
|
446
|
+
"ra_Friday": "Sexta-feira",
|
|
447
|
+
"ra_Saturday": "Sábado",
|
|
448
|
+
"sc_invalid_cron": "CRON inválido"
|
|
439
449
|
}
|
package/i18n/ru.json
CHANGED
|
@@ -435,5 +435,15 @@
|
|
|
435
435
|
"ra_warning_every_second": "Внимание: задание CRON будет выполняться каждую секунду в течение указанного периода!",
|
|
436
436
|
"ra_warning_every_minute": "Внимание: задание CRON будет запускаться каждую минуту в течение указанного периода!",
|
|
437
437
|
"ra_The schedule will be executed every second. Are you sure?": "Расписание будет выполняться каждую секунду. Вы уверены?",
|
|
438
|
-
"ra_The schedule will be executed every minute. Are you sure?": "Расписание будет выполняться каждую минуту. Вы уверены?"
|
|
438
|
+
"ra_The schedule will be executed every minute. Are you sure?": "Расписание будет выполняться каждую минуту. Вы уверены?",
|
|
439
|
+
"sc_dow": "День",
|
|
440
|
+
"ra_Define CRON...": "Определите CRON...",
|
|
441
|
+
"ra_Sunday": "Воскресенье",
|
|
442
|
+
"ra_Monday": "Понедельник",
|
|
443
|
+
"ra_Tuesday": "Вторник",
|
|
444
|
+
"ra_Wednesday": "Среда",
|
|
445
|
+
"ra_Thursday": "Четверг",
|
|
446
|
+
"ra_Friday": "Пятница",
|
|
447
|
+
"ra_Saturday": "Суббота",
|
|
448
|
+
"sc_invalid_cron": "Неверный CRON"
|
|
439
449
|
}
|
package/i18n/uk.json
CHANGED
|
@@ -435,5 +435,15 @@
|
|
|
435
435
|
"ra_warning_every_second": "Попередження: завдання CRON виконуватиметься кожну секунду протягом зазначеного періоду!",
|
|
436
436
|
"ra_warning_every_minute": "Попередження: завдання CRON виконуватиметься щохвилини протягом зазначеного періоду!",
|
|
437
437
|
"ra_The schedule will be executed every second. Are you sure?": "Розклад буде виконуватися щосекунди. Ви впевнені?",
|
|
438
|
-
"ra_The schedule will be executed every minute. Are you sure?": "Розклад буде виконуватися щохвилини. Ви впевнені?"
|
|
438
|
+
"ra_The schedule will be executed every minute. Are you sure?": "Розклад буде виконуватися щохвилини. Ви впевнені?",
|
|
439
|
+
"sc_dow": "День",
|
|
440
|
+
"ra_Define CRON...": "Визначити CRON...",
|
|
441
|
+
"ra_Sunday": "неділя",
|
|
442
|
+
"ra_Monday": "понеділок",
|
|
443
|
+
"ra_Tuesday": "вівторок",
|
|
444
|
+
"ra_Wednesday": "Середа",
|
|
445
|
+
"ra_Thursday": "четвер",
|
|
446
|
+
"ra_Friday": "П'ятниця",
|
|
447
|
+
"ra_Saturday": "Субота",
|
|
448
|
+
"sc_invalid_cron": "Недійсний CRON"
|
|
439
449
|
}
|
package/i18n/zh-cn.json
CHANGED
|
@@ -435,5 +435,15 @@
|
|
|
435
435
|
"ra_warning_every_second": "警告:CRON 作业将在指定期间内每秒运行一次!",
|
|
436
436
|
"ra_warning_every_minute": "警告:CRON 作业将在指定期间内每分钟运行一次!",
|
|
437
437
|
"ra_The schedule will be executed every second. Are you sure?": "该计划将每秒执行一次。你确定吗?",
|
|
438
|
-
"ra_The schedule will be executed every minute. Are you sure?": "该计划将每分钟执行一次。您确定吗?"
|
|
438
|
+
"ra_The schedule will be executed every minute. Are you sure?": "该计划将每分钟执行一次。您确定吗?",
|
|
439
|
+
"sc_dow": "天",
|
|
440
|
+
"ra_Define CRON...": "定义 CRON...",
|
|
441
|
+
"ra_Sunday": "星期日",
|
|
442
|
+
"ra_Monday": "周一",
|
|
443
|
+
"ra_Tuesday": "周二",
|
|
444
|
+
"ra_Wednesday": "周三",
|
|
445
|
+
"ra_Thursday": "周四",
|
|
446
|
+
"ra_Friday": "星期五",
|
|
447
|
+
"ra_Saturday": "周六",
|
|
448
|
+
"sc_invalid_cron": "无效的 CRON"
|
|
439
449
|
}
|
package/icons/IconClosed.js
CHANGED
|
@@ -6,5 +6,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const react_1 = __importDefault(require("react"));
|
|
7
7
|
// Icon copied from https://github.com/FortAwesome/Font-Awesome/blob/0d1f27efb836eb2ab994ba37221849ed64a73e5c/svgs/regular/
|
|
8
8
|
const IconClosed = (props) => (react_1.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", onClick: e => props.onClick && props.onClick(e), viewBox: "0 0 650 512", width: props.width || (props.fontSize === 'small' ? 16 : 20), height: props.height || props.width || (props.fontSize === 'small' ? 16 : 20), className: props.className, style: props.style },
|
|
9
|
-
react_1.default.createElement("path", { fill: "currentColor", d: "
|
|
9
|
+
react_1.default.createElement("path", { fill: "currentColor", d: "m524,128l-192,0l-64,-64l-160,0c-26.51,0 -48,21.49 -48,48l0,288c0,26.51 21.49,48 48,48l416,0c26.51,0 48,-21.49 48,-48l0,-224c0,-26.51 -21.49,-48 -48,-48z" })));
|
|
10
10
|
exports.default = IconClosed;
|
package/icons/IconOpen.js
CHANGED
|
@@ -6,5 +6,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const react_1 = __importDefault(require("react"));
|
|
7
7
|
// Icon copied from https://github.com/FortAwesome/Font-Awesome/blob/0d1f27efb836eb2ab994ba37221849ed64a73e5c/svgs/regular/
|
|
8
8
|
const IconOpen = (props) => (react_1.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", onClick: e => props.onClick && props.onClick(e), viewBox: "0 0 650 512", width: props.width || (props.fontSize === 'small' ? 16 : 20), height: props.height || props.width || (props.fontSize === 'small' ? 16 : 20), className: props.className, style: props.style },
|
|
9
|
-
react_1.default.createElement("path", { fill: "currentColor", d: "
|
|
9
|
+
react_1.default.createElement("path", { fill: "currentColor", d: "m631.75617,292.093l-72.424,124.155a63.997,63.997 0 0 1 -55.281,31.752l-399.964,0c-18.523,0 -30.064,-20.093 -20.731,-36.093l72.424,-124.155a64,64 0 0 1 55.282,-31.752l399.964,0c18.523,0 30.064,20.093 20.73,36.093zm-420.694,-68.093l328,0l0,-48c0,-26.51 -21.49,-48 -48,-48l-160,0l-64,-64l-160,0c-26.51,0 -48,21.49 -48,48l0,278.046l69.077,-118.418c17.137,-29.378 48.912,-47.628 82.923,-47.628z" })));
|
|
10
10
|
exports.default = IconOpen;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iobroker/adapter-react-v5",
|
|
3
|
-
"version": "7.2.
|
|
3
|
+
"version": "7.2.4",
|
|
4
4
|
"description": "React classes to develop admin interfaces for ioBroker with react.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Denis Haev (bluefox)",
|
|
@@ -27,21 +27,22 @@
|
|
|
27
27
|
"homepage": "https://github.com/ioBroker/adapter-react-v5#readme",
|
|
28
28
|
"devDependencies": {},
|
|
29
29
|
"dependencies": {
|
|
30
|
+
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
|
30
31
|
"@emotion/react": "^11.13.3",
|
|
31
32
|
"@emotion/styled": "^11.13.0",
|
|
32
|
-
"@iobroker/socket-client": "^3.1.
|
|
33
|
+
"@iobroker/socket-client": "^3.1.1",
|
|
33
34
|
"@iobroker/types": "^6.0.11",
|
|
34
35
|
"@iobroker/js-controller-common": "^6.0.11",
|
|
35
36
|
"@iobroker/js-controller-common-db": "^6.0.11",
|
|
36
|
-
"@mui/icons-material": "^6.1.
|
|
37
|
-
"@mui/material": "^6.1.
|
|
38
|
-
"@mui/x-date-pickers": "^7.
|
|
39
|
-
"@sentry/browser": "^8.
|
|
37
|
+
"@mui/icons-material": "^6.1.2",
|
|
38
|
+
"@mui/material": "^6.1.2",
|
|
39
|
+
"@mui/x-date-pickers": "^7.19.0",
|
|
40
|
+
"@sentry/browser": "^8.33.1",
|
|
40
41
|
"cronstrue": "^2.50.0",
|
|
41
42
|
"react-color": "^2.19.3",
|
|
42
43
|
"react-colorful": "^5.6.1",
|
|
43
44
|
"react-cropper": "^2.3.3",
|
|
44
|
-
"react-dropzone": "^14.2.
|
|
45
|
+
"react-dropzone": "^14.2.9",
|
|
45
46
|
"react-icons": "^5.3.0",
|
|
46
47
|
"react-inlinesvg": "^4.1.3"
|
|
47
48
|
}
|
|
@@ -13,7 +13,7 @@ const styles: Record<string, React.CSSProperties> = {
|
|
|
13
13
|
periodSelect: {
|
|
14
14
|
// margin: '0 10px 60px 10px',
|
|
15
15
|
display: 'block',
|
|
16
|
-
width:
|
|
16
|
+
width: 250,
|
|
17
17
|
},
|
|
18
18
|
slider: {
|
|
19
19
|
marginTop: 20,
|
|
@@ -479,7 +479,7 @@ class ComplexCron extends Component<ComplexCronProps, ComplexCronState> {
|
|
|
479
479
|
|
|
480
480
|
return (
|
|
481
481
|
<div style={styles.mainDiv}>
|
|
482
|
-
<div style={{ paddingLeft: 8, width: '100%' }}>
|
|
482
|
+
<div style={{ paddingLeft: 8, width: 'calc(100% - px)' }}>
|
|
483
483
|
<TextField
|
|
484
484
|
variant="standard"
|
|
485
485
|
style={{ width: '100%' }}
|
|
@@ -487,7 +487,7 @@ class ComplexCron extends Component<ComplexCronProps, ComplexCronState> {
|
|
|
487
487
|
disabled
|
|
488
488
|
/>
|
|
489
489
|
</div>
|
|
490
|
-
<div style={{ paddingLeft: 8, width: '100%', height: 60 }}>
|
|
490
|
+
<div style={{ paddingLeft: 8, width: 'calc(100% - px)', height: 60 }}>
|
|
491
491
|
{ComplexCron.convertCronToText(this.state.cron, this.props.language || 'en')}
|
|
492
492
|
<span style={styles.warning}>
|
|
493
493
|
{everySecond
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* MIT License
|
|
5
5
|
*
|
|
6
6
|
*/
|
|
7
|
-
import React, { Component } from 'react';
|
|
7
|
+
import React, { Component, type JSX } from 'react';
|
|
8
8
|
import Dropzone from 'react-dropzone';
|
|
9
9
|
|
|
10
10
|
import {
|
|
@@ -102,9 +102,6 @@ const FILE_TYPE_ICONS: Record<string, React.FC<{ fontSize?: 'small' }>> = {
|
|
|
102
102
|
};
|
|
103
103
|
|
|
104
104
|
const styles: Record<string, any> = {
|
|
105
|
-
dialog: (theme: IobTheme) => ({
|
|
106
|
-
height: `calc(100% - ${theme.mixins.toolbar.minHeight}px)`,
|
|
107
|
-
}),
|
|
108
105
|
root: {
|
|
109
106
|
width: '100%',
|
|
110
107
|
overflow: 'hidden',
|
|
@@ -147,7 +144,8 @@ const styles: Record<string, any> = {
|
|
|
147
144
|
textAlign: 'center',
|
|
148
145
|
opacity: 0.1,
|
|
149
146
|
transition: 'opacity 1s',
|
|
150
|
-
margin:
|
|
147
|
+
margin: '4px',
|
|
148
|
+
borderRadius: '4px',
|
|
151
149
|
'&:hover': {
|
|
152
150
|
background: theme.palette.secondary.light,
|
|
153
151
|
color: Utils.invertColor(theme.palette.secondary.main, true),
|
|
@@ -270,8 +268,8 @@ const styles: Record<string, any> = {
|
|
|
270
268
|
opacity: 0.4,
|
|
271
269
|
},
|
|
272
270
|
itemFolderIconTable: (theme: IobTheme) => ({
|
|
273
|
-
marginTop:
|
|
274
|
-
marginLeft:
|
|
271
|
+
marginTop: '1px',
|
|
272
|
+
marginLeft: '8px',
|
|
275
273
|
display: 'inline-block',
|
|
276
274
|
width: 30,
|
|
277
275
|
height: 30,
|
|
@@ -406,6 +404,9 @@ const styles: Record<string, any> = {
|
|
|
406
404
|
background: theme.palette.primary.main,
|
|
407
405
|
},
|
|
408
406
|
}),
|
|
407
|
+
pathDivBreadcrumbSelected: {
|
|
408
|
+
// todo: add style
|
|
409
|
+
},
|
|
409
410
|
backgroundImageLight: {
|
|
410
411
|
background: 'white',
|
|
411
412
|
},
|
|
@@ -500,7 +501,7 @@ export interface FileBrowserProps {
|
|
|
500
501
|
|
|
501
502
|
restrictToFolder?: string;
|
|
502
503
|
|
|
503
|
-
modalEditOfAccessControl?: (obj: FileBrowserClass) =>
|
|
504
|
+
modalEditOfAccessControl?: (obj: FileBrowserClass) => JSX.Element | null;
|
|
504
505
|
|
|
505
506
|
allowNonRestricted?: boolean;
|
|
506
507
|
|
|
@@ -1026,7 +1027,17 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
1026
1027
|
const relPath = parts.join('/');
|
|
1027
1028
|
|
|
1028
1029
|
// make all requests here serial
|
|
1029
|
-
|
|
1030
|
+
let files: ioBroker.ReadDirResult[];
|
|
1031
|
+
try {
|
|
1032
|
+
files = await this.readDirSerial(adapter || '', relPath);
|
|
1033
|
+
} catch (error: unknown) {
|
|
1034
|
+
// work around: 0_userdata.0 is a special folder, that should exist event when other folders and itself do not exit, as the browser shows it anyway.
|
|
1035
|
+
if (error === 'Not exists' && adapter === '0_userdata.0') {
|
|
1036
|
+
files = [];
|
|
1037
|
+
} else {
|
|
1038
|
+
throw error;
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1030
1041
|
try {
|
|
1031
1042
|
const _folders: FolderOrFileItem[] = [];
|
|
1032
1043
|
|
|
@@ -1090,7 +1101,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
1090
1101
|
return newFoldersNotNull;
|
|
1091
1102
|
}
|
|
1092
1103
|
|
|
1093
|
-
toggleFolder(item: FolderOrFileItem, e: React.MouseEvent
|
|
1104
|
+
toggleFolder(item: FolderOrFileItem, e: React.MouseEvent): void {
|
|
1094
1105
|
e?.stopPropagation();
|
|
1095
1106
|
const expanded = [...this.state.expanded];
|
|
1096
1107
|
const pos = expanded.indexOf(item.id);
|
|
@@ -1142,9 +1153,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
1142
1153
|
};
|
|
1143
1154
|
|
|
1144
1155
|
changeFolder(e: React.MouseEvent<HTMLDivElement>, folder?: string): void {
|
|
1145
|
-
|
|
1146
|
-
e.stopPropagation();
|
|
1147
|
-
}
|
|
1156
|
+
e?.stopPropagation();
|
|
1148
1157
|
|
|
1149
1158
|
this.lastSelect = Date.now();
|
|
1150
1159
|
|
|
@@ -1157,9 +1166,11 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
1157
1166
|
this.localStorage.setItem('files.currentDir', _folder);
|
|
1158
1167
|
|
|
1159
1168
|
if (folder && e && (e.altKey || e.shiftKey || e.ctrlKey || e.metaKey)) {
|
|
1160
|
-
|
|
1169
|
+
this.setState({ selected: _folder });
|
|
1170
|
+
return;
|
|
1161
1171
|
}
|
|
1162
1172
|
|
|
1173
|
+
// If desired folder is not yet loaded
|
|
1163
1174
|
if (_folder && !this.state.folders[_folder]) {
|
|
1164
1175
|
this.browseFolder(_folder)
|
|
1165
1176
|
.then(folders =>
|
|
@@ -1178,7 +1189,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
1178
1189
|
return;
|
|
1179
1190
|
}
|
|
1180
1191
|
|
|
1181
|
-
|
|
1192
|
+
this.setState(
|
|
1182
1193
|
{
|
|
1183
1194
|
currentDir: _folder,
|
|
1184
1195
|
selected: _folder,
|
|
@@ -1226,7 +1237,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
1226
1237
|
return undefined;
|
|
1227
1238
|
}
|
|
1228
1239
|
|
|
1229
|
-
renderFolder(item: FolderOrFileItem, expanded?: boolean):
|
|
1240
|
+
renderFolder(item: FolderOrFileItem, expanded?: boolean): JSX.Element | null {
|
|
1230
1241
|
if (
|
|
1231
1242
|
this.state.viewType === TABLE &&
|
|
1232
1243
|
this.state.filterEmpty &&
|
|
@@ -1241,6 +1252,11 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
1241
1252
|
const isUserData = item.name === USER_DATA;
|
|
1242
1253
|
const isSpecialData = isUserData || item.name === 'vis.0' || item.name === 'vis-2.0';
|
|
1243
1254
|
|
|
1255
|
+
const iconStyle = Utils.getStyle(
|
|
1256
|
+
this.props.theme,
|
|
1257
|
+
styles[`itemFolderIcon${this.state.viewType}`],
|
|
1258
|
+
isSpecialData && styles.specialFolder,
|
|
1259
|
+
);
|
|
1244
1260
|
return (
|
|
1245
1261
|
<Box
|
|
1246
1262
|
component="div"
|
|
@@ -1260,15 +1276,9 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
1260
1276
|
)}
|
|
1261
1277
|
>
|
|
1262
1278
|
<IconEl
|
|
1263
|
-
style={
|
|
1264
|
-
this.props.theme,
|
|
1265
|
-
styles[`itemFolderIcon${this.state.viewType}`],
|
|
1266
|
-
isSpecialData && styles.specialFolder,
|
|
1267
|
-
)}
|
|
1279
|
+
style={iconStyle}
|
|
1268
1280
|
onClick={
|
|
1269
|
-
this.state.viewType === TABLE
|
|
1270
|
-
? (e: React.MouseEvent<Element>) => this.toggleFolder(item, e)
|
|
1271
|
-
: undefined
|
|
1281
|
+
this.state.viewType === TABLE ? (e: React.MouseEvent) => this.toggleFolder(item, e) : undefined
|
|
1272
1282
|
}
|
|
1273
1283
|
/>
|
|
1274
1284
|
|
|
@@ -1340,7 +1350,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
1340
1350
|
);
|
|
1341
1351
|
}
|
|
1342
1352
|
|
|
1343
|
-
renderBackFolder():
|
|
1353
|
+
renderBackFolder(): JSX.Element {
|
|
1344
1354
|
return (
|
|
1345
1355
|
<Box
|
|
1346
1356
|
component="div"
|
|
@@ -1355,7 +1365,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
1355
1365
|
styles[`itemFolder${this.state.viewType}`],
|
|
1356
1366
|
)}
|
|
1357
1367
|
>
|
|
1358
|
-
<IconClosed style={styles[`itemFolderIcon${this.state.viewType}`]} />
|
|
1368
|
+
<IconClosed style={Utils.getStyle(this.props.theme, styles[`itemFolderIcon${this.state.viewType}`])} />
|
|
1359
1369
|
<IconBack sx={styles.itemFolderIconBack} />
|
|
1360
1370
|
|
|
1361
1371
|
<Box
|
|
@@ -1372,7 +1382,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
1372
1382
|
);
|
|
1373
1383
|
}
|
|
1374
1384
|
|
|
1375
|
-
formatSize(size: number | null | undefined):
|
|
1385
|
+
formatSize(size: number | null | undefined): JSX.Element {
|
|
1376
1386
|
return (
|
|
1377
1387
|
<div style={styles[`itemSize${this.state.viewType}`]}>
|
|
1378
1388
|
{size || size === 0 ? Utils.formatBytes(size) : ''}
|
|
@@ -1380,7 +1390,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
1380
1390
|
);
|
|
1381
1391
|
}
|
|
1382
1392
|
|
|
1383
|
-
formatAcl(acl: ioBroker.EvaluatedFileACL | MetaACL | undefined):
|
|
1393
|
+
formatAcl(acl: ioBroker.EvaluatedFileACL | MetaACL | undefined): JSX.Element {
|
|
1384
1394
|
const access: number = acl ? (acl as ioBroker.EvaluatedFileACL).permissions || (acl as MetaACL).file : 0;
|
|
1385
1395
|
let accessStr: string;
|
|
1386
1396
|
if (access) {
|
|
@@ -1406,7 +1416,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
1406
1416
|
);
|
|
1407
1417
|
}
|
|
1408
1418
|
|
|
1409
|
-
getFileIcon(ext: string | null):
|
|
1419
|
+
getFileIcon(ext: string | null): JSX.Element {
|
|
1410
1420
|
switch (ext) {
|
|
1411
1421
|
case 'json':
|
|
1412
1422
|
case 'json5':
|
|
@@ -1483,7 +1493,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
1483
1493
|
}
|
|
1484
1494
|
};
|
|
1485
1495
|
|
|
1486
|
-
renderFile(item: FolderOrFileItem):
|
|
1496
|
+
renderFile(item: FolderOrFileItem): JSX.Element {
|
|
1487
1497
|
const padding = this.state.viewType === TABLE ? item.level * this.levelPadding : 0;
|
|
1488
1498
|
const ext = Utils.getFileExtension(item.name);
|
|
1489
1499
|
|
|
@@ -1639,11 +1649,11 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
1639
1649
|
);
|
|
1640
1650
|
}
|
|
1641
1651
|
|
|
1642
|
-
renderItems(folderId: string):
|
|
1652
|
+
renderItems(folderId: string): JSX.Element | (JSX.Element | null)[] {
|
|
1643
1653
|
if (this.state.folders && this.state.folders[folderId]) {
|
|
1644
1654
|
// tile
|
|
1645
1655
|
if (this.state.viewType === TILE) {
|
|
1646
|
-
const res: (
|
|
1656
|
+
const res: (JSX.Element | null)[] = [];
|
|
1647
1657
|
if (folderId && folderId !== '/') {
|
|
1648
1658
|
res.push(this.renderBackFolder());
|
|
1649
1659
|
}
|
|
@@ -1662,7 +1672,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
1662
1672
|
return res;
|
|
1663
1673
|
}
|
|
1664
1674
|
|
|
1665
|
-
const totalResult: (
|
|
1675
|
+
const totalResult: (JSX.Element | null)[] = [];
|
|
1666
1676
|
this.state.folders[folderId].forEach(item => {
|
|
1667
1677
|
if (item.folder) {
|
|
1668
1678
|
const expanded = this.state.expanded.includes(item.id);
|
|
@@ -1716,7 +1726,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
1716
1726
|
);
|
|
1717
1727
|
}
|
|
1718
1728
|
|
|
1719
|
-
renderToolbar():
|
|
1729
|
+
renderToolbar(): JSX.Element {
|
|
1720
1730
|
const IconType: React.FC<{ fontSize?: 'small' }> | null = this.props.showTypeSelector
|
|
1721
1731
|
? FILE_TYPE_ICONS[this.state.filterByType || 'all'] || FILE_TYPE_ICONS.all
|
|
1722
1732
|
: null;
|
|
@@ -1965,7 +1975,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
1965
1975
|
return folders[parentFolder].find(item => item.id === id) || null;
|
|
1966
1976
|
}
|
|
1967
1977
|
|
|
1968
|
-
renderInputDialog():
|
|
1978
|
+
renderInputDialog(): JSX.Element | null {
|
|
1969
1979
|
if (this.state.addFolder) {
|
|
1970
1980
|
const parentFolder = this.findFirstFolder(this.state.selected);
|
|
1971
1981
|
|
|
@@ -2074,7 +2084,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
2074
2084
|
}
|
|
2075
2085
|
}
|
|
2076
2086
|
|
|
2077
|
-
renderUpload():
|
|
2087
|
+
renderUpload(): JSX.Element[] | null {
|
|
2078
2088
|
if (this.state.uploadFile) {
|
|
2079
2089
|
return [
|
|
2080
2090
|
<Fab
|
|
@@ -2274,7 +2284,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
2274
2284
|
);
|
|
2275
2285
|
}
|
|
2276
2286
|
|
|
2277
|
-
renderDeleteDialog():
|
|
2287
|
+
renderDeleteDialog(): JSX.Element | null {
|
|
2278
2288
|
if (this.state.deleteItem) {
|
|
2279
2289
|
return (
|
|
2280
2290
|
<Dialog
|
|
@@ -2322,7 +2332,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
2322
2332
|
return null;
|
|
2323
2333
|
}
|
|
2324
2334
|
|
|
2325
|
-
renderViewDialog():
|
|
2335
|
+
renderViewDialog(): JSX.Element | null {
|
|
2326
2336
|
return this.state.viewer ? (
|
|
2327
2337
|
<FileViewer
|
|
2328
2338
|
supportSubscribes={this.supportSubscribes}
|
|
@@ -2341,7 +2351,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
2341
2351
|
) : null;
|
|
2342
2352
|
}
|
|
2343
2353
|
|
|
2344
|
-
renderError():
|
|
2354
|
+
renderError(): JSX.Element | null {
|
|
2345
2355
|
if (this.state.errorText) {
|
|
2346
2356
|
return (
|
|
2347
2357
|
<ErrorDialog
|
|
@@ -2415,7 +2425,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
2415
2425
|
}, 100);
|
|
2416
2426
|
}
|
|
2417
2427
|
|
|
2418
|
-
renderBreadcrumb():
|
|
2428
|
+
renderBreadcrumb(): JSX.Element {
|
|
2419
2429
|
const parts = this.state.currentDir.startsWith('/')
|
|
2420
2430
|
? this.state.currentDir.split('/')
|
|
2421
2431
|
: `/${this.state.currentDir}`.split('/');
|
|
@@ -2454,7 +2464,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
2454
2464
|
);
|
|
2455
2465
|
}
|
|
2456
2466
|
|
|
2457
|
-
renderPath():
|
|
2467
|
+
renderPath(): JSX.Element {
|
|
2458
2468
|
return (
|
|
2459
2469
|
<Box
|
|
2460
2470
|
component="div"
|
|
@@ -2490,7 +2500,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
2490
2500
|
);
|
|
2491
2501
|
}
|
|
2492
2502
|
|
|
2493
|
-
render():
|
|
2503
|
+
render(): JSX.Element {
|
|
2494
2504
|
if (!this.props.ready) {
|
|
2495
2505
|
return <LinearProgress />;
|
|
2496
2506
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// File viewer in adapter-react does not support write
|
|
2
2
|
// import { Buffer } from 'buffer';
|
|
3
|
-
import React, { Component } from 'react';
|
|
3
|
+
import React, { Component, type JSX } from 'react';
|
|
4
4
|
|
|
5
5
|
import { TextField, Button, Dialog, DialogActions, DialogContent, DialogTitle, IconButton } from '@mui/material';
|
|
6
6
|
|
|
@@ -338,7 +338,7 @@ class FileViewer extends Component<FileViewerProps, FileViewerState> {
|
|
|
338
338
|
return null;
|
|
339
339
|
}
|
|
340
340
|
|
|
341
|
-
render():
|
|
341
|
+
render(): JSX.Element {
|
|
342
342
|
return (
|
|
343
343
|
<Dialog
|
|
344
344
|
sx={{
|