Start developing HOT Builder on Merlin
Create basic file structure and use common Django template for both views. Also rework forms/YAML/Graph divs layout to make it more flexible. Create draft version of 'Add Resource' panel for HotBuilder - with resources filtering and a list of all available resources obtained from server-side Heat API. Change-Id: Ia2e4f8a63d85d8d5dd7cdd731cc4878836176070
This commit is contained in:
parent
5ee471c930
commit
7fc50585be
17
extensions/enabled/_51_add_hotbuilder_panel.py
Normal file
17
extensions/enabled/_51_add_hotbuilder_panel.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# The name of the panel to be added to HORIZON_CONFIG. Required.
|
||||||
|
PANEL = 'hotbuilder'
|
||||||
|
# The name of the dashboard the PANEL associated with. Required.
|
||||||
|
PANEL_DASHBOARD = 'project'
|
||||||
|
# The name of the panel group the PANEL is associated with.
|
||||||
|
PANEL_GROUP = 'orchestration'
|
||||||
|
|
||||||
|
ADD_INSTALLED_APPS = ['merlin', 'hotbuilder']
|
||||||
|
|
||||||
|
# Python panel class of the PANEL to be added.
|
||||||
|
ADD_PANEL = 'hotbuilder.panel.HotBuilderPanel'
|
||||||
|
|
||||||
|
ADD_ANGULAR_MODULES = ['merlin', 'hotbuilder']
|
||||||
|
ADD_JS_FILES = ['merlin/js/custom-libs/ui-bootstrap-tpls-0.12.1.js',
|
||||||
|
'merlin/js/merlin.init.js',
|
||||||
|
'merlin/js/merlin.templates.js',
|
||||||
|
'hotbuilder/js/hotbuilder.init.js']
|
0
extensions/hotbuilder/__init__.py
Normal file
0
extensions/hotbuilder/__init__.py
Normal file
30
extensions/hotbuilder/api.py
Normal file
30
extensions/hotbuilder/api.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# Copyright (c) 2015 Mirantis, Inc.
|
||||||
|
#
|
||||||
|
# Licensed 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 logging
|
||||||
|
from openstack_dashboard.api import heat
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def resource_type_list(request):
|
||||||
|
client = heat.heatclient(request)
|
||||||
|
kwargs = {}
|
||||||
|
return client.resource_types.list(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def resource_type_show(request, resource_type):
|
||||||
|
client = heat.heatclient(request)
|
||||||
|
return client.resource_types.get(resource_type)
|
||||||
|
|
20
extensions/hotbuilder/panel.py
Normal file
20
extensions/hotbuilder/panel.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Copyright (c) 2014 Mirantis, Inc.
|
||||||
|
#
|
||||||
|
# Licensed 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 horizon
|
||||||
|
|
||||||
|
|
||||||
|
class HotBuilderPanel(horizon.Panel):
|
||||||
|
name = 'HOT Templates'
|
||||||
|
slug = 'hotbuilder'
|
@ -0,0 +1,46 @@
|
|||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('hotbuilder')
|
||||||
|
.controller('HotbuilderController', HotbuilderController);
|
||||||
|
|
||||||
|
HotbuilderController.$inject = ['$q', '$http'];
|
||||||
|
|
||||||
|
function HotbuilderController($q, $http) {
|
||||||
|
var deferred = $q.defer();
|
||||||
|
var vm = this;
|
||||||
|
|
||||||
|
deferred.promise.then(function(url) {
|
||||||
|
$http.get(url).success(function(data) {
|
||||||
|
data.forEach(function(resourceType) {
|
||||||
|
$http.get(url + '/' + resourceType).success(function(data) {
|
||||||
|
vm.allEntries.push(data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
vm.setUrl = setUrl;
|
||||||
|
|
||||||
|
vm.allEntries = [];
|
||||||
|
|
||||||
|
vm.entries = [
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
vm.panel = {
|
||||||
|
title: 'Add Resource'
|
||||||
|
};
|
||||||
|
|
||||||
|
vm.tabs = [
|
||||||
|
{title: 'Parameters', content: 'There'},
|
||||||
|
{title: 'Outputs', content: 'Where'}
|
||||||
|
];
|
||||||
|
|
||||||
|
function setUrl(url) {
|
||||||
|
deferred.resolve(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
@ -0,0 +1,14 @@
|
|||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('hotbuilder', ['merlin'])
|
||||||
|
.run(initModule);
|
||||||
|
|
||||||
|
initModule.$inject = ['merlin.templates'];
|
||||||
|
|
||||||
|
function initModule(templates) {
|
||||||
|
templates.prefetch('/static/hotbuilder/templates/fields/', []);
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
@ -0,0 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* Created by tsufiev on 2/24/15.
|
||||||
|
*/
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('hotbuilder');
|
||||||
|
|
||||||
|
})();
|
88
extensions/hotbuilder/templates/hotbuilder/index.html
Normal file
88
extensions/hotbuilder/templates/hotbuilder/index.html
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
{% extends 'merlin/base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block title %}{% trans "Template Builder" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block merlin-css %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block merlin-js %}
|
||||||
|
<script type="text/javascript" src="{{ STATIC_URL }}hotbuilder/js/hotbuilder.init.js"></script>
|
||||||
|
<script type="text/javascript" src="{{ STATIC_URL }}hotbuilder/js/hotbuilder.controllers.js"></script>
|
||||||
|
<script type="text/javascript" src="{{ STATIC_URL }}hotbuilder/js/hotbuilder.models.js"></script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block page_header %}
|
||||||
|
{% include "horizon/common/_page_header.html" with title=_("Template Builder") %}
|
||||||
|
{% endblock page_header %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<h3>Compose Template</h3>
|
||||||
|
<div ng-controller="HotbuilderController as hotbuilder"
|
||||||
|
ng-init="hotbuilder.setUrl('{% url "horizon:project:hotbuilder:resource_types" %}')">
|
||||||
|
<div class="well">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs">
|
||||||
|
<tabset>
|
||||||
|
<tab heading="Resources">
|
||||||
|
<panel content="hotbuilder.panel">
|
||||||
|
|
||||||
|
<collapsible-group class="col-xs-12" content="{}"
|
||||||
|
title="'Recent resources'">
|
||||||
|
<div class="col-xs-6">
|
||||||
|
<draggable-entry
|
||||||
|
ng-repeat="entry in hotbuilder.entries"
|
||||||
|
entry="entry" entry-icon="server">
|
||||||
|
</draggable-entry>
|
||||||
|
</div>
|
||||||
|
</collapsible-group>
|
||||||
|
<collapsible-group class="col-xs-12" content="{}"
|
||||||
|
title="'More resources'">
|
||||||
|
<div class="col-xs-6">
|
||||||
|
<div class="has-feedback">
|
||||||
|
<input type="text" ng-model="filterValue" placeholder="Filter">
|
||||||
|
<span class="form-control-feedback fa fa-filter"></span>
|
||||||
|
</div>
|
||||||
|
<draggable-entry
|
||||||
|
ng-repeat="entry in hotbuilder.allEntries | filter:filterValue"
|
||||||
|
entry="entry" entry-icon="server">
|
||||||
|
</draggable-entry>
|
||||||
|
</div>
|
||||||
|
</collapsible-group>
|
||||||
|
</panel>
|
||||||
|
</tab>
|
||||||
|
<tab ng-repeat="tab in hotbuilder.tabs" heading="{$ tab.title $}" active="tab.active">
|
||||||
|
<panel>
|
||||||
|
{$ tab.content $}
|
||||||
|
</panel>
|
||||||
|
</tab>
|
||||||
|
</tabset>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs end-xs">
|
||||||
|
<div class="btn-group btn-toggle">
|
||||||
|
<button ng-click="isGraphMode = true" class="btn btn-sm"
|
||||||
|
ng-class="isGraphMode ? 'active btn-primary' : 'btn-default'">Graph</button>
|
||||||
|
<button ng-click="isGraphMode = false" class="btn btn-sm"
|
||||||
|
ng-class="!isGraphMode ? 'active btn-primary' : 'btn-default'">YAML</button>
|
||||||
|
</div>
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-body" ng-show="!isGraphMode">
|
||||||
|
<pre>{$ workbook.toYAML() $}</pre>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body" ng-show="isGraphMode">
|
||||||
|
Here will be a fancy Graph View as soon as we implement it!
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- page footer -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs end-xs">
|
||||||
|
<button ng-click="discardWorkbook()" class="btn btn-default cancel">Cancel</button>
|
||||||
|
<button ng-click="commitWorkbook()" class="btn btn-primary">
|
||||||
|
{$ workbookID ? 'Modify' : 'Create' $}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
26
extensions/hotbuilder/urls.py
Normal file
26
extensions/hotbuilder/urls.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Copyright (c) 2014 Mirantis, Inc.
|
||||||
|
#
|
||||||
|
# Licensed 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.
|
||||||
|
|
||||||
|
from django.conf.urls import patterns
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from hotbuilder import views
|
||||||
|
|
||||||
|
urlpatterns = patterns('',
|
||||||
|
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||||
|
url(r'^heat_resources$', views.ResourceTypesView.as_view(),
|
||||||
|
name='resource_types'),
|
||||||
|
url(r'^heat_resources/(?P<resource_type>[^/]+)$',
|
||||||
|
views.ShowResourceView.as_view(), name='show_resource')
|
||||||
|
)
|
45
extensions/hotbuilder/views.py
Normal file
45
extensions/hotbuilder/views.py
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# Copyright 2014 Rackspace
|
||||||
|
#
|
||||||
|
# Licensed 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 json
|
||||||
|
|
||||||
|
from django.views.generic import TemplateView, View
|
||||||
|
from django.http import HttpResponse
|
||||||
|
|
||||||
|
from hotbuilder import api
|
||||||
|
|
||||||
|
|
||||||
|
class JSONView(View):
|
||||||
|
def get_data(self, request, *args, **kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
return HttpResponse(
|
||||||
|
json.dumps(self.get_data(request, *args, **kwargs)),
|
||||||
|
content_type='application/json')
|
||||||
|
|
||||||
|
|
||||||
|
class ResourceTypesView(JSONView):
|
||||||
|
def get_data(self, request, *args, **kwargs):
|
||||||
|
return [resource.resource_type for resource in
|
||||||
|
api.resource_type_list(request)]
|
||||||
|
|
||||||
|
|
||||||
|
class ShowResourceView(JSONView):
|
||||||
|
def get_data(self, request, *args, **kwargs):
|
||||||
|
return api.resource_type_show(request, kwargs['resource_type'])
|
||||||
|
|
||||||
|
|
||||||
|
class IndexView(TemplateView):
|
||||||
|
template_name = 'hotbuilder/index.html'
|
@ -1,41 +1,18 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "merlin/base.html" %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load url from future %}
|
|
||||||
{% load static %}
|
|
||||||
{% load compress %}
|
|
||||||
{% block title %}{% trans "Create Workbook" %}{% endblock %}
|
{% block title %}{% trans "Create Workbook" %}{% endblock %}
|
||||||
|
|
||||||
{% block page_header %}
|
{% block page_header %}
|
||||||
{% include "horizon/common/_page_header.html" with title=_("Workbooks") %}
|
{% include "horizon/common/_page_header.html" with title=_("Workbooks") %}
|
||||||
{% endblock page_header %}
|
{% endblock page_header %}
|
||||||
|
|
||||||
{% block js %}
|
{% block merlin-js %}
|
||||||
{% include "horizon/_scripts.html" %}
|
<script type="text/javascript" src="{{ STATIC_URL }}mistral/js/mistral.init.js"></script>
|
||||||
<script type="text/javascript" src="{{ STATIC_URL }}merlin/js/custom-libs/barricade.js"></script>
|
<script type="text/javascript" src="{{ STATIC_URL }}mistral/js/mistral.workbook.controllers.js"></script>
|
||||||
<script type="text/javascript" src="{{ STATIC_URL }}merlin/libs/js-yaml/dist/js-yaml.min.js"></script>
|
<script type="text/javascript" src="{{ STATIC_URL }}mistral/js/mistral.workbook.models.js"></script>
|
||||||
<script type="text/javascript" src="{{ STATIC_URL }}merlin/libs/underscore/underscore-min.js"></script>
|
|
||||||
<script type="text/javascript" src="{{ STATIC_URL }}merlin/js/merlin.init.js"></script>
|
|
||||||
<script type="text/javascript" src="{{ STATIC_URL }}merlin/js/merlin.templates.js"></script>
|
|
||||||
<script type="text/javascript" src="{{ STATIC_URL }}merlin/js/merlin.filters.js"></script>
|
|
||||||
<script type="text/javascript" src="{{ STATIC_URL }}merlin/js/merlin.directives.js"></script>
|
|
||||||
<script type="text/javascript" src="{{ STATIC_URL }}merlin/js/merlin.field.models.js"></script>
|
|
||||||
<script type="text/javascript" src="{{ STATIC_URL }}merlin/js/merlin.panel.models.js"></script>
|
|
||||||
<script type="text/javascript" src="{{ STATIC_URL }}merlin/js/merlin.utils.js"></script>
|
|
||||||
|
|
||||||
<script type="text/javascript" src="{{ STATIC_URL }}mistral/js/mistral.init.js"></script>
|
|
||||||
<script type="text/javascript" src="{{ STATIC_URL }}mistral/js/mistral.workbook.controllers.js"></script>
|
|
||||||
<script type="text/javascript" src="{{ STATIC_URL }}mistral/js/mistral.workbook.models.js"></script>
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block css %}
|
{% block merlin-css %}{% endblock %}
|
||||||
{% include "_stylesheets.html" %}
|
|
||||||
{% compress css %}
|
|
||||||
<link href='{{ STATIC_URL }}merlin/scss/merlin.scss' type='text/scss' media='screen' rel='stylesheet' />
|
|
||||||
{% endcompress %}
|
|
||||||
<link href='{{ STATIC_URL }}merlin/libs/flexboxgrid/dist/flexboxgrid.css' type='text/css' media='screen' rel='stylesheet' />
|
|
||||||
{% block merlin-css %}{% endblock %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
<h3>Create Workbook</h3>
|
<h3>Create Workbook</h3>
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
.directive('typedField', typedField)
|
.directive('typedField', typedField)
|
||||||
|
|
||||||
.directive('editableTitle', editableTitle)
|
.directive('editableTitle', editableTitle)
|
||||||
|
.directive('draggableEntry', draggableEntry)
|
||||||
.directive('labeled', labeled);
|
.directive('labeled', labeled);
|
||||||
|
|
||||||
function labeled() {
|
function labeled() {
|
||||||
@ -230,4 +231,21 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function draggableEntry() {
|
||||||
|
return {
|
||||||
|
restrict: 'E',
|
||||||
|
scope: {
|
||||||
|
entry: '='
|
||||||
|
},
|
||||||
|
link: link,
|
||||||
|
templateUrl: '/static/merlin/templates/draggable-entry.html'
|
||||||
|
};
|
||||||
|
|
||||||
|
function link(scope, element, attrs) {
|
||||||
|
if (angular.isDefined(attrs.entryIcon)) {
|
||||||
|
scope.iconCls = 'fa-' + attrs.entryIcon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
|
@ -61,4 +61,15 @@ i.fa-times-circle {
|
|||||||
.section .section .section-heading & {
|
.section .section .section-heading & {
|
||||||
margin-top: 7px;
|
margin-top: 7px;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
.has-feedback {
|
||||||
|
input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.form-control-feedback {
|
||||||
|
top: -5px;
|
||||||
|
right: 7px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
13
merlin/static/merlin/templates/draggable-entry.html
Normal file
13
merlin/static/merlin/templates/draggable-entry.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<div class="col-xs-12">
|
||||||
|
<div class="row middle-xs">
|
||||||
|
<div class="col-xs-10">
|
||||||
|
<span ng-show="iconCls" class="fa" ng-class="iconCls"></span>
|
||||||
|
{$ entry.resource_type $}
|
||||||
|
</div>
|
||||||
|
<div class="add-btn add-entry col-xs">
|
||||||
|
<button class="btn btn-default btn-sm" ng-click="onAdd()">
|
||||||
|
<i class="fa fa-plus"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
26
merlin/templates/merlin/base.html
Normal file
26
merlin/templates/merlin/base.html
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% load compress %}
|
||||||
|
|
||||||
|
{% block js %}
|
||||||
|
{% include "horizon/_scripts.html" %}
|
||||||
|
<script type="text/javascript" src="{{ STATIC_URL }}merlin/js/custom-libs/barricade.js"></script>
|
||||||
|
<script type="text/javascript" src="{{ STATIC_URL }}merlin/libs/js-yaml/dist/js-yaml.min.js"></script>
|
||||||
|
<script type="text/javascript" src="{{ STATIC_URL }}merlin/libs/underscore/underscore-min.js"></script>
|
||||||
|
<script type="text/javascript" src="{{ STATIC_URL }}merlin/js/merlin.init.js"></script>
|
||||||
|
<script type="text/javascript" src="{{ STATIC_URL }}merlin/js/merlin.templates.js"></script>
|
||||||
|
<script type="text/javascript" src="{{ STATIC_URL }}merlin/js/merlin.filters.js"></script>
|
||||||
|
<script type="text/javascript" src="{{ STATIC_URL }}merlin/js/merlin.directives.js"></script>
|
||||||
|
<script type="text/javascript" src="{{ STATIC_URL }}merlin/js/merlin.field.models.js"></script>
|
||||||
|
<script type="text/javascript" src="{{ STATIC_URL }}merlin/js/merlin.panel.models.js"></script>
|
||||||
|
<script type="text/javascript" src="{{ STATIC_URL }}merlin/js/merlin.utils.js"></script>
|
||||||
|
{% block merlin-js %}{% endblock %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block css %}
|
||||||
|
{% include "_stylesheets.html" %}
|
||||||
|
{% compress css %}
|
||||||
|
<link href='{{ STATIC_URL }}merlin/libs/flexboxgrid/dist/flexboxgrid.css' type='text/css' media='screen' rel='stylesheet' />
|
||||||
|
<link href='{{ STATIC_URL }}merlin/scss/merlin.scss' type='text/scss' media='screen' rel='stylesheet' />
|
||||||
|
{% endcompress %}
|
||||||
|
{% block merlin-css %}{% endblock %}
|
||||||
|
{% endblock %}
|
@ -44,6 +44,6 @@
|
|||||||
"postinstall": "bower install",
|
"postinstall": "bower install",
|
||||||
"test-unit": "grunt test:unit",
|
"test-unit": "grunt test:unit",
|
||||||
"test": "karma start ./karma-unit.conf.js",
|
"test": "karma start ./karma-unit.conf.js",
|
||||||
"lint": "eslint --no-color ./merlin/static ./extensions/mistral/static"
|
"lint": "eslint --no-color ./merlin/static ./extensions/mistral/static ./extensions/hotbuilder/static"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user