Merge pull request #2615 from ethereum/dev2master

EthWorks update for deploy & run module for the dark theme
pull/1/head
yann300 5 years ago committed by GitHub
commit 1042c2766e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      src/app/tabs/compileTab/compilerContainer.js
  2. 3
      src/app/tabs/runTab/contractDropdown.js
  3. 24
      src/app/tabs/runTab/settings.js
  4. 2
      src/app/tabs/staticanalysis/staticAnalysisView.js
  5. 91
      src/app/tabs/styles/run-tab-styles.js
  6. 2
      src/app/tabs/styles/settings-tab-styles.js
  7. 8
      src/app/udapp/run-tab.js
  8. 17
      src/app/ui/card.js
  9. 2
      src/app/ui/copy-to-clipboard.js
  10. 9
      src/app/ui/multiParamManager.js
  11. 8
      src/app/ui/universal-dapp-ui.js
  12. 120
      src/universal-dapp-styles.js

@ -241,7 +241,7 @@ class CompilerContainer {
<div class="row w-100 no-gutters mb-2">
<div class="col-sm-4">
<div class="d-flex flex-row justify-content-end">
<label class="${css.compilerLabel} input-group-text pr-0 border-0 w-100" for="versionSelector">
<label class="${css.compilerLabel} form-check-label input-group-text pr-0 border-0 w-100" for="versionSelector">
<button class="far fa-plus-square border-0 p-0 mx-2 btn-sm" onclick="${(e) => this.promtCompiler(e)}" title="Add a custom compiler with URL"></button>
Compiler
</label>
@ -250,14 +250,14 @@ class CompilerContainer {
<div class="col-sm-8">
${this._view.versionSelector}
<div class="pt-0 ${css.nightlyBuilds}">
<label for="nightlies" class="text-dark p-0 m-0">Include nightly builds</label>
<label for="nightlies" class="text-dark p-0 m-0 form-check-label">Include nightly builds</label>
${this._view.includeNightlies}
</div>
</div>
</div>
<div class="row w-100 no-gutters mb-2">
<div class="col-sm-4">
<label class="${css.compilerLabel} input-group-text pl-0 border-0" for="compilierLanguageSelector">Language</label>
<label class="${css.compilerLabel} form-check-label input-group-text pl-0 border-0" for="compilierLanguageSelector">Language</label>
</div>
<div class="col-sm-8">
${this._view.languageSelector}
@ -265,7 +265,7 @@ class CompilerContainer {
</div>
<div class="row w-100 no-gutters">
<div class="col-sm-4">
<label class="${css.compilerLabel} input-group-text pl-0 border-0" for="evmVersionSelector">EVM Version</label>
<label class="${css.compilerLabel} form-check-label input-group-text pl-0 border-0" for="evmVersionSelector">EVM Version</label>
</div>
<div class="col-sm-8">
${this._view.evmVersionSelector}
@ -280,15 +280,15 @@ class CompilerContainer {
<ul class="list-group list-group-flush">
<li class="list-group-item form-group ${css.compilerConfig}">
${this._view.autoCompile}
<label for="autoCompile">Auto compile</label>
<label class="form-check-label" for="autoCompile">Auto compile</label>
</li>
<li class="list-group-item form-group ${css.compilerConfig}">
${this._view.optimize}
<label for="optimize">Enable optimization</label>
<label class="form-check-label" for="optimize">Enable optimization</label>
</li>
<li class="list-group-item form-group ${css.compilerConfig}">
${this._view.hideWarningsBox}
<label for="hideWarningsBox">Hide warnings</label>
<label class="form-check-label" for="hideWarningsBox">Hide warnings</label>
</li>
</ul>
</article>

@ -51,10 +51,11 @@ class ContractDropdownUI {
this.atAddressButtonInput = yo`<input class="${css.input} ${css.ataddressinput} ataddressinput form-control" placeholder="Load contract from Address" title="address of contract" oninput=${this.atAddressChanged.bind(this)} />`
this.selectContractNames = yo`<select class="${css.contractNames} custom-select" disabled></select>`
this.createPanel = yo`<div class="${css.button}"></div>`
this.createPanel = yo`<div class="${css.deployDropdown}"></div>`
this.orLabel = yo`<div class="${css.orLabel}">or</div>`
let el = yo`
<div class="${css.container}">
<label class="${css.settingsLabel}">Contract</label>
<div class="${css.subcontainer}">
${this.selectContractNames} ${this.compFails} ${info}
</div>

@ -56,11 +56,11 @@ class SettingsUI {
var environmentEl = yo`
<div class="${css.crow}">
<div id="selectExEnv" class="${css.col1_1}">
<label id="selectExEnv" class="${css.settingsLabel}">
Environment
</div>
<div class=${css.environment}>
<select id="selectExEnvOptions" onchange=${() => { this.updateNetwork() }} class="form-control ${css.select}">
</label>
<div class="${css.environment}">
<select id="selectExEnvOptions" onchange=${() => { this.updateNetwork() }} class="form-control ${css.select} custom-select">
<option id="vm-mode"
title="Execution environment does not connect to any node, everything is local and in memory only."
value="vm" name="executionContext"> JavaScript VM
@ -81,7 +81,7 @@ class SettingsUI {
`
const networkEl = yo`
<div class="${css.crow}">
<div class="${css.col1_1}">
<div class="${css.settingsLabel}">
</div>
<div class="${css.environment}">
${this.netUI}
@ -90,14 +90,14 @@ class SettingsUI {
`
const accountEl = yo`
<div class="${css.crow}">
<div class="${css.col1_1}">
<label class="${css.settingsLabel}">
Account
<span id="remixRunPlusWraper" title="Create a new account" onload=${this.updatePlusButton.bind(this)}>
<i id="remixRunPlus" class="fas fa-plus-circle ${css.icon}" aria-hidden="true" onclick=${this.newAccount.bind(this)}"></i>
</span>
</div>
<div class=${css.account}>
<select name="txorigin" class="form-control ${css.select}" id="txorigin"></select>
</label>
<div class="${css.account}">
<select name="txorigin" class="form-control ${css.select} custom-select" id="txorigin"></select>
${copyToClipboard(() => document.querySelector('#runTabView #txorigin').value)}
<i id="remixRunSignMsg" class="fas fa-edit ${css.icon}" aria-hidden="true" onclick=${this.signMessage.bind(this)} title="Sign a message using this account key"></i>
</div>
@ -106,17 +106,17 @@ class SettingsUI {
const gasPriceEl = yo`
<div class="${css.crow}">
<div class="${css.col1_1}">Gas limit</div>
<label class="${css.settingsLabel}">Gas limit</label>
<input type="number" class="form-control ${css.gasNval} ${css.col2}" id="gasLimit" value="3000000">
</div>
`
const valueEl = yo`
<div class="${css.crow}">
<div class="${css.col1_1}">Value</div>
<label class="${css.settingsLabel}">Value</label>
<div class="${css.gasValueContainer}">
<input type="text" class="form-control ${css.gasNval} ${css.col2}" id="value" value="0" title="Enter the value and choose the unit">
<select name="unit" class="form-control p-1 ${css.gasNvalUnit} ${css.col2_2}" id="unit">
<select name="unit" class="form-control p-1 ${css.gasNvalUnit} ${css.col2_2} custom-select" id="unit">
<option data-unit="wei">wei</option>
<option data-unit="gwei">gwei</option>
<option data-unit="finney">finney</option>

@ -158,7 +158,7 @@ staticAnalysisView.prototype.renderModules = function () {
var category = groupedModules[categoryId]
var entriesDom = category.map((item, i) => {
return yo`
<label class="${css.label}">
<label class="${css.label} form-check-label">
<input id="staticanalysismodule_${categoryId}_${i}"
type="checkbox"
class="staticAnalysisItem"

@ -5,55 +5,50 @@ var css = csjs`
display: flex;
flex-direction: column;
}
.runTabView::-webkit-scrollbar {
display: none;
}
.instanceContainerTitle {
font-weight: bold;
margin-bottom: 25px;
font-size: 12px;
display: flex;
justify-content: space-between;
padding-left: 15px;
height: 0px;
align-items: center;
padding-left: 10px;
margin: 0 0 16px;
font-size: 14px;
line-height: 19px;
}
.settings {
margin-bottom: 2%;
padding: 10px 0px 15px 15px;
}
.recorderCount {
/* margin-right: 30px; */
/* min-width: 13px; */
/* display: flex; */
/* justify-content: center; */
/* align-items: center; */
/* font-size: 10px; */
padding: 0 24px 16px;
}
.crow {
margin-top: .5em;
display: flex;
align-items: center;
/*width: 500px;*/
display: block;
margin-top: 8px;
}
.col1 {
width: 30%;
float: left;
align-self: center;
}
.col1_1 {
font-size: 12px;
min-width: 75px;
float: left;
align-self: center;
.settingsLabel {
font-size: 11px;
margin-bottom: 4px;
text-transform: uppercase;
}
.environment {
display: flex;
align-items: center;
position: relative;
width: 100%;
padding-right: 25px;
}
.environment a {
margin-left: 7px;
}
.account {
display: flex;
align-items: center;
width: 90%;
}
.account i {
margin-left: 12px;
}
.col2 {
border-radius: 3px;
@ -74,7 +69,7 @@ var css = csjs`
margin-bottom: 2%;
border: none;
text-align: center;
padding: 10px 0px 15px 0px;
padding: 0 14px 16px;
}
.pendingTxsContainer {
display: flex;
@ -84,8 +79,7 @@ var css = csjs`
text-align: center;
}
.container {
margin-bottom: 4%;
padding-left: 15px;
padding: 0 24px 16px;
}
.recorderCollapsedView,
.recorderExpandedView {
@ -104,7 +98,14 @@ var css = csjs`
.subcontainer {
display: flex;
flex-direction: row;
align-items: baseline;
align-items: center;
margin-bottom: 8px;
}
.subcontainer i {
width: 16px;
display: flex;
justify-content: center;
margin-left: 1px;
}
.button button{
flex: none;
@ -127,13 +128,13 @@ var css = csjs`
border-right: 0;
}
.atAddressSect {
margin-top: 6px;
margin-top: 8px;
height: 32px;
}
.atAddressSect input {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
height: 100%;
height: 32px;
border-top-left-radius: 0 !important;
border-bottom-left-radius: 0 !important;
}
.ataddressinput {
padding: .25rem;
@ -141,7 +142,7 @@ var css = csjs`
.create {
}
.input {
font-size: 10px;
font-size: 10px !important;
}
.noInstancesText {
font-style: italic;
@ -209,10 +210,11 @@ var css = csjs`
width: 145px;
}
.orLabel {
margin-left: 44px;
text-align: center;
text-transform: uppercase;
}
.infoDeployAction {
margin-left: 5px;
margin-left: 1px;
font-size: 13px;
color: var(--info);
}
@ -221,18 +223,17 @@ var css = csjs`
display: flex;
}
.gasNval {
/* transform: scale(0.7); */
/* transform-origin: left; */
margin-right: 10px;
width: 100px;
width: 55%;
font-size: 0.8rem;
}
.gasNvalUnit {
/* transform: scale(0.7); */
/* transform-origin: left; */
margin-right: 10px;
width: 41%;
margin-left: 10px;
font-size: 0.8rem;
width: 70px;
}
.deployDropdown {
text-align: center;
text-transform: uppercase;
}
`

@ -49,8 +49,6 @@ const css = csjs`
margin-bottom: 3px;
}
input {
margin-right: 5px;
cursor: pointer;
width: inherit;
}
input[type=radio] {

@ -47,7 +47,7 @@ export class RunTab extends LibraryPlugin {
}
renderContainer () {
this.container = yo`<div class="${css.runTabView} py-0 px-2" id="runTabView" ></div>`
this.container = yo`<div class="${css.runTabView} run-tab" id="runTabView" ></div>`
var el = yo`
<div class="list-group list-group-flush">
@ -62,10 +62,10 @@ export class RunTab extends LibraryPlugin {
}
renderInstanceContainer () {
this.instanceContainer = yo`<div class="${css.instanceContainer}"></div>`
this.instanceContainer = yo`<div class="${css.instanceContainer} border-0 list-group-item"></div>`
const instanceContainerTitle = yo`
<div class=${css.instanceContainerTitle}
<div class="${css.instanceContainerTitle}"
title="Autogenerated generic user interfaces for interaction with deployed contracts">
Deployed Contracts
<i class="${css.clearinstance} ${css.icon} far fa-trash-alt" onclick=${() => this.event.trigger('clearInstance', [])}
@ -142,7 +142,7 @@ export class RunTab extends LibraryPlugin {
const expandedView = yo`
<div class=${css.recorderExpandedView}>
<div class=${css.recorderDescription}>
<div class="${css.recorderDescription} mt-2">
All transactions (deployed contracts and function executions) in this environment can be saved and replayed in
another environment. e.g Transactions created in Javascript VM can be replayed in the Injected Web3.
</div>

@ -24,7 +24,7 @@ module.exports = class Card {
self._view.statusBar = yo`<div class=${css.statusBar}>${self._opts.collapsedView}</div>`
self._view.cardHeader = yo`
<div class=${css.cardHeader} onclick=${() => trigger(self._view.arrow)}>
<div class="p-1 ${css.cardTitles}">
<div class="pr-1 ${css.cardTitles}">
<div class=${css.cardTitle}>${self._opts.title}</div>
${self._view.statusBar}
</div>
@ -43,7 +43,7 @@ module.exports = class Card {
// HTML
self._view.el = yo`
<div class="${css.cardContainer} p-2 list-group-item">
<div class="${css.cardContainer} list-group-item border-0">
${self._view.cardHeader}
${self._view.cardBody}
</div>`
@ -55,12 +55,14 @@ module.exports = class Card {
const css = csjs`
.cardContainer {
padding : 10px 15px 15px 0;
margin-bottom : 2%;
padding : 0 24px 16px;
margin : 0;
background : none;
}
.cardHeader {
display : flex;
justify-content : space-between;
align-items : center;
}
.statusBar {}
.cardBody {}
@ -70,9 +72,10 @@ const css = csjs`
align-items : center;
}
.cardTitle {
font-size : 13px;
font-weight : bold;
margin-right : 5px;
font-size : 14px;
font-weight : 400;
margin-right : 8px;
line-height : 19px;
}
.expandCollapseButton {}
.arrow {

@ -12,7 +12,7 @@ var css = csjs`
}
`
module.exports = function copyToClipboard (getContent, tip = 'Copy value to clipboard', icon = 'fa-clipboard') {
module.exports = function copyToClipboard (getContent, tip = 'Copy value to clipboard', icon = 'fa-copy') {
var copyIcon = yo`<i title="${tip}" class="${css.copyIcon} far ${icon}" aria-hidden="true"></i>`
copyIcon.onclick = (event) => {
event.stopPropagation()

@ -100,7 +100,7 @@ class MultiParamManager {
if (this.funABI.inputs) {
return yo`<div>
${this.funABI.inputs.map(function (inp) {
return yo`<div class="${css.multiArg}"><label for="${inp.name}"> ${inp.name}: </label><input placeholder="${inp.type}" title="${inp.name}"></div>`
return yo`<div class="${css.multiArg}"><label for="${inp.name}"> ${inp.name}: </label><input class="form-control" placeholder="${inp.type}" title="${inp.name}"></div>`
})}
</div>`
}
@ -116,10 +116,9 @@ class MultiParamManager {
title = this.funABI.type === 'receive' ? '(receive)' : '(fallback)'
}
this.basicInputField = yo`<input></input>`
this.basicInputField = yo`<input class="form-control"></input>`
this.basicInputField.setAttribute('placeholder', this.inputs)
this.basicInputField.setAttribute('title', this.inputs)
this.basicInputField.setAttribute('style', 'flex: 4')
var onClick = () => {
this.clickCallBack(this.funABI.inputs, this.basicInputField.value)
@ -148,12 +147,11 @@ class MultiParamManager {
this.contractActionsContainerMulti = yo`<div class="${css.contractActionsContainerMulti}" >
<div class="${css.contractActionsContainerMultiInner} text-dark" >
<div onclick=${() => { this.switchMethodViewOff() }} class="${css.multiHeader}">
<div class="${css.multiTitle}">${title}</div>
<div class="${css.multiTitle} run-instance-multi-title">${title}</div>
<i class='fas fa-angle-up ${css.methCaret}'></i>
</div>
${this.multiFields}
<div class="${css.group} ${css.multiArg}" >
${expandedButton}
${copyToClipboard(
() => {
var multiString = this.getMultiValsString()
@ -170,6 +168,7 @@ class MultiParamManager {
return encodeObj.data
}
}, 'Encode values of input fields & copy to clipboard', 'fa-clipboard')}
${expandedButton}
</div>
</div>
</div>`

@ -54,12 +54,12 @@ UniversalDAppUI.prototype.renderInstanceFromABI = function (contractABI, address
let self = this
address = (address.slice(0, 2) === '0x' ? '' : '0x') + address.toString('hex')
address = ethJSUtil.toChecksumAddress(address)
var instance = yo`<div class="instance ${css.instance} ${css.hidesub}" id="instance${address}"></div>`
var instance = yo`<div class="instance run-instance border-dark ${css.instance} ${css.hidesub}" id="instance${address}"></div>`
const context = this.blockchain.context()
var shortAddress = helper.shortenAddress(address)
var title = yo`
<div class="${css.title} alert alert-secondary p-2">
<div class="${css.title} alert alert-secondary">
<button class="btn ${css.titleExpander}" onclick="${(e) => { toggleClass(e) }}">
<i class="fas fa-angle-right" aria-hidden="true"></i>
</button>
@ -97,7 +97,7 @@ UniversalDAppUI.prototype.renderInstanceFromABI = function (contractABI, address
}
function toggleClass (e) {
$(instance).toggleClass(`${css.hidesub}`)
$(instance).toggleClass(`${css.hidesub} bg-light`)
// e.currentTarget.querySelector('i')
e.currentTarget.querySelector('i').classList.toggle(`fa-angle-right`)
e.currentTarget.querySelector('i').classList.toggle(`fa-angle-down`)
@ -120,7 +120,7 @@ UniversalDAppUI.prototype.renderInstanceFromABI = function (contractABI, address
})
const calldataInput = yo`
<input id="deployAndRunLLTxCalldata" class="w-100 m-0" title="The Calldata to send to fallback function of the contract.">
<input id="deployAndRunLLTxCalldata" class="w-100 m-0 form-control" title="The Calldata to send to fallback function of the contract.">
`
const llIError = yo`
<label id="deployAndRunLLTxError" class="text-danger"></label>

@ -9,33 +9,37 @@ var css = csjs`
display: flex;
justify-content: space-between;
font-size: 11px;
/* height: 30px; */
width: 100%;
overflow: hidden;
word-break: break-word;
line-height: initial;
overflow: visible;
margin-bottom: 0px;
padding-left: 0px;
padding-right: 10px;
padding: 0 0 8px;
margin: 0;
background: none;
border: none;
}
.noInstancesText {
.title button {
background: none;
border: none;
}
.titleLine {
display: flex;
align-items: baseline;
}
.titleText {
/* margin-right: 1em; */
word-break: break-word;
min-width: 170px;
width: 100%;
border: none;
}
.spanTitleText {
/* font-size: .8rem; */
line-height: 12px;
padding: 0;
font-size: 11px;
width:100%;
border: none;
background: none;
text-transform: uppercase;
}
.inputGroupText {
width: 100%;
@ -44,7 +48,6 @@ var css = csjs`
color: var(--primary);
}
.titleExpander {
/* margin-right: 10px; */
padding: 5px 7px;
}
.nameNbuts {
@ -54,10 +57,13 @@ var css = csjs`
}
.instance {
display: block;
/* display: flex; */
flex-direction: column;
/* padding: 5px 0 0 10px; */
margin-bottom: 10px;
margin-bottom: 12px;
background: none;
border-radius: 2px;
}
.instance.hidesub {
border-bottom: 1px solid;
}
.instance.hidesub .title {
display: flex;
@ -69,19 +75,21 @@ var css = csjs`
display: none;
}
.methCaret {
margin-right: 5px;
min-width: 12px;
width: 12px;
margin-left: 4px;
cursor: pointer;
font-size: 16px;
padding-top: 5px;
vertical-align: top;
line-height: 0.6;
vertical-align: middle;
padding: 0;
}
.cActionsWrapper {
padding: 0px 0 10px 10px;
border: 1px solid rgba(0,0,0,0.125);
border-top-left-radius: 0;
border-bottom-left-radius: 0.25rem;
border-top-rightt-radius: 0;
border-bottom-right-radius: 0.25rem;
padding: 8px 10px 7px;
}
.group:after {
content: "";
@ -93,12 +101,11 @@ var css = csjs`
display: flex;
overflow: hidden;
}
.contractActions {
}
.instanceButton {
height: 32px;
border-radius: 3px;
flex: 3;
white-space: nowrap;
font-size: 11px;
overflow: hidden;
text-overflow: ellipsis;
}
@ -107,14 +114,11 @@ var css = csjs`
cursor: pointer;
margin-left: 5px;
}
.udapp {}
.udappClose {
display: flex;
justify-content: flex-end;
}
.contractProperty {
margin-bottom: 0.4em;
margin-top: 1em;
width:100%;
}
.contractProperty.hasArgs input {
@ -126,10 +130,8 @@ var css = csjs`
border-bottom-left-radius: 0;
}
.contractProperty button {
/* background-color: var(--warning); */
min-width: 100px;
width: 100px;
/* font-size: 10px; */
margin:0;
word-break: inherit;
}
@ -139,7 +141,6 @@ var css = csjs`
border-color: lightgray;
}
.contractProperty.constant button {
/* background-color:var(--info); */
min-width: 100px;
width: 100px;
margin:0;
@ -149,57 +150,53 @@ var css = csjs`
overflow: hidden;
text-overflow: ellipsis;
}
.contractProperty input {
/* width: 75% */
}
.contractProperty > .value {
box-sizing: border-box;
float: left;
align-self: center;
margin-left: 4px;
}
.value ul {
margin-bottom: 10px;
padding-top: 5px;
border-bottom: 4px solid var(--light);
}
.contractActionsContainer {
width: 98%;
width: 100%;
margin-bottom: 8px;
}
.contractActionsContainerSingle {
display: flex;
width: 100%;
margin-bottom: 8px;
}
.contractActionsContainerSingle i {
line-height: 2;
}
.contractActionsContainerMulti {
display:none;
width: 100%;
}
.contractActionsContainerMultiInner {
margin-bottom: 10px;
padding: 0px 5px 5px 5px;
background-color: var(--light);
width: 99%;
width: 100%;
padding: 16px 8px 16px 14px;
border-radius: 3px;
margin-bottom: 8px;
}
.multiHeader {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
text-align: left;
font-size: 10px;
margin-bottom: 5px;
font-weight: bold;
}
.contractActionsContainerMultiInner .multiTitle {
padding-left: 10px;
}
.contractProperty .multiTitle {
padding: 0;
line-height: 16px;
display: inline-block;
width: 90%;
font-size: 12px;
height: 25px;
padding-left: 20px;
font-weight: bold;
line-height: 25px;
cursor: default;
padding-top: 5px;
}
.contractProperty .contractActionsContainerMultiInner .multiArg label{
text-align: right;
@ -219,26 +216,26 @@ var css = csjs`
cursor: default;
}
.multiArg {
margin-bottom: 8px;
/* display: flex; */
clear:both;
display: flex;
align-items: center;
justify-content: flex-end;
margin-top: 4px;
}
.multiArg input{
padding: 5px;
}
.multiArg label {
float: left;
margin-right: 6px;
width: auto;
padding: 0;
margin: 0 4px 0 0;
font-size: 10px;
width: 30%;
padding-top: 5px;
word-break: break-all;
line-height: 12px;
text-align: right;
word-break: initial;
}
.multiArg button {
max-width: 100px;
border-radius: 3px;
float: right;
margin-right: 2%;
border-width: 1px;
width: inherit;
}
@ -252,12 +249,12 @@ var css = csjs`
}
.hasArgs input {
display: block;
height: 32px;
border: 1px solid #dddddd;
padding: .36em;
border-left: none;
padding: 8px 8px 8px 10px;
font-size: 10px;
/* height: 25px; */
font-size: 10px !important;
}
.hasArgs button {
border-top-right-radius: 0;
@ -266,14 +263,13 @@ var css = csjs`
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 11px;
}
.hasArgs .contractActionsContainerMulti button {
border-radius: 3px;
}
.contractActionsContainerMultiInner .multiArg i {
padding-right: 15px;
padding-top: 5px;
float: right;
padding-right: 10px;
},
.hideWarningsContainer {
display: flex;

Loading…
Cancel
Save