cmdbox 0.5.3.1__py3-none-any.whl → 0.6.0__py3-none-any.whl
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.
Potentially problematic release.
This version of cmdbox might be problematic. Click here for more details.
- cmdbox/app/auth/__init__.py +0 -0
- cmdbox/app/auth/azure_signin.py +38 -0
- cmdbox/app/auth/azure_signin_saml.py +12 -0
- cmdbox/app/auth/github_signin.py +38 -0
- cmdbox/app/auth/google_signin.py +32 -0
- cmdbox/app/auth/signin.py +490 -287
- cmdbox/app/auth/signin_saml.py +61 -0
- cmdbox/app/common.py +48 -3
- cmdbox/app/edge.py +182 -213
- cmdbox/app/edge_tool.py +177 -0
- cmdbox/app/feature.py +10 -10
- cmdbox/app/features/cli/agent_base.py +477 -0
- cmdbox/app/features/cli/audit_base.py +1 -1
- cmdbox/app/features/cli/cmdbox_audit_search.py +24 -1
- cmdbox/app/features/cli/cmdbox_client_file_download.py +1 -1
- cmdbox/app/features/cli/cmdbox_cmd_list.py +105 -0
- cmdbox/app/features/cli/cmdbox_cmd_load.py +104 -0
- cmdbox/app/features/cli/cmdbox_edge_config.py +21 -7
- cmdbox/app/features/cli/cmdbox_edge_start.py +1 -1
- cmdbox/app/features/cli/cmdbox_gui_start.py +9 -132
- cmdbox/app/features/cli/cmdbox_gui_stop.py +4 -21
- cmdbox/app/features/cli/cmdbox_server_start.py +1 -1
- cmdbox/app/features/cli/cmdbox_web_apikey_add.py +1 -1
- cmdbox/app/features/cli/cmdbox_web_apikey_del.py +1 -1
- cmdbox/app/features/cli/cmdbox_web_genpass.py +0 -3
- cmdbox/app/features/cli/cmdbox_web_group_add.py +1 -1
- cmdbox/app/features/cli/cmdbox_web_group_del.py +1 -1
- cmdbox/app/features/cli/cmdbox_web_group_edit.py +1 -1
- cmdbox/app/features/cli/cmdbox_web_group_list.py +1 -1
- cmdbox/app/features/cli/cmdbox_web_start.py +119 -104
- cmdbox/app/features/cli/cmdbox_web_stop.py +1 -1
- cmdbox/app/features/cli/cmdbox_web_user_add.py +4 -4
- cmdbox/app/features/cli/cmdbox_web_user_del.py +1 -1
- cmdbox/app/features/cli/cmdbox_web_user_edit.py +4 -4
- cmdbox/app/features/cli/cmdbox_web_user_list.py +1 -1
- cmdbox/app/features/web/cmdbox_web_agent.py +250 -0
- cmdbox/app/features/web/cmdbox_web_do_signin.py +79 -103
- cmdbox/app/features/web/cmdbox_web_exec_cmd.py +8 -3
- cmdbox/app/features/web/cmdbox_web_signin.py +26 -4
- cmdbox/app/features/web/cmdbox_web_users.py +2 -0
- cmdbox/app/options.py +55 -2
- cmdbox/app/web.py +155 -27
- cmdbox/extensions/features.yml +18 -0
- cmdbox/extensions/sample_project/sample/app/features/cli/__init__.py +0 -0
- cmdbox/extensions/sample_project/sample/app/features/web/__init__.py +0 -0
- cmdbox/extensions/sample_project/sample/extensions/features.yml +23 -0
- cmdbox/extensions/sample_project/sample/extensions/user_list.yml +40 -6
- cmdbox/extensions/user_list.yml +37 -6
- cmdbox/licenses/{LICENSE.starlette.0.41.3(BSD License).txt → LICENSE.Authlib.1.5.2(BSD License).txt } +3 -1
- cmdbox/licenses/{LICENSE.pydantic_core.2.33.0(MIT License).txt → LICENSE.Deprecated.1.2.18(MIT License).txt } +2 -2
- cmdbox/licenses/{LICENSE.more-itertools.10.6.0(MIT License).txt → LICENSE.SQLAlchemy.2.0.40(MIT License).txt } +1 -1
- cmdbox/licenses/LICENSE.aiohttp.3.11.18(Apache Software License).txt +13 -0
- cmdbox/licenses/LICENSE.aiosignal.1.3.2(Apache Software License).txt +201 -0
- cmdbox/licenses/LICENSE.async-timeout.5.0.1(Apache Software License).txt +13 -0
- cmdbox/licenses/{LICENSE.watchfiles.1.0.0(MIT License).txt → LICENSE.attrs.25.3.0(UNKNOWN).txt} +1 -1
- cmdbox/licenses/{LICENSE.anyio.4.6.2.post1(MIT License).txt → LICENSE.cachetools.5.5.2(MIT License).txt } +1 -1
- cmdbox/licenses/LICENSE.distro.1.9.0(Apache Software License).txt +202 -0
- cmdbox/licenses/{LICENSE.pydantic_core.2.33.1(MIT License).txt → LICENSE.docstring_parser.0.16(MIT License).txt } +1 -1
- cmdbox/licenses/LICENSE.filelock.3.18.0(The Unlicense (Unlicense)).txt +24 -0
- cmdbox/licenses/LICENSE.frozenlist.1.6.0(Apache-2.0).txt +201 -0
- cmdbox/licenses/{LICENSE.starlette.0.46.1(BSD License).txt → LICENSE.fsspec.2025.3.2(BSD License).txt } +3 -1
- cmdbox/licenses/{LICENSE.argcomplete.3.6.1(Apache Software License).txt → LICENSE.google-adk.0.5.0(Apache Software License).txt } +25 -0
- cmdbox/licenses/LICENSE.google-api-python-client.2.169.0(Apache Software License).txt +201 -0
- cmdbox/licenses/LICENSE.google-auth-httplib2.0.2.0(Apache Software License).txt +201 -0
- cmdbox/licenses/LICENSE.google-auth.2.40.1(Apache Software License).txt +201 -0
- cmdbox/licenses/LICENSE.google-cloud-aiplatform.1.92.0(Apache 2.0).txt +202 -0
- cmdbox/licenses/LICENSE.google-cloud-bigquery.3.31.0(Apache Software License).txt +202 -0
- cmdbox/licenses/LICENSE.google-cloud-core.2.4.3(Apache Software License).txt +202 -0
- cmdbox/licenses/LICENSE.google-cloud-resource-manager.1.14.2(Apache Software License).txt +202 -0
- cmdbox/licenses/LICENSE.google-cloud-secret-manager.2.23.3(Apache Software License).txt +202 -0
- cmdbox/licenses/LICENSE.google-cloud-speech.2.32.0(Apache Software License).txt +202 -0
- cmdbox/licenses/LICENSE.google-cloud-storage.2.19.0(Apache Software License).txt +202 -0
- cmdbox/licenses/LICENSE.google-cloud-trace.1.16.1(Apache Software License).txt +202 -0
- cmdbox/licenses/LICENSE.google-crc32c.1.7.1(Apache 2.0).txt +202 -0
- cmdbox/licenses/LICENSE.google-genai.1.14.0(Apache Software License).txt +202 -0
- cmdbox/licenses/LICENSE.google-resumable-media.2.7.2(Apache Software License).txt +202 -0
- cmdbox/licenses/LICENSE.googleapis-common-protos.1.70.0(Apache Software License).txt +202 -0
- cmdbox/licenses/{LICENSE.fastapi.0.115.5(MIT License).txt → LICENSE.graphviz.0.20.3(MIT License).txt } +1 -1
- cmdbox/licenses/LICENSE.grpc-google-iam-v1.0.14.2(Apache Software License).txt +202 -0
- cmdbox/licenses/LICENSE.grpcio-status.1.71.0(Apache Software License).txt +610 -0
- cmdbox/licenses/LICENSE.grpcio.1.71.0(Apache Software License).txt +610 -0
- cmdbox/licenses/{LICENSE.uvicorn.0.34.0(BSD License).txt → LICENSE.httpcore.1.0.9(BSD License).txt } +1 -1
- cmdbox/licenses/LICENSE.httplib2.0.22.0(MIT License).txt +23 -0
- cmdbox/licenses/{LICENSE.tomli.2.1.0(MIT License).txt → LICENSE.httpx-sse.0.4.0(MIT).txt} +1 -1
- cmdbox/licenses/LICENSE.httpx.0.28.1(BSD License).txt +12 -0
- cmdbox/licenses/LICENSE.huggingface-hub.0.31.1(Apache Software License).txt +201 -0
- cmdbox/licenses/{LICENSE.charset-normalizer.3.4.0(MIT License).txt → LICENSE.jsonschema-specifications.2025.4.1(UNKNOWN).txt} +5 -7
- cmdbox/licenses/LICENSE.jsonschema.4.23.0(MIT License).txt +19 -0
- cmdbox/licenses/{LICENSE.pkginfo.1.10.0(MIT License).txt → LICENSE.litellm.1.69.0(MIT License).txt } +6 -1
- cmdbox/licenses/{LICENSE.redis.5.2.1(MIT License).txt → LICENSE.mcp.1.8.0(MIT License).txt } +1 -1
- cmdbox/licenses/LICENSE.multidict.6.4.3(Apache Software License).txt +13 -0
- cmdbox/licenses/{LICENSE.argcomplete.3.5.1(Apache Software License).txt → LICENSE.openai.1.75.0(Apache Software License).txt } +25 -1
- cmdbox/licenses/LICENSE.opentelemetry-api.1.33.0(Apache Software License).txt +201 -0
- cmdbox/licenses/LICENSE.opentelemetry-exporter-gcp-trace.1.9.0(Apache Software License).txt +201 -0
- cmdbox/licenses/LICENSE.opentelemetry-resourcedetector-gcp.1.9.0a0(Apache Software License).txt +201 -0
- cmdbox/licenses/LICENSE.opentelemetry-sdk.1.33.0(Apache Software License).txt +201 -0
- cmdbox/licenses/LICENSE.opentelemetry-semantic-conventions.0.54b0(Apache Software License).txt +201 -0
- cmdbox/licenses/LICENSE.propcache.0.3.1(Apache Software License).txt +202 -0
- cmdbox/licenses/LICENSE.proto-plus.1.26.1(Apache Software License).txt +202 -0
- cmdbox/licenses/{LICENSE.Pygments.2.18.0(BSD License).txt → LICENSE.protobuf.5.29.4(3-Clause BSD License).txt } +15 -8
- cmdbox/licenses/LICENSE.pyasn1.0.6.1(BSD License).txt +24 -0
- cmdbox/licenses/LICENSE.pyasn1_modules.0.4.2(BSD License).txt +24 -0
- cmdbox/licenses/LICENSE.pydantic-settings.2.9.1(MIT License).txt +21 -0
- cmdbox/licenses/{LICENSE.gevent.25.4.1(MIT).txt → LICENSE.pyparsing.3.2.3(MIT License).txt } +5 -12
- cmdbox/licenses/LICENSE.python-dateutil.2.9.0.post0(Apache Software License; BSD License).txt +54 -0
- cmdbox/licenses/LICENSE.referencing.0.36.2(UNKNOWN).txt +19 -0
- cmdbox/licenses/LICENSE.regex.2024.11.6(Apache Software License).txt +208 -0
- cmdbox/licenses/LICENSE.rpds-py.0.24.0(MIT).txt +19 -0
- cmdbox/licenses/{LICENSE.python-multipart.0.0.17(Apache Software License).txt → LICENSE.rsa.4.9.1(Apache Software License).txt } +1 -2
- cmdbox/licenses/{LICENSE.sphinx-intl.2.3.0(BSD License).txt → LICENSE.shapely.2.1.0(BSD License).txt } +6 -2
- cmdbox/licenses/LICENSE.sse-starlette.2.3.4(BSD License).txt +27 -0
- cmdbox/licenses/LICENSE.tiktoken.0.9.0(MIT License).txt +21 -0
- cmdbox/licenses/LICENSE.tokenizers.0.21.1(Apache Software License).txt +1 -0
- cmdbox/licenses/{LICENSE.six.1.16.0(MIT License).txt → LICENSE.tqdm.4.67.1(MIT License; Mozilla Public License 2.0 (MPL 2.0)).txt } +32 -1
- cmdbox/licenses/{LICENSE.rich.13.9.4(MIT License).txt → LICENSE.tzlocal.5.3.1(MIT License).txt } +3 -3
- cmdbox/licenses/LICENSE.uritemplate.4.1.1(Apache Software License; BSD License).txt +3 -0
- cmdbox/licenses/LICENSE.wrapt.1.17.2(BSD License).txt +24 -0
- cmdbox/licenses/LICENSE.yarl.1.20.0(Apache Software License).txt +202 -0
- cmdbox/licenses/files.txt +111 -17
- cmdbox/logconf_agent.yml +38 -0
- cmdbox/logconf_audit.yml +13 -5
- cmdbox/logconf_client.yml +13 -5
- cmdbox/logconf_cmdbox.yml +13 -5
- cmdbox/logconf_edge.yml +13 -5
- cmdbox/logconf_gui.yml +13 -5
- cmdbox/logconf_server.yml +13 -5
- cmdbox/logconf_web.yml +13 -5
- cmdbox/version.py +3 -2
- cmdbox/web/agent.html +263 -0
- cmdbox/web/assets/cmdbox/agent.js +335 -0
- cmdbox/web/assets/cmdbox/common.js +1111 -1020
- cmdbox/web/assets/cmdbox/signin.js +16 -3
- cmdbox/web/assets/cmdbox/users.js +1 -1
- cmdbox/web/assets/filer/filer.js +4 -2
- cmdbox/web/signin.html +10 -6
- {cmdbox-0.5.3.1.dist-info → cmdbox-0.6.0.dist-info}/METADATA +132 -35
- {cmdbox-0.5.3.1.dist-info → cmdbox-0.6.0.dist-info}/RECORD +161 -123
- cmdbox/app/features/web/cmdbox_web_load_pin.py +0 -43
- cmdbox/app/features/web/cmdbox_web_save_pin.py +0 -42
- cmdbox/licenses/LICENSE.Jinja2.3.1.4(BSD License).txt +0 -28
- cmdbox/licenses/LICENSE.Sphinx.8.1.3(BSD License).txt +0 -31
- cmdbox/licenses/LICENSE.babel.2.16.0(BSD License).txt +0 -27
- cmdbox/licenses/LICENSE.certifi.2025.1.31(Mozilla Public License 2.0 (MPL 2.0)).txt +0 -20
- cmdbox/licenses/LICENSE.click.8.1.8(BSD License).txt +0 -28
- cmdbox/licenses/LICENSE.cryptography.44.0.2(Apache Software License; BSD License).txt +0 -3
- cmdbox/licenses/LICENSE.greenlet.3.2.0(MIT AND Python-2.0).txt +0 -30
- cmdbox/licenses/LICENSE.keyring.25.5.0(MIT License).txt +0 -17
- cmdbox/licenses/LICENSE.numpy.2.2.4(BSD License).txt +0 -950
- cmdbox/licenses/LICENSE.pillow.11.0.0(CMU License (MIT-CMU)).txt +0 -1226
- cmdbox/licenses/LICENSE.pillow.11.1.0(CMU License (MIT-CMU)).txt +0 -1213
- cmdbox/licenses/LICENSE.prettytable.3.12.0(BSD License).txt +0 -30
- cmdbox/licenses/LICENSE.prompt_toolkit.3.0.50(BSD License).txt +0 -27
- cmdbox/licenses/LICENSE.psycopg.3.2.6(GNU Lesser General Public License v3 (LGPLv3)).txt +0 -165
- cmdbox/licenses/LICENSE.pydantic.2.11.1(MIT License).txt +0 -21
- cmdbox/licenses/LICENSE.pydantic.2.11.3(MIT License).txt +0 -21
- cmdbox/licenses/LICENSE.python-dotenv.1.0.1(BSD License).txt +0 -27
- cmdbox/licenses/LICENSE.twine.5.1.1(Apache Software License).txt +0 -174
- cmdbox/licenses/LICENSE.typing_extensions.4.13.0(UNKNOWN).txt +0 -279
- cmdbox/licenses/LICENSE.urllib3.2.2.3(MIT License).txt +0 -21
- cmdbox/licenses/LICENSE.urllib3.2.3.0(MIT License).txt +0 -21
- cmdbox/licenses/LICENSE.uvicorn.0.34.1(BSD License).txt +0 -27
- cmdbox/licenses/LICENSE.watchfiles.1.0.4(MIT License).txt +0 -21
- cmdbox/licenses/LICENSE.websockets.14.1(BSD License).txt +0 -24
- cmdbox/licenses/LICENSE.zope.interface.7.1.1(Zope Public License).txt +0 -44
- /cmdbox/licenses/{LICENSE.typing_extensions.4.12.2(Python Software Foundation License).txt → LICENSE.aiohappyeyeballs.2.6.1(Python Software Foundation License).txt} +0 -0
- /cmdbox/licenses/{LICENSE.certifi.2024.8.30(Mozilla Public License 2.0 (MPL 2.0)).txt → LICENSE.certifi.2025.4.26(Mozilla Public License 2.0 (MPL 2.0)).txt} +0 -0
- /cmdbox/licenses/{LICENSE.charset-normalizer.3.4.1(MIT License).txt → LICENSE.charset-normalizer.3.4.2(MIT License).txt} +0 -0
- /cmdbox/licenses/{LICENSE.click.8.1.7(BSD License).txt → LICENSE.click.8.2.0(UNKNOWN).txt} +0 -0
- /cmdbox/licenses/{LICENSE.cryptography.43.0.3(Apache Software License; BSD License).txt → LICENSE.cryptography.44.0.3(Apache Software License; BSD License).txt} +0 -0
- /cmdbox/licenses/{LICENSE.gevent.24.11.1(MIT License).txt → LICENSE.gevent.25.4.2(MIT).txt} +0 -0
- /cmdbox/licenses/{LICENSE.importlib_metadata.8.5.0(Apache Software License).txt → LICENSE.google-api-core.2.24.2(Apache Software License).txt} +0 -0
- /cmdbox/licenses/{LICENSE.greenlet.3.1.1(MIT License).txt → LICENSE.greenlet.3.2.2(MIT AND Python-2.0).txt} +0 -0
- /cmdbox/licenses/{LICENSE.h11.0.14.0(MIT License).txt → LICENSE.h11.0.16.0(MIT License).txt} +0 -0
- /cmdbox/licenses/{LICENSE.nh3.0.2.18(MIT).txt → LICENSE.jiter.0.9.0(MIT License).txt} +0 -0
- /cmdbox/licenses/{LICENSE.more-itertools.10.5.0(MIT License).txt → LICENSE.more-itertools.10.7.0(MIT License).txt} +0 -0
- /cmdbox/licenses/{LICENSE.numpy.2.1.3(BSD License).txt → LICENSE.numpy.2.2.5(BSD License).txt} +0 -0
- /cmdbox/licenses/{LICENSE.packaging.24.2(Apache Software License; BSD License).txt → LICENSE.packaging.25.0(Apache Software License; BSD License).txt} +0 -0
- /cmdbox/licenses/{LICENSE.psycopg-binary.3.2.6(GNU Lesser General Public License v3 (LGPLv3)).txt → LICENSE.psycopg-binary.3.2.7(GNU Lesser General Public License v3 (LGPLv3)).txt} +0 -0
- /cmdbox/licenses/{LICENSE.psycopg-pool.3.2.6(GNU Lesser General Public License v3 (LGPLv3)).txt → LICENSE.psycopg.3.2.7(GNU Lesser General Public License v3 (LGPLv3)).txt} +0 -0
- /cmdbox/licenses/{LICENSE.pydantic.2.10.2(MIT License).txt → LICENSE.pydantic.2.11.4(MIT License).txt} +0 -0
- /cmdbox/licenses/{LICENSE.pydantic_core.2.27.1(MIT License).txt → LICENSE.pydantic_core.2.33.2(MIT License).txt} +0 -0
- /cmdbox/licenses/{LICENSE.redis.5.2.0(MIT License).txt → LICENSE.redis.6.0.0(MIT License).txt} +0 -0
- /cmdbox/licenses/{LICENSE.snowballstemmer.2.2.0(BSD License).txt → LICENSE.snowballstemmer.3.0.1(BSD License).txt} +0 -0
- /cmdbox/licenses/{LICENSE.uvicorn.0.32.1(BSD License).txt → LICENSE.uvicorn.0.34.2(BSD License).txt} +0 -0
- {cmdbox-0.5.3.1.dist-info → cmdbox-0.6.0.dist-info}/LICENSE +0 -0
- {cmdbox-0.5.3.1.dist-info → cmdbox-0.6.0.dist-info}/WHEEL +0 -0
- {cmdbox-0.5.3.1.dist-info → cmdbox-0.6.0.dist-info}/entry_points.txt +0 -0
- {cmdbox-0.5.3.1.dist-info → cmdbox-0.6.0.dist-info}/top_level.txt +0 -0
|
@@ -4,46 +4,55 @@ const cmdbox = {}
|
|
|
4
4
|
* @param {bool} dark_mode
|
|
5
5
|
*/
|
|
6
6
|
cmdbox.change_dark_mode = (dark_mode) => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
const html = $('html');
|
|
8
|
+
if(dark_mode) html.attr('data-bs-theme','dark');
|
|
9
|
+
else if(html.attr('data-bs-theme')=='dark') html.removeAttr('data-bs-theme');
|
|
10
|
+
else html.attr('data-bs-theme','dark');
|
|
11
|
+
$('body').css('background-color', '');
|
|
12
12
|
};
|
|
13
13
|
cmdbox.change_color_mode = (color_mode) => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
14
|
+
const html = $('html');
|
|
15
|
+
color_mode = !color_mode ? localStorage.getItem('color_mode') : color_mode;
|
|
16
|
+
if(color_mode == 'light') html.attr('data-bs-theme','light');
|
|
17
|
+
else if(color_mode == 'midnight') html.attr('data-bs-theme','midnight');
|
|
18
|
+
else if(color_mode == 'deepsea') html.attr('data-bs-theme','deepsea');
|
|
19
|
+
else if(color_mode == 'verdant') html.attr('data-bs-theme','verdant');
|
|
20
|
+
else if(color_mode == 'bumblebee') html.attr('data-bs-theme','bumblebee');
|
|
21
|
+
else if(color_mode == 'crimson') html.attr('data-bs-theme','crimson');
|
|
22
|
+
else html.attr('data-bs-theme','dark');
|
|
23
|
+
localStorage.setItem('color_mode', color_mode);
|
|
24
|
+
if (color_mode) {
|
|
25
|
+
const elem = $('.change_color_mode');
|
|
26
|
+
elem.val(color_mode);
|
|
27
|
+
elem.css('background-color', 'var(--bs-body-bg)');
|
|
28
|
+
elem.css('color', 'var(--bs-body-color)');
|
|
29
|
+
}
|
|
30
|
+
$('body').css('background-color', '');
|
|
31
31
|
};
|
|
32
32
|
/**
|
|
33
33
|
* ローディング表示
|
|
34
34
|
*/
|
|
35
|
-
cmdbox.show_loading = () => {
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
cmdbox.show_loading = async (target) => {
|
|
36
|
+
if (!target) {
|
|
37
|
+
const elem = $('#loading');
|
|
38
|
+
elem.removeClass('d-none');
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
$('<div class="spinner-grow spinner-grow-sm" role="status"><span class="visually-hidden">Loading...</span></div>').appendTo(target);
|
|
42
|
+
await cmdbox.sleep(100);
|
|
43
|
+
$('<div class="spinner-grow spinner-grow-sm" role="status"><span class="visually-hidden">Loading...</span></div>').appendTo(target);
|
|
44
|
+
await cmdbox.sleep(100);
|
|
45
|
+
$('<div class="spinner-grow spinner-grow-sm" role="status"><span class="visually-hidden">Loading...</span></div>').appendTo(target);
|
|
38
46
|
};
|
|
47
|
+
cmdbox.sleep = (time) => new Promise((r) => setTimeout(r, time));
|
|
39
48
|
/**
|
|
40
49
|
* ローディング非表示
|
|
41
50
|
*/
|
|
42
51
|
cmdbox.hide_loading = () => {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
52
|
+
const elem = $('#loading');
|
|
53
|
+
elem.addClass('d-none');
|
|
54
|
+
const progress = $('#progress');
|
|
55
|
+
progress.addClass('d-none');
|
|
47
56
|
};
|
|
48
57
|
/**
|
|
49
58
|
* テキストデータかどうか判定
|
|
@@ -51,8 +60,8 @@ cmdbox.hide_loading = () => {
|
|
|
51
60
|
* @returns {bool} - テキストデータかどうか
|
|
52
61
|
*/
|
|
53
62
|
cmdbox.is_text = (array) => {
|
|
54
|
-
|
|
55
|
-
|
|
63
|
+
const textChars = [7, 8, 9, 10, 12, 13, 27, ...cmdbox.range(0x20, 0xff, 1)];
|
|
64
|
+
return array.every(e => textChars.includes(e));
|
|
56
65
|
};
|
|
57
66
|
/**
|
|
58
67
|
* Dateオブジェクトを日付文字列に変換
|
|
@@ -60,9 +69,9 @@ cmdbox.is_text = (array) => {
|
|
|
60
69
|
* @returns {string} - 日付文字列
|
|
61
70
|
*/
|
|
62
71
|
cmdbox.toDateStr = (date) => {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
72
|
+
return date.toLocaleDateString('ja-JP', {
|
|
73
|
+
year:'numeric', month:'2-digit', day:'2-digit', hour:'2-digit', minute:'2-digit', second:'2-digit'
|
|
74
|
+
});
|
|
66
75
|
};
|
|
67
76
|
/**
|
|
68
77
|
* 指定された範囲の数値の配列を生成する
|
|
@@ -72,37 +81,37 @@ cmdbox.toDateStr = (date) => {
|
|
|
72
81
|
* @returns {number[]} - 生成された数値の配列
|
|
73
82
|
*/
|
|
74
83
|
cmdbox.range = (start, stop, step) => {
|
|
75
|
-
|
|
84
|
+
return Array.from({ length: (stop - start) / step + 1 }, (_, i) => start + i * step);
|
|
76
85
|
};
|
|
77
86
|
/**
|
|
78
87
|
* アラートメッセージ表示
|
|
79
88
|
* @param {object} res - レスポンス
|
|
80
89
|
*/
|
|
81
90
|
cmdbox.message = (res) => {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
91
|
+
msg = JSON.stringify(res)
|
|
92
|
+
alert(msg.replace(/\\n/g, '\n'));
|
|
93
|
+
cmdbox.hide_loading();
|
|
85
94
|
};
|
|
86
95
|
/**
|
|
87
96
|
* コピーライト表示
|
|
88
97
|
*/
|
|
89
98
|
cmdbox.copyright = async () => {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
99
|
+
const res = await fetch('copyright', {method: 'GET'});
|
|
100
|
+
if (res.status != 200) cmdbox.message({'error':`${res.status}: ${res.statusText}`});
|
|
101
|
+
$('.copyright').text(await res.text());
|
|
93
102
|
};
|
|
94
103
|
/**
|
|
95
104
|
* appid表示
|
|
96
105
|
* @param {string} sel - セレクタ
|
|
97
106
|
*/
|
|
98
107
|
cmdbox.appid = async (sel) => {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
108
|
+
const res = await fetch('gui/appid', {method: 'GET'});
|
|
109
|
+
if (res.status != 200) cmdbox.message({'error':`${res.status}: ${res.statusText}`});
|
|
110
|
+
const appid = await res.text()
|
|
111
|
+
$(sel).text(appid);
|
|
112
|
+
const head = $('head');
|
|
113
|
+
head.append(`<title>${appid}</title>`);
|
|
114
|
+
head.append(`<link rel="icon" type="image/x-icon" href="assets/${appid}/favicon.ico">`);
|
|
106
115
|
};
|
|
107
116
|
/**
|
|
108
117
|
* 指定のセレクタの前要素にロゴ画像を設定
|
|
@@ -110,286 +119,360 @@ cmdbox.appid = async (sel) => {
|
|
|
110
119
|
* @param {string} sel - セレクタ
|
|
111
120
|
**/
|
|
112
121
|
cmdbox.set_logoicon = async (sel) => {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
122
|
+
const res = await fetch('gui/version_info', {method: 'GET'});
|
|
123
|
+
if (res.status != 200) cmdbox.message({'error':`${res.status}: ${res.statusText}`});
|
|
124
|
+
const verinfos = await res.json();
|
|
125
|
+
for (const v of verinfos) {
|
|
126
|
+
if (!v['thisapp']) continue;
|
|
127
|
+
$(sel).before(`<img class="icon-logo me-3" src="${v['icon']}" width="40" height="40"/>`);
|
|
128
|
+
cmdbox.logoicon_src = v['icon'];
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
121
131
|
};
|
|
122
132
|
/**
|
|
123
133
|
* サインアウト
|
|
124
134
|
* @param {string} sitepath - サイトパス
|
|
125
135
|
**/
|
|
126
136
|
cmdbox.singout = (sitepath) => {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
137
|
+
if (confirm('Sign out ok ?')) {
|
|
138
|
+
const rand = cmdbox.random_string(8);
|
|
139
|
+
location.href = `dosignout/${sitepath}?r=${rand}`;
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
cmdbox.editapikey = async () => {
|
|
143
|
+
const user = await cmdbox.user_info();
|
|
144
|
+
if (!user) {
|
|
145
|
+
cmdbox.message('user not found');
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
const editapikey_modal = $('#editapikey_modal').length?$('#editapikey_modal'):$(`<div id="editapikey_modal" class="modal" tabindex="-1" style="display: none;" aria-hidden="true"/>`);
|
|
149
|
+
editapikey_modal.html('');
|
|
150
|
+
const daialog = $(`<div class="modal-dialog ui-draggable ui-draggable-handle"/>`).appendTo(editapikey_modal);
|
|
151
|
+
const form = $(`<form id="editapikey_form" class="modal-content novalidate"/>`).appendTo(daialog);
|
|
152
|
+
const header = $(`<div class="modal-header"/>`).appendTo(form);
|
|
153
|
+
header.append('<h5 class="modal-title">Edit ApiKey</h5>');
|
|
154
|
+
header.append('<button type="button" class="btn btn_close p-0 m-0" data-bs-dismiss="modal" aria-label="Close" style="margin-left: 0px;">'
|
|
155
|
+
+'<svg class="bi bi-x" width="24" height="24" fill="currentColor"><use href="#btn_x"></use></svg>'
|
|
156
|
+
+'</button>');
|
|
157
|
+
const body = $(`<div class="modal-body"/>`).appendTo(form);
|
|
158
|
+
const row_content = $(`<div class="row row_content"/>`).appendTo(body);
|
|
159
|
+
const table = $(`<table class="table table-bordered table-hover"/>`).appendTo(row_content);
|
|
160
|
+
const thead = $(`<thead><tr><th class="th" scope="col" width="40">-</th><th class="th" scope="col">apikey name</th></tr></thead>`).appendTo(table);
|
|
161
|
+
const tbody = $(`<tbody/>`).appendTo(table);
|
|
162
|
+
const apikey_names = user['apikeys'] ? Object.keys(user['apikeys']) : [];
|
|
163
|
+
apikey_names.forEach((name, i) => {
|
|
164
|
+
const tr = $(`<tr/>`).appendTo(tbody);
|
|
165
|
+
const td_no = $(`<td>${i+1}</td>`).appendTo(tr);
|
|
166
|
+
const td_name = $(`<td>${name}</td>`).appendTo(tr);
|
|
167
|
+
});
|
|
168
|
+
const footer = $(`<div class="modal-footer"/>`).appendTo(form);
|
|
169
|
+
const addapikey_btn = $(`<button type="button" class="btn btn-info">Add apikey</button>`).appendTo(footer);
|
|
170
|
+
addapikey_btn.off('click').on('click', async (event) => {
|
|
171
|
+
const apikey_name = window.prompt('Please enter the apikey name.');
|
|
172
|
+
if (!apikey_name) return;
|
|
173
|
+
const res = await fetch('gui/apikey/add', {
|
|
174
|
+
method: 'POST',
|
|
175
|
+
headers: {'Content-Type': 'application/json'},
|
|
176
|
+
body: JSON.stringify({'name': user['name'], 'apikey_name': apikey_name})
|
|
177
|
+
});
|
|
178
|
+
if (res.status != 200) {
|
|
179
|
+
cmdbox.message({'error':`${res.status}: ${res.statusText}`});
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
cmdbox.message(await res.json());
|
|
183
|
+
editapikey_modal.modal('hide');
|
|
184
|
+
});
|
|
185
|
+
const delapikey_btn = $(`<button type="button" class="btn btn-warning">Del apikey</button>`).appendTo(footer);
|
|
186
|
+
delapikey_btn.off('click').on('click', async (event) => {
|
|
187
|
+
const apikey_name = window.prompt('Please enter the apikey name.');
|
|
188
|
+
if (!apikey_name) return;
|
|
189
|
+
const res = await fetch('gui/apikey/del', {
|
|
190
|
+
method: 'POST',
|
|
191
|
+
headers: {'Content-Type': 'application/json'},
|
|
192
|
+
body: JSON.stringify({'name': user['name'], 'apikey_name': apikey_name})
|
|
193
|
+
});
|
|
194
|
+
if (res.status != 200) {
|
|
195
|
+
cmdbox.message({'error':`${res.status}: ${res.statusText}`});
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
cmdbox.message(await res.json());
|
|
199
|
+
editapikey_modal.modal('hide');
|
|
200
|
+
});
|
|
201
|
+
const close_btn = $('<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>').appendTo(footer);
|
|
202
|
+
editapikey_modal.appendTo('body');
|
|
203
|
+
daialog.draggable({cursor:'move',cancel:'.modal-body'});
|
|
204
|
+
editapikey_modal.modal('show');
|
|
131
205
|
};
|
|
132
206
|
/**
|
|
133
207
|
* 現在のユーザーのパスワード変更
|
|
134
208
|
*/
|
|
135
209
|
cmdbox.passchange = async () => {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
if (user['hash']=='oauth2') {
|
|
142
|
-
cmdbox.message('This account is an OAuth2 account and cannot be changed.');
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
const chpass_modal = $('#chpass_modal').length?$('#chpass_modal'):$(`<div id="chpass_modal" class="modal" tabindex="-1" style="display: none;" aria-hidden="true"/>`);
|
|
146
|
-
chpass_modal.html('');
|
|
147
|
-
const daialog = $(`<div class="modal-dialog ui-draggable ui-draggable-handle"/>`).appendTo(chpass_modal);
|
|
148
|
-
const form = $(`<form id="chpass_form" class="modal-content novalidate"/>`).appendTo(daialog);
|
|
149
|
-
const header = $(`<div class="modal-header"/>`).appendTo(form);
|
|
150
|
-
header.append('<h5 class="modal-title">Change Password</h5>');
|
|
151
|
-
header.append('<button type="button" class="btn btn_close p-0 m-0" data-bs-dismiss="modal" aria-label="Close" style="margin-left: 0px;">'
|
|
152
|
-
+'<svg class="bi bi-x" width="24" height="24" fill="currentColor"><use href="#btn_x"></use></svg>'
|
|
153
|
-
+'</button>');
|
|
154
|
-
const body = $(`<div class="modal-body"/>`).appendTo(form);
|
|
155
|
-
const row_content = $(`<div class="row row_content"/>`).appendTo(body);
|
|
156
|
-
const crrent_pass = $(`<div class="col-12 mb-3"><div class="input-group">`+
|
|
157
|
-
`<label class="input-group-text">Current Password</label>`+
|
|
158
|
-
`<input type="password" class="form-control" name="password"/>`+
|
|
159
|
-
`<button class="btn btn-secondary eye_buton" type="button"><svg width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16"><use href="#svg_eyeslash_btn"></use></svg></button>`+
|
|
160
|
-
`</div>`).appendTo(row_content);
|
|
161
|
-
crrent_pass.find('.eye_buton').off('click').on('click', () => {
|
|
162
|
-
const input = crrent_pass.find('input');
|
|
163
|
-
const btn = crrent_pass.find('.eye_buton');
|
|
164
|
-
if (input.attr('type') == 'password') {
|
|
165
|
-
input.attr('type', 'text');
|
|
166
|
-
btn.find('use').attr('href', '#svg_eye_btn');
|
|
167
|
-
} else {
|
|
168
|
-
input.attr('type', 'password');
|
|
169
|
-
btn.find('use').attr('href', '#svg_eyeslash_btn');
|
|
210
|
+
const user = await cmdbox.user_info();
|
|
211
|
+
if (!user) {
|
|
212
|
+
cmdbox.message('user not found');
|
|
213
|
+
return;
|
|
170
214
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
`<input type="password" class="form-control" name="new_password"/>`+
|
|
175
|
-
`<button class="btn btn-secondary gen_buton" type="button"><svg width="16" height="16" fill="currentColor" class="bi bi-magic" viewBox="0 0 16 16"><use href="#svg_magic_btn"></use></svg></button>`+
|
|
176
|
-
`<button class="btn btn-secondary eye_buton" type="button"><svg width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16"><use href="#svg_eyeslash_btn"></use></svg></button>`+
|
|
177
|
-
`</div>`).appendTo(row_content);
|
|
178
|
-
new_pass.find('.eye_buton').off('click').on('click', () => {
|
|
179
|
-
const input = new_pass.find('input');
|
|
180
|
-
const btn = new_pass.find('.eye_buton');
|
|
181
|
-
if (input.attr('type') == 'password') {
|
|
182
|
-
input.attr('type', 'text');
|
|
183
|
-
btn.find('use').attr('href', '#svg_eye_btn');
|
|
184
|
-
} else {
|
|
185
|
-
input.attr('type', 'password');
|
|
186
|
-
btn.find('use').attr('href', '#svg_eyeslash_btn');
|
|
215
|
+
if (user['hash']=='oauth2') {
|
|
216
|
+
cmdbox.message('This account is an OAuth2 account and cannot be changed.');
|
|
217
|
+
return;
|
|
187
218
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
`<input type="password" class="form-control" name="confirm_password"/>`+
|
|
192
|
-
`<button class="btn btn-secondary eye_buton" type="button"><svg width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16"><use href="#svg_eyeslash_btn"></use></svg></button>`+
|
|
193
|
-
`</div>`).appendTo(row_content);
|
|
194
|
-
confirm_pass.find('.eye_buton').off('click').on('click', () => {
|
|
195
|
-
const input = confirm_pass.find('input');
|
|
196
|
-
const btn = confirm_pass.find('.eye_buton');
|
|
197
|
-
if (input.attr('type') == 'password') {
|
|
198
|
-
input.attr('type', 'text');
|
|
199
|
-
btn.find('use').attr('href', '#svg_eye_btn');
|
|
200
|
-
} else {
|
|
201
|
-
input.attr('type', 'password');
|
|
202
|
-
btn.find('use').attr('href', '#svg_eyeslash_btn');
|
|
219
|
+
if (user['hash']=='saml') {
|
|
220
|
+
cmdbox.message('This account is an SAML account and cannot be changed.');
|
|
221
|
+
return;
|
|
203
222
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
const
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
223
|
+
const chpass_modal = $('#chpass_modal').length?$('#chpass_modal'):$(`<div id="chpass_modal" class="modal" tabindex="-1" style="display: none;" aria-hidden="true"/>`);
|
|
224
|
+
chpass_modal.html('');
|
|
225
|
+
const daialog = $(`<div class="modal-dialog ui-draggable ui-draggable-handle"/>`).appendTo(chpass_modal);
|
|
226
|
+
const form = $(`<form id="chpass_form" class="modal-content novalidate"/>`).appendTo(daialog);
|
|
227
|
+
const header = $(`<div class="modal-header"/>`).appendTo(form);
|
|
228
|
+
header.append('<h5 class="modal-title">Change Password</h5>');
|
|
229
|
+
header.append('<button type="button" class="btn btn_close p-0 m-0" data-bs-dismiss="modal" aria-label="Close" style="margin-left: 0px;">'
|
|
230
|
+
+'<svg class="bi bi-x" width="24" height="24" fill="currentColor"><use href="#btn_x"></use></svg>'
|
|
231
|
+
+'</button>');
|
|
232
|
+
const body = $(`<div class="modal-body"/>`).appendTo(form);
|
|
233
|
+
const row_content = $(`<div class="row row_content"/>`).appendTo(body);
|
|
234
|
+
const crrent_pass = $(`<div class="col-12 mb-3"><div class="input-group">`+
|
|
235
|
+
`<label class="input-group-text">Current Password</label>`+
|
|
236
|
+
`<input type="password" class="form-control" name="password"/>`+
|
|
237
|
+
`<button class="btn btn-secondary eye_buton" type="button"><svg width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16"><use href="#svg_eyeslash_btn"></use></svg></button>`+
|
|
238
|
+
`</div>`).appendTo(row_content);
|
|
239
|
+
crrent_pass.find('.eye_buton').off('click').on('click', () => {
|
|
240
|
+
const input = crrent_pass.find('input');
|
|
241
|
+
const btn = crrent_pass.find('.eye_buton');
|
|
242
|
+
if (input.attr('type') == 'password') {
|
|
243
|
+
input.attr('type', 'text');
|
|
244
|
+
btn.find('use').attr('href', '#svg_eye_btn');
|
|
245
|
+
} else {
|
|
246
|
+
input.attr('type', 'password');
|
|
247
|
+
btn.find('use').attr('href', '#svg_eyeslash_btn');
|
|
248
|
+
}
|
|
212
249
|
});
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
250
|
+
const new_pass = $(`<div class="col-12 mb-3"><div class="input-group">`+
|
|
251
|
+
`<label class="input-group-text">New Password</label>`+
|
|
252
|
+
`<input type="password" class="form-control" name="new_password"/>`+
|
|
253
|
+
`<button class="btn btn-secondary gen_buton" type="button"><svg width="16" height="16" fill="currentColor" class="bi bi-magic" viewBox="0 0 16 16"><use href="#svg_magic_btn"></use></svg></button>`+
|
|
254
|
+
`<button class="btn btn-secondary eye_buton" type="button"><svg width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16"><use href="#svg_eyeslash_btn"></use></svg></button>`+
|
|
255
|
+
`</div>`).appendTo(row_content);
|
|
256
|
+
new_pass.find('.eye_buton').off('click').on('click', () => {
|
|
257
|
+
const input = new_pass.find('input');
|
|
258
|
+
const btn = new_pass.find('.eye_buton');
|
|
259
|
+
if (input.attr('type') == 'password') {
|
|
260
|
+
input.attr('type', 'text');
|
|
261
|
+
btn.find('use').attr('href', '#svg_eye_btn');
|
|
262
|
+
} else {
|
|
263
|
+
input.attr('type', 'password');
|
|
264
|
+
btn.find('use').attr('href', '#svg_eyeslash_btn');
|
|
265
|
+
}
|
|
228
266
|
});
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
267
|
+
const confirm_pass = $(`<div class="col-12 mb-3"><div class="input-group">`+
|
|
268
|
+
`<label class="input-group-text">Confirm Password</label>`+
|
|
269
|
+
`<input type="password" class="form-control" name="confirm_password"/>`+
|
|
270
|
+
`<button class="btn btn-secondary eye_buton" type="button"><svg width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16"><use href="#svg_eyeslash_btn"></use></svg></button>`+
|
|
271
|
+
`</div>`).appendTo(row_content);
|
|
272
|
+
confirm_pass.find('.eye_buton').off('click').on('click', () => {
|
|
273
|
+
const input = confirm_pass.find('input');
|
|
274
|
+
const btn = confirm_pass.find('.eye_buton');
|
|
275
|
+
if (input.attr('type') == 'password') {
|
|
276
|
+
input.attr('type', 'text');
|
|
277
|
+
btn.find('use').attr('href', '#svg_eye_btn');
|
|
278
|
+
} else {
|
|
279
|
+
input.attr('type', 'password');
|
|
280
|
+
btn.find('use').attr('href', '#svg_eyeslash_btn');
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
new_pass.find('.gen_buton').off('click').on('click', () => {
|
|
284
|
+
const newinput = new_pass.find('input');
|
|
285
|
+
const confinput = confirm_pass.find('input');
|
|
286
|
+
cmdbox.genpass().then((pass) => {
|
|
287
|
+
if (!pass || pass.length == 0) return;
|
|
288
|
+
newinput.val(pass[0]['password']);
|
|
289
|
+
confinput.val(pass[0]['password']);
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
const footer = $(`<div class="modal-footer"/>`).appendTo(form);
|
|
293
|
+
footer.append('<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>');
|
|
294
|
+
const change = $(`<button type="button" class="btn btn-success">Change</button>`).appendTo(footer);
|
|
295
|
+
change.off('click').on('click', async (event) => {
|
|
296
|
+
cmdbox.show_loading();
|
|
297
|
+
const res = await fetch('password/change', {
|
|
298
|
+
method: 'POST',
|
|
299
|
+
headers: {'Content-Type': 'application/json'},
|
|
300
|
+
body: JSON.stringify({
|
|
301
|
+
'user_name': user['name'],
|
|
302
|
+
'password': crrent_pass.find('input').val(),
|
|
303
|
+
'new_password': new_pass.find('input').val(),
|
|
304
|
+
'confirm_password': confirm_pass.find('input').val()
|
|
305
|
+
})
|
|
306
|
+
});
|
|
307
|
+
cmdbox.hide_loading();
|
|
308
|
+
cmdbox.message(await res.json());
|
|
309
|
+
});
|
|
310
|
+
chpass_modal.appendTo('body');
|
|
311
|
+
daialog.draggable({cursor:'move',cancel:'.modal-body'});
|
|
312
|
+
chpass_modal.modal('show');
|
|
235
313
|
};
|
|
236
314
|
$(()=>{
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
if (params.
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
315
|
+
// サインアウトメニューを表示
|
|
316
|
+
fetch('usesignout', {method: 'GET'}).then(async res => {
|
|
317
|
+
try {
|
|
318
|
+
if (res.status != 200) cmdbox.message({'error':`${res.status}: ${res.statusText}`});
|
|
319
|
+
const json = await res.json();
|
|
320
|
+
const usesignout = json['success']['usesignout'];
|
|
321
|
+
if (!usesignout) return;
|
|
322
|
+
const user = await cmdbox.user_info();
|
|
323
|
+
if (!user) return;
|
|
324
|
+
const user_info_menu = $('.user_info');
|
|
325
|
+
user_info_menu.removeClass('d-none').addClass('d-flex');
|
|
326
|
+
|
|
327
|
+
if (!user_info_menu.find('.dropdown-menu .editapikey-menu-item').length) {
|
|
328
|
+
const editapikey_item = $(`<li><a class="dropdown-item editapikey-menu-item" href="#" onclick="cmdbox.editapikey();">Edit ApiKey</a></li>`);
|
|
329
|
+
user_info_menu.find('.dropdown-menu').append(editapikey_item);
|
|
330
|
+
}
|
|
331
|
+
if (!user_info_menu.find('.dropdown-menu .changepass-menu-item').length) {
|
|
332
|
+
const changepass_item = $(`<li><a class="dropdown-item changepass-menu-item" href="#" onclick="cmdbox.passchange();">Change Password</a></li>`);
|
|
333
|
+
user_info_menu.find('.dropdown-menu').append(changepass_item);
|
|
334
|
+
}
|
|
335
|
+
if (!user_info_menu.find('.dropdown-menu .signout-menu-item').length) {
|
|
336
|
+
const parts = location.pathname.split('/');
|
|
337
|
+
const sitepath = parts[parts.length-1];
|
|
338
|
+
const signout_item = $(`<li><a class="dropdown-item signout-menu-item" href="#" onclick="cmdbox.singout('${sitepath}');">Sign out</a></li>`);
|
|
339
|
+
user_info_menu.find('.dropdown-menu').append(`<li><hr class="dropdown-divider"></li>`).append(signout_item);
|
|
340
|
+
}
|
|
341
|
+
user_info_menu.find('.user_info_note').html(`Groups: ${user['groups'].join(', ')}`);
|
|
342
|
+
user_info_menu.find('.username').text(user['name']);
|
|
343
|
+
} catch (e) {}
|
|
344
|
+
});
|
|
345
|
+
cmdbox.appid('.navbar-brand');
|
|
346
|
+
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]')
|
|
347
|
+
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl))
|
|
348
|
+
// サインイン関連エラーがある場合表示
|
|
349
|
+
if (window.location.search) {
|
|
350
|
+
const params = new URLSearchParams(window.location.search);
|
|
351
|
+
if (params.has('error') || params.has('warn')) {
|
|
352
|
+
const elem = $(`<div class="alert alert-warning alert-dismissible d-block" role="alert">`).css('z-index', '10000');
|
|
353
|
+
const msgelem = $('<div>Sign in faild: The ID or PW is incorrect or the user is not authorized.</div>').appendTo(elem);
|
|
354
|
+
if (params.get('error') == 'noauth') msgelem.text('Sign in faild: No credentials are available. Please sign in.');
|
|
355
|
+
if (params.get('error') == 'expirationofpassword') msgelem.text('Sign in faild: The password has expired.');
|
|
356
|
+
if (params.get('error') == 'appdeny') msgelem.text('OAuth2 succeeded but app not allowed.');
|
|
357
|
+
if (params.get('error') == 'apikeyfail') msgelem.text('Authentication failed due to incorrect apikey.');
|
|
358
|
+
if (params.get('error') == 'unauthorizedsite') msgelem.text('Access to an unauthorized site.');
|
|
359
|
+
if (params.get('error') == 'lockout') msgelem.text('The account is locked.');
|
|
360
|
+
if (params.get('warn') == 'passchange') msgelem.text('Your password has not been changed or is about to expire. Please change your password.');
|
|
361
|
+
$('<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>').appendTo(elem);
|
|
362
|
+
$('body').prepend(elem);
|
|
363
|
+
}
|
|
280
364
|
}
|
|
281
|
-
}
|
|
282
365
|
});
|
|
283
366
|
/**
|
|
284
367
|
* バージョンモーダルを初期化
|
|
285
368
|
*/
|
|
286
369
|
cmdbox.init_version_modal = () => {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
370
|
+
$('#versions_modal').on('shown.bs.modal', async () => {
|
|
371
|
+
// cmdboxのバージョン情報取得
|
|
372
|
+
const versions_func = async (tabid, title, icon, url) => {
|
|
373
|
+
const tab = $(`<li class="nav-item" role="presentation">`)
|
|
374
|
+
const btn = $(`<button class="nav-link" id="${tabid}-tab" data-bs-toggle="tab" data-bs-target="#${tabid}" type="button" role="tab" aria-controls="${tabid}" aria-selected="true"/>`);
|
|
375
|
+
if (icon) btn.append(`<span><img class="me-2" src="${icon}" width="32" height="32"/>${title}</span>`);
|
|
376
|
+
else {
|
|
377
|
+
btn.addClass('mt-2');
|
|
378
|
+
btn.html(title);
|
|
379
|
+
}
|
|
380
|
+
tab.append(btn);
|
|
381
|
+
$('.version-tabs').prepend(tab);
|
|
382
|
+
if (!url) return;
|
|
383
|
+
const tabcont = $(`<div class="tab-pane fade show" id="${tabid}" role="tabpanel" aria-labelledby="${tabid}-tab"/>`);
|
|
384
|
+
$('.version-content').prepend(tabcont);
|
|
385
|
+
const res = await fetch(url, {method: 'GET'});
|
|
386
|
+
if (res.status != 200) cmdbox.message({'error':`${res.status}: ${res.statusText}`});
|
|
387
|
+
const vi = await res.json();
|
|
388
|
+
vi.forEach((v, i) => {
|
|
389
|
+
v = v.replace(/<([^>]+)>/g, '<a href="$1" target="_blank">$1</a>');
|
|
390
|
+
const div = $('<div></div>');
|
|
391
|
+
tabcont.append(div);
|
|
392
|
+
if(i==0) {
|
|
393
|
+
div.addClass('d-flex');
|
|
394
|
+
div.addClass('m-3');
|
|
395
|
+
div.append(`<h4><pre class="m-0">${v}</pre></h4>`);
|
|
396
|
+
} else if(i==1) {
|
|
397
|
+
div.addClass('m-3');
|
|
398
|
+
div.append(`<h4>${v}</h4>`);
|
|
399
|
+
} else {
|
|
400
|
+
div.addClass('ms-5 me-5');
|
|
401
|
+
div.append(`<h6>${v}</h6>`);
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
$('.version-tabs').find('.nav-link').removeClass('active');
|
|
405
|
+
$('.version-content').children().removeClass('active');
|
|
406
|
+
$('.version-tabs').find('.nav-link').first().addClass('active');
|
|
407
|
+
$('.version-content').children().first().addClass('active');
|
|
319
408
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
if(i==0) table_head.append(tr);
|
|
356
|
-
else table_body.append(tr);
|
|
357
|
-
});
|
|
358
|
-
};
|
|
359
|
-
versions_used_func();
|
|
360
|
-
});
|
|
409
|
+
$('.version-tabs').html('');
|
|
410
|
+
$('.version-content').html('<div class="tab-pane fade" id="versions_used" role="tabpanel" aria-labelledby="versions_used-tab">versions_used</div>');
|
|
411
|
+
await versions_func('versions_used', 'Used software', null, null);
|
|
412
|
+
const res = await fetch('gui/version_info', {method: 'GET'});
|
|
413
|
+
if (res.status != 200) cmdbox.message({'error':`${res.status}: ${res.statusText}`});
|
|
414
|
+
const verinfos = await res.json();
|
|
415
|
+
for (const v of verinfos) {
|
|
416
|
+
await versions_func(v['tabid'], v['title'], v['icon'], v['url']);
|
|
417
|
+
}
|
|
418
|
+
// usedのバージョン情報取得
|
|
419
|
+
const versions_used_func = async () => {
|
|
420
|
+
const res = await fetch('versions_used', {method: 'GET'});
|
|
421
|
+
if (res.status != 200) cmdbox.message({'error':`${res.status}: ${res.statusText}`});
|
|
422
|
+
const vu = await res.json();
|
|
423
|
+
$('#versions_used').html('');
|
|
424
|
+
const div = $('<div class="overflow-auto" style="height:calc(100vh - 260px);"></div>');
|
|
425
|
+
const table = $('<table class="table table-bordered table-hover table-sm"></table>');
|
|
426
|
+
const table_head = $('<thead class="table-dark bg-dark"></thead>');
|
|
427
|
+
const table_body = $('<tbody></tbody>');
|
|
428
|
+
table.append(table_head);
|
|
429
|
+
table.append(table_body);
|
|
430
|
+
div.append(table);
|
|
431
|
+
$('#versions_used').append(div);
|
|
432
|
+
vu.forEach((row, i) => {
|
|
433
|
+
const tr = $('<tr></tr>');
|
|
434
|
+
row.forEach((cel, j) => {
|
|
435
|
+
const td = $('<td></td>').text(cel);
|
|
436
|
+
tr.append(td);
|
|
437
|
+
});
|
|
438
|
+
if(i==0) table_head.append(tr);
|
|
439
|
+
else table_body.append(tr);
|
|
440
|
+
});
|
|
441
|
+
};
|
|
442
|
+
versions_used_func();
|
|
443
|
+
});
|
|
361
444
|
};
|
|
362
445
|
/**
|
|
363
446
|
* モーダルボタン初期化
|
|
364
447
|
*/
|
|
365
448
|
cmdbox.init_modal_button = () => {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
449
|
+
// modal setting
|
|
450
|
+
$('.modal-dialog').draggable({cursor:'move',cancel:'.modal-body'});
|
|
451
|
+
$('#filer_modal .modal-dialog').draggable({cursor:'move',cancel:'.modal-body, .filer_address'});
|
|
452
|
+
$('.btn_window_stack').off('click').on('click', () => {
|
|
453
|
+
$('.btn_window_stack').css('margin-left', '0px').hide();
|
|
454
|
+
$('.btn_window').css('margin-left', 'auto').show();
|
|
455
|
+
$('.btn_window_stack').parents('.modal-dialog').removeClass('modal-fullscreen');
|
|
456
|
+
});
|
|
457
|
+
$('.btn_window').off('click').on('click', () => {
|
|
458
|
+
$('.btn_window_stack').css('margin-left', 'auto').show();
|
|
459
|
+
$('.btn_window').css('margin-left', '0px').hide();
|
|
460
|
+
$('.btn_window_stack').parents('.modal-dialog').css('top', '').css('left', '').addClass('modal-fullscreen');
|
|
461
|
+
});
|
|
370
462
|
$('.btn_window_stack').css('margin-left', '0px').hide();
|
|
371
463
|
$('.btn_window').css('margin-left', 'auto').show();
|
|
372
|
-
$('.
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
$(
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
});
|
|
385
|
-
// F5 and Ctrl+R 無効化
|
|
386
|
-
$(document).on('keydown', (e) => {
|
|
387
|
-
if ((e.which || e.keyCode) == 116) {
|
|
388
|
-
return false;
|
|
389
|
-
} else if ((e.which || e.keyCode) == 82 && e.ctrlKey) {
|
|
390
|
-
return false;
|
|
391
|
-
}
|
|
392
|
-
});
|
|
464
|
+
$('.bbforce').off('click').on('click', async () => {
|
|
465
|
+
await bbforce_cmd();
|
|
466
|
+
cmdbox.hide_loading();
|
|
467
|
+
});
|
|
468
|
+
// F5 and Ctrl+R 無効化
|
|
469
|
+
$(document).on('keydown', (e) => {
|
|
470
|
+
if ((e.which || e.keyCode) == 116) {
|
|
471
|
+
return false;
|
|
472
|
+
} else if ((e.which || e.keyCode) == 82 && e.ctrlKey) {
|
|
473
|
+
return false;
|
|
474
|
+
}
|
|
475
|
+
});
|
|
393
476
|
};
|
|
394
477
|
/**
|
|
395
478
|
* ファイルサイズ表記を取得する
|
|
@@ -397,41 +480,41 @@ cmdbox.init_modal_button = () => {
|
|
|
397
480
|
* @returns {string} - ファイルサイズ表記
|
|
398
481
|
*/
|
|
399
482
|
cmdbox.calc_size = (size) => {
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
483
|
+
const kb = 1024
|
|
484
|
+
const mb = Math.pow(kb, 2)
|
|
485
|
+
const gb = Math.pow(kb, 3)
|
|
486
|
+
const tb = Math.pow(kb, 4)
|
|
487
|
+
let target = null
|
|
488
|
+
let unit = 'B'
|
|
489
|
+
if (size >= tb) {
|
|
490
|
+
target = tb
|
|
491
|
+
unit = 'TB'
|
|
492
|
+
} else if (size >= gb) {
|
|
493
|
+
target = gb
|
|
494
|
+
unit = 'GB'
|
|
495
|
+
} else if (size >= mb) {
|
|
496
|
+
target = mb
|
|
497
|
+
unit = 'MB'
|
|
498
|
+
} else if (size >= kb) {
|
|
499
|
+
target = kb
|
|
500
|
+
unit = 'KB'
|
|
501
|
+
}
|
|
502
|
+
const res = target !== null ? Math.floor((size / target) * 100) / 100 : size
|
|
503
|
+
return `${res} ${unit}`
|
|
421
504
|
};
|
|
422
505
|
/**
|
|
423
506
|
* カラーコードを取得する
|
|
424
507
|
* @param {bool} color - カラーを指定。省略するとランダムなカラーコードを生成
|
|
425
508
|
* @returns {string, array} - カラーコード
|
|
426
509
|
**/
|
|
427
|
-
cmdbox.
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
510
|
+
cmdbox.random_color = (color=undefined) => {
|
|
511
|
+
if (!color) {
|
|
512
|
+
color = [(~~(256 * Math.random())), (~~(256 * Math.random())), (~~(256 * Math.random()))];
|
|
513
|
+
} else if (typeof color === 'string') {
|
|
514
|
+
color = color.split(',').map(e => parseInt(e, 16));
|
|
515
|
+
}
|
|
516
|
+
code = color.map(e => ("00"+e.toString(16)).slice(-2)).join('');
|
|
517
|
+
return code;
|
|
435
518
|
};
|
|
436
519
|
/**
|
|
437
520
|
* カラーコードを取得する
|
|
@@ -439,18 +522,18 @@ cmdbox.randam_color = (color=undefined) => {
|
|
|
439
522
|
* @returns {string} - カラーコード
|
|
440
523
|
**/
|
|
441
524
|
cmdbox.make_color4id = (id=0) => {
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
525
|
+
color = [(~~(256*(id/(256**3)))), (~~(256*(id/(256**2)))), (~~(256*(id/(256**1))))];
|
|
526
|
+
code = color.map(e => ("00"+e.toString(16)).slice(-2)).join('');
|
|
527
|
+
return code;
|
|
445
528
|
};
|
|
446
529
|
/**
|
|
447
530
|
* ランダムな文字列を生成する
|
|
448
531
|
* @param {number} length - 文字列の長さ
|
|
449
532
|
* @returns {string} - ランダムな文字列
|
|
450
533
|
**/
|
|
451
|
-
cmdbox.
|
|
452
|
-
|
|
453
|
-
|
|
534
|
+
cmdbox.random_string = (length) => {
|
|
535
|
+
const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
|
536
|
+
return Array.from({length: length}, () => chars[Math.floor(Math.random() * chars.length)]).join('');
|
|
454
537
|
};
|
|
455
538
|
/**
|
|
456
539
|
* ファイル名から拡張子を取り除いた文字列を取得する
|
|
@@ -458,7 +541,7 @@ cmdbox.randam_string = (length) => {
|
|
|
458
541
|
* @returns {string} - 拡張子を取り除いた文字列
|
|
459
542
|
**/
|
|
460
543
|
cmdbox.chopext = (filename) => {
|
|
461
|
-
|
|
544
|
+
return filename.replace(/\.[^/.]+$/, "");
|
|
462
545
|
};
|
|
463
546
|
/**
|
|
464
547
|
* Imageオブジェクトを使用して画像を読み込むPromiseを生成する
|
|
@@ -466,12 +549,12 @@ cmdbox.chopext = (filename) => {
|
|
|
466
549
|
* @returns {Promise} - 画像の読み込みPromise
|
|
467
550
|
**/
|
|
468
551
|
cmdbox.load_img_sync = (url) => {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
552
|
+
return new Promise((resolve, reject) => {
|
|
553
|
+
const img = new Image();
|
|
554
|
+
img.onload = () => resolve(img);
|
|
555
|
+
img.onerror = () => reject(new Error(`Failed to load image's URL: ${url}`));
|
|
556
|
+
img.src = url;
|
|
557
|
+
});
|
|
475
558
|
};
|
|
476
559
|
/**
|
|
477
560
|
* サーバーAPI実行
|
|
@@ -479,15 +562,15 @@ cmdbox.load_img_sync = (url) => {
|
|
|
479
562
|
* @returns {Promise} - レスポンス
|
|
480
563
|
*/
|
|
481
564
|
cmdbox.sv_exec_cmd = async (opt) => {
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
565
|
+
return fetch('exec_cmd', {
|
|
566
|
+
method: 'POST',
|
|
567
|
+
headers: {
|
|
568
|
+
'Content-Type': 'application/json'
|
|
569
|
+
},
|
|
570
|
+
body: JSON.stringify(opt)
|
|
571
|
+
}).then(response => response.json()).catch((e) => {
|
|
572
|
+
console.log(e);
|
|
573
|
+
});
|
|
491
574
|
};
|
|
492
575
|
/**
|
|
493
576
|
* 接続情報取得
|
|
@@ -496,30 +579,30 @@ cmdbox.sv_exec_cmd = async (opt) => {
|
|
|
496
579
|
* @returns {object | Promise} - 接続情報又はPromise
|
|
497
580
|
*/
|
|
498
581
|
cmdbox.get_server_opt = (do_sv_exec_cmd, parent_elem) => {
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
582
|
+
if (do_sv_exec_cmd) {
|
|
583
|
+
const prom = fetch('get_server_opt', {method: 'GET'}).then(res => res.json()).then(opt => {
|
|
584
|
+
cmdbox.initargs = opt;
|
|
585
|
+
parent_elem.find('.filer_host').val(opt['host']);
|
|
586
|
+
parent_elem.find('.filer_port').val(opt['port']);
|
|
587
|
+
parent_elem.find('.filer_password').val(opt['password']);
|
|
588
|
+
parent_elem.find('.filer_svname').val(opt['svname']);
|
|
589
|
+
parent_elem.find('.filer_client_data').val("client");
|
|
590
|
+
parent_elem.find('.filer_client_data').val(opt['data']);
|
|
591
|
+
});
|
|
592
|
+
return prom;
|
|
593
|
+
}
|
|
594
|
+
try {
|
|
595
|
+
const filer_host = parent_elem.find('.filer_host').val();
|
|
596
|
+
const filer_port = parent_elem.find('.filer_port').val();
|
|
597
|
+
const filer_password = parent_elem.find('.filer_password').val();
|
|
598
|
+
const filer_svname = parent_elem.find('.filer_svname').val();
|
|
599
|
+
const filer_scope = parent_elem.find('.filer_scope').val();
|
|
600
|
+
const filer_client_data = parent_elem.find('.filer_client_data').val();
|
|
601
|
+
return {"host":filer_host, "port":filer_port, "password":filer_password, "svname":filer_svname, "scope": filer_scope, "client_data": filer_client_data};
|
|
602
|
+
} catch (e) {
|
|
603
|
+
console.log(e);
|
|
604
|
+
return {};
|
|
605
|
+
}
|
|
523
606
|
};
|
|
524
607
|
/**
|
|
525
608
|
* サーバーリスト取得
|
|
@@ -529,77 +612,78 @@ cmdbox.get_server_opt = (do_sv_exec_cmd, parent_elem) => {
|
|
|
529
612
|
* @param {bool} current_only - カレントのみ表示
|
|
530
613
|
*/
|
|
531
614
|
cmdbox.load_server_list = (parent_elem, call_back_func, server_only, current_only) => {
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
615
|
+
cmdbox.show_loading();
|
|
616
|
+
parent_elem.find('.filer_svnames').remove();
|
|
617
|
+
const mk_func = (elem) => {return ()=>{
|
|
618
|
+
parent_elem.find('.filer_server_bot').text(elem.attr('data-svname'));
|
|
619
|
+
parent_elem.find('.filer_host').val(elem.attr('data-host'));
|
|
620
|
+
parent_elem.find('.filer_port').val(elem.attr('data-port'));
|
|
621
|
+
parent_elem.find('.filer_password').val(elem.attr('data-password'));
|
|
622
|
+
parent_elem.find('.filer_svname').val(elem.attr('data-svname'));
|
|
623
|
+
parent_elem.find('.filer_scope').val(elem.attr('data-scope'));
|
|
624
|
+
parent_elem.find('.filer_client_data').val(elem.attr('data-client_data'));
|
|
625
|
+
if (call_back_func) call_back_func(cmdbox.get_server_opt(false, parent_elem));
|
|
626
|
+
//fsapi.tree(fsapi.right, "/", fsapi.right.find('.tree-menu'), false);
|
|
627
|
+
}};
|
|
628
|
+
if (!cmdbox.initargs['client_only'] && !current_only) {
|
|
629
|
+
const opt = cmdbox.get_server_opt(false, parent_elem);
|
|
630
|
+
opt['mode'] = 'server';
|
|
631
|
+
opt['cmd'] = 'list';
|
|
632
|
+
opt["capture_stdout"] = true;
|
|
633
|
+
delete opt['svname'];
|
|
634
|
+
cmdbox.sv_exec_cmd(opt).then(res => {
|
|
635
|
+
if(res && res['success']) res = [res];
|
|
636
|
+
if(!res[0] || !res[0]['success']) {
|
|
637
|
+
cmdbox.message(res);
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
if(res.length<=0 || !res[0]['success']) {
|
|
641
|
+
cmdbox.hide_loading();
|
|
642
|
+
return;
|
|
643
|
+
}
|
|
644
|
+
const svnames = {};
|
|
645
|
+
res[0]['success'].forEach(elem => {
|
|
646
|
+
const svname = elem['svname'].split('-')[0];
|
|
647
|
+
if (svnames[svname]) return;
|
|
648
|
+
svnames[svname] = true;
|
|
649
|
+
const a_elem = $(`<a class="dropdown-item" href="#" data-client_data="">${svname} ( ${opt['host']}:${opt['port']} )</a>`);
|
|
650
|
+
a_elem.attr('data-host', opt['host']);
|
|
651
|
+
a_elem.attr('data-port', opt['port']);
|
|
652
|
+
a_elem.attr('data-password', opt['password']);
|
|
653
|
+
a_elem.attr('data-svname', svname);
|
|
654
|
+
a_elem.attr('data-scope', "server");
|
|
655
|
+
a_elem.off("click").on("click", mk_func(a_elem));
|
|
656
|
+
const li_elem = $('<li class="filer_svnames"></li>').append(a_elem);
|
|
657
|
+
parent_elem.find('.filer_server').append(li_elem);
|
|
658
|
+
});
|
|
659
|
+
parent_elem.find('.filer_server').find('.dropdown-item:first').click();
|
|
660
|
+
}).catch((e) => {
|
|
661
|
+
console.log(e);
|
|
662
|
+
}).finally(() => {
|
|
663
|
+
cmdbox.hide_loading();
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
const cl = (label, local_dir) => {
|
|
667
|
+
const a_elem = $(`<a class="dropdown-item" href="#">${label}</a>`);
|
|
668
|
+
a_elem.attr('data-host', cmdbox.initargs['host']);
|
|
669
|
+
a_elem.attr('data-port', cmdbox.initargs['port']);
|
|
670
|
+
a_elem.attr('data-password', cmdbox.initargs['password']);
|
|
671
|
+
a_elem.attr('data-svname', label);
|
|
672
|
+
a_elem.attr('data-scope', label);
|
|
673
|
+
a_elem.attr('data-client_data', local_dir);
|
|
674
|
+
a_elem.off("click").on("click", (event) => {
|
|
675
|
+
parent_elem.find('.filer_address').val(current_only ? '.' : '/');
|
|
676
|
+
mk_func($(event.target))();
|
|
677
|
+
});
|
|
572
678
|
const li_elem = $('<li class="filer_svnames"></li>').append(a_elem);
|
|
573
679
|
parent_elem.find('.filer_server').append(li_elem);
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
}
|
|
582
|
-
const cl = (label, local_dir) => {
|
|
583
|
-
const a_elem = $(`<a class="dropdown-item" href="#">${label}</a>`);
|
|
584
|
-
a_elem.attr('data-host', cmdbox.initargs['host']);
|
|
585
|
-
a_elem.attr('data-port', cmdbox.initargs['port']);
|
|
586
|
-
a_elem.attr('data-password', cmdbox.initargs['password']);
|
|
587
|
-
a_elem.attr('data-svname', label);
|
|
588
|
-
a_elem.attr('data-scope', label);
|
|
589
|
-
a_elem.attr('data-client_data', local_dir);
|
|
590
|
-
a_elem.off("click").on("click", (event) => {
|
|
591
|
-
parent_elem.find('.filer_address').val(current_only ? '.' : '/');
|
|
592
|
-
mk_func($(event.target))();
|
|
593
|
-
});
|
|
594
|
-
const li_elem = $('<li class="filer_svnames"></li>').append(a_elem);
|
|
595
|
-
parent_elem.find('.filer_server').append(li_elem);
|
|
596
|
-
}
|
|
597
|
-
if (current_only) cl('current', '.');
|
|
598
|
-
else if (!server_only) {
|
|
599
|
-
cl('client', cmdbox.initargs['data']);
|
|
600
|
-
cl('current', '.');
|
|
601
|
-
}
|
|
602
|
-
parent_elem.find('.filer_server').find('.dropdown-item:first').click();
|
|
680
|
+
}
|
|
681
|
+
if (current_only) cl('current', '.');
|
|
682
|
+
else if (!server_only) {
|
|
683
|
+
cl('client', cmdbox.initargs['data']);
|
|
684
|
+
cl('current', '.');
|
|
685
|
+
}
|
|
686
|
+
parent_elem.find('.filer_server').find('.dropdown-item:first').click();
|
|
603
687
|
};
|
|
604
688
|
/**
|
|
605
689
|
* deployリスト取得
|
|
@@ -608,37 +692,37 @@ cmdbox.load_server_list = (parent_elem, call_back_func, server_only, current_onl
|
|
|
608
692
|
* @returns {Promise} - レスポンス
|
|
609
693
|
**/
|
|
610
694
|
cmdbox.deploy_list = (target, error_func=undefined) => {
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
695
|
+
const opt = cmdbox.get_server_opt(false, target);
|
|
696
|
+
opt['mode'] = 'client';
|
|
697
|
+
opt['cmd'] = 'deploy_list';
|
|
698
|
+
opt['capture_stdout'] = true;
|
|
699
|
+
cmdbox.show_loading();
|
|
700
|
+
return cmdbox.sv_exec_cmd(opt).then(res => {
|
|
701
|
+
if(!res[0] || !res[0]['success']) {
|
|
702
|
+
if (error_func) {
|
|
703
|
+
error_func(res);
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
706
|
+
cmdbox.hide_loading();
|
|
707
|
+
cmdbox.message(res);
|
|
708
|
+
return;
|
|
709
|
+
}
|
|
710
|
+
if (!res[0]['success']['data']) {
|
|
711
|
+
cmdbox.hide_loading();
|
|
712
|
+
return
|
|
713
|
+
}
|
|
714
|
+
return res[0]['success'];
|
|
715
|
+
});
|
|
632
716
|
};
|
|
633
717
|
/**
|
|
634
718
|
* 現在のユーザー情報取得
|
|
635
719
|
* @returns {Promise} - レスポンス
|
|
636
720
|
*/
|
|
637
721
|
cmdbox.user_info = async () => {
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
722
|
+
const res = await fetch('gui/user_info', {method: 'GET'});
|
|
723
|
+
if (!res.ok) return null;
|
|
724
|
+
const user = await res.json()
|
|
725
|
+
return user;
|
|
642
726
|
};
|
|
643
727
|
/**
|
|
644
728
|
* 新しいパスワード取得
|
|
@@ -652,31 +736,31 @@ cmdbox.user_info = async () => {
|
|
|
652
736
|
* @returns {Promise} - レスポンス
|
|
653
737
|
**/
|
|
654
738
|
cmdbox.genpass = (pass_length=16, pass_count=1, use_alphabet="both", use_number="use", use_symbol="use", similar="exclude", error_func=undefined) => {
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
739
|
+
const opt = {};
|
|
740
|
+
opt['mode'] = 'web';
|
|
741
|
+
opt['cmd'] = 'genpass';
|
|
742
|
+
opt['pass_length'] = pass_length;
|
|
743
|
+
opt['pass_count'] = pass_count;
|
|
744
|
+
opt['use_alphabet'] = use_alphabet;
|
|
745
|
+
opt['use_number'] = use_number;
|
|
746
|
+
opt['use_symbol'] = use_symbol;
|
|
747
|
+
opt['similar'] = similar;
|
|
748
|
+
opt['capture_stdout'] = true;
|
|
749
|
+
cmdbox.show_loading();
|
|
750
|
+
return cmdbox.sv_exec_cmd(opt).then(res => {
|
|
751
|
+
if(!res[0] || !res[0]['success']) {
|
|
752
|
+
cmdbox.hide_loading();
|
|
753
|
+
if (error_func) {
|
|
754
|
+
error_func(res);
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
cmdbox.message(res);
|
|
758
|
+
return res[0];
|
|
759
|
+
}
|
|
760
|
+
const ret = res[0]['success'];
|
|
761
|
+
cmdbox.hide_loading();
|
|
762
|
+
return ret['passwords'];
|
|
763
|
+
});
|
|
680
764
|
};
|
|
681
765
|
/**
|
|
682
766
|
* ファイルリスト取得
|
|
@@ -688,26 +772,27 @@ cmdbox.genpass = (pass_length=16, pass_count=1, use_alphabet="both", use_number=
|
|
|
688
772
|
* @returns {Promise} - レスポンス
|
|
689
773
|
**/
|
|
690
774
|
cmdbox.file_list = (target, svpath, recursive=false, error_func=undefined, exec_cmd=undefined) => {
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
775
|
+
const opt = cmdbox.get_server_opt(false, target);
|
|
776
|
+
opt['mode'] = 'client';
|
|
777
|
+
opt['cmd'] = 'file_list';
|
|
778
|
+
opt['capture_stdout'] = true;
|
|
779
|
+
opt['svpath'] = svpath;
|
|
780
|
+
opt['recursive'] = recursive ? true : false;
|
|
781
|
+
cmdbox.show_loading();
|
|
782
|
+
const exec = exec_cmd ? exec_cmd : cmdbox.sv_exec_cmd;
|
|
783
|
+
return exec(opt).then(res => {
|
|
784
|
+
if (res && res['success']) res = [res];
|
|
785
|
+
if (!res[0] || !res[0]['success']) {
|
|
786
|
+
if (error_func) {
|
|
787
|
+
error_func(res);
|
|
788
|
+
return;
|
|
789
|
+
}
|
|
790
|
+
cmdbox.hide_loading();
|
|
791
|
+
cmdbox.message(res);
|
|
792
|
+
return;
|
|
793
|
+
}
|
|
794
|
+
return res[0]['success'];
|
|
795
|
+
});
|
|
711
796
|
};
|
|
712
797
|
/**
|
|
713
798
|
* ファイルダウンロード
|
|
@@ -718,28 +803,29 @@ cmdbox.file_list = (target, svpath, recursive=false, error_func=undefined, exec_
|
|
|
718
803
|
* @returns {Promise} - レスポンス
|
|
719
804
|
**/
|
|
720
805
|
cmdbox.file_download = (target, svpath, error_func=undefined, exec_cmd=undefined) => {
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
806
|
+
const opt = cmdbox.get_server_opt(false, target);
|
|
807
|
+
opt['mode'] = 'client';
|
|
808
|
+
opt['cmd'] = 'file_download';
|
|
809
|
+
opt['capture_stdout'] = true;
|
|
810
|
+
opt['svpath'] = svpath;
|
|
811
|
+
opt['capture_maxsize'] = 1024**3*10;
|
|
812
|
+
cmdbox.show_loading();
|
|
813
|
+
const exec = exec_cmd ? exec_cmd : cmdbox.sv_exec_cmd;
|
|
814
|
+
return exec(opt).then(res => {
|
|
815
|
+
if (res && res['success']) res = [res];
|
|
816
|
+
if (!res[0] || !res[0]['success'] || !res[0]['success']['data']) {
|
|
817
|
+
if (error_func) {
|
|
818
|
+
error_func(res);
|
|
819
|
+
return;
|
|
820
|
+
}
|
|
821
|
+
cmdbox.hide_loading();
|
|
822
|
+
cmdbox.message(res);
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
return res[0]['success'];
|
|
826
|
+
}).catch((e) => {
|
|
827
|
+
console.log(e);
|
|
828
|
+
});
|
|
743
829
|
};
|
|
744
830
|
/**
|
|
745
831
|
* ファイルアップロード
|
|
@@ -753,45 +839,45 @@ cmdbox.file_download = (target, svpath, error_func=undefined, exec_cmd=undefined
|
|
|
753
839
|
* @param {bool} async_fg - 非同期で実行するかどうか
|
|
754
840
|
*/
|
|
755
841
|
cmdbox.file_upload = (target, svpath, formData, orverwrite=false, progress_func=undefined, success_func=undefined, error_func=undefined, async_fg=true) => {
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
842
|
+
const param = {method: 'POST', body: formData};
|
|
843
|
+
const opt = cmdbox.get_server_opt(false, target);
|
|
844
|
+
let param_str = `host=${encodeURI(opt['host'])}`;
|
|
845
|
+
param_str += `&port=${encodeURI(opt['port'])}`;
|
|
846
|
+
param_str += `&password=${encodeURI(opt['password'])}`;
|
|
847
|
+
param_str += `&svname=${encodeURI(opt['svname'])}`;
|
|
848
|
+
param_str += `&orverwrite=${!!orverwrite}`;
|
|
849
|
+
param_str += `&svpath=${encodeURI(svpath)}`;
|
|
850
|
+
param_str += `&scope=${encodeURI(opt['scope'])}`;
|
|
851
|
+
param_str += `&client_data=${encodeURI(opt['client_data'])}`;
|
|
852
|
+
$.ajax({ // fetchだとxhr.upload.onprogressが使えないため、$.ajaxを使用
|
|
853
|
+
url: `filer/upload?${param_str}`,
|
|
854
|
+
type: 'POST',
|
|
855
|
+
processData: false,
|
|
856
|
+
contentType: false,
|
|
857
|
+
async: async_fg,
|
|
858
|
+
data: formData,
|
|
859
|
+
xhr: function() {
|
|
860
|
+
const xhr = $.ajaxSettings.xhr();
|
|
861
|
+
xhr.upload.onprogress = function(e) {
|
|
862
|
+
if (e.lengthComputable && progress_func) {
|
|
863
|
+
progress_func(e);
|
|
864
|
+
}
|
|
865
|
+
};
|
|
866
|
+
return xhr;
|
|
867
|
+
},
|
|
868
|
+
success: function(data) {
|
|
869
|
+
if (success_func) {
|
|
870
|
+
success_func(target, svpath, data);
|
|
871
|
+
}
|
|
872
|
+
},
|
|
873
|
+
error: function(data) {
|
|
874
|
+
console.log(data);
|
|
875
|
+
cmdbox.message(data);
|
|
876
|
+
if (error_func) {
|
|
877
|
+
error_func(target, svpath, data);
|
|
878
|
+
}
|
|
778
879
|
}
|
|
779
|
-
|
|
780
|
-
return xhr;
|
|
781
|
-
},
|
|
782
|
-
success: function(data) {
|
|
783
|
-
if (success_func) {
|
|
784
|
-
success_func(target, svpath, data);
|
|
785
|
-
}
|
|
786
|
-
},
|
|
787
|
-
error: function(data) {
|
|
788
|
-
console.log(data);
|
|
789
|
-
cmdbox.message(data);
|
|
790
|
-
if (error_func) {
|
|
791
|
-
error_func(target, svpath, data);
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
});
|
|
880
|
+
});
|
|
795
881
|
}
|
|
796
882
|
/**
|
|
797
883
|
* ファイルコピ-
|
|
@@ -804,27 +890,28 @@ cmdbox.file_upload = (target, svpath, formData, orverwrite=false, progress_func=
|
|
|
804
890
|
* @returns {Promise} - レスポンス
|
|
805
891
|
*/
|
|
806
892
|
cmdbox.file_copy = (target, from_path, to_path, orverwrite=false, error_func=undefined, exec_cmd=undefined) => {
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
893
|
+
const opt = cmdbox.get_server_opt(false, target);
|
|
894
|
+
opt['mode'] = 'client';
|
|
895
|
+
opt['cmd'] = 'file_copy';
|
|
896
|
+
opt['capture_stdout'] = true;
|
|
897
|
+
opt['from_path'] = from_path;
|
|
898
|
+
opt['to_path'] = to_path;
|
|
899
|
+
opt['orverwrite'] = orverwrite;
|
|
900
|
+
cmdbox.show_loading();
|
|
901
|
+
const exec = exec_cmd ? exec_cmd : cmdbox.sv_exec_cmd;
|
|
902
|
+
return exec(opt).then(res => {
|
|
903
|
+
if (res && res['success']) res = [res];
|
|
904
|
+
if (!res[0] || !res[0]['success']) {
|
|
905
|
+
if (error_func) {
|
|
906
|
+
error_func(res);
|
|
907
|
+
return;
|
|
908
|
+
}
|
|
909
|
+
cmdbox.hide_loading();
|
|
910
|
+
cmdbox.message(res);
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
913
|
+
return res[0]['success'];
|
|
914
|
+
});
|
|
828
915
|
};
|
|
829
916
|
/**
|
|
830
917
|
* ファイル移動
|
|
@@ -836,26 +923,27 @@ cmdbox.file_copy = (target, from_path, to_path, orverwrite=false, error_func=und
|
|
|
836
923
|
* @returns {Promise} - レスポンス
|
|
837
924
|
*/
|
|
838
925
|
cmdbox.file_move = (target, from_path, to_path, error_func=undefined, exec_cmd=undefined) => {
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
926
|
+
const opt = cmdbox.get_server_opt(false, target);
|
|
927
|
+
opt['mode'] = 'client';
|
|
928
|
+
opt['cmd'] = 'file_move';
|
|
929
|
+
opt['capture_stdout'] = true;
|
|
930
|
+
opt['from_path'] = from_path;
|
|
931
|
+
opt['to_path'] = to_path;
|
|
932
|
+
cmdbox.show_loading();
|
|
933
|
+
const exec = exec_cmd ? exec_cmd : cmdbox.sv_exec_cmd;
|
|
934
|
+
return exec(opt).then(res => {
|
|
935
|
+
if (res && res['success']) res = [res];
|
|
936
|
+
if (!res[0] || !res[0]['success']) {
|
|
937
|
+
if (error_func) {
|
|
938
|
+
error_func(res);
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
cmdbox.hide_loading();
|
|
942
|
+
cmdbox.message(res);
|
|
943
|
+
return;
|
|
944
|
+
}
|
|
945
|
+
return res[0]['success'];
|
|
946
|
+
});
|
|
859
947
|
};
|
|
860
948
|
/**
|
|
861
949
|
* ファイル削除
|
|
@@ -866,25 +954,26 @@ cmdbox.file_move = (target, from_path, to_path, error_func=undefined, exec_cmd=u
|
|
|
866
954
|
* @returns {Promise} - レスポンス
|
|
867
955
|
**/
|
|
868
956
|
cmdbox.file_remove = (target, svpath, error_func=undefined, exec_cmd=undefined) => {
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
957
|
+
const opt = cmdbox.get_server_opt(false, target);
|
|
958
|
+
opt['mode'] = 'client';
|
|
959
|
+
opt['cmd'] = 'file_remove';
|
|
960
|
+
opt['capture_stdout'] = true;
|
|
961
|
+
opt['svpath'] = svpath;
|
|
962
|
+
cmdbox.show_loading();
|
|
963
|
+
const exec = exec_cmd ? exec_cmd : cmdbox.sv_exec_cmd;
|
|
964
|
+
return exec(opt).then(res => {
|
|
965
|
+
if (res && res['success']) res = [res];
|
|
966
|
+
if (!res[0] || !res[0]['success']) {
|
|
967
|
+
if (error_func) {
|
|
968
|
+
error_func(res);
|
|
969
|
+
return;
|
|
970
|
+
}
|
|
971
|
+
cmdbox.hide_loading();
|
|
972
|
+
cmdbox.message(res);
|
|
973
|
+
return;
|
|
974
|
+
}
|
|
975
|
+
return res[0]['success'];
|
|
976
|
+
});
|
|
888
977
|
};
|
|
889
978
|
/**
|
|
890
979
|
* ディレクトリ削除
|
|
@@ -895,25 +984,26 @@ cmdbox.file_remove = (target, svpath, error_func=undefined, exec_cmd=undefined)
|
|
|
895
984
|
* @returns {Promise} - レスポンス
|
|
896
985
|
**/
|
|
897
986
|
cmdbox.file_rmdir = (target, svpath, error_func=undefined, exec_cmd=undefined) => {
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
987
|
+
const opt = cmdbox.get_server_opt(false, target);
|
|
988
|
+
opt['mode'] = 'client';
|
|
989
|
+
opt['cmd'] = 'file_rmdir';
|
|
990
|
+
opt['capture_stdout'] = true;
|
|
991
|
+
opt['svpath'] = svpath;
|
|
992
|
+
cmdbox.show_loading();
|
|
993
|
+
const exec = exec_cmd ? exec_cmd : cmdbox.sv_exec_cmd;
|
|
994
|
+
return exec(opt).then(res => {
|
|
995
|
+
if (res && res['success']) res = [res];
|
|
996
|
+
if (!res[0] || !res[0]['success']) {
|
|
997
|
+
if (error_func) {
|
|
998
|
+
error_func(res);
|
|
999
|
+
return;
|
|
1000
|
+
}
|
|
1001
|
+
cmdbox.hide_loading();
|
|
1002
|
+
cmdbox.message(res);
|
|
1003
|
+
return;
|
|
1004
|
+
}
|
|
1005
|
+
return res[0]['success'];
|
|
1006
|
+
});
|
|
917
1007
|
};
|
|
918
1008
|
/**
|
|
919
1009
|
* ディレクトリ作成
|
|
@@ -924,25 +1014,26 @@ cmdbox.file_rmdir = (target, svpath, error_func=undefined, exec_cmd=undefined) =
|
|
|
924
1014
|
* @returns {Promise} - レスポンス
|
|
925
1015
|
**/
|
|
926
1016
|
cmdbox.file_mkdir = (target, svpath, error_func=undefined, exec_cmd=undefined) => {
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
1017
|
+
const opt = cmdbox.get_server_opt(false, target);
|
|
1018
|
+
opt['mode'] = 'client';
|
|
1019
|
+
opt['cmd'] = 'file_mkdir';
|
|
1020
|
+
opt['capture_stdout'] = true;
|
|
1021
|
+
opt['svpath'] = svpath;
|
|
1022
|
+
cmdbox.show_loading();
|
|
1023
|
+
const exec = exec_cmd ? exec_cmd : cmdbox.sv_exec_cmd;
|
|
1024
|
+
return exec(opt).then(res => {
|
|
1025
|
+
if (res && res['success']) res = [res];
|
|
1026
|
+
if (!res[0] || !res[0]['success']) {
|
|
1027
|
+
if (error_func) {
|
|
1028
|
+
error_func(res);
|
|
1029
|
+
return;
|
|
1030
|
+
}
|
|
1031
|
+
cmdbox.hide_loading();
|
|
1032
|
+
cmdbox.message(res);
|
|
1033
|
+
return;
|
|
1034
|
+
}
|
|
1035
|
+
return res[0]['success'];
|
|
1036
|
+
});
|
|
946
1037
|
};
|
|
947
1038
|
/**
|
|
948
1039
|
* プログレスバー表示
|
|
@@ -954,33 +1045,33 @@ cmdbox.file_mkdir = (target, svpath, error_func=undefined, exec_cmd=undefined) =
|
|
|
954
1045
|
* @param {bool} _cycle - サイクル表示するかどうか
|
|
955
1046
|
*/
|
|
956
1047
|
cmdbox.progress = (_min, _max, _now, _text, _show, _cycle) => {
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
1048
|
+
const prog_elem = $('.progress');
|
|
1049
|
+
const bar_elem = prog_elem.find('.progress-bar');
|
|
1050
|
+
const bar_text = bar_elem.find('.progress-bar-text');
|
|
1051
|
+
if(_show) prog_elem.removeClass('d-none');
|
|
1052
|
+
else prog_elem.addClass('d-none');
|
|
1053
|
+
prog_elem.attr('aria-valuemin', _min);
|
|
1054
|
+
prog_elem.attr('aria-valuemax', _max);
|
|
1055
|
+
prog_elem.attr('aria-valuenow', _now);
|
|
1056
|
+
if (!_cycle) {
|
|
1057
|
+
const par = Math.floor((_now / (_max-_min)) * 10000) / 100
|
|
1058
|
+
bar_elem.css('left', 'auto').css('width', `${par}%`);
|
|
1059
|
+
bar_text.text(`${par.toFixed(2)}% ( ${_now} / ${_max} ) ${_text}`);
|
|
1060
|
+
if (cmdbox.progress_handle) clearTimeout(cmdbox.progress_handle);
|
|
1061
|
+
} else {
|
|
1062
|
+
let maxwidth = prog_elem.css('width');
|
|
1063
|
+
maxwidth = parseInt(maxwidth.replace('px', ''));
|
|
1064
|
+
let left = bar_elem.css('left');
|
|
1065
|
+
if (!left || left=='auto') left = 0;
|
|
1066
|
+
else left = parseInt(left.replace('px', ''));
|
|
1067
|
+
if (left > maxwidth) left = -200;
|
|
1068
|
+
left += 2;
|
|
1069
|
+
bar_elem.css('width', '200px').css('position', 'relative').css('left', `${left}px`);
|
|
1070
|
+
bar_text.text(_text?_text:'Server processing...');
|
|
1071
|
+
cmdbox.progress_handle = setTimeout(() => {
|
|
1072
|
+
if (!$('#loading').is('.d-none')) cmdbox.progress(_min, _max, _now, _text, _show, _cycle);
|
|
1073
|
+
}, 20);
|
|
1074
|
+
}
|
|
984
1075
|
};
|
|
985
1076
|
/**
|
|
986
1077
|
* ユーザーデータを保存
|
|
@@ -990,14 +1081,14 @@ cmdbox.progress = (_min, _max, _now, _text, _show, _cycle) => {
|
|
|
990
1081
|
* @returns {Promise}
|
|
991
1082
|
*/
|
|
992
1083
|
cmdbox.save_user_data = async (cat, key, val) => {
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1084
|
+
const formData = new FormData();
|
|
1085
|
+
formData.append('categoly', cat);
|
|
1086
|
+
formData.append('key', key);
|
|
1087
|
+
formData.append('val', val);
|
|
1088
|
+
const res = await fetch('gui/user_data/save', {method:'POST', body:formData});
|
|
1089
|
+
if (!res.ok) cmdbox.message({'error':`${res.status}: ${res.statusText}`});
|
|
1090
|
+
const msg = await res.json()
|
|
1091
|
+
return msg;
|
|
1001
1092
|
};
|
|
1002
1093
|
/**
|
|
1003
1094
|
* ユーザーデータを取得
|
|
@@ -1006,13 +1097,13 @@ cmdbox.save_user_data = async (cat, key, val) => {
|
|
|
1006
1097
|
* @returns {Promise}
|
|
1007
1098
|
*/
|
|
1008
1099
|
cmdbox.load_user_data = async (cat, key) => {
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1100
|
+
const formData = new FormData();
|
|
1101
|
+
formData.append('categoly', cat);
|
|
1102
|
+
if (key) formData.append('key', key);
|
|
1103
|
+
const res = await fetch('gui/user_data/load', {method:'POST', body:formData});
|
|
1104
|
+
if (!res.ok) cmdbox.message({'error':`${res.status}: ${res.statusText}`});
|
|
1105
|
+
const data = await res.json();
|
|
1106
|
+
return data;
|
|
1016
1107
|
};
|
|
1017
1108
|
/**
|
|
1018
1109
|
* ユーザーデータを削除
|
|
@@ -1021,13 +1112,13 @@ cmdbox.load_user_data = async (cat, key) => {
|
|
|
1021
1112
|
* @returns {Promise}
|
|
1022
1113
|
*/
|
|
1023
1114
|
cmdbox.delete_user_data = async (cat, key) => {
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1115
|
+
const formData = new FormData();
|
|
1116
|
+
formData.append('categoly', cat);
|
|
1117
|
+
formData.append('key', key);
|
|
1118
|
+
const res = await fetch('gui/user_data/delete', {method:'POST', body:formData});
|
|
1119
|
+
if (!res.ok) cmdbox.message({'error':`${res.status}: ${res.statusText}`});
|
|
1120
|
+
const data = await res.json();
|
|
1121
|
+
return data;
|
|
1031
1122
|
};
|
|
1032
1123
|
/**
|
|
1033
1124
|
* コマンドピンを保存
|
|
@@ -1035,7 +1126,7 @@ cmdbox.delete_user_data = async (cat, key) => {
|
|
|
1035
1126
|
* @param {bool} pin - ピン
|
|
1036
1127
|
*/
|
|
1037
1128
|
cmdbox.save_cmd_pin = async (title, pin) => {
|
|
1038
|
-
|
|
1129
|
+
return await cmdbox.save_user_data('cmdpins', title, pin?'on':'off');
|
|
1039
1130
|
};
|
|
1040
1131
|
/**
|
|
1041
1132
|
* コマンドピンをロード
|
|
@@ -1043,7 +1134,7 @@ cmdbox.save_cmd_pin = async (title, pin) => {
|
|
|
1043
1134
|
* @returns {Promise}
|
|
1044
1135
|
*/
|
|
1045
1136
|
cmdbox.load_cmd_pin = async (title) => {
|
|
1046
|
-
|
|
1137
|
+
return await cmdbox.load_user_data('cmdpins', title);
|
|
1047
1138
|
};
|
|
1048
1139
|
/**
|
|
1049
1140
|
* パイプピンを保存
|
|
@@ -1051,7 +1142,7 @@ cmdbox.load_cmd_pin = async (title) => {
|
|
|
1051
1142
|
* @param {bool} pin - ピン
|
|
1052
1143
|
*/
|
|
1053
1144
|
cmdbox.save_pipe_pin = async (title, pin) => {
|
|
1054
|
-
|
|
1145
|
+
return await cmdbox.save_user_data('pipepins', title, pin?'on':'off');
|
|
1055
1146
|
};
|
|
1056
1147
|
/**
|
|
1057
1148
|
* パイプピンをロード
|
|
@@ -1059,7 +1150,7 @@ cmdbox.save_pipe_pin = async (title, pin) => {
|
|
|
1059
1150
|
* @returns {Promise}
|
|
1060
1151
|
*/
|
|
1061
1152
|
cmdbox.load_pipe_pin = async (title) => {
|
|
1062
|
-
|
|
1153
|
+
return await cmdbox.load_user_data('pipepins', title);
|
|
1063
1154
|
}
|
|
1064
1155
|
/**
|
|
1065
1156
|
* コマンドモーダルのフォームを追加
|
|
@@ -1073,217 +1164,217 @@ cmdbox.load_pipe_pin = async (title) => {
|
|
|
1073
1164
|
* @returns {void}
|
|
1074
1165
|
*/
|
|
1075
1166
|
cmdbox.add_form_func = (i, cmd_modal, row_content, row, next_elem, lcolsize=12, scolsize=6) => {
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
+'<label class="input-group-text row_content_template_title">title</label>'
|
|
1092
|
-
+'<input type="text" class="form-control row_content_key row_content_template_input">'
|
|
1093
|
-
+'<label class="input-group-text">=</label>'
|
|
1094
|
-
+'<input type="text" class="form-control row_content_val row_content_template_input">'
|
|
1095
|
-
+'</div></div>');
|
|
1096
|
-
} else {
|
|
1097
|
-
elem = $(`<div class="col-${scolsize} mb-3">` // row_content_template_str
|
|
1098
|
-
+'<div class="input-group">'
|
|
1099
|
-
+'<label class="input-group-text row_content_template_title">title</label>'
|
|
1100
|
-
+'<input type="text" class="form-control row_content_template_input">'
|
|
1101
|
-
+'</div></div>');
|
|
1102
|
-
}
|
|
1103
|
-
if (next_elem) next_elem.after(elem);
|
|
1104
|
-
else row_content.append(elem);
|
|
1105
|
-
input_elem = elem.find('.row_content_template_input');
|
|
1106
|
-
if(row.type=='date') input_elem.attr('type', 'date');
|
|
1107
|
-
else if(row.type=='datetime') input_elem.attr('type', 'datetime-local');
|
|
1108
|
-
input_elem.removeClass('row_content_template_input');
|
|
1109
|
-
input_elem.val(row.default);
|
|
1110
|
-
}
|
|
1111
|
-
else {
|
|
1112
|
-
// 選択肢がある場合
|
|
1113
|
-
if(row.type=='dict') {
|
|
1114
|
-
if (Array.isArray(row.choice)) {
|
|
1115
|
-
elem = $(`<div class="col-${lcolsize} mb-3">` // row_content_template_dict_choice
|
|
1116
|
-
+'<div class="input-group">'
|
|
1167
|
+
const target_name = row.opt;
|
|
1168
|
+
// clmsg_idのオプションは隠しオプション扱い。restapiで指定はできる。
|
|
1169
|
+
if (target_name=='clmsg_id') return;
|
|
1170
|
+
let input_elem, elem;
|
|
1171
|
+
if(!row.choice) {
|
|
1172
|
+
// 選択肢がない場合
|
|
1173
|
+
if(row.type=='text') {
|
|
1174
|
+
elem = $(`<div class="col-${lcolsize} mb-3">` // row_content_template_text
|
|
1175
|
+
+'<div class="input-group">'
|
|
1176
|
+
+'<label class="input-group-text row_content_template_title">title</label>'
|
|
1177
|
+
+'<textarea class="form-control row_content_template_input" rows="1" style="field-sizing:content;"></textarea>'
|
|
1178
|
+
+'</div></div>');
|
|
1179
|
+
} else if(row.type=='dict') {
|
|
1180
|
+
elem = $(`<div class="col-${lcolsize} mb-3">` // row_content_template_dict
|
|
1181
|
+
+'<div class="input-group">'
|
|
1117
1182
|
+'<label class="input-group-text row_content_template_title">title</label>'
|
|
1118
1183
|
+'<input type="text" class="form-control row_content_key row_content_template_input">'
|
|
1119
1184
|
+'<label class="input-group-text">=</label>'
|
|
1120
|
-
+'<
|
|
1185
|
+
+'<input type="text" class="form-control row_content_val row_content_template_input">'
|
|
1121
1186
|
+'</div></div>');
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1187
|
+
} else {
|
|
1188
|
+
elem = $(`<div class="col-${scolsize} mb-3">` // row_content_template_str
|
|
1189
|
+
+'<div class="input-group">'
|
|
1190
|
+
+'<label class="input-group-text row_content_template_title">title</label>'
|
|
1191
|
+
+'<input type="text" class="form-control row_content_template_input">'
|
|
1192
|
+
+'</div></div>');
|
|
1193
|
+
}
|
|
1194
|
+
if (next_elem) next_elem.after(elem);
|
|
1195
|
+
else row_content.append(elem);
|
|
1196
|
+
input_elem = elem.find('.row_content_template_input');
|
|
1197
|
+
if(row.type=='date') input_elem.attr('type', 'date');
|
|
1198
|
+
else if(row.type=='datetime') input_elem.attr('type', 'datetime-local');
|
|
1199
|
+
input_elem.removeClass('row_content_template_input');
|
|
1200
|
+
input_elem.val(row.default);
|
|
1201
|
+
}
|
|
1202
|
+
else {
|
|
1203
|
+
// 選択肢がある場合
|
|
1204
|
+
if(row.type=='dict') {
|
|
1205
|
+
if (Array.isArray(row.choice)) {
|
|
1206
|
+
elem = $(`<div class="col-${lcolsize} mb-3">` // row_content_template_dict_choice
|
|
1207
|
+
+'<div class="input-group">'
|
|
1208
|
+
+'<label class="input-group-text row_content_template_title">title</label>'
|
|
1209
|
+
+'<input type="text" class="form-control row_content_key row_content_template_input">'
|
|
1210
|
+
+'<label class="input-group-text">=</label>'
|
|
1211
|
+
+'<select class="form-select row_content_template_select"></select>'
|
|
1212
|
+
+'</div></div>');
|
|
1213
|
+
}
|
|
1214
|
+
else {
|
|
1215
|
+
elem = $(`<div class="col-${lcolsize} mb-3">` // row_content_template_dict_choice
|
|
1216
|
+
+'<div class="input-group">'
|
|
1217
|
+
+'<label class="input-group-text row_content_template_title">title</label>'
|
|
1218
|
+
+'<select class="form-select row_content_key row_content_template_select"></select>'
|
|
1219
|
+
+'<label class="input-group-text">=</label>'
|
|
1220
|
+
+'<select class="form-select row_content_template_select"></select>'
|
|
1221
|
+
+'</div></div>');
|
|
1222
|
+
}
|
|
1223
|
+
} else {
|
|
1224
|
+
elem = $(`<div class="col-${scolsize} mb-3">` // row_content_template_choice
|
|
1225
|
+
+'<div class="input-group">'
|
|
1126
1226
|
+'<label class="input-group-text row_content_template_title">title</label>'
|
|
1127
|
-
+'<select class="form-select row_content_key row_content_template_select"></select>'
|
|
1128
|
-
+'<label class="input-group-text">=</label>'
|
|
1129
1227
|
+'<select class="form-select row_content_template_select"></select>'
|
|
1130
1228
|
+'</div></div>');
|
|
1131
|
-
|
|
1229
|
+
}
|
|
1230
|
+
if (next_elem) next_elem.after(elem);
|
|
1231
|
+
else row_content.append(elem);
|
|
1232
|
+
input_elem = elem.find('.row_content_template_select,.row_content_template_input');
|
|
1233
|
+
input_elem.removeClass('row_content_template_select').removeClass('row_content_template_input');
|
|
1234
|
+
if (row.choice_show) {
|
|
1235
|
+
input_elem.addClass('choice_show');
|
|
1236
|
+
input_elem.change(() => {
|
|
1237
|
+
let names = []
|
|
1238
|
+
for (const ns of Object.values(row.choice_show)) {
|
|
1239
|
+
if (Array.isArray(ns)) {
|
|
1240
|
+
ns.forEach(n => names.push(n));
|
|
1241
|
+
} else {
|
|
1242
|
+
names.push(ns);
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
names = [...new Set(names)];
|
|
1246
|
+
names.forEach(name => row_content.find(`[name="${name}"]`).parent().parent().hide());
|
|
1247
|
+
const v = input_elem.val();
|
|
1248
|
+
if (!row.choice_show[v]) return;
|
|
1249
|
+
row.choice_show[v].forEach(n => row_content.find(`[name="${n}"]`).parent().parent().show());
|
|
1250
|
+
});
|
|
1251
|
+
}
|
|
1252
|
+
// 配列をoptionタグに変換
|
|
1253
|
+
const mkopt = (arr) => {
|
|
1254
|
+
if (!arr) return '';
|
|
1255
|
+
const opt = arr.map(row => {
|
|
1256
|
+
if (row && typeof row === 'object') {
|
|
1257
|
+
key = Object.keys(row)[0];
|
|
1258
|
+
d = window.navigator.language=='ja'?row[key].discription_ja:row[key].discription_en;
|
|
1259
|
+
return `<option value="${key}" discription="${d}">${key}</option>`;
|
|
1260
|
+
}
|
|
1261
|
+
return `<option value="${row}" discription="">${row}</option>`;
|
|
1262
|
+
}).join('');
|
|
1263
|
+
return opt;
|
|
1264
|
+
}
|
|
1265
|
+
if (Array.isArray(row.choice)) {
|
|
1266
|
+
// 配列の場合
|
|
1267
|
+
input_elem.html(mkopt(row.choice));
|
|
1268
|
+
input_elem.val(`${row.default!=null?row.default:''}`);
|
|
1269
|
+
} else {
|
|
1270
|
+
// 辞書の場合
|
|
1271
|
+
const cho = [row.choice['key'], row.choice['val']];
|
|
1272
|
+
let def = row.default!=null?[row.default, row.default]:null;
|
|
1273
|
+
if (row.default && typeof row.default === 'object') {
|
|
1274
|
+
def[0] = Object.keys(row.default)[0];
|
|
1275
|
+
def[1] = row.default[def[0]];
|
|
1276
|
+
}
|
|
1277
|
+
input_elem.each((i, e) => {
|
|
1278
|
+
$(e).html(mkopt(cho[i]));
|
|
1279
|
+
$(e).val(`${def!=null?def[i]:''}`);
|
|
1280
|
+
});
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
let index = 0;
|
|
1284
|
+
if (cmd_modal.find(`[name="${target_name}"]`).length > 0) {
|
|
1285
|
+
index = 0;
|
|
1286
|
+
cmd_modal.find(`[name="${target_name}"][param_data_index]`).each((i, val) => {
|
|
1287
|
+
v = Number($(val).attr('param_data_index'));
|
|
1288
|
+
if (index <= v) index = v + 1;
|
|
1289
|
+
});
|
|
1290
|
+
}
|
|
1291
|
+
input_elem.attr('name', target_name);
|
|
1292
|
+
if(row.type=='dict') {
|
|
1293
|
+
input_elem.each((i, e) => {
|
|
1294
|
+
$(e).attr('id', target_name + (index + i));
|
|
1295
|
+
$(e).attr('param_data_index', (index + i));
|
|
1296
|
+
});
|
|
1132
1297
|
} else {
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
+'<label class="input-group-text row_content_template_title">title</label>'
|
|
1136
|
-
+'<select class="form-select row_content_template_select"></select>'
|
|
1137
|
-
+'</div></div>');
|
|
1298
|
+
input_elem.attr('id', target_name + index);
|
|
1299
|
+
input_elem.attr('param_data_index', index);
|
|
1138
1300
|
}
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
input_elem
|
|
1142
|
-
input_elem.
|
|
1143
|
-
if (row.
|
|
1144
|
-
|
|
1145
|
-
input_elem.change(() => {
|
|
1146
|
-
let names = []
|
|
1147
|
-
for (const ns of Object.values(row.choice_show)) {
|
|
1148
|
-
if (Array.isArray(ns)) {
|
|
1149
|
-
ns.forEach(n => names.push(n));
|
|
1150
|
-
} else {
|
|
1151
|
-
names.push(ns);
|
|
1152
|
-
}
|
|
1153
|
-
}
|
|
1154
|
-
names = [...new Set(names)];
|
|
1155
|
-
names.forEach(name => row_content.find(`[name="${name}"]`).parent().parent().hide());
|
|
1156
|
-
const v = input_elem.val();
|
|
1157
|
-
if (!row.choice_show[v]) return;
|
|
1158
|
-
row.choice_show[v].forEach(n => row_content.find(`[name="${n}"]`).parent().parent().show());
|
|
1159
|
-
});
|
|
1301
|
+
input_elem.attr('required', row.required);
|
|
1302
|
+
input_elem.attr('param_data_type', row.type);
|
|
1303
|
+
input_elem.attr('param_data_multi', row.multi);
|
|
1304
|
+
input_elem.attr('param_data_web', row.web);
|
|
1305
|
+
if (row.web=='mask' || row.web=='readonly') {
|
|
1306
|
+
input_elem.attr('disabled', 'disabled');
|
|
1160
1307
|
}
|
|
1161
|
-
//
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1308
|
+
// ファイルタイプの場合はファイラーモーダルを開くボタンを追加
|
|
1309
|
+
if(row.type=='file'){
|
|
1310
|
+
const btn = $('<button class="btn btn-secondary" type="button">file</button>');
|
|
1311
|
+
input_elem.parent().append(btn);
|
|
1312
|
+
const mk_func = (tid, tn) => {
|
|
1313
|
+
// tid, tnの値を残すためにクロージャーにする
|
|
1314
|
+
return () => {
|
|
1315
|
+
const current_path = $(`[id="${tid}"]`).val();
|
|
1316
|
+
fmodal.filer_modal_func(tid, tn, current_path, false, true);
|
|
1317
|
+
}
|
|
1169
1318
|
}
|
|
1170
|
-
|
|
1171
|
-
}).join('');
|
|
1172
|
-
return opt;
|
|
1319
|
+
btn.click(mk_func(input_elem.attr('id'), input_elem.attr('name')));
|
|
1173
1320
|
}
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
input_elem.each((i, e) => {
|
|
1187
|
-
$(e).html(mkopt(cho[i]));
|
|
1188
|
-
$(e).val(`${def!=null?def[i]:''}`);
|
|
1189
|
-
});
|
|
1321
|
+
// ディレクトリタイプの場合はファイラーモーダルを開くボタンを追加
|
|
1322
|
+
if(row.type=='dir'){
|
|
1323
|
+
const btn = $('<button class="btn btn-secondary" type="button">dir</button>');
|
|
1324
|
+
input_elem.parent().append(btn);
|
|
1325
|
+
const mk_func = (tid, tn) => {
|
|
1326
|
+
// tid, tnの値を残すためにクロージャーにする
|
|
1327
|
+
return () => {
|
|
1328
|
+
const current_path = $(`[id="${tid}"]`).val();
|
|
1329
|
+
fmodal.filer_modal_func(tid, tn, current_path, true, true);
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
btn.click(mk_func(input_elem.attr('id'), input_elem.attr('name')));
|
|
1190
1333
|
}
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
if(row.type=='file'){
|
|
1219
|
-
const btn = $('<button class="btn btn-secondary" type="button">file</button>');
|
|
1220
|
-
input_elem.parent().append(btn);
|
|
1221
|
-
const mk_func = (tid, tn) => {
|
|
1222
|
-
// tid, tnの値を残すためにクロージャーにする
|
|
1223
|
-
return () => {
|
|
1224
|
-
const current_path = $(`[id="${tid}"]`).val();
|
|
1225
|
-
fmodal.filer_modal_func(tid, tn, current_path, false, true);
|
|
1226
|
-
}
|
|
1334
|
+
// マルチの場合は追加ボタンを追加
|
|
1335
|
+
if(row.multi){
|
|
1336
|
+
const btn_a = $('<button class="btn btn-secondary add_buton" type="button"></button>');
|
|
1337
|
+
btn_a.append('<svg class="bi bi-plus" width="16" height="16" fill="currentColor"><use href="#btn_plus"></use></svg>');
|
|
1338
|
+
input_elem.parent().append(btn_a);
|
|
1339
|
+
let mk_func = (row, next_elem) => {
|
|
1340
|
+
// row, next_elemの値を残すためにクロージャーにする
|
|
1341
|
+
return () => {
|
|
1342
|
+
const r = {...row};
|
|
1343
|
+
//r.hide = next_elem.is(':hidden');
|
|
1344
|
+
cmdbox.add_form_func(0, cmd_modal, row_content, r, next_elem, lcolsize, scolsize);
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
btn_a.click(mk_func(row, input_elem.parent().parent()));
|
|
1348
|
+
// 2個目以降は削除ボタンを追加
|
|
1349
|
+
const len = cmd_modal.find(`[name="${target_name}"]`).length;
|
|
1350
|
+
if (row.type!='dict' && len > 1 || row.type=='dict' && len > 2) {
|
|
1351
|
+
mk_func = (del_elem, row) => {
|
|
1352
|
+
// del_elemの値を残すためにクロージャーにする
|
|
1353
|
+
return () => del_elem.remove();
|
|
1354
|
+
}
|
|
1355
|
+
const btn_t = $('<button class="btn btn-secondary" type="button"></button>');
|
|
1356
|
+
btn_trash
|
|
1357
|
+
btn_t.append('<svg class="bi bi-trash" width="16" height="16" fill="currentColor"><use href="#btn_trash"></use></svg>');
|
|
1358
|
+
input_elem.parent().append(btn_t);
|
|
1359
|
+
btn_t.click(mk_func(input_elem.parent().parent(), row));
|
|
1360
|
+
}
|
|
1227
1361
|
}
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
input_elem.parent().append(btn);
|
|
1234
|
-
const mk_func = (tid, tn) => {
|
|
1235
|
-
// tid, tnの値を残すためにクロージャーにする
|
|
1236
|
-
return () => {
|
|
1237
|
-
const current_path = $(`[id="${tid}"]`).val();
|
|
1238
|
-
fmodal.filer_modal_func(tid, tn, current_path, true, true);
|
|
1239
|
-
}
|
|
1362
|
+
const title = elem.find('.row_content_template_title');
|
|
1363
|
+
title.html('');
|
|
1364
|
+
title.attr('title', window.navigator.language=='ja'?row.discription_ja:row.discription_en)
|
|
1365
|
+
if (row.required) {
|
|
1366
|
+
title.append('<span class="text-danger" title="required">*</span>');
|
|
1240
1367
|
}
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
// マルチの場合は追加ボタンを追加
|
|
1244
|
-
if(row.multi){
|
|
1245
|
-
const btn_a = $('<button class="btn btn-secondary add_buton" type="button"></button>');
|
|
1246
|
-
btn_a.append('<svg class="bi bi-plus" width="16" height="16" fill="currentColor"><use href="#btn_plus"></use></svg>');
|
|
1247
|
-
input_elem.parent().append(btn_a);
|
|
1248
|
-
let mk_func = (row, next_elem) => {
|
|
1249
|
-
// row, next_elemの値を残すためにクロージャーにする
|
|
1250
|
-
return () => {
|
|
1251
|
-
const r = {...row};
|
|
1252
|
-
//r.hide = next_elem.is(':hidden');
|
|
1253
|
-
cmdbox.add_form_func(0, cmd_modal, row_content, r, next_elem, lcolsize, scolsize);
|
|
1254
|
-
}
|
|
1368
|
+
if (row.choice_show) {
|
|
1369
|
+
title.append('<span class="text-primary" title="choice_show">*</span>');
|
|
1255
1370
|
}
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
return () => del_elem.remove();
|
|
1263
|
-
}
|
|
1264
|
-
const btn_t = $('<button class="btn btn-secondary" type="button"></button>');
|
|
1265
|
-
btn_trash
|
|
1266
|
-
btn_t.append('<svg class="bi bi-trash" width="16" height="16" fill="currentColor"><use href="#btn_trash"></use></svg>');
|
|
1267
|
-
input_elem.parent().append(btn_t);
|
|
1268
|
-
btn_t.click(mk_func(input_elem.parent().parent(), row));
|
|
1371
|
+
title.append(`<span>${row.opt}</span>`);
|
|
1372
|
+
if (row.hide) {
|
|
1373
|
+
if (row_content.find('.row_content_hide').is(':hidden')) elem.hide();
|
|
1374
|
+
elem.addClass('row_content_hide');
|
|
1375
|
+
} else {
|
|
1376
|
+
title.addClass('text-decoration-underline');
|
|
1269
1377
|
}
|
|
1270
|
-
}
|
|
1271
|
-
const title = elem.find('.row_content_template_title');
|
|
1272
|
-
title.html('');
|
|
1273
|
-
title.attr('title', window.navigator.language=='ja'?row.discription_ja:row.discription_en)
|
|
1274
|
-
if (row.required) {
|
|
1275
|
-
title.append('<span class="text-danger" title="required">*</span>');
|
|
1276
|
-
}
|
|
1277
|
-
if (row.choice_show) {
|
|
1278
|
-
title.append('<span class="text-primary" title="choice_show">*</span>');
|
|
1279
|
-
}
|
|
1280
|
-
title.append(`<span>${row.opt}</span>`);
|
|
1281
|
-
if (row.hide) {
|
|
1282
|
-
if (row_content.find('.row_content_hide').is(':hidden')) elem.hide();
|
|
1283
|
-
elem.addClass('row_content_hide');
|
|
1284
|
-
} else {
|
|
1285
|
-
title.addClass('text-decoration-underline');
|
|
1286
|
-
}
|
|
1287
1378
|
}
|
|
1288
1379
|
/**
|
|
1289
1380
|
* コマンド選択肢取得
|
|
@@ -1292,116 +1383,116 @@ cmdbox.add_form_func = (i, cmd_modal, row_content, row, next_elem, lcolsize=12,
|
|
|
1292
1383
|
* @returns {Promise} - コマンドオプション
|
|
1293
1384
|
*/
|
|
1294
1385
|
cmdbox.get_cmd_choices = async (mode, cmd) => {
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1386
|
+
const formData = new FormData();
|
|
1387
|
+
formData.append('mode', mode);
|
|
1388
|
+
formData.append('cmd', cmd);
|
|
1389
|
+
const res = await fetch('gui/get_cmd_choices', {method: 'POST', body: formData});
|
|
1390
|
+
if (res.status != 200) cmdbox.message({'error':`${res.status}: ${res.statusText}`});
|
|
1391
|
+
return await res.json();
|
|
1301
1392
|
}
|
|
1302
1393
|
// コマンドフォームからパラメータを取得
|
|
1303
1394
|
cmdbox.get_param = (modal_elem) => {
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
}
|
|
1320
|
-
}
|
|
1321
|
-
const isInt = (i) => {
|
|
1322
|
-
try {
|
|
1323
|
-
n = Number(i);
|
|
1324
|
-
return n % 1 === 0;
|
|
1325
|
-
} catch(e) {
|
|
1326
|
-
return false;
|
|
1327
|
-
}
|
|
1328
|
-
}
|
|
1329
|
-
// フォームの入力値をチェック(不正な値があればフォームに'is-invalid'クラスを付加する)
|
|
1330
|
-
const dict_buf = {};
|
|
1331
|
-
modal_elem.find('.row_content, .row_content_common').find('input, select, textarea').each((i, elem) => {
|
|
1332
|
-
const data_name = $(elem).attr('name');
|
|
1333
|
-
let data_val = $(elem).val();
|
|
1334
|
-
const data_type = $(elem).attr('param_data_type');
|
|
1335
|
-
const data_web = $(elem).attr('param_data_web');
|
|
1336
|
-
const data_index = parseInt($(elem).attr('param_data_index'));
|
|
1337
|
-
const data_multi = $(elem).attr('param_data_multi');
|
|
1338
|
-
if ($(elem).attr('required') && (!data_val || data_val=='')) {
|
|
1339
|
-
$(elem).addClass('is-invalid');
|
|
1340
|
-
} else if (data_type=='int' && !data_web) {
|
|
1341
|
-
if(data_val && data_val!='') {
|
|
1342
|
-
if(!isInt(data_val)) $(elem).addClass('is-invalid');
|
|
1343
|
-
else {
|
|
1344
|
-
$(elem).removeClass('is-invalid');
|
|
1345
|
-
$(elem).addClass('is-valid');
|
|
1346
|
-
data_val = parseInt(data_val);
|
|
1395
|
+
modal_elem.find('.is-invalid, .is-valid').removeClass('is-invalid').removeClass('is-valid');
|
|
1396
|
+
const opt = {};
|
|
1397
|
+
const title = modal_elem.find('[name="title"]').val();
|
|
1398
|
+
opt["modal_mode"] = modal_elem.find('[name="modal_mode"]').val();
|
|
1399
|
+
opt["mode"] = modal_elem.find('[name="mode"]').val();
|
|
1400
|
+
opt["cmd"] = modal_elem.find('[name="cmd"]').val();
|
|
1401
|
+
if(!opt["mode"]) delete opt["mode"];
|
|
1402
|
+
if(!opt["cmd"]) delete opt["cmd"];
|
|
1403
|
+
opt["title"] = title;
|
|
1404
|
+
const isFloat = (i) => {
|
|
1405
|
+
try {
|
|
1406
|
+
n = Number(i);
|
|
1407
|
+
return n % 1 !== 0;
|
|
1408
|
+
} catch(e) {
|
|
1409
|
+
return false;
|
|
1347
1410
|
}
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
else {
|
|
1356
|
-
$(elem).removeClass('is-invalid');
|
|
1357
|
-
$(elem).addClass('is-valid');
|
|
1358
|
-
data_val = parseFloat(data_val);
|
|
1411
|
+
}
|
|
1412
|
+
const isInt = (i) => {
|
|
1413
|
+
try {
|
|
1414
|
+
n = Number(i);
|
|
1415
|
+
return n % 1 === 0;
|
|
1416
|
+
} catch(e) {
|
|
1417
|
+
return false;
|
|
1359
1418
|
}
|
|
1360
|
-
} else {
|
|
1361
|
-
$(elem).removeClass('is-invalid');
|
|
1362
|
-
$(elem).addClass('is-valid');
|
|
1363
|
-
}
|
|
1364
|
-
} else if (data_type=='bool') {
|
|
1365
|
-
if(data_val!='true' && data_val!='false' && !$(elem).prop('disabled')) $(elem).addClass('is-invalid');
|
|
1366
|
-
else {
|
|
1367
|
-
data_val = data_val=='true';
|
|
1368
|
-
$(elem).removeClass('is-invalid');
|
|
1369
|
-
$(elem).addClass('is-valid');
|
|
1370
|
-
}
|
|
1371
|
-
} else if (data_type=='dict') {
|
|
1372
|
-
data_val = data_val ? data_val : '';
|
|
1373
|
-
if(data_val.indexOf(' ')>=0) $(elem).addClass('is-invalid');
|
|
1374
|
-
else {
|
|
1375
|
-
$(elem).removeClass('is-invalid');
|
|
1376
|
-
$(elem).addClass('is-valid');
|
|
1377
|
-
}
|
|
1378
|
-
} else if (data_type=='text') {
|
|
1379
|
-
$(elem).removeClass('is-invalid');
|
|
1380
|
-
$(elem).addClass('is-valid');
|
|
1381
|
-
} else {
|
|
1382
|
-
$(elem).removeClass('is-invalid');
|
|
1383
|
-
$(elem).addClass('is-valid');
|
|
1384
1419
|
}
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1420
|
+
// フォームの入力値をチェック(不正な値があればフォームに'is-invalid'クラスを付加する)
|
|
1421
|
+
const dict_buf = {};
|
|
1422
|
+
modal_elem.find('.row_content, .row_content_common').find('input, select, textarea').each((i, elem) => {
|
|
1423
|
+
const data_name = $(elem).attr('name');
|
|
1424
|
+
let data_val = $(elem).val();
|
|
1425
|
+
const data_type = $(elem).attr('param_data_type');
|
|
1426
|
+
const data_web = $(elem).attr('param_data_web');
|
|
1427
|
+
const data_index = parseInt($(elem).attr('param_data_index'));
|
|
1428
|
+
const data_multi = $(elem).attr('param_data_multi');
|
|
1429
|
+
if ($(elem).attr('required') && (!data_val || data_val=='')) {
|
|
1430
|
+
$(elem).addClass('is-invalid');
|
|
1431
|
+
} else if (data_type=='int' && !data_web) {
|
|
1432
|
+
if(data_val && data_val!='') {
|
|
1433
|
+
if(!isInt(data_val)) $(elem).addClass('is-invalid');
|
|
1434
|
+
else {
|
|
1435
|
+
$(elem).removeClass('is-invalid');
|
|
1436
|
+
$(elem).addClass('is-valid');
|
|
1437
|
+
data_val = parseInt(data_val);
|
|
1438
|
+
}
|
|
1439
|
+
} else {
|
|
1440
|
+
$(elem).removeClass('is-invalid');
|
|
1441
|
+
$(elem).addClass('is-valid');
|
|
1442
|
+
}
|
|
1443
|
+
} else if (data_type=='float') {
|
|
1444
|
+
if(data_val && data_val!='') {
|
|
1445
|
+
if(!isFloat(data_val) && !isInt(data_val)) $(elem).addClass('is-invalid');
|
|
1446
|
+
else {
|
|
1447
|
+
$(elem).removeClass('is-invalid');
|
|
1448
|
+
$(elem).addClass('is-valid');
|
|
1449
|
+
data_val = parseFloat(data_val);
|
|
1450
|
+
}
|
|
1451
|
+
} else {
|
|
1452
|
+
$(elem).removeClass('is-invalid');
|
|
1453
|
+
$(elem).addClass('is-valid');
|
|
1454
|
+
}
|
|
1455
|
+
} else if (data_type=='bool') {
|
|
1456
|
+
if(data_val!='true' && data_val!='false' && !$(elem).prop('disabled')) $(elem).addClass('is-invalid');
|
|
1457
|
+
else {
|
|
1458
|
+
data_val = data_val=='true';
|
|
1459
|
+
$(elem).removeClass('is-invalid');
|
|
1460
|
+
$(elem).addClass('is-valid');
|
|
1461
|
+
}
|
|
1462
|
+
} else if (data_type=='dict') {
|
|
1463
|
+
data_val = data_val ? data_val : '';
|
|
1464
|
+
if(data_val.indexOf(' ')>=0) $(elem).addClass('is-invalid');
|
|
1465
|
+
else {
|
|
1466
|
+
$(elem).removeClass('is-invalid');
|
|
1467
|
+
$(elem).addClass('is-valid');
|
|
1468
|
+
}
|
|
1469
|
+
} else if (data_type=='text') {
|
|
1470
|
+
$(elem).removeClass('is-invalid');
|
|
1471
|
+
$(elem).addClass('is-valid');
|
|
1472
|
+
} else {
|
|
1473
|
+
$(elem).removeClass('is-invalid');
|
|
1474
|
+
$(elem).addClass('is-valid');
|
|
1390
1475
|
}
|
|
1391
|
-
if(
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1476
|
+
if(data_multi=='true' || data_type=='dict') {
|
|
1477
|
+
if (data_type=='dict') {
|
|
1478
|
+
if(!opt[data_name]) {
|
|
1479
|
+
opt[data_name] = {};
|
|
1480
|
+
dict_buf[data_name] = {};
|
|
1481
|
+
}
|
|
1482
|
+
if(data_index%2==0) dict_buf[data_name]['key'] = data_val;
|
|
1483
|
+
else if (dict_buf[data_name]['key']) {
|
|
1484
|
+
opt[data_name][dict_buf[data_name]['key']] = data_val;
|
|
1485
|
+
delete dict_buf[data_name]['key'];
|
|
1486
|
+
}
|
|
1487
|
+
} else {
|
|
1488
|
+
if(!opt[data_name]) opt[data_name] = [];
|
|
1489
|
+
if(data_val && data_val!='') opt[data_name].push(data_val);
|
|
1490
|
+
else if(data_val==false) opt[data_name].push(data_val);
|
|
1491
|
+
}
|
|
1492
|
+
} else {
|
|
1493
|
+
if(data_val && data_val!='') opt[data_name] = data_val;
|
|
1494
|
+
else if(data_val==false) opt[data_name] = data_val;
|
|
1395
1495
|
}
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
else if(data_val==false) opt[data_name].push(data_val);
|
|
1400
|
-
}
|
|
1401
|
-
} else {
|
|
1402
|
-
if(data_val && data_val!='') opt[data_name] = data_val;
|
|
1403
|
-
else if(data_val==false) opt[data_name] = data_val;
|
|
1404
|
-
}
|
|
1405
|
-
});
|
|
1406
|
-
return [title, opt];
|
|
1407
|
-
}
|
|
1496
|
+
});
|
|
1497
|
+
return [title, opt];
|
|
1498
|
+
}
|