YARN-7445. Render Applications and Services page with filters in new YARN UI. Contributed by Vasudevan Skm.
This commit is contained in:
parent
3e26077848
commit
fb62bd625f
3
.gitignore
vendored
3
.gitignore
vendored
@ -44,3 +44,6 @@ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/dist
|
||||
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/tmp
|
||||
yarnregistry.pdf
|
||||
patchprocess/
|
||||
|
||||
|
||||
.history/
|
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
content: null,
|
||||
|
||||
classNames: ["em-table-simple-status-cell"],
|
||||
|
||||
statusName: Ember.computed("content", function () {
|
||||
var status = this.get("content");
|
||||
|
||||
return status.toLowerCase().capitalize();
|
||||
}),
|
||||
});
|
@ -34,7 +34,8 @@ export default Ember.Controller.extend({
|
||||
headerTitle: 'Application ID',
|
||||
contentPath: 'id',
|
||||
cellComponentName: 'em-table-linked-cell',
|
||||
minWidth: "250px",
|
||||
minWidth: "280px",
|
||||
facetType: null,
|
||||
getCellContent: function(row) {
|
||||
return {
|
||||
displayText: row.id,
|
||||
@ -45,30 +46,33 @@ export default Ember.Controller.extend({
|
||||
id: 'appType',
|
||||
headerTitle: 'Application Type',
|
||||
contentPath: 'applicationType',
|
||||
facetType: null,
|
||||
}, {
|
||||
id: 'appName',
|
||||
headerTitle: 'Application Name',
|
||||
contentPath: 'appName',
|
||||
facetType: null,
|
||||
}, {
|
||||
id: 'appUsr',
|
||||
headerTitle: 'User',
|
||||
contentPath: 'user',
|
||||
minWidth: "50px"
|
||||
}, {
|
||||
id: 'state',
|
||||
headerTitle: 'State',
|
||||
contentPath: 'state',
|
||||
cellComponentName: 'em-table-simple-status-cell',
|
||||
minWidth: "50px"
|
||||
}, {
|
||||
id: 'queue',
|
||||
headerTitle: 'Queue',
|
||||
contentPath: 'queue',
|
||||
}, {
|
||||
id: 'state',
|
||||
headerTitle: 'State',
|
||||
contentPath: 'state',
|
||||
cellComponentName: 'em-table-status-cell',
|
||||
minWidth: "50px"
|
||||
}, {
|
||||
id: 'progress',
|
||||
headerTitle: 'Progress',
|
||||
contentPath: 'progress',
|
||||
cellComponentName: 'em-table-progress-cell',
|
||||
facetType: null,
|
||||
cellDefinition: {
|
||||
valueMax: 100
|
||||
}
|
||||
@ -76,10 +80,12 @@ export default Ember.Controller.extend({
|
||||
id: 'stTime',
|
||||
headerTitle: 'Start Time',
|
||||
contentPath: 'startTime',
|
||||
facetType: null,
|
||||
}, {
|
||||
id: 'elTime',
|
||||
headerTitle: 'Elapsed Time',
|
||||
contentPath: 'elapsedTime',
|
||||
facetType: null,
|
||||
cellDefinition: {
|
||||
type: "duration"
|
||||
}
|
||||
@ -87,6 +93,7 @@ export default Ember.Controller.extend({
|
||||
id: 'finishTime',
|
||||
headerTitle: 'Finished Time',
|
||||
contentPath: 'validatedFinishedTs',
|
||||
facetType: null,
|
||||
observePath: true
|
||||
}, {
|
||||
id: 'priority',
|
||||
@ -108,6 +115,7 @@ export default Ember.Controller.extend({
|
||||
headerTitle: 'Service Name',
|
||||
contentPath: 'appName',
|
||||
minWidth: "200px",
|
||||
facetType: null,
|
||||
cellComponentName: 'em-table-linked-cell',
|
||||
getCellContent: function(row) {
|
||||
return {
|
||||
@ -119,22 +127,25 @@ export default Ember.Controller.extend({
|
||||
id: 'appId',
|
||||
headerTitle: 'Application ID',
|
||||
contentPath: 'id',
|
||||
facetType: null,
|
||||
minWidth: "250px"
|
||||
}, {
|
||||
id: 'state',
|
||||
headerTitle: 'State',
|
||||
contentPath: 'state',
|
||||
cellComponentName: 'em-table-status-cell',
|
||||
cellComponentName: 'em-table-simple-status-cell',
|
||||
minWidth: "50px"
|
||||
}, {
|
||||
id: 'cluster',
|
||||
headerTitle: '%Cluster',
|
||||
contentPath: 'clusterUsagePercentage',
|
||||
facetType: null,
|
||||
observePath: true
|
||||
}, {
|
||||
id: 'elTime',
|
||||
headerTitle: 'Elapsed Time',
|
||||
contentPath: 'elapsedTime',
|
||||
facetType: null,
|
||||
cellDefinition: {
|
||||
type: "duration"
|
||||
},
|
||||
@ -143,6 +154,7 @@ export default Ember.Controller.extend({
|
||||
id: 'appUsr',
|
||||
headerTitle: 'User',
|
||||
contentPath: 'user',
|
||||
facetType: null,
|
||||
minWidth: "50px"
|
||||
}, {
|
||||
id: 'queue',
|
||||
@ -152,10 +164,12 @@ export default Ember.Controller.extend({
|
||||
id: 'stTime',
|
||||
headerTitle: 'Started Time',
|
||||
contentPath: 'startTime',
|
||||
facetType: null,
|
||||
}, {
|
||||
id: 'finishTime',
|
||||
headerTitle: 'Finished Time',
|
||||
contentPath: 'validatedFinishedTs',
|
||||
facetType: null,
|
||||
observePath: true
|
||||
});
|
||||
return ColumnDef.make(colums);
|
||||
|
@ -22,7 +22,10 @@ import AppTableController from '../app-table-columns';
|
||||
|
||||
export default AppTableController.extend({
|
||||
queryParams: ['searchText', 'sortColumnId', 'sortOrder', 'pageNum', 'rowCount'],
|
||||
tableDefinition: TableDefinition.create(),
|
||||
tableDefinition: TableDefinition.create({
|
||||
enableFaceting: true,
|
||||
rowCount: 25
|
||||
}),
|
||||
searchText: Ember.computed.alias('tableDefinition.searchText'),
|
||||
sortColumnId: Ember.computed.alias('tableDefinition.sortColumnId'),
|
||||
sortOrder: Ember.computed.alias('tableDefinition.sortOrder'),
|
||||
|
@ -24,7 +24,9 @@ export default AppTableController.extend({
|
||||
queryParams: ['searchText', 'sortColumnId', 'sortOrder', 'pageNum', 'rowCount'],
|
||||
tableDefinition: TableDefinition.create({
|
||||
sortColumnId: 'stTime',
|
||||
sortOrder: 'desc'
|
||||
sortOrder: 'desc',
|
||||
rowCount: 25,
|
||||
enableFaceting: true
|
||||
}),
|
||||
searchText: Ember.computed.alias('tableDefinition.searchText'),
|
||||
sortColumnId: Ember.computed.alias('tableDefinition.sortColumnId'),
|
||||
|
@ -19,7 +19,6 @@
|
||||
body, html, body > .ember-view {
|
||||
height: 100%;
|
||||
overflow: visible;
|
||||
color: @text-color;
|
||||
background: #f6f6f8;
|
||||
font-family: "Open Sans","Helvetica Neue", sans-serif!important;
|
||||
}
|
||||
@ -419,29 +418,44 @@ div.attempt-info-panel table > tbody > tr > td:last-of-type {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.yarn-cluster-status i {
|
||||
.yarn-cluster-status i,
|
||||
.em-table-simple-status-cell i{
|
||||
display: inline-block;
|
||||
border-radius: 100%;
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
.yarn-cluster-status i {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 10px;
|
||||
border: 1px solid;
|
||||
margin: 3px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.yarn-cluster-status i.started {
|
||||
.em-table-simple-status-cell i {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
margin: 3px 3px 3px 0;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
.yarn-cluster-status i.started,
|
||||
.em-table-simple-status-cell i.finished {
|
||||
border-color: #43b135;
|
||||
background-color: #60cea5;
|
||||
}
|
||||
.yarn-cluster-status i.stopped {
|
||||
.yarn-cluster-status i.stopped,
|
||||
.em-table-simple-status-cell i.killed {
|
||||
border-color: #b04b4e;
|
||||
background-color: #ef6162;
|
||||
}
|
||||
.yarn-cluster-status i.inited{
|
||||
.yarn-cluster-status i.inited,
|
||||
.em-table-simple-status-cell i.running {
|
||||
border-color: #1c95c0;
|
||||
background-color: #26bbf0;
|
||||
}
|
||||
.yarn-cluster-status i.notinited {
|
||||
.yarn-cluster-status i.notinited,
|
||||
.em-table-simple-status-cell i.accepted {
|
||||
border-color: #dca41b;
|
||||
background-color: #ffbc0b;
|
||||
}
|
||||
@ -630,3 +644,74 @@ div.service-action-mask img {
|
||||
left: 45% !important;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.yarn-applications-container .table-panel-left .em-table-facet-panel {
|
||||
width: 240px;
|
||||
margin-right: 15px;
|
||||
padding: 0 0 15px 0;
|
||||
background: none;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.yarn-applications-container .table-panel-left .em-table-facet-panel .field-list > li .em-table-facet-panel-values{
|
||||
margin-top: 0px;
|
||||
margin-bottom: -4px;
|
||||
background: #fff;
|
||||
border: 1px solid #d5d5d5;
|
||||
}
|
||||
|
||||
.yarn-applications-container .table-panel-left .em-table-facet-panel .field-name {
|
||||
background-color: #f7f7f7;
|
||||
border-bottom: 1px solid #d5d5d5;
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
.yarn-applications-container .table-panel-left .em-table-facet-panel .all-button {
|
||||
right: 5px !important;
|
||||
}
|
||||
|
||||
.yarn-applications-container .table-panel-left .em-table-facet-panel .field-name::before {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.yarn-applications-container .table-panel-left .em-table-facet-panel .value-list {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.yarn-applications-container .table-panel-left .em-table-facet-panel .filter-box {
|
||||
padding: 5px;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.yarn-applications-container .table-panel-left .em-table-facet-panel .more-less {
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.yarn-applications-container .table-panel-left .em-table-facet-panel .field-list {
|
||||
padding-top: 0px;
|
||||
}
|
||||
|
||||
.yarn-applications-container .em-table .table-column .table-header-cell {
|
||||
padding: 7.5px 0 7.5px 7.5px;
|
||||
}
|
||||
|
||||
.yarn-applications-container .ember-view.table-cell {
|
||||
padding: 10px 15px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.yarn-applications-container .resize-column {
|
||||
position: absolute;
|
||||
right: -14px;
|
||||
display: inline-block;
|
||||
padding: 10px 0;
|
||||
top: -36px;
|
||||
font-size: 42px;
|
||||
line-height: 2em;
|
||||
}
|
||||
|
||||
.em-table .table-column .table-header-cell {
|
||||
background-color: #f7f7f7;
|
||||
border-bottom: 1px solid #d5d5d5;
|
||||
}
|
||||
|
@ -0,0 +1,27 @@
|
||||
{{!
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
}}
|
||||
|
||||
|
||||
{{#if content}}
|
||||
<span>
|
||||
<i class={{lower content}} />
|
||||
{{statusName}}
|
||||
</span>
|
||||
{{else}}
|
||||
<span class="txt-message"> N/A </span>
|
||||
{{/if}}
|
@ -18,68 +18,8 @@
|
||||
|
||||
{{breadcrumb-bar breadcrumbs=breadcrumbs}}
|
||||
|
||||
<div class="col-md-12 container-fluid">
|
||||
<div class="col-md-12 container-fluid yarn-applications-container">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-2 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Applications
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<ul class="nav nav-pills nav-stacked" id="stacked-menu">
|
||||
<ul class="nav nav-pills nav-stacked collapse in">
|
||||
{{#link-to 'yarn-apps.apps' tagName="li"}}
|
||||
{{#link-to 'yarn-apps.apps'}}All Applications{{/link-to}}
|
||||
{{/link-to}}
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-10 container-fluid">
|
||||
{{#if model.clusterMetrics}}
|
||||
<div class="row">
|
||||
<div class="col-lg-4 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Finished Apps
|
||||
</div>
|
||||
<div class="container-fluid" id="finishedapps-donut-chart">
|
||||
{{donut-chart data=model.clusterMetrics.firstObject.getFinishedAppsDataForDonutChart
|
||||
showLabels=true
|
||||
parentId="finishedapps-donut-chart"
|
||||
ratio=0.6
|
||||
maxHeight=350
|
||||
colorTargets="good warn error"
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Running Apps
|
||||
</div>
|
||||
<div class="container-fluid" id="runningapps-donut-chart">
|
||||
{{donut-chart data=model.clusterMetrics.firstObject.getRunningAppsDataForDonutChart
|
||||
showLabels=true
|
||||
parentId="runningapps-donut-chart"
|
||||
ratio=0.6
|
||||
maxHeight=350
|
||||
colorTargets="warn good"
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="row">
|
||||
{{outlet}}
|
||||
</div>
|
||||
</div>
|
||||
{{outlet}}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -18,72 +18,10 @@
|
||||
|
||||
{{breadcrumb-bar breadcrumbs=breadcrumbs}}
|
||||
|
||||
|
||||
<div class="col-md-12 container-fluid">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-2 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Services
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<ul class="nav nav-pills nav-stacked" id="stacked-menu">
|
||||
<ul class="nav nav-pills nav-stacked collapse in">
|
||||
{{#link-to 'yarn-services' tagName="li"}}
|
||||
{{#link-to 'yarn-services'}}Long Running Services{{/link-to}}
|
||||
{{/link-to}}
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-10 container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-lg-4 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Finished Services
|
||||
</div>
|
||||
<div class="container-fluid" id="finishedapps-donut-chart">
|
||||
{{donut-chart data=getFinishedServicesDataForDonutChart
|
||||
showLabels=true
|
||||
parentId="finishedapps-donut-chart"
|
||||
ratio=0.6
|
||||
maxHeight=350
|
||||
colorTargets="good warn error"
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4 container-fluid">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Running Services
|
||||
</div>
|
||||
<div class="container-fluid" id="runningapps-donut-chart">
|
||||
{{donut-chart data=getRunningServicesDataForDonutChart
|
||||
showLabels=true
|
||||
parentId="runningapps-donut-chart"
|
||||
ratio=0.6
|
||||
maxHeight=350
|
||||
colorTargets="warn good"
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4 container-fluid">
|
||||
<a class="btn btn-primary pull-right" href="#/yarn-deploy-service">New Service</a>
|
||||
</div>
|
||||
</div>
|
||||
{{#if model.apps}}
|
||||
{{em-table columns=serviceColumns rows=model.apps definition=tableDefinition}}
|
||||
{{else}}
|
||||
<h4 align="center">Could not find any services from this cluster</h4>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12 container-fluid yarn-applications-container">
|
||||
{{#if model.apps}}
|
||||
{{em-table columns=serviceColumns rows=model.apps definition=tableDefinition}}
|
||||
{{else}}
|
||||
<h4 align="center">Could not find any services from this cluster</h4>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
@ -21,6 +21,7 @@
|
||||
"spin.js": "~2.3.2",
|
||||
"momentjs": "~2.10.6",
|
||||
"select2": "4.0.0",
|
||||
"snippet-ss": "~1.11.0"
|
||||
"snippet-ss": "~1.11.0",
|
||||
"alasql": "^0.4.3"
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,6 @@ module.exports = function(environment) {
|
||||
'connect-src': "* 'self'",
|
||||
'child-src': "'self' 'unsafe-inline'",
|
||||
'style-src': "'self' 'unsafe-inline'",
|
||||
'script-src': "'self' 'unsafe-inline'"
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -49,6 +49,7 @@ module.exports = function(defaults) {
|
||||
app.import('bower_components/bootstrap/dist/css/bootstrap.css');
|
||||
app.import('bower_components/bootstrap/dist/css/bootstrap-theme.css');
|
||||
app.import('bower_components/bootstrap/dist/js/bootstrap.min.js');
|
||||
app.import('bower_components/alasql/dist/alasql.js');
|
||||
|
||||
// Use `app.import` to add additional libraries to the generated
|
||||
// output files.
|
||||
|
@ -2,5 +2,13 @@
|
||||
"compilerOptions": {
|
||||
"target": "ES6",
|
||||
"module": "commonjs"
|
||||
}
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"dist",
|
||||
"bower_components",
|
||||
"jspm_packages",
|
||||
"tmp",
|
||||
"temp"
|
||||
]
|
||||
}
|
||||
|
@ -56,6 +56,6 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"em-helpers": "^0.8.0",
|
||||
"em-table": "^0.7.0"
|
||||
"em-table": "0.11.3"
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { moduleForComponent, test } from 'ember-qunit';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
moduleForComponent('em-table-simple-status-cell', 'Integration | Component | em table simple status cell', {
|
||||
integration: true
|
||||
});
|
||||
|
||||
test('it renders', function(assert) {
|
||||
|
||||
// Set any properties with this.set('myProperty', 'value');
|
||||
// Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL +
|
||||
|
||||
this.render(hbs`{{em-table-simple-status-cell}}`);
|
||||
|
||||
assert.equal(this.$().text().trim(), '');
|
||||
|
||||
// Template block usage:" + EOL +
|
||||
this.render(hbs`
|
||||
{{#em-table-simple-status-cell}}
|
||||
template block text
|
||||
{{/em-table-simple-status-cell}}
|
||||
`);
|
||||
|
||||
assert.equal(this.$().text().trim(), 'template block text');
|
||||
});
|
@ -1402,9 +1402,9 @@ em-helpers@^0.8.0:
|
||||
optionalDependencies:
|
||||
phantomjs-prebuilt "2.1.13"
|
||||
|
||||
em-table@^0.7.0:
|
||||
version "0.7.2"
|
||||
resolved "https://registry.yarnpkg.com/em-table/-/em-table-0.7.2.tgz#867ff734701df9765f2505e02acd74768edb0f71"
|
||||
em-table@0.11.3:
|
||||
version "0.11.3"
|
||||
resolved "https://registry.yarnpkg.com/em-table/-/em-table-0.11.3.tgz#20e605cc3814214e644199399a2383cee8d23eeb"
|
||||
dependencies:
|
||||
ember-cli-htmlbars "^1.0.1"
|
||||
ember-cli-less "^1.4.0"
|
||||
|
Loading…
Reference in New Issue
Block a user