mirror of
https://github.com/mkschreder/juci.git
synced 2025-01-09 04:19:29 +08:00
Latest parental control implementation
This commit is contained in:
parent
2f575f92fa
commit
01df45a0eb
10
juci-dev-upload
Executable file
10
juci-dev-upload
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
ROUTER="$1"
|
||||
|
||||
set -e
|
||||
|
||||
make clean && make DEFAULT_THEME=y
|
||||
scp ~/.ssh/id_rsa.pub "root@$ROUTER:/etc/dropbear/authorized_keys"
|
||||
scp -r htdocs/* root@$ROUTER:/www/
|
||||
scp -r menu.d/* root@$ROUTER:/usr/share/rpcd/menu.d/
|
@ -54,14 +54,15 @@ var rpc_calls = {
|
||||
};
|
||||
|
||||
var spawn = require('child_process').spawn;
|
||||
|
||||
|
||||
/*
|
||||
setTimeout(function recompile(){
|
||||
spawn('make', ["debug", "DEFAULT_THEME=y"], { customFds: [0,1,2] })
|
||||
.on("exit", function(code){
|
||||
console.log("Recompiled gui, code: "+code);
|
||||
setTimeout(recompile, 5000);
|
||||
});
|
||||
}, 0);
|
||||
}, 0); */
|
||||
|
||||
/**
|
||||
* Real keep-alive HTTP agent
|
||||
|
@ -26,5 +26,10 @@
|
||||
"modes": [ "expert" ],
|
||||
"acls": [ "hostnames" ],
|
||||
"index": 50
|
||||
},
|
||||
"internet/parental_control": {
|
||||
"title": "Parental Control",
|
||||
"acls": [ "firewall" ],
|
||||
"index": 60
|
||||
}
|
||||
}
|
||||
|
@ -122,9 +122,11 @@ UCI.firewall.$registerSectionType("dmz", {
|
||||
"host": { dvalue: "", type: String } // TODO: change to ip address
|
||||
});
|
||||
UCI.firewall.$registerSectionType("rule", {
|
||||
"type": { dvalue: "generic", type: String },
|
||||
"name": { dvalue: "", type: String },
|
||||
"src": { dvalue: "lan", type: String },
|
||||
"src_ip": { dvalue: "", type: String }, // needs to be extended type of ip address/mask
|
||||
"src_mac": { dvalue: [], type: Array },
|
||||
"src_port": { dvalue: 0, type: Number },
|
||||
"proto": { dvalue: "tcp", type: String },
|
||||
"dest": { dvalue: "*", type: String },
|
||||
@ -135,9 +137,19 @@ UCI.firewall.$registerSectionType("rule", {
|
||||
"icmp_type": { dvalue: [], type: Array },
|
||||
"enabled": { dvalue: true, type: Boolean },
|
||||
"hidden": { dvalue: true, type: Boolean },
|
||||
"limit": { dvalue: "", type: String }
|
||||
"limit": { dvalue: "", type: String },
|
||||
// scheduling
|
||||
"weekdays": { dvalue: "", type: String },
|
||||
"start_time": { dvalue: "", type: String },
|
||||
"stop_time": { dvalue: "", type: String },
|
||||
});
|
||||
UCI.firewall.$registerSectionType("settings", {
|
||||
"disabled": { dvalue: false, type: Boolean },
|
||||
"ping_wan": { dvalue: false, type: Boolean }
|
||||
});
|
||||
UCI.firewall.$registerSectionType("urlblock", {
|
||||
"enabled": { dvalue: false, type: Boolean },
|
||||
"url": { dvalue: [], type: Array },
|
||||
"src_mac": { dvalue: [], type: Array },
|
||||
});
|
||||
|
||||
|
80
juci-mod-network/src/pages/internet.parental_control.html
Normal file
80
juci-mod-network/src/pages/internet.parental_control.html
Normal file
@ -0,0 +1,80 @@
|
||||
<juci-layout-with-sidebar>
|
||||
<div ng-controller="InternetParentalControlPage">
|
||||
<h2 translate>Parental Control</h2>
|
||||
<p translate>internet.parental.control.info</p>
|
||||
<juci-config-section>
|
||||
<h2 translate>URL Blocking Function</h2>
|
||||
<juci-config-lines>
|
||||
<juci-config-line title="{{'URL Blocking'|translate}}">
|
||||
<switch ng-model="firewall.urlblock.enabled.value" class="green"></switch>
|
||||
</juci-config-line>
|
||||
</juci-config-lines>
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
<div class="row" ng-repeat="r in urlList track by $index">
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" ng-model="r.url" placeholder="{{'URL'|translate}}"/>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<button class="btn btn-default" ng-click="onDeleteURL(r.url)"><i class="fa fa-trash-o"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-10"/>
|
||||
<div class="col-sm-2">
|
||||
<button class="btn btn-default" ng-click="onAddURL()"><i class="fa fa-plus"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<div class="row" ng-repeat="r in macList track by $index">
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" ng-model="r.mac" placeholder="{{'URL'|translate}}"/>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<button class="btn btn-default" ng-click="onDeleteMAC(r.mac)"><i class="fa fa-trash-o"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-10">
|
||||
<juci-select ng-model="selectedMAC" ng-items="connectedHosts" placeholder="{{'Select Existing Host'|translate}}" on-change="onSelectExistingMAC($value)"/>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<button class="btn btn-default" ng-click="onAddMAC()"><i class="fa fa-plus"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</juci-config-section>
|
||||
<juci-config-section>
|
||||
<h2 translate>Internet Access Scheduling</h2>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th translate>Weekdays</th>
|
||||
<th translate>Start Time</th>
|
||||
<th translate>Stop Time</th>
|
||||
<th translate>MAC Addresses</th>
|
||||
<th></th>
|
||||
</thead>
|
||||
<tbody >
|
||||
<tr ng-repeat="r in accessRules">
|
||||
<td>{{r.weekdays.value}}</td>
|
||||
<td>{{r.start_time.value}}</td>
|
||||
<td>{{r.stop_time.value}}</td>
|
||||
<td><ul><li ng-repeat="mac in r.src_mac.value">{{mac}}</li></ul></td>
|
||||
<td style="width: 1%"><button class="btn btn-default" ng-click="onDeleteAccessRule(r)"><i class="fa fa-trash-o"></i></button></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3"></td>
|
||||
<td style="width: 1%"><button class="btn btn-default" ng-click="onAddAccessRule()"><i class="fa fa-plus"></i></button></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</juci-config-section>
|
||||
<juci-config-apply></juci-config-apply>
|
||||
<modal title="Add / Edit MAC Filter Scheduling" ng-show="rule" on-accept="onAcceptEdit()" on-dismiss="onCancelEdit()" dismiss-label="Cancel" accept-label="Save">
|
||||
<uci-firewall-nat-rule-edit ng-model="rule"></uci-firewall-nat-rule-edit>
|
||||
<div class="alert alert-danger" ng-show="errors && errors.length"><ul><li ng-repeat="e in errors track by $index">{{e|translate}}</li></ul></div>
|
||||
</modal>
|
||||
</div>
|
||||
</juci-layout-with-sidebar>
|
111
juci-mod-network/src/pages/internet.parental_control.js
Normal file
111
juci-mod-network/src/pages/internet.parental_control.js
Normal file
@ -0,0 +1,111 @@
|
||||
JUCI.app
|
||||
.controller("InternetParentalControlPage", function($scope, $uci, $rpc){
|
||||
function reload(){
|
||||
$uci.sync("firewall").done(function(){
|
||||
$scope.rules = $uci.firewall["@rule"];
|
||||
$scope.$apply();
|
||||
});
|
||||
} reload();
|
||||
|
||||
$scope.urlList = [];
|
||||
$scope.macList = [];
|
||||
$scope.connectedHosts = [];
|
||||
|
||||
$rpc.router.clients().done(function(clients){
|
||||
$scope.connectedHosts = Object.keys(clients).filter(function(x){
|
||||
// use only connected hosts
|
||||
return clients[x].connected;
|
||||
}).map(function(k){
|
||||
return { label: clients[k].hostname+" ("+clients[k].ipaddr+")", value: clients[k].macaddr };
|
||||
});
|
||||
$scope.$apply();
|
||||
});
|
||||
|
||||
$uci.sync("firewall").done(function(){
|
||||
$scope.urlblock = $uci.firewall.urlblock;
|
||||
$scope.urlblock.url.value.map(function(x){ $scope.urlList.push({url: x}); });
|
||||
$scope.urlblock.src_mac.value.map(function(x){ $scope.macList.push({mac: x}); });
|
||||
|
||||
$scope.accessRules = $uci.firewall["@rule"].filter(function(rule){
|
||||
return rule.type.value == "internet_access";
|
||||
});
|
||||
|
||||
$scope.onAddURL = function(){
|
||||
$scope.urlList.push({url: ""});
|
||||
}
|
||||
$scope.onDeleteURL = function(url){
|
||||
$scope.urlList = $scope.urlList.filter(function(x){
|
||||
return x.url != url;
|
||||
});
|
||||
}
|
||||
$scope.onAddMAC = function(){
|
||||
$scope.macList.push({mac: ""});
|
||||
}
|
||||
$scope.onDeleteMAC = function(mac){
|
||||
$scope.macList = $scope.macList.filter(function(x){
|
||||
return x.mac != mac;
|
||||
});
|
||||
}
|
||||
$scope.$watch("urlList", function(){
|
||||
$scope.urlblock.url.value = $scope.urlList.map(function(k){
|
||||
return k.url;
|
||||
});
|
||||
}, true);
|
||||
$scope.$watch("macList", function(){
|
||||
$scope.urlblock.src_mac.value = $scope.macList.map(function(k){
|
||||
return k.mac;
|
||||
});
|
||||
}, true);
|
||||
|
||||
$scope.onSelectExistingMAC = function(value){
|
||||
$scope.macList.push({mac: value});
|
||||
$scope.selectedMAC = "";
|
||||
}
|
||||
|
||||
$scope.$apply();
|
||||
});
|
||||
/*
|
||||
$scope.onAddRule = function(net){
|
||||
$uci.firewall.create({
|
||||
".type": "rule",
|
||||
"src": "wan",
|
||||
"dest": "lan",
|
||||
"target": "DNAT"
|
||||
}).done(function(section){
|
||||
$scope.rule = section;
|
||||
$scope.rule[".new"] = true;
|
||||
//$scope.rule[".edit"] = true;
|
||||
$scope.$apply();
|
||||
});
|
||||
};
|
||||
|
||||
$scope.onEditRule = function(rule){
|
||||
$scope.rule = rule;
|
||||
//$scope.rule[".edit"] = true;
|
||||
console.log($scope.rule[".name"]);
|
||||
console.log(Object.keys($scope.redirects).map(function(k) { return $scope.redirects[k][".name"]; }));
|
||||
};
|
||||
|
||||
$scope.onDeleteRule = function(rule){
|
||||
rule.$delete().done(function(){
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
$scope.onAcceptEdit = function(){
|
||||
$scope.errors = $scope.rule.$getErrors();
|
||||
if($scope.errors.length) return;
|
||||
$scope.rule = null;
|
||||
};
|
||||
|
||||
$scope.onCancelEdit = function(){
|
||||
if($scope.rule[".new"]){
|
||||
$scope.rule.$delete().done(function(){
|
||||
$scope.rule = null;
|
||||
$scope.$apply();
|
||||
});
|
||||
} else {
|
||||
$scope.rule = null;
|
||||
}
|
||||
}*/
|
||||
});
|
42
juci-mod-network/src/widgets/uci.firewall.rule.edit.html
Normal file
42
juci-mod-network/src/widgets/uci.firewall.rule.edit.html
Normal file
@ -0,0 +1,42 @@
|
||||
<div class="form-horizontal" >
|
||||
<div class="form-group">
|
||||
<label for="device" class="control-label col-xs-4" translate>Device</label>
|
||||
<div class="col-xs-8" id="device">
|
||||
<juci-select ng-model="ngModel.dest_ip.value" ng-items="deviceChoices" placeholder="Select connected device"></juci-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="ipAddress" class="control-label col-xs-4" translate>Local IP Address</label>
|
||||
<div class="col-xs-8">
|
||||
<input id="ipAddress" type="text" class="form-control" ng-model="ngModel.dest_ip.value" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="protocol" class="control-label col-xs-4" translate>Protocol</label>
|
||||
<div class="col-xs-8" id="protocol">
|
||||
<juci-select ng-model="ngModel.proto.value" ng-items="protocolChoices" placeholder="Select protocol"></juci-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="range" class="control-label col-xs-4">Type</label>
|
||||
<div class="col-xs-8" id="range">
|
||||
<div class="btn-group">
|
||||
<button ng-repeat="item in [[false,'Port'], [true, 'Port range']]" class="btn btn-default" ng-model="portIsRange" btn-radio="item[0]" ng-click="onPortRangeClick(item[0])">{{item[1]}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" >
|
||||
<label for="range" class="control-label col-xs-4" ng-show="!portIsRange" translate>Public port</label>
|
||||
<label for="range" class="control-label col-xs-4" ng-show="portIsRange" translate>Public port range</label>
|
||||
<div class="col-xs-8" ng-class="{'field-error': ngModel.src_dport.error}" >
|
||||
<juci-input-port ng-model="ngModel.src_dport.value" port-range="portIsRange"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" >
|
||||
<label for="range" class="control-label col-xs-4" ng-show="!portIsRange" translate>Private port</label>
|
||||
<label for="range" class="control-label col-xs-4" ng-show="portIsRange" translate>Private port range</label>
|
||||
<div class="col-xs-8" ng-class="{'field-error': ngModel.dest_port.error}" >
|
||||
<juci-input-port ng-model="ngModel.dest_port.value" port-range="portIsRange"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
43
juci-mod-network/src/widgets/uci.firewall.rule.edit.js
Normal file
43
juci-mod-network/src/widgets/uci.firewall.rule.edit.js
Normal file
@ -0,0 +1,43 @@
|
||||
JUCI.app
|
||||
.directive("uciFirewallRuleEdit", function($compile, $parse){
|
||||
return {
|
||||
templateUrl: plugin_root+"/widgets/uci.firewall.rule.edit.html",
|
||||
scope: {
|
||||
ngModel: "=ngModel"
|
||||
},
|
||||
controller: "uciFirewallRuleEdit",
|
||||
replace: true
|
||||
};
|
||||
}).controller("uciFirewallRuleEdit", function($scope, $uci, $rpc, $log){
|
||||
$scope.$watch("ngModel", function(value){
|
||||
if(!value) return;
|
||||
var ngModel = value;
|
||||
if(ngModel && ngModel.src_dport && ngModel.dest_port && ngModel.src_dport.value && ngModel.dest_port.value){
|
||||
|
||||
$scope.portIsRange = (ngModel.src_dport.value.indexOf("-") != -1) || (ngModel.dest_port.value.indexOf("-") != -1);
|
||||
}
|
||||
});
|
||||
$scope.protocolChoices = [
|
||||
{ label: "UDP", value: "udp"},
|
||||
{ label: "TCP", value: "tcp"},
|
||||
{ label: "TCP + UDP", value: "tcpudp" }
|
||||
];
|
||||
$scope.deviceChoices = [];
|
||||
$rpc.router.clients().done(function(clients){
|
||||
var choices = [];
|
||||
Object.keys(clients).map(function(x) {
|
||||
var c = clients[x];
|
||||
if(c.connected){
|
||||
choices.push({
|
||||
label: (c.hostname && c.hostname.length)?c.hostname:c.ipaddr,
|
||||
value: c.ipaddr
|
||||
});
|
||||
}
|
||||
});
|
||||
$scope.deviceChoices = choices;
|
||||
$scope.$apply();
|
||||
});
|
||||
$scope.onPortRangeClick = function(value){
|
||||
$scope.portIsRange = value;
|
||||
}
|
||||
});
|
@ -47,8 +47,8 @@
|
||||
<juci-config-line title="{{'Pick configuration backup to upload'|translate}}">
|
||||
<input type="file" class="btn btn-default btn-file" name="filedata" />
|
||||
</juci-config-line>
|
||||
<juci-config-line title="{{'Backup file password (if encrypted)'|translate}}">
|
||||
<input type="password" class="form-control" name="password" ng-model="restore.password" />
|
||||
<juci-config-line title="{{'Backup file password'|translate}}">
|
||||
<input type="password" class="form-control" name="password" ng-model="restore.password" placeholder="{{'Password (if encrypted)'|translate}}"/>
|
||||
</juci-config-line>
|
||||
<!--<juci-config-line title="{{'Start upgrade'|translate}}">
|
||||
<input type="submit" class="btn btn-lg btn-default" value="{{'Upgrade'|translate}}"/>
|
||||
|
@ -49,6 +49,9 @@
|
||||
</juci-config-line>
|
||||
</juci-config-lines>
|
||||
</juci-config-section>
|
||||
<modal title="Do you want to keep your configuration?" ng-show="showConfirm" on-accept="onConfirmKeep()" on-dismiss="onConfirmWipe()" accept-label="Yes" dismiss-label="No">
|
||||
<p translate>If you answer yes then your confiruation will be saved before the upgrade and restored after the upgrade has completed. If you choose 'no' then all your current confiration will be reset to defaults.</p>
|
||||
</modal>
|
||||
<modal title="Firmware Upgrade" ng-show="showUpgradeStatus">
|
||||
<center>
|
||||
<p style="text-align: center;" ng-show="!error">{{message}}</p>
|
||||
|
@ -117,7 +117,25 @@ JUCI.app
|
||||
|
||||
$scope.config = $config;
|
||||
|
||||
function upgradeStart(path){
|
||||
function confirmKeep(){
|
||||
var deferred = $.Deferred();
|
||||
|
||||
$scope.onConfirmKeep = function(){
|
||||
$scope.showConfirm = 0;
|
||||
deferred.resolve(true);
|
||||
}
|
||||
$scope.onConfirmWipe = function(){
|
||||
$scope.showConfirm = 0;
|
||||
deferred.resolve(false);
|
||||
}
|
||||
|
||||
$scope.showConfirm = 1;
|
||||
setTimeout(function(){ $scope.$apply(); }, 0);
|
||||
|
||||
return deferred.promise();
|
||||
}
|
||||
|
||||
function upgradeStart(path, keep_configs){
|
||||
$scope.showUpgradeStatus = 1;
|
||||
$scope.error = null;
|
||||
$scope.message = gettext("Verifying firmware image")+"...";
|
||||
@ -125,8 +143,8 @@ JUCI.app
|
||||
setTimeout(function(){ $scope.$apply(); }, 0);
|
||||
|
||||
console.log("Trying to upgrade from "+path);
|
||||
|
||||
$rpc.juci.system.upgrade_start({"path": path}).done(function(result){
|
||||
|
||||
$rpc.juci.system.upgrade_start({"path": path, "keep": ((keep_configs)?1:0)}).done(function(result){
|
||||
// this will actually never succeed because server will be killed
|
||||
console.error("upgrade_start returned success, which means that it actually probably failed but did not return an error");
|
||||
$scope.error = (result.stdout||"") + (result.stderr||"");
|
||||
@ -172,7 +190,9 @@ JUCI.app
|
||||
});
|
||||
}
|
||||
$scope.onUpgradeOnline = function(){
|
||||
upgradeStart($scope.onlineUpgrade);
|
||||
confirmKeep().done(function(keep){
|
||||
upgradeStart($scope.onlineUpgrade, keep);
|
||||
});
|
||||
}
|
||||
|
||||
$scope.onCheckUSB = function(){
|
||||
@ -191,7 +211,9 @@ JUCI.app
|
||||
});
|
||||
}
|
||||
$scope.onUpgradeUSB = function(){
|
||||
upgradeStart($scope.usbUpgrade);
|
||||
confirmKeep().done(function(keep){
|
||||
upgradeStart($scope.usbUpgrade, keep);
|
||||
});
|
||||
}
|
||||
|
||||
$scope.onCheckUSB();
|
||||
@ -200,8 +222,8 @@ JUCI.app
|
||||
$scope.onUploadComplete = function(result){
|
||||
console.log("Upload completed: "+JSON.stringify(result));
|
||||
}
|
||||
$scope.onUploadUpgrade = function(){
|
||||
$scope.showUpgradeStatus = 1;
|
||||
$scope.onUploadUpgrade = function(keep_configs){
|
||||
//$scope.showUpgradeStatus = 1;
|
||||
$scope.message = "Uploading...";
|
||||
$scope.progress = 'uploading';
|
||||
$("#postiframe").bind("load", function(){
|
||||
@ -216,8 +238,14 @@ JUCI.app
|
||||
//return;
|
||||
}
|
||||
|
||||
upgradeStart($scope.uploadFilename);
|
||||
$scope.showUpgradeStatus = 0;
|
||||
$scope.$apply();
|
||||
|
||||
confirmKeep().done(function(keep){
|
||||
$scope.showUpgradeStatus = 1;
|
||||
//$scope.$apply();
|
||||
upgradeStart($scope.uploadFilename, keep);
|
||||
});
|
||||
$(this).unbind("load");
|
||||
});
|
||||
$("form[name='uploadForm']").submit();
|
||||
|
@ -9,7 +9,7 @@
|
||||
<juci-config-line title="Outgoing Number Blocking">
|
||||
<switch ng-model="filter.block_outgoing.value"></switch>
|
||||
</juci-config-line>
|
||||
<juci-config-lines>
|
||||
</juci-config-lines>
|
||||
<juci-config-lines ng-show="filter.block_outgoing.value">
|
||||
<hr/>
|
||||
<juci-config-line title="Do not allow connections to these numbers">
|
||||
@ -35,7 +35,7 @@
|
||||
<juci-config-line title="Block connections to all special rate numbers">
|
||||
<switch ng-model="filter.block_special_rate.value"></switch>
|
||||
</juci-config-line>
|
||||
<juci-config-lines>
|
||||
</juci-config-lines>
|
||||
</juci-config-section>
|
||||
<juci-config-section>
|
||||
<h2 translate>Incoming Calls</h2>
|
||||
@ -43,7 +43,7 @@
|
||||
<juci-config-line title="Incoming Number Blocking">
|
||||
<switch ng-model="filter.block_incoming.value"></switch>
|
||||
</juci-config-line>
|
||||
<juci-config-lines>
|
||||
</juci-config-lines>
|
||||
<juci-config-lines ng-show="filter.block_incoming.value">
|
||||
<juci-config-line title="Do not allow connections from these numbers">
|
||||
<div class="row" ng-repeat="rule in incomingRules">
|
||||
@ -58,7 +58,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</juci-config-line>
|
||||
<juci-config-lines>
|
||||
</juci-config-lines>
|
||||
</juci-config-section>
|
||||
<juci-config-apply></juci-config-apply>
|
||||
</div>
|
||||
|
@ -26,8 +26,7 @@ div.logo {
|
||||
}
|
||||
|
||||
.overview-banner {
|
||||
background: url("../img/family_web.jpg") repeat scroll center center !important;
|
||||
width: 100%;
|
||||
background: url("../img/overview_header.jpg") repeat scroll top center !important;
|
||||
height: 400px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 200 KiB |
BIN
juci-theme-inteno/src/img/overview_header.jpg
Normal file
BIN
juci-theme-inteno/src/img/overview_header.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 430 KiB |
3740
juci/src/lib/js/angular-animate.min.js
vendored
3740
juci/src/lib/js/angular-animate.min.js
vendored
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,7 @@
|
||||
<h3 class="modal-title">{{title|translate}}</h3>
|
||||
</div>
|
||||
<div class="modal-body" ng-transclude></div>
|
||||
<div class="modal-footer">
|
||||
<div class="modal-footer" ng-hide="noFooter">
|
||||
<div class="btn-toolbar">
|
||||
<button class="btn btn-primary btn-lg" ng-show="acceptLabel" ng-click="onAccept()">{{acceptLabel}}</button>
|
||||
<button class="btn btn-default btn-lg" ng-show="dismissLabel" ng-click="onDismiss()">{{dismissLabel}}</button>
|
||||
|
@ -14,6 +14,7 @@ JUCI.app
|
||||
ngShow: "=",
|
||||
onAccept: "&",
|
||||
onDismiss: "&",
|
||||
noFooter: "@",
|
||||
title: "@",
|
||||
hideCloseBtn : "@"
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user