Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
26b11a0
dev-bl/zoombuttons: Centralize zoom handler and add zoom buttons.
benloh Dec 6, 2018
81129be
dev-bl/zoombuttons: Move zoom buttons to upper right and stack them v…
benloh Dec 6, 2018
60c0b7b
dev-bl/edge-highlight: Highlight edges adjacent to selected node on n…
benloh Dec 7, 2018
adbd44d
dev-bl/edge-highlight: Hilight edges on mouseover.
benloh Dec 7, 2018
61edda9
dev-bl/edge-counts: Add edge counts to Node table.
benloh Dec 7, 2018
1db293b
dev-bl/edge-counts: Add "Degrees" label to template.
benloh Dec 7, 2018
47812e1
dev-bl/table-format: Fix header rows for both Node Table and Edge Table.
benloh Dec 7, 2018
885692e
dev-bl/table-format: Add tab navigation for tables and help.
benloh Dec 7, 2018
3bd86ca
dev-bl/table-format: Show expanded table by default. Remove "Show/Hi…
benloh Dec 7, 2018
e382ed2
dev-bl/table-resize: Add new resizable InfoPanel for tables.
benloh Dec 8, 2018
a34134f
dev-bl/delete-node: Show/hide delete button based on template.
benloh Dec 10, 2018
e3ff24e
dev-bl/delete-node: Add server handlers for delete node requests. Al…
benloh Dec 10, 2018
857d4c4
dev-bl/delete-node: Add local handler for deleting nodes (and related…
benloh Dec 11, 2018
0aa75c0
dev-bl/delete-note: Add replacementNodeID field next to Delete button…
benloh Dec 11, 2018
4528379
dev-bl/edge-highlight: Make non-moused-over edges more visible.
benloh Dec 12, 2018
202d853
dev-bl/delete-node: Add validation for replacement Node ID.
benloh Dec 12, 2018
4c7f1bd
dev-bl/table-format: Remove test click button.
benloh Dec 12, 2018
72390b9
dev-bl/delete-node: Show delete button only on localhost.
benloh Dec 13, 2018
05092aa
dev-bl/delete-node: Bug Fix: DB was not deleting nodes because string…
benloh Dec 13, 2018
7c9089b
dev-bl/delete-ndoe: Bug Fix: Convert any legacy edge-related string i…
benloh Dec 13, 2018
9392ce2
dev-bl/duplicate-label: Add duplicate node label warning.
benloh Dec 13, 2018
4fae68e
dev-bl/duplicate-label: Read duplicate warning from template.
benloh Dec 13, 2018
3664be4
dev-bl/table-format: Fix bug where a second click of EdgeTable "Edit"…
benloh Dec 13, 2018
18377c7
dev-bl/table-format: Fix bug where AutoComplete field would use outda…
benloh Dec 13, 2018
03bbca7
dev-bl/table-format: Set min widths of Node and EdgeTable so columns …
benloh Dec 13, 2018
58a34a5
dev-bl/table-format: Second click on tab now 'closes' the tab.
benloh Dec 13, 2018
be58c8e
dev-bl/duplicate-label: Duplicate warning is now only shown when edit…
benloh Dec 13, 2018
b2cc3cb
dev-bl/table-format: Cusor is now a pointer over InfoPanel tabs.
benloh Dec 14, 2018
ec031f5
dev-bl/duplicate-label: Case-insensitive search for duplicate labels.
benloh Dec 14, 2018
4d2d335
dev-bl/center-zoom: Maximize svg and center the graph.
benloh Dec 18, 2018
cf20d21
dev-bl/duplicate-label: Show duplicate lable warning with recovery op…
benloh Dec 18, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion build/app/assets/templates/alexander.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"label": {
"label": "Label",
"help": "A short title for the node",
"duplicateWarning": "You’re entering a duplicate node. Do you want to View the Existing node, or Continue creating?",
"_cmt4": "/// `Label` is always required and cannot be hidden"
},
"type": {
Expand Down Expand Up @@ -59,6 +60,11 @@
}
]
},
"degrees": {
"label": "Degrees",
"help": "Number of edges.",
"hidden": false
},
"notes": {
"label": "Significance",
"help": "Add some details.",
Expand All @@ -68,7 +74,10 @@
"label": "Geocode or Date",
"help": "Use latitude/longitude or a date mm/dd/yyy",
"hidden": true
}
},
"delete": {
"hidden": false
}
},


Expand Down
39 changes: 38 additions & 1 deletion build/app/unisys/server-database.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ let DB = {};
};
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DB.PKT_Update = function ( pkt ) {
let { node, edge, edgeID } = pkt.Data();
let { node, edge, nodeID, replacementNodeID, edgeID } = pkt.Data();
let retval = {};

// PROCESS NODE INSERT/UPDATE
Expand Down Expand Up @@ -192,6 +192,43 @@ let DB = {};
return retval;
} // if edge

// DELETE NODES
if (nodeID !== undefined) {
if (DBG) console.log(PR, `PKT_Update ${pkt.Info()} DELETE nodeID ${nodeID}`);

// Log first so it's apparent what is triggering the edge changes
LOGGER.Write(pkt.Info(), `delete node`, nodeID);

// handle edges
let edgesToProcess = EDGES.where((e) => {
return e.source === nodeID || e.target === nodeID;
});
// `NaN` is not valid JSON, so we use ``
if (replacementNodeID !== '') {
// re-link edges to replacementNodeID
EDGES.findAndUpdate({ source: nodeID }, (e) => {
LOGGER.Write(`...`, pkt.Info(), `relinking edge`, e.id, `to`, replacementNodeID);
e.source = replacementNodeID;
});
EDGES.findAndUpdate({ target: nodeID }, (e) => {
LOGGER.Write(`...`, pkt.Info(), `relinking edge`, e.id, `to`, replacementNodeID);
e.target = replacementNodeID;
});
} else {
// delete edges
EDGES.findAndRemove({ source: nodeID }, (e) => {
LOGGER.Write(`...`, pkt.Info(), `deleting edge`, e.id, `from`, nodeID);
e.source = nodeID;
});
EDGES.findAndRemove({ target: nodeID }, (e) => {
LOGGER.Write(`...`, pkt.Info(), `deleting edge`, e.id, `from`, nodeID);
e.target = nodeID;
});
}
NODES.findAndRemove({ id: nodeID });
return { op: 'delete', nodeID, replacementNodeID };
}

// DELETE EDGES
if (edgeID!==undefined) {
if (DBG) console.log(PR,`PKT_Update ${pkt.Info()} DELETE edgeID ${edgeID}`);
Expand Down
3 changes: 2 additions & 1 deletion build/app/unisys/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ var UNISYS = {};
data.src = 'remote';
// fire update messages
if (data.node) UNET.NetSend('SOURCE_UPDATE',data);
if (data.edge) UNET.NetSend('EDGE_UPDATE',data);
if (data.edge) UNET.NetSend('EDGE_UPDATE', data);
if (data.nodeID!==undefined) UNET.NetSend('NODE_DELETE', data);
if (data.edgeID!==undefined) UNET.NetSend('EDGE_DELETE',data);
// return SRV_DBUPDATE value (required)
return { OK:true, info:'SRC_DBUPDATE' };
Expand Down
14 changes: 8 additions & 6 deletions build/app/view/netcreate/NetCreate.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,7 @@ const { Route } = require('react-router-dom');
const NetGraph = require('./components/NetGraph');
const Search = require('./components/Search');
const NodeSelector = require('./components/NodeSelector');
const Help = require('./components/Help');
const NodeTable = require('./components/NodeTable');
const EdgeTable = require('./components/EdgeTable');
const InfoPanel = require('./components/InfoPanel');
const NCLOGIC = require('./nc-logic'); // require to bootstrap data loading


Expand Down Expand Up @@ -77,11 +75,17 @@ const NCLOGIC = require('./nc-logic'); // require to bootstrap data loading
});
}




/// REACT LIFECYCLE METHODS ///////////////////////////////////////////////////
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*/ This is the root component, so this fires after all subcomponents have
been fully rendered by render().
/*/ componentDidMount () {
// Init dragger
let dragger = document.getElementById('dragger');
dragger.onmousedown = this.handleMouseDown;
}
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*/ Define the component structure of the web application
Expand All @@ -100,9 +104,7 @@ const NCLOGIC = require('./nc-logic'); // require to bootstrap data loading
</div>
</div>
<div id="middle" style={{backgroundColor:'#fcfcfc', flex:'3 0 60%', padding:'10px',marginTop:'56px'}}>
<Help/>
<NodeTable/>
<EdgeTable/>
<InfoPanel/>
<NetGraph/>
<div style={{fontSize:'10px',position:'absolute',left:'0px',bottom:'0px',zIndex:'1500',color:'#aaa',backgroundColor:'#eee',padding:'5px 10px'}}>Please contact Professor
Kalani Craig, Institute for Digital Arts & Humanities at
Expand Down
5 changes: 5 additions & 0 deletions build/app/view/netcreate/components/AutoComplete.css
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ td {
hyphens: auto;
}

/* Bootstrap override */
.nav-item {
cursor: pointer;
}

/* SVG styles */
/* REVIEW!!! These are global!!! */
svg {
Expand Down
97 changes: 69 additions & 28 deletions build/app/view/netcreate/components/AutoComplete.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ class AutoComplete extends UNISYS.Component {
https://reactjs.org/blog/2015/12/16/ismounted-antipattern.html
/*/ componentDidMount () {
_IsMounted = true;
this.setState({ mode: this.props.inactiveMode })
this.setState({ mode: this.props.inactiveMode });
}
/*/
/*/ componentWillUnmount () {
Expand All @@ -357,34 +357,75 @@ class AutoComplete extends UNISYS.Component {
onChange : this.onInputChange
};
let jsx;
switch (this.state.mode) {
case MODE_STATIC:
jsx = ( <p>{this.props.disabledValue}</p> );
break;
case MODE_DISABLED:
jsx = ( <Input type="text" value={this.props.disabledValue} readOnly={true}/> );
break;
case MODE_ACTIVE:
jsx = (
<Autosuggest
suggestions={suggestions}
shouldRenderSuggestions={this.shouldRenderSuggestions}
// Map to Local Handlers for Autosuggest event triggers (requests)
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
getSuggestionValue={this.getSuggestionValue}
renderSuggestion={this.renderSuggestion}
// Receive Data from Autosuggest
onSuggestionHighlighted={this.onSuggestionHighlighted}
onSuggestionSelected={this.onSuggestionSelected}
// Pass Data to Autosuggest
inputProps={inputProps}
/>
);
break;
default:
throw Error(`AutoComplete: Unhandled mode '${this.state.mode}'`);

// Show different widgets depending on mode.
// If MODE_ACTIVE is just show the active state,
// otherwise, use the current inactive mode in this.props.inactiveMode
// to define the inactive state
// because this.state.mode may not be up to date if the mode is inactive
// due to prop changes not triggering mode updates.
// e.g. if the parent container changed props from a disabled to
// static state, it does not trigger a mode update in AUTOCOMPLETE.
// This is mostly an edge case with EDGE_EDITs which will update props
// without a corresponding UNISYS message call to trigger the mode
// change.
if (this.state.mode === MODE_ACTIVE) {
jsx = (
<Autosuggest
suggestions={suggestions}
shouldRenderSuggestions={this.shouldRenderSuggestions}
// Map to Local Handlers for Autosuggest event triggers (requests)
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
getSuggestionValue={this.getSuggestionValue}
renderSuggestion={this.renderSuggestion}
// Receive Data from Autosuggest
onSuggestionHighlighted={this.onSuggestionHighlighted}
onSuggestionSelected={this.onSuggestionSelected}
// Pass Data to Autosuggest
inputProps={inputProps}
/>
);
} else if (this.props.inactiveMode === MODE_STATIC) {
jsx = (<p>{this.props.disabledValue}</p>);
} else if (this.props.inactiveMode === MODE_DISABLED) {
jsx = (<Input type="text" value={this.props.disabledValue} readOnly={true} />);
} else {
throw Error(`AutoComplete: Unhandled mode '${this.state.mode}'`);
}

// OLD METHOD
// This relied on mode being updated, but a change in props does not
// trigger a corresponding change in mode.
// switch (this.state.mode) {
// case MODE_STATIC:
// jsx = ( <p>{this.props.disabledValue}</p> );
// break;
// case MODE_DISABLED:
// jsx = ( <Input type="text" value={this.props.disabledValue} readOnly={true}/> );
// break;
// case MODE_ACTIVE:
// jsx = (
// <Autosuggest
// suggestions={suggestions}
// shouldRenderSuggestions={this.shouldRenderSuggestions}
// // Map to Local Handlers for Autosuggest event triggers (requests)
// onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
// onSuggestionsClearRequested={this.onSuggestionsClearRequested}
// getSuggestionValue={this.getSuggestionValue}
// renderSuggestion={this.renderSuggestion}
// // Receive Data from Autosuggest
// onSuggestionHighlighted={this.onSuggestionHighlighted}
// onSuggestionSelected={this.onSuggestionSelected}
// // Pass Data to Autosuggest
// inputProps={inputProps}
// />
// );
// break;
// default:
// throw Error(`AutoComplete: Unhandled mode '${this.state.mode}'`);
// }

return jsx;
} // render()

Expand Down
24 changes: 14 additions & 10 deletions build/app/view/netcreate/components/EdgeEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ class EdgeEditor extends UNISYS.Component {
// as a handler, otherwise object context is lost

/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*/ SESSION is called by SessionSHell when the ID changes
/*/ SESSION is called by SessionShell when the ID changes
set system-wide. data: { classId, projId, hashedId, groupId, isValid }
/*/ this.OnAppStateChange('SESSION',this.onStateChange_SESSION);
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Expand Down Expand Up @@ -313,12 +313,16 @@ class EdgeEditor extends UNISYS.Component {
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*/ populate formdata from D3DATA
/*/ loadSourceAndTarget () {
if (DBG) console.log('EdgeEditor.loadSourceAndTarget!')
if (DBG) console.log('EdgeEditor.loadSourceAndTarget!')

let edgeID = this.props.edgeID || '';

// Clean Data
if (isNaN(edgeID)) { edgeID = parseInt(edgeID); }

let D3DATA = this.AppState('D3DATA');

let edges = D3DATA.edges.filter( edge=>edge.id===edgeID );
// parseInt in case of old bad string id
let edges = D3DATA.edges.filter( edge=>parseInt(edge.id)===edgeID );
if (!edges) {
throw 'EdgeEditor: Passed edgeID'+edgeID+'not found!';
}
Expand All @@ -344,7 +348,7 @@ class EdgeEditor extends UNISYS.Component {
// Define `edge` so it can be loaded later during setState.
edge = {
id: edgeID,
source: sourceNodes[0].id, // REVIEW: d3data 'source' is id, rename this to 'sourceId'?
source: parseInt(sourceNodes[0].id), // REVIEW: d3data 'source' is id, rename this to 'sourceId'?
// though after d3 processes, source does become an object.
target: undefined,
attributes: {
Expand All @@ -365,8 +369,8 @@ class EdgeEditor extends UNISYS.Component {

// LOAD EXISTING EDGE

sourceNodes = D3DATA.nodes.filter( node => node.id===edge.source.id );
targetNodes = D3DATA.nodes.filter( node => node.id===edge.target.id );
sourceNodes = D3DATA.nodes.filter( node => parseInt(node.id)===parseInt(edge.source.id) );
targetNodes = D3DATA.nodes.filter( node => parseInt(node.id)===parseInt(edge.target.id) );

// Assume we have a valid target node
this.setState({
Expand All @@ -388,7 +392,7 @@ class EdgeEditor extends UNISYS.Component {
if (DBG) console.log('...EdgeEditor.loadSourceAndTarget: Setting formData sourceID to',edge.source,'and sourceNode to',sourceNode,'and targetNode to',targetNode);
this.setState({
formData: {
id: edge.id || '',
id: parseInt(edge.id) || '',
sourceId: edge.source,
targetId: edge.target,
relationship: edge.attributes["Relationship"] || '', // Make sure there's valid data
Expand Down Expand Up @@ -430,7 +434,7 @@ class EdgeEditor extends UNISYS.Component {
// SOURCE
if (DBG) console.log('EdgeEditor.handleSelection:',this.props.edgeID,'setting source node to',node);

// Set sourceNpde state
// Set sourceNode state
this.setState({
sourceNode: node
});
Expand All @@ -447,7 +451,7 @@ class EdgeEditor extends UNISYS.Component {
sourceIsEditable: false
});

} else {
} else if (this.state.targetIsEditable) {
// TARGET
if (DBG) console.log('EdgeEditor.handleSelection:',this.props.edgeID,'setting target node to',node);

Expand Down
29 changes: 25 additions & 4 deletions build/app/view/netcreate/components/EdgeTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@

Set `DBG` to true to show the `ID` column.

## 2018-12-07 Update

Since we're not using tab navigation:
1. The table isExpanded is now true by default.
2. The "Show/Hide Table" button is hidden.

Reset these to restore previous behavior.

\*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ * //////////////////////////////////////*/

Expand All @@ -38,7 +45,7 @@ class EdgeTable extends UNISYS.Component {
this.state = {
edgePrompts: this.AppState('TEMPLATE').edgePrompts,
edges: [],
isExpanded: false,
isExpanded: true,
sortkey: 'Citations'
};

Expand Down Expand Up @@ -259,13 +266,27 @@ class EdgeTable extends UNISYS.Component {
/*/
/*/ render () {
let { edgePrompts } = this.state;
let { tableHeight } = this.props;
let styles = `thead, tbody { display: block; }
thead { position: relative; }
tbody { overflow: auto; }
.edgetable td:nth-child(1), .edgetable th:nth-child(1) {width: 2em; min-width: 2em;}
.edgetable td:nth-child(2), .edgetable th:nth-child(2) {width: 2em; min-width: 2em;}
.edgetable td:nth-child(3), .edgetable th:nth-child(3) {width: 4em; min-width: 4em;}
.edgetable td:nth-child(4), .edgetable th:nth-child(4) {width: 6em; min-width: 6em;}
.edgetable td:nth-child(5), .edgetable th:nth-child(5) {width: 14em; min-width: 14em;}
.edgetable td:nth-child(6), .edgetable th:nth-child(6) {width: 6em; min-width: 6em;}
.edgetable td:nth-child(7), .edgetable th:nth-child(7) {width: 6em; min-width: 6em;}
.edgetable td:nth-child(8), .edgetable th:nth-child(8) {min-width: 6em; }`
return (
<div style={{maxHeight:'50vh',overflow:'scroll',backgroundColor:'#f3f3ff'}}>
<Button size="sm" outline
<div style={{backgroundColor:'#f3f3ff'}}>
<style>{styles}</style>
<Button size="sm" outline hidden
onClick={this.onToggleExpanded}
>{this.state.isExpanded ? "Hide Edge Table" : "Show Edge Table"}</Button>
<Table hidden={!this.state.isExpanded} hover size="sm"
responsive striped
className="edgetable"
>
<thead>
<tr>
Expand Down Expand Up @@ -301,7 +322,7 @@ class EdgeTable extends UNISYS.Component {
>{edgePrompts.info.label}</Button></th>
</tr>
</thead>
<tbody>
<tbody style={{ maxHeight: tableHeight }}>
{this.state.edges.map( (edge,i) => (
<tr key={i}>
<td hidden={!DBG}>{edge.id}</td>
Expand Down
Loading