Skip to content

Commit

Permalink
fix: Add empty tip if workspace has no cluster
Browse files Browse the repository at this point in the history
  • Loading branch information
leoliu committed Jun 9, 2020
1 parent f738068 commit 9dfd319
Show file tree
Hide file tree
Showing 14 changed files with 138 additions and 32 deletions.
5 changes: 3 additions & 2 deletions server/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ client:
icon: earth
children:
- { name: networkpolicies, title: Network Policies }
- { name: customresources, title: Custom Resources, icon: select }
# Contains dangerous operations, only available for platform-admin.
- { name: customresources, title: Custom Resources, icon: select, admin: true }
- name: storage
title: Storage Management
icon: database
Expand Down Expand Up @@ -345,7 +346,7 @@ client:

# preset infos
presetUsers: ['admin', 'sonarqube']
presetGlobalRoles: ['global-admin']
presetGlobalRoles: ['platform-admin']
presetClusterRoles: [cluster-admin, cluster-regular, workspaces-manager]
presetWorkspaceRoles: [workspace-admin, workspace-regular, workspace-viewer]
presetDevOpsRoles: [owner, maintainer, developer, reporter]
Expand Down
3 changes: 2 additions & 1 deletion src/actions/project.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default {
const modal = Modal.open({
onOk: data => {
set(data, 'metadata.labels["kubesphere.io/workspace"]', workspace)
store.create(data).then(() => {
store.create(data, { cluster, workspace }).then(() => {
const clusters = get(data, 'spec.placement.clusters', [])
clusters.length > 1 &&
federatedStore.create(FED_TEMPLATES.namespaces(data), {
Expand All @@ -50,6 +50,7 @@ export default {
})
},
hideCluster: !globals.app.isMultiCluster || !!cluster,
cluster,
workspace,
formTemplate: FORM_TEMPLATES.project(),
modal: ProjectCreateModal,
Expand Down
5 changes: 3 additions & 2 deletions src/components/Modals/ProjectCreate/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ export default class ProjectCreateModal extends React.Component {
return callback()
}

this.props.store.checkName({ name: value }).then(resp => {
const { cluster } = this.props
this.props.store.checkName({ name: value, cluster }).then(resp => {
if (resp.exist) {
return callback({ message: t('Name exists'), field: rule.field })
}
Expand Down Expand Up @@ -195,7 +196,7 @@ export default class ProjectCreateModal extends React.Component {
<Select
name="metadata.annotations['kubesphere.io/network-isolate']"
options={this.networkOptions}
defaultValue={'enabled'}
defaultValue=""
/>
</Form.Item>
</Column>
Expand Down
8 changes: 7 additions & 1 deletion src/locales/en/workspace.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ export default {

WORKSPACE_ROLE_DESC:
"Workspace role determines the role's authorizations in the current workspace.",

SEARCH_WORKSPACE_TIP: 'Please enter the workspace name to search',

NO_PUBLIC_CLUSTER_TIP:
'There are no public clusters available, please apply for cluster authorization from the platform administrator or cluster administrator after workspace is created',

NO_CLUSTER_TIP:
'You need to contact the platform administrator or cluster administrator to authorize the access rights of the cluster for the workspace',
}
7 changes: 7 additions & 0 deletions src/locales/zh/workspace.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ export default {

'Clusters Info': '集群信息',

'No Available Cluster': '暂时没有可用集群',

WORKSPACE_OVERVIEW_DESC:
'企业空间为 KubeSphere 提供了安全隔离的、具有访问权限控制的工作平台。这里您可以看到当前企业空间内资源运行的概况。',

Expand Down Expand Up @@ -101,4 +103,9 @@ export default {
HOW_TO_APPLY_MORE_CLUSTER_Q: '如何为企业空间申请更多的集群?',
HOW_TO_APPLY_MORE_CLUSTER_A:
'集群由平台管理员以及集群管理员共同运营维护,如果您需要使用更多的集群请联系您的平台管理员,或者提交申请',

NO_PUBLIC_CLUSTER_TIP:
'暂无可用的公开集群, 请在企业空间创建完毕后, 向平台管理员或集群管理员申请集群的授权',
NO_CLUSTER_TIP:
'您需要联系平台管理员或者集群管理员为企业空间授权集群的访问权限',
}
8 changes: 5 additions & 3 deletions src/pages/clusters/containers/layout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,11 @@ export default class App extends Component {
this.props.rootStore.getRules({ cluster: params.cluster }),
])

this.store.fetchProjects({
cluster: params.cluster,
})
if (this.store.detail.isReady) {
await this.store.fetchProjects({
cluster: params.cluster,
})
}

globals.app.cacheHistory(this.props.match.url, {
type: 'Cluster',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ export default class BaseInfo extends React.Component {
}))
}

get networkOptions() {
return [
{ label: t('Off'), value: '' },
{ label: t('On'), value: 'enabled' },
]
}

nameValidator = (rule, value, callback) => {
if (!value) {
return callback()
Expand Down Expand Up @@ -151,6 +158,16 @@ export default class BaseInfo extends React.Component {
onMenuScrollToBottom={this.handleScrollToBottom}
/>
</Form.Item>
<Form.Item
label={t('Network Isolated')}
desc={t('NETWORK_ISOLATED_DESC')}
>
<Select
name="metadata.annotations['kubesphere.io/network-isolate']"
options={this.networkOptions}
defaultValue=""
/>
</Form.Item>
<Form.Item
controlClassName={styles.textarea}
label={t('Description')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@

import React, { Component } from 'react'
import classNames from 'classnames'
import { isEmpty } from 'lodash'
import { toJS } from 'mobx'
import { observer } from 'mobx-react'
import { Checkbox } from '@pitrix/lego-ui'
import { Alert } from 'components/Base'
import ClusterTitle from 'components/ClusterTitle'

import ClusterStore from 'stores/cluster'
Expand Down Expand Up @@ -57,9 +60,15 @@ export default class ClusterSettings extends Component {

render() {
const { value = [] } = this.props
const { data, isLoading } = toJS(this.clusterStore.list)

if (isEmpty(data) && !isLoading) {
return <Alert type="warning" message={t('NO_PUBLIC_CLUSTER_TIP')} />
}

return (
<div className={styles.wrapper}>
{this.clusterStore.list.data.map(cluster => (
{data.map(cluster => (
<div
key={cluster.name}
className={classNames(styles.item, {
Expand Down
17 changes: 17 additions & 0 deletions src/pages/workspaces/components/ResourceTable/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/

import React from 'react'
import { isEmpty } from 'lodash'

import {
Dropdown,
Expand All @@ -28,6 +29,7 @@ import {
} from '@pitrix/lego-ui'
import { Button } from 'components/Base'
import BaseTable from 'components/Tables/Base'
import EmptyList from 'components/Cards/EmptyList'
import withTableActions from 'components/HOCs/withTableActions'
import ClusterSelect from './ClusterSelect'

Expand Down Expand Up @@ -71,6 +73,21 @@ class ResourceTable extends BaseTable {
</Level>
)
}

render() {
const { clusters } = this.props
if (isEmpty(clusters)) {
return (
<EmptyList
icon="cluster"
title={t('No Available Cluster')}
desc={t('NO_CLUSTER_TIP')}
/>
)
}

return BaseTable.prototype.render.call(this)
}
}

export default withTableActions(ResourceTable)
7 changes: 6 additions & 1 deletion src/pages/workspaces/containers/BaseInfo/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,16 @@ class BaseInfo extends React.Component {
return <Panel title={t('Network Policy')}>xxx</Panel>
}

const { data, isLoading } = toJS(this.store.clusters)

const { workspaces } = this.state

return (
<Panel className={styles.network} title={t('Network Policy')}>
{this.store.clusters.data.map(cluster => {
{isEmpty(data) && !isLoading && (
<div className={styles.empty}>{t('No Available Cluster')}</div>
)}
{data.map(cluster => {
const workspace = workspaces[cluster.name] || {}
const networkIsolation = workspace.networkIsolation || false
return (
Expand Down
8 changes: 8 additions & 0 deletions src/pages/workspaces/containers/BaseInfo/index.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@import '~scss/variables';
@import '~scss/mixins';

.header {
position: relative;
Expand Down Expand Up @@ -69,4 +70,11 @@

.clusterTitle {
width: 50%;
}

.empty {
padding: 12px;
background-color: $card-bg-color;
border-radius: $border-radius;
@include TypographyTitleH5($dark-color01);
}
18 changes: 15 additions & 3 deletions src/pages/workspaces/containers/Clusters/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@
*/

import React from 'react'
import { isEmpty } from 'lodash'
import { toJS } from 'mobx'
import { observer, inject } from 'mobx-react'
import Banner from 'components/Cards/Banner'
import EmptyList from 'components/Cards/EmptyList'

import ClusterMonitorStore from 'stores/monitoring/cluster'

Expand Down Expand Up @@ -64,9 +67,18 @@ class BaseInfo extends React.Component {
return null
}

return this.store.clusters.data.map(cluster => (
<Card key={cluster.name} cluster={cluster} />
))
const { data, isLoading } = toJS(this.store.clusters)
if (isEmpty(data) && !isLoading) {
return (
<EmptyList
icon="cluster"
title={t('No Available Cluster')}
desc={t('NO_CLUSTER_TIP')}
/>
)
}

return data.map(cluster => <Card key={cluster.name} cluster={cluster} />)
}

render() {
Expand Down
16 changes: 14 additions & 2 deletions src/pages/workspaces/containers/Overview/ResourceUsage/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import React from 'react'
import { inject, observer } from 'mobx-react'

import EmptyList from 'components/Cards/EmptyList'
import WorkspaceStore from 'stores/workspace'

import ResourceStatistics from './Statistics'
Expand Down Expand Up @@ -54,11 +54,21 @@ class ResourceUsage extends React.Component {
this.workspaceStore.fetchClusters({ workspace: this.workspace })
}

renderEmpty() {
return (
<EmptyList
icon="cluster"
title={t('No Available Cluster')}
desc={t('NO_CLUSTER_TIP')}
/>
)
}

render() {
return (
<div>
<ResourceStatistics workspace={this.workspace} />
{this.workspaceStore.clusters.data.length > 0 && (
{this.workspaceStore.clusters.data.length > 0 ? (
<>
<PhysicalResource
workspace={this.workspace}
Expand All @@ -71,6 +81,8 @@ class ResourceUsage extends React.Component {
defaultCluster={this.defaultCluster}
/>
</>
) : (
this.renderEmpty()
)}
</div>
)
Expand Down
40 changes: 24 additions & 16 deletions src/pages/workspaces/containers/Overview/UsageRanking/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import classNames from 'classnames'
import { get } from 'lodash'

import Store from 'stores/rank/project'
import WorkspaceStore from 'stores/workspace'

import {
Select,
Expand All @@ -34,12 +33,13 @@ import {
Loading,
} from '@pitrix/lego-ui'
import { Button } from 'components/Base'
import EmptyList from 'components/Cards/EmptyList'
import SortMetricSelect from 'clusters/components/Cards/Monitoring/UsageRank/select'
import Table from 'clusters/containers/Monitor/Resource/Ranking/Project/Table'

import styles from './index.scss'

@inject('rootStore')
@inject('rootStore', 'workspaceStore')
@observer
class Ranking extends React.Component {
constructor(props) {
Expand All @@ -54,7 +54,7 @@ class Ranking extends React.Component {
limit: 10,
sort_type: 'desc',
})
this.workspaceStore = new WorkspaceStore()
this.workspaceStore = this.props.workspaceStore
}

get workspace() {
Expand All @@ -80,16 +80,14 @@ class Ranking extends React.Component {
}

componentDidMount() {
this.workspaceStore
.fetchClusters({ workspace: this.workspace })
.then(() => {
const cluster = this.workspaceStore.clusters.data.find(
item => item.isHost
)
this.setState({ cluster: cluster.name }, () => {
this.fetchMetrics()
})
const cluster =
this.workspaceStore.clusters.data.find(item => item.isHost) ||
this.workspaceStore.clusters.data[0]
if (cluster) {
this.setState({ cluster: cluster.name }, () => {
this.fetchMetrics()
})
}
}

handleClusterChange = cluster => {
Expand All @@ -99,11 +97,21 @@ class Ranking extends React.Component {
}

render() {
if (this.workspaceStore.clusters.data.length > 0) {
return (
<div className={styles.wrapper}>
{this.renderToolbar()}
{this.renderList()}
</div>
)
}

return (
<div className={styles.wrapper}>
{this.renderToolbar()}
{this.renderList()}
</div>
<EmptyList
icon="cluster"
title={t('No Available Cluster')}
desc={t('NO_CLUSTER_TIP')}
/>
)
}

Expand Down

0 comments on commit 9dfd319

Please sign in to comment.