-1 })}
- to="/dashboard/repos"
- >
- {t('Repos')}
-
-
);
}
@@ -180,7 +221,9 @@ class SideNav extends React.Component {
return (
-
{t(subNavData.title)}
+
+
{t(subNavData.title)}
+
{subNavData.links.map(link => (
-
- {this.renderNav(role)}
- {isDev && this.renderSubDev()}
- {isAdmin && this.renderSubAdmin()}
-
-
- {this.renderHeader()}
+ {this.renderNav()}
+ {hasSubNav && isDev && this.renderSubDev()}
+ {hasSubNav && isAdmin && this.renderSubAdmin()}
);
}
diff --git a/src/components/Layout/SideNav/index.scss b/src/components/Layout/SideNav/index.scss
index 447bc9e3..a908b42d 100644
--- a/src/components/Layout/SideNav/index.scss
+++ b/src/components/Layout/SideNav/index.scss
@@ -1,179 +1,195 @@
@import '~scss/vars';
-.menu {
- display: inline-block;
+.nav {
position: fixed;
left: 0;
top: 0;
- z-index: 4;
- width: $menu-width;
+ z-index: 3;
+ width: $menu-nav-width;
+ height: 100vh;
+ background-color: $N0;
+ border-right: 1px solid $N10;
+ transition: all 0.3s ease-out 0s;
- .nav {
- float: left;
- width: $menu-nav-width;
- height: 100vh;
- background-image: linear-gradient(to top, $P75, #854fb9 32%, #484999);
+ &:hover {
+ width: $menu-width;;
- .item {
- [class*='target'] {
- width: auto;
- height: auto;
- border: 0 none;
- }
+ .bottomNav {
+ width: $menu-width;
+ }
+ }
- [class*='popper']{
- border: 0 none;
- &:active, &:hover {
- border: 0 none;
- }
- }
+ li {
+ height: 40px;
+ overflow: hidden;
+
+ a {
+ color: $N300;
}
- li{
- height: 48px;
+ .icon {
+ float: left;
+ margin: 10px 22px;
+ }
- >a {
- display: inline-block;
- height: 48px;
- width: 100%;
- text-align: center;
- }
+ .title {
+ margin-left: -4px;
+ line-height: 40px;
+ cursor: pointer;
+ }
- .active {
- background-color: #343945;
- cursor: auto;
- }
- &:hover {
- background-color: #343945;
- cursor: auto;
+ &:hover {
+ a {
+ color: $P75;
}
- transition: all .3s ease-in-out;
- :global {
- .icon {
- margin: 12px;
- }
-
- .icon-op-logo{
- margin: 16px;
- }
+ .icon svg {
+ --primary-color: #{$N300};
+ --secondary-color: #{$P30};
}
}
}
}
-.subNav {
- float: left;
- height: 100vh;
- width: $menu-sub-nav-width;
- background-color: #343945;
- box-shadow: 0 1px 4px 0 rgba(73, 33, 173, 0.07);
+.topNav {
+ >li {
+ .imageOuter {
+ float: left;
+ display: inline-block;
+ width: 20px;
+ height: 20px;
+ margin: 9px 22px;
+ border: 1px solid $N30;
- .title {
- margin: 0 24px;
- font-size: 16px;
- font-weight: 900;
- line-height: 48px;
- color: $N0;
- }
+ &:hover, &.activeApp {
+ border-color: $P75;
+ }
- .apps {
- margin: 0 24px 12px;
+ .image {
+ margin: 2px;
+ }
+ }
- >a {
- display: inline-block;
- box-sizing: border-box;
- height: 32px;
- border-radius: 2px;
- border: 1px solid $N400;
- background-color: $N400;
- text-align: center;
- cursor: pointer;
- opacity: 0.5;
+ &:nth-child(1) {
+ margin-bottom: 14px;
+ height: 63px;
+ border-bottom: 1px solid $N10;
- &:hover {
- opacity: 1;
+ .icon {
+ margin: 23px 24px 16px 24px;
}
- }
- .app {
- margin-bottom: 8px;
- width: 100%;
- height: 32px;
- padding: 6px 12px;
- font-size: 12px;
- font-weight: 500;
- //line-height: 16px;
- color: $N0;
- text-align: left;
- @include textCut;
-
- &.active {
- border-color: $Y300;
- opacity: 1;
+ .title {
+ line-height: 64px;
+ font-size: 16px;
+ color: $N500;
+ font-weight: 500;
+ cursor: default;
}
+ }
+ }
+
+ :global {
+ .icon-more{
+ transform: rotate(90deg);
+ }
+ }
+}
- img {
- margin-right: 4px;
- width: 16px;
- max-width: 100%;
- max-height: 100%;
- vertical-align: middle;
- border-radius: 50%;
+
+.bottomNav {
+ >li {
+ .iconOuter {
+ [class*='target'] {
+ width: auto;
+ height: auto;
+ border-radius: 0;
+ border: 0 none;
}
- .appName {
- vertical-align: middle;
+ :global{
+ .pi-popover-popper{
+ margin-left: -10px !important;
+ margin-bottom: -30px !important;
+ }
}
}
- .plus {
- width: 104px;
- line-height: 36px;
+ .icon svg {
+ opacity: 0.6;
}
- .more {
- float: right;
- width: 40px;
- line-height: 36px;
+ &:last-child {
+ margin-bottom: 14px;
}
}
+}
- .test {
- margin: 5px 0 16px;
- height: 32px;
- border-bottom: 1px solid rgba($N400, 0.4);
+@media screen and (min-height: 550px) {
+ .bottomNav {
+ position: fixed;
+ bottom: 0;
+ left: 0;
+ z-index: 4;
+ width: $menu-nav-width;
+ }
+}
- .word {
- display: inline-block;
- position: relative;
- bottom: -16px;
- left: 22px;
- padding: 0 3px;
- line-height: 32px;
+
+.subNav {
+ position: fixed;
+ left: $menu-nav-width;
+ top: 0;
+ z-index: 2;
+ height: 100vh;
+ width: $menu-sub-nav-width;
+ background-color: $N0;
+ box-shadow: 0 1px 7px 0 rgba(71, 78, 93, 0.1);
+
+ .title {
+ margin: 24px 0;
+ padding-left: 20px;
+
+ .name {
+ line-height: 16px;
+ font-size: 16px;
+ font-weight: 500;
+ color: $N500;
+ }
+
+ .status {
+ display: block;
+ margin-top: 8px;
font-size: 12px;
- color: #69748c;
- background-color: #343945;
+ color: $N75;
}
}
+
+ .subContent {
+ margin-bottom: 28px;
+ }
+ .subTitle {
+ padding-left:20px;
+ line-height: 24px;
+ font-size: 12px;
+ color: $N65;
+ }
.link {
display: block;
- padding: 9px 24px;
- line-height: 14px;
+ padding: 0 20px;
+ line-height: 32px;
font-size: 14px;
- color: $N30;
+ color: $N300;
&:hover {
- color: $N0;
+ color: $P75;
}
&.active {
font-weight: 500;
- border-right: 2px solid $Y200;
- color: $N0;
+ color: $P75;
}
}
-
}
.header{
@@ -193,7 +209,6 @@
height: 20px;
width: auto;
line-height: 20px;
- opacity: 0.9;
color: $N500;
font-weight: 500;
border: 0 none;
@@ -243,6 +258,7 @@
background-color: $N10;
color: $N500;
}
+
&.line{
border-bottom: 1px solid $N10;
}
diff --git a/src/components/Layout/SideNav/navMap.js b/src/components/Layout/SideNav/navMap.js
index 129e4b82..a8e36ab8 100644
--- a/src/components/Layout/SideNav/navMap.js
+++ b/src/components/Layout/SideNav/navMap.js
@@ -15,10 +15,9 @@ export const subNavMap = {
user: {
title: 'Users',
links: [
- { name: 'All Users', link: '/dashboard/users', active: 'user' }
- /* { name: 'User Groups', link: '#', active: 'group' },
- { name: 'Roles', link: '#', active: 'role' },
- { name: 'Policy', link: '#', active: 'policy' }*/
+ { name: 'All Users', link: '/dashboard/users', active: 'user' },
+ { name: 'Roles', link: '#', active: 'role' },
+ { name: 'Permission and Policy', link: '#', active: 'policy' }
]
},
repo: {
@@ -34,35 +33,160 @@ export const subNavMap = {
}
};
-export const getNavs = role => [
+export const getNavs = {
+ global_admin: [
+ {
+ link: '/dashboard',
+ iconName: 'dashboard',
+ active: 'dashboard',
+ title: 'My dashboard'
+ },
+ {
+ link: '/dashboard/apps',
+ iconName: 'components',
+ active: 'app',
+ title: 'App Store'
+ },
+ {
+ link: '/dashboard/repos',
+ iconName: 'shield',
+ active: 'repo',
+ title: 'App service provider ISV'
+ },
+ {
+ link: '#',
+ iconName: 'ticket',
+ active: '',
+ title: 'Work list'
+ },
+ {
+ link: '#',
+ iconName: 'wallet',
+ active: '',
+ title: 'Financial Center'
+ },
+ {
+ link: '#',
+ iconName: 'linechart',
+ active: '',
+ title: 'Message and monitoring'
+ },
+ {
+ link: '/dashboard/users',
+ iconName: 'group',
+ active: 'user',
+ title: 'Users'
+ },
+ {
+ link: '#',
+ iconName: 'cogwheel',
+ active: '',
+ title: 'Settings'
+ }
+ ],
+ developer: [
+ {
+ link: '/dashboard/app/create',
+ iconName: 'plus-square',
+ active: 'create',
+ title: 'Create app'
+ },
+ {
+ link: '/dev/apps',
+ iconName: 'more',
+ active: 'app',
+ title: 'View all'
+ }
+ ]
+};
+
+export const getBottomNavs = [
+ {
+ link: '#',
+ iconName: 'magnifier',
+ active: '',
+ title: 'Global search'
+ },
+ {
+ link: '#',
+ iconName: 'bell',
+ active: '',
+ title: 'Alarms'
+ },
{
- link: '/',
- iconName: 'op-logo',
+ link: '#',
+ iconName: 'mail',
active: '',
- title: 'Home'
+ title: 'My news'
+ },
+ {
+ link: '/profile',
+ iconName: 'human',
+ active: 'profile',
+ title: 'My account'
+ }
+];
+
+export const getDevSubNavs = [
+ {
+ title: 'Development',
+ items: [
+ { name: 'Version management', link: '#' },
+ { name: 'Audit record', link: '#' },
+ { name: 'App information', link: '#' }
+ ]
+ },
+ {
+ title: 'Operation and maintenance',
+ items: [
+ { name: 'Monitor', link: '#' },
+ { name: 'Event', link: '#' },
+ { name: 'App information', link: '#' }
+ ]
+ },
+ {
+ title: 'Customer',
+ items: [
+ { name: 'Example', link: '#' },
+ { name: 'Work list', link: '#' },
+ { name: 'News', link: '#' }
+ ]
+ },
+ {
+ title: 'Sandbox',
+ items: [{ name: 'Example', link: '#' }, { name: 'Environment', link: '#' }]
+ }
+];
+
+export const userMeuns = [
+ {
+ name: 'Account info',
+ link: '/profile',
+ iconName: 'folder'
+ },
+ {
+ name: 'Change Password',
+ link: '/profile',
+ iconName: 'lock'
},
{
- link: '/dashboard',
- iconName: 'dashboard',
- active: 'dashboard',
- title: 'Dashboard'
+ name: 'Notice settings',
+ link: '#',
+ iconName: 'loudspeaker'
},
{
- link: '/dashboard/repos',
- iconName: 'appcenter',
- active: 'repo',
- title: 'Platform'
+ name: 'Payment',
+ link: '#',
+ iconName: 'creditcard'
},
{
- link: '/dashboard/apps',
- iconName: 'components',
- active: 'app',
- title: role === 'developer' ? 'My Apps' : 'Store'
+ name: 'SSH Keys',
+ link: '/ssh_keys',
+ iconName: 'ssh'
},
{
- link: '/dashboard/users',
- iconName: 'group',
- active: 'user',
- title: 'Users'
+ name: 'Log out',
+ link: '/logout',
+ iconName: 'logout'
}
];
diff --git a/src/components/Layout/TitleBanner.jsx b/src/components/Layout/TitleBanner.jsx
index f203a243..0e50d82e 100644
--- a/src/components/Layout/TitleBanner.jsx
+++ b/src/components/Layout/TitleBanner.jsx
@@ -3,15 +3,20 @@ import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom';
import { observer } from 'mobx-react';
import { translate } from 'react-i18next';
+import { inject } from 'mobx-react';
-import Input from '../Base/Input';
-
+import { Image, Icon, Input } from 'components/Base';
import styles from './index.scss';
-import { inject } from 'mobx-react/index';
// translate hoc should place before mobx
@translate()
-@inject('rootStore')
+@inject(({ rootStore }) => ({
+ rootStore,
+ appStore: rootStore.appStore,
+ clusterDetailStore: rootStore.clusterDetailStore,
+ runtimeStore: rootStore.runtimeStore,
+ user: rootStore.user
+}))
@observer
class TitleBanner extends Component {
static propTypes = {
@@ -33,22 +38,65 @@ class TitleBanner extends Component {
this.props.history.push('/');
};
- render() {
- const { title, hasSearch, t } = this.props;
+ renderContent = type => {
+ const { appStore, clusterDetailStore, runtimeStore } = this.props;
+ let detail = {};
+ let hasImage = false;
- return (
-
+ switch (type) {
+ case 'appDetail':
+ detail = appStore.appDetail;
+ hasImage = true;
+ break;
+ case 'clusterDetail':
+ detail = clusterDetailStore.cluster;
+ break;
+ case 'runtimeDetail':
+ detail = runtimeStore.runtimeDetail;
+ break;
+ default:
+ detail = {};
+ }
+
+ if (detail.name) {
+ return (
-
{t(title)}
- {hasSearch && (
-
+ {hasImage && (
+
+
+
+ )}
+ {type === 'runtimeDetail' && (
+
+
+
)}
+
{detail.name}
+
{detail.description}
+ );
+ }
+
+ return null;
+ };
+
+ render() {
+ const { appStore, title, t } = this.props;
+ const descMap = {
+ 'App Store': t('APP_STORE_DESC', { total: appStore.storeTotal }),
+ Purchased: t('PURCHASED_DESC'),
+ 'My Runtimes': t('MY_RUNTIMES_DESC')
+ };
+
+ return (
+
+ {Boolean(descMap[title]) && (
+
+
{t(title)}
+
{descMap[title]}
+
+ )}
+ {!Boolean(descMap[title]) && this.renderContent(title)}
);
}
diff --git a/src/components/Layout/index.jsx b/src/components/Layout/index.jsx
index 793b7274..bf20c918 100644
--- a/src/components/Layout/index.jsx
+++ b/src/components/Layout/index.jsx
@@ -1,5 +1,6 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
+import { withRouter } from 'react-router-dom';
import classnames from 'classnames';
import { inject } from 'mobx-react';
import { noop, clone, isEmpty, get } from 'lodash';
@@ -16,7 +17,7 @@ import styles from './index.scss';
user: rootStore.user,
sock
}))
-export default class Layout extends Component {
+class Layout extends Component {
static propTypes = {
className: PropTypes.string,
children: PropTypes.node,
@@ -86,27 +87,31 @@ export default class Layout extends Component {
backBtn,
hasSearch,
title,
- isHome
+ isHome,
+ match
} = this.props;
const { isNormal, isDev, isAdmin } = this.props.user;
const hasMenu = (isDev || isAdmin) && !isHome;
const { isScroll } = this.state;
+ const paths = ['/dashboard', '/profile', '/ssh_keys', '/dev/apps'];
+ const hasSubNav = hasMenu && !paths.includes(match.path);
return (
- {hasMenu &&
}
{noNotification ? null :
}
+ {backBtn}
+ {hasMenu &&
}
{isNormal && !isHome &&
}
- {backBtn}
{children}
@@ -115,3 +120,5 @@ export default class Layout extends Component {
);
}
}
+
+export default withRouter(Layout);
diff --git a/src/components/Layout/index.scss b/src/components/Layout/index.scss
index 05e44d43..2c942f19 100644
--- a/src/components/Layout/index.scss
+++ b/src/components/Layout/index.scss
@@ -6,34 +6,43 @@
width: $content-width;
margin: 0 auto;
- &.hasBack{
+ &.hasBack {
padding-top: $layout-top - 20px;
}
- &.hasMenu{
- margin: 56px 20px 32px $menu-width+20px;
- width: calc(100% - #{$menu-width} - 40px);
+ &.hasMenu,
+ &.hasNav {
+ margin: 56px 20px 32px $menu-width + 20px;
//min-width: 950px;
min-width: 992px;
min-height: calc(100vh - 100px);
padding-top: 0;
}
- .backBtn{
+ &.hasMenu {
+ width: calc(100% - #{$menu-width} - 40px);
+ }
+
+ &.hasNav {
+ width: calc(100% - #{$menu-nav-width} - 40px);
+ margin-left: $menu-nav-width + 20px;
+ }
+
+ .backBtn {
//width: $content-width;
margin: 0 auto 20px;
font-size: $size-normal;
line-height: 1.43;
- a{
+ a {
color: $P75;
}
}
- &.noTabs{
- padding-top: $header-height+32px;
+ &.noTabs {
+ padding-top: $header-height + 32px;
}
- .detailTab{
+ .detailTab {
position: absolute;
top: 150px;
left: 384px;
@@ -50,27 +59,60 @@
}
}
-.titleBanner{
+.titleBanner {
position: fixed;
top: 48px;
left: 0;
z-index: 3;
width: 100%;
height: $title-banner-height;
- background-color: $N0;
- box-shadow: 0 4px 8px 0 rgba(35, 35, 36, 0.04);
+ background-color: $N500;
- .wrapper{
+ .wrapper {
width: $content-width;
- margin: 20px auto;
+ margin: 30px auto;
+ }
+
+ .image,
+ .icon {
+ float: left;
+ margin-right: 12px;
+ width: 48px;
+ height: 48px;
+ }
+
+ .image {
+ line-height: 48px;
+
+ img {
+ max-width: 100%;
+ max-height: 100%;
+ vertical-align: middle;
+ }
+ }
+
+ .icon {
+ box-sizing: border-box;
+ padding: 12px;
+ background-color: $N400;
+ border-radius: 3px;
}
- .name{
- font-size: 28px;
+ .name {
+ margin-bottom: 4px;
+ font-size: 20px;
font-weight: 500;
- line-height: 32px;
+ line-height: 24px;
letter-spacing: 0;
- color: #343945;
+ color: $N0;
+ }
+
+ .desc {
+ height: 20px;
+ line-height: 20px;
+ font-size: 12px;
+ color: $N65;
+ overflow: hidden;
}
.search {
@@ -90,11 +132,11 @@
border-radius: 16px;
border: 1px solid transparent;
background-color: $N10;
- transition: all .3s ease-in-out;
+ transition: all 0.3s ease-in-out;
&::placeholder {
font-size: 14px;
color: $N45;
- line-height: 1.0;
+ line-height: 1;
letter-spacing: 0;
}
&:focus {
@@ -109,12 +151,11 @@
.icon {
color: $N65;
opacity: 0.5;
- &:hover, &:focus {
+ &:hover,
+ &:focus {
opacity: 1;
}
}
}
}
}
-
-
diff --git a/src/components/MenuLayer/index.jsx b/src/components/MenuLayer/index.jsx
index d0a2bf85..4cc3eeeb 100644
--- a/src/components/MenuLayer/index.jsx
+++ b/src/components/MenuLayer/index.jsx
@@ -1,13 +1,14 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
-import { NavLink, Link, withRouter } from 'react-router-dom';
+import { Link } from 'react-router-dom';
import { observer, inject } from 'mobx-react';
import { translate } from 'react-i18next';
import { Popover, Icon } from 'components/Base';
import styles from './index.scss';
+import { userMeuns } from 'components/Layout/SideNav/navMap';
// translate hoc should place before mobx
@translate()
@@ -30,44 +31,44 @@ export default class MenuLayer extends Component {
};
render() {
- const { className, user, t } = this.props;
- const { role, isNormal } = user;
- const changeWord = isNormal ? t('Back to developer') : t('Back to user');
+ const { user, className, t } = this.props;
+ const { isNormal } = user;
+ const changeWord = isNormal ? t('Develop Center') : t('App Center');
+ const isDeveloper = user.role === 'developer';
return (
- {role === 'developer' && (
- - this.becomeDeveloper(isNormal)} className={styles.line}>
-
-
- )}
- -
-
-
- {t('Dashboard')}
-
-
-
-
-
- {t('Profile')}
-
-
- -
-
-
- {t('SSH Keys')}
-
-
- -
-
-
- {t('Log out')}
-
+
+
+
+ {user.username}
+ {isDeveloper && (
+
+
+
+ )}
+
+ {isDeveloper && (
+ - this.becomeDeveloper(isNormal)}>
+
+
+
+ )}
+
+ {userMeuns.map(item => (
+ -
+
+ {item.name === 'Log out' && {t(item.name)}}
+ {item.name !== 'Log out' && {t(item.name)}}
+
+ ))}
);
}
diff --git a/src/components/MenuLayer/index.scss b/src/components/MenuLayer/index.scss
index 5cd6f17a..166a5e42 100644
--- a/src/components/MenuLayer/index.scss
+++ b/src/components/MenuLayer/index.scss
@@ -1,19 +1,18 @@
-@import "~scss/vars";
+@import '~scss/vars';
.menuLayer {
- min-width: 130px;
+ min-width: 140px;
li {
+ height: 32px;
+
> a,
> label {
display: block;
- height: 32px;
- padding: 0 12px;
- //width: 100%;
line-height: 32px;
- font-size: $font14;
+ font-size: 12px;
font-weight: normal;
- color: $N300;
+ color: $N300 !important;
border-radius: 0;
cursor: pointer;
@@ -23,16 +22,81 @@
}
}
- &.line{
+ .iconImg {
+ float: left;
+ margin: 8px 8px 8px 15px;
+ }
+
+ &:hover {
+ a {
+ color: $N500;
+ }
+ }
+
+ &:first-child {
+ padding: 12px 15px 15px;
+ font-size: 16px;
+ line-height: 32px;
+ font-weight: 500;
+ color: $N500;
+ border-bottom: 1px solid $N10;
+
+ .userIcon {
+ float: left;
+ display: inline-block;
+ margin-right: 8px;
+ width: 32px;
+ height: 32px;
+ background-color: $N10;
+ border-radius: 50%;
+
+ .iconImg {
+ margin: 0;
+ svg {
+ --primary-color: #{$N300};
+ --secondary-color: #{$N45};
+ }
+ }
+ }
+
+ .devIconOuter {
+ display: inline-block;
+ position: relative;
+ margin-left: 4px;
+ width: 12px;
+ height: 12px;
+ border-radius: 50%;
+ background-color: $P75;
+
+ .devIcon {
+ position: absolute;
+ left: 2px;
+ top: 2px;
+ line-height: 0px;
+ svg {
+ --primary-color: #{$N0};
+ --secondary-color: #{$N0};
+ --primary-opacity: 0.9;
+ --secondary-opacity: 0.4;
+ }
+ }
+ }
+ }
+
+ &.dev {
+ height: 40px;
+ > label {
+ line-height: 40px;
+ }
border-bottom: 1px solid $N10;
+
+ .iconImg {
+ margin: 12px 8px 12px 15px;
+ }
}
- .icon {
- float: left;
- position: relative;
- top: 4px;
- margin-right: 4px;
+ &:last-child {
+ border-top: 1px solid $N10;
}
}
}
-
diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json
index 59429753..b4f766a1 100644
--- a/src/locales/en/translation.json
+++ b/src/locales/en/translation.json
@@ -84,5 +84,10 @@
"DEPLOY_NO_RUNTIME_NOTE": "There is currently no available runtime, please go to ",
- "HELM_APP_NAME_TIP": "Start with [a-z], with '-', 0~9, lowercase letter in the middle, no more than 14 characters in length."
+ "HELM_APP_NAME_TIP": "Start with [a-z], with '-', 0~9, lowercase letter in the middle, no more than 14 characters in length.",
+
+ "APP_STORE_DESC": "Openpitrix official store has {{total}} apps",
+ "PURCHASED_DESC": "All the apps you have purchased will be shown here, including the corresponding instance of the app.",
+ "MY_RUNTIMES_DESC": "The platform supports multiple cloud environments, at the same time and can be managed here.",
+ "UPGRADE_PROVIDER": "Upgrade to an「application provider」"
}
diff --git a/src/locales/zh/translation.json b/src/locales/zh/translation.json
index 8d705809..64b9d6ad 100644
--- a/src/locales/zh/translation.json
+++ b/src/locales/zh/translation.json
@@ -272,7 +272,7 @@
"Tickets": "优惠卷",
"Notifications": "通知",
"Service Status": "服务状态",
- "All Users": "所有用户",
+ "All Users": "全部用户",
"User Groups": "用户分组",
"Policy": "政策",
"SSH Keys": "SSH密钥",
@@ -285,6 +285,7 @@
"Administrator": "管理员",
"Developer": "开发者",
"Normal User": "普通用户",
+ "Permission and Policy": "权限与策略",
"Email": "邮箱",
"delete_user_desc": "您确定要删除该用户吗?",
"Organization": "机构",
@@ -312,8 +313,13 @@
"Attach": "绑定",
"Detach": "解绑",
+ "App Store": "应用商店",
"Purchased": "已部署应用",
"My runtimes": "我的环境",
+ "APP_STORE_DESC": "Openpitrix 官方商店,有{{total}}款应用。",
+ "PURCHASED_DESC": "所有你购买过的应用都会展示在此,包括应用对应的实例。",
+ "MY_RUNTIMES_DESC": "平台同时支持多种云环境,可以在这里进行统一管理。",
+ "UPGRADE_PROVIDER": "升级成为「应用提供商」",
"creat_new_app": "创建新应用程序",
"creat_new_version": "创建新版本",
@@ -376,6 +382,8 @@
"Back to user": "普通用户",
"Back to developer": "开发中心",
+ "App Center": "应用中心",
+ "Develop Center": "开发中心",
"Document": "文档",
"Already create new version": "已创建新版本",
@@ -400,5 +408,34 @@
"Version should not be empty": "版本不能为空",
"Runtime should not be empty": "运行环境不能为空",
"Deploy app successfully": "部署应用成功",
- "Invalid config file, failed to render page": "无效的配置文件,无法渲染页面"
+ "Invalid config file, failed to render page": "无效的配置文件,无法渲染页面",
+
+ "QingCloud App Center": "QingCloud 应用中心",
+ "My dashboard": "我的工作台",
+ "App service provider ISV": "应用服务商ISV",
+ "Work list": "工单",
+ "Financial Center": "财务中心",
+ "Message and monitoring": "消息与监控",
+ "Settings": "设置",
+ "Create app": "创建新应用",
+ "View all": "查看全部",
+ "Global search": "全局搜索",
+ "Alarms": "告警",
+ "My news": "我的消息",
+ "My account": "我的帐户",
+ "Version management": "版本管理",
+ "Audit record": "审核记录",
+ "App information": "应用信息",
+ "Operation and maintenance": "运维",
+ "Monitor": "监控",
+ "Event": "事件",
+ "Customer": "客户",
+ "News": "消息",
+ "Sandbox": "沙盒",
+ "Example": "实例",
+ "Environment": "环境",
+ "Account info": "账户信息",
+ "Change Password": "修改密码",
+ "Notice settings": "通知设置",
+ "Payment": "支付"
}
diff --git a/src/pages/AppDetail/index.jsx b/src/pages/AppDetail/index.jsx
index b3dc5c92..3e6826cd 100644
--- a/src/pages/AppDetail/index.jsx
+++ b/src/pages/AppDetail/index.jsx
@@ -271,7 +271,7 @@ export default class AppDetail extends Component {
}
diff --git a/src/pages/Dashboard/Clusters/Detail/index.jsx b/src/pages/Dashboard/Clusters/Detail/index.jsx
index a0aab7f0..d925d933 100644
--- a/src/pages/Dashboard/Clusters/Detail/index.jsx
+++ b/src/pages/Dashboard/Clusters/Detail/index.jsx
@@ -357,7 +357,7 @@ export default class ClusterDetail extends Component {
className={classnames({ [styles.clusterDetail]: !isNormal })}
backBtn={isNormal && }
listenToJob={this.listenToJob}
- title="Purchased"
+ title="clusterDetail"
>
{!isNormal && }
diff --git a/src/pages/Dashboard/Runtimes/Detail/index.jsx b/src/pages/Dashboard/Runtimes/Detail/index.jsx
index 87f18275..f3ff127d 100644
--- a/src/pages/Dashboard/Runtimes/Detail/index.jsx
+++ b/src/pages/Dashboard/Runtimes/Detail/index.jsx
@@ -343,7 +343,7 @@ export default class RuntimeDetail extends Component {
return (
}
listenToJob={this.listenToJob}
>
diff --git a/src/pages/Store/index.jsx b/src/pages/Store/index.jsx
index 0ce5da8f..636c0407 100644
--- a/src/pages/Store/index.jsx
+++ b/src/pages/Store/index.jsx
@@ -39,6 +39,7 @@ export default class Store extends Component {
}
await appStore.fetchAll(params);
+ appStore.storeTotal = appStore.totalCount;
appStore.storeApps = appStore.apps.slice();
if (!category && !search) {
@@ -114,7 +115,7 @@ export default class Store extends Component {
const categoryTitle = get(find(categories, { category_id: category }), 'name', '');
return (
-
+
diff --git a/src/routes/index.js b/src/routes/index.js
index 9e454121..5b74ceb5 100644
--- a/src/routes/index.js
+++ b/src/routes/index.js
@@ -45,6 +45,7 @@ const routes = {
'/:dash': Dash.Overview,
'/:dash/apps': Dash.Apps,
+ '/dev/apps': Dash.Apps,
'/:dash/reviews': Dash.AppReview,
'/:dash/review/:appId/:versionId': AppDetail,
'/:dash/app/create': Dash.AppAdd,
diff --git a/src/scss/partial/_grid.scss b/src/scss/partial/_grid.scss
index 69f6bcf0..15d6a218 100644
--- a/src/scss/partial/_grid.scss
+++ b/src/scss/partial/_grid.scss
@@ -1,7 +1,7 @@
$content-width: 1128px;
-$menu-width: 248px;
-$menu-nav-width: 48px;
-$menu-sub-nav-width: 200px;
+$menu-nav-width: 64px;
+$menu-sub-nav-width: 192px;
+$menu-width: $menu-nav-width + $menu-sub-nav-width;
$columns: 12;
$grid-gap: 24px; // gap for normal layout
@@ -15,7 +15,7 @@ $layout-margin: 156px;
// basic
$nav-width: 264px;
$header-height: 48px;
-$title-banner-height: 72px;
+$title-banner-height: 108px;
$layout-top: $header-height + $title-banner-height + 40px;
$tabNavs-height: 48px;
$banner-height: 400px;
diff --git a/src/stores/app/index.js b/src/stores/app/index.js
index 0ed4123c..ab85b41f 100644
--- a/src/stores/app/index.js
+++ b/src/stores/app/index.js
@@ -11,6 +11,7 @@ export default class AppStore extends Store {
@observable apps = [];
@observable homeApps = [];
@observable storeApps = []; //store page category apps
+ @observable storeTotal = 0; // normal user store page app total
@observable menuApps = []; //menu apps
@observable hasMeunApps = false; // judje query menu apps
@observable appDetail = {};
diff --git a/src/utils/icons.js b/src/utils/icons.js
index b5065d91..00cacc8f 100644
--- a/src/utils/icons.js
+++ b/src/utils/icons.js
@@ -912,10 +912,10 @@ const svgSprites = `
-
+
-
-
+
+
`;