add cloud shell in device simulation (#354)
* add cloud shell in device simulation * address comments * update test
This commit is contained in:
Родитель
2e725e8226
Коммит
1e22027bb1
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.4 KiB |
|
@ -837,6 +837,49 @@
|
|||
"resolved": "https://registry.npmjs.org/@microsoft/load-themed-styles/-/load-themed-styles-1.10.39.tgz",
|
||||
"integrity": "sha512-KKeQSM0FMTR7VtvkVF+D488zUmO3YoImxJ3O2xyLDEu9GqxqthF3Zvv1GddC2Jyoj2vuAJ0RGGgrI/T+MxLLDg=="
|
||||
},
|
||||
"@nodelib/fs.scandir": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
|
||||
"integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@nodelib/fs.stat": "2.0.3",
|
||||
"run-parallel": "^1.1.9"
|
||||
}
|
||||
},
|
||||
"@nodelib/fs.stat": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz",
|
||||
"integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==",
|
||||
"dev": true
|
||||
},
|
||||
"@nodelib/fs.walk": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz",
|
||||
"integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@nodelib/fs.scandir": "2.1.3",
|
||||
"fastq": "^1.6.0"
|
||||
}
|
||||
},
|
||||
"@npmcli/move-file": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.0.1.tgz",
|
||||
"integrity": "sha512-Uv6h1sT+0DrblvIrolFtbvM1FgWm+/sy4B3pvLp67Zys+thcukzS5ekn7HsZFGpWP4Q3fYJCljbWQE/XivMRLw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mkdirp": "^1.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"mkdirp": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@redux-saga/core": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@redux-saga/core/-/core-1.1.3.tgz",
|
||||
|
@ -1737,6 +1780,24 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"aggregate-error": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
|
||||
"integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"clean-stack": "^2.0.0",
|
||||
"indent-string": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"indent-string": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
|
||||
"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"airbnb-prop-types": {
|
||||
"version": "2.15.0",
|
||||
"resolved": "https://registry.npmjs.org/airbnb-prop-types/-/airbnb-prop-types-2.15.0.tgz",
|
||||
|
@ -3539,6 +3600,12 @@
|
|||
"source-map": "~0.6.0"
|
||||
}
|
||||
},
|
||||
"clean-stack": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
|
||||
"integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
|
||||
"dev": true
|
||||
},
|
||||
"cli-boxes": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz",
|
||||
|
@ -4044,6 +4111,206 @@
|
|||
"integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
|
||||
"dev": true
|
||||
},
|
||||
"copy-webpack-plugin": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-6.1.0.tgz",
|
||||
"integrity": "sha512-aWjIuLt1OVQxaDVffnt3bnGmLA8zGgAJaFwPA+a+QYVPh1vhIKjVfh3SbOFLV0kRPvGBITbw17n5CsmiBS4LQQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cacache": "^15.0.5",
|
||||
"fast-glob": "^3.2.4",
|
||||
"find-cache-dir": "^3.3.1",
|
||||
"glob-parent": "^5.1.1",
|
||||
"globby": "^11.0.1",
|
||||
"loader-utils": "^2.0.0",
|
||||
"normalize-path": "^3.0.0",
|
||||
"p-limit": "^3.0.2",
|
||||
"schema-utils": "^2.7.1",
|
||||
"serialize-javascript": "^4.0.0",
|
||||
"webpack-sources": "^1.4.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/json-schema": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz",
|
||||
"integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==",
|
||||
"dev": true
|
||||
},
|
||||
"ajv": {
|
||||
"version": "6.12.4",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz",
|
||||
"integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.4.1",
|
||||
"uri-js": "^4.2.2"
|
||||
}
|
||||
},
|
||||
"ajv-keywords": {
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
|
||||
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
|
||||
"dev": true
|
||||
},
|
||||
"array-union": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
|
||||
"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
|
||||
"dev": true
|
||||
},
|
||||
"cacache": {
|
||||
"version": "15.0.5",
|
||||
"resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.5.tgz",
|
||||
"integrity": "sha512-lloiL22n7sOjEEXdL8NAjTgv9a1u43xICE9/203qonkZUCj5X1UEWIdf2/Y0d6QcCtMzbKQyhrcDbdvlZTs/+A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@npmcli/move-file": "^1.0.1",
|
||||
"chownr": "^2.0.0",
|
||||
"fs-minipass": "^2.0.0",
|
||||
"glob": "^7.1.4",
|
||||
"infer-owner": "^1.0.4",
|
||||
"lru-cache": "^6.0.0",
|
||||
"minipass": "^3.1.1",
|
||||
"minipass-collect": "^1.0.2",
|
||||
"minipass-flush": "^1.0.5",
|
||||
"minipass-pipeline": "^1.2.2",
|
||||
"mkdirp": "^1.0.3",
|
||||
"p-map": "^4.0.0",
|
||||
"promise-inflight": "^1.0.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"ssri": "^8.0.0",
|
||||
"tar": "^6.0.2",
|
||||
"unique-filename": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"chownr": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
|
||||
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
|
||||
"dev": true
|
||||
},
|
||||
"find-cache-dir": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz",
|
||||
"integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"commondir": "^1.0.1",
|
||||
"make-dir": "^3.0.2",
|
||||
"pkg-dir": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"globby": {
|
||||
"version": "11.0.1",
|
||||
"resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz",
|
||||
"integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"array-union": "^2.1.0",
|
||||
"dir-glob": "^3.0.1",
|
||||
"fast-glob": "^3.1.1",
|
||||
"ignore": "^5.1.4",
|
||||
"merge2": "^1.3.0",
|
||||
"slash": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"json5": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz",
|
||||
"integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.5"
|
||||
}
|
||||
},
|
||||
"loader-utils": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
|
||||
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"big.js": "^5.2.2",
|
||||
"emojis-list": "^3.0.0",
|
||||
"json5": "^2.1.2"
|
||||
}
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
|
||||
"dev": true
|
||||
},
|
||||
"p-limit": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz",
|
||||
"integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"p-try": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"p-map": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
|
||||
"integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"aggregate-error": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"schema-utils": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
|
||||
"integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/json-schema": "^7.0.5",
|
||||
"ajv": "^6.12.4",
|
||||
"ajv-keywords": "^3.5.2"
|
||||
}
|
||||
},
|
||||
"ssri": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.0.tgz",
|
||||
"integrity": "sha512-aq/pz989nxVYwn16Tsbj1TqFpD5LLrQxHf5zaHuieFV+R0Bbr4y8qUsOA45hXT/N4/9UNXTarBjnjVmjSOVaAA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minipass": "^3.1.1"
|
||||
}
|
||||
},
|
||||
"tar": {
|
||||
"version": "6.0.5",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-6.0.5.tgz",
|
||||
"integrity": "sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chownr": "^2.0.0",
|
||||
"fs-minipass": "^2.0.0",
|
||||
"minipass": "^3.0.0",
|
||||
"minizlib": "^2.1.1",
|
||||
"mkdirp": "^1.0.3",
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
|
@ -4940,6 +5207,23 @@
|
|||
"randombytes": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"dir-glob": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
||||
"integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"path-type": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"path-type": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
|
||||
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"discontinuous-range": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz",
|
||||
|
@ -6115,6 +6399,65 @@
|
|||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
|
||||
"integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA=="
|
||||
},
|
||||
"fast-glob": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz",
|
||||
"integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@nodelib/fs.stat": "^2.0.2",
|
||||
"@nodelib/fs.walk": "^1.2.3",
|
||||
"glob-parent": "^5.1.0",
|
||||
"merge2": "^1.3.0",
|
||||
"micromatch": "^4.0.2",
|
||||
"picomatch": "^2.2.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fill-range": "^7.0.1"
|
||||
}
|
||||
},
|
||||
"fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"is-number": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true
|
||||
},
|
||||
"micromatch": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
|
||||
"integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"braces": "^3.0.1",
|
||||
"picomatch": "^2.0.5"
|
||||
}
|
||||
},
|
||||
"to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-number": "^7.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fast-json-stable-stringify": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||
|
@ -6132,6 +6475,15 @@
|
|||
"integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==",
|
||||
"dev": true
|
||||
},
|
||||
"fastq": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz",
|
||||
"integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"reusify": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"faye-websocket": {
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
|
||||
|
@ -6389,6 +6741,15 @@
|
|||
"universalify": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"fs-minipass": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
|
||||
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minipass": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"fs-write-stream-atomic": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
|
||||
|
@ -7253,6 +7614,12 @@
|
|||
"integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
|
||||
"dev": true
|
||||
},
|
||||
"ignore": {
|
||||
"version": "5.1.8",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
|
||||
"integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
|
||||
"dev": true
|
||||
},
|
||||
"ignore-by-default": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
|
||||
|
@ -9598,6 +9965,12 @@
|
|||
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
|
||||
"dev": true
|
||||
},
|
||||
"merge2": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
|
||||
"dev": true
|
||||
},
|
||||
"methods": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||
|
@ -9732,6 +10105,68 @@
|
|||
"integrity": "sha1-Z9ZgFLZqaoqqDAg8X9WN9OTpdgI=",
|
||||
"dev": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz",
|
||||
"integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"minipass-collect": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
|
||||
"integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minipass": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"minipass-flush": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
|
||||
"integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minipass": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"minipass-pipeline": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
|
||||
"integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minipass": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"minizlib": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
|
||||
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minipass": "^3.0.0",
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"mississippi": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
|
||||
|
@ -14655,6 +15090,12 @@
|
|||
"integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
|
||||
"dev": true
|
||||
},
|
||||
"reusify": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
|
||||
"dev": true
|
||||
},
|
||||
"rgb-regex": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz",
|
||||
|
@ -14735,6 +15176,12 @@
|
|||
"integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==",
|
||||
"dev": true
|
||||
},
|
||||
"run-parallel": {
|
||||
"version": "1.1.9",
|
||||
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz",
|
||||
"integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==",
|
||||
"dev": true
|
||||
},
|
||||
"run-queue": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
|
||||
|
|
|
@ -124,6 +124,7 @@
|
|||
"@types/webpack-merge": "4.1.5",
|
||||
"awesome-typescript-loader": "5.2.1",
|
||||
"concurrently": "4.1.0",
|
||||
"copy-webpack-plugin": "6.1.0",
|
||||
"css-loader": "1.0.0",
|
||||
"electron": "7.2.4",
|
||||
"electron-builder": "22.8.0",
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
@import 'themes';
|
||||
|
||||
.collapsible-section {
|
||||
padding-bottom: 20px;
|
||||
padding-bottom: 5px;
|
||||
@include themify($themes) {
|
||||
border: 1px solid themed('borderColor')
|
||||
}
|
||||
|
@ -13,4 +13,7 @@
|
|||
float: left;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.collapsible-section-children {
|
||||
margin: 0px 10px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
@import 'themes';
|
||||
|
||||
.sas-token-section {
|
||||
margin: 0px 10px;
|
||||
|
||||
.ms-Dropdown-title {
|
||||
@include themify($themes){
|
||||
background-color: themed('inputComponentBackgroundColor');
|
||||
|
|
|
@ -39,6 +39,15 @@ exports[`deviceEvents deviceEvents in non-pnp context matches snapshot in electr
|
|||
"name": "deviceEvents.command.clearEvents",
|
||||
"onClick": [Function],
|
||||
},
|
||||
Object {
|
||||
"ariaLabel": "deviceEvents.command.clearEvents",
|
||||
"iconProps": Object {
|
||||
"iconName": "Code",
|
||||
},
|
||||
"key": "deviceEvents.command.simulate",
|
||||
"name": "deviceEvents.command.simulate",
|
||||
"onClick": [Function],
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
|
@ -66,6 +75,10 @@ exports[`deviceEvents deviceEvents in non-pnp context matches snapshot in electr
|
|||
onChange={[Function]}
|
||||
onText="deviceEvents.toggleUseDefaultEventHub.on"
|
||||
/>
|
||||
<Component
|
||||
onToggleSimulationPanel={[Function]}
|
||||
showSimulationPanel={false}
|
||||
/>
|
||||
<div
|
||||
className="device-events-container"
|
||||
>
|
||||
|
@ -136,6 +149,15 @@ exports[`deviceEvents deviceEvents in non-pnp context matches snapshot in hosted
|
|||
"name": "deviceEvents.command.clearEvents",
|
||||
"onClick": [Function],
|
||||
},
|
||||
Object {
|
||||
"ariaLabel": "deviceEvents.command.clearEvents",
|
||||
"iconProps": Object {
|
||||
"iconName": "Code",
|
||||
},
|
||||
"key": "deviceEvents.command.simulate",
|
||||
"name": "deviceEvents.command.simulate",
|
||||
"onClick": [Function],
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
|
@ -163,6 +185,10 @@ exports[`deviceEvents deviceEvents in non-pnp context matches snapshot in hosted
|
|||
onChange={[Function]}
|
||||
onText="deviceEvents.toggleUseDefaultEventHub.on"
|
||||
/>
|
||||
<Component
|
||||
onToggleSimulationPanel={[Function]}
|
||||
showSimulationPanel={false}
|
||||
/>
|
||||
<div
|
||||
className="device-events-container"
|
||||
>
|
||||
|
@ -233,6 +259,15 @@ exports[`deviceEvents deviceEvents in pnp context matches snapshot while interfa
|
|||
"name": "deviceEvents.command.clearEvents",
|
||||
"onClick": [Function],
|
||||
},
|
||||
Object {
|
||||
"ariaLabel": "deviceEvents.command.clearEvents",
|
||||
"iconProps": Object {
|
||||
"iconName": "Code",
|
||||
},
|
||||
"key": "deviceEvents.command.simulate",
|
||||
"name": "deviceEvents.command.simulate",
|
||||
"onClick": [Function],
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
|
@ -260,6 +295,10 @@ exports[`deviceEvents deviceEvents in pnp context matches snapshot while interfa
|
|||
onChange={[Function]}
|
||||
onText="deviceEvents.toggleUseDefaultEventHub.on"
|
||||
/>
|
||||
<Component
|
||||
onToggleSimulationPanel={[Function]}
|
||||
showSimulationPanel={false}
|
||||
/>
|
||||
<div
|
||||
className="device-events-container"
|
||||
>
|
||||
|
@ -309,6 +348,15 @@ exports[`deviceEvents deviceEvents in pnp context matches snapshot while interfa
|
|||
"name": "deviceEvents.command.clearEvents",
|
||||
"onClick": [Function],
|
||||
},
|
||||
Object {
|
||||
"ariaLabel": "deviceEvents.command.clearEvents",
|
||||
"iconProps": Object {
|
||||
"iconName": "Code",
|
||||
},
|
||||
"key": "deviceEvents.command.simulate",
|
||||
"name": "deviceEvents.command.simulate",
|
||||
"onClick": [Function],
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
|
@ -336,6 +384,10 @@ exports[`deviceEvents deviceEvents in pnp context matches snapshot while interfa
|
|||
onChange={[Function]}
|
||||
onText="deviceEvents.toggleUseDefaultEventHub.on"
|
||||
/>
|
||||
<Component
|
||||
onToggleSimulationPanel={[Function]}
|
||||
showSimulationPanel={false}
|
||||
/>
|
||||
<div
|
||||
className="device-events-container"
|
||||
>
|
||||
|
@ -385,6 +437,15 @@ exports[`deviceEvents deviceEvents in pnp context matches snapshot while interfa
|
|||
"name": "deviceEvents.command.clearEvents",
|
||||
"onClick": [Function],
|
||||
},
|
||||
Object {
|
||||
"ariaLabel": "deviceEvents.command.clearEvents",
|
||||
"iconProps": Object {
|
||||
"iconName": "Code",
|
||||
},
|
||||
"key": "deviceEvents.command.simulate",
|
||||
"name": "deviceEvents.command.simulate",
|
||||
"onClick": [Function],
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
|
@ -412,6 +473,10 @@ exports[`deviceEvents deviceEvents in pnp context matches snapshot while interfa
|
|||
onChange={[Function]}
|
||||
onText="deviceEvents.toggleUseDefaultEventHub.on"
|
||||
/>
|
||||
<Component
|
||||
onToggleSimulationPanel={[Function]}
|
||||
showSimulationPanel={false}
|
||||
/>
|
||||
<div
|
||||
className="device-events-container"
|
||||
>
|
||||
|
|
|
@ -0,0 +1,176 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`deviceSimulationPanel matches snapshot 1`] = `
|
||||
<StyledPanelBase
|
||||
closeButtonAriaLabel="common.close"
|
||||
headerText="deviceEvents.simulation.header"
|
||||
isBlocking={false}
|
||||
isOpen={true}
|
||||
onDismiss={[MockFunction]}
|
||||
type={3}
|
||||
>
|
||||
<a
|
||||
onClick={[Function]}
|
||||
target="_blank"
|
||||
>
|
||||
<img
|
||||
alt="deviceEvents.simulation.cloudShell.imageDescription"
|
||||
className="cloudShellButton"
|
||||
src="images/launchcloudshell.png"
|
||||
/>
|
||||
</a>
|
||||
<StyledLabelBase>
|
||||
deviceEvents.simulation.cloudShell.textDescription
|
||||
</StyledLabelBase>
|
||||
<Component
|
||||
expanded={true}
|
||||
label="deviceEvents.simulation.prerequisite.label"
|
||||
tooltipText="deviceEvents.simulation.prerequisite.tooltiop"
|
||||
>
|
||||
<span>
|
||||
deviceEvents.simulation.prerequisite.instruction
|
||||
</span>
|
||||
</Component>
|
||||
<Component
|
||||
expanded={true}
|
||||
label="deviceEvents.simulation.basic.label"
|
||||
tooltipText="deviceEvents.simulation.basic.tooltiop"
|
||||
>
|
||||
<span>
|
||||
deviceEvents.simulation.basic.instruction
|
||||
</span>
|
||||
<Component
|
||||
allowMask={false}
|
||||
ariaLabel="deviceEvents.simulation.basic.copyLabel"
|
||||
label="deviceEvents.simulation.basic.copyLabel"
|
||||
readOnly={true}
|
||||
value="az iot device simulate --device-id device1 --login \\"\\""
|
||||
/>
|
||||
</Component>
|
||||
<Component
|
||||
expanded={false}
|
||||
label="deviceEvents.simulation.advanced.label"
|
||||
tooltipText="deviceEvents.simulation.advanced.tooltiop"
|
||||
>
|
||||
<span>
|
||||
deviceEvents.simulation.advanced.instruction
|
||||
</span>
|
||||
<Component
|
||||
tooltipText="deviceEvents.simulation.advanced.body.tooltip"
|
||||
>
|
||||
deviceEvents.simulation.advanced.body.label
|
||||
</Component>
|
||||
<StyledTextFieldBase
|
||||
multiline={true}
|
||||
onChange={[Function]}
|
||||
rows={5}
|
||||
/>
|
||||
<StyledCommandBarBase
|
||||
className="properties-section-command-bar"
|
||||
items={
|
||||
Array [
|
||||
Object {
|
||||
"ariaLabel": "deviceEvents.simulation.advanced.properties.addProperty",
|
||||
"iconProps": Object {
|
||||
"iconName": "CircleAddition",
|
||||
},
|
||||
"key": "deviceEvents.simulation.advanced.properties.addProperty",
|
||||
"name": "deviceEvents.simulation.advanced.properties.addProperty",
|
||||
"onClick": [Function],
|
||||
},
|
||||
Object {
|
||||
"ariaLabel": "deviceEvents.simulation.advanced.properties.delete",
|
||||
"disabled": true,
|
||||
"iconProps": Object {
|
||||
"iconName": "Delete",
|
||||
},
|
||||
"key": "deviceEvents.simulation.advanced.properties.delete",
|
||||
"name": "deviceEvents.simulation.advanced.properties.delete",
|
||||
"onClick": [Function],
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
<StyledMarqueeSelectionBase
|
||||
selection={
|
||||
Selection {
|
||||
"_anchoredIndex": 0,
|
||||
"_canSelectItem": [Function],
|
||||
"_changeEventSuppressionCount": 0,
|
||||
"_exemptedCount": 0,
|
||||
"_exemptedIndices": Object {},
|
||||
"_getKey": [Function],
|
||||
"_isModal": false,
|
||||
"_items": Array [],
|
||||
"_keyToIndexMap": Object {},
|
||||
"_onSelectionChanged": [Function],
|
||||
"_selectedItems": null,
|
||||
"_unselectableCount": 0,
|
||||
"_unselectableIndices": Object {},
|
||||
"count": 0,
|
||||
"mode": 2,
|
||||
}
|
||||
}
|
||||
>
|
||||
<StyledWithViewportComponent
|
||||
ariaLabelForSelectAllCheckbox="deviceEvents.simulation.advanced.properties.selectAllCheckboxAriaLabel"
|
||||
ariaLabelForSelectionColumn="deviceEvents.simulation.advanced.properties.toggleSelectionColumnAriaLabel"
|
||||
checkButtonAriaLabel="deviceEvents.simulation.advanced.properties.rowCheckBoxAriaLabel"
|
||||
columns={
|
||||
Array [
|
||||
Object {
|
||||
"isResizable": true,
|
||||
"key": "key",
|
||||
"maxWidth": 300,
|
||||
"minWidth": 150,
|
||||
"name": "deviceEvents.simulation.advanced.properties.key",
|
||||
},
|
||||
Object {
|
||||
"isResizable": true,
|
||||
"key": "value",
|
||||
"minWidth": 150,
|
||||
"name": "deviceEvents.simulation.advanced.properties.value",
|
||||
},
|
||||
]
|
||||
}
|
||||
items={
|
||||
Array [
|
||||
Object {
|
||||
"index": 0,
|
||||
"keyName": "",
|
||||
"value": "",
|
||||
},
|
||||
]
|
||||
}
|
||||
onRenderItemColumn={[Function]}
|
||||
selection={
|
||||
Selection {
|
||||
"_anchoredIndex": 0,
|
||||
"_canSelectItem": [Function],
|
||||
"_changeEventSuppressionCount": 0,
|
||||
"_exemptedCount": 0,
|
||||
"_exemptedIndices": Object {},
|
||||
"_getKey": [Function],
|
||||
"_isModal": false,
|
||||
"_items": Array [],
|
||||
"_keyToIndexMap": Object {},
|
||||
"_onSelectionChanged": [Function],
|
||||
"_selectedItems": null,
|
||||
"_unselectableCount": 0,
|
||||
"_unselectableIndices": Object {},
|
||||
"count": 0,
|
||||
"mode": 2,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</StyledMarqueeSelectionBase>
|
||||
<Component
|
||||
allowMask={false}
|
||||
ariaLabel="deviceEvents.simulation.advanced.copyLabel"
|
||||
label="deviceEvents.simulation.advanced.copyLabel"
|
||||
readOnly={true}
|
||||
value="az iot device simulate --device-id device1 --login \\"\\""
|
||||
/>
|
||||
</Component>
|
||||
</StyledPanelBase>
|
||||
`;
|
|
@ -81,7 +81,7 @@ describe('deviceEvents', () => {
|
|||
const wrapper = mount(<DeviceEvents/>);
|
||||
const commandBar = wrapper.find(CommandBar).first();
|
||||
// tslint:disable-next-line: no-magic-numbers
|
||||
expect(commandBar.props().items.length).toEqual(3);
|
||||
expect(commandBar.props().items.length).toEqual(4);
|
||||
|
||||
// click the start button
|
||||
const startEventsMonitoringSpy = jest.spyOn(startEventsMonitoringAction, 'started');
|
||||
|
|
|
@ -14,7 +14,7 @@ import { Label } from 'office-ui-fabric-react/lib/components/Label';
|
|||
import { ResourceKeys } from '../../../../localization/resourceKeys';
|
||||
import { Message, MESSAGE_SYSTEM_PROPERTIES, MESSAGE_PROPERTIES } from '../../../api/models/messages';
|
||||
import { parseDateTimeString } from '../../../api/dataTransforms/transformHelper';
|
||||
import { CLEAR, CHECKED_CHECKBOX, EMPTY_CHECKBOX, START, STOP, NAVIGATE_BACK, REFRESH, REMOVE } from '../../../constants/iconNames';
|
||||
import { CLEAR, CHECKED_CHECKBOX, EMPTY_CHECKBOX, START, STOP, NAVIGATE_BACK, REFRESH, REMOVE, CODE } from '../../../constants/iconNames';
|
||||
import { getDeviceIdFromQueryString, getComponentNameFromQueryString, getInterfaceIdFromQueryString } from '../../../shared/utils/queryStringHelper';
|
||||
import { SynchronizationStatus } from '../../../api/models/synchronizationStatus';
|
||||
import { MonitorEventsParameters } from '../../../api/parameters/deviceParameters';
|
||||
|
@ -40,6 +40,7 @@ import { getSchemaValidationErrors } from '../../../shared/utils/jsonSchemaAdapt
|
|||
import { ParsedJsonSchema } from '../../../api/models/interfaceJsonParserOutput';
|
||||
import { TelemetryContent } from '../../../api/models/modelDefinition';
|
||||
import { getLocalizedData } from '../../../api/dataTransforms/modelDefinitionTransform';
|
||||
import { DeviceSimulationPanel } from './deviceSimulationPanel';
|
||||
import './deviceEvents.scss';
|
||||
|
||||
const JSON_SPACES = 2;
|
||||
|
@ -78,6 +79,9 @@ export const DeviceEvents: React.FC = () => {
|
|||
const telemetrySchema = React.useMemo(() => getDeviceTelemetry(modelDefinition), [modelDefinition]);
|
||||
const [ showPnpModeledEvents, setShowPnpModeledEvents ] = React.useState(false);
|
||||
|
||||
// simulation specific
|
||||
const [ showSimulationPanel, setShowSimulationPanel ] = React.useState(false);
|
||||
|
||||
React.useEffect(() => {
|
||||
return () => {
|
||||
stopMonitoring();
|
||||
|
@ -123,7 +127,8 @@ export const DeviceEvents: React.FC = () => {
|
|||
else {
|
||||
return [createStartMonitoringCommandItem(),
|
||||
createSystemPropertiesCommandItem(),
|
||||
createClearCommandItem()
|
||||
createClearCommandItem(),
|
||||
createSimulationCommandItem()
|
||||
];
|
||||
}
|
||||
};
|
||||
|
@ -197,6 +202,18 @@ export const DeviceEvents: React.FC = () => {
|
|||
}
|
||||
};
|
||||
|
||||
const createSimulationCommandItem = (): ICommandBarItemProps => {
|
||||
return {
|
||||
ariaLabel: t(ResourceKeys.deviceEvents.command.clearEvents),
|
||||
iconProps: {
|
||||
iconName: CODE
|
||||
},
|
||||
key: t(ResourceKeys.deviceEvents.command.simulate),
|
||||
name: t(ResourceKeys.deviceEvents.command.simulate),
|
||||
onClick: onToggleSimulationPanel
|
||||
};
|
||||
};
|
||||
|
||||
const renderConsumerGroup = () => {
|
||||
const renderConsumerGroupLabel = (textFieldProps: ITextFieldProps) => (
|
||||
<LabelWithTooltip
|
||||
|
@ -632,6 +649,10 @@ export const DeviceEvents: React.FC = () => {
|
|||
setShowPnpModeledEvents(!showPnpModeledEvents);
|
||||
};
|
||||
|
||||
const onToggleSimulationPanel = () => {
|
||||
setShowSimulationPanel(!showSimulationPanel);
|
||||
};
|
||||
|
||||
if (isLoading) {
|
||||
return <MultiLineShimmer/>;
|
||||
}
|
||||
|
@ -639,6 +660,7 @@ export const DeviceEvents: React.FC = () => {
|
|||
const className = componentName ?
|
||||
'scrollable-pnp-telemetry' + (!useBuiltInEventHub ? ' scrollable-pnp-telemetry-custom' : '') :
|
||||
'scrollable-telemetry' + (!useBuiltInEventHub ? ' scrollable-telemetry-custom' : '');
|
||||
|
||||
return (
|
||||
<div className="device-events" key="device-events">
|
||||
<CommandBar
|
||||
|
@ -652,6 +674,10 @@ export const DeviceEvents: React.FC = () => {
|
|||
/>
|
||||
{renderConsumerGroup()}
|
||||
{renderCustomEventHub()}
|
||||
<DeviceSimulationPanel
|
||||
showSimulationPanel={showSimulationPanel}
|
||||
onToggleSimulationPanel={onToggleSimulationPanel}
|
||||
/>
|
||||
<div className="device-events-container">
|
||||
{renderLoader()}
|
||||
<div className={className}>
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
.ms-Panel-content {
|
||||
.cloudShellButton {
|
||||
cursor: pointer;
|
||||
}
|
||||
.collapsible-section {
|
||||
margin-top: 30px;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/***********************************************************
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License
|
||||
**********************************************************/
|
||||
import 'jest';
|
||||
import * as React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { DeviceSimulationPanel } from './deviceSimulationPanel';
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
useLocation: () => ({ search: `?deviceId=device1` })
|
||||
}));
|
||||
|
||||
describe('deviceSimulationPanel', () => {
|
||||
it('matches snapshot ', () => {
|
||||
expect(shallow(
|
||||
<DeviceSimulationPanel
|
||||
showSimulationPanel={true}
|
||||
onToggleSimulationPanel={jest.fn()}
|
||||
/>)).toMatchSnapshot();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,279 @@
|
|||
/***********************************************************
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License
|
||||
**********************************************************/
|
||||
import * as React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { TextField } from 'office-ui-fabric-react/lib/components/TextField';
|
||||
import { Panel, PanelType } from 'office-ui-fabric-react/lib/components/Panel';
|
||||
import { Label } from 'office-ui-fabric-react/lib/components/Label';
|
||||
import { DetailsList, IColumn } from 'office-ui-fabric-react/lib/components/DetailsList';
|
||||
import { MarqueeSelection } from 'office-ui-fabric-react/lib/components/MarqueeSelection/MarqueeSelection';
|
||||
import { Selection } from 'office-ui-fabric-react/lib/utilities/selection/Selection';
|
||||
import { CommandBar } from 'office-ui-fabric-react/lib/components/CommandBar';
|
||||
import { ResourceKeys } from '../../../../localization/resourceKeys';
|
||||
import { getDeviceIdFromQueryString } from '../../../shared/utils/queryStringHelper';
|
||||
import { LabelWithTooltip } from '../../../shared/components/labelWithTooltip';
|
||||
import { CollapsibleSection } from '../../../shared/components/collapsibleSection';
|
||||
import { MaskedCopyableTextField } from '../../../shared/components/maskedCopyableTextField';
|
||||
import { getHubInformationFromLocalStorage } from '../../../shared/hooks/localStorageInformationRetriever';
|
||||
import { CIRCLE_ADD, ArrayOperation } from '../../../constants/iconNames';
|
||||
import { MEDIUM_COLUMN_WIDTH } from '../../../constants/columnWidth';
|
||||
import './deviceSimulationPanel.scss';
|
||||
|
||||
export interface DeviceSimulationPanelProps {
|
||||
showSimulationPanel: boolean;
|
||||
onToggleSimulationPanel: () => void;
|
||||
}
|
||||
|
||||
interface PropertyItem {
|
||||
index: number;
|
||||
keyName: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export const DeviceSimulationPanel: React.FC<DeviceSimulationPanelProps> = props => {
|
||||
const { t } = useTranslation();
|
||||
const { search } = useLocation();
|
||||
|
||||
const deviceId = getDeviceIdFromQueryString(search);
|
||||
|
||||
const [ hubConnectionString, ] = getHubInformationFromLocalStorage();
|
||||
const [ simulationBody, setSimulationBody ] = React.useState<string>('');
|
||||
const [ propertyIndex, setPropertyIndex ] = React.useState<number>(0);
|
||||
const [ selectedIndices, setSelectedIndices ] = React.useState<Set<number>>(new Set());
|
||||
const [ properties, setProperties ] = React.useState<PropertyItem[]>([{index: 0, keyName: '', value: ''}]);
|
||||
const selection = new Selection({
|
||||
onSelectionChanged: () => onSelectionChanged()
|
||||
});
|
||||
|
||||
const renderSimulationPanel = () => {
|
||||
return (
|
||||
<Panel
|
||||
isOpen={props.showSimulationPanel}
|
||||
type={PanelType.medium}
|
||||
isBlocking={false}
|
||||
onDismiss={props.onToggleSimulationPanel}
|
||||
closeButtonAriaLabel={t(ResourceKeys.common.close)}
|
||||
headerText={t(ResourceKeys.deviceEvents.simulation.header)}
|
||||
>
|
||||
<a onClick={onclick} target="_blank">
|
||||
<img className="cloudShellButton" alt={t(ResourceKeys.deviceEvents.simulation.cloudShell.imageDescription)} src="images/launchcloudshell.png" />
|
||||
</a>
|
||||
<Label>{t(ResourceKeys.deviceEvents.simulation.cloudShell.textDescription)}</Label>
|
||||
<CollapsibleSection
|
||||
expanded={true}
|
||||
label={t(ResourceKeys.deviceEvents.simulation.prerequisite.label)}
|
||||
tooltipText={t(ResourceKeys.deviceEvents.simulation.prerequisite.tooltiop)}
|
||||
>
|
||||
<span>{t(ResourceKeys.deviceEvents.simulation.prerequisite.instruction)}</span>
|
||||
</CollapsibleSection>
|
||||
<CollapsibleSection
|
||||
expanded={true}
|
||||
label={t(ResourceKeys.deviceEvents.simulation.basic.label)}
|
||||
tooltipText={t(ResourceKeys.deviceEvents.simulation.basic.tooltiop)}
|
||||
>
|
||||
<span>{t(ResourceKeys.deviceEvents.simulation.basic.instruction)}</span>
|
||||
<MaskedCopyableTextField
|
||||
ariaLabel={t(ResourceKeys.deviceEvents.simulation.basic.copyLabel, {deviceId})}
|
||||
label={t(ResourceKeys.deviceEvents.simulation.basic.copyLabel, {deviceId})}
|
||||
value={`az iot device simulate --device-id ${deviceId} --login \"${hubConnectionString}\"`}
|
||||
allowMask={false}
|
||||
readOnly={true}
|
||||
/>
|
||||
</CollapsibleSection>
|
||||
<CollapsibleSection
|
||||
expanded={false}
|
||||
label={t(ResourceKeys.deviceEvents.simulation.advanced.label)}
|
||||
tooltipText={t(ResourceKeys.deviceEvents.simulation.advanced.tooltiop)}
|
||||
>
|
||||
<span>{t(ResourceKeys.deviceEvents.simulation.advanced.instruction)}</span>
|
||||
{renderMessageBodySection()}
|
||||
{renderPropertiesList()}
|
||||
<MaskedCopyableTextField
|
||||
ariaLabel={t(ResourceKeys.deviceEvents.simulation.advanced.copyLabel, {deviceId})}
|
||||
label={t(ResourceKeys.deviceEvents.simulation.advanced.copyLabel, {deviceId})}
|
||||
value={convertToCliCommand()}
|
||||
allowMask={false}
|
||||
readOnly={true}
|
||||
/>
|
||||
</CollapsibleSection>
|
||||
</Panel>
|
||||
);
|
||||
};
|
||||
|
||||
const renderMessageBodySection = () => {
|
||||
const textFieldRows = 5;
|
||||
return (
|
||||
<>
|
||||
<LabelWithTooltip
|
||||
tooltipText={t(ResourceKeys.deviceEvents.simulation.advanced.body.tooltip)}
|
||||
>
|
||||
{t(ResourceKeys.deviceEvents.simulation.advanced.body.label)}
|
||||
</LabelWithTooltip>
|
||||
<TextField multiline={true} rows={textFieldRows} onChange={onTextFieldChange}/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const renderPropertiesList = () => {
|
||||
return (
|
||||
<>
|
||||
<CommandBar
|
||||
className="properties-section-command-bar"
|
||||
items={[
|
||||
{
|
||||
ariaLabel: t(ResourceKeys.deviceEvents.simulation.advanced.properties.addProperty),
|
||||
iconProps: {
|
||||
iconName: CIRCLE_ADD
|
||||
},
|
||||
key: t(ResourceKeys.deviceEvents.simulation.advanced.properties.addProperty),
|
||||
name: t(ResourceKeys.deviceEvents.simulation.advanced.properties.addProperty),
|
||||
onClick: handleAddProperty
|
||||
},
|
||||
{
|
||||
ariaLabel: t(ResourceKeys.deviceEvents.simulation.advanced.properties.delete),
|
||||
disabled: selectedIndices.size === 0,
|
||||
iconProps: {
|
||||
iconName: ArrayOperation.REMOVE
|
||||
},
|
||||
key: t(ResourceKeys.deviceEvents.simulation.advanced.properties.delete),
|
||||
name: t(ResourceKeys.deviceEvents.simulation.advanced.properties.delete),
|
||||
onClick: handleDelete
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<MarqueeSelection selection={selection}>
|
||||
<DetailsList
|
||||
items={properties}
|
||||
columns={getColumns()}
|
||||
onRenderItemColumn={renderItemColumn()}
|
||||
ariaLabelForSelectionColumn={t(ResourceKeys.deviceEvents.simulation.advanced.properties.toggleSelectionColumnAriaLabel)}
|
||||
ariaLabelForSelectAllCheckbox={t(ResourceKeys.deviceEvents.simulation.advanced.properties.selectAllCheckboxAriaLabel)}
|
||||
checkButtonAriaLabel={t(ResourceKeys.deviceEvents.simulation.advanced.properties.rowCheckBoxAriaLabel)}
|
||||
selection={selection}
|
||||
/>
|
||||
</MarqueeSelection>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const renderItemColumn = () => (item: PropertyItem, index: number, column: IColumn) => {
|
||||
const handleEditCustomPropertyKey = (event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue?: string) => {
|
||||
const items = [...properties];
|
||||
items[index] = {...items[index], keyName: newValue};
|
||||
setProperties(items);
|
||||
};
|
||||
|
||||
switch (column.key) {
|
||||
case 'key':
|
||||
const hasDuplicateKey = (keyName: string) => keyName && properties.filter(property => property.keyName === keyName).length > 1;
|
||||
return (
|
||||
<TextField
|
||||
ariaLabel={t(ResourceKeys.deviceEvents.simulation.advanced.properties.key)}
|
||||
errorMessage={hasDuplicateKey(item.keyName) && t(ResourceKeys.deviceEvents.simulation.advanced.properties.keyDup)}
|
||||
value={item.keyName}
|
||||
onChange={handleEditCustomPropertyKey}
|
||||
/>);
|
||||
case 'value':
|
||||
return renderItemValueColumn(item, column);
|
||||
default:
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
const findMatchingItemIndex = (property: PropertyItem): number => {
|
||||
let indexFound = -1;
|
||||
properties.forEach((element, index) => {
|
||||
if (element.index === property.index) {
|
||||
indexFound = index;
|
||||
}
|
||||
});
|
||||
return indexFound;
|
||||
};
|
||||
|
||||
const renderItemValueColumn = (item: PropertyItem, column: IColumn) => {
|
||||
const index = findMatchingItemIndex(item);
|
||||
|
||||
const handleEditPropertyValue = (event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue?: string) => {
|
||||
const items = [...properties];
|
||||
items[index] = {...items[index], value: newValue};
|
||||
setProperties(items);
|
||||
};
|
||||
|
||||
return (
|
||||
<TextField
|
||||
ariaLabel={t(ResourceKeys.deviceEvents.simulation.advanced.properties.value)}
|
||||
value={item.value}
|
||||
onChange={handleEditPropertyValue}
|
||||
/>);
|
||||
};
|
||||
|
||||
const getColumns = (): IColumn[] => {
|
||||
return [
|
||||
{
|
||||
isResizable: true,
|
||||
key: 'key',
|
||||
maxWidth: MEDIUM_COLUMN_WIDTH,
|
||||
minWidth: 150,
|
||||
name: t(ResourceKeys.deviceEvents.simulation.advanced.properties.key),
|
||||
},
|
||||
{
|
||||
isResizable: true,
|
||||
key: 'value',
|
||||
minWidth: 150,
|
||||
name: t(ResourceKeys.deviceEvents.simulation.advanced.properties.value),
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
const onSelectionChanged = () => {
|
||||
setSelectedIndices(new Set(selection.getSelectedIndices()));
|
||||
};
|
||||
|
||||
const handleAddProperty = () => {
|
||||
const newIndex = propertyIndex + 1;
|
||||
const newProperties = [...properties, {index: newIndex, keyName: '', value: ''}];
|
||||
setProperties(newProperties);
|
||||
setPropertyIndex(newIndex);
|
||||
};
|
||||
|
||||
const handleDelete = () => {
|
||||
const updatedProperties = [];
|
||||
for (let i = 0; i < properties.length; i++) {
|
||||
if (!selectedIndices.has(i)) {
|
||||
updatedProperties.push(properties[i]);
|
||||
}
|
||||
}
|
||||
setProperties(updatedProperties);
|
||||
};
|
||||
|
||||
const onTextFieldChange = (ev: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newText: string) => {
|
||||
setSimulationBody(newText);
|
||||
};
|
||||
|
||||
const convertToCliPropertyFormat = () => {
|
||||
let returnValue = '';
|
||||
properties.forEach(item => { if (item.keyName && item.value) {returnValue += `${item.keyName}=${item.value}`; }});
|
||||
return returnValue;
|
||||
};
|
||||
|
||||
const convertToCliCommand = () => {
|
||||
let returnValue = `az iot device simulate --device-id ${deviceId} --login \"${hubConnectionString}\"`;
|
||||
if (simulationBody) {
|
||||
returnValue += ` --data \"${simulationBody}\"`;
|
||||
}
|
||||
const commandProperties = convertToCliPropertyFormat();
|
||||
if (commandProperties !== '') {
|
||||
returnValue += ` --properties \"${commandProperties}\"`;
|
||||
}
|
||||
return returnValue;
|
||||
};
|
||||
|
||||
const onclick = () => {
|
||||
window.open('https://shell.azure.com');
|
||||
};
|
||||
|
||||
return renderSimulationPanel();
|
||||
};
|
|
@ -20,5 +20,8 @@ exports[`collapsibleSection matches snapshot 1`] = `
|
|||
>
|
||||
Label
|
||||
</Component>
|
||||
<div
|
||||
className="collapsible-section-children"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
|
|
@ -7,20 +7,12 @@ import { useTranslation } from 'react-i18next';
|
|||
import { Route, NavLink, useLocation, useRouteMatch } from 'react-router-dom';
|
||||
import { ResourceKeys } from '../../../localization/resourceKeys';
|
||||
import { ROUTE_PARTS, ROUTE_PARAMS } from '../../constants/routes';
|
||||
import { CONNECTION_STRING_NAME_LIST } from '../../constants/browserStorage';
|
||||
import { getConnectionInfoFromConnectionString } from '../../api/shared/utils';
|
||||
import { getDeviceIdFromQueryString, getComponentNameFromQueryString } from '../utils/queryStringHelper';
|
||||
import { getHubInformationFromLocalStorage } from '../hooks/localStorageInformationRetriever';
|
||||
import '../../css/_breadcrumb.scss';
|
||||
|
||||
export const Breadcrumb: React.FC = () => {
|
||||
const [ hostName, setHostName ] = React.useState<string>('');
|
||||
const connectionStrings = localStorage.getItem(CONNECTION_STRING_NAME_LIST);
|
||||
const connectionString = connectionStrings && connectionStrings.split(',')[0];
|
||||
|
||||
React.useEffect(() => {
|
||||
const host = getConnectionInfoFromConnectionString(connectionString).hostName;
|
||||
setHostName(host);
|
||||
}, [connectionString]);
|
||||
const [ , hostName] = getHubInformationFromLocalStorage();
|
||||
|
||||
const renderBreadcrumbItem = () => <BreadcrumbItem hostName={hostName}/>;
|
||||
|
||||
|
|
|
@ -43,7 +43,9 @@ export const CollapsibleSection: React.FC<CollapsibleSectionProps> = (props: Col
|
|||
<LabelWithTooltip tooltipText={tooltipText}>
|
||||
{label}
|
||||
</LabelWithTooltip>
|
||||
{expanded && children}
|
||||
<div className="collapsible-section-children">
|
||||
{expanded && children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
import * as React from 'react';
|
||||
import { CONNECTION_STRING_NAME_LIST } from '../../constants/browserStorage';
|
||||
import { getConnectionInfoFromConnectionString } from '../../api/shared/utils';
|
||||
|
||||
export const getHubInformationFromLocalStorage = () => {
|
||||
const [ hubConnectionString, setHubConnectionString ] = React.useState<string>('');
|
||||
const [ hostName, setHostName ] = React.useState<string>('');
|
||||
const connectionStrings = localStorage.getItem(CONNECTION_STRING_NAME_LIST);
|
||||
const connectionString = connectionStrings && connectionStrings.split(',')[0];
|
||||
React.useEffect(() => {
|
||||
setHubConnectionString(connectionString);
|
||||
setHostName(getConnectionInfoFromConnectionString(connectionString).hostName);
|
||||
}, [connectionString]);
|
||||
return [hubConnectionString, hostName];
|
||||
};
|
|
@ -567,7 +567,8 @@
|
|||
"start": "Start",
|
||||
"stop": "Stop",
|
||||
"fetch": "Retrieve events",
|
||||
"close": "Back"
|
||||
"close": "Back",
|
||||
"simulate": "Simulation device"
|
||||
},
|
||||
"consumerGroups": {
|
||||
"label": "Consumer group",
|
||||
|
@ -625,7 +626,45 @@
|
|||
"on": "Yes",
|
||||
"off": "No"
|
||||
},
|
||||
"error": "Failed to monitor events. {{error}}"
|
||||
"error": "Failed to monitor events. {{error}}",
|
||||
"simulation": {
|
||||
"header": "Simulate a device using CLI in Azure Cloud Shell",
|
||||
"cloudShell": {
|
||||
"imageDescription": "Launch Azure Cloud Shell",
|
||||
"textDescription": "Click Launch Cloud Shell, paste the commands below to simulate a device sending telemetry. You will be able to start monitoring events from the built-in event hub."
|
||||
},
|
||||
"prerequisite": {
|
||||
"label": "Prerequisite",
|
||||
"tooltiop": "If you have not used Azure Cloud Shell before",
|
||||
"instruction": "Follow the instructions in Azure Cloud Shell to pick a subscription and set up a storage if you haven't used Cloud Shell before. If you have encountered error 'az iot: 'device' is not in the 'az iot' command group', use command 'az extension add --name azure-iot' to install Azure IoT CLI extension."
|
||||
},
|
||||
"basic": {
|
||||
"label": "Basic scenario",
|
||||
"tooltiop": "Zero input basic scenario",
|
||||
"instruction": "Simply copy paste the following command to Azure Cloud Shell. It will start simulating device {{deviceId}} as it's sending messages to IoT Hub. You can click 'Start' button from the Telemetry page to start monitoring the events.",
|
||||
"copyLabel": "Simulating device {{deviceId}}"
|
||||
},
|
||||
"advanced": {
|
||||
"label": "Advance scenario",
|
||||
"tooltiop": "For advanced users to simulate events' body or properties",
|
||||
"instruction": "Enter the desired message body and/or properties, and copy paste the generated command to Azure Cloud Shell. It will start simulating device {{deviceId}} as it's sending messages to IoT Hub. You can click 'Start' button from the Telemetry page to start monitoring the events.",
|
||||
"copyLabel": "Simulating device {{deviceId}}",
|
||||
"body": {
|
||||
"label": "Provide event body",
|
||||
"tooltip": "If left empty, the default value would be: 'Ping from Az CLI IoT Extension'."
|
||||
},
|
||||
"properties": {
|
||||
"key": "Key",
|
||||
"keyDup": "Key must be unique",
|
||||
"value": "Value",
|
||||
"addProperty": "Add a property",
|
||||
"delete": "Delete",
|
||||
"toggleSelectionColumnAriaLabel": "Toggle selection",
|
||||
"selectAllCheckboxAriaLabel": "Toggle selection for all",
|
||||
"rowCheckBoxAriaLabel": "Row checkbox"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"directMethod": {
|
||||
"headerText": "Direct method",
|
||||
|
|
|
@ -291,6 +291,7 @@ export class ResourceKeys {
|
|||
fetch : "deviceEvents.command.fetch",
|
||||
refresh : "deviceEvents.command.refresh",
|
||||
showSystemProperties : "deviceEvents.command.showSystemProperties",
|
||||
simulate : "deviceEvents.command.simulate",
|
||||
start : "deviceEvents.command.start",
|
||||
stop : "deviceEvents.command.stop",
|
||||
},
|
||||
|
@ -323,6 +324,44 @@ export class ResourceKeys {
|
|||
placeHolder : "deviceEvents.interfaceDropDown.placeHolder",
|
||||
},
|
||||
noEvent : "deviceEvents.noEvent",
|
||||
simulation : {
|
||||
advanced : {
|
||||
body : {
|
||||
label : "deviceEvents.simulation.advanced.body.label",
|
||||
tooltip : "deviceEvents.simulation.advanced.body.tooltip",
|
||||
},
|
||||
copyLabel : "deviceEvents.simulation.advanced.copyLabel",
|
||||
instruction : "deviceEvents.simulation.advanced.instruction",
|
||||
label : "deviceEvents.simulation.advanced.label",
|
||||
properties : {
|
||||
addProperty : "deviceEvents.simulation.advanced.properties.addProperty",
|
||||
delete : "deviceEvents.simulation.advanced.properties.delete",
|
||||
key : "deviceEvents.simulation.advanced.properties.key",
|
||||
keyDup : "deviceEvents.simulation.advanced.properties.keyDup",
|
||||
rowCheckBoxAriaLabel : "deviceEvents.simulation.advanced.properties.rowCheckBoxAriaLabel",
|
||||
selectAllCheckboxAriaLabel : "deviceEvents.simulation.advanced.properties.selectAllCheckboxAriaLabel",
|
||||
toggleSelectionColumnAriaLabel : "deviceEvents.simulation.advanced.properties.toggleSelectionColumnAriaLabel",
|
||||
value : "deviceEvents.simulation.advanced.properties.value",
|
||||
},
|
||||
tooltiop : "deviceEvents.simulation.advanced.tooltiop",
|
||||
},
|
||||
basic : {
|
||||
copyLabel : "deviceEvents.simulation.basic.copyLabel",
|
||||
instruction : "deviceEvents.simulation.basic.instruction",
|
||||
label : "deviceEvents.simulation.basic.label",
|
||||
tooltiop : "deviceEvents.simulation.basic.tooltiop",
|
||||
},
|
||||
cloudShell : {
|
||||
imageDescription : "deviceEvents.simulation.cloudShell.imageDescription",
|
||||
textDescription : "deviceEvents.simulation.cloudShell.textDescription",
|
||||
},
|
||||
header : "deviceEvents.simulation.header",
|
||||
prerequisite : {
|
||||
instruction : "deviceEvents.simulation.prerequisite.instruction",
|
||||
label : "deviceEvents.simulation.prerequisite.label",
|
||||
tooltiop : "deviceEvents.simulation.prerequisite.tooltiop",
|
||||
},
|
||||
},
|
||||
toggleShowRawData : {
|
||||
label : "deviceEvents.toggleShowRawData.label",
|
||||
off : "deviceEvents.toggleShowRawData.off",
|
||||
|
|
|
@ -2,6 +2,7 @@ import * as webpack from 'webpack';
|
|||
import * as path from 'path';
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin'); // tslint:disable-line: no-var-requires
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // tslint:disable-line: no-var-requires
|
||||
const CopyPlugin = require('copy-webpack-plugin'); // tslint:disable-line: no-var-requires
|
||||
|
||||
const config: webpack.Configuration = {
|
||||
entry: {
|
||||
|
@ -53,6 +54,14 @@ const config: webpack.Configuration = {
|
|||
template: path.resolve(__dirname, '.', 'src', 'index.html')
|
||||
}),
|
||||
// new BundleAnalyzerPlugin(),
|
||||
new CopyPlugin({
|
||||
patterns: [
|
||||
{
|
||||
from: 'images',
|
||||
to: 'images',
|
||||
}
|
||||
]
|
||||
})
|
||||
],
|
||||
resolve: {
|
||||
// Add '.ts' and '.tsx' as resolvable extensions.
|
||||
|
|
Загрузка…
Ссылка в новой задаче