提交 3a492dd3 编写于 作者: P Piotr Bryk 提交者: Rob Franken

Redesign secret detail page (#1452)

* Redesign secret detail page

This is my second iteration to the details page upgrade effort started by @batikanu.

* I propose moving eye icon to the left of the list of secrets
* Changed card titles of cards there to be same as in resource lists
* Changed eye-off eye-on icons to reflect material design guidelines (one icon is artificially created using SVG)
上级 a61cf1dd
......@@ -1214,6 +1214,9 @@
<translation id="1320482404001625698" key="MSG_SECRETDETAIL_ACTIONBAR_0" desc="Label \'Secret\' which appears at the top of the delete dialog, opened from a secret details page.">Secret</translation>
<translation id="1561742373508692276" key="MSG_SECRETDETAIL_DETAIL_0" desc="Secrets info details section data.">Data </translation>
<translation id="1940368443923988450" key="MSG_SECRETDETAIL_DETAIL_1" desc="Secrets info details section bytes.">bytes </translation>
<translation id="7488314601782256695" key="MSG_SECRETDETAIL_DETAIL_1" desc="Tooltip label for showing secret content">Show secret content</translation>
<translation id="1451479307509203762" key="MSG_SECRETDETAIL_DETAIL_2" desc="Tooltip label for hiding secret content">Hide secret content</translation>
<translation id="9171260393962890085" key="MSG_SECRETDETAIL_DETAIL_3" desc="Secrets info details section bytes.">{{::value.length}} bytes </translation>
<translation id="4201489447726655383" key="MSG_SECRETDETAIL_INFO_0" desc="Config map info details section name.">Details</translation>
<translation id="2838644310432685833" key="MSG_SECRETLIST_CARDLIST_0" desc="Label \'Name\' which appears as a column label in the table of secrets (secret list view).">Name</translation>
<translation id="3059701171980133521" key="MSG_SECRETLIST_CARDLIST_1" desc="Label \'Namespace\' which appears as a column label in the table of secrets (secret list view).">Namespace</translation>
......
......@@ -1300,6 +1300,9 @@
<translation id="1561742373508692276" key="MSG_SECRETDETAIL_DETAIL_0" desc="Secrets info details section data.">Data </translation>
<translation id="7988357395949564443" key="MSG_SECRETDETAIL_DETAIL_0" desc="Config map info details section name.">Data</translation>
<translation id="1940368443923988450" key="MSG_SECRETDETAIL_DETAIL_1" desc="Secrets info details section bytes.">bytes </translation>
<translation id="7488314601782256695" key="MSG_SECRETDETAIL_DETAIL_1" desc="Tooltip label for showing secret content">Show secret content</translation>
<translation id="1451479307509203762" key="MSG_SECRETDETAIL_DETAIL_2" desc="Tooltip label for hiding secret content">Hide secret content</translation>
<translation id="9171260393962890085" key="MSG_SECRETDETAIL_DETAIL_3" desc="Secrets info details section bytes.">{{::value.length}} bytes </translation>
<translation id="4201489447726655383" key="MSG_SECRETDETAIL_INFO_0" desc="Config map info details section name.">Details</translation>
<translation id="2838644310432685833" key="MSG_SECRETLIST_CARDLIST_0" desc="Label \'Name\' which appears as a column label in the table of secrets (secret list view).">Name</translation>
<translation id="3059701171980133521" key="MSG_SECRETLIST_CARDLIST_1" desc="Label \'Namespace\' which appears as a column label in the table of secrets (secret list view).">Namespace</translation>
......
......@@ -36,9 +36,6 @@ type SecretDetail struct {
// Used to facilitate programmatic handling of secret data.
Type api.SecretType `json:"type"`
// Determines if the secret is hidden type in case of opaque and basicAuth types.
IsHiddenType bool `json:"isHiddenType"`
}
// GetSecretDetail returns returns detailed information about a secret
......@@ -54,17 +51,11 @@ func GetSecretDetail(client *client.Clientset, namespace, name string) (*SecretD
return getSecretDetail(rawSecret), nil
}
// For opaque and basicAuth secret types the credentials like username, password and etc. should be hidden.
func isHiddenType(secretType api.SecretType) bool {
return secretType == api.SecretTypeBasicAuth || secretType == api.SecretTypeOpaque
}
func getSecretDetail(rawSecret *api.Secret) *SecretDetail {
return &SecretDetail{
ObjectMeta: common.NewObjectMeta(rawSecret.ObjectMeta),
TypeMeta: common.NewTypeMeta(common.ResourceKindSecret),
Data: rawSecret.Data,
IsHiddenType: isHiddenType(rawSecret.Type),
Type: rawSecret.Type,
ObjectMeta: common.NewObjectMeta(rawSecret.ObjectMeta),
TypeMeta: common.NewTypeMeta(common.ResourceKindSecret),
Data: rawSecret.Data,
Type: rawSecret.Type,
}
}
......@@ -1000,7 +1000,6 @@ backendApi.NamespaceDetail;
* objectMeta: !backendApi.ObjectMeta,
* typeMeta: !backendApi.TypeMeta,
* data: !Object<string, string>,
* isHiddenType: boolean,
* }}
*/
backendApi.SecretDetail;
......
......@@ -120,6 +120,7 @@ a {
.kd-pre-block {
margin: 0;
min-width: 0;
white-space: pre-wrap;
word-wrap: break-word;
}
......
......@@ -15,6 +15,6 @@ limitations under the License.
-->
<div layout="column" class="kd-info-card-section-container">
<div class="kd-info-card-section-name">{{$ctrl.name}}</div>
<div class="kd-info-card-section-name" ng-if="::$ctrl.name">{{$ctrl.name}}</div>
<div flex="auto" ng-transclude></div>
</div>
<div layout="row" flex="auto" class="kd-toggle-hidden-text-row">
<input readonly flex="nogrow" ng-if="isActive" type="text"
class="kd-toggle-hidden-text-input" value="{{::$ctrl.text}}">
<span ng-if="!isActive">
<input ng-if="::$ctrl.placeholder.length" readonly flex="nogrow"
type="text" class="kd-toggle-hidden-text-input"
value="{{::$ctrl.placeholder}}">
<input ng-if="::!$ctrl.placeholder.length" type="password" readonly
flex="nogrow" class="kd-toggle-hidden-text-input"
value="{{::$ctrl.text}}">
</span>
<div>
<md-icon ng-show="!isActive" ng-click="isActive = !isActive"
md-font-set="material-icons"
class="kd-toggle-eye-icon kd-toggle-eye-icon-off "> remove_red_eye </md-icon>
<md-icon ng-show="isActive" ng-click="isActive = !isActive"
md-font-set="material-icons"
class="kd-toggle-eye-icon kd-toggle-eye-icon-on"> remove_red_eye </md-icon>
</div>
</div>
\ No newline at end of file
<pre ng-if="$ctrl.active" class="kd-pre-block">{{::$ctrl.text}}</pre>
<span ng-if="!$ctrl.active">
<span ng-if="::$ctrl.placeholder.length">{{::$ctrl.placeholder}}</span>
<input ng-if="::!$ctrl.placeholder.length" type="password" readonly
flex="nogrow" class="kd-toggle-hidden-text-input"
value="{{::$ctrl.text}}">
</span>
......@@ -12,40 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
@import '../../../variables';
$eye-icon-size: $body-font-size-base * 1.8;
$eye-icon-color-on: rgba(0, 0, 0, .84);
$eye-icon-color-off: rgba(0, 0, 0, .54);
$eye-icon-background-color-on: rgba(224, 224, 224, 1);
.kd-toggle-hidden-text-input {
border: 0 none;
font-size: $body-font-size-base;
}
.kd-toggle-hidden-text-row {
display: inline-flex;
}
.kd-toggle-eye-icon {
border-radius: 54%;
cursor: pointer;
font-size: $body-font-size-base;
height: $eye-icon-size;
line-height: $eye-icon-size;
margin-top: -4px;
outline: none;
position: fixed;
text-align: center;
width: $eye-icon-size;
}
.kd-toggle-eye-icon-on {
background-color: $eye-icon-background-color-on;
color: $eye-icon-color-on;
}
.kd-toggle-eye-icon-off {
color: $eye-icon-color-off;
}
......@@ -12,22 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @final
*/
export class ToggleHiddenTextController {
/**
* @ngInject
*/
constructor() {
/** @export {string} Initialized from the scope. */
this.text;
/** @export {string} Initialized from the scope. */
this.placeholder;
}
}
/**
* Represents a toggle to hide and show text.
*
......@@ -35,11 +19,12 @@ export class ToggleHiddenTextController {
*/
export const toggleHiddenTextComponent = {
templateUrl: 'common/components/togglehiddentext/togglehiddentext.html',
controller: ToggleHiddenTextController,
bindings: {
/** {!string} */
/** {string} */
'placeholder': '@?',
/** {!string} */
/** {string} */
'text': '@',
/** {boolean} */
'active': '<',
},
};
......@@ -15,17 +15,34 @@ limitations under the License.
-->
<div layout="column">
<kd-secret-info secret="::$ctrl.secretDetail"></kd-secret-info>
<kd-info-card>
<kd-info-card-section name="[[Data | Secrets info details section data.]]">
<kd-info-card-entry ng-repeat="(key, value) in ::$ctrl.secretDetail.data"
title="{{::key}}">
<pre ng-if="::!$ctrl.secretDetail.isHiddenType" class="kd-pre-block">{{::$ctrl.formatDataValue(value)}}</pre>
<kd-toggle-hidden-text ng-if="::$ctrl.secretDetail.isHiddenType"
placeholder="{{::value.length}} [[bytes | Secrets info details section bytes.]]"
text="{{ ::value }}">
</kd-toggle-hidden-text>
</kd-info-card-entry>
</kd-info-card-section>
</kd-info-card>
<kd-secret-info secret="::$ctrl.secretDetail"></kd-secret-info>
<kd-info-card>
<kd-info-card-header>[[Data | Secrets info details section data.]]</kd-info-card-header>
<kd-info-card-section>
<div layout="row" class="kd-info-card-entry kd-secret-detail-row" ng-repeat="(key, value) in ::$ctrl.secretDetail.data">
<div flex="nogrow" style="position: relative">
<md-button ng-click="isActive = !isActive" class="md-icon-button">
<!-- SVG drawing to simulate crossed-eye icon.
This should be removed if possible. -->
<svg ng-if="isActive" width="40px" height="40px" viewBox="0 0 40 40"
style="left: 0; top:0; position:absolute; bottom:0, right: 0;">
<line x1="10" y1="10" x2="30" y2="30"
style="stroke-width: 2; stroke: rgba(0,0,0,0.54);"/>
</svg>
<md-icon md-font-library="material-icons">remove_red_eye</md-icon>
<md-tooltip ng-if="!isActive">[[Show secret content|Tooltip label for showing secret content]]</md-tooltip>
<md-tooltip ng-if="isActive">[[Hide secret content|Tooltip label for hiding secret content]]</md-tooltip>
</md-button>
{{::key}}:
</div>
<div class="kd-info-card-entry-content">
<kd-toggle-hidden-text active="isActive"
placeholder="[[{{::value.length}} bytes | Secrets info details section bytes.]]"
text="{{ ::value }}">
</kd-toggle-hidden-text>
</div>
</div>
</kd-info-card-section>
</kd-info-card>
</div>
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
@import '../variables';
.kd-secret-detail-row {
&.kd-info-card-entry {
padding: 0;
}
.kd-info-card-entry-content {
padding-top: 1.125 * $baseline-grid;
}
}
......@@ -15,7 +15,8 @@ limitations under the License.
-->
<kd-info-card>
<kd-info-card-section name="[[Details|Secret info details section name.]]">
<kd-info-card-header>[[Details|Secret info details section name.]]</kd-info-card-header>
<kd-info-card-section>
<kd-object-meta-info-card object-meta="::$ctrl.secret.objectMeta">
</kd-object-meta-info-card>
</kd-info-card-section>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册