提交 07f648d1 编写于 作者: S Sebastian Florek 提交者: Marcin Maciaszczyk

Add filtering (search) support (#1875)

* Move pagination to the footer of the list

* Add filtering support to pods list

* Reverse filter by logic and use contains instead of startsWith

* Update list header title to correctly support overriding

* Refactor zerostate and make it work better with filtering

* Update search UI

* Add search support to remaining resources and adapt backend

* Fix existing tests

* Update debounce of search input

* Add tests

* Add externs for dirPagination module and format project
上级 1a388b15
......@@ -161,6 +161,7 @@ function compileES6(translation) {
path.join(conf.paths.externs, 'clipboard.js'),
path.join(conf.paths.externs, 'uirouter.js'),
path.join(conf.paths.externs, 'dataselect.js'),
path.join(conf.paths.externs, 'dirPagination.js'),
];
let closureCompilerConfig = {
......
此差异已折叠。
此差异已折叠。
......@@ -73,7 +73,9 @@ func getConfigMapList(configMaps []api.ConfigMap, dsQuery *dataselect.DataSelect
ListMeta: common.ListMeta{TotalItems: len(configMaps)},
}
configMaps = fromCells(dataselect.GenericDataSelect(toCells(configMaps), dsQuery))
configMapCells, filteredTotal := dataselect.GenericDataSelectWithFilter(toCells(configMaps), dsQuery)
configMaps = fromCells(configMapCells)
result.ListMeta = common.ListMeta{TotalItems: filteredTotal}
for _, item := range configMaps {
result.Items = append(result.Items,
......
......@@ -100,8 +100,9 @@ func CreateDaemonSetList(daemonSets []extensions.DaemonSet, pods []api.Pod,
cachedResources := &dataselect.CachedResources{
Pods: pods,
}
dsCells, metricPromises := dataselect.GenericDataSelectWithMetrics(ToCells(daemonSets), dsQuery, cachedResources, heapsterClient)
dsCells, metricPromises, filteredTotal := dataselect.GenericDataSelectWithFilterAndMetrics(ToCells(daemonSets), dsQuery, cachedResources, heapsterClient)
daemonSets = FromCells(dsCells)
daemonSetList.ListMeta = common.ListMeta{TotalItems: filteredTotal}
for _, daemonSet := range daemonSets {
matchingPods := common.FilterPodsByOwnerReference(daemonSet.Namespace, daemonSet.UID, pods)
......
......@@ -58,6 +58,8 @@ type MetricDataCell interface {
type ComparableValue interface {
// Compares self with other value. Returns 1 if other value is smaller, 0 if they are the same, -1 if other is larger.
Compare(ComparableValue) int
// Returns true if self value contains or is equal to other value, false otherwise.
Contains(ComparableValue) bool
}
// SelectableData contains all the required data to perform data selection.
......@@ -122,7 +124,7 @@ func (self *DataSelector) Filter() *DataSelector {
matches = false
continue
}
if filterBy.Value.Compare(v) != 0 {
if !v.Contains(filterBy.Value) {
matches = false
continue
}
......@@ -199,6 +201,19 @@ func GenericDataSelect(dataList []DataCell, dsQuery *DataSelectQuery) []DataCell
return SelectableData.Sort().Paginate().GenericDataList
}
// GenericDataSelectWithFilter takes a list of GenericDataCells and DataSelectQuery and returns selected data as instructed by dsQuery.
func GenericDataSelectWithFilter(dataList []DataCell, dsQuery *DataSelectQuery) ([]DataCell, int) {
SelectableData := DataSelector{
GenericDataList: dataList,
DataSelectQuery: dsQuery,
}
// Pipeline is Filter -> Sort -> CollectMetrics -> Paginate
filtered := SelectableData.Filter()
filteredTotal := len(filtered.GenericDataList)
processed := filtered.Sort().Paginate()
return processed.GenericDataList, filteredTotal
}
// GenericDataSelect takes a list of GenericDataCells and DataSelectQuery and returns selected data as instructed by dsQuery.
func GenericDataSelectWithMetrics(dataList []DataCell, dsQuery *DataSelectQuery,
cachedResources *CachedResources, heapsterClient *client.HeapsterClient) ([]DataCell, metric.MetricPromises) {
......
......@@ -32,6 +32,10 @@ func (self StdComparableInt) Compare(otherV ComparableValue) int {
return intsCompare(int(self), int(other))
}
func (self StdComparableInt) Contains(otherV ComparableValue) bool {
return self.Compare(otherV) == 0
}
type StdComparableString string
func (self StdComparableString) Compare(otherV ComparableValue) int {
......@@ -39,6 +43,11 @@ func (self StdComparableString) Compare(otherV ComparableValue) int {
return strings.Compare(string(self), string(other))
}
func (self StdComparableString) Contains(otherV ComparableValue) bool {
other := otherV.(StdComparableString)
return strings.Contains(string(self), string(other))
}
// StdComparableRFC3339Timestamp takes RFC3339 Timestamp strings and compares them as TIMES. In case of time parsing error compares values as strings.
type StdComparableRFC3339Timestamp string
......@@ -56,6 +65,10 @@ func (self StdComparableRFC3339Timestamp) Compare(otherV ComparableValue) int {
}
}
func (self StdComparableRFC3339Timestamp) Contains(otherV ComparableValue) bool {
return self.Compare(otherV) == 0
}
type StdComparableTime time.Time
func (self StdComparableTime) Compare(otherV ComparableValue) int {
......@@ -63,6 +76,10 @@ func (self StdComparableTime) Compare(otherV ComparableValue) int {
return ints64Compare(time.Time(self).Unix(), time.Time(other).Unix())
}
func (self StdComparableTime) Contains(otherV ComparableValue) bool {
return self.Compare(otherV) == 0
}
// Int comparison functions. Similar to strings.Compare.
func intsCompare(a, b int) int {
if a > b {
......
......@@ -117,8 +117,9 @@ func CreateDeploymentList(deployments []extensions.Deployment, pods []api.Pod, e
cachedResources := &dataselect.CachedResources{
Pods: pods,
}
deploymentCells, metricPromises := dataselect.GenericDataSelectWithMetrics(toCells(deployments), dsQuery, cachedResources, heapsterClient)
deploymentCells, metricPromises, filteredTotal := dataselect.GenericDataSelectWithFilterAndMetrics(toCells(deployments), dsQuery, cachedResources, heapsterClient)
deployments = fromCells(deploymentCells)
deploymentList.ListMeta = common.ListMeta{TotalItems: filteredTotal}
for _, deployment := range deployments {
matchingPods := common.FilterDeploymentPodsByOwnerReference(deployment, rs, pods)
......
......@@ -34,7 +34,7 @@ func GetDeploymentPods(client client.Interface, heapsterClient heapster.Heapster
}
channels := &common.ResourceChannels{
PodList: common.GetPodListChannel(client, common.NewSameNamespaceQuery(namespace), 1),
PodList: common.GetPodListChannel(client, common.NewSameNamespaceQuery(namespace), 1),
ReplicaSetList: common.GetReplicaSetListChannel(client, common.NewSameNamespaceQuery(namespace), 1),
}
......
......@@ -94,7 +94,9 @@ func NewIngressList(ingresses []extensions.Ingress, dsQuery *dataselect.DataSele
Items: make([]Ingress, 0),
}
ingresses = fromCells(dataselect.GenericDataSelect(toCells(ingresses), dsQuery))
ingresCells, filteredTotal := dataselect.GenericDataSelectWithFilter(toCells(ingresses), dsQuery)
ingresses = fromCells(ingresCells)
newIngressList.ListMeta = common.ListMeta{TotalItems: filteredTotal}
for _, ingress := range ingresses {
newIngressList.Items = append(newIngressList.Items, *NewIngress(&ingress))
......
......@@ -108,8 +108,9 @@ func CreateJobList(jobs []batch.Job, pods []api.Pod, events []api.Event,
cachedResources := &dataselect.CachedResources{
Pods: pods,
}
jobCells, metricPromises := dataselect.GenericDataSelectWithMetrics(ToCells(jobs), dsQuery, cachedResources, heapsterClient)
jobCells, metricPromises, filteredTotal := dataselect.GenericDataSelectWithFilterAndMetrics(ToCells(jobs), dsQuery, cachedResources, heapsterClient)
jobs = FromCells(jobCells)
jobList.ListMeta = common.ListMeta{TotalItems: filteredTotal}
for _, job := range jobs {
var completions int32
......
......@@ -92,7 +92,7 @@ func TestGetJobListFromChannels(t *testing.T) {
Name: "rs-name",
Namespace: "rs-namespace",
Labels: map[string]string{"key": "value"},
UID: "uid",
UID: "uid",
CreationTimestamp: metaV1.Unix(111, 222),
},
Spec: batch.JobSpec{
......@@ -108,7 +108,7 @@ func TestGetJobListFromChannels(t *testing.T) {
Name: "rs-name",
Namespace: "rs-namespace",
Labels: map[string]string{"key": "value"},
UID: "uid",
UID: "uid",
CreationTimestamp: metaV1.Unix(111, 222),
},
Spec: batch.JobSpec{
......
......@@ -4,8 +4,8 @@ import (
"fmt"
"github.com/kubernetes/dashboard/src/app/backend/resource/common"
api "k8s.io/client-go/pkg/api/v1"
"k8s.io/apimachinery/pkg/types"
api "k8s.io/client-go/pkg/api/v1"
)
// DerivedResources is a map from a derived resource(a resource that is not supported by heapster)
......
......@@ -80,7 +80,9 @@ func toNamespaceList(namespaces []api.Namespace, dsQuery *dataselect.DataSelectQ
ListMeta: common.ListMeta{TotalItems: len(namespaces)},
}
namespaces = fromCells(dataselect.GenericDataSelect(toCells(namespaces), dsQuery))
namespaceCells, filteredTotal := dataselect.GenericDataSelectWithFilter(toCells(namespaces), dsQuery)
namespaces = fromCells(namespaceCells)
namespaceList.ListMeta = common.ListMeta{TotalItems: filteredTotal}
for _, namespace := range namespaces {
namespaceList.Namespaces = append(namespaceList.Namespaces, toNamespace(namespace))
......
......@@ -82,8 +82,9 @@ func toNodeList(nodes []api.Node, dsQuery *dataselect.DataSelectQuery, heapsterC
ListMeta: common.ListMeta{TotalItems: len(nodes)},
}
replicationControllerCells, metricPromises := dataselect.GenericDataSelectWithMetrics(toCells(nodes), dsQuery, dataselect.NoResourceCache, heapsterClient)
nodes = fromCells(replicationControllerCells)
nodeCells, metricPromises, filteredTotal := dataselect.GenericDataSelectWithFilterAndMetrics(toCells(nodes), dsQuery, dataselect.NoResourceCache, heapsterClient)
nodes = fromCells(nodeCells)
nodeList.ListMeta = common.ListMeta{TotalItems: filteredTotal}
for _, node := range nodes {
nodeList.Nodes = append(nodeList.Nodes, toNode(node))
......
......@@ -75,7 +75,9 @@ func getPersistentVolumeList(persistentVolumes []api.PersistentVolume, dsQuery *
ListMeta: common.ListMeta{TotalItems: len(persistentVolumes)},
}
persistentVolumes = fromCells(dataselect.GenericDataSelect(toCells(persistentVolumes), dsQuery))
pvCells, filteredTotal := dataselect.GenericDataSelectWithFilter(toCells(persistentVolumes), dsQuery)
persistentVolumes = fromCells(pvCells)
result.ListMeta = common.ListMeta{TotalItems: filteredTotal}
for _, item := range persistentVolumes {
result.Items = append(result.Items,
......
......@@ -79,7 +79,9 @@ func getPersistentVolumeClaimList(persistentVolumeClaims []api.PersistentVolumeC
ListMeta: common.ListMeta{TotalItems: len(persistentVolumeClaims)},
}
persistentVolumeClaims = fromCells(dataselect.GenericDataSelect(toCells(persistentVolumeClaims), dsQuery))
pvcCells, filteredTotal := dataselect.GenericDataSelectWithFilter(toCells(persistentVolumeClaims), dsQuery)
persistentVolumeClaims = fromCells(pvcCells)
result.ListMeta = common.ListMeta{TotalItems: filteredTotal}
for _, item := range persistentVolumeClaims {
result.Items = append(result.Items,
......
......@@ -70,6 +70,11 @@ func GetRbacRoleListFromChannels(channels *common.ResourceChannels, dsQuery *dat
func SimplifyRbacRoleLists(roles []rbac.Role, clusterRoles []rbac.ClusterRole, dsQuery *dataselect.DataSelectQuery) *RbacRoleList {
items := make([]RbacRole, 0)
result := &RbacRoleList{
Items: make([]RbacRole, 0),
ListMeta: common.ListMeta{TotalItems: len(roles) + len(clusterRoles)},
}
for _, item := range roles {
items = append(items,
RbacRole{
......@@ -85,10 +90,12 @@ func SimplifyRbacRoleLists(roles []rbac.Role, clusterRoles []rbac.ClusterRole, d
TypeMeta: common.NewTypeMeta(common.ResourceKindRbacClusterRole),
})
}
selectedItems := fromCells(dataselect.GenericDataSelect(toCells(items), dsQuery))
result := &RbacRoleList{
Items: selectedItems,
ListMeta: common.ListMeta{TotalItems: len(roles) + len(clusterRoles)},
}
roleCells, filteredTotal := dataselect.GenericDataSelectWithFilter(toCells(items), dsQuery)
items = fromCells(roleCells)
result.ListMeta = common.ListMeta{TotalItems: filteredTotal}
result.Items = items
return result
}
......@@ -95,9 +95,9 @@ func CreateReplicaSetList(replicaSets []extensions.ReplicaSet, pods []api.Pod, e
cachedResources := &dataselect.CachedResources{
Pods: pods,
}
rsCells, metricPromises := dataselect.GenericDataSelectWithMetrics(ToCells(replicaSets),
dsQuery, cachedResources, heapsterClient)
rsCells, metricPromises, filteredTotal := dataselect.GenericDataSelectWithFilterAndMetrics(ToCells(replicaSets), dsQuery, cachedResources, heapsterClient)
replicaSets = FromCells(rsCells)
replicaSetList.ListMeta = common.ListMeta{TotalItems: filteredTotal}
for _, replicaSet := range replicaSets {
matchingPods := common.FilterPodsByOwnerReference(replicaSet.Namespace,
......
......@@ -84,8 +84,10 @@ func CreateReplicationControllerList(replicationControllers []api.ReplicationCon
cachedResources := &dataselect.CachedResources{
Pods: pods,
}
rcCells, metricPromises := dataselect.GenericDataSelectWithMetrics(toCells(replicationControllers), dsQuery, cachedResources, heapsterClient)
rcCells, metricPromises, filteredTotal := dataselect.GenericDataSelectWithFilterAndMetrics(
toCells(replicationControllers), dsQuery, cachedResources, heapsterClient)
replicationControllers = fromCells(rcCells)
rcList.ListMeta = common.ListMeta{TotalItems: filteredTotal}
for _, rc := range replicationControllers {
matchingPods := common.FilterPodsByOwnerReference(rc.Namespace, rc.UID, pods)
......
......@@ -130,7 +130,9 @@ func NewSecretList(secrets []api.Secret, dsQuery *dataselect.DataSelectQuery) *S
Secrets: make([]Secret, 0),
}
secrets = fromCells(dataselect.GenericDataSelect(toCells(secrets), dsQuery))
secretCells, filteredTotal := dataselect.GenericDataSelectWithFilter(toCells(secrets), dsQuery)
secrets = fromCells(secretCells)
newSecretList.ListMeta = common.ListMeta{TotalItems: filteredTotal}
for _, secret := range secrets {
newSecretList.Secrets = append(newSecretList.Secrets, *NewSecret(&secret))
......
......@@ -54,7 +54,9 @@ func CreateServiceList(services []api.Service, dsQuery *dataselect.DataSelectQue
ListMeta: common.ListMeta{TotalItems: len(services)},
}
services = fromCells(dataselect.GenericDataSelect(toCells(services), dsQuery))
serviceCells, filteredTotal := dataselect.GenericDataSelectWithFilter(toCells(services), dsQuery)
services = fromCells(serviceCells)
serviceList.ListMeta = common.ListMeta{TotalItems: filteredTotal}
for _, service := range services {
serviceList.Services = append(serviceList.Services, ToService(&service))
......
......@@ -110,8 +110,10 @@ func CreateStatefulSetList(statefulSets []apps.StatefulSet, pods []api.Pod, even
cachedResources := &dataselect.CachedResources{
Pods: pods,
}
ssCells, metricPromises := dataselect.GenericDataSelectWithMetrics(toCells(statefulSets), dsQuery, cachedResources, heapsterClient)
ssCells, metricPromises, filteredTotal := dataselect.GenericDataSelectWithFilterAndMetrics(
toCells(statefulSets), dsQuery, cachedResources, heapsterClient)
statefulSets = fromCells(ssCells)
statefulSetList.ListMeta = common.ListMeta{TotalItems: filteredTotal}
for _, statefulSet := range statefulSets {
matchingPods := common.FilterPodsByOwnerReference(statefulSet.Namespace,
......
......@@ -59,7 +59,9 @@ func CreateStorageClassList(storageClasses []storage.StorageClass, dsQuery *data
ListMeta: common.ListMeta{TotalItems: len(storageClasses)},
}
storageClasses = fromCells(dataselect.GenericDataSelect(toCells(storageClasses), dsQuery))
storageClassCells, filteredTotal := dataselect.GenericDataSelectWithFilter(toCells(storageClasses), dsQuery)
storageClasses = fromCells(storageClassCells)
storageClassList.ListMeta = common.ListMeta{TotalItems: filteredTotal}
for _, storageClass := range storageClasses {
storageClassList.StorageClasses = append(storageClassList.StorageClasses, ToStorageClass(&storageClass))
......
......@@ -69,7 +69,9 @@ func getThirdPartyResourceList(thirdPartyResources []extensions.ThirdPartyResour
ListMeta: common.ListMeta{TotalItems: len(thirdPartyResources)},
}
thirdPartyResources = fromCells(dataselect.GenericDataSelect(toCells(thirdPartyResources), dsQuery))
tprCells, filteredTotal := dataselect.GenericDataSelectWithFilter(toCells(thirdPartyResources), dsQuery)
thirdPartyResources = fromCells(tprCells)
result.ListMeta = common.ListMeta{TotalItems: filteredTotal}
for _, item := range thirdPartyResources {
result.ThirdPartyResources = append(result.ThirdPartyResources,
......
......@@ -64,7 +64,9 @@ func GetThirdPartyResourceObjects(client k8sClient.Interface, config *rest.Confi
list.ListMeta.TotalItems = len(list.Items)
// Return only slice of data, pagination is done here.
list.Items = fromObjectCells(dataselect.GenericDataSelect(toObjectCells(list.Items), dsQuery))
tprObjectCells, filteredTotal := dataselect.GenericDataSelectWithFilter(toObjectCells(list.Items), dsQuery)
list.Items = fromObjectCells(tprObjectCells)
list.ListMeta = common.ListMeta{TotalItems: filteredTotal}
return list, err
}
......
......@@ -25,6 +25,7 @@ const DataSelectApi = {};
* sortBy: string,
* namespace: string,
* name: string,
* filterBy: string
* }}
*/
DataSelectApi.DataSelectQuery;
......@@ -42,6 +43,7 @@ DataSelectApi.SortableProperties;
* @typedef{{
* PAGINATE: number,
* SORT: number,
* FILTER: number,
* }}
*/
DataSelectApi.SupportedActions;
// 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.
/**
* @fileoverview Externs for external dirPagination module.
*
* @externs
*/
const paginationService = {};
/**
* @param {string} instanceId
* @param {number} val
*/
paginationService.setCurrentPage = function(instanceId, val) {};
......@@ -39,6 +39,7 @@ $secondary: #f51200;
$warning: #ffa500;
$delicate: #aaa;
$border: rgba(0, 0, 0, .12);
$border-solid: rgba(0, 0, 0, .38);
$muted: #888;
$hover-primary: #1254df;
$hover-secondary: #ff1c19;
......
......@@ -69,4 +69,9 @@ limitations under the License.
</kd-content>
</kd-content-card>
</div>
<kd-zero-state ng-if="$ctrl.shouldShowZeroState()"></kd-zero-state>
<kd-content-card ng-if="$ctrl.shouldShowZeroState()">
<kd-content>
<kd-zero-state></kd-zero-state>
</kd-content>
</kd-content-card>
......@@ -17,7 +17,9 @@ limitations under the License.
<kd-resource-card-list selectable="false"
with-statuses="false">
<kd-resource-card-list-header>
[[Conditions|Label 'Conditions' for the conditions section.]]
<kd-resource-card-list-title>
[[Conditions|Label 'Conditions' for the conditions section.]]
</kd-resource-card-list-title>
</kd-resource-card-list-header>
<kd-resource-card-header-columns>
<kd-resource-card-header-column size="small"
......
......@@ -23,10 +23,12 @@ import {resourceCardFooterComponent} from './resourcecardfooter_component';
import {resourceCardHeaderColumnComponent} from './resourcecardheadercolumn_component';
import {resourceCardHeaderColumnsComponent} from './resourcecardheadercolumns_component';
import {resourceCardListComponent} from './resourcecardlist_component';
import {resourceCardListFilterComponent} from './resourcecardlistfilter_component';
import {resourceCardListFooterComponent} from './resourcecardlistfooter_component';
import {resourceCardListHeaderComponent} from './resourcecardlistheader_component';
import {resourceCardListPaginationComponent} from './resourcecardlistpagination_component';
import {resourceCardMenuComponent} from './resourcecardmenu_component';
/**
* Module containing common components for resource cards. A resource card should be used
* for displaying every kind of Kubernetes resource (e.g., Services, Secrets or Replica Sets).
......@@ -42,6 +44,9 @@ export default angular
])
.component('kdResourceCard', resourceCardComponent)
.component('kdResourceCardList', resourceCardListComponent)
.component('kdResourceCardListFooter', resourceCardListFooterComponent)
.component('kdResourceCardListHeader', resourceCardListHeaderComponent)
.component('kdResourceCardListFilter', resourceCardListFilterComponent)
.component('kdResourceCardListPagination', resourceCardListPaginationComponent)
.component('kdResourceCardMenu', resourceCardMenuComponent)
.component('kdResourceCardDeleteMenuItem', resourceCardDeleteMenuItemComponent)
......
......@@ -15,17 +15,17 @@ limitations under the License.
-->
<div class="kd-resource-card-list-wrapper">
<div class="kd-resource-card-list-header-wrapper">
<div ng-transclude="header"
class="kd-resource-card-list-header md-title"
ng-if="::$ctrl.hasHeader()"></div>
<div ng-transclude="pagination"
class="kd-resource-card-list-pagination"></div>
<div ng-transclude="header"
ng-if="::$ctrl.hasHeader()">
</div>
<div class="kd-resource-card-list"
ng-class="{'kd-resource-card-list-selectable': $ctrl.selectable, 'kd-resource-card-list-with-statuses': $ctrl.withStatuses}"
ng-class="{'kd-resource-card-list-selectable': $ctrl.selectable,
'kd-resource-card-list-with-statuses': $ctrl.withStatuses}"
ng-transclude>
</div>
<div ng-transclude="footer"
ng-if="::$ctrl.hasFooter()">
</div>
<div class="kd-resource-card-list-pending-overlay"
ng-if="$ctrl.pending">
<md-progress-circular md-mode="indeterminate"
......
......@@ -21,42 +21,6 @@
overflow-y: auto;
}
.kd-resource-card-list-header-wrapper {
align-items: center;
border-bottom: 1px solid $border;
display: flex;
flex-direction: row;
justify-content: space-between;
}
.kd-resource-card-list-pagination {
flex-grow: 0;
}
kd-resource-card-list-header {
align-items: center;
display: flex;
height: 100%;
padding-left: 2 * $baseline-grid;
}
.kd-resource-card-list-header {
box-sizing: border-box;
flex-grow: 1;
font-weight: $regular-font-weight;
height: 7 * $baseline-grid;
line-height: 5 * $baseline-grid;
margin: 0;
kd-title {
font-weight: $regular-font-weight;
a {
color: $foreground-1;
}
}
}
.kd-resource-card-list-wrapper {
display: flex;
flex-direction: column;
......
......@@ -13,6 +13,7 @@
// limitations under the License.
const HEADER_SLOT = 'header';
const FOOTER_SLOT = 'footer';
/**
* @final
......@@ -94,6 +95,14 @@ export class ResourceCardListController {
hasHeader() {
return this.transclude_.isSlotFilled(HEADER_SLOT);
}
/**
* @return {boolean}
* @export
*/
hasFooter() {
return this.transclude_.isSlotFilled(FOOTER_SLOT);
}
}
/**
......@@ -140,8 +149,8 @@ export class ResourceCardListController {
export const resourceCardListComponent = {
templateUrl: 'common/components/resourcecard/resourcecardlist.html',
transclude: {
'pagination': '?kdResourceCardListPagination',
[HEADER_SLOT]: '?kdResourceCardListHeader',
[FOOTER_SLOT]: '?kdResourceCardListFooter',
},
controller: ResourceCardListController,
bindings: {
......@@ -154,7 +163,7 @@ export const resourceCardListComponent = {
*/
/** {string|undefined} unique data select id */
'selectId': '@',
/** {Array<Object>|undefined} List of objects to paginate */
/** {Array<Object>|undefined} List of objects to apply data selection */
'list': '=',
/** {angular.$resource|undefined} */
'listResource': '<',
......
<!--
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.
-->
<div class="kd-resource-card-list-filter-wrapper">
<div class="kd-search-container">
<input ng-model="$ctrl.inputText"
ng-model-options="{
updateOn: 'default blur',
debounce: {
'default': 250,
'blur': 0
}
}"
ng-change="$ctrl.onTextUpdate()"
ng-class="{'kd-search-input-keep-open': $ctrl.shouldKeepSearchOpen()}"
name="search"
type="search"
placeholder="Search"
class="kd-search-input">
<md-icon class="material-icons kd-search-icon"
ng-if="!$ctrl.shouldKeepSearchOpen()">
search
</md-icon>
<md-icon class="material-icons kd-clear-icon"
ng-if="$ctrl.shouldKeepSearchOpen()"
ng-click="$ctrl.clearInput()">
close
</md-icon>
</div>
</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-search-input-border {
border: 1px solid $border;
border-radius: $baseline-grid / 4;
outline: none;
}
%kd-search-input-border-solid {
@extend %kd-search-input-border;
border: 1px solid $border-solid !important;
}
%kd-search-input-visible {
opacity: 1;
width: 20 * $baseline-grid;
}
kd-resource-card-list-filter {
display: flex;
justify-content: flex-end;
}
.kd-resource-card-list-filter-wrapper {
padding-right: 3 * $baseline-grid;
}
.kd-search-icon {
padding-left: $baseline-grid;
}
.kd-clear-icon {
cursor: pointer;
outline: none;
padding-left: $baseline-grid;
}
.kd-search-input {
@extend %kd-search-input-border;
opacity: 0;
padding-left: $baseline-grid;
transition: opacity .5s, width .5s;
width: 0;
&:focus {
@extend %kd-search-input-border-solid;
@extend %kd-search-input-visible;
}
&.kd-search-input-keep-open {
@extend %kd-search-input-visible;
}
}
.kd-search-container {
display: flex;
flex-direction: row;
&:hover {
.kd-search-input {
@extend %kd-search-input-border;
@extend %kd-search-input-visible;
transition: opacity .25s, width .5s;
}
}
}
// 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.
/**
* @final
*/
class ResourceCardListFilterController {
/** @ngInject */
constructor(kdDataSelectService, errorDialog) {
/** @export {!./resourcecardlist_component.ResourceCardListController} -
* Initialized from require just before $onInit is called. */
this.resourceCardListCtrl;
/** @private {!../../dataselect/service.DataSelectService} */
this.dataSelectService_ = kdDataSelectService;
/** @private {!../../errorhandling/service.ErrorDialog} */
this.errorDialog_ = errorDialog;
/** @export {string} */
this.inputText = '';
/** @private {string} - Unique data select id. Initialized from resource card list controller. */
this.selectId_;
/** @export */
this.i18n = i18n;
}
/** @export */
$onInit() {
this.selectId_ = this.resourceCardListCtrl.selectId;
if (this.shouldEnable() &&
(this.resourceCardListCtrl.list === undefined ||
this.resourceCardListCtrl.listResource === undefined)) {
throw new Error('List and list resource have to be set on list card.');
}
if (!this.dataSelectService_.isRegistered(this.selectId_)) {
this.dataSelectService_.registerInstance(this.selectId_);
}
}
/**
* @export
* @return {boolean}
*/
shouldEnable() {
return this.selectId_ !== undefined && this.selectId_.length > 0;
}
/**
* @export
* @return {boolean}
*/
shouldKeepSearchOpen() {
return this.inputText.length > 0;
}
/** @export */
clearInput() {
this.inputText = '';
this.onTextUpdate();
}
/** @export */
onTextUpdate() {
this.resourceCardListCtrl.setPending(true);
let promise = this.dataSelectService_.filter(
this.resourceCardListCtrl.listResource, this.selectId_, this.inputText);
promise
.then((list) => {
this.resourceCardListCtrl.list = list;
this.resourceCardListCtrl.setPending(false);
})
.catch((err) => {
this.errorDialog_.open(this.i18n.MSG_RESOURCE_CARD_LIST_FILTERING_ERROR, err.data);
this.resourceCardListCtrl.setPending(false);
});
}
}
/**
* Resource card list filter component. See resource card for documentation.
* @type {!angular.Component}
*/
export const resourceCardListFilterComponent = {
templateUrl: 'common/components/resourcecard/resourcecardlistfilter.html',
controller: ResourceCardListFilterController,
require: {
'resourceCardListCtrl': '^kdResourceCardList',
// Make sure that filtering can be only placed in a header
'resourceCardListHeader': '^^kdResourceCardListHeader',
},
};
const i18n = {
/** @export {string} @desc Message shown to the user when there is a filtering error. */
MSG_RESOURCE_CARD_LIST_FILTERING_ERROR: goog.getMsg('Filtering error'),
};
<!--
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.
-->
<div class="kd-resource-card-list-footer">
<div ng-transclude
class="kd-resource-card-list-footer-content"></div>
<div ng-transclude="pagination"
class="kd-resource-card-list-footer-pagination"></div>
</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-resource-card-list-footer {
align-items: center;
border-top: 1px solid $border;
display: flex;
}
.kd-resource-card-list-footer-content {
flex: 1;
padding-left: 2 * $baseline-grid;
}
.kd-resource-card-list-footer-pagination {
flex: 1;
}
// 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.
const PAGINATION_SLOT = 'pagination';
/**
* Resource card list footer component. See resource card for documentation.
* @type {!angular.Component}
*/
export const resourceCardListFooterComponent = {
templateUrl: 'common/components/resourcecard/resourcecardlistfooter.html',
transclude: {
[PAGINATION_SLOT]: '?kdResourceCardListPagination',
},
};
<!--
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.
-->
<div ng-transclude="title"
class="kd-resource-card-list-header md-title"></div>
<div ng-transclude></div>
<div ng-transclude="filter"
ng-if="::$ctrl.isFilterSlotFilled()"
class="kd-resource-card-list-header-filter"></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-resource-card-list-footer {
align-items: center;
border-top: 1px solid $border;
display: flex;
}
kd-resource-card-list-header {
align-items: center;
border-bottom: 1px solid $border;
display: flex;
flex-direction: row;
height: 7 * $baseline-grid;
justify-content: space-between;
padding-left: 2 * $baseline-grid;
}
.kd-resource-card-list-header {
flex-grow: 1;
font-weight: $regular-font-weight;
height: 7 * $baseline-grid;
line-height: 7 * $baseline-grid;
margin: 0;
kd-title {
font-weight: $regular-font-weight;
a {
color: $foreground-1;
}
}
}
.kd-resource-card-list-header-filter {
flex: 1;
}
// 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.
const FILTER_SLOT = 'filter';
const TITLE_SLOT = 'title';
/**
* @final
*/
class ResourceCardListHeaderController {
/**
* @param {!angular.$transclude} $transclude
* @ngInject
*/
constructor($transclude) {
/** @private {!angular.$transclude} */
this.transclude_ = $transclude;
}
/**
* @export
* @return {boolean}
*/
isFilterSlotFilled() {
return this.transclude_.isSlotFilled(FILTER_SLOT);
}
}
/**
* Resource card list header component. See resource card for documentation.
* @type {!angular.Component}
*/
export const resourceCardListHeaderComponent = {
templateUrl: 'common/components/resourcecard/resourcecardlistheader.html',
controller: ResourceCardListHeaderController,
transclude: {
[TITLE_SLOT]: '?kdResourceCardListTitle',
[FILTER_SLOT]: '?kdResourceCardListFilter',
},
};
......@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
<div ng-if="::$ctrl.shouldShowPagination()"
<div ng-if="$ctrl.shouldShowPagination()"
flex="auto"
layout="row"
class="kd-list-pagination">
......
......@@ -25,20 +25,3 @@
display: flex;
}
}
.kd-rows-selector-label {
line-height: 6 * $baseline-grid;
margin-right: $baseline-grid;
vertical-align: middle;
}
md-select {
&.kd-list-pagination-row-selector {
margin: 0 ($baseline-grid * 2) ($baseline-grid / 2) 0;
.md-select-value {
min-width: 6 * $baseline-grid;
width: 100%;
}
}
}
......@@ -108,6 +108,8 @@ export const resourceCardListPaginationComponent = {
transclude: true,
require: {
'resourceCardListCtrl': '^kdResourceCardList',
// Make sure that pagination can be only placed in a footer
'resourceCardListFooter': '^^kdResourceCardListFooter',
},
};
......
......@@ -14,17 +14,23 @@
import {deployAppStateName} from 'deploy/state';
const TITLE_SLOT = 'title';
const TEXT_SLOT = 'text';
/**
* @final
*/
export class ZeroStateController {
/**
* @param {!ui.router.$state} $state
* @param {!angular.$transclude} $transclude
* @ngInject
*/
constructor($state) {
constructor($state, $transclude) {
/** @private {!ui.router.$state} */
this.state_ = $state;
/** @private {!angular.$transclude} */
this.transclude_ = $transclude;
}
/**
......@@ -34,6 +40,14 @@ export class ZeroStateController {
getStateHref() {
return this.state_.href(deployAppStateName);
}
/**
* @return {boolean}
* @export
*/
showDefaultZerostate() {
return !this.transclude_.isSlotFilled(TITLE_SLOT) && !this.transclude_.isSlotFilled(TEXT_SLOT);
}
}
/**
......@@ -41,6 +55,9 @@ export class ZeroStateController {
*/
export const zeroStateComponent = {
templateUrl: 'common/components/zerostate/zerostate.html',
transclude: true,
transclude: {
[TITLE_SLOT]: '?kdZeroStateTitle',
[TEXT_SLOT]: '?kdZeroStateText',
},
controller: ZeroStateController,
};
......@@ -14,19 +14,18 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
<kd-content-card>
<kd-content>
<div class="kd-zerostate-message"
layout-padding>
<div class="kd-zerostate-title">[[There is nothing to display here|Title text which appears on zero state view.]]</div>
<div class="kd-zerostate-text">
<span>
[[You can <a href="{{::$ctrl.getStateHref()}}">deploy a containerized app</a>,
select other namespace or
<a href="http://kubernetes.io/docs/user-guide/ui/" target="_blank">take the Dashboard Tour
<i class="material-icons kd-zerostate-icon">open_in_new</i></a>
to learn more.| Description for a zero state page.]]</span>
</div>
</div>
</kd-content>
</kd-content-card>
<div ng-class="{'layout-padding': $ctrl.showDefaultZerostate()}"
class="kd-zerostate-message">
<div class="kd-zerostate-title"
ng-transclude="title">[[There is nothing to display here|Title text which appears on zero state view.]]
</div>
<div class="kd-zerostate-text"
ng-transclude="text">
<span>
[[You can <a href="{{::$ctrl.getStateHref()}}">deploy a containerized app</a>, select other namespace or
<a href="http://kubernetes.io/docs/user-guide/ui/" target="_blank">take the Dashboard Tour
<i class="material-icons kd-zerostate-icon">open_in_new</i></a>
to learn more.| Description for a zero state page.]]
</span>
</div>
</div>
......@@ -46,6 +46,8 @@ export class DataSelectQueryBuilder {
this.namespace_ = '';
/** @private {string} */
this.name_ = '';
/** @private {string} */
this.filterBy_ = '';
return this;
}
......@@ -96,6 +98,13 @@ export class DataSelectQueryBuilder {
return this;
}
/** @export */
setFilterBy(filterBy) {
this.filterBy_ = filterBy;
return this;
}
/**
* @param sortBy
* @param ascending
......@@ -106,6 +115,17 @@ export class DataSelectQueryBuilder {
return `${ascending ? 'a' : 'd'},${sortBy}`;
}
/**
* Filter only by name property.
* TODO(floreks): extend filtering to support more fields
* @param filterBy
* @returns {string}
* @private
*/
getFilterString_(filterBy) {
return filterBy.length > 0 ? `name,${filterBy}` : '';
}
/**
* @return {!DataSelectApi.DataSelectQuery}
* @export
......@@ -117,6 +137,7 @@ export class DataSelectQueryBuilder {
sortBy: this.getSortString_(this.sortBy_, this.ascending_),
namespace: this.namespace_,
name: this.name_,
filterBy: this.getFilterString_(this.filterBy_),
};
}
}
......@@ -20,6 +20,8 @@ const Actions = {
PAGINATE: 0,
/** @export */
SORT: 1,
/** @export */
FILTER: 2,
};
/**
......@@ -29,9 +31,10 @@ export class DataSelectService {
/**
* @param {!./../namespace/service.NamespaceService} kdNamespaceService
* @param {!../../chrome/state.StateParams|!../resource/resourcedetail.StateParams} $stateParams
* @param {!{setCurrentPage: function(string, number)}} paginationService
* @ngInject
*/
constructor(kdNamespaceService, $stateParams) {
constructor(kdNamespaceService, $stateParams, paginationService) {
/** @private {!Map<string, !DataSelectApi.DataSelectQuery>} */
this.instances_ = new Map();
/** @private {!./../namespace/service.NamespaceService} */
......@@ -42,6 +45,8 @@ export class DataSelectService {
this.rowsLimit = ItemsPerPage;
/** {!../../../chrome/chrome_state.StateParams|!../../resource/resourcedetail.StateParams} */
this.stateParams_ = $stateParams;
/** @private {!{setCurrentPage: function(string, number)}} */
this.paginationService_ = paginationService;
}
/**
......@@ -70,11 +75,19 @@ export class DataSelectService {
return this.rowsLimit;
}
/**
* @param {string} dataSelectId
* @private
*/
resetPagination_(dataSelectId) {
this.paginationService_.setCurrentPage(dataSelectId, 1);
}
/**
* @param listResource {!angular.$resource}
* @param dataSelectId {string}
* @param dataSelectQuery {!DataSelectApi.DataSelectQuery}
* @param action {string}
* @param action {number}
* @return {!angular.$q.Promise}
* @private
*/
......@@ -102,6 +115,10 @@ export class DataSelectService {
case this.actions_.SORT:
query.sortBy = dataSelectQuery.sortBy;
break;
case this.actions_.FILTER:
query.filterBy = dataSelectQuery.filterBy;
query.page = 1;
this.resetPagination_(dataSelectId);
}
this.instances_.set(dataSelectId, query);
......@@ -138,6 +155,18 @@ export class DataSelectService {
return this.selectData_(listResource, dataSelectId, dataSelectQuery, this.actions_.SORT);
}
/**
* @param listResource {!angular.$resource}
* @param dataSelectId {string}
* @param filterBy {string}
* @return {!angular.$q.Promise}
* @export
*/
filter(listResource, dataSelectId, filterBy) {
let dataSelectQuery = new DataSelectQueryBuilder().setFilterBy(filterBy).build();
return this.selectData_(listResource, dataSelectId, dataSelectQuery, this.actions_.FILTER);
}
/**
* @param {string|undefined} [namespace]
* @param {string|undefined} [name]
......
......@@ -41,4 +41,8 @@ limitations under the License.
</kd-content>
</kd-content-card>
</div>
<kd-zero-state ng-if="$ctrl.shouldShowZeroState()"></kd-zero-state>
<kd-content-card ng-if="$ctrl.shouldShowZeroState()">
<kd-content>
<kd-zero-state></kd-zero-state>
</kd-content>
</kd-content-card>
......@@ -19,12 +19,19 @@ limitations under the License.
select-id="{{::$ctrl.getSelectId()}}"
list="$ctrl.configMapList"
list-resource="$ctrl.configMapListResource">
<kd-resource-card-list-header ng-transclude="header">
[[Config Maps|Label which appears above the list of such objects.]]
<kd-resource-card-list-header>
<kd-resource-card-list-title ng-transclude="header">
[[Config Maps|Label which appears above the list of such objects.]]
</kd-resource-card-list-title>
<kd-resource-card-list-filter></kd-resource-card-list-filter>
</kd-resource-card-list-header>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
<kd-resource-card-header-columns>
<kd-zero-state ng-if="!$ctrl.configMapList.listMeta.totalItems">
<kd-zero-state-text ng-transclude="zerostate">
[[There are no Config Maps to display.|Text for config map card list zerostate.]]
</kd-zero-state-text>
</kd-zero-state>
<kd-resource-card-header-columns ng-show="$ctrl.configMapList.listMeta.totalItems">
<kd-resource-card-header-column size="small"
grow="2"
sortable="true"
......@@ -55,4 +62,8 @@ limitations under the License.
pagination-id="{{::$ctrl.getSelectId()}}"
total-items="::$ctrl.configMapList.listMeta.totalItems">
</kd-config-map-card>
<kd-resource-card-list-footer>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
</kd-resource-card-list-footer>
</kd-resource-card-list>
......@@ -64,6 +64,8 @@ export const configMapCardListComponent = {
transclude: {
// Optional header that is transcluded instead of the default one.
'header': '?kdHeader',
// Optional zerostate content that is shown when there are zero items.
'zerostate': '?kdEmptyListText',
},
controller: ConfigMapCardListController,
bindings: {
......
......@@ -14,11 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
<kd-content-card ng-if="!$ctrl.shouldShowZeroState()">
<kd-content-card>
<kd-content>
<kd-config-map-card-list config-map-list="$ctrl.configMapList"
<kd-config-map-card-list ng-if="!$ctrl.shouldShowZeroState()"
config-map-list="$ctrl.configMapList"
config-map-list-resource="$ctrl.configMapListResource">
</kd-config-map-card-list>
<kd-zero-state ng-if="$ctrl.shouldShowZeroState()"></kd-zero-state>
</kd-content>
</kd-content-card>
<kd-zero-state ng-if="$ctrl.shouldShowZeroState()"></kd-zero-state>
......@@ -32,10 +32,9 @@ limitations under the License.
<kd-content>
<kd-service-card-list service-list="::ctrl.daemonSetDetail.serviceList"
service-list-resource="::ctrl.daemonSetServicesResource">
<kd-zerostate>
<div class="kd-zerostate-title">[[There is nothing to display here|Title for services card zerostate in daemon set details page.]]</div>
<div class="kd-zerostate-text">[[There are currently no Services with the same label selector as this Daemon Set.|Text for services card zerostate in daemon set details page.]]</div>
</kd-zerostate>
<kd-empty-list-text>
[[There are currently no Services with the same label selector as this Daemon Set.|Text for services card zerostate in daemon set details page.]]
</kd-empty-list-text>
</kd-service-card-list>
</kd-content>
</kd-content-card>
......@@ -45,10 +44,9 @@ limitations under the License.
<kd-pod-card-list pod-list="::ctrl.daemonSetDetail.podList"
pod-list-resource="::ctrl.daemonSetPodsResource"
with-statuses="true">
<kd-zerostate>
<div class="kd-zerostate-title">[[There is nothing to display here|Title for pods card zerostate in daemon set details page.]]</div>
<div class="kd-zerostate-text">[[There are currently no Pods scheduled on this Daemon Set.|Text for pods card zerostate in daemon set details page.]]</div>
</kd-zerostate>
<kd-empty-list-text>
[[There are currently no Pods scheduled on this Daemon Set.|Text for pods card zerostate in daemon set details page.]]
</kd-empty-list-text>
</kd-pod-card-list>
</kd-content>
</kd-content-card>
......
......@@ -16,15 +16,22 @@ limitations under the License.
<kd-resource-card-list selectable="::$ctrl.selectable"
with-statuses="::$ctrl.withStatuses"
select-id="cardlist.html"
select-id="{{::$ctrl.getSelectId()}}"
list="$ctrl.daemonSetList"
list-resource="$ctrl.daemonSetListResource">
<kd-resource-card-list-header ng-transclude="header">
[[Daemon Sets|Label which appears above the list of such objects.]]
<kd-resource-card-list-header>
<kd-resource-card-list-title ng-transclude="header">
[[Daemon Sets|Label which appears above the list of such objects.]]
</kd-resource-card-list-title>
<kd-resource-card-list-filter></kd-resource-card-list-filter>
</kd-resource-card-list-header>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
<kd-resource-card-header-columns>
<kd-zero-state ng-if="!$ctrl.daemonSetList.listMeta.totalItems">
<kd-zero-state-text ng-transclude="zerostate">
[[There are no Daemon Sets to display.|Text for daemon set card list zerostate.]]
</kd-zero-state-text>
</kd-zero-state>
<kd-resource-card-header-columns ng-show="$ctrl.daemonSetList.listMeta.totalItems">
<kd-resource-card-header-column size="small"
grow="2"
sortable="true"
......@@ -69,4 +76,8 @@ limitations under the License.
daemon-set="daemonSet"
show-resource-kind="::$ctrl.showResourceKind">
</kd-daemon-set-card>
<kd-resource-card-list-footer>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
</kd-resource-card-list-footer>
</kd-resource-card-list>
......@@ -64,6 +64,8 @@ export const daemonSetCardListComponent = {
transclude: {
// Optional header that is transcluded instead of the default one.
'header': '?kdHeader',
// Optional zerostate content that is shown when there are zero items.
'zerostate': '?kdEmptyListText',
},
templateUrl: 'daemonset/list/cardlist.html',
controller: DaemonSetCardListController,
......
......@@ -26,12 +26,13 @@ limitations under the License.
</kd-graph-card>
</div>
<kd-content-card ng-if="!ctrl.shouldShowZeroState()">
<kd-content-card>
<kd-content>
<kd-daemon-set-card-list daemon-set-list="::ctrl.daemonSetList"
<kd-daemon-set-card-list ng-if="!ctrl.shouldShowZeroState()"
daemon-set-list="::ctrl.daemonSetList"
daemon-set-list-resource="::ctrl.daemonSetListResource"
with-statuses="true">
</kd-daemon-set-card-list>
<kd-zero-state ng-if="ctrl.shouldShowZeroState()"></kd-zero-state>
</kd-content>
</kd-content-card>
<kd-zero-state ng-if="ctrl.shouldShowZeroState()"></kd-zero-state>
......@@ -32,14 +32,9 @@ limitations under the License.
<kd-content>
<kd-replica-set-card-list replica-set-list="::ctrl.newReplicaSetList">
<kd-header>[[New Replica Set|Title 'New Replica Set' for the newly created replica set view, on the deployment details page.]]</kd-header>
<kd-zerostate>
<div class="kd-zerostate-title">
[[There is nothing to display here|Title for new replica sets card zero-state in deployment details page.]]
</div>
<div class="kd-zerostate-text">
[[There are currently no new Replica Sets on this Deployment.|Text for new replica sets card zero-state in deployment details page.]]
</div>
</kd-zerostate>
<kd-empty-list-text>
[[There are currently no new Replica Sets on this Deployment.|Text for new replica sets card zero-state in deployment details page.]]
</kd-empty-list-text>
</kd-replica-set-card-list>
</kd-content>
</kd-content-card>
......@@ -49,14 +44,9 @@ limitations under the License.
<kd-replica-set-card-list replica-set-list="::ctrl.deploymentDetail.oldReplicaSetList"
replica-set-list-resource="::ctrl.oldReplicaSetListResource">
<kd-header>[[Old Replica Sets|Title 'Old Replica Sets' for the old replica sets view, on the deployment details page.]]</kd-header>
<kd-zerostate>
<div class="kd-zerostate-title">
[[There is nothing to display here|Title for old replica sets cards zero-state in deployment details page.]]
</div>
<div class="kd-zerostate-text">
[[This Deployment does not have any old replica sets|Text for old replica sets card zero-state in deployment details page.]]
</div>
</kd-zerostate>
<kd-empty-list-text>
[[This Deployment does not have any old replica sets|Text for old replica sets card zero-state in deployment details page.]]
</kd-empty-list-text>
</kd-replica-set-card-list>
</kd-content>
</kd-content-card>
......@@ -64,10 +54,9 @@ limitations under the License.
<kd-content-card>
<kd-content>
<kd-horizontal-pod-autoscaler-card-list horizontal-pod-autoscaler-list="::ctrl.deploymentDetail.horizontalPodAutoscalerList">
<kd-zerostate>
<div class="kd-zerostate-title">[[There is nothing to display here|Title for horizontal pod autoscalers card zerostate in replica set details page.]]</div>
<div class="kd-zerostate-text">[[There are currently no Horizontal Pod Autoscalers targeting this Deployment.|Text for horizontal pod autoscalers card zerostate in replica set details page.]]</div>
</kd-zerostate>
<kd-empty-list-text>
[[There are currently no Horizontal Pod Autoscalers targeting this Deployment.|Text for horizontal pod autoscalers card zerostate in replica set details page.]]
</kd-empty-list-text>
</kd-horizontal-pod-autoscaler-card-list>
</kd-content>
</kd-content-card>
......
......@@ -19,12 +19,19 @@ limitations under the License.
select-id="{{::$ctrl.getSelectId()}}"
list="$ctrl.deploymentList"
list-resource="::$ctrl.deploymentListResource">
<kd-resource-card-list-header ng-transclude="header">
[[Deployments|Label which appears above the list of such objects.]]
<kd-resource-card-list-header>
<kd-resource-card-list-title ng-transclude="header">
[[Deployments|Label which appears above the list of such objects.]]
</kd-resource-card-list-title>
<kd-resource-card-list-filter></kd-resource-card-list-filter>
</kd-resource-card-list-header>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
<kd-resource-card-header-columns>
<kd-zero-state ng-if="!$ctrl.deploymentList.listMeta.totalItems">
<kd-zero-state-text ng-transclude="zerostate">
[[There are no Deployment to display.|Text for deployment card list zerostate.]]
</kd-zero-state-text>
</kd-zero-state>
<kd-resource-card-header-columns ng-show="$ctrl.deploymentList.listMeta.totalItems">
<kd-resource-card-header-column size="small"
grow="2"
sortable="true"
......@@ -63,4 +70,8 @@ limitations under the License.
pagination-id="{{::$ctrl.getSelectId()}}"
total-items="$ctrl.deploymentList.listMeta.totalItems">
</kd-deployment-card>
<kd-resource-card-list-footer>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
</kd-resource-card-list-footer>
</kd-resource-card-list>
......@@ -62,6 +62,8 @@ export const deploymentCardListComponent = {
transclude: {
// Optional header that is transcluded instead of the default one.
'header': '?kdHeader',
// Optional zerostate content that is shown when there are zero items.
'zerostate': '?kdEmptyListText',
},
bindings: {
'deploymentList': '<',
......
......@@ -26,11 +26,12 @@ limitations under the License.
</kd-graph-card>
</div>
<kd-content-card ng-if="!$ctrl.shouldShowZeroState()">
<kd-content-card>
<kd-content>
<kd-deployment-card-list deployment-list="::$ctrl.deploymentList"
<kd-deployment-card-list ng-if="!$ctrl.shouldShowZeroState()"
deployment-list="::$ctrl.deploymentList"
deployment-list-resource="::$ctrl.deploymentListResource">
</kd-deployment-card-list>
<kd-zero-state ng-if="$ctrl.shouldShowZeroState()"></kd-zero-state>
</kd-content>
</kd-content-card>
<kd-zero-state ng-if="$ctrl.shouldShowZeroState()"></kd-zero-state>
......@@ -33,4 +33,9 @@ limitations under the License.
</kd-content>
</kd-content-card>
</div>
<kd-zero-state ng-if="$ctrl.shouldShowZeroState()"></kd-zero-state>
<kd-content-card ng-if="$ctrl.shouldShowZeroState()">
<kd-content>
<kd-zero-state></kd-zero-state>
</kd-content>
</kd-content-card>
......@@ -22,9 +22,16 @@ limitations under the License.
list="$ctrl.eventList"
list-resource="$ctrl.eventListResource">
<kd-resource-card-list-header>
[[Events|Label which appears above the list of such objects.]]
<kd-resource-card-list-title>
[[Events|Label which appears above the list of such objects.]]
</kd-resource-card-list-title>
</kd-resource-card-list-header>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
<kd-zero-state ng-if="!$ctrl.hasEvents()">
<kd-zero-state-text>
[[It is possible that all events have expired.|User help on the events page when no events are to be displayed.]]
</kd-zero-state-text>
</kd-zero-state>
<kd-resource-card-header-columns ng-show="$ctrl.hasEvents()">
<kd-resource-card-header-column size="medium"
grow="4">
......@@ -80,11 +87,10 @@ limitations under the License.
</kd-resource-card-column>
</kd-resource-card-columns>
</kd-resource-card>
<kd-zerostate class="kd-zerostate-message"
ng-if="!$ctrl.hasEvents()">
<div class="kd-zerostate-title">[[There is nothing to display here|Title of section when there are no events.]]</div>
<div class="kd-zerostate-text">[[It is possible that all events have expired.|User help on the events page when no events are to be displayed.]]</div>
</kd-zerostate>
<kd-resource-card-list-footer>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
</kd-resource-card-list-footer>
</kd-resource-card-list>
</kd-content>
</kd-content-card>
......@@ -14,18 +14,21 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
{{$ctrl.horizontalPodAutoscalerListResource}}
<kd-resource-card-list select-id="{{::$ctrl.getSelectId()}}"
list="$ctrl.horizontalPodAutoscalerList"
list-resource="$ctrl.horizontalPodAutoscalerListResource">
<kd-resource-card-list-header ng-transclude="header">
[[Horizontal Pod Autoscalers|Label which appears above the list of such objects.]]
<kd-resource-card-list-header>
<kd-resource-card-list-title ng-transclude="header">
[[Horizontal Pod Autoscalers|Label which appears above the list of such objects.]]
</kd-resource-card-list-title>
<kd-resource-card-list-filter></kd-resource-card-list-filter>
</kd-resource-card-list-header>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
<div ng-show="!$ctrl.horizontalPodAutoscalerList.listMeta.totalItems"
class="kd-zerostate-message"
ng-transclude="zerostate"></div>
<kd-zero-state ng-if="!$ctrl.horizontalPodAutoscalerList.listMeta.totalItems">
<kd-zero-state-text ng-transclude="zerostate">
[[There are no Horizontal Pod Autoscalers to display.|Text for horizontal pod autoscaler card list zerostate.]]
</kd-zero-state-text>
</kd-zero-state>
<kd-resource-card-header-columns ng-show="$ctrl.horizontalPodAutoscalerList.listMeta.totalItems">
<kd-resource-card-header-column size="small"
grow="2">
......@@ -71,4 +74,8 @@ limitations under the License.
horizontal-pod-autoscaler="horizontalPodAutoscaler"
show-scale-target="::$ctrl.showScaleTarget">
</kd-horizontal-pod-autoscaler-card>
<kd-resource-card-list-footer>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
</kd-resource-card-list-footer>
</kd-resource-card-list>
......@@ -66,7 +66,7 @@ export const horizontalPodAutoscalerCardListComponent = {
// Optional header that is transcluded instead of the default one.
'header': '?kdHeader',
// Optional zerostate content that is shown when there are zero items.
'zerostate': '?kdZerostate',
'zerostate': '?kdEmptyListText',
},
templateUrl: 'horizontalpodautoscaler/list/cardlist.html',
controller: HorizontalPodAutoscalerCardListController,
......
......@@ -14,13 +14,14 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
<kd-content-card ng-if="!ctrl.shouldShowZeroState()">
<kd-content-card>
<kd-content>
<kd-horizontal-pod-autoscaler-card-list horizontal-pod-autoscaler-list="ctrl.horizontalPodAutoscalerList"
<kd-horizontal-pod-autoscaler-card-list ng-if="!ctrl.shouldShowZeroState()"
horizontal-pod-autoscaler-list="ctrl.horizontalPodAutoscalerList"
horizontal-pod-autoscaler-list-resource="ctrl.horizontalPodAutoscalerListResource"
show-scale-target="true">
</kd-horizontal-pod-autoscaler-card-list>
<kd-zero-state ng-if="ctrl.shouldShowZeroState()"></kd-zero-state>
</kd-content>
</kd-content-card>
<kd-zero-state ng-if="ctrl.shouldShowZeroState()"></kd-zero-state>
......@@ -18,12 +18,19 @@ limitations under the License.
select-id="{{::$ctrl.getSelectId()}}"
list="$ctrl.ingressList"
list-resource="$ctrl.ingressListResource">
<kd-resource-card-list-header ng-transclude="header">
[[Ingresses|Label which appears above the list of such objects.]]
<kd-resource-card-list-header>
<kd-resource-card-list-title ng-transclude="header">
[[Ingresses|Label which appears above the list of such objects.]]
</kd-resource-card-list-title>
<kd-resource-card-list-filter></kd-resource-card-list-filter>
</kd-resource-card-list-header>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
<kd-resource-card-header-columns>
<kd-zero-state ng-if="!$ctrl.ingressList.listMeta.totalItems">
<kd-zero-state-text ng-transclude="zerostate">
[[There are no Ingresses to display.|Text for ingress card list zerostate.]]
</kd-zero-state-text>
</kd-zero-state>
<kd-resource-card-header-columns ng-show="$ctrl.ingressList.listMeta.totalItems">
<kd-resource-card-header-column size="small"
grow="2"
sortable="true"
......@@ -51,4 +58,8 @@ limitations under the License.
dir-paginate="ingress in $ctrl.ingressList.items | itemsPerPage: default"
total-items="::$ctrl.ingressList.listMeta.totalItems">
</kd-ingress-card>
<kd-resource-card-list-footer>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
</kd-resource-card-list-footer>
</kd-resource-card-list>
......@@ -64,6 +64,8 @@ export const ingressCardListComponent = {
transclude: {
// Optional header that is transcluded instead of the default one.
'header': '?kdHeader',
// Optional zerostate content that is shown when there are zero items.
'zerostate': '?kdEmptyListText',
},
templateUrl: 'ingress/list/cardlist.html',
controller: IngressCardListController,
......
......@@ -14,12 +14,13 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
<kd-content-card ng-if="!$ctrl.shouldShowZeroState()">
<kd-content-card>
<kd-content>
<kd-ingress-card-list ingress-list="$ctrl.ingressList"
<kd-ingress-card-list ng-if="!$ctrl.shouldShowZeroState()"
ingress-list="$ctrl.ingressList"
with-statuses="false"
ingress-list-resource="$ctrl.ingressListResource">
</kd-ingress-card-list>
<kd-zero-state ng-if="$ctrl.shouldShowZeroState()"></kd-zero-state>
</kd-content>
</kd-content-card>
<kd-zero-state ng-if="$ctrl.shouldShowZeroState()"></kd-zero-state>
......@@ -33,10 +33,9 @@ limitations under the License.
<kd-pod-card-list pod-list="::ctrl.jobDetail.podList"
with-statuses="true"
pod-list-resource="::ctrl.jobPodsResource">
<kd-zerostate>
<div class="kd-zerostate-title">[[There is nothing to display here|Title for pods card zerostate in job details page.]]</div>
<div class="kd-zerostate-text">[[There are currently no Pods managed by this Job.|Text for pods card zerostate in job details page.]]</div>
</kd-zerostate>
<kd-empty-list-text>
[[There are currently no Pods managed by this Job.|Text for pods card zerostate in job details page.]]
</kd-empty-list-text>
</kd-pod-card-list>
</kd-content>
</kd-content-card>
......
......@@ -19,12 +19,19 @@ limitations under the License.
select-id="{{::$ctrl.getSelectId()}}"
list="$ctrl.jobList"
list-resource="::$ctrl.jobListResource">
<kd-resource-card-list-header ng-transclude="header">
[[Jobs|Label which appears above the list of such objects.]]
<kd-resource-card-list-header>
<kd-resource-card-list-title ng-transclude="header">
[[Jobs|Label which appears above the list of such objects.]]
</kd-resource-card-list-title>
<kd-resource-card-list-filter></kd-resource-card-list-filter>
</kd-resource-card-list-header>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
<kd-resource-card-header-columns>
<kd-zero-state ng-if="!$ctrl.jobList.listMeta.totalItems">
<kd-zero-state-text ng-transclude="zerostate">
[[There are no Jobs to display.|Text for job card list zerostate.]]
</kd-zero-state-text>
</kd-zero-state>
<kd-resource-card-header-columns ng-show="$ctrl.jobList.listMeta.totalItems">
<kd-resource-card-header-column size="small"
grow="2"
sortable="true"
......@@ -69,4 +76,8 @@ limitations under the License.
show-resource-kind="::$ctrl.showResourceKind"
total-items="::$ctrl.jobList.listMeta.totalItems">
</kd-job-card>
<kd-resource-card-list-footer>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
</kd-resource-card-list-footer>
</kd-resource-card-list>
......@@ -62,6 +62,8 @@ export const jobCardListComponent = {
transclude: {
// Optional header that is transcluded instead of the default one.
'header': '?kdHeader',
// Optional zerostate content that is shown when there are zero items.
'zerostate': '?kdEmptyListText',
},
bindings: {
/** {!backendApi.JobList} */
......
......@@ -26,11 +26,12 @@ limitations under the License.
</kd-graph-card>
</div>
<kd-content-card ng-if="!$ctrl.shouldShowZeroState()">
<kd-content-card>
<kd-content>
<kd-job-card-list job-list="$ctrl.jobList"
<kd-job-card-list ng-if="!$ctrl.shouldShowZeroState()"
job-list="$ctrl.jobList"
job-list-resource="$ctrl.jobListResource">
</kd-job-card-list>
<kd-zero-state ng-if="$ctrl.shouldShowZeroState()"></kd-zero-state>
</kd-content>
</kd-content-card>
<kd-zero-state ng-if="$ctrl.shouldShowZeroState()"></kd-zero-state>
......@@ -19,12 +19,19 @@ limitations under the License.
select-id="{{::$ctrl.getSelectId()}}"
list="$ctrl.namespaceList"
list-resource="$ctrl.namespaceListResource">
<kd-resource-card-list-header ng-transclude="header">
[[Namespaces|Label which appears above the list of such objects.]]
<kd-resource-card-list-header>
<kd-resource-card-list-title ng-transclude="header">
[[Namespaces|Label which appears above the list of such objects.]]
</kd-resource-card-list-title>
<kd-resource-card-list-filter></kd-resource-card-list-filter>
</kd-resource-card-list-header>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
<kd-resource-card-header-columns>
<kd-zero-state ng-if="!$ctrl.namespaceList.listMeta.totalItems">
<kd-zero-state-text ng-transclude="zerostate">
[[There are no Namespaces to display.|Text for namespace card list zerostate.]]
</kd-zero-state-text>
</kd-zero-state>
<kd-resource-card-header-columns ng-show="$ctrl.namespaceList.listMeta.totalItems">
<kd-resource-card-header-column size="small"
grow="2"
sortable="true"
......@@ -51,4 +58,8 @@ limitations under the License.
namespace="ns"
total-items="::$ctrl.namespaceList.listMeta.totalItems">
</kd-namespace-card>
<kd-resource-card-list-footer>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
</kd-resource-card-list-footer>
</kd-resource-card-list>
......@@ -49,6 +49,8 @@ export const namespaceCardListComponent = {
transclude: {
// Optional header that is transcluded instead of the default one.
'header': '?kdHeader',
// Optional zerostate content that is shown when there are zero items.
'zerostate': '?kdEmptyListText',
},
controller: NamespaceCardListController,
bindings: {
......
......@@ -17,7 +17,9 @@ limitations under the License.
<kd-resource-card-list selectable="false"
with-statuses="false">
<kd-resource-card-list-header>
[[Allocated resources|Label 'Allocated resources' for the allocated resources section.]]
<kd-resource-card-list-title>
[[Allocated resources|Label 'Allocated resources' for the allocated resources section.]]
</kd-resource-card-list-title>
</kd-resource-card-list-header>
<kd-resource-card-header-columns>
<kd-resource-card-header-column size="large">
......
......@@ -33,10 +33,9 @@ limitations under the License.
<kd-pod-card-list pod-list="::ctrl.nodeDetail.podList"
pod-list-resource="::ctrl.podListResource"
with-statuses="true">
<kd-zerostate>
<div class="kd-zerostate-title">[[There is nothing to display here|Title for pods card zerostate in node details page.]]</div>
<div class="kd-zerostate-text">[[There are currently no Pods scheduled on this Node.|Text for pods card zerostate in node details page.]]</div>
</kd-zerostate>
<kd-empty-list-text>
[[There are currently no Pods scheduled on this Node.|Text for pods card zerostate in node details page.]]
</kd-empty-list-text>
</kd-pod-card-list>
</kd-content>
</kd-content-card>
......
......@@ -15,7 +15,11 @@ limitations under the License.
-->
<kd-info-card>
<kd-info-card-header>[[Details|Header in a detail view]]</kd-info-card-header>
<kd-info-card-header>
<kd-resource-card-list-title>
[[Details|Header in a detail view]]
</kd-resource-card-list-title>
</kd-info-card-header>
<kd-info-card-section>
<kd-object-meta-info-card object-meta="::$ctrl.node.objectMeta">
</kd-object-meta-info-card>
......
......@@ -19,12 +19,19 @@ limitations under the License.
select-id="{{::$ctrl.getSelectId()}}"
list="$ctrl.nodeList"
list-resource="::$ctrl.nodeListResource">
<kd-resource-card-list-header ng-transclude="header">
[[Nodes|Label which appears above the list of such objects.]]
<kd-resource-card-list-header>
<kd-resource-card-list-title ng-transclude="header">
[[Nodes|Label which appears above the list of such objects.]]
</kd-resource-card-list-title>
<kd-resource-card-list-filter></kd-resource-card-list-filter>
</kd-resource-card-list-header>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
<kd-resource-card-header-columns>
<kd-zero-state ng-if="!$ctrl.nodeList.listMeta.totalItems">
<kd-zero-state-text ng-transclude="zerostate">
[[There are no Nodes to display.|Text for node card list zerostate.]]
</kd-zero-state-text>
</kd-zero-state>
<kd-resource-card-header-columns ng-show="$ctrl.nodeList.listMeta.totalItems">
<kd-resource-card-header-column size="small"
grow="2"
sortable="true"
......@@ -51,4 +58,8 @@ limitations under the License.
node="node"
total-items="::$ctrl.nodeList.listMeta.totalItems">
</kd-node-card>
<kd-resource-card-list-footer>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
</kd-resource-card-list-footer>
</kd-resource-card-list>
......@@ -49,6 +49,8 @@ export const nodeCardListComponent = {
transclude: {
// Optional header that is transcluded instead of the default one.
'header': '?kdHeader',
// Optional zerostate content that is shown when there are zero items.
'zerostate': '?kdEmptyListText',
},
controller: NodeCardListController,
bindings: {
......
......@@ -19,12 +19,19 @@ limitations under the License.
select-id="{{::$ctrl.getSelectId()}}"
list="$ctrl.persistentVolumeList"
list-resource="$ctrl.persistentVolumeListResource">
<kd-resource-card-list-header ng-transclude="header">
[[Persistent Volumes|Label which appears above the list of such objects.]]
<kd-resource-card-list-header>
<kd-resource-card-list-title ng-transclude="header">
[[Persistent Volumes|Label which appears above the list of such objects.]]
</kd-resource-card-list-title>
<kd-resource-card-list-filter></kd-resource-card-list-filter>
</kd-resource-card-list-header>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
<kd-resource-card-header-columns>
<kd-zero-state ng-if="!$ctrl.persistentVolumeList.listMeta.totalItems">
<kd-zero-state-text ng-transclude="zerostate">
[[There are no Persistent Volumes to display.|Text for persistent volume card list zerostate.]]
</kd-zero-state-text>
</kd-zero-state>
<kd-resource-card-header-columns ng-show="$ctrl.persistentVolumeList.listMeta.totalItems">
<kd-resource-card-header-column size="small"
grow="2"
sortable="true"
......@@ -70,4 +77,8 @@ limitations under the License.
pagination-id="{{::$ctrl.getSelectId()}}"
total-items="::$ctrl.persistentVolumeList.listMeta.totalItems">
</kd-persistent-volume-card>
<kd-resource-card-list-footer>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
</kd-resource-card-list-footer>
</kd-resource-card-list>
......@@ -50,6 +50,8 @@ export const persistentVolumeCardListComponent = {
transclude: {
// Optional header that is transcluded instead of the default one.
'header': '?kdHeader',
// Optional zerostate content that is shown when there are zero items.
'zerostate': '?kdEmptyListText',
},
controller: PersistentVolumeCardListController,
bindings: {
......
......@@ -14,11 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
<kd-content-card ng-if="!$ctrl.shouldShowZeroState()">
<kd-content-card>
<kd-content>
<kd-persistent-volume-card-list persistent-volume-list="$ctrl.persistentVolumeList"
<kd-persistent-volume-card-list ng-if="!$ctrl.shouldShowZeroState()"
persistent-volume-list="$ctrl.persistentVolumeList"
persistent-volume-list-resource="$ctrl.persistentVolumeListResource">
</kd-persistent-volume-card-list>
<kd-zero-state ng-if="$ctrl.shouldShowZeroState()"></kd-zero-state>
</kd-content>
</kd-content-card>
<kd-zero-state ng-if="$ctrl.shouldShowZeroState()"></kd-zero-state>
......@@ -19,12 +19,19 @@ limitations under the License.
select-id="{{::$ctrl.getSelectId()}}"
list="$ctrl.persistentVolumeClaimList"
list-resource="$ctrl.persistentVolumeClaimListResource">
<kd-resource-card-list-header ng-transclude="header">
[[Persistent Volume Claims|Label which appears above the list of such objects.]]
<kd-resource-card-list-header>
<kd-resource-card-list-title ng-transclude="header">
[[Persistent Volume Claims|Label which appears above the list of such objects.]]
</kd-resource-card-list-title>
<kd-resource-card-list-filter></kd-resource-card-list-filter>
</kd-resource-card-list-header>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
<kd-resource-card-header-columns>
<kd-zero-state ng-if="!$ctrl.persistentVolumeClaimList.listMeta.totalItems">
<kd-zero-state-text ng-transclude="zerostate">
[[There are no Persistent Volume Claims to display.|Text for persistent volume claim card list zerostate.]]
</kd-zero-state-text>
</kd-zero-state>
<kd-resource-card-header-columns ng-show="$ctrl.persistentVolumeClaimList.listMeta.totalItems">
<kd-resource-card-header-column size="small"
grow="2"
sortable="true"
......@@ -56,4 +63,8 @@ limitations under the License.
persistent-volume-claim="persistentVolumeClaim"
total-items="$ctrl.persistentVolumeClaimList.listMeta.totalItems">
</kd-persistent-volume-claim-card>
<kd-resource-card-list-footer>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
</kd-resource-card-list-footer>
</kd-resource-card-list>
......@@ -63,6 +63,8 @@ export const persistentVolumeClaimCardListComponent = {
transclude: {
// Optional header that is transcluded instead of the default one.
'header': '?kdHeader',
// Optional zerostate content that is shown when there are zero items.
'zerostate': '?kdEmptyListText',
},
bindings: {
'persistentVolumeClaimList': '<',
......
......@@ -13,11 +13,12 @@ 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.
-->
<kd-content-card ng-if="!$ctrl.shouldShowZeroState()">
<kd-content-card>
<kd-content>
<kd-persistent-volume-claim-card-list persistent-volume-claim-list="$ctrl.persistentVolumeClaimList"
<kd-persistent-volume-claim-card-list ng-if="!$ctrl.shouldShowZeroState()"
persistent-volume-claim-list="$ctrl.persistentVolumeClaimList"
persistent-volume-claim-list-resource="$ctrl.persistentVolumeClaimListResource">
</kd-persistent-volume-claim-card-list>
<kd-zero-state ng-if="$ctrl.shouldShowZeroState()"></kd-zero-state>
</kd-content>
</kd-content-card>
<kd-zero-state ng-if="$ctrl.shouldShowZeroState()"></kd-zero-state>
......@@ -34,7 +34,7 @@ limitations under the License.
</span><span>:&nbsp;</span>
<kd-middle-ellipsis display-string="{{::env.value}}"
flex="shrink">
<kd-middle-ellipsis>
</kd-middle-ellipsis>
</div>
</div>
<div ng-if="::!container.env.length">
......
......@@ -19,120 +19,122 @@ limitations under the License.
<kd-resource-card-list selectable="false"
with-statuses="true">
<kd-resource-card-list-header>
[[Created by|Heading for Creator card on pod detail page.]]
<kd-resource-card-list-title>
[[Created by|Heading for Creator card on pod detail page.]]
</kd-resource-card-list-title>
</kd-resource-card-list-header>
<div ng-if="$ctrl.creator">
<kd-resource-card-header-columns>
<kd-resource-card-header-column size="small"
grow="2">
[[Name|Label 'Name' which appears as a column label in the creator card.]]
</kd-resource-card-header-column>
<kd-resource-card-header-column size="small"
grow="1">
[[Kind|Label 'Kind' which appears as a column label in the creator card.]]
</kd-resource-card-header-column>
<kd-resource-card-header-column size="small"
grow="2"
ng-if="$ctrl.areMultipleNamespacesSelected()">
[[Namespace|Label 'Namespace' which appears as a column label in the creator card.]]
</kd-resource-card-header-column>
<kd-resource-card-header-column size="small"
grow="2">
[[Labels|Label 'Labels' which appears as a column label in the creator card.]]
</kd-resource-card-header-column>
<kd-resource-card-header-column size="small"
grow="1">
[[Pods|Label 'Pods' which appears as a column label in the creator card.]]
</kd-resource-card-header-column>
<kd-resource-card-header-column size="small"
grow="1">
[[Age|Label 'Age' which appears as a column label in the creator card.]]
</kd-resource-card-header-column>
<kd-resource-card-header-column size="small"
grow="2">
[[Images|Label 'Images' which appears as a column label in the creator card.]]
</kd-resource-card-header-column>
<kd-resource-card-header-column size="small"
grow="nogrow">
</kd-resource-card-header-column>
</kd-resource-card-header-columns>
<kd-resource-card object-meta="$ctrl.creator.objectMeta"
type-meta="$ctrl.creator.typeMeta">
<kd-resource-card-status layout="row">
<md-icon class="material-icons md-warn"
ng-if="::$ctrl.hasWarnings()">
error
<md-tooltip>One or more pods have errors</md-tooltip>
</md-icon>
<md-icon class="material-icons"
ng-if="::$ctrl.isPending()">
timelapse
<md-tooltip>One or more pods are in pending state</md-tooltip>
</md-icon>
<md-icon class="material-icons kd-success"
ng-if="::$ctrl.isSuccess()">
check_circle
</md-icon>
</kd-resource-card-status>
<kd-resource-card-columns>
<kd-resource-card-column>
<div>
<a ng-href="{{::$ctrl.getCreatorDetailHref()}}"
class="kd-middle-ellipsised-link">
<kd-middle-ellipsis display-string="{{$ctrl.creator.objectMeta.name}}">
</kd-middle-ellipsis>
</a>
</div>
</kd-resource-card-column>
<kd-resource-card-column>
{{::$ctrl.creator.typeMeta.kind}}
</kd-resource-card-column>
<kd-resource-card-column ng-if="$ctrl.areMultipleNamespacesSelected()">
<div>
<kd-middle-ellipsis display-string="{{::$ctrl.creator.objectMeta.namespace}}">
<kd-zero-state ng-if="!$ctrl.creator.typeMeta.kind">
<kd-zero-state-text>
[[This Pod does not have a creator.|Text for pod creator zero state in pod details page.]]
</kd-zero-state-text>
</kd-zero-state>
<kd-resource-card-header-columns ng-show="$ctrl.creator.typeMeta.kind">
<kd-resource-card-header-column size="small"
grow="2">
[[Name|Label 'Name' which appears as a column label in the creator card.]]
</kd-resource-card-header-column>
<kd-resource-card-header-column size="small"
grow="1">
[[Kind|Label 'Kind' which appears as a column label in the creator card.]]
</kd-resource-card-header-column>
<kd-resource-card-header-column size="small"
grow="2"
ng-if="$ctrl.areMultipleNamespacesSelected()">
[[Namespace|Label 'Namespace' which appears as a column label in the creator card.]]
</kd-resource-card-header-column>
<kd-resource-card-header-column size="small"
grow="2">
[[Labels|Label 'Labels' which appears as a column label in the creator card.]]
</kd-resource-card-header-column>
<kd-resource-card-header-column size="small"
grow="1">
[[Pods|Label 'Pods' which appears as a column label in the creator card.]]
</kd-resource-card-header-column>
<kd-resource-card-header-column size="small"
grow="1">
[[Age|Label 'Age' which appears as a column label in the creator card.]]
</kd-resource-card-header-column>
<kd-resource-card-header-column size="small"
grow="2">
[[Images|Label 'Images' which appears as a column label in the creator card.]]
</kd-resource-card-header-column>
<kd-resource-card-header-column size="small"
grow="nogrow">
</kd-resource-card-header-column>
</kd-resource-card-header-columns>
<kd-resource-card ng-if="$ctrl.creator.typeMeta.kind"
object-meta="$ctrl.creator.objectMeta"
type-meta="$ctrl.creator.typeMeta">
<kd-resource-card-status layout="row">
<md-icon class="material-icons md-warn"
ng-if="::$ctrl.hasWarnings()">
error
<md-tooltip>One or more pods have errors</md-tooltip>
</md-icon>
<md-icon class="material-icons"
ng-if="::$ctrl.isPending()">
timelapse
<md-tooltip>One or more pods are in pending state</md-tooltip>
</md-icon>
<md-icon class="material-icons kd-success"
ng-if="::$ctrl.isSuccess()">
check_circle
</md-icon>
</kd-resource-card-status>
<kd-resource-card-columns>
<kd-resource-card-column>
<div>
<a ng-href="{{::$ctrl.getCreatorDetailHref()}}"
class="kd-middle-ellipsised-link">
<kd-middle-ellipsis display-string="{{$ctrl.creator.objectMeta.name}}">
</kd-middle-ellipsis>
</div>
</kd-resource-card-column>
<kd-resource-card-column>
<kd-labels labels="::$ctrl.creator.objectMeta.labels"></kd-labels>
</kd-resource-card-column>
<kd-resource-card-column>
<span class="kd-replicase-card-pods-stat">
</a>
</div>
</kd-resource-card-column>
<kd-resource-card-column>
{{::$ctrl.creator.typeMeta.kind}}
</kd-resource-card-column>
<kd-resource-card-column ng-if="$ctrl.areMultipleNamespacesSelected()">
<div>
<kd-middle-ellipsis display-string="{{::$ctrl.creator.objectMeta.namespace}}">
</kd-middle-ellipsis>
</div>
</kd-resource-card-column>
<kd-resource-card-column>
<kd-labels labels="::$ctrl.creator.objectMeta.labels"></kd-labels>
</kd-resource-card-column>
<kd-resource-card-column>
<span class="kd-replicase-card-pods-stat">
{{::$ctrl.creator.pods.running}} / {{::$ctrl.creator.pods.desired}}
</span>
</kd-resource-card-column>
<kd-resource-card-column>
{{::$ctrl.creator.objectMeta.creationTimestamp | relativeTime}}
<md-tooltip>
Created at {{::$ctrl.creator.objectMeta.creationTimestamp | date}}
</md-tooltip>
</kd-resource-card-column>
<kd-resource-card-column>
<div ng-repeat="image in ::$ctrl.creator.containerImages track by $index">
<kd-middle-ellipsis display-string="{{::image}}"></kd-middle-ellipsis>
</div>
</kd-resource-card-column>
<kd-resource-card-column class="kd-row-layout-column kd-icon-column">
<kd-resource-card-menu>
<kd-resource-card-delete-menu-item resource-kind-name="{{::$ctrl.creator.typeMeta.kind}}">
</kd-resource-card-delete-menu-item>
</kd-resource-card-menu>
</kd-resource-card-column>
</kd-resource-card-columns>
<kd-resource-card-footer ng-if="::$ctrl.hasWarnings()">
<div ng-repeat="warning in ::$ctrl.creator.pods.warnings">
<span class="kd-error">{{::warning.message}}</span>
</kd-resource-card-column>
<kd-resource-card-column>
{{::$ctrl.creator.objectMeta.creationTimestamp | relativeTime}}
<md-tooltip>
Created at {{::$ctrl.creator.objectMeta.creationTimestamp | date}}
</md-tooltip>
</kd-resource-card-column>
<kd-resource-card-column>
<div ng-repeat="image in ::$ctrl.creator.containerImages track by $index">
<kd-middle-ellipsis display-string="{{::image}}"></kd-middle-ellipsis>
</div>
</kd-resource-card-footer>
</kd-resource-card>
</div>
<div class="kd-zerostate-message"
ng-if="!$ctrl.creator">
<kd-zerostate>
<div class="kd-zerostate-title">[[There is nothing to display here|Title for pods card zero state in pod details page.]]</div>
<div class="kd-zerostate-text">[[This Pod does not have a creator.|Text for pod creator zero state in pod details page.]]</div>
</kd-zerostate>
</div>
</kd-resource-card-column>
<kd-resource-card-column class="kd-row-layout-column kd-icon-column">
<kd-resource-card-menu>
<kd-resource-card-delete-menu-item resource-kind-name="{{::$ctrl.creator.typeMeta.kind}}">
</kd-resource-card-delete-menu-item>
</kd-resource-card-menu>
</kd-resource-card-column>
</kd-resource-card-columns>
<kd-resource-card-footer ng-if="::$ctrl.hasWarnings()">
<div ng-repeat="warning in ::$ctrl.creator.pods.warnings">
<span class="kd-error">{{::warning.message}}</span>
</div>
</kd-resource-card-footer>
</kd-resource-card>
</kd-resource-card-list>
</kd-content>
</kd-content-card>
......@@ -14,21 +14,24 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
<kd-resource-card-list ng-if="::$ctrl.podList.pods"
selectable="::$ctrl.selectable"
<kd-resource-card-list selectable="::$ctrl.selectable"
with-statuses="::$ctrl.withStatuses"
select-id="{{::$ctrl.getSelectId()}}"
list="$ctrl.podList"
list-resource="$ctrl.podListResource">
<kd-resource-card-list-header ng-transclude="header">
[[Pods|Label which appears above the list of such objects.]]
<kd-resource-card-list-header>
<kd-resource-card-list-title ng-transclude="header">
[[Pods|Label which appears above the list of such objects.]]
</kd-resource-card-list-title>
<kd-resource-card-list-filter></kd-resource-card-list-filter>
</kd-resource-card-list-header>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
<div ng-show="!$ctrl.podList.listMeta.totalItems"
class="kd-zerostate-message"
ng-transclude="zerostate"></div>
<kd-resource-card-header-columns ng-show="::$ctrl.podList.listMeta.totalItems">
<kd-zero-state ng-if="!$ctrl.podList.listMeta.totalItems">
<kd-zero-state-text ng-transclude="zerostate">
[[There are no Pods to display.|Text for pods card list zerostate.]]
</kd-zero-state-text>
</kd-zero-state>
<kd-resource-card-header-columns ng-show="$ctrl.podList.listMeta.totalItems">
<kd-resource-card-header-column size="small"
grow="2"
sortable="true"
......@@ -76,4 +79,8 @@ limitations under the License.
show-metrics="::$ctrl.showMetrics()"
total-items="::$ctrl.podList.listMeta.totalItems">
</kd-pod-card>
<kd-resource-card-list-footer>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
</kd-resource-card-list-footer>
</kd-resource-card-list>
......@@ -85,7 +85,7 @@ export const podCardListComponent = {
// Optional header that is transcluded instead of the default one.
'header': '?kdHeader',
// Optional zerostate content that is shown when there are zero items.
'zerostate': '?kdZerostate',
'zerostate': '?kdEmptyListText',
},
templateUrl: 'pod/list/cardlist.html',
controller: PodCardListController,
......
......@@ -26,12 +26,13 @@ limitations under the License.
</kd-graph-card>
</div>
<kd-content-card ng-if="!$ctrl.shouldShowZeroState()">
<kd-content-card>
<kd-content>
<kd-pod-card-list pod-list="$ctrl.podList"
pod-list-resource="$ctrl.podListResource"
with-statuses="true">
with-statuses="true"
ng-if="!$ctrl.shouldShowZeroState()">
</kd-pod-card-list>
<kd-zero-state ng-if="$ctrl.shouldShowZeroState()"></kd-zero-state>
</kd-content>
</kd-content-card>
<kd-zero-state ng-if="$ctrl.shouldShowZeroState()"></kd-zero-state>
......@@ -32,10 +32,9 @@ limitations under the License.
<kd-pod-card-list pod-list="::ctrl.replicaSetDetail.podList"
with-statuses="true"
pod-list-resource="::ctrl.replicaSetPodsResource">
<kd-zerostate>
<div class="kd-zerostate-title">[[There is nothing to display here|Title for pods card zerostate in replica set details page.]]</div>
<div class="kd-zerostate-text">[[There are currently no Pods managed by this Replica Set|Text for pods card zerostate in replica set details page.]]</div>
</kd-zerostate>
<kd-empty-list-text>
[[There are currently no Pods managed by this Replica Set|Text for pods card zerostate in replica set details page.]]
</kd-empty-list-text>
</kd-pod-card-list>
</kd-content>
</kd-content-card>
......@@ -43,10 +42,9 @@ limitations under the License.
<kd-content>
<kd-service-card-list service-list="::ctrl.replicaSetDetail.serviceList"
service-list-resource="::ctrl.replicaSetServicesResource">
<kd-zerostate>
<div class="kd-zerostate-title">[[There is nothing to display here|Title for services card zerostate in replica set details page.]]</div>
<div class="kd-zerostate-text">[[There are currently no Services with the same label selector as this Replica Set.|Text for services card zerostate in replica set details page.]]</div>
</kd-zerostate>
<kd-empty-list-text>
[[There are currently no Services with the same label selector as this Replica Set.|Text for services card zerostate in replica set details page.]]
</kd-empty-list-text>
</kd-service-card-list>
</kd-content>
</kd-content-card>
......@@ -54,10 +52,9 @@ limitations under the License.
<kd-content-card>
<kd-content>
<kd-horizontal-pod-autoscaler-card-list horizontal-pod-autoscaler-list="::ctrl.replicaSetDetail.horizontalPodAutoscalerList">
<kd-zerostate>
<div class="kd-zerostate-title">[[There is nothing to display here|Title for horizontal pod autoscalers card zerostate in replica set details page.]]</div>
<div class="kd-zerostate-text">[[There are currently no Horizontal Pod Autoscalers targeting this Replica Set.|Text for horizontal pod autoscalers card zerostate in replica set details page.]]</div>
</kd-zerostate>
<kd-empty-list-text>
[[There are currently no Horizontal Pod Autoscalers targeting this Replica Set.|Text for horizontal pod autoscalers card zerostate in replica set details page.]]
</kd-empty-list-text>
</kd-horizontal-pod-autoscaler-card-list>
</kd-content>
</kd-content-card>
......
......@@ -19,10 +19,18 @@ limitations under the License.
select-id="{{::$ctrl.getSelectId()}}"
list="$ctrl.replicaSetList"
list-resource="::$ctrl.replicaSetListResource">
<kd-resource-card-list-header ng-transclude="header">
[[Replica Sets|Label which appears above the list of such objects.]]
<kd-resource-card-list-header>
<kd-resource-card-list-title ng-transclude="header">
[[Replica Sets|Label which appears above the list of such objects.]]
</kd-resource-card-list-title>
<kd-resource-card-list-filter></kd-resource-card-list-filter>
</kd-resource-card-list-header>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
<kd-zero-state ng-if="!$ctrl.replicaSetList.listMeta.totalItems">
<kd-zero-state-text ng-transclude="zerostate">
[[There are no Replica Sets to display.|Text for replica set card list zerostate.]]
</kd-zero-state-text>
</kd-zero-state>
<kd-resource-card-header-columns ng-show="$ctrl.replicaSetList.listMeta.totalItems">
<kd-resource-card-header-column size="small"
grow="2"
......@@ -68,8 +76,8 @@ limitations under the License.
show-resource-kind="::$ctrl.showResourceKind"
total-items="::$ctrl.replicaSetList.listMeta.totalItems">
</kd-replica-set-card>
<div ng-show="!$ctrl.replicaSetList.listMeta.totalItems"
class="kd-zerostate-message"
ng-transclude="zerostate"></div>
<kd-resource-card-list-footer>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
</kd-resource-card-list-footer>
</kd-resource-card-list>
......@@ -65,7 +65,7 @@ export const replicaSetCardListComponent = {
// Optional header that is transcluded instead of the default one.
'header': '?kdHeader',
// Optional zerostate content that is shown when there are zero items.
'zerostate': '?kdZerostate',
'zerostate': '?kdEmptyListText',
},
bindings: {
'replicaSetList': '<',
......
......@@ -26,11 +26,12 @@ limitations under the License.
</kd-graph-card>
</div>
<kd-content-card ng-if="!$ctrl.shouldShowZeroState()">
<kd-content-card>
<kd-content>
<kd-replica-set-card-list replica-set-list="$ctrl.replicaSetList"
<kd-replica-set-card-list ng-if="!$ctrl.shouldShowZeroState()"
replica-set-list="$ctrl.replicaSetList"
replica-set-list-resource="$ctrl.replicaSetListResource">
</kd-replica-set-card-list>
<kd-zero-state ng-if="$ctrl.shouldShowZeroState()"></kd-zero-state>
</kd-content>
</kd-content-card>
<kd-zero-state ng-if="$ctrl.shouldShowZeroState()"></kd-zero-state>
......@@ -33,10 +33,9 @@ limitations under the License.
<kd-content>
<kd-service-card-list service-list="::$ctrl.replicationControllerDetail.serviceList"
service-list-resource="::$ctrl.serviceListResource">
<kd-zerostate>
<div class="kd-zerostate-title">[[There is nothing to display here|Title for services card zerostate in replication controller details page.]]</div>
<div class="kd-zerostate-text">[[There are currently no Services with the same label selector as this Replication Controller.|Text for services card zerostate in replication controller details page.]]</div>
</kd-zerostate>
<kd-empty-list-text>
[[There are currently no Services with the same label selector as this Replication Controller.|Text for services card zerostate in replication controller details page.]]
</kd-empty-list-text>
</kd-service-card-list>
</kd-content>
</kd-content-card>
......@@ -46,10 +45,9 @@ limitations under the License.
<kd-pod-card-list pod-list="::$ctrl.replicationControllerDetail.podList"
pod-list-resource="::$ctrl.podListResource"
with-statuses="true">
<kd-zerostate>
<div class="kd-zerostate-title">[[There is nothing to display here|Title for pods card zerostate in replication controller details page.]]</div>
<div class="kd-zerostate-text">[[There are currently no Pods managed by this Replication Controller.|Text for pods card zerostate in replication controller details page.]]</div>
</kd-zerostate>
<kd-empty-list-text>
[[There are currently no Pods managed by this Replication Controller.|Text for pods card zerostate in replication controller details page.]]
</kd-empty-list-text>
</kd-pod-card-list>
</kd-content>
</kd-content-card>
......@@ -57,10 +55,9 @@ limitations under the License.
<kd-content-card>
<kd-content>
<kd-horizontal-pod-autoscaler-card-list horizontal-pod-autoscaler-list="::$ctrl.replicationControllerDetail.horizontalPodAutoscalerList">
<kd-zerostate>
<div class="kd-zerostate-title">[[There is nothing to display here|Title for horizontal pod autoscalers card zerostate in replica set details page.]]</div>
<div class="kd-zerostate-text">[[There are currently no Horizontal Pod Autoscalers targeting this Replication Controller.|Text for horizontal pod autoscalers card zerostate in replica set details page.]]</div>
</kd-zerostate>
<kd-empty-list-text>
[[There are currently no Horizontal Pod Autoscalers targeting this Replication Controller.|Text for horizontal pod autoscalers card zerostate in replica set details page.]]
</kd-empty-list-text>
</kd-horizontal-pod-autoscaler-card-list>
</kd-content>
</kd-content-card>
......
......@@ -19,12 +19,19 @@ limitations under the License.
select-id="{{::$ctrl.getSelectId()}}"
list="$ctrl.replicationControllerList"
list-resource="$ctrl.replicationControllerListResource">
<kd-resource-card-list-header ng-transclude="header">
[[Replication Controllers|Label which appears above the list of such objects.]]
<kd-resource-card-list-header>
<kd-resource-card-list-title ng-transclude="header">
[[Replication Controllers|Label which appears above the list of such objects.]]
</kd-resource-card-list-title>
<kd-resource-card-list-filter></kd-resource-card-list-filter>
</kd-resource-card-list-header>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
<kd-resource-card-header-columns>
<kd-zero-state ng-if="!$ctrl.replicationControllerList.listMeta.totalItems">
<kd-zero-state-text ng-transclude="zerostate">
[[There are no Replication Controllers to display.|Text for replication controller card list zerostate.]]
</kd-zero-state-text>
</kd-zero-state>
<kd-resource-card-header-columns ng-show="$ctrl.replicationControllerList.listMeta.totalItems">
<kd-resource-card-header-column size="small"
grow="2"
sortable="true"
......@@ -70,4 +77,8 @@ limitations under the License.
show-resource-kind="::$ctrl.showResourceKind"
total-items="$ctrl.replicationControllerList.listMeta.totalItems">
</kd-replication-controller-card>
<kd-resource-card-list-footer>
<kd-resource-card-list-pagination></kd-resource-card-list-pagination>
</kd-resource-card-list-footer>
</kd-resource-card-list>
......@@ -63,6 +63,8 @@ export const replicationControllerCardListComponent = {
transclude: {
// Optional header that is transcluded instead of the default one.
'header': '?kdHeader',
// Optional zerostate content that is shown when there are zero items.
'zerostate': '?kdEmptyListText',
},
bindings: {
'replicationControllerList': '<',
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册