diff --git a/src/components/Base/Modal/index.scss b/src/components/Base/Modal/index.scss index 5a57b32b..b7dfb719 100644 --- a/src/components/Base/Modal/index.scss +++ b/src/components/Base/Modal/index.scss @@ -39,7 +39,7 @@ $padding-left: 24px; .footer { padding: 32px $padding-left; //border-top: 1px solid $N10; - //text-align: right; + text-align: right; .operationBtn{ margin-left: 192px; text-align: left; diff --git a/src/locales/zh/apps.json b/src/locales/zh/apps.json index 5aabdfe8..c15c9fc6 100644 --- a/src/locales/zh/apps.json +++ b/src/locales/zh/apps.json @@ -184,5 +184,10 @@ "STEPPER_TITLE_VERSION_SUBMIT_CHECK_2": "检查版本信息", "STEPPER_FOOTER_VERSION_SUBMIT_CHECK_2": "版本号以及版本的更新日志都是重要的信息。", "STEPPER_HEADER_VERSION_SUBMIT_CHECK_2": "「检查应用信息」", - "": "" + + "Please input the reason for reject": "请您填写拒绝原因", + + "ISV_REVIEW_PASS": "应用服务商审核通过了该应用版本", + "BUSINESS_ADMIN_REVIEW_PASS": "平台商务审核通过了该应用版本", + "DEVELOP_ADMIN_REVIEW_PASS": "平台技术审核审核通过了该应用版本" } diff --git a/src/pages/Dashboard/Apps/Detail/index.jsx b/src/pages/Dashboard/Apps/Detail/index.jsx index e7c8a930..f46004cf 100644 --- a/src/pages/Dashboard/Apps/Detail/index.jsx +++ b/src/pages/Dashboard/Apps/Detail/index.jsx @@ -1,9 +1,8 @@ -import React, { Component, Fragment } from 'react'; +import React, { Component } from 'react'; import { observer, inject } from 'mobx-react'; import { Link } from 'react-router-dom'; import { translate } from 'react-i18next'; import _ from 'lodash'; -import classNames from 'classnames'; import { Icon, Input, Table, Button, Image @@ -15,6 +14,7 @@ import TdName from 'components/TdName'; import TimeShow from 'components/TimeShow'; import AppStatistics from 'components/AppStatistics'; import versionTypes from 'config/version-types'; +import { formatTime } from 'utils'; import Versions from '../../Versions'; import styles from './index.scss'; @@ -37,31 +37,48 @@ const tags = [ export default class AppDetail extends Component { async componentDidMount() { const { - appStore, appVersionStore, clusterStore, match + appStore, + appVersionStore, + clusterStore, + userStore, + match } = this.props; const { appId } = match.params; await appStore.fetch(appId); + await appVersionStore.fetchActiveVersions({ app_id: appId, noLimit: true }); + clusterStore.appId = appId; + // get month deploy total + await clusterStore.fetchAll({ app_id: appId, created_date: 30, limit: 1 }); + // get deploy total and user instance await clusterStore.fetchAll({ app_id: appId }); - await appVersionStore.fetchAll({ app_id: appId, noLimit: true }); + const { appDetail } = appStore; + await userStore.fetchDetail({ user_id: appDetail.owner }); } changeTab = async tab => { - const { appStore, appVersionStore, match } = this.props; + const { + appStore, appVersionStore, userStore, match + } = this.props; if (tab !== appStore.detailTab) { appStore.detailTab = tab; if (tab === 'online') { const { appId } = match.params; - await appVersionStore.fetchTypeVersions(appId); + await appVersionStore.fetchTypeVersions(appId, true); } else if (tab === 'record') { const { appDetail } = appStore; - const versoinId = _.get(appDetail, 'latest_app_version.version_id', ''); - await appVersionStore.fetchAudits(appDetail.app_id, versoinId); + const versionId = _.get(appDetail, 'latest_app_version.version_id', ''); + await appVersionStore.fetchAudits(appDetail.app_id, versionId); + // query record relative operators name + const userIds = _.get(appVersionStore.audits, versionId, []).map( + item => item.operator + ); + await userStore.fetchAll({ user_id: _.uniq(userIds) }); } } }; @@ -87,8 +104,8 @@ export default class AppDetail extends Component { const { appDetail } = appStore; const { users } = userStore; const { audits } = appVersionStore; - const versoinId = _.get(appDetail, 'latest_app_version.version_id', ''); - const records = audits[versoinId] || []; + const versionId = _.get(appDetail, 'latest_app_version.version_id', ''); + const records = audits[versionId] || []; const columns = [ { @@ -101,7 +118,7 @@ export default class AppDetail extends Component { title: t('申请类型'), key: 'type', width: '60px', - render: item => item.type + render: item => item.type || t('应用上架') }, { title: t('Status'), @@ -115,13 +132,13 @@ export default class AppDetail extends Component { title: t('Update time'), key: 'status_time', width: '100px', - render: item => item.status_time + render: item => formatTime(item.status_time, 'YYYY/MM/DD HH:mm:ss') }, { title: t('审核人员'), key: 'operator', width: '80px', - render: item => item.operator + render: item => (_.find(users, { user_id: item.operator }) || {}).username } ]; @@ -217,8 +234,9 @@ export default class AppDetail extends Component { } renderAppBase() { - const { appStore, t } = this.props; + const { appStore, userStore, t } = this.props; const { appDetail } = appStore; + const { userDetail } = userStore; const categories = _.get(appDetail, 'category_set', []); return ( @@ -256,11 +274,11 @@ export default class AppDetail extends Component {
{t('开发者')}
-
{appDetail.owner}
+
{userDetail.username}
{t('上架时间')}
-
{appDetail.status_time}
+
{formatTime(appDetail.status_time, 'YYYY/MM/DD HH:mm:ss')}
{t('去商店中查看')} → @@ -271,7 +289,9 @@ export default class AppDetail extends Component { } render() { - const { appVersionStore, appStore, t } = this.props; + const { + appVersionStore, appStore, clusterStore, t + } = this.props; const { detailTab } = appStore; const { versions } = appVersionStore; @@ -280,7 +300,12 @@ export default class AppDetail extends Component {
{this.renderAppBase()}
- + {detailTab === 'instance' && this.renderInstance()} {detailTab === 'online' && } diff --git a/src/pages/Dashboard/Apps/Info/index.jsx b/src/pages/Dashboard/Apps/Info/index.jsx index da09c249..a3ebd332 100644 --- a/src/pages/Dashboard/Apps/Info/index.jsx +++ b/src/pages/Dashboard/Apps/Info/index.jsx @@ -47,7 +47,9 @@ export default class Info extends Component { // judge you can edit app info const { versions } = appVersionStore; - appStore.isEdit = !_.find(versions, { status: 'submitted' }); + const { appDetail } = appStore; + appStore.isEdit = !_.find(versions, { status: 'in-view' }) + && appDetail.status !== 'deleted'; // query categories data for category select await categoryStore.fetchAll(); diff --git a/src/pages/Dashboard/Apps/index.jsx b/src/pages/Dashboard/Apps/index.jsx index 08fe6357..90ee6bc0 100644 --- a/src/pages/Dashboard/Apps/index.jsx +++ b/src/pages/Dashboard/Apps/index.jsx @@ -242,7 +242,7 @@ export default class Apps extends Component { } = appStore; const { users } = userStore; const { isAdmin } = user; - const urlPrefix = isAdmin ? '/store/' : '/dashboard/versions/'; + const urlPrefix = '/dashboard/app/'; const columnsFilter = columns => { const excludeKeys = isAdmin ? 'owner' : 'maintainers'; return columns.filter(item => item.key !== excludeKeys); diff --git a/src/pages/Dashboard/Categories/index.scss b/src/pages/Dashboard/Categories/index.scss index 41246754..af22ba13 100644 --- a/src/pages/Dashboard/Categories/index.scss +++ b/src/pages/Dashboard/Categories/index.scss @@ -133,4 +133,5 @@ .dialogFooter{ margin-left: 75px; + text-align: left !important; } diff --git a/src/pages/Dashboard/Reviews/Detail/index.jsx b/src/pages/Dashboard/Reviews/Detail/index.jsx index e7bbe397..7bcf3a1d 100644 --- a/src/pages/Dashboard/Reviews/Detail/index.jsx +++ b/src/pages/Dashboard/Reviews/Detail/index.jsx @@ -31,6 +31,11 @@ const reviewStatus = { business_admin: ['isv-passed', 'business-in-review'], develop_admin: ['business-passed', 'dev-in-review'] }; +const rejectStatus = { + isv: 'isv-rejected', + business_admin: 'business-rejected', + develop_admin: 'dev-rejected' +}; const reviewTitle = { isv: '应用服务商审核', business_admin: '平台商务审核', @@ -48,6 +53,7 @@ const reviewPassNote = { appVersionStore: rootStore.appVersionStore, appStore: rootStore.appStore, categoryStore: rootStore.categoryStore, + userStore: rootStore.userStore, user: rootStore.user })) @observer @@ -136,6 +142,21 @@ export default class ReviewDetail extends Component { ); }; + renderOperator(operatorId) { + const { + appVersionStore, userStore, user, t + } = this.props; + const { users } = userStore; + const operator = _.find(users, { user_id: operatorId }) || user; + + return ( +
+ {' '} + {operator.email} +
+ ); + } + renderReviewCard(role) { const { appVersionStore, user, t } = this.props; const { reviewDetail } = appVersionStore; @@ -174,7 +195,7 @@ export default class ReviewDetail extends Component {
{t('审核人员')}:
-
{record.operator}
+
{this.renderOperator(record.operator)}
{t('开始时间')}:
@@ -182,6 +203,11 @@ export default class ReviewDetail extends Component {
+ {user.username === 'develop_admin' && ( + + + + )} @@ -193,9 +219,9 @@ export default class ReviewDetail extends Component { ); } - // passed + // passed, rejectd if (phaseKeys.includes(role) && !reviewStatus[role].includes(status)) { - const isReject = status.indexOf('reject') > -1; + const isReject = status === rejectStatus[role]; return (
{t('审核人员')}:
-
{record.operator}
+
{this.renderOperator(record.operator)}
{t('开始时间')}:
diff --git a/src/pages/Dashboard/Reviews/Detail/index.scss b/src/pages/Dashboard/Reviews/Detail/index.scss index d498f442..2b5b326c 100644 --- a/src/pages/Dashboard/Reviews/Detail/index.scss +++ b/src/pages/Dashboard/Reviews/Detail/index.scss @@ -193,6 +193,15 @@ float: right; } } + + .operator { + @include note-font; + + .name { + color: $N500; + font-weight: 500; + } + } } .rejectMessage { diff --git a/src/pages/Dashboard/Versions/Detail/index.jsx b/src/pages/Dashboard/Versions/Detail/index.jsx index aef62aeb..13a0ac41 100644 --- a/src/pages/Dashboard/Versions/Detail/index.jsx +++ b/src/pages/Dashboard/Versions/Detail/index.jsx @@ -318,9 +318,9 @@ export default class VersionDetail extends Component { />
- {t(audit.role)}: { - (_.find(users, { user_id: audit.operator }) || {}).username - } + {t(audit.role)}: {( + _.find(users, { user_id: audit.operator }) || {} + ).username || audit.operator}
{this.renderReason(audit)}
diff --git a/src/pages/Dashboard/Versions/index.jsx b/src/pages/Dashboard/Versions/index.jsx index 4a0a3773..2e62c76f 100644 --- a/src/pages/Dashboard/Versions/index.jsx +++ b/src/pages/Dashboard/Versions/index.jsx @@ -32,8 +32,12 @@ export default class Versions extends Component { } componentWillUnmount() { - const { appVersionStore } = this.props; - appVersionStore.reset(); + const { appVersionStore, match } = this.props; + const appId = _.get(match, 'params.appId', ''); + + if (appId) { + appVersionStore.reset(); + } } toggleHistoryVersions(typeVersion) { diff --git a/src/stores/app/index.js b/src/stores/app/index.js index 84b805a6..7bd1c06a 100644 --- a/src/stores/app/index.js +++ b/src/stores/app/index.js @@ -141,6 +141,11 @@ class AppStore extends Store { } else { await this.fetch(appId); + // if can't get app, should not storage app info + if (!this.appDetail.app_id) { + return; + } + if (appDetail) { const index = _.findIndex(apps, { app_id: appId }); apps.splice(index, 1, this.appDetail); diff --git a/src/stores/app/version.js b/src/stores/app/version.js index 8158f549..0c106566 100644 --- a/src/stores/app/version.js +++ b/src/stores/app/version.js @@ -5,7 +5,6 @@ import _, { import { Base64 } from 'js-base64'; import ts from 'config/translation'; -import { t } from 'i18next'; import Store from '../Store'; const defaultStatus = [ @@ -160,6 +159,35 @@ export default class AppVersionStore extends Store { this.isLoading = false; }; + @action + fetchActiveVersions = async (params = {}) => { + const defaultParams = { + sort_key: 'status_time', + limit: this.pageSize, + offset: (this.currentPage - 1) * this.pageSize + }; + + if (params.noLimit) { + defaultParams.limit = this.maxLimit; + defaultParams.offset = 0; + delete params.noLimit; + } + + if (this.appId) { + defaultParams.app_id = this.appId; + } + + this.isLoading = true; + const result = await this.request.get( + 'active_app_versions', + assign(defaultParams, params) + ); + this.isLoading = false; + + this.versions = get(result, 'app_version_set', []); + this.totalCount = get(result, 'total_count', 0); + }; + @action fetch = async (versionId = '') => { this.isLoading = true; @@ -257,7 +285,7 @@ export default class AppVersionStore extends Store { @action versionReview = async (handleType, versionId, role) => { if (handleType === 'reject' && !this.reason) { - return this.error(t('请您填写拒绝原因')); + return this.error('Please input the reason for reject'); } const params = { version_id: versionId }; @@ -279,7 +307,7 @@ export default class AppVersionStore extends Store { if (handleType === 'review') { this.isTipsOpen = true; } else { - this.success(`${capitalize(handleType)} this version successfully.`); + this.success(`${role.toUpperCase()}_REVIEW_PASS`); } } else { return result; @@ -303,11 +331,15 @@ export default class AppVersionStore extends Store { `app/${appId}/version/${versionId}/reviews`, { limit: this.maxLimit, - sort_key: 'review_time' + sort_key: 'status_time', + reverse: true } ); this.reviewDetail = _.get(result, 'app_version_review_set[0]', {}); + const { phase } = this.reviewDetail; + const userIds = _.map(phase, o => o.operator); + await this.userStore.fetchAll({ user_id: userIds }); }; // todo @@ -431,9 +463,10 @@ export default class AppVersionStore extends Store { }; @action - fetchTypeVersions = async appId => { + fetchTypeVersions = async (appId, isActive) => { + const url = isActive ? 'active_app_versions' : 'app_versions'; this.isLoading = true; - const result = await this.request.get('app_versions', { + const result = await this.request.get(url, { limit: this.maxLimit, app_id: appId }); diff --git a/src/stores/cluster/index.js b/src/stores/cluster/index.js index fb2cb727..f380c83a 100644 --- a/src/stores/cluster/index.js +++ b/src/stores/cluster/index.js @@ -104,6 +104,10 @@ export default class ClusterStore extends Store { this.clusterCount = this.totalCount; } + if (params.created_date === 30) { + this.monthCount = get(result, 'total_count', 0); + } + if (attachApps) { const appIds = this.clusters.map(cluster => cluster.app_id); if (appIds.length) {