Update SyncModal to only show current Workspace

This commit is contained in:
Gregory Schier 2016-11-10 14:14:39 -08:00
parent 7f0991c2e1
commit 2172df2d40
3 changed files with 141 additions and 163 deletions

View File

@ -4,8 +4,8 @@ import * as fetch from '../common/fetch';
import * as crypt from './crypt';
import * as session from './session';
import * as store from './storage';
import Logger from './logger';
import * as misc from '../common/misc';
import Logger from './logger';
export const FULL_SYNC_INTERVAL = 60E3;
export const QUEUE_DEBOUNCE_TIME = 1E3;

View File

@ -51,12 +51,13 @@ class SyncButton extends Component {
}
render () {
const {workspaceId} = this.props;
const {state: buttonState} = this.state;
if (session.isLoggedIn()) {
return (
<button className="btn btn--super-duper-compact btn--outlined wide ellipsis"
onClick={e => showModal(SyncModal)}>
Sync
{this.state.state ? <span>&nbsp;({this.state.state})</span> : null}
onClick={e => showModal(SyncModal, workspaceId)}>
Sync {buttonState ? `(${buttonState})` : null}
</button>
)
} else {

View File

@ -20,8 +20,9 @@ class SyncModal extends Component {
email: 'n/a',
sessionId: 'n/a',
dirty: [],
syncData: [],
syncingResourceGroups: {},
workspace: null,
syncData: null
}
}
@ -39,7 +40,7 @@ class SyncModal extends Component {
delete syncingResourceGroups[resourceGroupId];
this.setState({syncingResourceGroups});
await this._updateModal();
await this._updateModal(this.state.workspace);
trackEvent('Sync', 'Push');
}
@ -50,7 +51,7 @@ class SyncModal extends Component {
await sync.createOrUpdateConfig(resourceGroupId, syncMode);
// Refresh the modal
this._updateModal();
this._updateModal(this.state.workspace);
trackEvent('Sync', 'Change Mode', syncMode);
}
@ -68,55 +69,50 @@ class SyncModal extends Component {
sync.logout();
}
async _updateModal () {
const workspaces = await models.workspace.all();
const syncData = [];
for (const workspace of workspaces) {
async _updateModal (workspace) {
// Get or create any related sync data
const resource = await sync.getOrCreateResourceForDoc(workspace);
const resourceGroupId = resource.resourceGroupId;
const config = await sync.getOrCreateConfig(resourceGroupId);
// Get or create any related sync data
const resource = await sync.getOrCreateResourceForDoc(workspace);
const resourceGroupId = resource.resourceGroupId;
const config = await sync.getOrCreateConfig(resourceGroupId);
// Analyze it
const dirty = await syncStorage.findActiveDirtyResourcesForResourceGroup(resourceGroupId);
const all = await syncStorage.findResourcesForResourceGroup(resourceGroupId);
const numClean = all.length - dirty.length;
const syncPercent = all.length === 0 ? 100 : parseInt(numClean / all.length * 1000) / 10;
// Analyze it
const dirty = await syncStorage.findActiveDirtyResourcesForResourceGroup(resourceGroupId);
const all = await syncStorage.findResourcesForResourceGroup(resourceGroupId);
const numClean = all.length - dirty.length;
let syncPercent;
if (all.length === 0) {
syncPercent = 100;
} else {
syncPercent = parseInt(numClean / all.length * 1000) / 10
}
syncData.push({
resource,
syncPercent,
syncMode: config.syncMode,
name: workspace.name,
});
}
const syncData ={
resource,
syncPercent,
syncMode: config.syncMode,
name: workspace.name,
};
this.setState({
syncData,
workspace,
email: session.getEmail(),
firstName: session.getFirstName(),
sessionId: session.getCurrentSessionId(),
});
}
async show () {
async show (workspaceId) {
if (!session.isLoggedIn()) {
console.error('Not logged in');
return;
}
this.modal.show();
const workspace = await models.workspace.getById(workspaceId);
if (!workspace) {
return;
}
clearInterval(this._interval);
await this._updateModal();
this._interval = setInterval(() => this._updateModal(), 2000);
this.modal.show();
await this._updateModal(workspace);
clearInterval(this._interval); // Make sure it's off
this._interval = setInterval(() => this._updateModal(workspace), 2000);
}
hide () {
@ -125,10 +121,17 @@ class SyncModal extends Component {
}
render () {
const s = this.state;
const {
email,
sessionId,
workspace,
syncData,
syncingResourceGroups
} = this.state;
const data = [
['Email', s.email],
['Session', s.sessionId],
['Email', email],
['Session', sessionId],
['Full Sync', `${sync.FULL_SYNC_INTERVAL / 1000} second interval`],
['Partial Sync', `${sync.PUSH_DEBOUNCE_TIME / 1000} seconds after change`],
];
@ -143,134 +146,108 @@ class SyncModal extends Component {
const allLogs = sync.logger.tail();
const logs = allLogs.slice(allLogs.length - 500);
return (
<Modal ref={m => this.modal = m} tall={true} wide={true}>
<ModalHeader>
Sync Settings
{" "}
<span className="faint txt-md monospace">({s.email})</span>
</ModalHeader>
<ModalBody noScroll={true}>
<Tabs>
<TabList>
<Tab>
<button>Overview</button>
</Tab>
<Tab>
<button>Debug Info</button>
</Tab>
<Tab>
<button>Debug Logs</button>
</Tab>
</TabList>
<TabPanel className="pad scrollable">
<table>
<thead>
<tr>
<th>Workspace</th>
<th>Sync</th>
<th>Synced</th>
<th>Team</th>
let modalBody = null;
if (syncData) {
const {syncMode, syncPercent, resource} = syncData;
const {resourceGroupId} = resource;
modalBody = (
<Tabs>
<TabList>
<Tab>
<button>Overview</button>
</Tab>
<Tab>
<button>Debug Info</button>
</Tab>
<Tab>
<button>Debug Logs</button>
</Tab>
</TabList>
<TabPanel className="pad scrollable">
<h1>{workspace ? workspace.name : 'Loading...'} {syncPercent}%</h1>
<div key={resource._id}>
<select name="sync-type"
id="sync-type"
value={syncMode}
onChange={this._handleSyncModeChange.bind(this, syncData)}>
<option value={syncStorage.SYNC_MODE_ON}>Automatic</option>
<option value={syncStorage.SYNC_MODE_OFF}>Manual</option>
</select>
&nbsp;&nbsp;
<button
title={syncPercent === 100 ? 'Nothing to push' : 'Push local changes'}
disabled={syncPercent === 100}
className="btn btn--super-duper-compact btn--outlined"
onClick={e => this._handleSyncResourceGroupId(resourceGroupId)}>
<i className={classnames(
'fa fa-refresh', {'fa-spin': syncingResourceGroups[resourceGroupId]}
)}></i> Sync
</button>
<div>
<select name="team" id="team" disabled="disabled">
<option value="other">Coming soon...</option>
</select>
</div>
</div>
</TabPanel>
<TabPanel className="pad scrollable">
<p>
Here is some useful debug info in case you need to report a bug.
</p>
<table>
<tbody>
{data.map(([label, value]) => (
<tr key={label}>
<td>{label}</td>
<td>
<code className="txt-sm selectable">{value}</code>
</td>
</tr>
</thead>
<tbody>
{this.state.syncData.map(data => {
const {syncMode, name, syncPercent, resource} = data;
const {resourceGroupId} = resource;
return (
<tr key={resource._id}>
<td>{name}</td>
<td>
<select name="sync-type"
id="sync-type"
value={syncMode}
onChange={this._handleSyncModeChange.bind(this, data)}>
<option value={syncStorage.SYNC_MODE_ON}>Automatic
</option>
<option value={syncStorage.SYNC_MODE_OFF}>Manual
</option>
</select>
&nbsp;&nbsp;
<button
title={syncPercent === 100 ? 'Nothing to push' : 'Push local changes'}
disabled={syncPercent === 100}
className="btn btn--super-duper-compact btn--outlined"
onClick={e => this._handleSyncResourceGroupId(resourceGroupId)}>
<i className={classnames(
'fa fa-refresh',
{'fa-spin': this.state.syncingResourceGroups[resourceGroupId]}
)}></i>
{" "}
Sync
</button>
</td>
<td className={syncPercent < 100 ? 'warning' : ''}>
{syncPercent}%
</td>
<td className="faint italic">
<select name="team" id="team" disabled="disabled">
<option value="other">Coming soon...</option>
</select>
</td>
</tr>
)
}
)}
</tbody>
</table>
</TabPanel>
<TabPanel className="pad scrollable">
<p>
Here is some useful debug info in case you need to report a bug.
</p>
<table>
<tbody>
{data.map(([label, value]) => (
<tr key={label}>
<td>{label}</td>
<td>
<code className="txt-sm selectable">{value}</code>
</td>
</tr>
))}
</tbody>
</table>
</TabPanel>
<TabPanel className="scrollable">
<div className="selectable txt-sm monospace pad">
{logs.map((entry, i) => {
function pad (n, length) {
let s = n + '';
while (s.length < length) {
s = '0' + s;
}
return s;
))}
</tbody>
</table>
</TabPanel>
<TabPanel className="scrollable">
<div className="selectable txt-sm monospace pad">
{logs.map((entry, i) => {
function pad (n, length) {
let s = n + '';
while (s.length < length) {
s = '0' + s;
}
return s;
}
const dateString =
pad(entry.date.getFullYear(), 4) + '/' +
pad(entry.date.getMonth() + 1, 2) + '/' +
pad(entry.date.getDate(), 2) + ' ' +
pad(entry.date.getHours(), 2) + ':' +
pad(entry.date.getMinutes(), 2) + ':' +
pad(entry.date.getSeconds(), 2);
return (
<pre key={i}>
const dateString =
pad(entry.date.getFullYear(), 4) + '/' +
pad(entry.date.getMonth() + 1, 2) + '/' +
pad(entry.date.getDate(), 2) + ' ' +
pad(entry.date.getHours(), 2) + ':' +
pad(entry.date.getMinutes(), 2) + ':' +
pad(entry.date.getSeconds(), 2);
return (
<pre key={i}>
<span className="faint">{dateString}</span>
{" "}
<span style={{minWidth: '4rem'}}
className={classnames(colors[entry.type], 'inline-block')}>
{" "}
<span style={{minWidth: '4rem'}}
className={classnames(colors[entry.type], 'inline-block')}>
[{entry.type}]
</span>
{" "}
{entry.message}
{" "}
{entry.message}
</pre>
)
})}
</div>
</TabPanel>
</Tabs>
</ModalBody>
)
})}
</div>
</TabPanel>
</Tabs>
)
}
return (
<Modal ref={m => this.modal = m} tall={true} wide={true}>
<ModalHeader>Sync Settings</ModalHeader>
<ModalBody noScroll={true}>{modalBody}</ModalBody>
<ModalFooter>
<div>
<PromptButton className="btn" onClick={e => this._handleLogout()}>