feat_fix_n_refactor: exptracted checkbox as a reusable component and fix selec all and auto run,

pull/5370/head
tizah 4 years ago
parent 667de72915
commit 491cd9d0c0
  1. 4
      libs/remix-ui/checkbox/.babelrc
  2. 19
      libs/remix-ui/checkbox/.eslintrc
  3. 7
      libs/remix-ui/checkbox/README.md
  4. 1
      libs/remix-ui/checkbox/src/index.ts
  5. 0
      libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.css
  6. 47
      libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.tsx
  7. 16
      libs/remix-ui/checkbox/tsconfig.json
  8. 13
      libs/remix-ui/checkbox/tsconfig.lib.json
  9. 4
      libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx
  10. 8
      libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx
  11. 31
      libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx
  12. 54
      libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx
  13. 3
      nx.json
  14. 2
      package.json
  15. 3
      tsconfig.json
  16. 16
      workspace.json

@ -0,0 +1,4 @@
{
"presets": ["@nrwl/react/babel"],
"plugins": []
}

@ -0,0 +1,19 @@
{
"env": {
"browser": true,
"es6": true
},
"extends": "../../../.eslintrc",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 11,
"sourceType": "module"
},
"rules": {
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": "error"
}
}

@ -0,0 +1,7 @@
# remix-ui-checkbox
This library was generated with [Nx](https://nx.dev).
## Running unit tests
Run `nx test remix-ui-checkbox` to execute the unit tests via [Jest](https://jestjs.io).

@ -0,0 +1 @@
export * from './lib/remix-ui-checkbox'

@ -0,0 +1,47 @@
import React from 'react' //eslint-disable-line
import './remix-ui-checkbox.css'
/* eslint-disable-next-line */
export interface RemixUiCheckboxProps {
onClick?: (event) => void
onChange?: (event) => void
label?: string
inputType?: string
name?: string
checked?: boolean
id?: string
itemName?: string
categoryId?: string
}
export const RemixUiCheckbox = ({
id,
label,
onClick,
inputType,
name,
checked,
onChange,
itemName,
categoryId
}: RemixUiCheckboxProps) => {
return (
<div className="listenOnNetwork_2A0YE0 custom-control custom-checkbox" style={{ display: 'flex', alignItems: 'center' }} onClick={onClick}>
<input
id={id}
type={inputType}
onChange={onChange}
style={{ verticalAlign: 'bottom' }}
name={name}
className="custom-control-input"
checked={checked}
/>
<label className="form-check-label custom-control-label" id={`heading${categoryId}`} style={{ paddingTop: '0.15rem' }}>
{name ? <div className="font-weight-bold">{itemName}</div> : ''}
{label}
</label>
</div>
)
}
export default RemixUiCheckbox

@ -0,0 +1,16 @@
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"jsx": "react",
"allowJs": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
}
]
}

@ -0,0 +1,13 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../dist/out-tsc",
"types": ["node"]
},
"files": [
"../../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../../node_modules/@nrwl/react/typings/image.d.ts"
],
"exclude": ["**/*.spec.ts", "**/*.spec.tsx"],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}

@ -12,11 +12,9 @@ const StaticAnalyserButton = ({
disabled disabled
}: StaticAnalyserButtonProps) => { }: StaticAnalyserButtonProps) => {
return ( return (
<div className="remixui-button-container" id='staticanalysisButton'> <button className="btn btn-sm w-25 btn-primary" onClick={onClick} disabled={disabled}>
<button className="btn btn-sm w-31 btn-primary" onClick={onClick} disabled={disabled}>
{buttonText} {buttonText}
</button> </button>
</div>
) )
} }

@ -24,7 +24,7 @@ const StaticAnalyserCheckedBox = ({
categoryId categoryId
}: StaticAnalyserCheckBoxProps) => { }: StaticAnalyserCheckBoxProps) => {
return ( return (
<div className="pt-1 h-80 mx-3 align-items-center listenOnNetwork_2A0YE0 custom-control custom-checkbox " onClick={onClick}> <div className="listenOnNetwork_2A0YE0 custom-control custom-checkbox" style={{ display: 'flex', alignItems: 'center' }} onClick={onClick}>
<input <input
id={id} id={id}
type={inputType} type={inputType}
@ -34,9 +34,9 @@ const StaticAnalyserCheckedBox = ({
className="custom-control-input" className="custom-control-input"
checked={checked} checked={checked}
/> />
<label className="pt-1 form-check-label custom-control-label" id={`heading${categoryId}`} > <label className="form-check-label custom-control-label" id={`heading${categoryId}`} style={{ paddingTop: '0.15rem' }}>
{name ? <h6>{itemName}</h6> : ''} {name ? <div className="font-weight-bold">{itemName}</div> : ''}
<p>{label}</p> {label}
</label> </label>
</div> </div>
) )

@ -4,20 +4,12 @@ interface ErrorRendererProps {
message: any; message: any;
opt: any, opt: any,
warningErrors: any warningErrors: any
editor: any
} }
const ErrorRenderer = ({ message, opt }: ErrorRendererProps) => { const ErrorRenderer = ({ message, opt, editor }: ErrorRendererProps) => {
const [, setError] = useState(
{
row: null,
column: null,
text: null,
type: null,
errFile: null
}
)
const getPositionDetails = (msg: any) => { const getPositionDetails = (msg: any) => {
const result = { } as any const result = { } as Record<string, number | string>
// To handle some compiler warning without location like SPDX license warning etc // To handle some compiler warning without location like SPDX license warning etc
if (!msg.includes(':')) return { errLine: -1, errCol: -1, errFile: msg } if (!msg.includes(':')) return { errLine: -1, errCol: -1, errFile: msg }
@ -32,6 +24,12 @@ const ErrorRenderer = ({ message, opt }: ErrorRendererProps) => {
result.errFile = position ? position[1] : '' result.errFile = position ? position[1] : ''
return result return result
} }
const handlePointToErrorOnClick = () => {
const result = opt.locationString.split(':')
editor._components.registry.get('editor').api.gotoLine(parseInt(result[0]) - 1, parseInt(result[1]))
}
if (!message) return if (!message) return
let position = getPositionDetails(message) let position = getPositionDetails(message)
if (!position.errFile || (opt.errorType && opt.errorType === position.errFile)) { if (!position.errFile || (opt.errorType && opt.errorType === position.errFile)) {
@ -43,15 +41,6 @@ const ErrorRenderer = ({ message, opt }: ErrorRendererProps) => {
opt.errLine = position.errLine opt.errLine = position.errLine
opt.errCol = position.errCol opt.errCol = position.errCol
opt.errFile = position.errFile.trim() opt.errFile = position.errFile.trim()
if (!opt.noAnnotations && opt.errFile) {
setError({
errFile: opt.errFile,
row: opt.errLine,
column: opt.errCol,
text: message,
type: opt.type
})
}
const classList = opt.type === 'error' ? 'alert alert-danger' : 'alert alert-warning' const classList = opt.type === 'error' ? 'alert alert-danger' : 'alert alert-warning'
return ( return (
<div> <div>
@ -59,7 +48,7 @@ const ErrorRenderer = ({ message, opt }: ErrorRendererProps) => {
<div className="close" data-id="renderer"> <div className="close" data-id="renderer">
<i className="fas fa-times"></i> <i className="fas fa-times"></i>
</div> </div>
<span className='d-flex flex-column'> <span className='d-flex flex-column' onClick={handlePointToErrorOnClick}>
<span className='h6 font-weight-bold'>{opt.name}</span> <span className='h6 font-weight-bold'>{opt.name}</span>
{ opt.item.warning } { opt.item.warning }
{opt.item.more {opt.item.more

@ -5,6 +5,7 @@ import Button from './Button/StaticAnalyserButton' // eslint-disable-line
import remixLib from '@remix-project/remix-lib' import remixLib from '@remix-project/remix-lib'
import _ from 'lodash' import _ from 'lodash'
import { TreeView, TreeViewItem } from '@remix-ui/tree-view' // eslint-disable-line import { TreeView, TreeViewItem } from '@remix-ui/tree-view' // eslint-disable-line
import { RemixUiCheckbox } from '@remix-ui/checkbox' // eslint-disable-line
import ErrorRenderer from './ErrorRenderer' // eslint-disable-line import ErrorRenderer from './ErrorRenderer' // eslint-disable-line
const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis
const utils = remixLib.util const utils = remixLib.util
@ -60,12 +61,12 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
} }
return indexOfCategory return indexOfCategory
} }
const [autoRun, setAutoRun] = useState(true)
const [categoryIndex, setCategoryIndex] = useState(groupedModuleIndex(groupedModules)) const [categoryIndex, setCategoryIndex] = useState(groupedModuleIndex(groupedModules))
const warningContainer = React.useRef(null) const warningContainer = React.useRef(null)
const [runButtonState, setRunButtonState] = useState(true) const [runButtonState, setRunButtonState] = useState(true)
const [autoRun, setAutoRun] = useState(false)
const [result, setResult] = useState({ const [result, setResult] = useState({
lastCompilationResult: null, lastCompilationResult: null,
lastCompilationSource: null, lastCompilationSource: null,
@ -81,41 +82,33 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
const [warningState, setWarningState] = useState([]) const [warningState, setWarningState] = useState([])
useEffect(() => { useEffect(() => {
if (autoRun) { if (autoRun) {
const setCompilationResult = async (data, source, file) => { const setCompilationResult = async (data, source, file) => {
await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file })
} }
if (props.analysisModule) { if (props.analysisModule) {
props.analysisModule.on( props.analysisModule.on(
'solidity', 'solidity',
'compilationFinished', 'compilationFinished',
(file, source, languageVersion, data) => { (file, source, languageVersion, data) => {
if (languageVersion.indexOf('soljson') !== 0) return if (languageVersion.indexOf('soljson') !== 0) return
setCompilationResult(data, source, file) setCompilationResult(data, source, file)
if(categoryIndex.length > 0){ if (categoryIndex.length > 0) {
run(data, source, file) run(data, source, file)
} }
} }
) )
} }
} else {
setAutoRun(true)
} }
return () => { } return () => { }
}, [autoRun, categoryIndex]) }, [autoRun, categoryIndex])
const run = (lastCompilationResult, lastCompilationSource, currentFile) => { const run = (lastCompilationResult, lastCompilationSource, currentFile) => {
// const highlightLocation = async (location, fileName) => { if (autoRun) {
// await props.analysisModule.call('editor', 'discardHighlight')
// await props.analysisModule.call('editor', 'highlight', location, fileName)
// }
setResult({ lastCompilationResult, lastCompilationSource, currentFile }) setResult({ lastCompilationResult, lastCompilationSource, currentFile })
if (lastCompilationResult && categoryIndex.length) { if (lastCompilationResult && categoryIndex.length > 0) {
setRunButtonState(false) setRunButtonState(false)
let warningCount = 0 let warningCount = 0
const warningMessage = [] const warningMessage = []
@ -139,8 +132,8 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
let row = 0 let row = 0
let fileName = currentFile let fileName = currentFile
if (item.location) { if (item.location) {
var split = item.location.split(':') const split = item.location.split(':')
var file = split[2] const file = split[2]
location = { location = {
start: parseInt(split[0]), start: parseInt(split[0]),
length: parseInt(split[1]) length: parseInt(split[1])
@ -202,7 +195,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
const groupedCategory = groupBy(resultArray, 'warningModuleName') const groupedCategory = groupBy(resultArray, 'warningModuleName')
setWarningState(groupedCategory) setWarningState(groupedCategory)
}) })
if(categoryIndex.length > 0){ if (categoryIndex.length > 0) {
props.event.trigger('staticAnaysisWarning', [warningCount]) props.event.trigger('staticAnaysisWarning', [warningCount])
} }
} else { } else {
@ -213,6 +206,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
props.event.trigger('staticAnaysisWarning', [-1]) props.event.trigger('staticAnaysisWarning', [-1])
} }
} }
}
const handleCheckAllModules = (groupedModules) => { const handleCheckAllModules = (groupedModules) => {
const index = groupedModuleIndex(groupedModules) const index = groupedModuleIndex(groupedModules)
@ -223,9 +217,8 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
}) })
) )
} else { } else {
setCategoryIndex(_.uniq([...categoryIndex])) setCategoryIndex(_.uniq([...categoryIndex, ...index]))
} }
} }
const handleCheckOrUncheckCategory = (category) => { const handleCheckOrUncheckCategory = (category) => {
@ -261,7 +254,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
const categoryItem = (categoryId, item, i) => { const categoryItem = (categoryId, item, i) => {
return ( return (
<div className="form-check" key={i}> <div className="form-check" key={i}>
<CheckBox <RemixUiCheckbox
categoryId={categoryId} categoryId={categoryId}
id={`staticanalysismodule_${categoryId}_${i}`} id={`staticanalysismodule_${categoryId}_${i}`}
inputType="checkbox" inputType="checkbox"
@ -285,7 +278,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
<label <label
htmlFor={`heading${categoryId}`} htmlFor={`heading${categoryId}`}
style={{ cursor: 'pointer' }} style={{ cursor: 'pointer' }}
className="pl-3 card-header h6 d-flex justify-content-between font-weight-bold border-left px-1 py-2 w-100" className="pl-3 card-header h6 d-flex justify-content-between font-weight-bold px-1 py-2 w-100"
data-bs-toggle="collapse" data-bs-toggle="collapse"
data-bs-expanded="false" data-bs-expanded="false"
data-bs-controls={`heading${categoryId}`} data-bs-controls={`heading${categoryId}`}
@ -294,10 +287,10 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
{category[0].categoryDisplayName} {category[0].categoryDisplayName}
</label> </label>
} }
expand={true} expand={false}
> >
<div> <div>
<CheckBox onClick={() => handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} /> <RemixUiCheckbox onClick={() => handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} />
</div> </div>
<div className="w-100 d-block px-2 my-1 entries collapse multi-collapse" id={`heading${categoryId}`}> <div className="w-100 d-block px-2 my-1 entries collapse multi-collapse" id={`heading${categoryId}`}>
{category.map((item, i) => { {category.map((item, i) => {
@ -314,11 +307,10 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
} }
return ( return (
<div style={{ marginLeft: '10px', marginRight: '10px' }}> <div className="analysis_3ECCBV px-3 pb-1">
<div className="my-2 d-flex flex-column align-items-left"> <div className="my-2 d-flex flex-column align-items-left">
<div className="d-flex justify-content-between"> <div className="d-flex justify-content-between">
<div > <RemixUiCheckbox
<CheckBox
id="checkAllEntries" id="checkAllEntries"
inputType="checkbox" inputType="checkbox"
checked={Object.values(groupedModules).map((value: any) => { checked={Object.values(groupedModules).map((value: any) => {
@ -329,16 +321,13 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
label="Select all" label="Select all"
onClick={() => handleCheckAllModules(groupedModules)} onClick={() => handleCheckAllModules(groupedModules)}
/> />
</div> <RemixUiCheckbox
<div className="" >
<CheckBox
id="autorunstaticanalysis" id="autorunstaticanalysis"
inputType="checkbox" inputType="checkbox"
onClick={handleAutoRun} onClick={handleAutoRun}
checked={autoRun} checked={autoRun}
label="Autorun" label="Autorun"
/> />
</div>
<Button buttonText="Run" onClick={() => run(result.lastCompilationResult, result.lastCompilationSource, result.currentFile)} disabled={runButtonState || categoryIndex.length === 0}/> <Button buttonText="Run" onClick={() => run(result.lastCompilationResult, result.lastCompilationSource, result.currentFile)} disabled={runButtonState || categoryIndex.length === 0}/>
</div> </div>
</div> </div>
@ -368,7 +357,12 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
<> <>
<span className="text-dark h6">{element[0]}</span> <span className="text-dark h6">{element[0]}</span>
{element[1].map(x => ( {element[1].map(x => (
x.hasWarning ? (<ErrorRenderer message={x.msg} opt={x.options} warningErrors={ x.warningErrors}/>) : null x.hasWarning ? (
<div id={`staticAnalysisModule${element[1].warningModuleName}`}>
<ErrorRenderer message={x.msg} opt={x.options} warningErrors={ x.warningErrors} editor={props.analysisModule}/>
</div>
) : null
))} ))}
</> </>
))) )))

@ -98,6 +98,9 @@
}, },
"remix-ui-static-analyser": { "remix-ui-static-analyser": {
"tags": [] "tags": []
},
"remix-ui-checkbox": {
"tags": []
} }
} }
} }

@ -41,7 +41,7 @@
"workspace-schematic": "nx workspace-schematic", "workspace-schematic": "nx workspace-schematic",
"dep-graph": "nx dep-graph", "dep-graph": "nx dep-graph",
"help": "nx help", "help": "nx help",
"lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui,remix-ui-workspace", "lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox",
"build:libs": "nx run-many --target=build --parallel=false --with-deps=true --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd", "build:libs": "nx run-many --target=build --parallel=false --with-deps=true --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd",
"test:libs": "nx run-many --target=test --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd", "test:libs": "nx run-many --target=test --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd",
"publish:libs": "npm run build:libs & lerna publish --skip-git & npm run bumpVersion:libs", "publish:libs": "npm run build:libs & lerna publish --skip-git & npm run bumpVersion:libs",

@ -39,7 +39,8 @@
"@remix-ui/toaster": ["libs/remix-ui/toaster/src/index.ts"], "@remix-ui/toaster": ["libs/remix-ui/toaster/src/index.ts"],
"@remix-ui/file-explorer": ["libs/remix-ui/file-explorer/src/index.ts"], "@remix-ui/file-explorer": ["libs/remix-ui/file-explorer/src/index.ts"],
"@remix-ui/workspace": ["libs/remix-ui/workspace/src/index.ts"], "@remix-ui/workspace": ["libs/remix-ui/workspace/src/index.ts"],
"@remix-ui/static-analyser": ["libs/remix-ui/static-analyser/src/index.ts"] "@remix-ui/static-analyser": ["libs/remix-ui/static-analyser/src/index.ts"],
"@remix-ui/checkbox": ["libs/remix-ui/checkbox/src/index.ts"]
} }
}, },
"exclude": ["node_modules", "tmp"] "exclude": ["node_modules", "tmp"]

@ -744,6 +744,22 @@
} }
} }
} }
},
"remix-ui-checkbox": {
"root": "libs/remix-ui/checkbox",
"sourceRoot": "libs/remix-ui/checkbox/src",
"projectType": "library",
"schematics": {},
"architect": {
"lint": {
"builder": "@nrwl/linter:lint",
"options": {
"linter": "eslint",
"tsConfig": ["libs/remix-ui/checkbox/tsconfig.lib.json"],
"exclude": ["**/node_modules/**", "!libs/remix-ui/checkbox/**/*"]
}
}
}
} }
}, },
"cli": { "cli": {

Loading…
Cancel
Save