Add migrate function to virtual profile.

This commit is contained in:
FelisCatus 2014-10-27 21:16:57 +08:00
parent a66f604fae
commit 054be60531
22 changed files with 409 additions and 84 deletions

View File

@ -343,6 +343,21 @@
"options_virtualProfileTargetHelp": {
"message": "When this profile is applied, it acts exactly the same as the profile selected below."
},
"options_group_virtualProfileReplace": {
"message": "Migrate to Virtual Profile"
},
"options_virtualProfileReplace": {
"message": "Replace target profile"
},
"options_virtualProfileReplaceHelp": {
"message": "You can migrate existing options to use this virtual profile instead of $PROFILE$. Doing so will update all existing rules concerning $PROFILE$ and point them to this virtual profile, so that their result profile can be controlled here.",
"placeholders": {
"PROFILE": {
"content": "$1",
"example": "direct"
}
}
},
"options_group_ruleListConfig": {
"message": "Rule List Config"
},
@ -445,6 +460,41 @@
"options_profileNameHidden": {
"message": "Profiles with names starting with underscore will be hidden on the popup menu. However, they can still be used in places like switch profile results."
},
"options_modalHeader_replaceProfile": {
"message": "Replace Profile"
},
"options_replaceProfile": {
"message": "Replace Profile"
},
"options_replaceProfileConfirm": {
"message": "Do you really want to replace $FromProfile$ with $ToProfile$?",
"placeholders": {
"FromProfile": {
"content": "$1",
"example": "autoswitch"
},
"ToProfile": {
"content": "$2",
"example": "direct"
}
}
},
"options_replaceProfileHelp": {
"message": "If you proceed, all rules pointing to $FromProfile$ will be updated to use $ToProfile$ instead. Other options, such as startup profile and Quick Switch will also be modified as appropriate. However, the two profile themselves will NOT be changed or deleted.",
"placeholders": {
"FromProfile": {
"content": "$1",
"example": "autoswitch"
},
"ToProfile": {
"content": "$2",
"example": "direct"
}
}
},
"options_replaceProfileSuccess": {
"message": "Options updated."
},
"options_modalHeader_deleteProfile": {
"message": "Delete Profile"
},

View File

@ -334,15 +334,36 @@
"options_group_pacScript": {
"message": "PAC 脚本"
},
"options_group_virtualProfile": {
"message": "虚情景模式"
},
"options_virtualProfileTarget": {
"message": "目标"
},
"options_virtualProfileTargetHelp": {
"message": "当使用此情景模式时,相当于使用了以下情景模式:"
},
"options_group_virtualProfileReplace": {
"message": "迁移到虚情景模式"
},
"options_virtualProfileReplace": {
"message": "取代目标情景模式"
},
"options_virtualProfileReplaceHelp": {
"message": "通过此功能可以更改现有的选项,使用此虚情景模式来取代 $PROFILE$ 。此功能会把所有和 $PROFILE$ 相关的切换规则改为使用此虚情景模式。这样一来,就可以通过此虚情景模式来控制那些切换条件对应的结果。",
"placeholders": {
"PROFILE": {
"content": "$1",
"example": "direct"
}
}
},
"options_group_ruleListConfig": {
"message": "规则列表设置"
},
"options_ruleListFormat": {
"message": "规则列表格式"
},
"options_virtualProfileTargetHelp": {
"message": "当使用此情景模式时,相当于使用了以下情景模式:"
},
"options_group_ruleListResult": {
"message": "规则列表结果情景模式"
},
@ -439,6 +460,38 @@
"options_profileNameHidden": {
"message": "以下划线开头的情景模式不会在弹出菜单中显示,但仍可被用作切换的结果等。"
},
"options_modalHeader_replaceProfile": {
"message": "替换情景模式"
},
"options_replaceProfile": {
"message": "替换"
},
"options_replaceProfileConfirm": {
"message": "您确定要使用 $ToProfile 来代替 $FromProfile$ 吗?",
"placeholders": {
"FromProfile": {
"content": "$1",
"example": "autoswitch"
},
"ToProfile": {
"content": "$2",
"example": "direct"
}
}
},
"options_replaceProfileHelp": {
"message": "如果继续操作,则和 $FromProfile$ 有关的切换规则将改为使用 $ToProfile$ 来代替。此外,启动情景模式、快速切换等设置也会做相应调整。但请注意,此操作不影响这两个情景模式本身。",
"placeholders": {
"FromProfile": {
"content": "$1",
"example": "autoswitch"
},
"ToProfile": {
"content": "$2",
"example": "direct"
}
}
},
"options_modalHeader_deleteProfile": {
"message": "删除情景模式"
},

View File

@ -334,15 +334,36 @@
"options_group_pacScript": {
"message": "PAC 腳本"
},
"options_group_virtualProfile": {
"message": "虛情景模式"
},
"options_virtualProfileTarget": {
"message": "目標"
},
"options_virtualProfileTargetHelp": {
"message": "當使用此情景模式時,相當於使用了以下情景模式:"
},
"options_group_virtualProfileReplace": {
"message": "遷移到虛情景模式"
},
"options_virtualProfileReplace": {
"message": "取代目標情景模式"
},
"options_virtualProfileReplaceHelp": {
"message": "通過此功能可以更改現有的選項,使用此虛情景模式來取代 $PROFILE$ 。此功能會把所有和 $PROFILE$ 相關的切換規則改為使用此虛情景模式。這樣一來,就可以通過此虛情景模式來控制那些切換條件對應的結果。",
"placeholders": {
"PROFILE": {
"content": "$1",
"example": "direct"
}
}
},
"options_group_ruleListConfig": {
"message": "規則列表設置"
},
"options_ruleListFormat": {
"message": "規則列表格式"
},
"options_virtualProfileTargetHelp": {
"message": "當使用此情景模式時,相當於使用了以下情景模式:"
},
"options_group_ruleListResult": {
"message": "規則列表結果情景模式"
},
@ -439,6 +460,38 @@
"options_profileNameHidden": {
"message": "以下劃線開頭的情景模式不會在彈出菜單中顯示,但仍可被用作切換的結果等。"
},
"options_modalHeader_replaceProfile": {
"message": "替換情景模式"
},
"options_replaceProfile": {
"message": "替換"
},
"options_replaceProfileConfirm": {
"message": "您確定要使用 $ToProfile 來代替 $FromProfile$ 嗎?",
"placeholders": {
"FromProfile": {
"content": "$1",
"example": "autoswitch"
},
"ToProfile": {
"content": "$2",
"example": "direct"
}
}
},
"options_replaceProfileHelp": {
"message": "如果繼續操作,則和 $FromProfile$ 有關的切換規則將改為使用 $ToProfile$ 來代替。此外,啟動情景模式、快速切換等設定也會做相應調整。但請注意,此操作不影響這兩個情景模式本身。",
"placeholders": {
"FromProfile": {
"content": "$1",
"example": "autoswitch"
},
"ToProfile": {
"content": "$2",
"example": "direct"
}
}
},
"options_modalHeader_deleteProfile": {
"message": "刪除情景模式"
},

View File

@ -334,15 +334,36 @@
"options_group_pacScript": {
"message": "PAC 指令碼"
},
"options_group_virtualProfile": {
"message": "虛情景模式"
},
"options_virtualProfileTarget": {
"message": "目標"
},
"options_virtualProfileTargetHelp": {
"message": "當使用此情景模式時,相當於使用了以下情景模式:"
},
"options_group_virtualProfileReplace": {
"message": "遷移到虛情景模式"
},
"options_virtualProfileReplace": {
"message": "取代目標情景模式"
},
"options_virtualProfileReplaceHelp": {
"message": "通過此功能可以更改現有的選項,使用此虛情景模式來取代 $PROFILE$ 。此功能會把所有和 $PROFILE$ 相關的切換規則改為使用此虛情景模式。這樣一來,就可以通過此虛情景模式來控制那些切換條件對應的結果。",
"placeholders": {
"PROFILE": {
"content": "$1",
"example": "direct"
}
}
},
"options_group_ruleListConfig": {
"message": "規則列表設定"
},
"options_ruleListFormat": {
"message": "規則列表格式"
},
"options_virtualProfileTargetHelp": {
"message": "當使用此情景模式時,相當於使用了以下情景模式:"
},
"options_group_ruleListResult": {
"message": "規則列表結果情景模式"
},
@ -439,6 +460,38 @@
"options_profileNameHidden": {
"message": "以下劃線開頭的情景模式不會在彈出選單中顯示,但仍可被用作切換的結果等。"
},
"options_modalHeader_replaceProfile": {
"message": "替換情景模式"
},
"options_replaceProfile": {
"message": "替換"
},
"options_replaceProfileConfirm": {
"message": "您確定要使用 $ToProfile 來代替 $FromProfile$ 嗎?",
"placeholders": {
"FromProfile": {
"content": "$1",
"example": "autoswitch"
},
"ToProfile": {
"content": "$2",
"example": "direct"
}
}
},
"options_replaceProfileHelp": {
"message": "如果繼續操作,則和 $FromProfile$ 有關的切換規則將改為使用 $ToProfile$ 來代替。此外,啟動情景模式、快速切換等設定也會做相應調整。但請注意,此操作不影響這兩個情景模式本身。",
"placeholders": {
"FromProfile": {
"content": "$1",
"example": "autoswitch"
},
"ToProfile": {
"content": "$2",
"example": "direct"
}
}
},
"options_modalHeader_deleteProfile": {
"message": "刪除情景模式"
},

View File

@ -58,6 +58,8 @@ angular.module('omegaTarget', []).factory 'omegaTarget', ($q) ->
return args
renameProfile: (fromName, toName) ->
callBackground('renameProfile', fromName, toName).then omegaTarget.refresh
replaceRef: (fromName, toName) ->
callBackground('replaceRef', fromName, toName).then omegaTarget.refresh
optionsPatch: (patch) ->
callBackground('patch', patch).then omegaTarget.refresh
resetOptions: (opt) ->

View File

@ -462,25 +462,11 @@ class Options
fetchUrl: (url, opt_bypass_cache) ->
Promise.reject new Error('not implemented')
###*
# Rename a profile and update references and options
# @param {String} fromName The original profile name
# @param {String} toname The target profile name
# @returns {Promise<OmegaOptions>} The updated options
###
renameProfile: (fromName, toName) ->
@log.method('Options#renameProfile', this, arguments)
if OmegaPac.Profiles.byName(toName, @_options)
return Promise.reject new Error("Target name #{name} already taken!")
profile = OmegaPac.Profiles.byName(fromName, @_options)
if not profile
return Promise.reject new ProfileNotExistError(name)
profile.name = toName
changes = {}
changes[OmegaPac.Profiles.nameAsKey(profile)] = profile
_replaceRefChanges: (fromName, toName, changes) ->
changes ?= {}
OmegaPac.Profiles.each @_options, (key, p) ->
return if p.name == fromName or p.name == toName
if OmegaPac.Profiles.replaceRef(p, fromName, toName)
OmegaPac.Profiles.updateRevision(p)
changes[OmegaPac.Profiles.nameAsKey(p)] = p
@ -493,6 +479,51 @@ class Options
quickSwitch[i] = toName
changes['-quickSwitchProfiles'] = quickSwitch
return changes
###*
# Replace all references of profile fromName to toName.
# @param {String} fromName The original profile name
# @param {String} toname The target profile name
# @returns {Promise<OmegaOptions>} The updated options
###
replaceRef: (fromName, toName) ->
@log.method('Options#replaceRef', this, arguments)
profile = OmegaPac.Profiles.byName(fromName, @_options)
if not profile
return Promise.reject new ProfileNotExistError(fromName)
changes = @_replaceRefChanges(fromName, toName)
for own key, value of changes
@_options[key] = value
fromKey = OmegaPac.Profiles.nameAsKey(fromName)
if @_watchingProfiles[fromKey]
if @_currentProfileName == fromName
@_currentProfileName = toName
@applyProfile(@_currentProfileName)
@_setOptions(changes)
###*
# Rename a profile and update references and options
# @param {String} fromName The original profile name
# @param {String} toname The target profile name
# @returns {Promise<OmegaOptions>} The updated options
###
renameProfile: (fromName, toName) ->
@log.method('Options#renameProfile', this, arguments)
if OmegaPac.Profiles.byName(toName, @_options)
return Promise.reject new Error("Target name #{name} already taken!")
profile = OmegaPac.Profiles.byName(fromName, @_options)
if not profile
return Promise.reject new ProfileNotExistError(fromName)
profile.name = toName
changes = {}
changes[OmegaPac.Profiles.nameAsKey(profile)] = profile
@_replaceRefChanges(fromName, toName, changes)
for own key, value of changes
@_options[key] = value

View File

@ -25,13 +25,43 @@ angular.module('omegaDecoration', []).value('profileIcons', {
1
).directive('omegaProfileIcon', (profileIcons) ->
restrict: 'A'
templateUrl: 'partials/omega_profile_icon.html'
template: '''
<span ng-style="{color: color || profile.color}"
ng-class="{'virtual-profile-icon': profile.virtualType}"
class="glyphicon {{getIcon(profile)}}">
</span>
'''
scope:
'profile': '=?omegaProfileIcon'
'icon': '=?icon'
'color': '=?color'
link: (scope, element, attrs, ngModel) ->
scope.profileIcons = profileIcons
scope.getIcon = (profile) ->
(scope.icon || scope.profileIcons[profile.virtualType] ||
profileIcons[profile.profileType])
).directive('omegaProfileInline', ->
restrict: 'A'
template: '''
<span omega-profile-icon="profile"></span>
{{dispName ? dispName(profile) : profile.name}}
'''
scope:
'profile': '=omegaProfileInline'
'dispName': '=?dispName'
).directive('omegaHtml', ($compile) ->
restrict: 'A'
link: (scope, element, attrs, ngModel) ->
locals =
$profile: (profile = 'profile', dispName = 'dispNameFilter') ->
"""
<span class="profile-inline" omega-profile-inline="#{profile}"
disp-name="#{dispName}"></span>
"""
getHtml = -> scope.$eval(attrs.omegaHtml, locals)
scope.$watch getHtml, (html) ->
element.html(html)
$compile(element.contents())(scope)
).directive('omegaProfileSelect', ($timeout, profileIcons) ->
restrict: 'A'
templateUrl: 'partials/omega_profile_select.html'
@ -39,7 +69,7 @@ angular.module('omegaDecoration', []).value('profileIcons', {
scope:
'profiles': '&omegaProfileSelect'
'defaultText': '@?defaultText'
'dispName': '&?dispName'
'dispName': '=?dispName'
link: (scope, element, attrs, ngModel) ->
scope.profileIcons = profileIcons
scope.currentProfiles = []
@ -75,5 +105,5 @@ angular.module('omegaDecoration', []).value('profileIcons', {
scope.getName = (profile) ->
if profile
scope.dispName?({$profile: profile}) || profile?.name
scope.dispName(profile) || profile.name
)

View File

@ -3,10 +3,13 @@ module = angular.module('omegaPopup', ['omegaTarget', 'omegaDecoration',
module.filter 'tr', (omegaTarget) -> omegaTarget.getMessage
module.filter 'dispName', (omegaTarget) ->
(name) -> omegaTarget.getMessage('profile_' + name) || name
(name) ->
if typeof name == 'object'
name = name.name
omegaTarget.getMessage('profile_' + name) || name
module.controller 'PopupCtrl', ($scope, $window, $q, omegaTarget,
profileIcons, profileOrder) ->
profileIcons, profileOrder, dispNameFilter) ->
refreshOnProfileChange = false
refresh = ->
@ -16,6 +19,7 @@ module.controller 'PopupCtrl', ($scope, $window, $q, omegaTarget,
else
$window.close()
$scope.profileIcons = profileIcons
$scope.dispNameFilter = dispNameFilter
$scope.isActive = (profileName) ->
if $scope.isSystemProfile
profileName == 'system'

View File

@ -42,6 +42,12 @@ a[role="button"] {
margin: -1px;
}
.profile-inline {
background-color: #eee;
color: #333;
padding: 0 5px;
}
/* omega-profile-select */
.omega-profile-select {

View File

@ -15,11 +15,6 @@ body.with-condition-form {
min-width: 360px;
}
.profile-inline {
background-color: #eee;
padding: 0 5px;
}
.nav {
margin-bottom: 0;
}

View File

@ -1,24 +1,10 @@
angular.module('omega').controller 'MasterCtrl', ($scope, $rootScope, $window,
$modal, $state, builtinProfiles, profileColors, profileIcons, omegaTarget, $q,
$timeout, $location, $filter, getAttachedName, isProfileNameReserved,
isProfileNameHidden) ->
isProfileNameHidden, dispNameFilter) ->
tr = $filter('tr')
# This method allows watchers to change the value without recursively firing
# itself. Usage: $scope.omegaWatchAndChange
# coffeelint: disable=missing_fat_arrows
$rootScope.omegaWatchAndChange = (expression, listener, objectEquality) ->
scope = this
# coffeelint: enable=missing_fat_arrows
handler = (newValue, oldValue) ->
modified = listener(newValue, oldValue)
return if newValue == oldValue and newValue == modified
for watcher in scope.$$watchers
if watcher.exp == expression
watcher.last = modified
return scope.$watch(expression, handler, objectEquality)
$rootScope.options = null
omegaTarget.addOptionsChangeCallback (newOptions) ->
@ -128,6 +114,37 @@ angular.module('omega').controller 'MasterCtrl', ($scope, $rootScope, $window,
$rootScope.options[OmegaPac.Profiles.nameAsKey(profile)] = profile
$state.go('profile', {name: profile.name})
$rootScope.replaceProfile = (fromName, toName) ->
$rootScope.applyOptionsConfirm().then ->
scope = $rootScope.$new('isolate')
scope.options = $rootScope.options
scope.fromName = fromName
scope.toName = toName
scope.profileByName = $rootScope.profileByName
scope.dispNameFilter = dispNameFilter
scope.profileSelect = (model) ->
"""
<div omega-profile-select="options | profiles:profile"
ng-model="#{model}"
disp-name="dispNameFilter" style="display: inline-block;">
</div>
"""
$modal.open(
templateUrl: 'partials/replace_profile.html'
scope: scope
).result.then ({fromName, toName}) ->
omegaTarget.replaceRef(fromName, toName).then(->
$rootScope.showAlert(
type: 'success'
i18n: 'options_replaceProfileSuccess'
)
).catch (err) ->
$rootScope.showAlert(
type: 'error'
message: err
)
$rootScope.renameProfile = (fromName) ->
$rootScope.applyOptionsConfirm().then ->
profile = $rootScope.profileByName(fromName)
@ -228,6 +245,7 @@ angular.module('omega').controller 'MasterCtrl', ($scope, $rootScope, $window,
), false
$scope.profileIcons = profileIcons
$scope.dispNameFilter = dispNameFilter
for own type of OmegaPac.Profiles.formatByType
$scope.profileIcons[type] = $scope.profileIcons['RuleListProfile']

View File

@ -1,6 +1,6 @@
angular.module('omega').controller 'ProfileCtrl', ($scope, $stateParams,
$location, $rootScope, $state, $modal, profileColorPalette, getAttachedName,
getParentName) ->
$location, $rootScope, $timeout, $state, $modal, profileColorPalette,
getAttachedName, getParentName) ->
name = $stateParams.name
profileTemplates =
'FixedProfile': 'profile_fixed.html'
@ -83,9 +83,26 @@ angular.module('omega').controller 'ProfileCtrl', ($scope, $stateParams,
$scope.profileTemplate = 'partials/' + templ
$scope.scriptable = true
onProfileChange = (profile, oldProfile) ->
return profile if profile == oldProfile
$scope.watchAndUpdateRevision = (expression) ->
revisionChanged = false
onChange = (profile, oldProfile) ->
return profile if profile == oldProfile or not profile or not oldProfile
if revisionChanged and profile.revision != oldProfile.revision
revisionChanged = false
else
OmegaPac.Profiles.updateRevision(profile)
return profile
revisionChanged = true
$scope.$watch expression, onChange, true
$scope.omegaWatchAndChange 'profile', onProfileChange, true
onProfileChange = (profile, oldProfile) ->
return if profile == oldProfile
if profile.virtualType
target = $scope.profileByName(profile.defaultProfileName)
profile.color = target.color
profile.virtualType = target.profileType
OmegaPac.Profiles.each $scope.options, (key, p) ->
if p.virtualType and p.defaultProfileName == profile.name
onProfileChange(p, null)
$scope.watchAndUpdateRevision 'profile'
$scope.$watch 'profile', onProfileChange, true

View File

@ -154,11 +154,7 @@ angular.module('omega').controller 'SwitchProfileCtrl', ($scope, $location,
$scope.$watch 'options[attachedKey]', (attached) ->
$scope.attached = attached
onAttachedChange = (profile, oldProfile) ->
return profile if profile == oldProfile or not profile or not oldProfile
OmegaPac.Profiles.updateRevision(profile)
return profile
$scope.omegaWatchAndChange 'options[attachedKey]', onAttachedChange, true
$scope.watchAndUpdateRevision 'options[attachedKey]'
$scope.attachedOptions = {enabled: false}
$scope.$watch 'profile.defaultProfileName', (name) ->

View File

@ -1,9 +0,0 @@
angular.module('omega').controller 'VirtualProfileCtrl', ($scope, $location,
$modal, profileIcons, getAttachedName) ->
onProfileChange = (profile, oldProfile) ->
return if profile == oldProfile or not profile or not oldProfile
target = $scope.profileByName(profile.defaultProfileName)
profile.color = target.color
profile.virtualType = target.profileType
$scope.$watch 'profile', onProfileChange, true

View File

@ -23,4 +23,7 @@ angular.module('omega').filter 'profiles', (builtinProfiles, profileOrder,
angular.module('omega').filter 'tr', (omegaTarget) -> omegaTarget.getMessage
angular.module('omega').filter 'dispName', (omegaTarget) ->
(name) -> omegaTarget.getMessage('profile_' + name) || name
(name) ->
if typeof name == 'object'
name = name.name
omegaTarget.getMessage('profile_' + name) || name

View File

@ -1,2 +0,0 @@
span.glyphicon(class='{{icon || profileIcons[profile.virtualType] || profileIcons[profile.profileType]}}'
ng-style='{color: color || profile.color}' ng-class='{"virtual-profile-icon": profile.profileType == "VirtualProfile"}')

View File

@ -5,12 +5,12 @@ div(ng-controller='RuleListProfileCtrl')
label {{'options_ruleListMatchProfile' | tr}}
= ' '
div(omega-profile-select='options | profiles:profile' ng-model='profile.matchProfileName'
disp-name='$profile.name | dispName' style='display: inline-block;')
disp-name='dispNameFilter' style='display: inline-block;')
.form-group
label {{'options_ruleListDefaultProfile' | tr}}
= ' '
div(omega-profile-select='options | profiles:profile' ng-model='profile.defaultProfileName'
disp-name='$profile.name | dispName' style='display: inline-block;')
disp-name='dispNameFilter' style='display: inline-block;')
form.form-group
label {{'options_ruleListFormat' | tr}}
.radio.inline-form-control.no-min-width(ng-repeat='format in ruleListFormats')

View File

@ -52,7 +52,7 @@ div(ng-controller='SwitchProfileCtrl')
ui-validate='{pattern: "validateCondition(rule.condition, $value)"}')
td
div(omega-profile-select='options | profiles:profile' ng-model='rule.profileName'
disp-name='$profile.name | dispName' ng-class='{disabled: rule.condition.conditionType == "NeverCondition"}')
disp-name='dispNameFilter' ng-class='{disabled: rule.condition.conditionType == "NeverCondition"}')
td
button.btn.btn-danger.btn-sm(title="{{'options_deleteRule' | tr}}" ng-click='removeRule($index)')
span.glyphicon.glyphicon-trash
@ -80,7 +80,7 @@ div(ng-controller='SwitchProfileCtrl')
| {{'options_switchAttachedProfileInConditionDisabled' | tr}}
td
div(omega-profile-select='options | profiles:profile' ng-model='attached.matchProfileName'
disp-name='$profile.name | dispName' ng-class='{disabled: !attachedOptions.enabled}')
disp-name='dispNameFilter' ng-class='{disabled: !attachedOptions.enabled}')
td
button.btn.btn-danger.btn-sm(title="{{'options_deleteAttached' | tr}}" ng-click='removeAttached()')
span.glyphicon.glyphicon-trash
@ -90,7 +90,7 @@ div(ng-controller='SwitchProfileCtrl')
td(colspan='2') {{'options_switchDefaultProfile' | tr}}
td
div(omega-profile-select='options | profiles:profile' ng-model='defaultProfileName'
disp-name='$profile.name | dispName')
disp-name='dispNameFilter')
td
button.btn.btn-info.btn-sm(title="{{'options_resetRules_help' | tr}}" ng-click='resetRules()')
span.glyphicon.glyphicon-chevron-up

View File

@ -1,4 +1,4 @@
div(ng-controller='VirtualProfileCtrl')
div
section.settings-group
h3 {{'options_group_virtualProfile' | tr}}
p.help-block
@ -7,4 +7,12 @@ div(ng-controller='VirtualProfileCtrl')
label {{'options_virtualProfileTarget' | tr}}
= ' '
div(omega-profile-select='options | profiles:profile' ng-model='profile.defaultProfileName'
disp-name='$profile.name | dispName' style='display: inline-block;')
disp-name='dispNameFilter' style='display: inline-block;')
section.settings-group
h3 {{'options_group_virtualProfileReplace' | tr}}
p.help-block(omega-html='"options_virtualProfileReplaceHelp" | tr:[$profile("profileByName(profile.defaultProfileName)")]')
.form-group
button.btn.btn-default(ng-click='replaceProfile(profile.defaultProfileName, profile.name)')
span.glyphicon.glyphicon-search
= ' '
| {{'options_virtualProfileReplace' | tr}}

View File

@ -0,0 +1,17 @@
.modal-header
button.close(type='button' ng-click='$dismiss()')
span(aria-hidden='true') ×
span.sr-only {{'dialog_close' | tr}}
h4.modal-title {{'options_modalHeader_replaceProfile' | tr}}
.modal-body
p(omega-html='"options_replaceProfileConfirm" | tr:[profileSelect("fromName"), profileSelect("toName")]')
.well
span(omega-profile-inline='profileByName(fromName)')
= ' '
span.glyphicon.glyphicon-chevron-right
= ' '
span(omega-profile-inline='profileByName(toName)')
.help-block(omega-html="'options_replaceProfileHelp' | tr:[$profile('profileByName(fromName)'), $profile('profileByName(toName)')]")
.modal-footer
button.btn.btn-default(ng-click='$dismiss()') {{'dialog_cancel' | tr}}
button.btn.btn-warning(type='button' ng-click='$close({fromName: fromName, toName: toName})') {{'options_replaceProfile' | tr}}

View File

@ -16,7 +16,7 @@ section.settings-group
label {{'options_startupProfile' | tr}}
= ' '
div(omega-profile-select='options | profiles:"all"' ng-model='options["-startupProfileName"]'
default-text="{{'options_startupProfile_none' | tr}}" disp-name='$profile.name | dispName'
default-text="{{'options_startupProfile_none' | tr}}" disp-name='dispNameFilter'
style='display: inline-block;')
div.checkbox
label

View File

@ -123,7 +123,7 @@ html(lang='en' ng-app='omegaPopup' ng-controller='PopupCtrl' ng-csp)
div.form-group
label {{'options_resultProfile' | tr}}
div(omega-profile-select='validResultProfiles' ng-model='rule.profileName'
disp-name='$profile.name | dispName')
disp-name='dispNameFilter')
div.condition-controls
button.btn.btn-default(type='button' ng-click='showConditionForm = false')
| {{'dialog_cancel' | tr}}