GUACAMOLE-1509: Merge add contextual CSS classes to reduce template ambiguity.

This commit is contained in:
Virtually Nick
2022-01-23 15:30:37 -05:00
committed by GitHub
41 changed files with 184 additions and 65 deletions

View File

@@ -41,6 +41,7 @@
<div class="totp-code">
<input type="text"
placeholder="{{'TOTP.FIELD_PLACEHOLDER_CODE' |translate}}"
ng-attr-name="{{ field.name }}"
ng-model="model" autocorrect="off" autocapitalize="off" autofocus>
</div>

View File

@@ -243,6 +243,7 @@ angular.module('client').directive('guacClientNotification', [function guacClien
if (connectionState === ManagedClientState.ConnectionState.CONNECTING
|| connectionState === ManagedClientState.ConnectionState.WAITING) {
$scope.status = {
className : "connecting",
title: "CLIENT.DIALOG_HEADER_CONNECTING",
text: {
key : "CLIENT.TEXT_CLIENT_STATUS_" + connectionState.toUpperCase()
@@ -360,6 +361,7 @@ angular.module('client').directive('guacClientNotification', [function guacClien
// Prompt for parameters
$scope.status = {
className : "parameters-required",
formNamespace : Protocol.getNamespace($scope.client.protocol),
forms : $scope.client.forms,
formModel : requiredParameters,

View File

@@ -1,4 +1,4 @@
<div class="connection">
<div class="connection-select-menu-connection connection">
<input type="checkbox"
ng-model="context.attachedClients[item.getClientIdentifier()]"
ng-change="context.updateAttachedClients(item.getClientIdentifier())">

View File

@@ -1,4 +1,4 @@
<div class="connection-group">
<div class="connection-select-menu-connection-group connection-group">
<input type="checkbox"
ng-show="item.balancing"
ng-model="context.attachedClients[item.getClientIdentifier()]"

View File

@@ -1,4 +1,4 @@
<div class="list-item">
<div class="file-browser-file list-item">
<!-- Filename and icon -->
<div class="caption">

View File

@@ -1,4 +1,4 @@
<div class="main"
<div class="client-main main"
ng-class="{ 'drop-pending': dropPending }"
guac-resize="mainElementResized"
guac-touch-drag="clientDrag"

View File

@@ -86,6 +86,7 @@ angular.module('form').directive('guacForm', [function form() {
controller: ['$scope', '$injector', function formController($scope, $injector) {
// Required services
var formService = $injector.get('formService');
var translationStringService = $injector.get('translationStringService');
/**
@@ -134,6 +135,22 @@ angular.module('form').directive('guacForm', [function form() {
};
/**
* Returns an object as would be provided to the ngClass directive
* that defines the CSS classes that should be applied to the given
* form.
*
* @param {Form} form
* The form to generate the CSS classes for.
*
* @return {!Object.<string, boolean>}
* The ngClass object defining the CSS classes for the given
* form.
*/
$scope.getFormClasses = function getFormClasses(form) {
return formService.getClasses('form-', form);
};
/**
* Determines whether the given object is a form, under the
* assumption that the object is either a form or a field.

View File

@@ -155,6 +155,21 @@ angular.module('form').directive('guacFormField', [function formField() {
};
/**
* Returns an object as would be provided to the ngClass directive
* that defines the CSS classes that should be applied to this
* field.
*
* @return {!Object.<string, boolean>}
* The ngClass object defining the CSS classes for the current
* field.
*/
$scope.getFieldClasses = function getFieldClasses() {
return formService.getClasses('labeled-field-', $scope.field, {
empty: !$scope.model
});
};
/**
* Returns whether the current field should be displayed.
*

View File

@@ -91,7 +91,7 @@ angular.module('form').provider('formService', function formServiceProvider() {
* @type FieldType
*/
'USERNAME' : {
templateUrl : 'app/form/templates/textField.html'
templateUrl : 'app/form/templates/usernameField.html'
},
/**
@@ -272,6 +272,53 @@ angular.module('form').provider('formService', function formServiceProvider() {
};
/**
* Given form content and an arbitrary prefix, returns a corresponding
* CSS class object as would be provided to the ngClass directive that
* assigns a content-specific CSS class based on the prefix and
* form/field name. Generated class names follow the lowercase with
* dashes naming convention. For example, if the prefix is "field-" and
* the provided content is a field with the name "Swap red/blue", the
* object { 'field-swap-red-blue' : true } would be returned.
*
* @param {!string} prefix
* The arbitrary prefix to prepend to the name of the generated CSS
* class.
*
* @param {!(Form|Field)} [content]
* The form or field whose name should be used to produce the CSS
* class name.
*
* @param {Object.<string, boolean>} [object={}]
* The optional base ngClass object that should be used to provide
* additional name/value pairs within the returned object.
*
* @return {!Object.<string, boolean>}
* The ngClass object based on the provided object and defining a
* CSS class name for the given content.
*/
service.getClasses = function getClasses(prefix, content, object) {
// Default to no additional properties
object = object || {};
// Perform no transformation if there is no content or
// corresponding name
if (!content || !content.name)
return object;
// Transform content name and prefix into lowercase-with-dashes
// CSS class name
var className = prefix + content.name.replace(/[^a-zA-Z0-9]+/g, '-').toLowerCase();
// Add CSS class name to provided base object (without touching
// base object)
var classes = angular.extend({}, object);
classes[className] = true;
return classes;
};
/**
* Compiles and links the field associated with the given name to the given
* scope, producing a distinct and independent DOM Element which functions

View File

@@ -1,7 +1,10 @@
<input type="checkbox"
<div class="checkbox-field">
<input type="checkbox"
ng-attr-id="{{ fieldId }}"
ng-attr-name="{{ field.name }}"
ng-disabled="disabled"
ng-model="typedValue"
guac-focus="focused"
autocorrect="off"
autocapitalize="off">
</div>

View File

@@ -2,6 +2,7 @@
<input type="date"
ng-disabled="disabled"
ng-attr-id="{{ fieldId }}"
ng-attr-name="{{ field.name }}"
ng-model="typedValue"
ng-model-options="modelOptions"
guac-lenient-date

View File

@@ -2,6 +2,7 @@
<input type="email"
ng-disabled="disabled"
ng-attr-id="{{ fieldId }}"
ng-attr-name="{{ field.name }}"
ng-model="model"
ng-hide="readOnly"
guac-focus="focused"

View File

@@ -1,9 +1,10 @@
<div class="form-group">
<div ng-repeat="form in forms" class="form"
ng-class="getFormClasses(form)"
ng-show="containsVisible(form.fields)">
<!-- Form name -->
<h3 ng-show="form.name">{{getSectionHeader(form) | translate}}</h3>
<h3 class="form-header" ng-show="form.name">{{getSectionHeader(form) | translate}}</h3>
<!-- All fields in form -->
<div class="fields">

View File

@@ -1,4 +1,5 @@
<div class="labeled-field" ng-class="{empty: !model}" ng-show="isFieldVisible()">
<div class="labeled-field" ng-show="isFieldVisible()"
ng-class="getFieldClasses()">
<!-- Field header -->
<div class="field-header">

View File

@@ -1,4 +1,7 @@
<select guac-focus="focused"
<div class="language-field">
<select guac-focus="focused"
ng-attr-id="{{ fieldId }}"
ng-attr-name="{{ field.name }}"
ng-model="model"
ng-options="language.key as language.value for language in languages | toArray | orderBy: key"></select>
</div>

View File

@@ -1,7 +1,10 @@
<input type="number"
<div class="number-field">
<input type="number"
ng-disabled="disabled"
ng-attr-id="{{ fieldId }}"
ng-attr-name="{{ field.name }}"
ng-model="typedValue"
guac-focus="focused"
autocorrect="off"
autocapitalize="off">
</div>

View File

@@ -2,6 +2,7 @@
<input type="{{passwordInputType}}"
ng-disabled="disabled"
ng-attr-id="{{ fieldId }}"
ng-attr-name="{{ field.name }}"
ng-model="model"
ng-trim="false"
guac-focus="focused"

View File

@@ -1,5 +1,8 @@
<select ng-attr-id="{{ fieldId }}"
<div class="select-field">
<select ng-attr-id="{{ fieldId }}"
ng-attr-name="{{ field.name }}"
ng-disabled="disabled"
guac-focus="focused"
ng-model="model"
ng-options="option as getFieldOption(option) | translate for option in field.options | orderBy: value"></select>
</div>

View File

@@ -4,7 +4,9 @@
}">
<!-- Pre-defined color scheme options -->
<select ng-attr-id="{{ fieldId }}" ng-model="selectedColorScheme">
<select ng-attr-id="{{ fieldId }}"
ng-attr-name="{{ field.name }}"
ng-model="selectedColorScheme">
<option ng-repeat="option in field.options | orderBy: value"
ng-value="option">{{ getFieldOption(option) | translate }}</option>
<option value="custom">{{ 'COLOR_SCHEME.FIELD_OPTION_CUSTOM' | translate }}</option>

View File

@@ -1,6 +1,9 @@
<textarea ng-attr-id="{{ fieldId }}"
<div class="text-area-field">
<textarea ng-attr-id="{{ fieldId }}"
ng-attr-name="{{ field.name }}"
ng-model="model"
ng-disabled="disabled"
guac-focus="focused"
autocorrect="off"
autocapitalize="off"></textarea>
</div>

View File

@@ -2,6 +2,7 @@
<input type="text"
ng-attr-id="{{ fieldId }}"
ng-attr-list="{{ dataListId }}"
ng-attr-name="{{ field.name }}"
ng-model="model"
ng-disabled="disabled"
guac-focus="focused"

View File

@@ -2,6 +2,7 @@
<input type="time"
ng-disabled="disabled"
ng-attr-id="{{ fieldId }}"
ng-attr-name="{{ field.name }}"
ng-model="typedValue"
ng-model-options="modelOptions"
guac-focus="focused"

View File

@@ -10,6 +10,7 @@
<!-- Time zones within selected region -->
<select class="time-zone"
ng-attr-name="{{ field.name }}"
ng-disabled="disabled || !region"
ng-model="model"
ng-options="timeZone.value as timeZone.key for timeZone in timeZones[region] | toArray | orderBy: key"></select>

View File

@@ -0,0 +1,10 @@
<div class="username-field">
<input type="text"
ng-attr-id="{{ fieldId }}"
ng-attr-name="{{ field.name }}"
ng-model="model"
ng-disabled="disabled"
guac-focus="focused"
autocorrect="off"
autocapitalize="off">
</div>

View File

@@ -1,4 +1,4 @@
<div>
<div class="recent-connections">
<!-- Text displayed if no recent connections exist -->
<p class="placeholder" ng-hide="hasRecentConnections()">{{'HOME.INFO_NO_RECENT_CONNECTIONS' | translate}}</p>

View File

@@ -1,5 +1,4 @@
<div class="view" ng-class="{loading: !isLoaded()}">
<div class="home-view view" ng-class="{loading: !isLoaded()}">
<div class="connection-list-ui">
@@ -8,9 +7,7 @@
<h2>{{'HOME.SECTION_HEADER_RECENT_CONNECTIONS' | translate}}</h2>
<guac-user-menu></guac-user-menu>
</div>
<div class="recent-connections">
<guac-recent-connections root-groups="rootConnectionGroups"></guac-recent-connections>
</div>
<!-- All connections for this user -->
<div class="header">

View File

@@ -1,4 +1,4 @@
<div class="choice">
<div class="connection-group-permission choice">
<!-- Connection group icon -->
<div class="icon type"></div>

View File

@@ -1,4 +1,4 @@
<div class="choice">
<div class="connection-permission choice">
<!-- Connection icon -->
<div class="icon type" ng-class="item.protocol"></div>

View File

@@ -1,4 +1,4 @@
<span class="name" ng-click="context.chooseGroup(item.wrappedItem)">
<span class="location-chooser-connection-group name"
ng-click="context.chooseGroup(item.wrappedItem)">
{{item.name}}
</span>

View File

@@ -1,5 +1,5 @@
<div class="view" ng-class="{loading: !isLoaded()}">
<div class="manage-connection view" ng-class="{loading: !isLoaded()}">
<!-- Main property editor -->
<div class="header">

View File

@@ -1,5 +1,5 @@
<div class="view" ng-class="{loading: !isLoaded()}">
<div class="manage-connection-group view" ng-class="{loading: !isLoaded()}">
<!-- Main property editor -->
<div class="header">

View File

@@ -1,4 +1,4 @@
<div class="view" ng-class="{loading: !isLoaded()}">
<div class="manage-sharing-profile view" ng-class="{loading: !isLoaded()}">
<!-- Main property editor -->
<div class="header">

View File

@@ -1,6 +1,6 @@
<div class="action-buttons">
<button ng-show="permissions.canSaveObject" ng-click="saveObject()">{{namespace + '.ACTION_SAVE' | translate}}</button>
<button ng-show="permissions.canCloneObject" ng-click="cloneObject()">{{namespace + '.ACTION_CLONE' | translate}}</button>
<button ng-click="cancel()">{{namespace + '.ACTION_CANCEL' | translate}}</button>
<button ng-show="permissions.canDeleteObject" ng-click="deleteObject()" class="danger">{{namespace + '.ACTION_DELETE' | translate}}</button>
<button ng-show="permissions.canSaveObject" ng-click="saveObject()" class="save">{{namespace + '.ACTION_SAVE' | translate}}</button>
<button ng-show="permissions.canCloneObject" ng-click="cloneObject()" class="clone">{{namespace + '.ACTION_CLONE' | translate}}</button>
<button ng-click="cancel()" class="cancel">{{namespace + '.ACTION_CANCEL' | translate}}</button>
<button ng-show="permissions.canDeleteObject" ng-click="deleteObject()" class="danger delete">{{namespace + '.ACTION_DELETE' | translate}}</button>
</div>

View File

@@ -1,4 +1,4 @@
<div class="choice">
<div class="sharing-profile-permission choice">
<!-- Sharing profile icon -->
<div class="icon type"></div>

View File

@@ -1,5 +1,6 @@
<a ng-href="#/manage/{{item.dataSource}}/connections/{{item.identifier}}"
ng-class="{active: item.getActiveConnections()}">
ng-class="{active: item.getActiveConnections()}"
class="settings-connection">
<!-- Connection icon -->
<div class="icon type" ng-class="item.protocol"></div>

View File

@@ -1,4 +1,5 @@
<a ng-href="#/manage/{{item.dataSource}}/connectionGroups/{{item.identifier}}">
<a ng-href="#/manage/{{item.dataSource}}/connectionGroups/{{item.identifier}}"
class="settings-connection-group">
<!-- Connection group icon -->
<div class="icon type"></div>

View File

@@ -1,3 +1,4 @@
<a ng-href="#/manage/{{item.dataSource}}/connections/?parent={{item.wrappedItem.identifier}}">
<a ng-href="#/manage/{{item.dataSource}}/connections/?parent={{item.wrappedItem.identifier}}"
class="new-connection">
<span class="name">{{'SETTINGS_CONNECTIONS.ACTION_NEW_CONNECTION' | translate}}</span>
</a>

View File

@@ -1,3 +1,4 @@
<a ng-href="#/manage/{{item.dataSource}}/connectionGroups/?parent={{item.wrappedItem.identifier}}">
<a ng-href="#/manage/{{item.dataSource}}/connectionGroups/?parent={{item.wrappedItem.identifier}}"
class="new-connection-group">
<span class="name">{{'SETTINGS_CONNECTIONS.ACTION_NEW_CONNECTION_GROUP' | translate}}</span>
</a>

View File

@@ -1,3 +1,4 @@
<a ng-href="#/manage/{{item.dataSource}}/sharingProfiles/?parent={{item.wrappedItem.identifier}}">
<a ng-href="#/manage/{{item.dataSource}}/sharingProfiles/?parent={{item.wrappedItem.identifier}}"
class="new-sharing-profile">
<span class="name">{{'SETTINGS_CONNECTIONS.ACTION_NEW_SHARING_PROFILE' | translate}}</span>
</a>

View File

@@ -1,5 +1,4 @@
<div class="view">
<div class="settings-view view">
<div class="header tabbed">
<h2>{{'SETTINGS.SECTION_HEADER_SETTINGS' | translate}}</h2>

View File

@@ -1,4 +1,5 @@
<a ng-href="#/manage/{{item.dataSource}}/sharingProfiles/{{item.identifier}}">
<a ng-href="#/manage/{{item.dataSource}}/sharingProfiles/{{item.identifier}}"
class="settings-sharing-profile">
<!-- Sharing profile icon -->
<div class="icon type"></div>