mirror of
https://github.com/openstf/stf
synced 2025-10-04 02:09:32 +02:00
Reverse port forwarding UI actually works now.
This commit is contained in:
parent
99864fb223
commit
cecf08a244
10 changed files with 158 additions and 134 deletions
|
@ -130,6 +130,7 @@ dbapi.saveDevice = function(serial, device) {
|
||||||
, statusChangedAt: r.now()
|
, statusChangedAt: r.now()
|
||||||
, createdAt: r.now()
|
, createdAt: r.now()
|
||||||
, lastHeartbeatAt: r.now()
|
, lastHeartbeatAt: r.now()
|
||||||
|
, reverseForwards: []
|
||||||
}
|
}
|
||||||
return db.run(r.table('devices').get(serial).update(data))
|
return db.run(r.table('devices').get(serial).update(data))
|
||||||
.then(function(stats) {
|
.then(function(stats) {
|
||||||
|
@ -230,6 +231,12 @@ dbapi.setDeviceRotation = function(serial, rotation) {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dbapi.setDeviceReverseForwards = function(serial, forwards) {
|
||||||
|
return db.run(r.table('devices').get(serial).update({
|
||||||
|
reverseForwards: forwards
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
dbapi.setDeviceChannel = function(serial, channel) {
|
dbapi.setDeviceChannel = function(serial, channel) {
|
||||||
return db.run(r.table('devices').get(serial).update({
|
return db.run(r.table('devices').get(serial).update({
|
||||||
channel: channel
|
channel: channel
|
||||||
|
|
|
@ -2,6 +2,7 @@ var net = require('net')
|
||||||
|
|
||||||
var Promise = require('bluebird')
|
var Promise = require('bluebird')
|
||||||
var syrup = require('syrup')
|
var syrup = require('syrup')
|
||||||
|
var _ = require('lodash')
|
||||||
|
|
||||||
var wire = require('../../../../wire')
|
var wire = require('../../../../wire')
|
||||||
var logger = require('../../../../util/logger')
|
var logger = require('../../../../util/logger')
|
||||||
|
@ -61,33 +62,37 @@ module.exports = syrup.serial()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin.createForward = function(port, to) {
|
plugin.createForward = function(id, forward) {
|
||||||
log.info(
|
log.info(
|
||||||
'Creating reverse port forward from ":%d" to "%s:%d"'
|
'Creating reverse port forward "%s" from ":%d" to "%s:%d"'
|
||||||
, port
|
, id
|
||||||
, to.host
|
, forward.devicePort
|
||||||
, to.port
|
, forward.targetHost
|
||||||
|
, forward.targetPort
|
||||||
)
|
)
|
||||||
return connectService(1)
|
return connectService(1)
|
||||||
.then(function(out) {
|
.then(function(out) {
|
||||||
var header = new Buffer(4)
|
var header = new Buffer(4)
|
||||||
header.writeUInt16LE(0, 0)
|
header.writeUInt16LE(0, 0)
|
||||||
header.writeUInt16LE(port, 2)
|
header.writeUInt16LE(forward.devicePort, 2)
|
||||||
out.write(header)
|
out.write(header)
|
||||||
return manager.add(port, out, to)
|
return manager.add(id, out, forward)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin.removeForward = function(port) {
|
plugin.removeForward = function(id) {
|
||||||
log.info('Removing reverse port forward ":%d"', port)
|
log.info('Removing reverse port forward "%s"', id)
|
||||||
manager.remove(port)
|
manager.remove(id)
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin.connect = function(options) {
|
plugin.connect = function(options) {
|
||||||
var resolver = Promise.defer()
|
var resolver = Promise.defer()
|
||||||
|
|
||||||
var conn = net.connect(options)
|
var conn = net.connect({
|
||||||
|
host: options.targetHost
|
||||||
|
, port: options.targetPort
|
||||||
|
})
|
||||||
|
|
||||||
function connectListener() {
|
function connectListener() {
|
||||||
resolver.resolve(conn)
|
resolver.resolve(conn)
|
||||||
|
@ -112,44 +117,29 @@ module.exports = syrup.serial()
|
||||||
|
|
||||||
group.on('leave', plugin.reset)
|
group.on('leave', plugin.reset)
|
||||||
|
|
||||||
manager.on('add', function(port, to) {
|
var pushForwards = _.debounce(
|
||||||
push.send([
|
function() {
|
||||||
wireutil.global
|
push.send([
|
||||||
, wireutil.envelope(new wire.DeviceForwardAddEvent(
|
wireutil.global
|
||||||
options.serial
|
, wireutil.envelope(new wire.ReverseForwardsEvent(
|
||||||
, port
|
options.serial
|
||||||
, to.host
|
, manager.listAll()
|
||||||
, to.port
|
))
|
||||||
))
|
])
|
||||||
])
|
}
|
||||||
})
|
, 200
|
||||||
|
)
|
||||||
|
|
||||||
manager.on('remove', function(port) {
|
manager.on('add', pushForwards)
|
||||||
push.send([
|
manager.on('remove', pushForwards)
|
||||||
wireutil.global
|
|
||||||
, wireutil.envelope(new wire.DeviceForwardRemoveEvent(
|
|
||||||
options.serial
|
|
||||||
, port
|
|
||||||
))
|
|
||||||
])
|
|
||||||
})
|
|
||||||
|
|
||||||
return startService()
|
return startService()
|
||||||
.then(awaitServer)
|
.then(awaitServer)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
|
|
||||||
plugin.createForward(3000, {
|
|
||||||
host: '127.0.0.1'
|
|
||||||
, port: 3000
|
|
||||||
})
|
|
||||||
|
|
||||||
router
|
router
|
||||||
.on(wire.ForwardTestMessage, function(channel, message) {
|
.on(wire.ForwardTestMessage, function(channel, message) {
|
||||||
var reply = wireutil.reply(options.serial)
|
var reply = wireutil.reply(options.serial)
|
||||||
plugin.connect({
|
plugin.connect(message)
|
||||||
host: message.targetHost
|
|
||||||
, port: message.targetPort
|
|
||||||
})
|
|
||||||
.then(function(conn) {
|
.then(function(conn) {
|
||||||
conn.end()
|
conn.end()
|
||||||
push.send([
|
push.send([
|
||||||
|
@ -166,10 +156,7 @@ module.exports = syrup.serial()
|
||||||
})
|
})
|
||||||
.on(wire.ForwardCreateMessage, function(channel, message) {
|
.on(wire.ForwardCreateMessage, function(channel, message) {
|
||||||
var reply = wireutil.reply(options.serial)
|
var reply = wireutil.reply(options.serial)
|
||||||
plugin.createForward(message.devicePort, {
|
plugin.createForward(message.id, message)
|
||||||
host: message.targetHost
|
|
||||||
, port: message.targetPort
|
|
||||||
})
|
|
||||||
.then(function() {
|
.then(function() {
|
||||||
push.send([
|
push.send([
|
||||||
channel
|
channel
|
||||||
|
@ -186,7 +173,7 @@ module.exports = syrup.serial()
|
||||||
})
|
})
|
||||||
.on(wire.ForwardRemoveMessage, function(channel, message) {
|
.on(wire.ForwardRemoveMessage, function(channel, message) {
|
||||||
var reply = wireutil.reply(options.serial)
|
var reply = wireutil.reply(options.serial)
|
||||||
plugin.removeForward(message.devicePort)
|
plugin.removeForward(message.id)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
push.send([
|
push.send([
|
||||||
channel
|
channel
|
||||||
|
|
|
@ -7,45 +7,51 @@ var ForwardWriter = require('./writer')
|
||||||
|
|
||||||
// Handles multiple ports
|
// Handles multiple ports
|
||||||
function ForwardManager() {
|
function ForwardManager() {
|
||||||
var handlersByPort = Object.create(null)
|
var handlersById = Object.create(null)
|
||||||
|
|
||||||
this.has = function(port) {
|
this.has = function(id) {
|
||||||
return !!handlersByPort[port]
|
return !!handlersById[id]
|
||||||
}
|
}
|
||||||
|
|
||||||
this.add = function(port, conn, to) {
|
this.add = function(id, conn, options) {
|
||||||
function endListener() {
|
function endListener() {
|
||||||
delete handlersByPort[port]
|
delete handlersById[id]
|
||||||
this.emit('remove', port, to)
|
this.emit('remove', id, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
var handler = new ForwardHandler(conn, to)
|
if (this.has(id)) {
|
||||||
|
this.remove(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
var handler = new ForwardHandler(conn, options)
|
||||||
handler.on('end', endListener.bind(this))
|
handler.on('end', endListener.bind(this))
|
||||||
|
|
||||||
handlersByPort[port] = handler
|
handlersById[id] = handler
|
||||||
|
|
||||||
this.emit('add', port, to)
|
this.emit('add', id, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.remove = function(port) {
|
this.remove = function(id) {
|
||||||
var handler = handlersByPort[port]
|
var handler = handlersById[id]
|
||||||
if (handler) {
|
if (handler) {
|
||||||
handler.end()
|
handler.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.removeAll = function() {
|
this.removeAll = function() {
|
||||||
Object.keys(handlersByPort).forEach(function(port) {
|
Object.keys(handlersById).forEach(function(id) {
|
||||||
handlersByPort[port].end()
|
handlersById[id].end()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
this.listAll = function() {
|
this.listAll = function() {
|
||||||
return Object.keys(handlersByPort).map(function(port) {
|
return Object.keys(handlersById).map(function(id) {
|
||||||
var handler = handlersByPort[port]
|
var handler = handlersById[id]
|
||||||
return {
|
return {
|
||||||
port: port
|
id: id
|
||||||
, to: handler.to
|
, devicePort: handler.options.devicePort
|
||||||
|
, targetHost: handler.options.targetHost
|
||||||
|
, targetPort: handler.options.targetPort
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -56,7 +62,7 @@ function ForwardManager() {
|
||||||
util.inherits(ForwardManager, events.EventEmitter)
|
util.inherits(ForwardManager, events.EventEmitter)
|
||||||
|
|
||||||
// Handles a single port
|
// Handles a single port
|
||||||
function ForwardHandler(conn, to) {
|
function ForwardHandler(conn, options) {
|
||||||
var destHandlersById = Object.create(null)
|
var destHandlersById = Object.create(null)
|
||||||
|
|
||||||
function endListener() {
|
function endListener() {
|
||||||
|
@ -73,7 +79,7 @@ function ForwardHandler(conn, to) {
|
||||||
if (packet) {
|
if (packet) {
|
||||||
if (!dest) {
|
if (!dest) {
|
||||||
// Let's create a new connection
|
// Let's create a new connection
|
||||||
dest = destHandlersById[id] = new DestHandler(id, conn, to)
|
dest = destHandlersById[id] = new DestHandler(id, conn, options)
|
||||||
dest.on('end', packetEndListener.bind(null, id))
|
dest.on('end', packetEndListener.bind(null, id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,11 +93,16 @@ function ForwardHandler(conn, to) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function readableListener() {
|
||||||
|
// No-op but must exist so that we get the 'end' event.
|
||||||
|
}
|
||||||
|
|
||||||
conn.pipe(new ForwardReader())
|
conn.pipe(new ForwardReader())
|
||||||
.on('end', endListener.bind(this))
|
.on('end', endListener.bind(this))
|
||||||
.on('packet', packetListener)
|
.on('packet', packetListener)
|
||||||
|
.on('readable', readableListener)
|
||||||
|
|
||||||
this.to = to
|
this.options = options
|
||||||
|
|
||||||
this.end = function() {
|
this.end = function() {
|
||||||
conn.end()
|
conn.end()
|
||||||
|
@ -103,7 +114,7 @@ function ForwardHandler(conn, to) {
|
||||||
util.inherits(ForwardHandler, events.EventEmitter)
|
util.inherits(ForwardHandler, events.EventEmitter)
|
||||||
|
|
||||||
// Handles a single connection
|
// Handles a single connection
|
||||||
function DestHandler(id, conn, to) {
|
function DestHandler(id, conn, options) {
|
||||||
function endListener() {
|
function endListener() {
|
||||||
conn.removeListener('drain', drainListener)
|
conn.removeListener('drain', drainListener)
|
||||||
this.emit('end')
|
this.emit('end')
|
||||||
|
@ -133,7 +144,10 @@ function DestHandler(id, conn, to) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var dest = net.connect(to)
|
var dest = net.connect({
|
||||||
|
host: options.targetHost
|
||||||
|
, port: options.targetPort
|
||||||
|
})
|
||||||
.on('error', errorListener)
|
.on('error', errorListener)
|
||||||
|
|
||||||
var writer = dest.pipe(new ForwardWriter(id))
|
var writer = dest.pipe(new ForwardWriter(id))
|
||||||
|
|
|
@ -154,6 +154,10 @@ module.exports = function(options) {
|
||||||
dbapi.setDeviceRotation(message.serial, message.rotation)
|
dbapi.setDeviceRotation(message.serial, message.rotation)
|
||||||
appDealer.send([channel, data])
|
appDealer.send([channel, data])
|
||||||
})
|
})
|
||||||
|
.on(wire.ReverseForwardsEvent, function(channel, message, data) {
|
||||||
|
dbapi.setDeviceReverseForwards(message.serial, message.forwards)
|
||||||
|
appDealer.send([channel, data])
|
||||||
|
})
|
||||||
.handler())
|
.handler())
|
||||||
|
|
||||||
lifecycle.observe(function() {
|
lifecycle.observe(function() {
|
||||||
|
|
|
@ -106,6 +106,7 @@ module.exports = function(options) {
|
||||||
, provider: message.provider
|
, provider: message.provider
|
||||||
, present: true
|
, present: true
|
||||||
, owner: null
|
, owner: null
|
||||||
|
, reverseForwards: []
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -240,6 +241,15 @@ module.exports = function(options) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
.on(wire.ReverseForwardsEvent, function(channel, message) {
|
||||||
|
socket.emit('device.change', {
|
||||||
|
important: false
|
||||||
|
, data: {
|
||||||
|
serial: message.serial
|
||||||
|
, reverseForwards: message.forwards
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
.handler()
|
.handler()
|
||||||
|
|
||||||
// Global messages
|
// Global messages
|
||||||
|
@ -676,7 +686,6 @@ module.exports = function(options) {
|
||||||
if (!data.targetHost || data.targetHost === 'localhost') {
|
if (!data.targetHost || data.targetHost === 'localhost') {
|
||||||
data.targetHost = socket.request.ip
|
data.targetHost = socket.request.ip
|
||||||
}
|
}
|
||||||
socket.emit('forward.create', data)
|
|
||||||
joinChannel(responseChannel)
|
joinChannel(responseChannel)
|
||||||
push.send([
|
push.send([
|
||||||
channel
|
channel
|
||||||
|
@ -687,7 +696,6 @@ module.exports = function(options) {
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
.on('forward.remove', function(channel, responseChannel, data) {
|
.on('forward.remove', function(channel, responseChannel, data) {
|
||||||
socket.emit('forward.remove', data)
|
|
||||||
joinChannel(responseChannel)
|
joinChannel(responseChannel)
|
||||||
push.send([
|
push.send([
|
||||||
channel
|
channel
|
||||||
|
|
|
@ -70,8 +70,7 @@ enum MessageType {
|
||||||
AccountGetMessage = 62;
|
AccountGetMessage = 62;
|
||||||
AccountRemoveMessage = 55;
|
AccountRemoveMessage = 55;
|
||||||
SdStatusMessage = 61;
|
SdStatusMessage = 61;
|
||||||
DeviceForwardAddEvent = 72;
|
ReverseForwardsEvent = 72;
|
||||||
DeviceForwardRemoveEvent = 73;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message Envelope {
|
message Envelope {
|
||||||
|
@ -399,25 +398,26 @@ message ForwardTestMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
message ForwardCreateMessage {
|
message ForwardCreateMessage {
|
||||||
required uint32 devicePort = 1;
|
required string id = 1;
|
||||||
required string targetHost = 2;
|
|
||||||
required uint32 targetPort = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ForwardRemoveMessage {
|
|
||||||
required uint32 devicePort = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message DeviceForwardAddEvent {
|
|
||||||
required string serial = 1;
|
|
||||||
required uint32 devicePort = 2;
|
required uint32 devicePort = 2;
|
||||||
required string targetHost = 3;
|
required string targetHost = 3;
|
||||||
required uint32 targetPort = 4;
|
required uint32 targetPort = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message DeviceForwardRemoveEvent {
|
message ForwardRemoveMessage {
|
||||||
required string serial = 1;
|
required string id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ReverseForward {
|
||||||
|
required string id = 1;
|
||||||
required uint32 devicePort = 2;
|
required uint32 devicePort = 2;
|
||||||
|
required string targetHost = 3;
|
||||||
|
required uint32 targetPort = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ReverseForwardsEvent {
|
||||||
|
required string serial = 1;
|
||||||
|
repeated ReverseForward forwards = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message BrowserOpenMessage {
|
message BrowserOpenMessage {
|
||||||
|
|
|
@ -172,7 +172,8 @@ module.exports = function ControlServiceFactory(
|
||||||
|
|
||||||
this.createForward = function(forward) {
|
this.createForward = function(forward) {
|
||||||
return sendTwoWay('forward.create', {
|
return sendTwoWay('forward.create', {
|
||||||
devicePort: forward.devicePort
|
id: forward.id
|
||||||
|
, devicePort: forward.devicePort
|
||||||
, targetHost: forward.targetHost
|
, targetHost: forward.targetHost
|
||||||
, targetPort: forward.targetPort
|
, targetPort: forward.targetPort
|
||||||
})
|
})
|
||||||
|
@ -180,7 +181,7 @@ module.exports = function ControlServiceFactory(
|
||||||
|
|
||||||
this.removeForward = function(forward) {
|
this.removeForward = function(forward) {
|
||||||
return sendTwoWay('forward.remove', {
|
return sendTwoWay('forward.remove', {
|
||||||
devicePort: forward.devicePort
|
id: forward.id
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,8 @@ require('./port-forwarding.css')
|
||||||
module.exports = angular.module('stf.port-forwarding', [
|
module.exports = angular.module('stf.port-forwarding', [
|
||||||
require('stf/common-ui/table').name,
|
require('stf/common-ui/table').name,
|
||||||
require('stf/settings').name,
|
require('stf/settings').name,
|
||||||
require('gettext').name,
|
require('gettext').name
|
||||||
require('angular-xeditable').name
|
|
||||||
])
|
])
|
||||||
.run(function (editableOptions) {
|
|
||||||
editableOptions.theme = 'bs3'
|
|
||||||
|
|
||||||
})
|
|
||||||
.run(["$templateCache", function ($templateCache) {
|
.run(["$templateCache", function ($templateCache) {
|
||||||
$templateCache.put(
|
$templateCache.put(
|
||||||
'control-panes/advanced/port-forwarding/port-forwarding.jade',
|
'control-panes/advanced/port-forwarding/port-forwarding.jade',
|
||||||
|
|
|
@ -1,42 +1,67 @@
|
||||||
var _ = require('lodash')
|
var uuid = require('node-uuid')
|
||||||
|
var Promise = require('bluebird')
|
||||||
|
|
||||||
module.exports = function PortForwardingCtrl($scope
|
module.exports = function PortForwardingCtrl(
|
||||||
, SettingsService) {
|
$scope
|
||||||
|
, SettingsService
|
||||||
var defaultPortForwards = {
|
) {
|
||||||
targetHost: 'localhost'
|
function defaults(id) {
|
||||||
|
return {
|
||||||
|
id: id
|
||||||
|
, targetHost: 'localhost'
|
||||||
, targetPort: 8080
|
, targetPort: 8080
|
||||||
, devicePort: 8080
|
, devicePort: 8080
|
||||||
, enabled: false
|
, enabled: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.reversePortForwards = [
|
$scope.reversePortForwards = [defaults('_default')]
|
||||||
defaultPortForwards
|
|
||||||
]
|
|
||||||
|
|
||||||
SettingsService.bind($scope, {
|
SettingsService.bind($scope, {
|
||||||
target: 'reversePortForwards'
|
target: 'reversePortForwards'
|
||||||
, source: 'reversePortForwards'
|
, source: 'reversePortForwards'
|
||||||
})
|
})
|
||||||
|
|
||||||
$scope.enableForward = function (forward) {
|
$scope.$watch('device.reverseForwards', function(newValue) {
|
||||||
forward.processing = true
|
var map = Object.create(null)
|
||||||
return $scope.control.createForward(forward)
|
|
||||||
.finally(function () {
|
if (newValue) {
|
||||||
forward.processing = false
|
newValue.forEach(function(forward) {
|
||||||
|
map[forward.id] = forward
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.reversePortForwards.forEach(function(forward) {
|
||||||
|
var deviceForward = map[forward.id]
|
||||||
|
forward.enabled = !!(deviceForward && deviceForward.id === forward.id &&
|
||||||
|
deviceForward.devicePort == forward.devicePort)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
$scope.applyForward = function (forward) {
|
||||||
|
return forward.enabled
|
||||||
|
? $scope.control.createForward(forward)
|
||||||
|
: $scope.control.removeForward(forward)
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.enableForward = function (forward) {
|
||||||
|
if (forward.enabled) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
return $scope.control.createForward(forward)
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.disableForward = function (forward) {
|
$scope.disableForward = function (forward) {
|
||||||
forward.processing = true
|
if (!forward.enabled) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
return $scope.control.removeForward(forward)
|
return $scope.control.removeForward(forward)
|
||||||
.finally(function () {
|
|
||||||
forward.processing = false
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.addRow = function () {
|
$scope.addRow = function () {
|
||||||
$scope.reversePortForwards.push(defaultPortForwards)
|
$scope.reversePortForwards.push(defaults(uuid.v4()))
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.removeRow = function (forward) {
|
$scope.removeRow = function (forward) {
|
||||||
|
@ -44,13 +69,4 @@ module.exports = function PortForwardingCtrl($scope
|
||||||
$scope.reversePortForwards.splice(
|
$scope.reversePortForwards.splice(
|
||||||
$scope.reversePortForwards.indexOf(forward), 1)
|
$scope.reversePortForwards.indexOf(forward), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.showApply = function () {
|
|
||||||
$scope.isShowApply = true
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.applyTable = function () {
|
|
||||||
console.log('TODO: Sync back the changes')
|
|
||||||
$scope.isShowApply = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
i.fa.fa-plus.fa-fw
|
i.fa.fa-plus.fa-fw
|
||||||
|
|
||||||
.widget-content.padded(collapse='isCollapsed')
|
.widget-content.padded(collapse='isCollapsed')
|
||||||
|
|
||||||
//form(editable-form, name='table')
|
//form(editable-form, name='table')
|
||||||
table.table.table-bordered.table-hover.table-condensed
|
table.table.table-bordered.table-hover.table-condensed
|
||||||
tr
|
tr
|
||||||
|
@ -38,24 +37,17 @@
|
||||||
td(width='35%')
|
td(width='35%')
|
||||||
div.input-group
|
div.input-group
|
||||||
span.input-group-addon
|
span.input-group-addon
|
||||||
input(type='checkbox', ng-model='forward.enabled')
|
input(type='checkbox', ng-model='forward.enabled', ng-change='applyForward(forward)')
|
||||||
input.form-control(type='number', min='0', ng-model='forward.devicePort', ng-model-options="{ updateOn: 'default blur' }", placeholder='{{"Port"|translate}}', ng-change='showApply()')
|
input.form-control(type='number', min='0', ng-model='forward.devicePort', ng-model-options="{ updateOn: 'default blur' }", placeholder='{{"Port"|translate}}', ng-change='disableForward(forward)')
|
||||||
td
|
td
|
||||||
i.fa.fa-arrow-right.fa-fw
|
i.fa.fa-arrow-right.fa-fw
|
||||||
td(width='40%')
|
td(width='40%')
|
||||||
input.form-control(type='text', ng-model='forward.targetHost', ng-model-options="{ updateOn: 'default blur' }", placeholder='{{"Hostname"|translate}}', ng-change='showApply()')
|
input.form-control(type='text', ng-model='forward.targetHost', ng-model-options="{ updateOn: 'default blur' }", placeholder='{{"Hostname"|translate}}', ng-change='disableForward(forward)')
|
||||||
td
|
td
|
||||||
span :
|
span :
|
||||||
td(width='25%')
|
td(width='25%')
|
||||||
input.form-control(type='number', min='0', ng-model='forward.targetPort', ng-model-options="{ updateOn: 'default blur' }", placeholder='{{"Port"|translate}}', ng-change='showApply()')
|
input.form-control(type='number', min='0', ng-model='forward.targetPort', ng-model-options="{ updateOn: 'default blur' }", placeholder='{{"Port"|translate}}', ng-change='disableForward(forward)')
|
||||||
td
|
td
|
||||||
button.btn.btn-sm.btn-danger-outline(ng-click='removeRow(forward)')
|
button.btn.btn-sm.btn-danger-outline(ng-click='removeRow(forward)')
|
||||||
i.fa.fa-trash-o
|
i.fa.fa-trash-o
|
||||||
//span(translate) Remove
|
//span(translate) Remove
|
||||||
|
|
||||||
div(ng-show='isShowApply')
|
|
||||||
button.btn.btn-sm.btn-primary-outline.pull-right(ng-click='applyTable()')
|
|
||||||
//i.fa.fa-trash-o
|
|
||||||
span(translate) Apply
|
|
||||||
br
|
|
||||||
br
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue