mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-10-14 23:31:03 +08:00
Add option to group by process in collapsed dashboard view
This commit is contained in:
parent
579fe43fdf
commit
0abd70c746
6 changed files with 98 additions and 22 deletions
|
@ -248,3 +248,14 @@ pre {
|
||||||
.account-filter {
|
.account-filter {
|
||||||
padding-left: 5px;
|
padding-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.process-group {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 10px;
|
||||||
|
max-width: 250px;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
#group-by-process {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
<script src="/js/react.js"></script>
|
<script src="/js/react.js"></script>
|
||||||
<script src="/js/react-dom.js"></script>
|
<script src="/js/react-dom.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script>
|
||||||
<script src="/js/elapsed-time.jsx" type="text/babel"></script>
|
<script src="/js/elapsed-time.jsx" type="text/babel"></script>
|
||||||
<script src="/js/process-loads.jsx" type="text/babel"></script>
|
<script src="/js/process-loads.jsx" type="text/babel"></script>
|
||||||
<script src="/js/mini-account.jsx" type="text/babel"></script>
|
<script src="/js/mini-account.jsx" type="text/babel"></script>
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
const React = window.React;
|
const React = window.React;
|
||||||
const ReactDOM = window.ReactDOM;
|
const ReactDOM = window.ReactDOM;
|
||||||
|
const _ = window._;
|
||||||
const {
|
const {
|
||||||
SyncPolicy,
|
SyncPolicy,
|
||||||
SetAllSyncPolicies,
|
SetAllSyncPolicies,
|
||||||
|
@ -152,6 +153,7 @@ class Root extends React.Component {
|
||||||
assignments: {},
|
assignments: {},
|
||||||
activeAccountIds: [],
|
activeAccountIds: [],
|
||||||
visibleAccounts: AccountFilter.states.all,
|
visibleAccounts: AccountFilter.states.all,
|
||||||
|
groupByProcess: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +198,7 @@ class Root extends React.Component {
|
||||||
assignments: update.assignments || this.state.assignments,
|
assignments: update.assignments || this.state.assignments,
|
||||||
activeAccountIds: update.activeAccountIds || this.state.activeAccountIds,
|
activeAccountIds: update.activeAccountIds || this.state.activeAccountIds,
|
||||||
accounts: accounts,
|
accounts: accounts,
|
||||||
processLoadCounts: update.processLoadCounts,
|
processLoads: update.processLoads,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,6 +206,12 @@ class Root extends React.Component {
|
||||||
this.setState({visibleAccounts: document.getElementById('account-filter').value});
|
this.setState({visibleAccounts: document.getElementById('account-filter').value});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onGroupChange() {
|
||||||
|
this.setState({
|
||||||
|
groupByProcess: document.getElementById('group-by-proccess').checked,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let ids = Object.keys(this.state.accounts);
|
let ids = Object.keys(this.state.accounts);
|
||||||
|
|
||||||
|
@ -218,18 +226,70 @@ class Root extends React.Component {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AccountType = this.props.collapsed ? MiniAccount : Account;
|
let content;
|
||||||
let count = 0;
|
if (this.props.collapsed) {
|
||||||
|
const groupByProcess = (
|
||||||
return (
|
|
||||||
<div>
|
<div>
|
||||||
<ProcessLoads counts={this.state.processLoadCounts} />
|
<input
|
||||||
<AccountFilter id="account-filter" onChange={() => this.onFilter.call(this)} />
|
type="checkbox"
|
||||||
<SetAllSyncPolicies accountIds={ids.map((id) => parseInt(id, 10))} />
|
id="group-by-proccess"
|
||||||
|
onChange={() => this.onGroupChange()}
|
||||||
|
/>
|
||||||
|
Group Accounts By Process
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
if (this.state.groupByProcess) {
|
||||||
|
const accountsById = _.groupBy(this.state.accounts, 'id');
|
||||||
|
const processes = [];
|
||||||
|
|
||||||
|
for (const processName of Object.keys(this.state.processLoads)) {
|
||||||
|
const accounts = []
|
||||||
|
|
||||||
|
for (const accountId of this.state.processLoads[processName]) {
|
||||||
|
const account = accountsById[accountId][0];
|
||||||
|
accounts.push((
|
||||||
|
<MiniAccount key={accountId} account={account} />
|
||||||
|
))
|
||||||
|
}
|
||||||
|
processes.push((
|
||||||
|
<div key={processName} title={`Process: ${processName}`} className="process-group">
|
||||||
|
{accounts}
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
content = (
|
||||||
|
<div>
|
||||||
|
{groupByProcess}
|
||||||
|
<div id="accounts-wrapper">
|
||||||
|
{processes}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
content = (
|
||||||
|
<div>
|
||||||
|
{groupByProcess}
|
||||||
<div id="accounts-wrapper">
|
<div id="accounts-wrapper">
|
||||||
{
|
{
|
||||||
ids.sort((a, b) => a / 1 - b / 1).map((id) =>
|
ids.sort((a, b) => a / 1 - b / 1).map((id) =>
|
||||||
<AccountType
|
<MiniAccount
|
||||||
|
key={id}
|
||||||
|
account={this.state.accounts[id]}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let count = 0;
|
||||||
|
content = (
|
||||||
|
<div id="accounts-wrapper">
|
||||||
|
{
|
||||||
|
ids.sort((a, b) => a / 1 - b / 1).map((id) =>
|
||||||
|
<Account
|
||||||
key={id}
|
key={id}
|
||||||
active={this.state.activeAccountIds.includes(id)}
|
active={this.state.activeAccountIds.includes(id)}
|
||||||
assignment={this.state.assignments[id]}
|
assignment={this.state.assignments[id]}
|
||||||
|
@ -239,6 +299,15 @@ class Root extends React.Component {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<ProcessLoads loads={this.state.processLoads} />
|
||||||
|
<AccountFilter id="account-filter" onChange={() => this.onFilter.call(this)} />
|
||||||
|
<SetAllSyncPolicies accountIds={ids.map((id) => parseInt(id, 10))} />
|
||||||
|
{content}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,11 +15,9 @@ class MiniAccount extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {account, assignment, active} = this.props;
|
|
||||||
|
|
||||||
let errorClass;
|
let errorClass;
|
||||||
let style;
|
let style;
|
||||||
if (account.sync_error) {
|
if (this.props.account.sync_error) {
|
||||||
errorClass = 'errored';
|
errorClass = 'errored';
|
||||||
style = {};
|
style = {};
|
||||||
} else {
|
} else {
|
||||||
|
@ -38,9 +36,6 @@ class MiniAccount extends React.Component {
|
||||||
|
|
||||||
MiniAccount.propTypes = {
|
MiniAccount.propTypes = {
|
||||||
account: React.PropTypes.object,
|
account: React.PropTypes.object,
|
||||||
active: React.PropTypes.bool,
|
|
||||||
assignment: React.PropTypes.string,
|
|
||||||
count: React.PropTypes.number,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
window.MiniAccount = MiniAccount;
|
window.MiniAccount = MiniAccount;
|
||||||
|
|
|
@ -3,17 +3,17 @@ const React = window.React;
|
||||||
function ProcessLoads(props) {
|
function ProcessLoads(props) {
|
||||||
let entries;
|
let entries;
|
||||||
let sumElem;
|
let sumElem;
|
||||||
if (props.counts == null || Object.keys(props.counts).length === 0) {
|
if (props.loads == null || Object.keys(props.loads).length === 0) {
|
||||||
entries = "No Data";
|
entries = "No Data";
|
||||||
sumElem = "";
|
sumElem = "";
|
||||||
} else {
|
} else {
|
||||||
entries = [];
|
entries = [];
|
||||||
let sum = 0;
|
let sum = 0;
|
||||||
for (const processName of Object.keys(props.counts).sort()) {
|
for (const processName of Object.keys(props.loads).sort()) {
|
||||||
const count = props.counts[processName];
|
const count = props.loads[processName].length;
|
||||||
sum += count;
|
sum += count;
|
||||||
entries.push(
|
entries.push(
|
||||||
<div className="load-count">
|
<div className="load-count" key={processName}>
|
||||||
<b>{processName}</b>: {count} accounts
|
<b>{processName}</b>: {count} accounts
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -31,7 +31,7 @@ function ProcessLoads(props) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessLoads.propTypes = {
|
ProcessLoads.propTypes = {
|
||||||
counts: React.PropTypes.object,
|
loads: React.PropTypes.object,
|
||||||
}
|
}
|
||||||
|
|
||||||
window.ProcessLoads = ProcessLoads;
|
window.ProcessLoads = ProcessLoads;
|
||||||
|
|
|
@ -11,7 +11,7 @@ function onWebsocketConnected(wss, ws) {
|
||||||
updatedAccounts: [],
|
updatedAccounts: [],
|
||||||
activeAccountIds: [],
|
activeAccountIds: [],
|
||||||
assignments: {},
|
assignments: {},
|
||||||
processLoadCounts: {},
|
processLoads: {},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
resetToSend();
|
resetToSend();
|
||||||
|
@ -43,7 +43,7 @@ function onWebsocketConnected(wss, ws) {
|
||||||
toSend.activeAccountIds = accountIds;
|
toSend.activeAccountIds = accountIds;
|
||||||
});
|
});
|
||||||
const getAssignments = SchedulerUtils.forEachAccountList((identity, accountIds) => {
|
const getAssignments = SchedulerUtils.forEachAccountList((identity, accountIds) => {
|
||||||
toSend.processLoadCounts[identity] = accountIds.length;
|
toSend.processLoads[identity] = accountIds;
|
||||||
for (const accountId of accountIds) {
|
for (const accountId of accountIds) {
|
||||||
toSend.assignments[accountId] = identity;
|
toSend.assignments[accountId] = identity;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue