Comparing version 0.0.3 to 0.0.4
@@ -13,4 +13,4 @@ 'use strict'; | ||
R(MainActionBar, {loading, runLint}), | ||
R(LogView, {logs}), | ||
R('div', {className: 'SecondaryActionBar'}, 'Secondary Actions') | ||
R(LogView, {logs}) | ||
// R('div', {className: 'SecondaryActionBar'}, 'Secondary Actions') | ||
); | ||
@@ -17,0 +17,0 @@ } |
@@ -8,16 +8,13 @@ 'use strict'; | ||
function getSettings(props) { | ||
const {folder, updateFolder} = props; | ||
function textSetting(props, header, description, name) { | ||
const {settings, updateSettings} = props; | ||
return R('div', {className: 'AppSettingGroup'}, | ||
R('div', {className: 'AppSettingHeader'}, | ||
T.SETTINGS_HEADER_FOLDER | ||
), | ||
R('div', {className: 'AppSettingDescription'}, | ||
T.SETTINGS_DESCRIPTION_FOLDER | ||
), | ||
R('div', {className: 'AppSettingHeader'}, header), | ||
R('div', {className: 'AppSettingDescription'}, description), | ||
R('input', { | ||
className: 'AppSettingInput', | ||
value: settings[name], | ||
type: 'text', | ||
value: folder, | ||
onChange: event => updateFolder(event.target.value) | ||
onChange: event => | ||
updateSettings({[name]: event.target.value}) | ||
}) | ||
@@ -27,5 +24,40 @@ ); | ||
function checkboxSetting(props, header, description, name) { | ||
const {settings, updateSettings} = props; | ||
return R('div', {className: 'AppSettingGroup'}, | ||
R('div', {className: 'AppSettingHeader'}, header), | ||
R('label', {className: 'AppSettingCheckboxLabel'}, | ||
R('input', { | ||
className: 'AppSettingCheckbox', | ||
checked: settings[name], | ||
type: 'checkbox', | ||
onChange: event => | ||
updateSettings({[name]: event.target.checked}) | ||
}), | ||
description | ||
) | ||
); | ||
} | ||
function dropdownSetting(props, header, description, name, options) { | ||
const {settings, updateSettings} = props; | ||
const value = settings[name]; | ||
const onChange = (event) => { | ||
updateSettings({[name]: event.target.value}); | ||
}; | ||
return R('div', {className: 'AppSettingGroup'}, | ||
R('div', {className: 'AppSettingHeader'}, header), | ||
R('div', {className: 'AppSettingDescription'}, description), | ||
R('select', {className: 'AppSettingDropdown', onChange, value}, | ||
options.map(x => | ||
R('option', {key: x.value, value: x.value}, x.name) | ||
) | ||
) | ||
); | ||
} | ||
function AppSettings(props) { | ||
const className = css({ | ||
AppSettings: true, | ||
ThemeDark: true, | ||
hidden: !props.isVisible | ||
@@ -42,13 +74,24 @@ }); | ||
R('div', {className: 'AppSettingsContent'}, | ||
getSettings(props), | ||
getSettings(props), | ||
getSettings(props), | ||
getSettings(props), | ||
getSettings(props), | ||
getSettings(props), | ||
getSettings(props), | ||
getSettings(props), | ||
getSettings(props), | ||
getSettings(props), | ||
getSettings(props) | ||
textSetting( | ||
props, | ||
T.SETTINGS_HEADER_FOLDER, | ||
T.SETTINGS_DESCRIPTION_FOLDER, | ||
'folder' | ||
), | ||
checkboxSetting( | ||
props, | ||
T.SETTINGS_HEADER_REPLACE, | ||
T.SETTINGS_DESCRIPTION_REPLACE, | ||
'replace' | ||
), | ||
dropdownSetting( | ||
props, | ||
'Theme', | ||
'Which theme you like?', | ||
'theme', | ||
[ | ||
{value: 'dark', name: 'Dark'}, | ||
{value: 'light', name: 'Light'} | ||
] | ||
) | ||
) | ||
@@ -55,0 +98,0 @@ ); |
@@ -5,4 +5,6 @@ 'use strict'; | ||
require('whatwg-fetch'); | ||
const R = require('react').createElement; | ||
const connect = require('react-redux').connect; | ||
const AppHeader = require('./app-header'); | ||
@@ -12,7 +14,8 @@ const AppMain = require('./app-main'); | ||
const primaryReducer = require('./primary-reducer'); | ||
const css = require('./css'); | ||
function updateFolder_(store, folder) { | ||
function updateSettings_(store, settings) { | ||
store.dispatch({ | ||
type: 'UPDATE_FOLDER', | ||
value: folder | ||
type: 'UPDATE_SETTINGS', | ||
value: settings | ||
}); | ||
@@ -46,5 +49,5 @@ } | ||
const { | ||
settings, | ||
logs, | ||
dispatch, | ||
folder, | ||
loading, | ||
@@ -54,4 +57,5 @@ store, | ||
} = props; | ||
const {folder, theme} = settings; | ||
const runLint = runLint_.bind(null, store, folder); | ||
const updateFolder = updateFolder_.bind(null, store); | ||
const updateSettings = updateSettings_.bind(null, store); | ||
const onShowSettings = function() { | ||
@@ -63,3 +67,8 @@ dispatch({type: 'SHOW_SETTINGS'}); | ||
}; | ||
return R('div', {className: 'App'}, | ||
const className = css({ | ||
App: true, | ||
ThemeDark: theme === 'dark', | ||
ThemeLight: theme === 'light' || !theme, | ||
}); | ||
return R('div', {className}, | ||
R(AppHeader, {onShowSettings, folder}), | ||
@@ -69,5 +78,5 @@ R(AppMain, {logs, loading, runLint}), | ||
isVisible: settingsVisible, | ||
folder, | ||
settings, | ||
onHideSettings, | ||
updateFolder | ||
updateSettings | ||
}) | ||
@@ -74,0 +83,0 @@ ); |
@@ -13,2 +13,18 @@ require('./lint-file-specific-log.less'); | ||
function ruleUrl(ruleId) { | ||
return 'http://eslint.org/docs/rules/' + ruleId; | ||
} | ||
function openUrl(file, line, column) { | ||
return '/open?path=' + [file, line, column].join(':'); | ||
} | ||
function openUrlHandler(file, line, column, event) { | ||
const url = openUrl(file, line, column); | ||
const method = 'POST'; | ||
const req = new Request(url, {method}); | ||
fetch(req); | ||
event.preventDefault(); | ||
} | ||
function LintFileSpecificLog(props) { | ||
@@ -31,11 +47,20 @@ const {log} = props; | ||
R('th', {}, 'file'), | ||
R('td', {}, file) | ||
R('td', {}, | ||
R('a', | ||
{ | ||
target: '_blank', | ||
href: openUrl(file, line, column), | ||
onClick: openUrlHandler.bind(null, file, line, column) | ||
}, | ||
file, ':', line, ':', column | ||
) | ||
) | ||
), | ||
R('tr', {}, | ||
R('th', {}, 'line'), | ||
R('td', {}, line) | ||
), | ||
R('tr', {}, | ||
R('th', {}, 'eslint'), | ||
R('td', {}, ruleId) | ||
R('td', {}, | ||
R('a', {target: '_blank', href: ruleUrl(ruleId)}, | ||
ruleId | ||
) | ||
) | ||
) | ||
@@ -42,0 +67,0 @@ ) |
@@ -14,5 +14,9 @@ 'use strict'; | ||
const initialState = Object.freeze({ | ||
settings: { | ||
theme: 'light', | ||
replace: true, | ||
folder: '' | ||
}, | ||
loading: false, | ||
logs: [], | ||
folder: '', | ||
settingsVisible: false, | ||
@@ -41,6 +45,6 @@ }); | ||
.then(resp => resp.json()) | ||
.then(value => { | ||
.then(folder => { | ||
store.dispatch({ | ||
type:'UPDATE_FOLDER', | ||
value | ||
type:'UPDATE_SETTINGS', | ||
value: {folder} | ||
}); | ||
@@ -47,0 +51,0 @@ }); |
@@ -5,47 +5,40 @@ function merge(obj1, obj2) { | ||
function allLogs(folder, log) { | ||
// const summary = { | ||
// type: 'LINT_FILE', | ||
// file: log.filePath, | ||
// warningCount: log.warningCount, | ||
// errorCount: log.errorCount | ||
// }; | ||
const specifics = | ||
log.messages.map(message => | ||
getSpecifics(folder, log.filePath, message) | ||
); | ||
return specifics; | ||
// return [summary].concat(specifics); | ||
function allLogs(log) { | ||
return log.messages.map(message => | ||
getSpecifics(log.filePath, message) | ||
); | ||
} | ||
function getSpecifics(folder, file, message) { | ||
function getSpecifics(file, message) { | ||
const type = 'LINT_FILE_SPECIFIC'; | ||
// TODO: Unsafe use of JS replace (fix dollar signs) | ||
const folder_ = folder + '/'; | ||
const file_ = | ||
file.indexOf(folder_) === 0 ? | ||
file.replace(folder_, '') : | ||
file; | ||
return merge({file: file_, type}, message); | ||
return merge({file, type}, message); | ||
} | ||
function processLintResults(logs) { | ||
return logs | ||
.filter(x => x.warningCount + x.errorCount > 0) | ||
.map(allLogs) | ||
.reduce((acc, x) => acc.concat(x), []); | ||
} | ||
const table = { | ||
UPDATE_LOADING: (state, action) => ({loading: action.value}), | ||
UPDATE_FOLDER: (state, action) => ({folder: action.value}), | ||
SHOW_SETTINGS: (state, action) => ({settingsVisible: true}), | ||
HIDE_SETTINGS: (state, action) => ({settingsVisible: false}), | ||
UPDATE_LOADING: (state, action) => | ||
({loading: action.value}), | ||
UPDATE_SETTINGS: (state, action) => | ||
({settings: merge(state.settings, action.value)}), | ||
SHOW_SETTINGS: (state, action) => | ||
({settingsVisible: true}), | ||
HIDE_SETTINGS: (state, action) => | ||
({settingsVisible: false}), | ||
DISPLAY_LINT_RESULTS: (state, action) => { | ||
// const summary = { | ||
// type: 'LINT_FILE', | ||
// file: '__PROJECT__', | ||
// warningCount: action.value.warningCount, | ||
// errorCount: action.value.errorCount | ||
// }; | ||
const logs = action.value.results | ||
.filter(x => x.warningCount + x.errorCount > 0) | ||
.map(allLogs.bind(null, state.folder)) | ||
.reduce((acc, x) => acc.concat(x), []); | ||
// const newLogs = state.logs.concat([summary], logs); | ||
const newLogs = state.logs.concat(logs); | ||
return {logs: newLogs}; | ||
const logs = processLintResults(action.value.results); | ||
if (state.settings.replace) { | ||
return {logs}; | ||
} else { | ||
return {logs: state.logs.concat(logs)}; | ||
} | ||
}, | ||
@@ -52,0 +45,0 @@ }; |
@@ -5,4 +5,6 @@ { | ||
"SETTINGS": "Settings", | ||
"SETTINGS_HEADER_REPLACE": "Replace logs", | ||
"SETTINGS_DESCRIPTION_REPLACE": "Should logs be replaced or appended to when new logs appear", | ||
"SETTINGS_HEADER_FOLDER": "Folder", | ||
"SETTINGS_DESCRIPTION_FOLDER": "The root folder of the project you want to work with right now. The special character '~' is not currently supported, so please use '/Users/myname/blah' instead of '~/blah'." | ||
} |
{ | ||
"name": "battenberg", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"description": "A friendly web GUI for building and developing JavaScript projects", | ||
@@ -32,3 +32,4 @@ "main": "src/no-api.js", | ||
"eslint": "^2.10.2", | ||
"express": "^4.13.4" | ||
"express": "^4.13.4", | ||
"open-in-editor": "^1.2.0" | ||
}, | ||
@@ -35,0 +36,0 @@ "devDependencies": { |
@@ -9,2 +9,3 @@ 'use strict'; | ||
const routesLint = require('./routes/lint'); | ||
const routesOpen = require('./routes/open'); | ||
@@ -21,2 +22,4 @@ const app = express(); | ||
app.get('/lint', routesLint); | ||
app.get('/open', routesOpen); | ||
app.post('/open', routesOpen); | ||
app.listen(C.PORT, C.HOST, greet); |
@@ -6,5 +6,5 @@ const path = require('path'); | ||
function index(req, res) { | ||
res.sendFile(path.join(C.APP_PATH, 'dist', 'index.html')); | ||
res.sendFile(path.join(C.APP_PATH, 'index.html')); | ||
} | ||
module.exports = index; |
@@ -5,40 +5,6 @@ const path = require('path'); | ||
const S = require('../http-statuses'); | ||
const eslintOptions = require('../eslint-options'); | ||
// const OFF = 'off'; | ||
const WARN = 'warn'; | ||
const ERROR = 'error'; | ||
const cli = new eslint.CLIEngine(eslintOptions); | ||
const cli = new eslint.CLIEngine({ | ||
// TODO: Actually set the envs correctly | ||
envs: ['browser', 'mocha', 'node', 'es6'], | ||
useEslintrc: false, | ||
extends: 'eslint:recommended', | ||
ignorePattern: [ | ||
'node_modules', | ||
'bower_components', | ||
'build', | ||
'dist' | ||
], | ||
// Eventually let's enable it to fix problems automatically! :D | ||
// fix: true, | ||
rules: { | ||
semi: WARN, | ||
strict: [WARN, 'safe'], | ||
'wrap-iife': WARN, | ||
'no-trailing-spaces': WARN, | ||
'comma-style': [WARN, 'last'], | ||
'new-parens': WARN, | ||
'no-inline-comments': WARN, | ||
'no-sequences': ERROR, | ||
'no-alert': WARN, | ||
'no-caller': WARN, | ||
'no-lone-blocks': WARN, | ||
'object-curly-spacing': [WARN, 'never'], | ||
'space-infix-ops': WARN, | ||
'space-unary-ops': [WARN, {words: true, nonwords: false}], | ||
'spaced-comment': [WARN, 'always'], | ||
'no-unused-vars': [WARN, {argsIgnorePattern: '^_'}] | ||
} | ||
}); | ||
function lint(req, res) { | ||
@@ -45,0 +11,0 @@ if ('path' in req.query) { |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
877750
50
20874
3
328
6
+ Addedopen-in-editor@^1.2.0
+ Addedclap@1.2.3(transitive)
+ Addedes6-promise-polyfill@1.2.0(transitive)
+ Addedopen-in-editor@1.2.1(transitive)
+ Addedos-homedir@1.0.1(transitive)
- Removedos-homedir@1.0.2(transitive)