Skip to content

Commit fc85d86

Browse files
committed
Merge pull request #25 from ParsePlatform/better-apps-index
Remove useless/unavailable info from AppsIndex
2 parents e375c5b + b4a4206 commit fc85d86

File tree

3 files changed

+34
-93
lines changed

3 files changed

+34
-93
lines changed

dashboard/Apps/AppsIndex.react.js

Lines changed: 20 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,11 @@ let CloningNote = ({ app, clone_status, clone_progress }) => {
4545
return <div>Cloning is {progress}% complete</div>
4646
};
4747

48-
let CountsSection = (props) => {
49-
return (
50-
<div className={props.className}>
51-
<div className={styles.section}>{props.title}</div>
52-
{props.children}
53-
</div>
54-
);
55-
};
48+
let CountsSection = ({ className, title, children }) =>
49+
<div className={className}>
50+
<div className={styles.section}>{title}</div>
51+
{children}
52+
</div>
5653

5754
let Metric = (props) => {
5855
return (
@@ -63,46 +60,20 @@ let Metric = (props) => {
6360
);
6461
};
6562

66-
let AppCard = (props) => {
67-
let sharing = null;
68-
if (props.app.collabInfo) {
69-
if (props.app.isOwner()) {
70-
sharing = 'shared with ' + pluralize(props.app.collaboratorCount, 'person', 'people');
71-
} else {
72-
sharing = html`shared by ${props.app.owner}`;
73-
}
74-
}
75-
return (
76-
<li onClick={() => history.pushState(null, html`/apps/${props.app.slug}/browser`)}>
77-
<a className={styles.icon}>
78-
{props.icon ? <img src={props.icon} /> : <Icon width={56} height={56} name='blank-app-outline' fill='#1E384D' />}
79-
</a>
80-
<CountsSection className={styles.plan} title='Current plan'>
81-
<Metric number={dash(props.app.requestLimit)} label='requests/s' />
82-
<Metric number={dash(props.app.requestLimit, Math.floor(props.app.requestLimit / 20))} label='background job' />
83-
<Metric number={dash(props.app.requestLimit, '$' + (props.app.requestLimit - 30) * 10)} label='monthly' />
84-
<a href={html`/apps/${props.app.slug}/settings`} className={styles.edit} onClick={(e) => {
85-
e.stopPropagation();
86-
history.pushState(null, html`/apps/${props.app.slug}/settings`);
87-
}}>Edit</a>
88-
</CountsSection>
89-
<CountsSection className={styles.glance} title='At a glance'>
90-
<Metric number={dash(props.app.requests, prettyNumber(props.app.requests))} label='requests' />
91-
<Metric number={dash(props.app.users, prettyNumber(props.app.users))} label='total users' />
92-
<Metric number={dash(props.app.installations, prettyNumber(props.app.installations))} label='total installations' />
93-
</CountsSection>
94-
<div className={styles.details}>
95-
<a className={styles.appname}>{props.app.name}</a>
96-
{props.app.is_cloning ? <CloningNote
97-
app={props.app}
98-
clone_status={props.app.clone_status}
99-
clone_progress={props.app.clone_progress}/> :
100-
<div>Created <span className={styles.ago}>{howLongAgo(props.app.createdAt)}</span></div>}
101-
</div>
102-
{sharing}
103-
</li>
104-
)
105-
};
63+
let AppCard = ({
64+
app,
65+
icon,
66+
}) => <li onClick={() => history.pushState(null, html`/apps/${app.slug}/browser`)}>
67+
{icon ? <a className={styles.icon}><img src={icon} /></a> : null}
68+
<CountsSection className={styles.glance} title='At a glance'>
69+
<Metric number={dash(app.users, prettyNumber(app.users))} label='total users' />
70+
<Metric number={dash(app.installations, prettyNumber(app.installations))} label='total installations' />
71+
</CountsSection>
72+
<div className={styles.details}>
73+
<a className={styles.appname}>{app.name}</a>
74+
<div className={styles.serverVersion}>Server version: <span className={styles.ago}>{app.enabledFeatures.serverVersion || 'unknown'}</span></div>
75+
</div>
76+
</li>
10677

10778
export default class AppsIndex extends React.Component {
10879
constructor() {
@@ -113,7 +84,7 @@ export default class AppsIndex extends React.Component {
11384

11485
componentWillMount() {
11586
document.body.addEventListener('keydown', this.focusField);
116-
AppsManager.getAppsInfo().then(() => {
87+
AppsManager.getAllAppsIndexStats().then(() => {
11788
this.forceUpdate();
11889
});
11990
}

dashboard/Apps/AppsIndex.scss

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -129,16 +129,14 @@
129129
}
130130

131131
.appname {
132+
@include ellipsis();
132133
display: inline-block;
133134
font-size: 22px;
134135
color: white;
135-
max-width: 180px;
136-
overflow: hidden;
137-
text-overflow: ellipsis;
138-
white-space: nowrap;
139136
}
140137

141138
.details {
139+
@include ellipsis();
142140
padding: 9px 0;
143141
color: #788c97;
144142
font-size: 12px;
@@ -158,29 +156,8 @@
158156

159157
.glance {
160158
float: right;
161-
width: 340px;
162159
padding: 10px 12px;
163160
border-left: 1px solid #1e3b4d;
164-
border-right: 1px solid #1e3b4d;
165-
}
166-
167-
@media (max-width: 1300px) {
168-
.glance {
169-
display: none;
170-
}
171-
}
172-
173-
.plan {
174-
float: right;
175-
width: 300px;
176-
padding: 10px 12px;
177-
position: relative;
178-
}
179-
180-
@media (max-width: 640px) {
181-
.plan {
182-
display: none;
183-
}
184161
}
185162

186163
.section {
@@ -205,6 +182,10 @@
205182
font-size: 11px;
206183
}
207184

185+
.serverVersion {
186+
@include ellipsis();
187+
}
188+
208189
.edit {
209190
@include DIN17Font;
210191
position: absolute;

lib/AppsManager.js

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* This source code is licensed under the license found in the LICENSE file in
66
* the root directory of this source tree.
77
*/
8+
import Parse from 'parse';
89
import ParseApp from 'lib/ParseApp';
910
import { get, post, del } from 'lib/AJAX';
1011
import { unescape } from 'lib/StringEscaping';
@@ -66,25 +67,13 @@ const AppsManager = {
6667
},
6768

6869
// Fetch the latest usage and request info for the apps index
69-
getAppsInfo() {
70-
return get('/apps_info').then((response) => {
71-
this.apps().forEach((app) => {
72-
let info = response[app.slug];
73-
if (info) {
74-
app.installations = info.installations;
75-
app.requests = info.requests;
76-
app.users = info.users;
77-
app.requestLimit = info.requestLimit;
78-
79-
app.is_cloning = info.is_cloning;
80-
if (app.is_cloning) {
81-
app.clone_message = info.clone_message;
82-
app.clone_status = info.clone_status;
83-
app.clone_progress = info.clone_progress;
84-
}
85-
}
86-
});
87-
});
70+
getAllAppsIndexStats() {
71+
return Parse.Promise.when(this.apps().map(app => {
72+
return Parse.Promise.when(
73+
app.getClassCount('_Installation').then(count => app.installations = count),
74+
app.getClassCount('_User').then(count => app.users = count)
75+
);
76+
}));
8877
},
8978

9079
// Options should be a list containing a subset of

0 commit comments

Comments
 (0)