mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Explore: Metrics chooser for prometheus
- load all histogrammable metrics on start, based on `{le!=''}` series
query
- select dropdown shows all those metrics as well as histograms in a
special group
- select a metric will write fill the metric in the query box
- if a histogram is chosen, it will write a complete
`histogram_quantile` query
- added new dependency: rc-cascader
This commit is contained in:
@@ -166,6 +166,7 @@
|
||||
"mousetrap-global-bind": "^1.1.0",
|
||||
"prismjs": "^1.6.0",
|
||||
"prop-types": "^15.6.0",
|
||||
"rc-cascader": "^0.14.0",
|
||||
"react": "^16.2.0",
|
||||
"react-dom": "^16.2.0",
|
||||
"react-grid-layout": "0.16.6",
|
||||
@@ -187,4 +188,4 @@
|
||||
"resolutions": {
|
||||
"caniuse-db": "1.0.30000772"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ export class Explore extends React.Component<any, IExploreState> {
|
||||
};
|
||||
const nextQueries = [...queries];
|
||||
nextQueries[index] = nextQuery;
|
||||
this.setState({ queries: nextQueries });
|
||||
this.setState({ queries: nextQueries }, override ? () => this.onSubmit() : undefined);
|
||||
};
|
||||
|
||||
onChangeTime = nextRange => {
|
||||
|
||||
@@ -2,6 +2,7 @@ import _ from 'lodash';
|
||||
import moment from 'moment';
|
||||
import React from 'react';
|
||||
import { Value } from 'slate';
|
||||
import Cascader from 'rc-cascader';
|
||||
|
||||
// dom also includes Element polyfills
|
||||
import { getNextCharacter, getPreviousCousin } from './utils/dom';
|
||||
@@ -21,12 +22,14 @@ import TypeaheadField, {
|
||||
|
||||
const DEFAULT_KEYS = ['job', 'instance'];
|
||||
const EMPTY_SELECTOR = '{}';
|
||||
const HISTOGRAM_GROUP = '__histograms__';
|
||||
const HISTOGRAM_SELECTOR = '{le!=""}'; // Returns all timeseries for histograms
|
||||
const HISTORY_ITEM_COUNT = 5;
|
||||
const HISTORY_COUNT_CUTOFF = 1000 * 60 * 60 * 24; // 24h
|
||||
const METRIC_MARK = 'metric';
|
||||
const PRISM_LANGUAGE = 'promql';
|
||||
|
||||
export const wrapLabel = label => ({ label });
|
||||
export const wrapLabel = (label: string) => ({ label });
|
||||
export const setFunctionMove = (suggestion: Suggestion): Suggestion => {
|
||||
suggestion.move = -1;
|
||||
return suggestion;
|
||||
@@ -48,6 +51,22 @@ export function addHistoryMetadata(item: Suggestion, history: any[]): Suggestion
|
||||
};
|
||||
}
|
||||
|
||||
export function groupMetricsByPrefix(metrics: string[], delimiter = '_'): CascaderOption[] {
|
||||
return _.chain(metrics)
|
||||
.groupBy(metric => metric.split(delimiter)[0])
|
||||
.map((metricsForPrefix: string[], prefix: string): CascaderOption => {
|
||||
const prefixIsMetric = metricsForPrefix.length === 1 && metricsForPrefix[0] === prefix;
|
||||
const children = prefixIsMetric ? [] : metricsForPrefix.sort().map(m => ({ label: m, value: m }));
|
||||
return {
|
||||
children,
|
||||
label: prefix,
|
||||
value: prefix,
|
||||
};
|
||||
})
|
||||
.sortBy('label')
|
||||
.value();
|
||||
}
|
||||
|
||||
export function willApplySuggestion(
|
||||
suggestion: string,
|
||||
{ typeaheadContext, typeaheadText }: TypeaheadFieldState
|
||||
@@ -78,22 +97,33 @@ export function willApplySuggestion(
|
||||
return suggestion;
|
||||
}
|
||||
|
||||
interface CascaderOption {
|
||||
label: string;
|
||||
value: string;
|
||||
children?: CascaderOption[];
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
interface PromQueryFieldProps {
|
||||
history?: any[];
|
||||
histogramMetrics?: string[];
|
||||
initialQuery?: string | null;
|
||||
labelKeys?: { [index: string]: string[] }; // metric -> [labelKey,...]
|
||||
labelValues?: { [index: string]: { [index: string]: string[] } }; // metric -> labelKey -> [labelValue,...]
|
||||
metrics?: string[];
|
||||
metricsByPrefix?: CascaderOption[];
|
||||
onPressEnter?: () => void;
|
||||
onQueryChange?: (value: string) => void;
|
||||
onQueryChange?: (value: string, override?: boolean) => void;
|
||||
portalPrefix?: string;
|
||||
request?: (url: string) => any;
|
||||
}
|
||||
|
||||
interface PromQueryFieldState {
|
||||
histogramMetrics: string[];
|
||||
labelKeys: { [index: string]: string[] }; // metric -> [labelKey,...]
|
||||
labelValues: { [index: string]: { [index: string]: string[] } }; // metric -> labelKey -> [labelValue,...]
|
||||
metrics: string[];
|
||||
metricsByPrefix: CascaderOption[];
|
||||
}
|
||||
|
||||
interface PromTypeaheadInput {
|
||||
@@ -107,7 +137,7 @@ interface PromTypeaheadInput {
|
||||
class PromQueryField extends React.Component<PromQueryFieldProps, PromQueryFieldState> {
|
||||
plugins: any[];
|
||||
|
||||
constructor(props, context) {
|
||||
constructor(props: PromQueryFieldProps, context) {
|
||||
super(props, context);
|
||||
|
||||
this.plugins = [
|
||||
@@ -117,21 +147,45 @@ class PromQueryField extends React.Component<PromQueryFieldProps, PromQueryField
|
||||
];
|
||||
|
||||
this.state = {
|
||||
histogramMetrics: props.histogramMetrics || [],
|
||||
labelKeys: props.labelKeys || {},
|
||||
labelValues: props.labelValues || {},
|
||||
metrics: props.metrics || [],
|
||||
metricsByPrefix: props.metricsByPrefix || [],
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.fetchMetricNames();
|
||||
this.fetchHistogramMetrics();
|
||||
}
|
||||
|
||||
onChangeQuery = value => {
|
||||
onChangeMetrics = (values: string[], selectedOptions: CascaderOption[]) => {
|
||||
let query;
|
||||
if (selectedOptions.length === 1) {
|
||||
if (selectedOptions[0].children.length === 0) {
|
||||
query = selectedOptions[0].value;
|
||||
} else {
|
||||
// Ignore click on group
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
const prefix = selectedOptions[0].value;
|
||||
const metric = selectedOptions[1].value;
|
||||
if (prefix === HISTOGRAM_GROUP) {
|
||||
query = `histogram_quantile(0.95, sum(rate(${metric}[5m])) by (le))`;
|
||||
} else {
|
||||
query = metric;
|
||||
}
|
||||
}
|
||||
this.onChangeQuery(query, true);
|
||||
};
|
||||
|
||||
onChangeQuery = (value: string, override?: boolean) => {
|
||||
// Send text change to parent
|
||||
const { onQueryChange } = this.props;
|
||||
if (onQueryChange) {
|
||||
onQueryChange(value);
|
||||
onQueryChange(value, override);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -317,7 +371,17 @@ class PromQueryField extends React.Component<PromQueryFieldProps, PromQueryField
|
||||
return fetch(url);
|
||||
};
|
||||
|
||||
async fetchLabelValues(key) {
|
||||
fetchHistogramMetrics() {
|
||||
this.fetchSeriesLabels(HISTOGRAM_SELECTOR, true, () => {
|
||||
const histogramSeries = this.state.labelValues[HISTOGRAM_SELECTOR];
|
||||
if (histogramSeries && histogramSeries['__name__']) {
|
||||
const histogramMetrics = histogramSeries['__name__'].slice().sort();
|
||||
this.setState({ histogramMetrics });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async fetchLabelValues(key: string) {
|
||||
const url = `/api/v1/label/${key}/values`;
|
||||
try {
|
||||
const res = await this.request(url);
|
||||
@@ -337,7 +401,7 @@ class PromQueryField extends React.Component<PromQueryFieldProps, PromQueryField
|
||||
}
|
||||
}
|
||||
|
||||
async fetchSeriesLabels(name, withName?) {
|
||||
async fetchSeriesLabels(name: string, withName?: boolean, callback?: () => void) {
|
||||
const url = `/api/v1/series?match[]=${name}`;
|
||||
try {
|
||||
const res = await this.request(url);
|
||||
@@ -351,7 +415,7 @@ class PromQueryField extends React.Component<PromQueryFieldProps, PromQueryField
|
||||
...this.state.labelValues,
|
||||
[name]: values,
|
||||
};
|
||||
this.setState({ labelKeys, labelValues });
|
||||
this.setState({ labelKeys, labelValues }, callback);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
@@ -362,23 +426,41 @@ class PromQueryField extends React.Component<PromQueryFieldProps, PromQueryField
|
||||
try {
|
||||
const res = await this.request(url);
|
||||
const body = await (res.data || res.json());
|
||||
this.setState({ metrics: body.data }, this.onReceiveMetrics);
|
||||
const metrics = body.data;
|
||||
const metricsByPrefix = groupMetricsByPrefix(metrics);
|
||||
this.setState({ metrics, metricsByPrefix }, this.onReceiveMetrics);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { histogramMetrics, metricsByPrefix } = this.state;
|
||||
const histogramOptions = histogramMetrics.map(hm => ({ label: hm, value: hm }));
|
||||
const metricsOptions = [
|
||||
{ label: 'Histograms', value: HISTOGRAM_GROUP, children: histogramOptions },
|
||||
...metricsByPrefix,
|
||||
];
|
||||
|
||||
return (
|
||||
<TypeaheadField
|
||||
additionalPlugins={this.plugins}
|
||||
cleanText={cleanText}
|
||||
initialValue={this.props.initialQuery}
|
||||
onTypeahead={this.onTypeahead}
|
||||
onWillApplySuggestion={willApplySuggestion}
|
||||
onValueChanged={this.onChangeQuery}
|
||||
placeholder="Enter a PromQL query"
|
||||
/>
|
||||
<div className="prom-query-field">
|
||||
<div className="prom-query-field-tools">
|
||||
<Cascader options={metricsOptions} onChange={this.onChangeMetrics}>
|
||||
<button className="btn navbar-button navbar-button--tight">Metrics</button>
|
||||
</Cascader>
|
||||
</div>
|
||||
<div className="slate-query-field-wrapper">
|
||||
<TypeaheadField
|
||||
additionalPlugins={this.plugins}
|
||||
cleanText={cleanText}
|
||||
initialValue={this.props.initialQuery}
|
||||
onTypeahead={this.onTypeahead}
|
||||
onWillApplySuggestion={willApplySuggestion}
|
||||
onValueChanged={this.onChangeQuery}
|
||||
placeholder="Enter a PromQL query"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@ import React, { PureComponent } from 'react';
|
||||
import QueryField from './PromQueryField';
|
||||
|
||||
class QueryRow extends PureComponent<any, {}> {
|
||||
onChangeQuery = value => {
|
||||
onChangeQuery = (value, override?: boolean) => {
|
||||
const { index, onChangeQuery } = this.props;
|
||||
if (onChangeQuery) {
|
||||
onChangeQuery(value, index);
|
||||
onChangeQuery(value, index, override);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -18,10 +18,7 @@ class QueryRow extends PureComponent<any, {}> {
|
||||
};
|
||||
|
||||
onClickClearButton = () => {
|
||||
const { index, onChangeQuery } = this.props;
|
||||
if (onChangeQuery) {
|
||||
onChangeQuery('', index, true);
|
||||
}
|
||||
this.onChangeQuery('', true);
|
||||
};
|
||||
|
||||
onClickRemoveButton = () => {
|
||||
@@ -42,18 +39,7 @@ class QueryRow extends PureComponent<any, {}> {
|
||||
const { edited, history, query, request } = this.props;
|
||||
return (
|
||||
<div className="query-row">
|
||||
<div className="query-row-tools">
|
||||
<button className="btn navbar-button navbar-button--tight" onClick={this.onClickAddButton}>
|
||||
<i className="fa fa-plus" />
|
||||
</button>
|
||||
<button className="btn navbar-button navbar-button--tight" onClick={this.onClickRemoveButton}>
|
||||
<i className="fa fa-minus" />
|
||||
</button>
|
||||
<button className="btn navbar-button navbar-button--tight" onClick={this.onClickClearButton}>
|
||||
<i className="fa fa-times" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="slate-query-field-wrapper">
|
||||
<div className="query-row-field">
|
||||
<QueryField
|
||||
initialQuery={edited ? null : query}
|
||||
history={history}
|
||||
@@ -63,6 +49,17 @@ class QueryRow extends PureComponent<any, {}> {
|
||||
request={request}
|
||||
/>
|
||||
</div>
|
||||
<div className="query-row-tools">
|
||||
<button className="btn navbar-button navbar-button--tight" onClick={this.onClickClearButton}>
|
||||
<i className="fa fa-times" />
|
||||
</button>
|
||||
<button className="btn navbar-button navbar-button--tight" onClick={this.onClickAddButton}>
|
||||
<i className="fa fa-plus" />
|
||||
</button>
|
||||
<button className="btn navbar-button navbar-button--tight" onClick={this.onClickRemoveButton}>
|
||||
<i className="fa fa-minus" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// vendor
|
||||
@import '../vendor/css/timepicker.css';
|
||||
@import '../vendor/css/spectrum.css';
|
||||
@import '../vendor/css/rc-cascader.css';
|
||||
|
||||
// MIXINS
|
||||
@import 'mixins/mixins';
|
||||
|
||||
@@ -110,6 +110,11 @@
|
||||
width: 6rem;
|
||||
}
|
||||
|
||||
.query-row-field {
|
||||
margin-right: 3px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.explore {
|
||||
.logs {
|
||||
.logs-entries {
|
||||
@@ -146,3 +151,11 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prometheus-specifics, to be extracted to datasource soon
|
||||
|
||||
.explore {
|
||||
.prom-query-field {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
158
public/vendor/css/rc-cascader.css
vendored
Normal file
158
public/vendor/css/rc-cascader.css
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
.rc-cascader {
|
||||
font-size: 12px;
|
||||
}
|
||||
.rc-cascader-menus {
|
||||
font-size: 12px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
position: absolute;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 0 4px rgba(0, 0, 0, 0.17);
|
||||
white-space: nowrap;
|
||||
}
|
||||
.rc-cascader-menus-hidden {
|
||||
display: none;
|
||||
}
|
||||
.rc-cascader-menus.slide-up-enter,
|
||||
.rc-cascader-menus.slide-up-appear {
|
||||
animation-duration: .3s;
|
||||
animation-fill-mode: both;
|
||||
transform-origin: 0 0;
|
||||
opacity: 0;
|
||||
animation-timing-function: cubic-bezier(0.08, 0.82, 0.17, 1);
|
||||
animation-play-state: paused;
|
||||
}
|
||||
.rc-cascader-menus.slide-up-leave {
|
||||
animation-duration: .3s;
|
||||
animation-fill-mode: both;
|
||||
transform-origin: 0 0;
|
||||
opacity: 1;
|
||||
animation-timing-function: cubic-bezier(0.6, 0.04, 0.98, 0.34);
|
||||
animation-play-state: paused;
|
||||
}
|
||||
.rc-cascader-menus.slide-up-enter.slide-up-enter-active.rc-cascader-menus-placement-bottomLeft,
|
||||
.rc-cascader-menus.slide-up-appear.slide-up-appear-active.rc-cascader-menus-placement-bottomLeft {
|
||||
animation-name: SlideUpIn;
|
||||
animation-play-state: running;
|
||||
}
|
||||
.rc-cascader-menus.slide-up-enter.slide-up-enter-active.rc-cascader-menus-placement-topLeft,
|
||||
.rc-cascader-menus.slide-up-appear.slide-up-appear-active.rc-cascader-menus-placement-topLeft {
|
||||
animation-name: SlideDownIn;
|
||||
animation-play-state: running;
|
||||
}
|
||||
.rc-cascader-menus.slide-up-leave.slide-up-leave-active.rc-cascader-menus-placement-bottomLeft {
|
||||
animation-name: SlideUpOut;
|
||||
animation-play-state: running;
|
||||
}
|
||||
.rc-cascader-menus.slide-up-leave.slide-up-leave-active.rc-cascader-menus-placement-topLeft {
|
||||
animation-name: SlideDownOut;
|
||||
animation-play-state: running;
|
||||
}
|
||||
.rc-cascader-menu {
|
||||
display: inline-block;
|
||||
/* width: 100px; */
|
||||
max-width: 50vw;
|
||||
height: 192px;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border-right: 1px solid #e9e9e9;
|
||||
overflow: auto;
|
||||
}
|
||||
.rc-cascader-menu:last-child {
|
||||
border-right: 0;
|
||||
}
|
||||
.rc-cascader-menu-item {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
padding: 0 16px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
}
|
||||
.rc-cascader-menu-item:hover {
|
||||
background: #eaf8fe;
|
||||
}
|
||||
.rc-cascader-menu-item-disabled {
|
||||
cursor: not-allowed;
|
||||
color: #ccc;
|
||||
}
|
||||
.rc-cascader-menu-item-disabled:hover {
|
||||
background: transparent;
|
||||
}
|
||||
.rc-cascader-menu-item-loading:after {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
content: 'loading';
|
||||
color: #aaa;
|
||||
font-style: italic;
|
||||
}
|
||||
.rc-cascader-menu-item-active {
|
||||
background: #d5f1fd;
|
||||
}
|
||||
.rc-cascader-menu-item-active:hover {
|
||||
background: #d5f1fd;
|
||||
}
|
||||
.rc-cascader-menu-item-expand {
|
||||
position: relative;
|
||||
}
|
||||
.rc-cascader-menu-item-expand:after {
|
||||
content: '>';
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
line-height: 32px;
|
||||
}
|
||||
@keyframes SlideUpIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(0.8);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
}
|
||||
@keyframes SlideUpOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(0.8);
|
||||
}
|
||||
}
|
||||
@keyframes SlideDownIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform-origin: 0% 100%;
|
||||
transform: scaleY(0.8);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform-origin: 0% 100%;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
}
|
||||
@keyframes SlideDownOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform-origin: 0% 100%;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform-origin: 0% 100%;
|
||||
transform: scaleY(0.8);
|
||||
}
|
||||
}
|
||||
123
yarn.lock
123
yarn.lock
@@ -478,6 +478,12 @@ acorn@~2.6.4:
|
||||
version "2.6.4"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-2.6.4.tgz#eb1f45b4a43fa31d03701a5ec46f3b52673e90ee"
|
||||
|
||||
add-dom-event-listener@1.x:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/add-dom-event-listener/-/add-dom-event-listener-1.0.2.tgz#8faed2c41008721cf111da1d30d995b85be42bed"
|
||||
dependencies:
|
||||
object-assign "4.x"
|
||||
|
||||
after@0.8.2:
|
||||
version "0.8.2"
|
||||
resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f"
|
||||
@@ -771,6 +777,10 @@ array-slice@^0.2.3:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5"
|
||||
|
||||
array-tree-filter@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/array-tree-filter/-/array-tree-filter-1.0.1.tgz#0a8ad1eefd38ce88858632f9cc0423d7634e4d5d"
|
||||
|
||||
array-union@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
|
||||
@@ -1514,7 +1524,7 @@ babel-register@^6.26.0, babel-register@^6.9.0:
|
||||
mkdirp "^0.5.1"
|
||||
source-map-support "^0.4.15"
|
||||
|
||||
babel-runtime@^6.0.0, babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0, babel-runtime@^6.9.2:
|
||||
babel-runtime@6.x, babel-runtime@^6.0.0, babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0, babel-runtime@^6.9.2:
|
||||
version "6.26.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
|
||||
dependencies:
|
||||
@@ -2246,6 +2256,10 @@ classnames@2.x, classnames@^2.2.4, classnames@^2.2.5:
|
||||
version "2.2.5"
|
||||
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d"
|
||||
|
||||
classnames@^2.2.6:
|
||||
version "2.2.6"
|
||||
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
|
||||
|
||||
clean-css@3.4.x, clean-css@~3.4.2:
|
||||
version "3.4.28"
|
||||
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-3.4.28.tgz#bf1945e82fc808f55695e6ddeaec01400efd03ff"
|
||||
@@ -2553,6 +2567,12 @@ component-bind@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1"
|
||||
|
||||
component-classes@^1.2.5:
|
||||
version "1.2.6"
|
||||
resolved "https://registry.yarnpkg.com/component-classes/-/component-classes-1.2.6.tgz#c642394c3618a4d8b0b8919efccbbd930e5cd691"
|
||||
dependencies:
|
||||
component-indexof "0.0.3"
|
||||
|
||||
component-emitter@1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.1.2.tgz#296594f2753daa63996d2af08d15a95116c9aec3"
|
||||
@@ -2561,6 +2581,10 @@ component-emitter@1.2.1, component-emitter@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6"
|
||||
|
||||
component-indexof@0.0.3:
|
||||
version "0.0.3"
|
||||
resolved "https://registry.yarnpkg.com/component-indexof/-/component-indexof-0.0.3.tgz#11d091312239eb8f32c8f25ae9cb002ffe8d3c24"
|
||||
|
||||
component-inherit@0.0.3:
|
||||
version "0.0.3"
|
||||
resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143"
|
||||
@@ -2841,6 +2865,13 @@ crypto-random-string@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e"
|
||||
|
||||
css-animation@^1.3.2:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/css-animation/-/css-animation-1.4.1.tgz#5b8813125de0fbbbb0bbe1b472ae84221469b7a8"
|
||||
dependencies:
|
||||
babel-runtime "6.x"
|
||||
component-classes "^1.2.5"
|
||||
|
||||
css-color-names@0.0.4:
|
||||
version "0.0.4"
|
||||
resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0"
|
||||
@@ -3515,6 +3546,10 @@ doctrine@^1.2.2:
|
||||
esutils "^2.0.2"
|
||||
isarray "^1.0.0"
|
||||
|
||||
dom-align@^1.7.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/dom-align/-/dom-align-1.8.0.tgz#c0e89b5b674c6e836cd248c52c2992135f093654"
|
||||
|
||||
dom-converter@~0.1:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.1.4.tgz#a45ef5727b890c9bffe6d7c876e7b19cb0e17f3b"
|
||||
@@ -7354,6 +7389,10 @@ lodash._createset@~4.0.0:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26"
|
||||
|
||||
lodash._getnative@^3.0.0:
|
||||
version "3.9.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
|
||||
|
||||
lodash._root@~3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692"
|
||||
@@ -7386,6 +7425,14 @@ lodash.flattendeep@^4.4.0:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2"
|
||||
|
||||
lodash.isarguments@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a"
|
||||
|
||||
lodash.isarray@^3.0.0:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55"
|
||||
|
||||
lodash.isequal@^4.0.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
|
||||
@@ -7406,6 +7453,14 @@ lodash.kebabcase@^4.0.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36"
|
||||
|
||||
lodash.keys@^3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a"
|
||||
dependencies:
|
||||
lodash._getnative "^3.0.0"
|
||||
lodash.isarguments "^3.0.0"
|
||||
lodash.isarray "^3.0.0"
|
||||
|
||||
lodash.memoize@^4.1.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
||||
@@ -8651,7 +8706,7 @@ object-assign@4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.0.tgz#7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0"
|
||||
|
||||
object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
|
||||
object-assign@4.x, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
|
||||
@@ -9981,6 +10036,54 @@ raw-body@2.3.3:
|
||||
iconv-lite "0.4.23"
|
||||
unpipe "1.0.0"
|
||||
|
||||
rc-align@^2.4.0:
|
||||
version "2.4.3"
|
||||
resolved "https://registry.yarnpkg.com/rc-align/-/rc-align-2.4.3.tgz#b9b3c2a6d68adae71a8e1d041cd5e3b2a655f99a"
|
||||
dependencies:
|
||||
babel-runtime "^6.26.0"
|
||||
dom-align "^1.7.0"
|
||||
prop-types "^15.5.8"
|
||||
rc-util "^4.0.4"
|
||||
|
||||
rc-animate@2.x:
|
||||
version "2.4.4"
|
||||
resolved "https://registry.yarnpkg.com/rc-animate/-/rc-animate-2.4.4.tgz#a05a784c747beef140d99ff52b6117711bef4b1e"
|
||||
dependencies:
|
||||
babel-runtime "6.x"
|
||||
css-animation "^1.3.2"
|
||||
prop-types "15.x"
|
||||
|
||||
rc-cascader@^0.14.0:
|
||||
version "0.14.0"
|
||||
resolved "https://registry.yarnpkg.com/rc-cascader/-/rc-cascader-0.14.0.tgz#a956c99896f10883bf63d46fb894d0cb326842a4"
|
||||
dependencies:
|
||||
array-tree-filter "^1.0.0"
|
||||
prop-types "^15.5.8"
|
||||
rc-trigger "^2.2.0"
|
||||
rc-util "^4.0.4"
|
||||
shallow-equal "^1.0.0"
|
||||
warning "^4.0.1"
|
||||
|
||||
rc-trigger@^2.2.0:
|
||||
version "2.5.4"
|
||||
resolved "https://registry.yarnpkg.com/rc-trigger/-/rc-trigger-2.5.4.tgz#9088a24ba5a811b254f742f004e38a9e2f8843fb"
|
||||
dependencies:
|
||||
babel-runtime "6.x"
|
||||
classnames "^2.2.6"
|
||||
prop-types "15.x"
|
||||
rc-align "^2.4.0"
|
||||
rc-animate "2.x"
|
||||
rc-util "^4.4.0"
|
||||
|
||||
rc-util@^4.0.4, rc-util@^4.4.0:
|
||||
version "4.5.1"
|
||||
resolved "https://registry.yarnpkg.com/rc-util/-/rc-util-4.5.1.tgz#0e435057174c024901c7600ba8903dd03da3ab39"
|
||||
dependencies:
|
||||
add-dom-event-listener "1.x"
|
||||
babel-runtime "6.x"
|
||||
prop-types "^15.5.10"
|
||||
shallowequal "^0.2.2"
|
||||
|
||||
rc@^1.0.1, rc@^1.1.6, rc@^1.1.7:
|
||||
version "1.2.8"
|
||||
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
|
||||
@@ -10980,6 +11083,16 @@ shallow-clone@^1.0.0:
|
||||
kind-of "^5.0.0"
|
||||
mixin-object "^2.0.1"
|
||||
|
||||
shallow-equal@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-1.0.0.tgz#508d1838b3de590ab8757b011b25e430900945f7"
|
||||
|
||||
shallowequal@^0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-0.2.2.tgz#1e32fd5bcab6ad688a4812cb0cc04efc75c7014e"
|
||||
dependencies:
|
||||
lodash.keys "^3.1.2"
|
||||
|
||||
shallowequal@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.0.2.tgz#1561dbdefb8c01408100319085764da3fcf83f8f"
|
||||
@@ -12555,6 +12668,12 @@ walker@~1.0.5:
|
||||
dependencies:
|
||||
makeerror "1.0.x"
|
||||
|
||||
warning@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.1.tgz#66ce376b7fbfe8a887c22bdf0e7349d73d397745"
|
||||
dependencies:
|
||||
loose-envify "^1.0.0"
|
||||
|
||||
watch@~0.18.0:
|
||||
version "0.18.0"
|
||||
resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986"
|
||||
|
||||
Reference in New Issue
Block a user