Merge master into feature/tr-auth0-organizations
Conflicts were the addition of CLI flags from a concurrent branch.pull/10616/head
commit
5b5dbee078
|
@ -2,6 +2,8 @@
|
|||
### Bug Fixes
|
||||
1. [#1612](https://github.com/influxdata/chronograf/pull/1612): Prevent users from being able to write to internal system databases
|
||||
1. [#1655](https://github.com/influxdata/chronograf/pull/1655): Add more than one color to Line+Stat graphs
|
||||
1. [#1688](https://github.com/influxdata/chronograf/pull/1688): Fix updating retention policies on single-node instances.
|
||||
1. [#1689](https://github.com/influxdata/chronograf/pull/1689): Fix size jitter bug in Template Variable dropdown menus
|
||||
|
||||
### Features
|
||||
1. [#1645](https://github.com/influxdata/chronograf/pull/1645): Add Auth0 as a supported OAuth2 provider
|
||||
|
|
|
@ -65,7 +65,7 @@ func NewAuth0(auth0Domain, clientID, clientSecret, redirectURL string, organizat
|
|||
ClientID: clientID,
|
||||
ClientSecret: clientSecret,
|
||||
|
||||
RequiredScopes: []string{"openid"},
|
||||
RequiredScopes: []string{"openid", "email"},
|
||||
|
||||
RedirectURL: redirectURL,
|
||||
AuthURL: authURL,
|
||||
|
|
|
@ -78,15 +78,18 @@ type Server struct {
|
|||
GenericTokenURL string `long:"generic-token-url" description:"OAuth 2.0 provider's token endpoint URL" env:"GENERIC_TOKEN_URL"`
|
||||
GenericAPIURL string `long:"generic-api-url" description:"URL that returns OpenID UserInfo compatible information." env:"GENERIC_API_URL"`
|
||||
|
||||
StatusFeedURL string `long:"status-feed-url" description:"URL of a JSON Feed to display as a News Feed on the client Status page." default:"https://www.influxdata.com/feed/json" env:"STATUS_FEED_URL"`
|
||||
|
||||
CustomLinks map[string]string `long:"custom-link" description:"Custom link to be added to the client User menu" env:"CUSTOM_LINKS" env-delim:","`
|
||||
|
||||
Auth0Domain string `long:"auth0-domain" description:"Subdomain of auth0.com used for Auth0 OAuth2 authentication" env:"AUTH0_DOMAIN"`
|
||||
Auth0ClientID string `long:"auth0-client-id" description:"Auth0 Client ID for OAuth2 support" env:"AUTH0_CLIENT_ID"`
|
||||
Auth0ClientSecret string `long:"auth0-client-secret" description:"Auth0 Client Secret for OAuth2 support" env:"AUTH0_CLIENT_SECRET"`
|
||||
Auth0Organizations []string `long:"auth0-organizations" description:"Auth0 organizations permitted to access Chronograf (comma separated)" env:"AUTH0_ORGS" env-delim:","`
|
||||
|
||||
StatusFeedURL string `long:"status-feed-url" description:"URL of a JSON Feed to display as a News Feed on the client Status page." default:"https://www.influxdata.com/feed/json" env:"STATUS_FEED_URL"`
|
||||
|
||||
CustomLinks map[string]string `long:"custom-link" description:"Custom link to be added to the client User menu" env:"CUSTOM_LINKS" env-delim:","`
|
||||
|
||||
StatusFeedURL string `long:"status-feed-url" description:"URL of a JSON Feed to display as a News Feed on the client Status page." default:"https://www.influxdata.com/feed/json" env:"STATUS_FEED_URL"`
|
||||
CustomLinks map[string]string `long:"custom-link" description:"Custom link to be added to the client User menu. Multiple links can be added by using multiple of the same flag with different 'name:url' values, or as an environment variable with comma-separated 'name:url' values. E.g. via flags: '--custom-link=InfluxData:https://www.influxdata.com --custom-link=Chronograf:https://github.com/influxdata/chronograf'. E.g. via environment variable: 'export CUSTOM_LINKS=InfluxData:https://www.influxdata.com,Chronograf:https://github.com/influxdata/chronograf'" env:"CUSTOM_LINKS" env-delim:","`
|
||||
|
||||
ReportingDisabled bool `short:"r" long:"reporting-disabled" description:"Disable reporting of usage stats (os,arch,version,cluster_id,uptime) once every 24hr" env:"REPORTING_DISABLED"`
|
||||
LogLevel string `short:"l" long:"log-level" value-name:"choice" choice:"debug" choice:"info" choice:"error" default:"info" description:"Set the logging level" env:"LOG_LEVEL"`
|
||||
Basepath string `short:"p" long:"basepath" description:"A URL path prefix under which all chronograf routes will be mounted" env:"BASE_PATH"`
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
"mocha": "^2.4.5",
|
||||
"mocha-loader": "^0.7.1",
|
||||
"mustache": "^2.2.1",
|
||||
"node-sass": "^4.5.2",
|
||||
"node-sass": "^4.5.3",
|
||||
"postcss-browser-reporter": "^0.4.0",
|
||||
"postcss-calc": "^5.2.0",
|
||||
"postcss-loader": "^0.8.0",
|
||||
|
@ -90,6 +90,7 @@
|
|||
"dependencies": {
|
||||
"axios": "^0.13.1",
|
||||
"bootstrap": "^3.3.7",
|
||||
"calculate-size": "^1.1.1",
|
||||
"classnames": "^2.2.3",
|
||||
"dygraphs": "^2.0.0",
|
||||
"fast.js": "^0.1.1",
|
||||
|
|
|
@ -225,12 +225,18 @@ class DatabaseRow extends Component {
|
|||
}
|
||||
|
||||
getInputValues() {
|
||||
const {notify, retentionPolicy: {name: currentName}} = this.props
|
||||
const {
|
||||
notify,
|
||||
retentionPolicy: {name: currentName},
|
||||
isRFDisplayed,
|
||||
} = this.props
|
||||
|
||||
const name = (this.name && this.name.value.trim()) || currentName
|
||||
let duration = this.duration.value.trim()
|
||||
const replication = +this.replication.value.trim()
|
||||
// Replication > 1 is only valid for Influx Enterprise
|
||||
const replication = isRFDisplayed ? +this.replication.value.trim() : 1
|
||||
|
||||
if (!duration || !replication) {
|
||||
if (!duration || (isRFDisplayed && !replication)) {
|
||||
notify('error', 'Fields cannot be empty')
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1,30 +1,64 @@
|
|||
import React, {PropTypes} from 'react'
|
||||
import classnames from 'classnames'
|
||||
import calculateSize from 'calculate-size'
|
||||
|
||||
import Dropdown from 'shared/components/Dropdown'
|
||||
|
||||
import omit from 'lodash/omit'
|
||||
|
||||
const minTempVarDropdownWidth = 146
|
||||
const maxTempVarDropdownWidth = 300
|
||||
const tempVarDropdownPadding = 30
|
||||
|
||||
const TemplateControlBar = ({
|
||||
templates,
|
||||
onSelectTemplate,
|
||||
onOpenTemplateManager,
|
||||
isOpen,
|
||||
}) => (
|
||||
}) =>
|
||||
<div className={classnames('template-control-bar', {show: isOpen})}>
|
||||
<div className="template-control--container">
|
||||
<div className="template-control--controls">
|
||||
{templates.length
|
||||
? templates.map(({id, values, tempVar}) => {
|
||||
const items = values.map(value => ({...value, text: value.value}))
|
||||
const itemValues = values.map(value => value.value)
|
||||
const selectedItem = items.find(item => item.selected) || items[0]
|
||||
const selectedText = selectedItem && selectedItem.text
|
||||
let customDropdownWidth = 0
|
||||
if (itemValues.length > 1) {
|
||||
const longest = itemValues.reduce(
|
||||
(a, b) => (a.length > b.length ? a : b)
|
||||
)
|
||||
const longestLengthPixels =
|
||||
calculateSize(longest, {
|
||||
font: 'Monospace',
|
||||
fontSize: '12px',
|
||||
}).width + tempVarDropdownPadding
|
||||
|
||||
if (
|
||||
longestLengthPixels > minTempVarDropdownWidth &&
|
||||
longestLengthPixels < maxTempVarDropdownWidth
|
||||
) {
|
||||
customDropdownWidth = longestLengthPixels
|
||||
} else if (longestLengthPixels > maxTempVarDropdownWidth) {
|
||||
customDropdownWidth = maxTempVarDropdownWidth
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: change Dropdown to a MultiSelectDropdown, `selected` to
|
||||
// the full array, and [item] to all `selected` values when we update
|
||||
// this component to support multiple values
|
||||
return (
|
||||
<div key={id} className="template-control--dropdown">
|
||||
<div
|
||||
key={id}
|
||||
className="template-control--dropdown"
|
||||
style={
|
||||
customDropdownWidth > 0
|
||||
? {minWidth: customDropdownWidth}
|
||||
: null
|
||||
}
|
||||
>
|
||||
<Dropdown
|
||||
items={items}
|
||||
buttonSize="btn-xs"
|
||||
|
@ -53,7 +87,6 @@ const TemplateControlBar = ({
|
|||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
const {arrayOf, bool, func, shape, string} = PropTypes
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import React, {PropTypes} from 'react'
|
|||
import classnames from 'classnames'
|
||||
import OnClickOutside from 'react-onclickoutside'
|
||||
|
||||
const {bool, func, node, number, shape, string} = PropTypes
|
||||
const {array, bool, func, node, number, shape, string} = PropTypes
|
||||
|
||||
const NameableGraph = React.createClass({
|
||||
propTypes: {
|
||||
|
@ -11,6 +11,7 @@ const NameableGraph = React.createClass({
|
|||
isEditing: bool,
|
||||
x: number.isRequired,
|
||||
y: number.isRequired,
|
||||
queries: array.isRequired,
|
||||
}).isRequired,
|
||||
children: node.isRequired,
|
||||
onEditCell: func,
|
||||
|
@ -39,6 +40,21 @@ const NameableGraph = React.createClass({
|
|||
})
|
||||
},
|
||||
|
||||
renderCustomTimeIndicator() {
|
||||
const {cell} = this.props
|
||||
let customTimeRange = null
|
||||
|
||||
cell.queries.map(q => {
|
||||
if (!q.query.includes(':dashboardTime:')) {
|
||||
customTimeRange = q.queryConfig.range.lower.split(' ').reverse()[0]
|
||||
}
|
||||
})
|
||||
|
||||
return customTimeRange
|
||||
? <span className="dash-graph--custom-time">{customTimeRange}</span>
|
||||
: null
|
||||
},
|
||||
|
||||
render() {
|
||||
const {
|
||||
cell,
|
||||
|
@ -75,7 +91,12 @@ const NameableGraph = React.createClass({
|
|||
/>
|
||||
)
|
||||
} else {
|
||||
nameOrField = <span className="dash-graph--name">{name}</span>
|
||||
nameOrField = (
|
||||
<span className="dash-graph--name">
|
||||
{name}
|
||||
{this.renderCustomTimeIndicator()}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
let onStartRenaming
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
$template-control--margin: 2px;
|
||||
$template-control--min-height: 52px;
|
||||
$template-control-dropdown-min-width: 146px;
|
||||
$template-control-dropdown-max-width: 300px;
|
||||
|
||||
.template-control-bar {
|
||||
display: none;
|
||||
|
@ -54,6 +55,7 @@ button.btn.template-control--manage {
|
|||
.template-control--dropdown {
|
||||
flex: 0 1 auto;
|
||||
min-width: $template-control-dropdown-min-width;
|
||||
max-width: $template-control-dropdown-max-width;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
|
@ -70,6 +72,13 @@ button.btn.template-control--manage {
|
|||
font-size: 12px;
|
||||
font-family: $code-font;
|
||||
}
|
||||
.dropdown .dropdown-menu .fancy-scroll--view li.dropdown-item a {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
overflow: hidden;
|
||||
font-family: $code-font;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
.template-control--label {
|
||||
@include no-user-select();
|
||||
|
|
|
@ -20,4 +20,12 @@
|
|||
// Make Overlay Technology full screen
|
||||
.overlay-technology {
|
||||
left: -($sidebar--width) !important;
|
||||
|
||||
// Hacky way to ensure proper appearance of file upload modal
|
||||
// Needed to have a this div nested inside of itself for the
|
||||
// Drag & drop feature to work correctly
|
||||
.overlay-technology {
|
||||
left: 0 !important;
|
||||
&:before {display: none;}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -144,7 +144,7 @@ $dash-graph-options-arrow: 8px;
|
|||
.dash-graph--name {
|
||||
height: $dash-graph-heading;
|
||||
line-height: $dash-graph-heading;
|
||||
width: calc(100% - 50px);
|
||||
width: calc(100% - 30px);
|
||||
padding-left: 16px;
|
||||
transition:
|
||||
color 0.25s ease,
|
||||
|
@ -160,6 +160,19 @@ input.form-control.dash-graph--name-edit {
|
|||
position: relative;
|
||||
top: -1px; // Fix for slight offset
|
||||
}
|
||||
.dash-graph--custom-time {
|
||||
font-family: $code-font;
|
||||
color: $c-pool;
|
||||
background-color: $g2-kevlar;
|
||||
height: 24px;
|
||||
font-size: 10px;
|
||||
line-height: 24px;
|
||||
border-radius: 3px;
|
||||
padding: 0 7px;
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
right: 30px;
|
||||
}
|
||||
.dash-graph--options {
|
||||
width: $dash-graph-heading;
|
||||
position: absolute;
|
||||
|
|
10
ui/yarn.lock
10
ui/yarn.lock
|
@ -1564,6 +1564,10 @@ bytes@2.4.0:
|
|||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.4.0.tgz#7d97196f9d5baf7f6935e25985549edd2a6c2339"
|
||||
|
||||
calculate-size@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/calculate-size/-/calculate-size-1.1.1.tgz#ae7caa1c7795f82c4f035dc7be270e3581dae3ee"
|
||||
|
||||
caller-path@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f"
|
||||
|
@ -4800,9 +4804,9 @@ node-pre-gyp@^0.6.29:
|
|||
tar "~2.2.1"
|
||||
tar-pack "~3.3.0"
|
||||
|
||||
node-sass@^4.5.2:
|
||||
version "4.5.2"
|
||||
resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.5.2.tgz#4012fa2bd129b1d6365117e88d9da0500d99da64"
|
||||
node-sass@^4.5.3:
|
||||
version "4.5.3"
|
||||
resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.5.3.tgz#d09c9d1179641239d1b97ffc6231fdcec53e1568"
|
||||
dependencies:
|
||||
async-foreach "^0.1.3"
|
||||
chalk "^1.1.1"
|
||||
|
|
Loading…
Reference in New Issue