Improve UI for reserved and hidden profiles. Fix #43.

Prevent users from creating reserved profiles.
Show help on hidden profiles.

Also, avoid creating profile beginning with underscore on upgrade.
This commit is contained in:
FelisCatus 2014-10-12 14:47:47 +08:00
parent 73d4fd637e
commit 658764db10
8 changed files with 62 additions and 18 deletions

View File

@ -322,7 +322,7 @@
"message": "PAC URL"
},
"options_pacUrlHelp": {
"message": "The PAC script will be updated from this URL. If it is left blank, the following scripts will be used directly instead."
"message": "The PAC script will be updated from this URL. If it is left blank, the following script will be used directly instead."
},
"options_pacUrlFile": {
"message": "PAC profiles with file: URLs can only be applied directly. They cannot be used as result profiles because local files cannot be accessed due to browser limitation."
@ -429,6 +429,12 @@
"options_profileNameConflict": {
"message": "A profile with this name already exists."
},
"options_profileNameReserved": {
"message": "Profile names beginning with double-underscore are reserved."
},
"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_deleteProfile": {
"message": "Delete Profile"
},

View File

@ -429,6 +429,12 @@
"options_profileNameConflict": {
"message": "已经存在相同名称的情景模式。"
},
"options_profileNameReserved": {
"message": "以双下划线开头的名称为系统保留,禁止使用。"
},
"options_profileNameHidden": {
"message": "以下划线开头的情景模式不会在弹出菜单中显示,但仍可被用作切换的结果等。"
},
"options_modalHeader_deleteProfile": {
"message": "删除情景模式"
},

View File

@ -105,6 +105,8 @@ module.exports = (oldOptions, i18n) ->
color = oldProfile['color']
profile.color = colorTranslations[color] ? colorTranslations['']
name = oldProfile['name'] ? oldProfile['id']
if name[0] == '_'
name = 'p' + name
profile.name = name
num = 1
while OmegaPac.Profiles.byName(profile.name, options)

View File

@ -19,6 +19,16 @@ angular.module('omega').constant 'getParentName', (name) ->
else
undefined
charCodeUnderscore = '_'.charCodeAt(0)
angular.module('omega').constant 'charCodeUnderscore', charCodeUnderscore
angular.module('omega').constant 'isProfileNameHidden', (name) ->
# Hide profiles beginning with underscore.
name.charCodeAt(0) == charCodeUnderscore
angular.module('omega').constant 'isProfileNameReserved', (name) ->
# Reserve profile names beginning with double-underscore.
(name.charCodeAt(0) == charCodeUnderscore and
name.charCodeAt(1) == charCodeUnderscore)
angular.module('omega').config ($stateProvider, $urlRouterProvider,
$httpProvider, $animateProvider) ->
$animateProvider.classNameFilter(/angular-animate/)

View File

@ -1,6 +1,7 @@
angular.module('omega').controller 'MasterCtrl', ($scope, $rootScope, $window,
$modal, $state, builtinProfiles, profileColors, profileIcons, omegaTarget, $q,
$timeout, $location, $filter, getAttachedName) ->
$timeout, $location, $filter, getAttachedName, isProfileNameReserved,
isProfileNameHidden) ->
tr = $filter('tr')
@ -109,7 +110,12 @@ angular.module('omega').controller 'MasterCtrl', ($scope, $rootScope, $window,
$rootScope.newProfile = ->
scope = $rootScope.$new('isolate')
scope.options = $rootScope.options
scope.notConflict = (name) -> not $rootScope.profileByName(name)
scope.isProfileNameReserved = isProfileNameReserved
scope.isProfileNameHidden = isProfileNameHidden
scope.profileByName = $rootScope.profileByName
scope.validateProfileName =
conflict: '!$value || !profileByName($value)'
reserved: '!$value || !isProfileNameReserved($value)'
scope.profileIcons = profileIcons
$modal.open(
templateUrl: 'partials/new_profile.html'
@ -128,8 +134,12 @@ angular.module('omega').controller 'MasterCtrl', ($scope, $rootScope, $window,
scope = $rootScope.$new('isolate')
scope.options = $rootScope.options
scope.fromName = fromName
scope.notConflict = (name) ->
name == fromName or not $rootScope.profileByName(name)
scope.isProfileNameReserved = isProfileNameReserved
scope.isProfileNameHidden = isProfileNameHidden
scope.profileByName = $rootScope.profileByName
scope.validateProfileName =
conflict: '!$value || $value == fromName || !profileByName($value)'
reserved: '!$value || !isProfileNameReserved($value)'
scope.profileIcons = profileIcons
$modal.open(
templateUrl: 'partials/rename_profile.html'

View File

@ -1,6 +1,7 @@
angular.module('omega').filter 'profiles', (builtinProfiles, profileOrder) ->
angular.module('omega').filter 'profiles', (builtinProfiles, profileOrder,
isProfileNameHidden, isProfileNameReserved) ->
charCodePlus = '+'.charCodeAt(0)
charCodeUnderscore = '_'.charCodeAt(0)
builtinProfileList = (profile for _, profile of builtinProfiles)
(options, filter) ->
result = []
@ -12,15 +13,10 @@ angular.module('omega').filter 'profiles', (builtinProfiles, profileOrder) ->
filter = filter.substr(1)
result = OmegaPac.Profiles.validResultProfilesFor(filter, options)
if filter == 'all'
result = result.filter (profile) ->
# Hide profiles beginning with underscore.
profile.name.charCodeAt(0) != charCodeUnderscore
result = result.filter (profile) -> !isProfileNameHidden(profile.name)
result = result.concat builtinProfileList
else
result = result.filter (profile) ->
# Hide profiles beginning with double underscore in options.
(profile.name.charCodeAt(0) != charCodeUnderscore or
profile.name.charCodeAt(1) != charCodeUnderscore)
result = result.filter (profile) -> !isProfileNameReserved(profile.name)
if filter == 'sorted'
result.sort profileOrder
result

View File

@ -8,9 +8,16 @@ form(ng-submit='newProfile.$valid && $close(profile)' name='newProfile')
.form-group(ng-class='{"has-error": !newProfile.profileNewName.$valid}')
label(for='profile-new-name') {{'options_newProfileName' | tr}}
input#profile-new-name.form-control(type='text' name='profileNewName' required ng-model='profile.name'
ui-validate='{conflict: "notConflict($value)"}')
ui-validate='validateProfileName')
.help-block(ng-show='newProfile.profileNewName.$error.required') {{'options_profileNameEmpty' | tr}}
.help-block(ng-show='newProfile.profileNewName.$error.conflict') {{'options_profileNameConflict' | tr}}
.help-block(ng-show='newProfile.profileNewName.$error.reserved') {{'options_profileNameReserved' | tr}}
.help-block(ng-show='!newProfile.profileNewName.$error.reserved && newProfile.profileNewName.$error.conflict')
| {{'options_profileNameConflict' | tr}}
.help-block(ng-show='newProfile.profileNewName.$valid && profile.name && isProfileNameHidden(profile.name)')
.text-info
span.glyphicon.glyphicon-info-sign
= ' '
| {{'options_profileNameHidden' | tr}}
label {{'options_profileType' | tr}}
.radio
label

View File

@ -8,9 +8,16 @@ form(ng-submit='renameProfile.$valid && $close(newName)' name='renameProfile')
.form-group(ng-class='{"has-error": !renameProfile.profileNewName.$valid}')
label(for='profile-new-name') {{'options_renameProfileName' | tr}}
input#profile-new-name.form-control(type='text' name='profileNewName' required ng-model='newName'
ui-validate='{conflict: "notConflict($value)"}' ng-init='newName = fromName')
ui-validate='validateProfileName' ng-init='newName = fromName')
.help-block(ng-show='renameProfile.profileNewName.$error.required') {{'options_profileNameEmpty' | tr}}
.help-block(ng-show='renameProfile.profileNewName.$error.conflict') {{'options_profileNameConflict' | tr}}
.help-block(ng-show='renameProfile.profileNewName.$error.reserved') {{'options_profileNameReserved' | tr}}
.help-block(ng-show='!renameProfile.profileNewName.$error.reserved && renameProfile.profileNewName.$error.conflict')
| {{'options_profileNameConflict' | tr}}
.help-block(ng-show='renameProfile.profileNewName.$valid && newName && isProfileNameHidden(newName)')
.text-info
span.glyphicon.glyphicon-info-sign
= ' '
| {{'options_profileNameHidden' | tr}}
.modal-footer
button.btn.btn-default(type='button' ng-click='$dismiss()') {{'dialog_cancel' | tr}}
button.btn.btn-primary(type='submit' ng-disabled='!renameProfile.$valid') {{'options_renameProfile' | tr}}