Merge branch 'master' into fix_debug_live_tx

pull/1958/head
David Disu 3 years ago committed by GitHub
commit 07bfb493fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      apps/remix-ide-e2e/src/tests/defaultLayout.test.ts
  2. 2
      apps/remix-ide/src/app/editor/examples.js
  3. 2
      apps/remix-ide/src/app/tabs/runTab/model/recorder.js
  4. 8543
      apps/remix-ide/src/assets/css/themes/bootstrap-cerulean.min.css
  5. 8671
      apps/remix-ide/src/assets/css/themes/bootstrap-cyborg.min.css
  6. 7213
      apps/remix-ide/src/assets/css/themes/bootstrap-flatly.min.css
  7. 8645
      apps/remix-ide/src/assets/css/themes/bootstrap-spacelab.min.css
  8. 51
      apps/remix-ide/src/assets/css/themes/remix-black_undtds.css
  9. 3
      apps/remix-ide/src/assets/css/themes/remix-candy_ikhg4m.css
  10. 51
      apps/remix-ide/src/assets/css/themes/remix-dark_tvx1s2.css
  11. 20
      apps/remix-ide/src/assets/css/themes/remix-light_powaqg.css
  12. 3
      apps/remix-ide/src/assets/css/themes/remix-midcentury_hrzph3.css
  13. 4
      libs/remix-ui/helper/src/lib/remix-ui-helper.ts
  14. 43
      libs/remix-ui/run-tab/src/lib/actions/index.ts
  15. 4
      libs/remix-ui/run-tab/src/lib/run-tab.tsx
  16. 4
      libs/remix-ui/run-tab/src/lib/types/index.ts
  17. 8
      libs/remix-ui/terminal/src/lib/components/ChechTxStatus.tsx
  18. 48
      libs/remix-ui/terminal/src/lib/components/Context.tsx
  19. 19
      libs/remix-ui/terminal/src/lib/components/RenderCall.tsx
  20. 13
      libs/remix-ui/terminal/src/lib/components/RenderKnownTransactions.tsx
  21. 13
      libs/remix-ui/terminal/src/lib/components/RenderUnknownTransactions.tsx
  22. 84
      libs/remix-ui/terminal/src/lib/components/Table.tsx
  23. 581
      libs/remix-ui/terminal/src/lib/remix-ui-terminal.css
  24. 124
      libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx
  25. 6
      libs/remix-ui/terminal/src/lib/terminalWelcome.tsx

@ -50,11 +50,15 @@ module.exports = {
'Toggles Terminal': function (browser: NightwatchBrowser) { 'Toggles Terminal': function (browser: NightwatchBrowser) {
browser.waitForElementVisible('div[data-id="terminalContainer"]') browser.waitForElementVisible('div[data-id="terminalContainer"]')
.assert.elementPresent('div[data-id="terminalContainerDisplay"]') .assert.elementPresent('div[data-id="terminalCli"]')
.assert.elementPresent('div[data-id="terminalContainer"]')
.waitForElementVisible('div[data-id="terminalContainer"]')
.waitForElementVisible('div[data-id="terminalCli"]')
.click('i[data-id="terminalToggleIcon"]') .click('i[data-id="terminalToggleIcon"]')
.checkElementStyle('div[data-id="terminalToggleMenu"]', 'height', '35px') .checkElementStyle('div[data-id="terminalToggleMenu"]', 'height', '35px')
.assert.not.elementPresent('div[data-id="terminalCli"]')
.click('i[data-id="terminalToggleIcon"]') .click('i[data-id="terminalToggleIcon"]')
.assert.elementPresent('div[data-id="terminalContainerDisplay"]') .waitForElementVisible('div[data-id="terminalCli"]')
}, },
'Switch Tabs using tabs icon': function (browser: NightwatchBrowser) { 'Switch Tabs using tabs icon': function (browser: NightwatchBrowser) {

@ -313,7 +313,7 @@ const deployWithEthers = `// Right click on the script name and hit "Run" to exe
const readme = `REMIX EXAMPLE PROJECT const readme = `REMIX EXAMPLE PROJECT
Remix example project is present when Remix loads very first time or there are no files existing in the File Explorer. Remix example project is present when Remix loads for the very first time or there are no files existing in the File Explorer.
It contains 3 directories: It contains 3 directories:
1. 'contracts': Holds three contracts with different complexity level, denoted with number prefix in file name. 1. 'contracts': Holds three contracts with different complexity level, denoted with number prefix in file name.

@ -259,7 +259,7 @@ class Recorder {
cb(err) cb(err)
} }
) )
}, () => { self.setListen(true); self.clearAll() }) }, () => { self.setListen(true) })
} }
runScenario (json, continueCb, promptCb, alertCb, confirmationCb, logCallBack, cb) { runScenario (json, continueCb, promptCb, alertCb, confirmationCb, logCallBack, cb) {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -22,6 +22,7 @@
--light: #1f2020; --light: #1f2020;
--dark: #1a1a1a; --dark: #1a1a1a;
--text: #babbcc; --text: #babbcc;
--body-bg: #1a1a1a;
--breakpoint-xs: 0; --breakpoint-xs: 0;
--breakpoint-sm: 576px; --breakpoint-sm: 576px;
--breakpoint-md: 768px; --breakpoint-md: 768px;
@ -66,7 +67,7 @@ body {
line-height: 1.5; line-height: 1.5;
color: #b3b3b3; color: #b3b3b3;
text-align: left; text-align: left;
background-color: #1a1a1a; background-color: var(--body-bg);
} }
*::-webkit-scrollbar { *::-webkit-scrollbar {
width: 8px; width: 8px;
@ -1638,7 +1639,7 @@ pre code {
} }
.form-control:focus { .form-control:focus {
color: #aaaaaa; color: #aaaaaa;
background-color: #1a1a1a; background-color: var(--body-bg);
border-color: #6d7172; border-color: #6d7172;
outline: 0; outline: 0;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),
@ -1655,7 +1656,7 @@ pre code {
} }
select.form-control:focus::-ms-value { select.form-control:focus::-ms-value {
color: #aaaaaa; color: #aaaaaa;
background-color: #1a1a1a; background-color: var(--body-bg);
} }
.form-control-file, .form-control-file,
.form-control-range { .form-control-range {
@ -2361,8 +2362,8 @@ fieldset:disabled a.btn {
} }
.btn-dark { .btn-dark {
color: #d5d5d5; color: #d5d5d5;
background-color: #1a1a1a; background-color: var(--body-bg);
border-color: #1a1a1a; border-color: var(--body-bg);
} }
.btn-dark:hover { .btn-dark:hover {
color: #d5d5d5; color: #d5d5d5;
@ -2376,8 +2377,8 @@ fieldset:disabled a.btn {
.btn-dark.disabled, .btn-dark.disabled,
.btn-dark:disabled { .btn-dark:disabled {
color: #d5d5d5; color: #d5d5d5;
background-color: #1a1a1a; background-color: var(--body-bg);
border-color: #1a1a1a; border-color: var(--body-bg);
} }
.btn-dark:not(:disabled):not(.disabled).active, .btn-dark:not(:disabled):not(.disabled).active,
.btn-dark:not(:disabled):not(.disabled):active, .btn-dark:not(:disabled):not(.disabled):active,
@ -2602,13 +2603,13 @@ fieldset:disabled a.btn {
box-shadow: 0 0 0 0.2rem rgba(42, 44, 63, 0.5); box-shadow: 0 0 0 0.2rem rgba(42, 44, 63, 0.5);
} }
.btn-outline-dark { .btn-outline-dark {
color: #1a1a1a; color: var(--body-bg);
border-color: #1a1a1a; border-color: var(--body-bg);
} }
.btn-outline-dark:hover { .btn-outline-dark:hover {
color: #d5d5d5; color: #d5d5d5;
background-color: #1a1a1a; background-color: var(--body-bg);
border-color: #1a1a1a; border-color: var(--body-bg);
} }
.btn-outline-dark.focus, .btn-outline-dark.focus,
.btn-outline-dark:focus { .btn-outline-dark:focus {
@ -2616,15 +2617,15 @@ fieldset:disabled a.btn {
} }
.btn-outline-dark.disabled, .btn-outline-dark.disabled,
.btn-outline-dark:disabled { .btn-outline-dark:disabled {
color: #1a1a1a; color: var(--body-bg);
background-color: transparent; background-color: transparent;
} }
.btn-outline-dark:not(:disabled):not(.disabled).active, .btn-outline-dark:not(:disabled):not(.disabled).active,
.btn-outline-dark:not(:disabled):not(.disabled):active, .btn-outline-dark:not(:disabled):not(.disabled):active,
.show > .btn-outline-dark.dropdown-toggle { .show > .btn-outline-dark.dropdown-toggle {
color: #d5d5d5; color: #d5d5d5;
background-color: #1a1a1a; background-color: var(--body-bg);
border-color: #1a1a1a; border-color: var(--body-bg);
} }
.btn-outline-dark:not(:disabled):not(.disabled).active:focus, .btn-outline-dark:not(:disabled):not(.disabled).active:focus,
.btn-outline-dark:not(:disabled):not(.disabled):active:focus, .btn-outline-dark:not(:disabled):not(.disabled):active:focus,
@ -3359,7 +3360,7 @@ input[type="submit"].btn-block {
} }
.custom-select:focus::-ms-value { .custom-select:focus::-ms-value {
color: #aaaaaa; color: #aaaaaa;
background-color: #1a1a1a; background-color: var(--body-bg);
} }
.custom-select[multiple], .custom-select[multiple],
.custom-select[size]:not([size="1"]) { .custom-select[size]:not([size="1"]) {
@ -3427,7 +3428,7 @@ input[type="submit"].btn-block {
font-weight: 400; font-weight: 400;
line-height: 1.25; line-height: 1.25;
color: #aaaaaa; color: #aaaaaa;
background-color: #1a1a1a; background-color: var(--body-bg);
border: 1px solid transparent; border: 1px solid transparent;
border-radius: 2px; border-radius: 2px;
} }
@ -3458,15 +3459,15 @@ input[type="submit"].btn-block {
outline: 0; outline: 0;
} }
.custom-range:focus::-webkit-slider-thumb { .custom-range:focus::-webkit-slider-thumb {
box-shadow: 0 0 0 1px #1a1a1a, inset 0 1px 1px rgba(0, 0, 0, 0.075), box-shadow: 0 0 0 1px var(--body-bg), inset 0 1px 1px rgba(0, 0, 0, 0.075),
0 0 0 3px rgba(0, 122, 166, 0.25); 0 0 0 3px rgba(0, 122, 166, 0.25);
} }
.custom-range:focus::-moz-range-thumb { .custom-range:focus::-moz-range-thumb {
box-shadow: 0 0 0 1px #1a1a1a, inset 0 1px 1px rgba(0, 0, 0, 0.075), box-shadow: 0 0 0 1px var(--body-bg), inset 0 1px 1px rgba(0, 0, 0, 0.075),
0 0 0 3px rgba(0, 122, 166, 0.25); 0 0 0 3px rgba(0, 122, 166, 0.25);
} }
.custom-range:focus::-ms-thumb { .custom-range:focus::-ms-thumb {
box-shadow: 0 0 0 1px #1a1a1a, inset 0 1px 1px rgba(0, 0, 0, 0.075), box-shadow: 0 0 0 1px var(--body-bg), inset 0 1px 1px rgba(0, 0, 0, 0.075),
0 0 0 3px rgba(0, 122, 166, 0.25); 0 0 0 3px rgba(0, 122, 166, 0.25);
} }
.custom-range::-moz-focus-outer { .custom-range::-moz-focus-outer {
@ -4423,7 +4424,7 @@ a.badge-light:focus {
} }
.badge-dark { .badge-dark {
color: #d5d5d5; color: #d5d5d5;
background-color: #1a1a1a; background-color: var(--body-bg);
} }
a.badge-dark:focus, a.badge-dark:focus,
a.badge-dark:hover { a.badge-dark:hover {
@ -5040,7 +5041,7 @@ a.close.disabled {
width: 100%; width: 100%;
color: #d5d5d5; color: #d5d5d5;
pointer-events: auto; pointer-events: auto;
background-color: #1a1a1a; background-color: var(--body-bg);
background-clip: padding-box; background-clip: padding-box;
border: 1px solid #000000; border: 1px solid #000000;
border-radius: 2px; border-radius: 2px;
@ -5691,7 +5692,7 @@ button.bg-light:hover {
background-color: #161720 !important; background-color: #161720 !important;
} }
.bg-dark { .bg-dark {
background-color: #1a1a1a !important; background-color: var(--body-bg) !important;
} }
a.bg-dark:focus, a.bg-dark:focus,
a.bg-dark:hover, a.bg-dark:hover,
@ -8711,16 +8712,16 @@ a.text-dark:hover {
/* Plugins manager */ /* Plugins manager */
.plugin-manager { .plugin-manager {
background: #1a1a1a; background: var(--body-bg);
} }
.plugins-header { .plugins-header {
background-color: #1a1a1a !important; background-color: var(--body-bg) !important;
border-bottom: 1px solid #000000 !important; border-bottom: 1px solid #000000 !important;
} }
.plugins-list-header { .plugins-list-header {
justify-content: flex-start !important; justify-content: flex-start !important;
padding: 1rem 1.5rem; padding: 1rem 1.5rem;
background-color: #1a1a1a !important background-color: var(--body-bg) !important
} }
.plugins-list-title { .plugins-list-title {
margin: 0 0.5rem 0 0 !important; margin: 0 0.5rem 0 0 !important;

@ -21,6 +21,7 @@
--light: #fff; --light: #fff;
--dark: #645fb5; --dark: #645fb5;
--text: #11556c; --text: #11556c;
--body-bg: #d5efff;
--breakpoint-xs: 0; --breakpoint-xs: 0;
--breakpoint-sm: 576px; --breakpoint-sm: 576px;
--breakpoint-md: 768px; --breakpoint-md: 768px;
@ -69,7 +70,7 @@ body {
line-height: 1.5; line-height: 1.5;
color: #0f7292; color: #0f7292;
text-align: left; text-align: left;
background-color: #d5efff; background-color: var(--body-bg);
} }
[tabindex="-1"]:focus { [tabindex="-1"]:focus {

@ -23,6 +23,7 @@
--dark: #222336; --dark: #222336;
--text: #babbcc; --text: #babbcc;
--text-background: #222336; --text-background: #222336;
--body-bg: #222336;
--breakpoint-xs: 0; --breakpoint-xs: 0;
--breakpoint-sm: 576px; --breakpoint-sm: 576px;
--breakpoint-md: 768px; --breakpoint-md: 768px;
@ -67,7 +68,7 @@ body {
line-height: 1.5; line-height: 1.5;
color: #A2A3BD; color: #A2A3BD;
text-align: left; text-align: left;
background-color: #222336; background-color: var(--body-bg);
} }
*::-webkit-scrollbar { *::-webkit-scrollbar {
width: 8px; width: 8px;
@ -448,7 +449,7 @@ mark {
} }
.img-thumbnail { .img-thumbnail {
padding: 0.25rem; padding: 0.25rem;
background-color: #222336; background-color: var(--body-bg);
border: 1px solid #ddd; border: 1px solid #ddd;
border-radius: 2px; border-radius: 2px;
max-width: 100%; max-width: 100%;
@ -1364,7 +1365,7 @@ pre code {
border: 0; border: 0;
} }
.table-striped tbody tr:nth-of-type(odd) { .table-striped tbody tr:nth-of-type(odd) {
background-color: #222336; background-color: var(--body-bg);
} }
.table-hover tbody tr:hover { .table-hover tbody tr:hover {
color: #fff; color: #fff;
@ -1533,7 +1534,7 @@ pre code {
} }
.table .thead-light th { .table .thead-light th {
color: #fff; color: #fff;
background-color: #222336; background-color: var(--body-bg);
border-color: #51536b; border-color: #51536b;
} }
.table-dark { .table-dark {
@ -2353,8 +2354,8 @@ fieldset:disabled a.btn {
} }
.btn-dark { .btn-dark {
color: #fff; color: #fff;
background-color: #222336; background-color: var(--body-bg);
border-color: #222336; border-color: var(--body-bg);
} }
.btn-dark:hover { .btn-dark:hover {
color: #fff; color: #fff;
@ -2368,8 +2369,8 @@ fieldset:disabled a.btn {
.btn-dark.disabled, .btn-dark.disabled,
.btn-dark:disabled { .btn-dark:disabled {
color: #fff; color: #fff;
background-color: #222336; background-color: var(--body-bg);
border-color: #222336; border-color: var(--body-bg);
} }
.btn-dark:not(:disabled):not(.disabled).active, .btn-dark:not(:disabled):not(.disabled).active,
.btn-dark:not(:disabled):not(.disabled):active, .btn-dark:not(:disabled):not(.disabled):active,
@ -2594,13 +2595,13 @@ fieldset:disabled a.btn {
box-shadow: 0 0 0 0.2rem rgba(42, 44, 63, 0.5); box-shadow: 0 0 0 0.2rem rgba(42, 44, 63, 0.5);
} }
.btn-outline-dark { .btn-outline-dark {
color: #222336; color: var(--body-bg);
border-color: #222336; border-color: var(--body-bg);
} }
.btn-outline-dark:hover { .btn-outline-dark:hover {
color: #fff; color: #fff;
background-color: #222336; background-color: var(--body-bg);
border-color: #222336; border-color: var(--body-bg);
} }
.btn-outline-dark.focus, .btn-outline-dark.focus,
.btn-outline-dark:focus { .btn-outline-dark:focus {
@ -2608,15 +2609,15 @@ fieldset:disabled a.btn {
} }
.btn-outline-dark.disabled, .btn-outline-dark.disabled,
.btn-outline-dark:disabled { .btn-outline-dark:disabled {
color: #222336; color: var(--body-bg);
background-color: transparent; background-color: transparent;
} }
.btn-outline-dark:not(:disabled):not(.disabled).active, .btn-outline-dark:not(:disabled):not(.disabled).active,
.btn-outline-dark:not(:disabled):not(.disabled):active, .btn-outline-dark:not(:disabled):not(.disabled):active,
.show > .btn-outline-dark.dropdown-toggle { .show > .btn-outline-dark.dropdown-toggle {
color: #fff; color: #fff;
background-color: #222336; background-color: var(--body-bg);
border-color: #222336; border-color: var(--body-bg);
} }
.btn-outline-dark:not(:disabled):not(.disabled).active:focus, .btn-outline-dark:not(:disabled):not(.disabled).active:focus,
.btn-outline-dark:not(:disabled):not(.disabled):active:focus, .btn-outline-dark:not(:disabled):not(.disabled):active:focus,
@ -3454,15 +3455,15 @@ input[type="submit"].btn-block {
outline: 0; outline: 0;
} }
.custom-range:focus::-webkit-slider-thumb { .custom-range:focus::-webkit-slider-thumb {
box-shadow: 0 0 0 1px #222336, inset 0 1px 1px rgba(0, 0, 0, 0.075), box-shadow: 0 0 0 1px var(--body-bg), inset 0 1px 1px rgba(0, 0, 0, 0.075),
0 0 0 3px rgba(0, 122, 166, 0.25); 0 0 0 3px rgba(0, 122, 166, 0.25);
} }
.custom-range:focus::-moz-range-thumb { .custom-range:focus::-moz-range-thumb {
box-shadow: 0 0 0 1px #222336, inset 0 1px 1px rgba(0, 0, 0, 0.075), box-shadow: 0 0 0 1px var(--body-bg), inset 0 1px 1px rgba(0, 0, 0, 0.075),
0 0 0 3px rgba(0, 122, 166, 0.25); 0 0 0 3px rgba(0, 122, 166, 0.25);
} }
.custom-range:focus::-ms-thumb { .custom-range:focus::-ms-thumb {
box-shadow: 0 0 0 1px #222336, inset 0 1px 1px rgba(0, 0, 0, 0.075), box-shadow: 0 0 0 1px var(--body-bg), inset 0 1px 1px rgba(0, 0, 0, 0.075),
0 0 0 3px rgba(0, 122, 166, 0.25); 0 0 0 3px rgba(0, 122, 166, 0.25);
} }
.custom-range::-moz-focus-outer { .custom-range::-moz-focus-outer {
@ -3633,7 +3634,7 @@ input[type="submit"].btn-block {
.nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-item.show .nav-link,
.nav-tabs .nav-link.active { .nav-tabs .nav-link.active {
color: #fff; color: #fff;
background-color: #222336; background-color: var(--body-bg);
border-color: #3f4455; border-color: #3f4455;
} }
.nav-tabs .dropdown-menu { .nav-tabs .dropdown-menu {
@ -4419,7 +4420,7 @@ a.badge-light:focus {
} }
.badge-dark { .badge-dark {
color: #fff; color: #fff;
background-color: #222336; background-color: var(--body-bg);
} }
a.badge-dark:focus, a.badge-dark:focus,
a.badge-dark:hover { a.badge-dark:hover {
@ -5036,7 +5037,7 @@ a.close.disabled {
width: 100%; width: 100%;
color: #fff; color: #fff;
pointer-events: auto; pointer-events: auto;
background-color: #222336; background-color: var(--body-bg);
background-clip: padding-box; background-clip: padding-box;
border: 1px solid #2c3244; border: 1px solid #2c3244;
border-radius: 2px; border-radius: 2px;
@ -5687,7 +5688,7 @@ button.bg-light:hover {
background-color: #161720 !important; background-color: #161720 !important;
} }
.bg-dark { .bg-dark {
background-color: #222336 !important; background-color: var(--body-bg) !important;
} }
a.bg-dark:focus, a.bg-dark:focus,
a.bg-dark:hover, a.bg-dark:hover,
@ -8707,16 +8708,16 @@ a.text-dark:hover {
/* Plugins manager */ /* Plugins manager */
.plugin-manager { .plugin-manager {
background: #222336; background: var(--body-bg);
} }
.plugins-header { .plugins-header {
background-color: #222336 !important; background-color: var(--body-bg) !important;
border-bottom: 1px solid #2C3244 !important; border-bottom: 1px solid #2C3244 !important;
} }
.plugins-list-header { .plugins-list-header {
justify-content: flex-start !important; justify-content: flex-start !important;
padding: 1rem 1.5rem; padding: 1rem 1.5rem;
background-color: #222336 !important background-color: var(--body-bg) !important
} }
.plugins-list-title { .plugins-list-title {
margin: 0 0.5rem 0 0 !important; margin: 0 0.5rem 0 0 !important;

@ -21,6 +21,7 @@
--light: #fff; --light: #fff;
--dark: #f8fafe; --dark: #f8fafe;
--text: #3b445e; --text: #3b445e;
--body-bg: #eef1f6;
--breakpoint-xs: 0; --breakpoint-xs: 0;
--breakpoint-sm: 576px; --breakpoint-sm: 576px;
--breakpoint-md: 768px; --breakpoint-md: 768px;
@ -69,7 +70,7 @@ body {
line-height: 1.5; line-height: 1.5;
color: #2e3145; color: #2e3145;
text-align: left; text-align: left;
background-color: #eef1f6; background-color: var(--body-bg);
} }
[tabindex="-1"]:focus { [tabindex="-1"]:focus {
@ -517,7 +518,7 @@ mark,
.img-thumbnail { .img-thumbnail {
padding: 0.25rem; padding: 0.25rem;
background-color: #eef1f6; background-color: var(--body-bg);
border: 1px solid #dee2e6; border: 1px solid #dee2e6;
border-radius: 0.25rem; border-radius: 0.25rem;
max-width: 100%; max-width: 100%;
@ -1673,7 +1674,7 @@ pre code {
.table-active, .table-active,
.table-active > th, .table-active > th,
.table-active > td { .table-active > td {
background-color: #eef1f6; background-color: var(--body-bg);
} }
.table-hover .table-active:hover { .table-hover .table-active:hover {
@ -3767,13 +3768,13 @@ input[type="button"].btn-block {
outline: none; outline: none;
} }
.custom-range:focus::-webkit-slider-thumb { .custom-range:focus::-webkit-slider-thumb {
box-shadow: 0 0 0 1px #eef1f6, 0px 0px 5px #00bbff; box-shadow: 0 0 0 1px var(--body-bg), 0px 0px 5px #00bbff;
} }
.custom-range:focus::-moz-range-thumb { .custom-range:focus::-moz-range-thumb {
box-shadow: 0 0 0 1px #eef1f6, 0px 0px 5px #00bbff; box-shadow: 0 0 0 1px var(--body-bg), 0px 0px 5px #00bbff;
} }
.custom-range:focus::-ms-thumb { .custom-range:focus::-ms-thumb {
box-shadow: 0 0 0 1px #eef1f6, 0px 0px 5px #00bbff; box-shadow: 0 0 0 1px var(--body-bg), 0px 0px 5px #00bbff;
} }
.custom-range::-moz-focus-outer { .custom-range::-moz-focus-outer {
border: 0; border: 0;
@ -5482,7 +5483,7 @@ a.close.disabled {
flex-direction: column; flex-direction: column;
width: 100%; width: 100%;
pointer-events: auto; pointer-events: auto;
background-color: #eef1f6; background-color: var(--body-bg);
background-clip: padding-box; background-clip: padding-box;
border: 1px solid #dfe1ea; border: 1px solid #dfe1ea;
border-radius: 0.3rem; border-radius: 0.3rem;
@ -5496,7 +5497,7 @@ a.close.disabled {
z-index: 1040; z-index: 1040;
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
background-color: #eef1f6; background-color: var(--body-bg);
} }
.modal-backdrop.fade { .modal-backdrop.fade {
opacity: 0; opacity: 0;
@ -9494,8 +9495,9 @@ a.text-dark:focus {
border: none !important; border: none !important;
} }
.remix-bg-opacity { .remix-bg-opacity {
background: rgba(248, 250, 254, 0.80) !important; background: rgba(248, 250, 254, 0.80) !important;
} }
.plugins-list-header { .plugins-list-header {
background: transparent !important; background: transparent !important;
} }

@ -21,6 +21,7 @@
--light: #eeede9; --light: #eeede9;
--dark: #01414E; --dark: #01414E;
--text: #11556c; --text: #11556c;
--body-bg: #DBE2E0;
--breakpoint-xs: 0; --breakpoint-xs: 0;
--breakpoint-sm: 576px; --breakpoint-sm: 576px;
--breakpoint-md: 768px; --breakpoint-md: 768px;
@ -69,7 +70,7 @@ body {
line-height: 1.5; line-height: 1.5;
color: #062809; color: #062809;
text-align: left; text-align: left;
background-color: #DBE2E0; background-color: var(--body-bg);
} }
[tabindex="-1"]:focus { [tabindex="-1"]:focus {

@ -37,9 +37,9 @@ export const createNonClashingNameAsync = async (name: string, fileManager, pref
let exist = true let exist = true
do { do {
const isDuplicate = await fileManager.exists(name + _counter + prefix + '.' + ext) const isDuplicate = await fileManager.exists(name + (_counter || '') + prefix + '.' + ext)
if (isDuplicate) _counter = (_counter | 0) + 1 if (isDuplicate) _counter = (_counter || 0) + 1
else exist = false else exist = false
} while (exist) } while (exist)
const counter = _counter || '' const counter = _counter || ''

@ -2,7 +2,7 @@
import React from 'react' import React from 'react'
import * as ethJSUtil from 'ethereumjs-util' import * as ethJSUtil from 'ethereumjs-util'
import Web3 from 'web3' import Web3 from 'web3'
import { addressToString, createNonClashingNameAsync, shortenAddress } from '@remix-ui/helper' import { addressToString, createNonClashingNameAsync, extractNameFromKey, shortenAddress } from '@remix-ui/helper'
import { addNewInstance, addProvider, clearAllInstances, clearRecorderCount, displayNotification, displayPopUp, fetchAccountsListFailed, fetchAccountsListRequest, fetchAccountsListSuccess, fetchContractListSuccess, hidePopUp, removeExistingInstance, removeProvider, resetUdapp, setBaseFeePerGas, setConfirmSettings, setCurrentFile, setDecodedResponse, setEnvToasterContent, setExecutionEnvironment, setExternalEndpoint, setGasLimit, setGasPrice, setGasPriceStatus, setLoadType, setMatchPassphrase, setMaxFee, setMaxPriorityFee, setNetworkName, setPassphrase, setPathToScenario, setRecorderCount, setSelectedAccount, setSendUnit, setSendValue, setTxFeeContent, setWeb3Dialog } from './payload' import { addNewInstance, addProvider, clearAllInstances, clearRecorderCount, displayNotification, displayPopUp, fetchAccountsListFailed, fetchAccountsListRequest, fetchAccountsListSuccess, fetchContractListSuccess, hidePopUp, removeExistingInstance, removeProvider, resetUdapp, setBaseFeePerGas, setConfirmSettings, setCurrentFile, setDecodedResponse, setEnvToasterContent, setExecutionEnvironment, setExternalEndpoint, setGasLimit, setGasPrice, setGasPriceStatus, setLoadType, setMatchPassphrase, setMaxFee, setMaxPriorityFee, setNetworkName, setPassphrase, setPathToScenario, setRecorderCount, setSelectedAccount, setSendUnit, setSendValue, setTxFeeContent, setWeb3Dialog } from './payload'
import { RunTab } from '../types/run-tab' import { RunTab } from '../types/run-tab'
import { CompilerAbstract } from '@remix-project/remix-solidity' import { CompilerAbstract } from '@remix-project/remix-solidity'
@ -622,38 +622,39 @@ export const runTransactions = (
) )
} }
const saveScenario = (promptCb, cb) => { const saveScenario = (newPath: string, provider, promptCb, cb) => {
const txJSON = JSON.stringify(plugin.recorder.getAll(), null, 2) const txJSON = JSON.stringify(plugin.recorder.getAll(), null, 2)
const path = plugin.fileManager.currentPath()
promptCb(path, async () => {
const fileProvider = plugin.fileManager.fileProviderOf(path)
if (!fileProvider) return promptCb(() => {
const newFile = path + '/' + plugin.REACT_API.recorder.pathToScenario
try { try {
const newPath = await createNonClashingNameAsync(newFile, plugin.fileManager) if (!provider.set(newPath, txJSON)) return cb('Failed to create file ' + newPath)
if (!fileProvider.set(newPath, txJSON)) return cb('Failed to create file ' + newFile) plugin.fileManager.open(newPath)
plugin.fileManager.open(newFile)
} catch (error) { } catch (error) {
if (error) return cb('Failed to create file. ' + newFile + ' ' + error) if (error) return cb('Failed to create file. ' + newPath + ' ' + error)
} }
}) })
} }
export const storeScenario = (prompt: (msg: string) => JSX.Element) => { export const storeScenario = async (prompt: (msg: string, defaultValue: string) => JSX.Element) => {
saveScenario( const path = plugin.fileManager.currentPath()
(path, cb) => { const fileProvider = plugin.fileManager.fileProviderOf(path)
dispatch(displayNotification('Save transactions as scenario', prompt('Transactions will be saved in a file under ' + path), 'Ok', 'Cancel', cb, null))
if (!fileProvider) return displayNotification('Alert', 'Invalid File Provider', 'OK', null)
const newPath = await createNonClashingNameAsync(path + '/' + plugin.REACT_API.recorder.pathToScenario, plugin.fileManager)
const newName = extractNameFromKey(newPath)
saveScenario(newPath, fileProvider,
(cb) => {
dispatch(displayNotification('Save transactions as scenario', prompt('Transactions will be saved in a file under ' + path, newName), 'OK', 'Cancel', cb, null))
}, },
(error) => { (error) => {
if (error) return dispatch(displayNotification('Alert', error, 'Ok', null)) if (error) return dispatch(displayNotification('Alert', error, 'OK', null))
} }
) )
} }
const runScenario = (file: string, gasEstimationPrompt: (msg: string) => JSX.Element, passphrasePrompt: (msg: string) => JSX.Element, confirmDialogContent: MainnetPrompt, logBuilder: (msg: string) => JSX.Element) => { const runScenario = (file: string, gasEstimationPrompt: (msg: string) => JSX.Element, passphrasePrompt: (msg: string) => JSX.Element, confirmDialogContent: MainnetPrompt, logBuilder: (msg: string) => JSX.Element) => {
if (!file) return dispatch(displayNotification('Alert', 'Unable to run scenerio, no specified scenario file', 'Ok', null)) if (!file) return dispatch(displayNotification('Alert', 'Unable to run scenerio, no specified scenario file', 'OK', null))
plugin.fileManager.readFile(file).then((json) => { plugin.fileManager.readFile(file).then((json) => {
// TODO: there is still a UI dependency to remove here, it's still too coupled at this point to remove easily // TODO: there is still a UI dependency to remove here, it's still too coupled at this point to remove easily
@ -664,7 +665,7 @@ const runScenario = (file: string, gasEstimationPrompt: (msg: string) => JSX.Ele
}, (okCb, cancelCb) => { }, (okCb, cancelCb) => {
promptHandler(passphrasePrompt, okCb, cancelCb) promptHandler(passphrasePrompt, okCb, cancelCb)
}, (msg) => { }, (msg) => {
dispatch(displayNotification('Alert', msg, 'Ok', null)) dispatch(displayNotification('Alert', msg, 'OK', null))
}, (network, tx, gasEstimation, continueTxExecution, cancelCb) => { }, (network, tx, gasEstimation, continueTxExecution, cancelCb) => {
confirmationHandler(confirmDialogContent, network, tx, gasEstimation, continueTxExecution, cancelCb) confirmationHandler(confirmDialogContent, network, tx, gasEstimation, continueTxExecution, cancelCb)
}, (msg: string) => { }, (msg: string) => {
@ -673,11 +674,11 @@ const runScenario = (file: string, gasEstimationPrompt: (msg: string) => JSX.Ele
return terminalLogger(log) return terminalLogger(log)
}, (error, abi, address, contractName) => { }, (error, abi, address, contractName) => {
if (error) { if (error) {
return dispatch(displayNotification('Alert', error, 'Ok', null)) return dispatch(displayNotification('Alert', error, 'OK', null))
} }
addInstance({ name: contractName, address, abi }) addInstance({ name: contractName, address, abi })
}) })
}).catch((error) => dispatch(displayNotification('Alert', error, 'Ok', null))) }).catch((error) => dispatch(displayNotification('Alert', error, 'OK', null)))
} }
export const runCurrentScenario = (gasEstimationPrompt: (msg: string) => JSX.Element, passphrasePrompt: (msg: string) => JSX.Element, confirmDialogContent: MainnetPrompt, logBuilder: (msg: string) => JSX.Element) => { export const runCurrentScenario = (gasEstimationPrompt: (msg: string) => JSX.Element, passphrasePrompt: (msg: string) => JSX.Element, confirmDialogContent: MainnetPrompt, logBuilder: (msg: string) => JSX.Element) => {

@ -172,8 +172,8 @@ export function RunTabUI (props: RunTabProps) {
return <PassphrasePrompt message={message} setPassphrase={setPassphrasePrompt} defaultValue={runTab.passphrase} /> return <PassphrasePrompt message={message} setPassphrase={setPassphrasePrompt} defaultValue={runTab.passphrase} />
} }
const scenarioPrompt = (message: string) => { const scenarioPrompt = (message: string, defaultValue) => {
return <ScenarioPrompt message={message} setScenarioPath={updateScenarioPath} defaultValue={runTab.recorder.pathToScenario} /> return <ScenarioPrompt message={message} setScenarioPath={updateScenarioPath} defaultValue={defaultValue} />
} }
const mainnetPrompt = (tx: Tx, network: Network, amount: string, gasEstimation: string, gasFees: (maxFee: string, cb: (txFeeText: string, priceStatus: boolean) => void) => void, determineGasPrice: (cb: (txFeeText: string, gasPriceValue: string, gasPriceStatus: boolean) => void) => void) => { const mainnetPrompt = (tx: Tx, network: Network, amount: string, gasEstimation: string, gasFees: (maxFee: string, cb: (txFeeText: string, priceStatus: boolean) => void) => void, determineGasPrice: (cb: (txFeeText: string, gasPriceValue: string, gasPriceStatus: boolean) => void) => void) => {

@ -189,13 +189,13 @@ export interface ContractDropdownProps {
} }
export interface RecorderProps { export interface RecorderProps {
storeScenario: (prompt: (msg: string) => JSX.Element) => void, storeScenario: (prompt: (msg: string, defaultValue: string) => JSX.Element) => void,
runCurrentScenario: (gasEstimationPrompt: (msg: string) => JSX.Element, passphrasePrompt: (msg: string) => JSX.Element, confirmDialogContent: MainnetPrompt, logBuilder: (msg: string) => JSX.Element) => void, runCurrentScenario: (gasEstimationPrompt: (msg: string) => JSX.Element, passphrasePrompt: (msg: string) => JSX.Element, confirmDialogContent: MainnetPrompt, logBuilder: (msg: string) => JSX.Element) => void,
logBuilder: (msg: string) => JSX.Element, logBuilder: (msg: string) => JSX.Element,
mainnetPrompt: MainnetPrompt, mainnetPrompt: MainnetPrompt,
gasEstimationPrompt: (msg: string) => JSX.Element, gasEstimationPrompt: (msg: string) => JSX.Element,
passphrasePrompt: (msg: string) => JSX.Element, passphrasePrompt: (msg: string) => JSX.Element,
scenarioPrompt: (msg: string) => JSX.Element, scenarioPrompt: (msg: string, defaultValue: string) => JSX.Element,
count: number count: number
} }

@ -2,14 +2,14 @@ import React from 'react' // eslint-disable-line
const CheckTxStatus = ({ tx, type }) => { const CheckTxStatus = ({ tx, type }) => {
if (tx.status === '0x1' || tx.status === true) { if (tx.status === '0x1' || tx.status === true) {
return (<i className='txStatus succeeded fas fa-check-circle'></i>) return (<i className='remix_ui_terminal_txStatus remix_ui_terminal_succeeded fas fa-check-circle'></i>)
} }
if (type === 'call' || type === 'unknownCall' || type === 'unknown') { if (type === 'call' || type === 'unknownCall' || type === 'unknown') {
return (<i className='txStatus call'>call</i>) return (<i className='remix_ui_terminal_txStatus remix_ui_terminal_call'>call</i>)
} else if (tx.status === '0x0' || tx.status === false) { } else if (tx.status === '0x0' || tx.status === false) {
return (<i className='txStatus failed fas fa-times-circle'></i>) return (<i className='remix_ui_terminal_txStatus remix_ui_terminal_failed fas fa-times-circle'></i>)
} else { } else {
return (<i className='txStatus notavailable fas fa-circle-thin' title='Status not available' ></i>) return (<i className='remix_ui_terminal_txStatus fas fa-circle-thin' title='Status not available' ></i>)
} }
} }

@ -19,41 +19,41 @@ const Context = ({ opts, blockchain }) => {
if (blockchain.getProvider() === 'vm') { if (blockchain.getProvider() === 'vm') {
return ( return (
<div> <div>
<span className='txLog_7Xiho'> <span>
<span className='tx'>[vm]</span> <span className='remix_ui_terminal_tx'>[vm]</span>
<div className='txItem'><span className='txItemTitle'>from:</span> {from}</div> <div className='remix_ui_terminal_txItem'><span className='remix_ui_terminal_txItemTitle'>from:</span> {from}</div>
<div className='txItem'><span className='txItemTitle'>to:</span> {to}</div> <div className='remix_ui_terminal_txItem'><span className='remix_ui_terminal_txItemTitle'>to:</span> {to}</div>
<div className='txItem'><span className='txItemTitle'>value:</span> {value} wei</div> <div className='remix_ui_terminal_txItem'><span className='remix_ui_terminal_txItemTitle'>value:</span> {value} wei</div>
<div className='txItem'><span className='txItemTitle'>data:</span> {input}</div> <div className='remix_ui_terminal_txItem'><span className='remix_ui_terminal_txItemTitle'>data:</span> {input}</div>
<div className='txItem'><span className='txItemTitle'>logs:</span> {logs}</div> <div className='remix_ui_terminal_txItem'><span className='remix_ui_terminal_txItemTitle'>logs:</span> {logs}</div>
<div className='txItem'><span className='txItemTitle'>hash:</span> {hash}</div> <div className='remix_ui_terminal_txItem'><span className='remix_ui_terminal_txItemTitle'>hash:</span> {hash}</div>
</span> </span>
</div>) </div>)
} else if (blockchain.getProvider() !== 'vm' && data.resolvedData) { } else if (blockchain.getProvider() !== 'vm' && data.resolvedData) {
return ( return (
<div> <div>
<span className='txLog_7Xiho'> <span>
<span className='tx'>[block:{block} txIndex:{i}]</span> <span className='remix_ui_terminal_tx'>[block:{block} txIndex:{i}]</span>
<div className='txItem'><span className='txItemTitle'>from:</span> {from}</div> <div className='remix_ui_terminal_txItem'><span className='remix_ui_terminal_txItemTitle'>from:</span> {from}</div>
<div className='txItem'><span className='txItemTitle'>to:</span> {to}</div> <div className='remix_ui_terminal_txItem'><span className='remix_ui_terminal_txItemTitle'>to:</span> {to}</div>
<div className='txItem'><span className='txItemTitle'>value:</span> {value} wei</div> <div className='remix_ui_terminal_txItem'><span className='remix_ui_terminal_txItemTitle'>value:</span> {value} wei</div>
<div className='txItem'><span className='txItemTitle'>data:</span> {input}</div> <div className='remix_ui_terminal_txItem'><span className='remix_ui_terminal_txItemTitle'>data:</span> {input}</div>
<div className='txItem'><span className='txItemTitle'>logs:</span> {logs}</div> <div className='remix_ui_terminal_txItem'><span className='remix_ui_terminal_txItemTitle'>logs:</span> {logs}</div>
<div className='txItem'><span className='txItemTitle'>hash:</span> {hash}</div> <div className='remix_ui_terminal_txItem'><span className='remix_ui_terminal_txItemTitle'>hash:</span> {hash}</div>
</span> </span>
</div>) </div>)
} else { } else {
hash = helper.shortenHexData(data.blockHash) hash = helper.shortenHexData(data.blockHash)
return ( return (
<div> <div>
<span className='txLog'> <span>
<span className='tx'>[block:{block} txIndex:{i}]</span> <span className='remix_ui_terminal_tx'>[block:{block} txIndex:{i}]</span>
<div className='txItem'><span className='txItemTitle'>from:</span> {from}</div> <div className='remix_ui_terminal_txItem'><span className='remix_ui_terminal_txItemTitle'>from:</span> {from}</div>
<div className='txItem'><span className='txItemTitle'>to:</span> {to}</div> <div className='remix_ui_terminal_txItem'><span className='remix_ui_terminal_txItemTitle'>to:</span> {to}</div>
<div className='txItem'><span className='txItemTitle'>value:</span> {value} wei</div> <div className='remix_ui_terminal_txItem'><span className='remix_ui_terminal_txItemTitle'>value:</span> {value} wei</div>
<div className='txItem'><span className='txItemTitle'>data:</span> {input}</div> <div className='remix_ui_terminal_txItem'><span className='remix_ui_terminal_txItemTitle'>data:</span> {input}</div>
<div className='txItem'><span className='txItemTitle'>logs:</span> {logs}</div> <div className='remix_ui_terminal_txItem'><span className='remix_ui_terminal_txItemTitle'>logs:</span> {logs}</div>
<div className='txItem'><span className='txItemTitle'>hash:</span> {hash}</div> <div className='remix_ui_terminal_txItem'><span className='remix_ui_terminal_txItemTitle'>hash:</span> {hash}</div>
</span> </span>
</div>) </div>)
} }

@ -1,9 +1,8 @@
import React, { useState } from 'react' // eslint-disable-line import React, { useState } from 'react' // eslint-disable-line
import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line
import helper from 'apps/remix-ide/src/lib/helper' import helper from 'apps/remix-ide/src/lib/helper'
import CheckTxStatus from './ChechTxStatus' // eslint-disable-line import CheckTxStatus from './ChechTxStatus' // eslint-disable-line
import showTable from './Table' import showTable from './Table'
import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line
const remixLib = require('@remix-project/remix-lib') const remixLib = require('@remix-project/remix-lib')
const typeConversion = remixLib.execution.typeConversion const typeConversion = remixLib.execution.typeConversion
@ -25,18 +24,18 @@ const RenderCall = ({ tx, resolvedData, logs, index, plugin, showTableHash, txDe
return ( return (
<span id={`tx${tx.hash}`} key={index}> <span id={`tx${tx.hash}`} key={index}>
<div className="log" onClick={(event) => txDetails(event, tx)}> <div className="remix_ui_terminal_log" onClick={(event) => txDetails(event, tx)}>
<CheckTxStatus tx={tx} type={txType} /> <CheckTxStatus tx={tx} type={txType} />
<span className="txLog"> <span>
<span className="tx">[call]</span> <span className="tx">[call]</span>
<div className='txItem'><span className='txItemTitle'>from:</span> {from}</div> <div className='remix_ui_terminal_txItem'><span className='remix_ui_terminal_txItemTitle'>from:</span> {from}</div>
<div className='txItem'><span className='txItemTitle'>to:</span> {to}</div> <div className='remix_ui_terminal_txItem'><span className='remix_ui_terminal_txItemTitle'>to:</span> {to}</div>
<div className='txItem'><span className='txItemTitle'>data:</span> {input}</div> <div className='remix_ui_terminal_txItem'><span className='remix_ui_terminal_txItemTitle'>data:</span> {input}</div>
</span> </span>
<div className='buttons'> <div className='remix_ui_terminal_buttons'>
<div className="debug btn btn-primary btn-sm" onClick={(event) => debug(event, tx)}>Debug</div> <div className="remix_ui_terminal_debug btn btn-primary btn-sm" onClick={(event) => debug(event, tx)}>Debug</div>
</div> </div>
<i className="terminal_arrow fas fa-angle-down"></i> <i className="remix_ui_terminal_terminal_arrow fas fa-angle-down"></i>
</div> </div>
{showTableHash.includes(tx.hash) ? showTable({ {showTableHash.includes(tx.hash) ? showTable({
hash: tx.hash, hash: tx.hash,

@ -24,13 +24,18 @@ const RenderKnownTransactions = ({ tx, receipt, resolvedData, logs, index, plugi
const options = { from, to, tx, logs } const options = { from, to, tx, logs }
return ( return (
<span id={`tx${tx.hash}`} key={index}> <span id={`tx${tx.hash}`} key={index}>
<div className="log" onClick={(event) => txDetails(event, tx)}> <div className="remix_ui_terminal_log" onClick={(event) => txDetails(event, tx)}>
<CheckTxStatus tx={receipt} type={txType} /> <CheckTxStatus tx={receipt} type={txType} />
<Context opts = { options } blockchain={plugin.blockchain} /> <Context opts = { options } blockchain={plugin.blockchain} />
<div className='buttons'> <div className='remix_ui_terminal_buttons'>
<div className='debug btn btn-primary btn-sm' data-shared='txLoggerDebugButton' data-id={`txLoggerDebugButton${tx.hash}`} onClick={(event) => debug(event, tx)}>Debug</div> <div
className='remix_ui_terminal_debug btn btn-primary btn-sm'
data-shared='txLoggerDebugButton'
data-id={`txLoggerDebugButton${tx.hash}`}
onClick={(event) => debug(event, tx)}
>Debug</div>
</div> </div>
<i className = {`terminal_arrow fas ${(showTableHash.includes(tx.hash)) ? 'fa-angle-up' : 'fa-angle-down'}`}></i> <i className={`remix_ui_terminal_arrow fas ${(showTableHash.includes(tx.hash)) ? 'fa-angle-up' : 'fa-angle-down'}`}></i>
</div> </div>
{showTableHash.includes(tx.hash) ? showTable({ {showTableHash.includes(tx.hash) ? showTable({
hash: tx.hash, hash: tx.hash,

@ -1,5 +1,4 @@
import React, { useState } from 'react' // eslint-disable-line import React, { useState } from 'react' // eslint-disable-line
import { ModalDialog } from '@remix-ui/modal-dialog'// eslint-disable-line
import CheckTxStatus from './ChechTxStatus' // eslint-disable-line import CheckTxStatus from './ChechTxStatus' // eslint-disable-line
import Context from './Context' // eslint-disable-line import Context from './Context' // eslint-disable-line
import showTable from './Table' import showTable from './Table'
@ -20,13 +19,17 @@ const RenderUnKnownTransactions = ({ tx, receipt, index, plugin, showTableHash,
const options = { from, to, tx } const options = { from, to, tx }
return ( return (
<span id={`tx${tx.hash}`} key={index}> <span id={`tx${tx.hash}`} key={index}>
<div className="log" onClick={(event) => txDetails(event, tx)}> <div className="remix_ui_terminal_log" onClick={(event) => txDetails(event, tx)}>
<CheckTxStatus tx={receipt || tx} type={txType} /> <CheckTxStatus tx={receipt || tx} type={txType} />
<Context opts = { options } blockchain={plugin.blockchain} /> <Context opts = { options } blockchain={plugin.blockchain} />
<div className='buttons'> <div className='remix_ui_terminal_buttons'>
<div className='debug btn btn-primary btn-sm' data-shared='txLoggerDebugButton' data-id={`txLoggerDebugButton${tx.hash}`} onClick={(event) => debug(event, tx)}>Debug</div> <div className='remix_ui_terminal_debug btn btn-primary btn-sm'
data-shared='txLoggerDebugButton'
data-id={`txLoggerDebugButton${tx.hash}`}
onClick={(event) => debug(event, tx)}
>Debug</div>
</div> </div>
<i className = {`terminal_arrow fas ${(showTableHash.includes(tx.hash)) ? 'fa-angle-up' : 'fa-angle-down'}`}></i> <i className = {`remix_ui_terminal_arrow fas ${(showTableHash.includes(tx.hash)) ? 'fa-angle-up' : 'fa-angle-down'}`}></i>
</div> </div>
{showTableHash.includes(tx.hash) ? showTable({ {showTableHash.includes(tx.hash) ? showTable({
hash: tx.hash, hash: tx.hash,

@ -37,30 +37,30 @@ const showTable = (opts, showTableHash) => {
const val = opts.val != null ? typeConversion.toInt(opts.val) : 0 const val = opts.val != null ? typeConversion.toInt(opts.val) : 0
return ( return (
<table <table
className={`txTable ${showTableHash.includes(opts.hash) ? 'active' : ''}`} className={`mt-1 mb-2 mr-4 align-self-center ${showTableHash.includes(opts.hash) ? 'active' : ''}`}
id="txTable" id="txTable"
data-id={`txLoggerTable${opts.hash}`} data-id={`txLoggerTable${opts.hash}`}
> >
<tbody> <tbody>
{opts.status !== undefined ? ( {opts.status !== undefined ? (
<tr className="tr"> <tr className="remix_ui_terminal_tr">
<td className="td" data-shared={`key_${opts.hash}`}> <td className="remix_ui_terminal_td" data-shared={`key_${opts.hash}`}>
status status
</td> </td>
<td <td
className="td" className="remix_ui_terminal_td"
data-id={`txLoggerTableStatus${opts.hash}`} data-id={`txLoggerTableStatus${opts.hash}`}
data-shared={`pair_${opts.hash}`} data-shared={`pair_${opts.hash}`}
>{`${opts.status} ${msg}`}</td> >{`${opts.status} ${msg}`}</td>
</tr> </tr>
) : null} ) : null}
{opts.hash && !opts.isCall ? ( {opts.hash && !opts.isCall ? (
<tr className="tr"> <tr className="remix_ui_terminal_tr">
<td className="td" data-shared={`key_${opts.hash}`}> <td className="remix_ui_terminal_td" data-shared={`key_${opts.hash}`}>
transaction hash transaction hash
</td> </td>
<td <td
className="td" className="remix_ui_terminal_td"
data-id={`txLoggerTableHash${opts.hash}`} data-id={`txLoggerTableHash${opts.hash}`}
data-shared={`pair_${opts.hash}`} data-shared={`pair_${opts.hash}`}
> >
@ -70,12 +70,12 @@ const showTable = (opts, showTableHash) => {
</tr> </tr>
) : null} ) : null}
{opts.contractAddress ? ( {opts.contractAddress ? (
<tr className="tr"> <tr className="remix_ui_terminal_tr">
<td className="td" data-shared={`key_${opts.hash}`}> <td className="remix_ui_terminal_td" data-shared={`key_${opts.hash}`}>
contract address contract address
</td> </td>
<td <td
className="td" className="remix_ui_terminal_td"
data-id={`txLoggerTableContractAddress${opts.hash}`} data-id={`txLoggerTableContractAddress${opts.hash}`}
data-shared={`pair_${opts.hash}`} data-shared={`pair_${opts.hash}`}
> >
@ -85,12 +85,12 @@ const showTable = (opts, showTableHash) => {
</tr> </tr>
) : null} ) : null}
{opts.from ? ( {opts.from ? (
<tr className="tr"> <tr className="remix_ui_terminal_tr">
<td className="td tableTitle" data-shared={`key_${opts.hash}`}> <td className="td tableTitle" data-shared={`key_${opts.hash}`}>
from from
</td> </td>
<td <td
className="td" className="remix_ui_terminal_td"
data-id={`txLoggerTableFrom${opts.hash}`} data-id={`txLoggerTableFrom${opts.hash}`}
data-shared={`pair_${opts.hash}`} data-shared={`pair_${opts.hash}`}
> >
@ -100,12 +100,12 @@ const showTable = (opts, showTableHash) => {
</tr> </tr>
) : null} ) : null}
{opts.to ? ( {opts.to ? (
<tr className="tr"> <tr className="remix_ui_terminal_tr">
<td className="td" data-shared={`key_${opts.hash}`}> <td className="remix_ui_terminal_td" data-shared={`key_${opts.hash}`}>
to to
</td> </td>
<td <td
className="td" className="remix_ui_terminal_td"
data-id={`txLoggerTableTo${opts.hash}`} data-id={`txLoggerTableTo${opts.hash}`}
data-shared={`pair_${opts.hash}`} data-shared={`pair_${opts.hash}`}
> >
@ -115,12 +115,12 @@ const showTable = (opts, showTableHash) => {
</tr> </tr>
) : null} ) : null}
{opts.gas ? ( {opts.gas ? (
<tr className="tr"> <tr className="remix_ui_terminal_tr">
<td className="td" data-shared={`key_${opts.hash}`}> <td className="remix_ui_terminal_td" data-shared={`key_${opts.hash}`}>
gas gas
</td> </td>
<td <td
className="td" className="remix_ui_terminal_td"
data-id={`txLoggerTableGas${opts.hash}`} data-id={`txLoggerTableGas${opts.hash}`}
data-shared={`pair_${opts.hash}`} data-shared={`pair_${opts.hash}`}
> >
@ -130,12 +130,12 @@ const showTable = (opts, showTableHash) => {
</tr> </tr>
) : null} ) : null}
{opts.transactionCost ? ( {opts.transactionCost ? (
<tr className="tr"> <tr className="remix_ui_terminal_tr">
<td className="td" data-shared={`key_${opts.hash}`}> <td className="remix_ui_terminal_td" data-shared={`key_${opts.hash}`}>
transaction cost transaction cost
</td> </td>
<td <td
className="td" className="remix_ui_terminal_td"
data-id={`txLoggerTableTransactionCost${opts.hash}`} data-id={`txLoggerTableTransactionCost${opts.hash}`}
data-shared={`pair_${opts.hash}`} data-shared={`pair_${opts.hash}`}
> >
@ -145,12 +145,12 @@ const showTable = (opts, showTableHash) => {
</tr> </tr>
) : null} ) : null}
{opts.executionCost ? ( {opts.executionCost ? (
<tr className="tr"> <tr className="remix_ui_terminal_tr">
<td className="td" data-shared={`key_${opts.hash}`}> <td className="remix_ui_terminal_td" data-shared={`key_${opts.hash}`}>
execution cost execution cost
</td> </td>
<td <td
className="td" className="remix_ui_terminal_td"
data-id={`txLoggerTableExecutionHash${opts.hash}`} data-id={`txLoggerTableExecutionHash${opts.hash}`}
data-shared={`pair_${opts.hash}`} data-shared={`pair_${opts.hash}`}
> >
@ -160,12 +160,12 @@ const showTable = (opts, showTableHash) => {
</tr> </tr>
) : null} ) : null}
{opts.hash ? ( {opts.hash ? (
<tr className="tr"> <tr className="remix_ui_terminal_tr">
<td className="td" data-shared={`key_${opts.hash}`}> <td className="remix_ui_terminal_td" data-shared={`key_${opts.hash}`}>
hash hash
</td> </td>
<td <td
className="td" className="remix_ui_terminal_td"
data-id={`txLoggerTableHash${opts.hash}`} data-id={`txLoggerTableHash${opts.hash}`}
data-shared={`pair_${opts.hash}`} data-shared={`pair_${opts.hash}`}
> >
@ -175,12 +175,12 @@ const showTable = (opts, showTableHash) => {
</tr> </tr>
) : null} ) : null}
{opts.input ? ( {opts.input ? (
<tr className="tr"> <tr className="remix_ui_terminal_tr">
<td className="td" data-shared={`key_${opts.hash}`}> <td className="remix_ui_terminal_td" data-shared={`key_${opts.hash}`}>
input input
</td> </td>
<td <td
className="td" className="remix_ui_terminal_td"
data-id={`txLoggerTableHash${opts.hash}`} data-id={`txLoggerTableHash${opts.hash}`}
data-shared={`pair_${opts.hash}`} data-shared={`pair_${opts.hash}`}
> >
@ -190,12 +190,12 @@ const showTable = (opts, showTableHash) => {
</tr> </tr>
) : null} ) : null}
{opts['decoded input'] ? ( {opts['decoded input'] ? (
<tr className="tr"> <tr className="remix_ui_terminal_tr">
<td className="td" data-shared={`key_${opts.hash}`}> <td className="remix_ui_terminal_td" data-shared={`key_${opts.hash}`}>
decoded input decoded input
</td> </td>
<td <td
className="td" className="remix_ui_terminal_td"
data-id={`txLoggerTableHash${opts.hash}`} data-id={`txLoggerTableHash${opts.hash}`}
data-shared={`pair_${opts.hash}`} data-shared={`pair_${opts.hash}`}
> >
@ -205,12 +205,12 @@ const showTable = (opts, showTableHash) => {
</tr> </tr>
) : null} ) : null}
{opts['decoded output'] ? ( {opts['decoded output'] ? (
<tr className="tr"> <tr className="remix_ui_terminal_tr">
<td className="td" data-shared={`key_${opts.hash}`}> <td className="remix_ui_terminal_td" data-shared={`key_${opts.hash}`}>
decoded output decoded output
</td> </td>
<td <td
className="td" className="remix_ui_terminal_td"
data-id={`txLoggerTableHash${opts.hash}`} data-id={`txLoggerTableHash${opts.hash}`}
data-shared={`pair_${opts.hash}`} data-shared={`pair_${opts.hash}`}
> >
@ -220,12 +220,12 @@ const showTable = (opts, showTableHash) => {
</tr> </tr>
) : null} ) : null}
{opts.logs ? ( {opts.logs ? (
<tr className="tr"> <tr className="remix_ui_terminal_tr">
<td className="td" data-shared={`key_${opts.hash}`}> <td className="remix_ui_terminal_td" data-shared={`key_${opts.hash}`}>
logs logs
</td> </td>
<td <td
className="td" className="remix_ui_terminal_td"
data-id={`txLoggerTableHash${opts.hash}`} data-id={`txLoggerTableHash${opts.hash}`}
data-shared={`pair_${opts.hash}`} data-shared={`pair_${opts.hash}`}
> >
@ -238,12 +238,12 @@ const showTable = (opts, showTableHash) => {
</tr> </tr>
) : null} ) : null}
{opts.val ? ( {opts.val ? (
<tr className="tr"> <tr className="remix_ui_terminal_tr">
<td className="td" data-shared={`key_${opts.hash}`}> <td className="remix_ui_terminal_td" data-shared={`key_${opts.hash}`}>
val val
</td> </td>
<td <td
className="td" className="remix_ui_terminal_td"
data-id={`txLoggerTableHash${opts.hash}`} data-id={`txLoggerTableHash${opts.hash}`}
data-shared={`pair_${opts.hash}`} data-shared={`pair_${opts.hash}`}
> >

@ -3,425 +3,228 @@ element.style {
height: 323px !important; height: 323px !important;
} }
#terminalCliInput{ #terminalCliInput{
width: 95%; width: 97%;
background: transparent; font-weight: 800;
border: none; background: var(--body-bg)
font-weight: bold;
color: #a2a3b4;
border-top-style: hidden;
border-right-style: hidden;
border-left-style: hidden;
border-bottom-style: hidden;
} }
#terminalCliInput:focus { #terminalCliInput:focus {
outline: none; outline: none;
} }
.border-primary { .remix_ui_terminal_panel {
border-color: #007aa6!important; position : relative;
display : flex;
flex-direction : column;
font-size : 12px;
min-height : 3em;
} }
.remix_ui_terminal_bar {
/* seleted option should reflect the theme color */ z-index : 2;
.selectedOptions { }
background-color: #222336; .remix_ui_terminal_menu {
max-height : 35px;
min-height : 35px;
}
.remix_ui_terminal_toggleTerminal {
cursor : pointer;
}
.remix_ui_terminal_toggleTerminal:hover {
color : var(--secondary);
}
.remix_ui_terminal_container {
overflow-y : auto;
font-family : monospace;
background-repeat : no-repeat;
background-position : center 15%;
background-size : auto calc(75% - 1.7em);
} }
.panel { .remix_ui_terminal_journal {
position : relative; margin-top : auto;
display : flex; margin-bottom : 2rem;
flex-direction : column; font-family : monospace;
font-size : 12px; overflow-y : scroll;
min-height : 3em; }
} .remix_ui_terminal_block {
.bar { white-space : pre-wrap;
display : flex; font-family : monospace;
z-index : 2; line-height : 2ch;
} }
.menu { .remix_ui_terminal_block > pre {
position : relative; max-height : 200px;
display : flex; }
align-items : center; .remix_ui_terminal_cli {
width : 100%; white-space : nowrap;
max-height : 35px; line-height : 1.7em;
min-height : 35px; font-family : monospace;
} padding : .4em;
.toggleTerminal { color : var(--primary);
cursor : pointer; }
} .remix_ui_terminal_prompt {
.toggleTerminal:hover { font-family : monospace;
color : var(--secondary); }
} .remix_ui_terminal_input {
.terminal_container { outline : none;
display : flex; font-family : monospace;
flex-direction : column; }
height : 100%; .remix_ui_terminal_search {
overflow-y : auto; width : 330px;
font-family : monospace; padding-left : 20px;
margin : 0px; padding-top : 1px;
background-repeat : no-repeat; padding-bottom : 1px;
background-position : center 15%; }
background-size : auto calc(75% - 1.7em); .remix_ui_terminal_filter {
} height : 80%;
.terminal { white-space : nowrap;
position : relative; overflow : hidden;
display : flex; text-overflow : ellipsis;
flex-direction : column; }
height : 100%; .remix_ui_terminal_searchIcon {
} width : 25px;
.journal { border-top-left-radius : 3px;
margin-top : auto; border-bottom-left-radius : 3px;
font-family : monospace; margin-right : 5px;
} }
.block {
word-break : break-word;
white-space : pre-wrap;
line-height : 2ch;
padding : 1ch;
margin-top : 2ch;
}
.block > pre {
max-height : 200px;
}
.cli {
line-height : 1.7em;
font-family : monospace;
padding : .4em;
color : var(--primary);
}
.prompt {
margin-right : 0.5em;
font-family : monospace;
font-weight : bold;
font-size : 14px;
color : lightgray;
}
.input {
word-break : break-word;
outline : none;
font-family : monospace;
}
.search {
display : flex;
align-items : center;
width : 330px;
padding-left : 20px;
height : 100%;
padding-top : 1px;
padding-bottom : 1px;
}
.filter {
height : 80%;
white-space : nowrap;
overflow : hidden;
text-overflow : ellipsis;
}
.searchIcon {
width : 25px;
border-top-left-radius : 3px;
border-bottom-left-radius : 3px;
display : flex;
align-items : center;
justify-content : center;
margin-right : 5px;
}
.listen {
margin-right : 30px;
min-width : 40px;
height : 13px;
display : flex;
align-items : center;
}
.listenLabel {
min-width: 50px;
}
.verticalLine {
border-left : 1px solid var(--secondary);
height : 65%;
}
.dragbarHorizontal {
position : absolute;
top : 0;
height : 0.2em;
right : 0;
left : 0;
cursor : row-resize;
z-index : 999;
}
.dragbarDragging {
background-color: var(--primary);
border: 2px solid var(--primary);
}
.console {
cursor : pointer;
}
.dragbarHorizontal:hover {
background-color: var(--secondary);
border:2px solid var(--secondary);
}
.listenOnNetwork {
min-height: auto;
}
.ghostbar {
position : absolute;
height : 6px;
opacity : 0.5;
cursor : row-resize;
z-index : 9999;
left : 0;
right : 0;
}
.divider-hitbox {
color: white;
cursor: row-resize;
align-self: stretch;
display: flex;
align-items: center;
padding: 0 1rem;
}
.ul {margin-left: 0; padding-left: 20px;}
.popup {
position : absolute;
text-align : left;
width : 95%;
font-family : monospace;
background-color : var(--secondary);
overflow : auto;
padding-bottom : 13px;
z-index : 80;
bottom : 1em;
border-width : 4px;
left : 2em;
overflow-y : scroll;
}
.autoCompleteItem {
padding : 4px;
border-radius : 2px;
}
.popup a {
cursor : pointer;
}
.listHandlerShow {
display : block;
}
.listHandlerHide {
display : none;
}
.listHandlerButtonShow {
position : fixed;
width : 46%;
}
.pageNumberAlignment {
font-size : 10px;
float : right;
}
.modalContent {
position : absolute;
margin-left : 20%;
margin-bottom : 32px;
bottom : 0px;
padding : 0;
line-height : 18px;
font-size : 12px;
width : 40%;
box-shadow : 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
-webkit-animation-name: animatebottom;
-webkit-animation-duration: 0.4s;
animation-name : animatetop;
animation-duration: 0.4s
}
@-webkit-keyframes animatetop { .remix_ui_terminal_console {
from {bottom: -300px; opacity: 0} cursor : pointer;
to {bottom: 0; opacity: 1} }
}
@keyframes animatetop { .remix_ui_terminal_listenOnNetwork {
from {bottom: -300px; opacity: 0} min-height: auto;
to {bottom: 0; opacity: 1} }
}
.remix_ui_terminal_popup {
width : 95%;
font-family : monospace;
background-color : var(--secondary);
overflow : auto;
z-index : 80;
bottom : 2.2em;
border-width : 4px;
overflow-y : scroll;
box-shadow : 0px 0px 13px -8px;
}
.remix_ui_terminal_autoCompleteItem {
padding : 4px;
border-radius : 2px;
}
.remix_ui_terminal_popup a {
cursor : pointer;
}
/* tx logger css*/ .call {
font-size: 7px;
border-radius: 50%;
min-width: 20px;
min-height: 20px;
display: flex;
justify-content: center;
align-items: center;
color: var(--text-info);
text-transform: uppercase;
font-weight: bold;
}
.log { .remix_ui_terminal_txItem {
display: flex; color: var(--text-info);
cursor: pointer; margin-right: 5px;
align-items: center; float: left;
cursor: pointer; }
}
.log:hover {
opacity: 0.8;
}
.txStatus { .remix_ui_terminal_txItemTitle {
display: flex; font-weight: bold;
font-size: 20px; }
margin-right: 20px;
float: left;
}
.succeeded {
color: var(--success);
}
.failed {
color: var(--danger);
}
.terminal_arrow { /* tx logger css*/
color: var(--text-info);
font-size: 20px;
cursor: pointer;
display: flex;
margin-left: 10px;
}
.terminal_arrow:hover {
color: var(--secondary);
}
.notavailable {
}
.call {
font-size: 7px;
border-radius: 50%;
min-width: 20px;
min-height: 20px;
display: flex;
justify-content: center;
align-items: center;
color: var(--text-info);
text-transform: uppercase;
font-weight: bold;
}
.txItem {
color: var(--text-info);
margin-right: 5px;
float: left;
}
.txItemTitle {
font-weight: bold;
}
.tx {
color: var(--text-info);
font-weight: bold;
float: left;
margin-right: 10px;
}
.txTable,
.tr,
.td {
border-collapse: collapse;
font-size: 10px;
color: var(--text-info);
border: 1px solid var(--text-info);
transition: max-height 0.3s, padding 0.3s;
}
table .active {
transition: max-height 0.6s, padding 0.6s;
}
#txTable {
margin-top: 1%;
margin-bottom: 5%;
align-self: center;
width: 85%;
}
.tr, .td {
padding: 4px;
vertical-align: baseline;
}
.td:first-child {
min-width: 30%;
width: 30%;
align-items: baseline;
font-weight: bold;
}
.tableTitle {
width: 25%;
}
.buttons {
display: flex;
margin-left: auto;
}
.debug {
white-space: nowrap;
}
.debug:hover {
opacity: 0.8;
}
.remix_ui_terminal_log {
display: flex;
cursor: pointer;
align-items: center;
cursor: pointer;
padding-top: 0.5rem;
}
.remix_ui_terminal_log:hover {
opacity: 0.8;
}
/* Style the accordion section */ .remix_ui_terminal_txStatus {
.accordion__section {
display: flex; display: flex;
flex-direction: column; font-size: 20px;
margin-right: 20px;
float: left;
}
.remix_ui_terminal_succeeded {
color: var(--success);
}
.remix_ui_terminal_failed {
color: var(--danger);
} }
/* Style the buttons that are used to open and close the accordion panel */ .remix_ui_terminal_arrow {
.accordion { color: var(--text-info);
background-color: #eee; font-size: 20px;
color: #444;
cursor: pointer; cursor: pointer;
padding: 18px;
display: flex; display: flex;
margin-left: 10px;
}
.remix_ui_terminal_arrow:hover {
color: var(--secondary);
}
.remix_ui_terminal_call {
font-size: 7px;
border-radius: 50%;
min-width: 20px;
min-height: 20px;
display: flex;
justify-content: center;
align-items: center; align-items: center;
border: none; color: var(--text-info);
outline: none; text-transform: uppercase;
transition: background-color 0.6s ease; font-weight: bold;
} }
/* Add a background color to the button if it is clicked on (add the .active class with JS), and when you move the mouse over it (hover) */ .remix_ui_terminal_tx {
/* .accordion:hover, color: var(--text-info);
.active { font-weight: bold;
background-color: #ccc; float: left;
} */ margin-right: 10px;
/* Style the accordion content title */
.accordion__title {
font-family: "Open Sans", sans-serif;
font-weight: 600;
font-size: 14px;
} }
/* Style the accordion chevron icon */ .remix_ui_terminal_tr,
.accordion__icon { .remix_ui_terminal_td {
margin-left: auto; border-collapse: collapse;
transition: transform 0.6s ease; font-size: 10px;
color: var(--text-info);
border: 1px solid var(--text-info);
transition: max-height 0.3s, padding 0.3s;
} }
table .active {
/* Style to rotate icon when state is active */ transition: max-height 0.6s, padding 0.6s;
.rotate {
transform: rotate(90deg);
} }
.remix_ui_terminal_tr, .remix_ui_terminal_td {
/* Style the accordion content panel. Note: hidden by default */ padding: 4px;
.accordion__content { vertical-align: baseline;
background-color: white;
overflow: hidden;
transition: max-height 0.6s ease;
} }
.remix_ui_terminal_td:first-child {
/* Style the accordion content text */ min-width: 30%;
.accordion__text { width: 30%;
font-family: "Open Sans", sans-serif; align-items: baseline;
font-weight: 400; font-weight: bold;
font-size: 14px; }
padding: 18px; .remix_ui_terminal_tableTitle {
width: 25%;
}
.remix_ui_terminal_buttons {
display: flex;
margin-left: auto;
}
.remix_ui_terminal_debug {
white-space: nowrap;
}
.remix_ui_terminal_debug:hover {
opacity: 0.8;
} }

@ -72,13 +72,9 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
const messagesEndRef = useRef(null) const messagesEndRef = useRef(null)
// terminal dragable // terminal dragable
const leftRef = useRef(null)
const panelRef = useRef(null) const panelRef = useRef(null)
const terminalMenu = useRef(null) const terminalMenu = useRef(null)
const terminalMenuOffsetHeight = (terminalMenu.current && terminalMenu.current.offsetHeight) || 35
const terminalDefaultPosition = config.get('terminal-top-offset')
const scrollToBottom = () => { const scrollToBottom = () => {
messagesEndRef.current.scrollIntoView({ behavior: 'smooth' }) messagesEndRef.current.scrollIntoView({ behavior: 'smooth' })
} }
@ -381,14 +377,24 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
} else { } else {
setShowTableHash((prevState) => ([...prevState, tx.hash])) setShowTableHash((prevState) => ([...prevState, tx.hash]))
} }
scrollToBottom()
} }
const handleAutoComplete = () => ( const handleAutoComplete = () => (
<div className='popup alert alert-secondary' style={{ display: (autoCompletState.showSuggestions && autoCompletState.userInput !== '' && (autoCompletState.userInput.length > 2)) && autoCompletState.data._options.length > 0 ? 'block' : 'none' }}> <div
className='remix_ui_terminal_popup bg-light ml-4 p-2 position-absolute text-left '
style={{ display: (autoCompletState.showSuggestions && autoCompletState.userInput !== '' && (autoCompletState.userInput.length > 2)) && autoCompletState.data._options.length > 0 ? 'block' : 'none' }}
>
<div> <div>
{autoCompletState.data._options.map((item, index) => { {autoCompletState.data._options.map((item, index) => {
return ( return (
<div key={index} data-id="autoCompletePopUpAutoCompleteItem" className={`autoCompleteItem listHandlerShow item ${autoCompletState.data._options[autoCompletState.activeSuggestion] === item ? 'border border-primary ' : ''}`} onKeyDown={ handleSelect } onClick={() => handleClickSelect(item)}> <div
key={index}
data-id="autoCompletePopUpAutoCompleteItem"
className={`remix_ui_terminal_autoCompleteItem item ${autoCompletState.data._options[autoCompletState.activeSuggestion] === item ? 'border border-primary ' : ''}`}
onKeyDown={ handleSelect }
onClick={() => handleClickSelect(item)}
>
<div> <div>
{getKeyOf(item)} {getKeyOf(item)}
</div> </div>
@ -413,17 +419,19 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
props.plugin.call('layout', 'minimize', props.plugin.profile.name, isOpen) props.plugin.call('layout', 'minimize', props.plugin.profile.name, isOpen)
} }
const classNameBlock = 'remix_ui_terminal_block px-4 py-1 text-break'
return ( return (
<div style={{ flexGrow: 1 }} className='panel' ref={panelRef}> <div style={{ flexGrow: 1 }} className='remix_ui_terminal_panel' ref={panelRef}>
<div className="bar"> <div className="remix_ui_terminal_bar d-flex">
<div className="menu border-top border-dark bg-light" ref={terminalMenu} data-id="terminalToggleMenu"> <div className="remix_ui_terminal_menu d-flex w-100 align-items-center position-relative border-top border-dark bg-light" ref={terminalMenu} data-id="terminalToggleMenu">
<i className={`mx-2 toggleTerminal fas ${isOpen ? 'fa-angle-double-down' : 'fa-angle-double-up'}`} data-id="terminalToggleIcon" onClick={handleToggleTerminal}></i> <i className={`mx-2 remix_ui_terminal_toggleTerminal fas ${isOpen ? 'fa-angle-double-down' : 'fa-angle-double-up'}`} data-id="terminalToggleIcon" onClick={handleToggleTerminal}></i>
<div className="mx-2 console" id="clearConsole" data-id="terminalClearConsole" onClick={handleClearConsole} > <div className="mx-2 remix_ui_terminal_console" id="clearConsole" data-id="terminalClearConsole" onClick={handleClearConsole} >
<i className="fas fa-ban" aria-hidden="true" title="Clear console" <i className="fas fa-ban" aria-hidden="true" title="Clear console"
></i> ></i>
</div> </div>
<div className="mx-2" title='Pending Transactions'>0</div> <div className="mx-2" title='Pending Transactions'>0</div>
<div className="pt-1 h-80 mx-3 align-items-center listenOnNetwork custom-control custom-checkbox"> <div className="pt-1 h-80 mx-3 align-items-center remix_ui_terminal_listenOnNetwork custom-control custom-checkbox">
<input <input
className="custom-control-input" className="custom-control-input"
id="listenNetworkCheck" id="listenNetworkCheck"
@ -439,47 +447,79 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
listen on network listen on network
</label> </label>
</div> </div>
<div className="search"> <div className="remix_ui_terminal_search d-flex align-items-center h-100">
<i className="fas fa-search searchIcon bg-light" aria-hidden="true"></i> <i
className="remix_ui_terminal_searchIcon d-flex align-items-center justify-content-center fas fa-search bg-light"
aria-hidden="true">
</i>
<input <input
onChange={(event) => setSearchInput(event.target.value.trim()) } onChange={(event) => setSearchInput(event.target.value.trim()) }
type="text" type="text"
className="border filter form-control" className="remix_ui_terminal_filter border form-control"
id="searchInput" id="searchInput"
placeholder="Search with transaction hash or address" placeholder="Search with transaction hash or address"
data-id="terminalInputSearch" /> data-id="terminalInputSearch" />
</div> </div>
</div> </div>
</div> </div>
<div tabIndex={-1} className="terminal_container" data-id="terminalContainer" > <div tabIndex={-1} className="remix_ui_terminal_container d-flex h-100 m-0 flex-column" data-id="terminalContainer" >
{ {
handleAutoComplete() handleAutoComplete()
} }
<div data-id='terminalContainerDisplay' style = {{ <div className="position-relative d-flex flex-column-reverse h-100">
position: 'relative', <div id='journal' className='remix_ui_terminal_journal d-flex flex-column pt-3 pb-4 px-2 mx-2 mr-0' data-id='terminalJournal'>
height: '100%',
width: '100%',
opacity: '0.1',
zIndex: -1
}}></div>
<div className="terminal">
<div id='journal' className='journal' data-id='terminalJournal'>
{!clearConsole && <TerminalWelcomeMessage packageJson={version}/>} {!clearConsole && <TerminalWelcomeMessage packageJson={version}/>}
{newstate.journalBlocks && newstate.journalBlocks.map((x, index) => { {newstate.journalBlocks && newstate.journalBlocks.map((x, index) => {
if (x.name === EMPTY_BLOCK) { if (x.name === EMPTY_BLOCK) {
return ( return (
<div className="px-4 block" data-id='block' key={index}> <div className={classNameBlock} data-id='block' key={index}>
<span className='txLog'> <span className='remix_ui_terminal_tx'>
<span className='tx'><div className='txItem'>[<span className='txItemTitle'>block:{x.message} - </span> 0 {'transactions'} ] </div></span></span> <div className='remix_ui_terminal_txItem'>[<span className='remix_ui_terminal_txItemTitle'>block:{x.message} - </span> 0 {'transactions'} ]
</div>
</span>
</div> </div>
) )
} else if (x.name === UNKNOWN_TRANSACTION) { } else if (x.name === UNKNOWN_TRANSACTION) {
return x.message.filter(x => x.tx.hash.includes(searchInput) || x.tx.from.includes(searchInput) || (x.tx.to.includes(searchInput))).map((trans) => { return x.message.filter(x => x.tx.hash.includes(searchInput) || x.tx.from.includes(searchInput) || (x.tx.to.includes(searchInput))).map((trans) => {
return (<div className='px-4 block' data-id={`block_tx${trans.tx.hash}`} key={index}> { <RenderUnKnownTransactions tx={trans.tx} receipt={trans.receipt} index={index} plugin={props.plugin} showTableHash={showTableHash} txDetails={txDetails} modal={modal}/>} </div>) return (
<div className={classNameBlock} data-id={`block_tx${trans.tx.hash}`} key={index}> {
<RenderUnKnownTransactions
tx={trans.tx}
receipt={trans.receipt}
index={index} plugin={props.plugin}
showTableHash={showTableHash}
txDetails={txDetails}
modal={modal}
/>}
</div>
)
}) })
} else if (x.name === KNOWN_TRANSACTION) { } else if (x.name === KNOWN_TRANSACTION) {
return x.message.map((trans) => { return x.message.map((trans) => {
return (<div className='px-4 block' data-id={`block_tx${trans.tx.hash}`} key={index}> { trans.tx.isCall ? <RenderCall tx={trans.tx} resolvedData={trans.resolvedData} logs={trans.logs} index={index} plugin={props.plugin} showTableHash={showTableHash} txDetails={txDetails} modal={modal}/> : (<RenderKnownTransactions tx = { trans.tx } receipt = { trans.receipt } resolvedData = { trans.resolvedData } logs = {trans.logs } index = { index } plugin = { props.plugin } showTableHash = { showTableHash } txDetails = { txDetails } modal={modal}/>) } </div>) return (
<div className={classNameBlock} data-id={`block_tx${trans.tx.hash}`} key={index}>
{ trans.tx.isCall ? <RenderCall
tx={trans.tx}
resolvedData={trans.resolvedData}
logs={trans.logs}
index={index}
plugin={props.plugin}
showTableHash={showTableHash}
txDetails={txDetails}
modal={modal}
/> : (<RenderKnownTransactions
tx = { trans.tx }
receipt = { trans.receipt }
resolvedData = { trans.resolvedData }
logs = {trans.logs }
index = { index }
plugin = { props.plugin }
showTableHash = { showTableHash }
txDetails = { txDetails }
modal={modal}
/>) }
</div>
)
}) })
} else if (Array.isArray(x.message)) { } else if (Array.isArray(x.message)) {
return x.message.map((msg, i) => { return x.message.map((msg, i) => {
@ -489,28 +529,40 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => {
) )
} else if (typeof msg === 'object') { } else if (typeof msg === 'object') {
return ( return (
<div className="px-4 block" data-id="block" key={i}><span className={x.style}>{ msg.value ? parse(msg.value) : JSON.stringify(msg) } </span></div> <div className={classNameBlock} data-id="block" key={i}><span className={x.style}>{ msg.value ? parse(msg.value) : JSON.stringify(msg) } </span></div>
) )
} else { } else {
return ( return (
<div className="px-4 block" data-id="block" key={i}><span className={x.style}>{ msg ? msg.toString().replace(/,/g, '') : msg }</span></div> <div className={classNameBlock} data-id="block" key={i}><span className={x.style}>{ msg ? msg.toString().replace(/,/g, '') : msg }</span></div>
) )
} }
}) })
} else { } else {
if (typeof x.message !== 'function') { if (typeof x.message !== 'function') {
return ( return (
<div className="px-4 block" data-id="block" key={index}> <span className={x.style}> {x.message}</span></div> <div className={classNameBlock} data-id="block" key={index}> <span className={x.style}> {x.message}</span></div>
) )
} }
} }
})} })}
<div ref={messagesEndRef} /> <div ref={messagesEndRef} />
</div> </div>
<div id="terminalCli" data-id="terminalCli" className="cli" onClick={focusinput}> { isOpen && <div id="terminalCli" data-id="terminalCli" className="remix_ui_terminal_cli position-absolute w-100" onClick={focusinput}>
<span className="prompt">{'>'}</span> <span className="remix_ui_terminal_prompt blink mx-1 font-weight-bold text-dark">{'>'}</span>
<input className="input" ref={inputEl} spellCheck="false" contentEditable="true" id="terminalCliInput" data-id="terminalCliInput" onChange={(event) => onChange(event)} onKeyDown={(event) => handleKeyDown(event) } value={autoCompletState.userInput} onPaste={handlePaste}></input> <input
className="remix_ui_terminal_input ml-1 text-dark text-break border-0"
ref={inputEl}
spellCheck="false"
contentEditable="true"
id="terminalCliInput"
data-id="terminalCliInput"
onChange={(event) => onChange(event)}
onKeyDown={(event) => handleKeyDown(event) }
value={autoCompletState.userInput}
onPaste={handlePaste}
></input>
</div> </div>
}
</div> </div>
</div> </div>
<ModalDialog <ModalDialog

@ -2,10 +2,10 @@ import React from 'react' // eslint-disable-line
const TerminalWelcomeMessage = ({ packageJson }) => { const TerminalWelcomeMessage = ({ packageJson }) => {
return ( return (
<div className="px-4 block" data-id="block_null"> <div className="remix_ui_terminal_block px-4 " data-id="block_null">
<div> - Welcome to Remix {packageJson} - </div><br /> <div> - Welcome to Remix {packageJson} - </div><br />
<div>You can use this terminal to: </div> <div>You can use this terminal to: </div>
<ul className='ul'> <ul className='ml-0 mr-4'>
<li>Check transactions details and start debugging.</li> <li>Check transactions details and start debugging.</li>
<li>Execute JavaScript scripts: <li>Execute JavaScript scripts:
<br /> <br />
@ -17,7 +17,7 @@ const TerminalWelcomeMessage = ({ packageJson }) => {
</li> </li>
</ul> </ul>
<div>The following libraries are accessible:</div> <div>The following libraries are accessible:</div>
<ul className='ul'> <ul className='ml-0 mr-4'>
<li><a target="_blank" href="https://web3js.readthedocs.io/en/1.0/">web3 version 1.5.2</a></li> <li><a target="_blank" href="https://web3js.readthedocs.io/en/1.0/">web3 version 1.5.2</a></li>
<li><a target="_blank" href="https://docs.ethers.io">ethers.js</a> </li> <li><a target="_blank" href="https://docs.ethers.io">ethers.js</a> </li>
<li>remix (run remix.help() for more info)</li> <li>remix (run remix.help() for more info)</li>

Loading…
Cancel
Save