├── .dockerignore ├── .github └── ISSUE_TEMPLATE │ └── bug_report.md ├── .gitignore ├── LICENSE ├── README.md ├── app ├── .babelrc ├── .keep ├── package-lock.json ├── package.json ├── src │ ├── common │ │ ├── creds │ │ │ └── Creds.jsx │ │ ├── editable │ │ │ └── EditableElement.jsx │ │ ├── files_stats │ │ │ └── FilesStats.jsx │ │ ├── loading │ │ │ └── Loading.jsx │ │ ├── notifications │ │ │ └── Notifications.jsx │ │ ├── paginate │ │ │ ├── Page.jsx │ │ │ └── ReactPaginate.jsx │ │ ├── scope_comment │ │ │ ├── ScopeComment.jsx │ │ │ └── ScopeCommentPresentational.jsx │ │ ├── search │ │ │ └── Search.jsx │ │ ├── tasks │ │ │ ├── Tasks.jsx │ │ │ └── TasksGroup.jsx │ │ ├── tasks_buttons │ │ │ ├── components │ │ │ │ ├── ButtonTasks.jsx │ │ │ │ ├── CustomOptions.jsx │ │ │ │ ├── DictUploader.jsx │ │ │ │ ├── Dictionaries.jsx │ │ │ │ ├── DictionariesManager.jsx │ │ │ │ ├── DictionaryStats.jsx │ │ │ │ ├── DropButtonContent.jsx │ │ │ │ └── InnerModal.jsx │ │ │ └── presentational │ │ │ │ └── AdaptiveOption.jsx │ │ └── tasks_scoped │ │ │ └── TasksScoped.jsx │ ├── dirsearch_tables │ │ ├── components │ │ │ ├── DirsearchTable.jsx │ │ │ ├── Footer.jsx │ │ │ ├── MainAccumulatorFilters.jsx │ │ │ ├── MainAccumulatorUpdater.jsx │ │ │ ├── MainAccumulatorWrapper.jsx │ │ │ └── TablesAccumulator.jsx │ │ └── presentational │ │ │ └── FileStatsOverview.jsx │ ├── host_verbose │ │ ├── components │ │ │ ├── HostVerbose.jsx │ │ │ ├── HostVerboseUpdater.jsx │ │ │ ├── HostVerboseWrapper.jsx │ │ │ └── TasksButtonsTracked.jsx │ │ └── presentational │ │ │ └── PortsTabs.jsx │ ├── hosts_list │ │ ├── components │ │ │ ├── HostsList.jsx │ │ │ ├── HostsListFilters.jsx │ │ │ ├── HostsListScopesUpdater.jsx │ │ │ ├── HostsListWrapper.js │ │ │ ├── HostsTable.jsx │ │ │ ├── HostsTableTracked.jsx │ │ │ └── TasksButtonsTracked.jsx │ │ └── presentational │ │ │ └── HostsEntryLine.jsx │ ├── index.html │ ├── index.jsx │ ├── ip_verbose │ │ └── components │ │ │ ├── IPVerbose.jsx │ │ │ ├── IPVerboseUpdater.jsx │ │ │ └── MainAccumulatorWrapper.jsx │ ├── ips_list │ │ ├── components │ │ │ ├── IPTable.jsx │ │ │ ├── IPTableTracked.jsx │ │ │ ├── IPsList.jsx │ │ │ ├── IPsListFilters.jsx │ │ │ ├── IPsListScopesUpdater.jsx │ │ │ ├── IPsListWrapper.js │ │ │ ├── OtherIPsButton.jsx │ │ │ └── TitleButtonsWithHandlers.jsx │ │ └── presentational │ │ │ └── scope │ │ │ ├── HidingButtons.jsx │ │ │ └── IPEntryLine.jsx │ ├── navigation │ │ ├── DirsearchWrapper.jsx │ │ ├── Host.jsx │ │ ├── IP.jsx │ │ ├── NavigationTabs.jsx │ │ ├── NavigationTabsWrapper.jsx │ │ ├── Projects.jsx │ │ └── Routing.jsx │ ├── projects_list │ │ ├── components │ │ │ ├── ProjectsMainComponent.jsx │ │ │ └── ProjectsMainComponentWrapper.js │ │ └── presentational │ │ │ ├── ProjectsList.jsx │ │ │ ├── ProjectsListLine.jsx │ │ │ └── ProjectsMain.jsx │ ├── redux │ │ ├── SocketConnector.jsx │ │ ├── creds │ │ │ ├── actions.js │ │ │ └── reducers.js │ │ ├── dicts │ │ │ ├── actions.js │ │ │ └── reducers.js │ │ ├── files │ │ │ ├── actions.js │ │ │ └── reducers.js │ │ ├── hosts │ │ │ ├── HostsSocketioEventsEmitter.js │ │ │ ├── HostsSocketioEventsSubscriber.js │ │ │ ├── actions.js │ │ │ └── reducers.js │ │ ├── ips │ │ │ ├── IPsSocketioEventsSubscriber.js │ │ │ ├── actions.js │ │ │ └── reducers.js │ │ ├── notifications │ │ │ ├── NotificationsSocketioEventsSubscriber.js │ │ │ ├── actions.js │ │ │ └── reducers.js │ │ ├── project_uuid │ │ │ ├── actions.js │ │ │ └── reducers.js │ │ ├── projects │ │ │ ├── ProjectsSocketioEventsSubscriber.js │ │ │ ├── actions.js │ │ │ └── reducers.js │ │ ├── reducers.js │ │ ├── scans │ │ │ ├── actions.js │ │ │ └── reducers.js │ │ ├── scopes │ │ │ ├── ScopesSocketioEventsEmitter.js │ │ │ ├── actions.js │ │ │ └── reducers.js │ │ └── tasks │ │ │ ├── TasksSocketioEventsSubsriber.js │ │ │ ├── actions.js │ │ │ └── reducers.js │ ├── scope_setup │ │ ├── components │ │ │ ├── HeadButtonsTracked.jsx │ │ │ ├── ScopeSetup.jsx │ │ │ ├── ScopeSetupUpdater.jsx │ │ │ ├── ScopeSetupWrapper.js │ │ │ ├── TaskButton.jsx │ │ │ ├── project_comment │ │ │ │ ├── ProjectComment.jsx │ │ │ │ └── ProjectCommentPresentational.jsx │ │ │ └── scope_adder │ │ │ │ ├── components │ │ │ │ ├── ScopeAdderTracked.jsx │ │ │ │ └── ScopeUpload.jsx │ │ │ │ └── presentational │ │ │ │ └── ScopeAdder.jsx │ │ └── presentational │ │ │ ├── ResolveButton.jsx │ │ │ ├── ScopesLock.jsx │ │ │ ├── Statistic.jsx │ │ │ └── Stats.jsx │ ├── styles │ │ ├── notification_styles.css │ │ └── table_fix.css │ └── tasks_tab │ │ ├── components │ │ ├── ActiveTasks.jsx │ │ ├── TasksTab.jsx │ │ └── TasksTabWrapper.js │ │ └── presentational │ │ ├── ActiveTaskEntry.jsx │ │ ├── FinishedTaskEntry.jsx │ │ └── FinishedTasks.jsx └── webpack.config.js ├── black ├── __init__.py ├── db │ ├── __init__.py │ ├── models │ │ ├── __init__.py │ │ ├── base.py │ │ ├── cred.py │ │ ├── dictionary.py │ │ ├── file.py │ │ ├── host.py │ │ ├── ip.py │ │ ├── project.py │ │ ├── scan.py │ │ └── task.py │ └── sessions.py └── workers │ ├── __init__.py │ ├── amass │ ├── __init__.py │ ├── amass_task.py │ ├── amass_worker.py │ └── db_save.py │ ├── common │ ├── __init__.py │ ├── async_task.py │ ├── async_worker.py │ ├── task.py │ └── worker.py │ ├── dirsearch │ ├── __init__.py │ ├── db_save.py │ ├── dirsearch_ext │ │ ├── README.md │ │ ├── db │ │ │ ├── 400_blacklist.txt │ │ │ ├── 403_blacklist.txt │ │ │ ├── 500_blacklist.txt │ │ │ ├── dicc.txt │ │ │ └── user-agents.txt │ │ ├── default.conf │ │ ├── dirsearch.py │ │ ├── lib │ │ │ ├── __init__.py │ │ │ ├── connection │ │ │ │ ├── RequestException.py │ │ │ │ ├── Requester.py │ │ │ │ ├── Response.py │ │ │ │ └── __init__.py │ │ │ ├── controller │ │ │ │ ├── Controller.py │ │ │ │ ├── __init__.py │ │ │ │ └── banner.txt │ │ │ ├── core │ │ │ │ ├── ArgumentParser.py │ │ │ │ ├── Dictionary.py │ │ │ │ ├── Fuzzer.py │ │ │ │ ├── Path.py │ │ │ │ ├── ReportManager.py │ │ │ │ ├── Saver.py │ │ │ │ ├── Scanner.py │ │ │ │ └── __init__.py │ │ │ ├── output │ │ │ │ ├── CLIOutput.py │ │ │ │ └── __init__.py │ │ │ ├── reports │ │ │ │ ├── BaseReport.py │ │ │ │ ├── JSONReport.py │ │ │ │ └── __init__.py │ │ │ └── utils │ │ │ │ ├── DefaultConfigParser.py │ │ │ │ ├── FileUtils.py │ │ │ │ ├── RandomUtils.py │ │ │ │ ├── TerminalSize.py │ │ │ │ └── __init__.py │ │ ├── logs │ │ │ └── DO_NOT_DELETE_THIS_FOLDER.txt │ │ ├── output │ │ ├── reports │ │ │ ├── DO_NOT_DELETE_THIS_FOLDER.txt │ │ │ └── anatoly.tech │ │ │ │ ├── 17-04-14_14-49-57 │ │ │ │ └── 17-04-14_14-50-11 │ │ └── thirdparty │ │ │ ├── __init__.py │ │ │ ├── oset │ │ │ ├── __init__.py │ │ │ ├── _abc.py │ │ │ ├── pyoset.py │ │ │ └── tests.py │ │ │ ├── requests │ │ │ ├── __init__.py │ │ │ ├── adapters.py │ │ │ ├── api.py │ │ │ ├── auth.py │ │ │ ├── cacert.pem │ │ │ ├── certs.py │ │ │ ├── compat.py │ │ │ ├── cookies.py │ │ │ ├── exceptions.py │ │ │ ├── hooks.py │ │ │ ├── models.py │ │ │ ├── packages │ │ │ │ ├── README.rst │ │ │ │ ├── __init__.py │ │ │ │ ├── chardet │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── big5freq.py │ │ │ │ │ ├── big5prober.py │ │ │ │ │ ├── chardetect.py │ │ │ │ │ ├── chardistribution.py │ │ │ │ │ ├── charsetgroupprober.py │ │ │ │ │ ├── charsetprober.py │ │ │ │ │ ├── codingstatemachine.py │ │ │ │ │ ├── compat.py │ │ │ │ │ ├── constants.py │ │ │ │ │ ├── cp949prober.py │ │ │ │ │ ├── escprober.py │ │ │ │ │ ├── escsm.py │ │ │ │ │ ├── eucjpprober.py │ │ │ │ │ ├── euckrfreq.py │ │ │ │ │ ├── euckrprober.py │ │ │ │ │ ├── euctwfreq.py │ │ │ │ │ ├── euctwprober.py │ │ │ │ │ ├── gb2312freq.py │ │ │ │ │ ├── gb2312prober.py │ │ │ │ │ ├── hebrewprober.py │ │ │ │ │ ├── jisfreq.py │ │ │ │ │ ├── jpcntx.py │ │ │ │ │ ├── langbulgarianmodel.py │ │ │ │ │ ├── langcyrillicmodel.py │ │ │ │ │ ├── langgreekmodel.py │ │ │ │ │ ├── langhebrewmodel.py │ │ │ │ │ ├── langhungarianmodel.py │ │ │ │ │ ├── langthaimodel.py │ │ │ │ │ ├── latin1prober.py │ │ │ │ │ ├── mbcharsetprober.py │ │ │ │ │ ├── mbcsgroupprober.py │ │ │ │ │ ├── mbcssm.py │ │ │ │ │ ├── sbcharsetprober.py │ │ │ │ │ ├── sbcsgroupprober.py │ │ │ │ │ ├── sjisprober.py │ │ │ │ │ ├── universaldetector.py │ │ │ │ │ └── utf8prober.py │ │ │ │ └── urllib3 │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── _collections.py │ │ │ │ │ ├── connection.py │ │ │ │ │ ├── connectionpool.py │ │ │ │ │ ├── contrib │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── ntlmpool.py │ │ │ │ │ └── pyopenssl.py │ │ │ │ │ ├── exceptions.py │ │ │ │ │ ├── fields.py │ │ │ │ │ ├── filepost.py │ │ │ │ │ ├── packages │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── ordered_dict.py │ │ │ │ │ ├── six.py │ │ │ │ │ └── ssl_match_hostname │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ └── _implementation.py │ │ │ │ │ ├── poolmanager.py │ │ │ │ │ ├── request.py │ │ │ │ │ ├── response.py │ │ │ │ │ └── util │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── connection.py │ │ │ │ │ ├── request.py │ │ │ │ │ ├── response.py │ │ │ │ │ ├── retry.py │ │ │ │ │ ├── ssl_.py │ │ │ │ │ ├── timeout.py │ │ │ │ │ └── url.py │ │ │ ├── sessions.py │ │ │ ├── status_codes.py │ │ │ ├── structures.py │ │ │ └── utils.py │ │ │ └── sqlmap │ │ │ ├── DynamicContentParser.py │ │ │ └── __init__.py │ ├── dirsearch_task.py │ └── dirsearch_worker.py │ ├── masscan │ ├── __init__.py │ ├── db_save.py │ ├── masscan_task.py │ └── masscan_worker.py │ ├── nmap │ ├── __init__.py │ ├── nmap_task.py │ └── nmap_worker.py │ └── patator │ ├── __init__.py │ ├── patator_ext.py │ ├── patator_task.py │ ├── patator_worker.py │ ├── requirements.txt │ └── wordlists │ ├── logins.txt │ └── passwords.txt ├── common └── logger.py ├── config ├── __init__.py ├── config.yml ├── config_docker.yml └── custom.yml ├── docker-compose.yml ├── docker ├── amass.yml ├── black.yml ├── dirsearch.yml ├── masscan.yml ├── nmap.yml ├── patator.yml ├── postgres │ ├── Dockerfile │ └── pgpool_postgres_entrypoint.sh └── rabbitmq │ └── Dockerfile ├── events_handling ├── __init__.py ├── new_data_notifier.py ├── scopes_handlers.py └── tasks_handlers.py ├── managers ├── __init__.py ├── creds_manager.py ├── dicts_manager.py ├── files_manager.py ├── meta_manager.py ├── projects_manager.py ├── resolver.py ├── scans_manager.py ├── scopes │ ├── __init__.py │ ├── filters.py │ ├── scopes_manager.py │ ├── subquery_builder.py │ └── utils.py └── tasks │ ├── finished_task_notification_creator.py │ ├── shadow_task.py │ ├── task_spawner.py │ ├── tasks_cache.py │ └── tasks_manager.py ├── public ├── bundle.js └── index.html ├── requirements.txt ├── server.py ├── server ├── __init__.py └── handlers │ ├── __init__.py │ ├── creds.py │ ├── dictionaries.py │ ├── files.py │ ├── hosts.py │ ├── ips.py │ ├── projects.py │ ├── scans.py │ ├── scopes.py │ ├── static.py │ ├── tasks.py │ └── utils.py └── spawn_worker.py /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | Dockerfile* 4 | docker-compose* 5 | .dockerignore 6 | .git 7 | .gitignore 8 | README.md 9 | LICENSE 10 | .vscode -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[Bug] " 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser: [e.g. chrome, safari] 29 | - Environment: [Docker containers or standalone launch] 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.prof 2 | **/node_modules/ 3 | **/wordlists/* 4 | __pycache__/ 5 | .env/ 6 | .python-version 7 | .vscode 8 | logs/ 9 | -------------------------------------------------------------------------------- /app/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "es2015", 4 | "react", 5 | ["babel-preset-env", { "targets": { "node": 6 }}] 6 | ], 7 | "plugins": ["transform-object-rest-spread"] 8 | } -------------------------------------------------------------------------------- /app/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/c0rv4x/project-black/2d3df00ba1b1453c99ec5a247793a74e11adba2a/app/.keep -------------------------------------------------------------------------------- /app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "black_front", 3 | "version": "1.0.0", 4 | "description": "Frontend, solely", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "dev": "webpack -d --watch", 9 | "build": "webpack -p" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/iad42/black_pt_front.git" 14 | }, 15 | "author": "", 16 | "license": "ISC", 17 | "bugs": { 18 | "url": "https://github.com/iad42/black_pt_front/issues" 19 | }, 20 | "homepage": "https://github.com/iad42/black_pt_front#readme", 21 | "devDependencies": { 22 | "babel-cli": "^6.26.0", 23 | "babel-core": "^6.26.0", 24 | "babel-loader": "^6.4.0", 25 | "babel-plugin-lodash": "^3.3.2", 26 | "babel-plugin-transform-object-rest-spread": "^6.26.0", 27 | "babel-preset-airbnb": "^2.6.0", 28 | "babel-preset-env": "^1.6.1", 29 | "babel-preset-es2015": "^6.22.0", 30 | "babel-preset-react": "^6.23.0", 31 | "babel-preset-stage-1": "^6.24.1", 32 | "babel-preset-stage-2": "^6.22.0", 33 | "file-loader": "^0.10.1", 34 | "redux-devtools": "^3.3.2", 35 | "style-loader": "^0.19.0", 36 | "url-loader": "^1.0.1", 37 | "webpack": "^3.0.0" 38 | }, 39 | "dependencies": { 40 | "atob": ">=2.1.0", 41 | "autosize": "^4.0.2", 42 | "classnames": "^2.2.5", 43 | "macaddress": ">=0.2.9", 44 | "cross-fetch": "^3.0.1", 45 | "css-loader": "^0.28.7", 46 | "fsevents": "^1.2.7", 47 | "grommet": "^2.3.1", 48 | "grommet-icons": "^4.1.0", 49 | "history": "1.13.x", 50 | "html-webpack-plugin": "^3.0.7", 51 | "lodash": ">=4.17.13", 52 | "mixin-deep": ">=2.0.1", 53 | "natives": "^1.1.6", 54 | "randomatic": ">=3.0.0", 55 | "react": "^16.7.0", 56 | "react-addons-perf": "^15.4.2", 57 | "react-dom": "^16.7.0", 58 | "react-notification-system": "^0.2.15", 59 | "react-notification-system-redux": "^1.1.6", 60 | "react-paginate": "^4.4.2", 61 | "react-redux": "^5.0.3", 62 | "react-router": "latest", 63 | "react-router-dom": "^4.0.0-beta.7", 64 | "react-time-ago": "^5.0.0", 65 | "react-transition-group": "^1.2.1", 66 | "redux": "^3.6.0", 67 | "redux-notifications": "^4.0.1", 68 | "redux-thunk": "^2.3.0", 69 | "socket.io-client": "^1.7.3", 70 | "styled-components": "^4.1.3", 71 | "uuid": "^3.3.2" 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /app/src/common/loading/Loading.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import { Box, Layer, Stack } from 'grommet' 4 | 5 | const spinning = ( 6 | 13 | 18 | 19 | 27 | 28 | 29 | ); 30 | 31 | 32 | class Loading extends React.Component { 33 | render() { 34 | return ( 35 | 38 | {this.props.children} 39 | { 40 | this.props.componentLoading && ( 41 | 45 | {spinning} 46 | 47 | ) 48 | } 49 | 50 | ) 51 | } 52 | } 53 | 54 | export default Loading; -------------------------------------------------------------------------------- /app/src/common/paginate/Page.jsx: -------------------------------------------------------------------------------- 1 | import _ from 'lodash' 2 | import React from 'react' 3 | 4 | import { Box } from 'grommet' 5 | 6 | 7 | class Page extends React.Component { 8 | shouldComponentUpdate(nextProps, nextState) { 9 | return (!_.isEqual(nextProps, this.props) || !_.isEqual(nextState, this.state)); 10 | } 11 | 12 | render() { 13 | const { value, active, disabled, setActive }= this.props; 14 | 15 | return ( 16 | 22 | {value} 23 | 24 | ) 25 | } 26 | } 27 | 28 | export default Page; -------------------------------------------------------------------------------- /app/src/common/scope_comment/ScopeComment.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import ScopeCommentPresentational from './ScopeCommentPresentational.jsx' 4 | 5 | 6 | class ScopeComment extends React.Component { 7 | 8 | constructor(props) { 9 | super(props); 10 | 11 | this.state = { 12 | scopeComment: this.props.comment, 13 | valueBeforeEdited: this.props.comment 14 | }; 15 | 16 | this.commentSubmitted = this.commentSubmitted.bind(this); 17 | this.onChange = this.onChange.bind(this); 18 | } 19 | 20 | shouldComponentUpdate(nextProps, nextState) { 21 | return ((!_.isEqual(nextProps, this.props)) || (!_.isEqual(nextState, this.state))); 22 | } 23 | 24 | componentDidUpdate(prevProps) { 25 | if ((this.props.comment !== prevProps.comment) && (this.props.comment != this.state.valueBeforeEdited)) { 26 | this.setState({ 27 | scopeComment: this.props.comment, 28 | valueBeforeEdited : this.props.comment 29 | }); 30 | } 31 | } 32 | 33 | commentSubmitted(e) { 34 | this.props.onCommentSubmit(e); 35 | } 36 | 37 | onChange(value) { 38 | this.setState({ 39 | scopeComment: value 40 | }); 41 | } 42 | 43 | render() { 44 | return ( 45 | 50 | ) 51 | } 52 | } 53 | 54 | export default ScopeComment; 55 | -------------------------------------------------------------------------------- /app/src/common/scope_comment/ScopeCommentPresentational.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import EditableElement from '../editable/EditableElement.jsx' 4 | 5 | import { TextArea } from 'grommet' 6 | 7 | 8 | class ScopeCommentPresentational extends React.Component { 9 | 10 | render() { 11 | return ( 12 | 18 | ) 19 | } 20 | 21 | } 22 | 23 | 24 | export default ScopeCommentPresentational; 25 | -------------------------------------------------------------------------------- /app/src/common/tasks/Tasks.jsx: -------------------------------------------------------------------------------- 1 | import _ from 'lodash' 2 | import React from 'react' 3 | import { 4 | Box, 5 | Heading, 6 | Table, 7 | TableHeader, 8 | TableRow, 9 | TableCell, 10 | TableBody 11 | } from 'grommet' 12 | 13 | import TasksGroup from './TasksGroup.jsx' 14 | 15 | class Tasks extends React.Component { 16 | 17 | constructor(props) { 18 | super(props); 19 | } 20 | 21 | shouldComponentUpdate(nextProps) { 22 | return !_.isEqual(nextProps, this.props); 23 | } 24 | 25 | render() { 26 | let groupped_tasks = {}; 27 | 28 | for (let each_task of this.props.tasks) { 29 | const { task_type } = each_task; 30 | 31 | if (groupped_tasks.hasOwnProperty(task_type)) { 32 | groupped_tasks[task_type].push(each_task); 33 | } 34 | else { 35 | groupped_tasks[task_type] = [each_task]; 36 | } 37 | } 38 | 39 | let groupped_tasks_unsorted = []; 40 | _.forOwn(groupped_tasks, (value, key) => { 41 | groupped_tasks_unsorted.push([key, value]); 42 | }); 43 | 44 | let groupped_tasks_sorted = groupped_tasks_unsorted.sort((a, b) => { 45 | if (a[0] < b[0]) return -1; 46 | if (a[0] > b[0]) return 1; 47 | return 0; 48 | }); 49 | 50 | let tasks = []; 51 | groupped_tasks_sorted.map((a) => { 52 | let key = a[0]; 53 | let value = a[1]; 54 | tasks.push(); 55 | }); 56 | 57 | if (_.get(this.props.tasks, 'length', 0)) { 58 | return ( 59 | 60 | Active tasks 61 | 62 | 63 | 64 | Type 65 | Queued Tasks 66 | Progress 67 | 68 | 69 | 70 | {tasks} 71 | 72 |
73 |
74 | ) 75 | } 76 | else { 77 | return
There are no active tasks
; 78 | } 79 | } 80 | 81 | } 82 | 83 | export default Tasks; 84 | -------------------------------------------------------------------------------- /app/src/common/tasks/TasksGroup.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import { 4 | Box, 5 | TableRow, 6 | TableCell, 7 | Meter, 8 | Stack, 9 | Text 10 | } from 'grommet' 11 | 12 | 13 | class EachTask extends React.Component { 14 | 15 | constructor(props) { 16 | super(props) 17 | } 18 | 19 | render() { 20 | let { tasks, type } = this.props; 21 | let progresses = []; 22 | 23 | let tasks_sorted = tasks.sort((a, b) => { 24 | if (a.task_id > b.task_id) return 1; 25 | if (a.task_id < b.task_id) return -1; 26 | return 0; 27 | }); 28 | for (let each_task of tasks_sorted) { 29 | if (each_task.status == 'Working') { 30 | const progressValue = each_task.progress; 31 | 32 | progresses.push( 33 | 38 | { 39 | (progressValue != 1337) ? ( 40 | 41 | 47 | 48 | 49 | {each_task.progress} 50 | 51 | % 52 | 53 | 54 | ) : ( 55 | 56 | 62 | 63 | 64 | N/A 65 | 66 | 67 | 68 | ) 69 | } 70 | 71 | ); 72 | } 73 | } 74 | 75 | return ( 76 | 77 | {type} 78 | {tasks.length} 79 | {progresses} 80 | 81 | ) 82 | } 83 | } 84 | 85 | export default EachTask; 86 | -------------------------------------------------------------------------------- /app/src/common/tasks_buttons/components/ButtonTasks.jsx: -------------------------------------------------------------------------------- 1 | import _ from 'lodash' 2 | import React from 'react' 3 | import { DropButton } from 'grommet' 4 | 5 | import InnerModal from './InnerModal.jsx' 6 | import DropButtonContent from './DropButtonContent.jsx' 7 | 8 | 9 | 10 | class ButtonTasks extends React.Component { 11 | 12 | constructor(props) { 13 | super(props); 14 | 15 | this.state = { 16 | current_task: { 17 | name: "", 18 | preformedOptions: [], 19 | availableOptions: [], 20 | handler: (() => {}) 21 | }, 22 | dropDownOpen: false, 23 | modalOpen: false 24 | }; 25 | 26 | this.changeCurrentTask = this.changeCurrentTask.bind(this); 27 | } 28 | 29 | shouldComponentUpdate(nextProps, nextState) { 30 | return !_.isEqual(nextProps, this.props) || !_.isEqual(nextState, this.state); 31 | } 32 | 33 | changeCurrentTask(task) { 34 | this.setState({ 35 | current_task: task 36 | }); 37 | 38 | this.openModal(); 39 | } 40 | 41 | openModal() { 42 | this.setState({ 43 | modalOpen: true 44 | }); 45 | } 46 | 47 | closeModal() { 48 | this.setState({ 49 | modalOpen: false 50 | }); 51 | } 52 | 53 | render() { 54 | const { tasks } = this.props; 55 | 56 | return ( 57 | 58 | this.setState({ dropDownOpen: true })} 62 | onClose={() => this.setState({ dropDownOpen: false })} 63 | dropContent={ 64 | this.setState({ dropDownOpen: false })} 67 | changeCurrentTask={this.changeCurrentTask} 68 | /> 69 | } 70 | primary 71 | /> 72 | { 73 | this.state.modalOpen && ( 74 | 82 | ) 83 | } 84 | 85 | ) 86 | } 87 | 88 | } 89 | 90 | export default ButtonTasks; -------------------------------------------------------------------------------- /app/src/common/tasks_buttons/components/CustomOptions.jsx: -------------------------------------------------------------------------------- 1 | import _ from 'lodash' 2 | import React from 'react' 3 | 4 | 5 | import AdaptiveOption from '../presentational/AdaptiveOption.jsx' 6 | 7 | 8 | class CustomOptions extends React.Component { 9 | constructor(props) { 10 | super(props); 11 | } 12 | 13 | render() { 14 | var options = []; 15 | 16 | _.forOwn(this.props.inputs, (value, key) => { 17 | options.push( 18 | 24 | ); 25 | }); 26 | return ( 27 |
28 | {options} 29 |
30 | ) 31 | } 32 | } 33 | 34 | export default CustomOptions; -------------------------------------------------------------------------------- /app/src/common/tasks_buttons/components/Dictionaries.jsx: -------------------------------------------------------------------------------- 1 | import _ from 'lodash' 2 | import React from 'react' 3 | 4 | import { Button } from 'grommet' 5 | import { Catalog } from 'grommet-icons' 6 | 7 | import DictionariesManager from './DictionariesManager.jsx' 8 | 9 | 10 | class Dictionaries extends React.Component { 11 | constructor(props) { 12 | super(props); 13 | 14 | this.state = { 15 | "dictsHidden": true 16 | }; 17 | } 18 | 19 | render() { 20 | return ( 21 |
22 | {!this.state.dictsHidden && 23 | 28 | } 29 |
35 | ) 36 | } 37 | 38 | } 39 | 40 | export default Dictionaries; 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /app/src/common/tasks_buttons/components/DictionariesManager.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | 4 | import DictionaryStats from './DictionaryStats.jsx' 5 | import { requestDicts } from '../../../redux/dicts/actions.js' 6 | 7 | import { Heading } from 'grommet' 8 | 9 | 10 | class DictionariesManager extends React.Component { 11 | constructor(props) { 12 | super(props); 13 | 14 | this.renewDicts = this.renewDicts.bind(this); 15 | this.deleteDict = this.deleteDict.bind(this); 16 | } 17 | 18 | renewDicts() { 19 | this.context.store.dispatch(requestDicts()); 20 | } 21 | 22 | componentDidMount() { 23 | this.renewDicts(); 24 | } 25 | 26 | deleteDict(dict_id) { 27 | 28 | } 29 | 30 | render() { 31 | return ( 32 |
33 | Dictionaries 34 | 41 |
42 | ) 43 | } 44 | 45 | } 46 | 47 | DictionariesManager.contextTypes = { 48 | store: PropTypes.object 49 | } 50 | 51 | export default DictionariesManager; 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /app/src/common/tasks_buttons/components/DropButtonContent.jsx: -------------------------------------------------------------------------------- 1 | import _ from 'lodash' 2 | import React from 'react' 3 | import { Box, Button } from 'grommet' 4 | 5 | 6 | class DropButtonContent extends React.Component { 7 | render() { 8 | let items = this.props.tasks.map((task) => { 9 | return ( 10 |