mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-23 14:00:56 +01:00
d25a9530a7
Summary: Moves search and new room out of crumb bar and into the thread column. This opens up space to add "Edit Room" into the crumbs area as an action link. Also removed 'widget-edit' pathways and javascript. Fixes T8972 Test Plan: Search, New, Edit rooms. Click different rooms, see correct URL each time. {F1813226} Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Maniphest Tasks: T8972 Differential Revision: https://secure.phabricator.com/D16543
382 lines
12 KiB
JavaScript
382 lines
12 KiB
JavaScript
/**
|
|
* @requires javelin-behavior
|
|
* javelin-dom
|
|
* javelin-stratcom
|
|
* javelin-workflow
|
|
* javelin-util
|
|
* phabricator-notification
|
|
* javelin-behavior-device
|
|
* phuix-dropdown-menu
|
|
* phuix-action-list-view
|
|
* phuix-action-view
|
|
* conpherence-thread-manager
|
|
* @provides javelin-behavior-conpherence-widget-pane
|
|
*/
|
|
|
|
JX.behavior('conpherence-widget-pane', function(config) {
|
|
|
|
/**
|
|
* There can be race conditions around loading the messages or the widgets
|
|
* first. Keep track of what widgets we've loaded with this variable.
|
|
*/
|
|
var _loadedWidgetsID = null;
|
|
|
|
/**
|
|
* At any given time there can be only one selected widget. Keep track of
|
|
* which one it is by the user-facing name for ease of use with
|
|
* PhabricatorDropdownMenuItems.
|
|
*/
|
|
var _selectedWidgetName = null;
|
|
|
|
/**
|
|
* This is potentially built each time the user switches conpherence threads
|
|
* or when the result JX.Device.getDevice() changes from desktop to some
|
|
* other value.
|
|
*/
|
|
var buildDeviceWidgetSelector = function (data) {
|
|
var device_header = _getDeviceWidgetHeader();
|
|
if (!device_header) {
|
|
return;
|
|
}
|
|
JX.DOM.show(device_header);
|
|
var device_menu = new JX.PHUIXDropdownMenu(device_header);
|
|
data.deviceMenu = true;
|
|
_buildWidgetSelector(device_menu, data);
|
|
};
|
|
|
|
/**
|
|
* This is potentially built each time the user switches conpherence threads
|
|
* or when the result JX.Device.getDevice() changes from mobile or tablet to
|
|
* desktop.
|
|
*/
|
|
var buildDesktopWidgetSelector = function (data) {
|
|
var root = JX.DOM.find(document, 'div', 'conpherence-layout');
|
|
var widget_pane = JX.DOM.find(root, 'div', 'conpherence-widget-pane');
|
|
var widget_header = JX.DOM.find(widget_pane, 'a', 'widgets-selector');
|
|
|
|
var menu = new JX.PHUIXDropdownMenu(widget_header);
|
|
menu
|
|
.setAlign('left')
|
|
.setOffsetY(4);
|
|
|
|
data.deviceMenu = false;
|
|
_buildWidgetSelector(menu, data);
|
|
};
|
|
|
|
/**
|
|
* Workhorse that actually builds the widget selector. Note some fancy bits
|
|
* where we listen for the "open" event and enable / disable widgets as
|
|
* appropos.
|
|
*/
|
|
var _buildWidgetSelector = function (menu, data) {
|
|
_loadedWidgetsID = data.threadID;
|
|
|
|
var list = new JX.PHUIXActionListView();
|
|
var map = {};
|
|
|
|
var widgets = config.widgetRegistry;
|
|
for (var widget in widgets) {
|
|
var widget_data = widgets[widget];
|
|
if (widget_data.deviceOnly && data.deviceMenu === false) {
|
|
continue;
|
|
}
|
|
|
|
var handler;
|
|
var href;
|
|
handler = JX.bind(null, function(widget, e) {
|
|
toggleWidget({widget: widget});
|
|
e.prevent();
|
|
menu.close();
|
|
}, widget);
|
|
var item = new JX.PHUIXActionView()
|
|
.setIcon(widget_data.icon || 'none')
|
|
.setName(widget_data.name)
|
|
.setHref(href)
|
|
.setHandler(handler);
|
|
map[widget_data.name] = item;
|
|
list.addItem(item);
|
|
}
|
|
|
|
menu
|
|
.setWidth(200)
|
|
.setContent(list.getNode());
|
|
|
|
menu.listen('open', function() {
|
|
for (var k in map) {
|
|
map[k].setDisabled((k == _selectedWidgetName));
|
|
}
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Since this is not always on the page, avoid having a repeat
|
|
* try / catch block and consolidate into this helper function.
|
|
*/
|
|
var _getDeviceWidgetHeader = function () {
|
|
var root = JX.DOM.find(document, 'div', 'conpherence-layout');
|
|
var device_header = null;
|
|
try {
|
|
device_header = JX.DOM.find(
|
|
root,
|
|
'a',
|
|
'device-widgets-selector');
|
|
} catch (ex) {
|
|
// is okay - no deviceWidgetHeader yet... but bail time
|
|
}
|
|
return device_header;
|
|
};
|
|
|
|
/**
|
|
* Responder to the 'conpherence-did-redraw-thread' event, this bad boy
|
|
* hides or shows the device widget selector as appropros.
|
|
*/
|
|
var _didRedrawThread = function (data) {
|
|
if (_loadedWidgetsID === null || _loadedWidgetsID != data.threadID) {
|
|
return;
|
|
}
|
|
var device = JX.Device.getDevice();
|
|
var device_selector = _getDeviceWidgetHeader();
|
|
if (device == 'desktop') {
|
|
JX.DOM.hide(device_selector);
|
|
} else {
|
|
JX.DOM.show(device_selector);
|
|
}
|
|
if (data.buildDeviceWidgetSelector) {
|
|
buildDeviceWidgetSelector(data);
|
|
}
|
|
toggleWidget(data);
|
|
};
|
|
JX.Stratcom.listen(
|
|
'conpherence-did-redraw-thread',
|
|
null,
|
|
function (e) {
|
|
_didRedrawThread(e.getData());
|
|
}
|
|
);
|
|
|
|
/**
|
|
* Toggling a widget involves showing / hiding the appropriate widget
|
|
* bodies as well as updating the selectors to have the label on the
|
|
* newly selected widget.
|
|
*/
|
|
var toggleWidget = function (data) {
|
|
var widgets = config.widgetRegistry;
|
|
var widget_data = widgets[data.widget];
|
|
var device = JX.Device.getDevice();
|
|
var is_desktop = device == 'desktop';
|
|
|
|
if (widget_data.deviceOnly && is_desktop) {
|
|
return;
|
|
}
|
|
_selectedWidgetName = widget_data.name;
|
|
|
|
var device_header = _getDeviceWidgetHeader();
|
|
if (device_header) {
|
|
// this is fragile but adding a sigil to this element is awkward
|
|
var device_header_spans = JX.DOM.scry(device_header, 'span');
|
|
var device_header_span = device_header_spans[1];
|
|
JX.DOM.setContent(
|
|
device_header_span,
|
|
widget_data.name);
|
|
}
|
|
|
|
// don't update the non-device selector with device only widget stuff
|
|
if (!widget_data.deviceOnly) {
|
|
var root = JX.DOM.find(document, 'div', 'conpherence-layout');
|
|
var widget_pane = JX.DOM.find(root, 'div', 'conpherence-widget-pane');
|
|
var widget_header = JX.DOM.find(widget_pane, 'a', 'widgets-selector');
|
|
var adder = JX.DOM.find(widget_pane, 'a', 'conpherence-widget-adder');
|
|
var threadManager = JX.ConpherenceThreadManager.getInstance();
|
|
var disabled = !threadManager.getCanEditLoadedThread();
|
|
JX.DOM.setContent(
|
|
widget_header,
|
|
widget_data.name);
|
|
JX.DOM.appendContent(
|
|
widget_header,
|
|
JX.$N('span', { className : 'caret' }));
|
|
if (widget_data.hasCreate) {
|
|
JX.DOM.show(adder);
|
|
JX.DOM.alterClass(
|
|
adder,
|
|
'disabled',
|
|
disabled);
|
|
} else {
|
|
JX.DOM.hide(adder);
|
|
}
|
|
}
|
|
|
|
for (var widget in config.widgetRegistry) {
|
|
widget_data = widgets[widget];
|
|
if (widget_data.deviceOnly && is_desktop) {
|
|
// some one off code for conpherence messages which are device-only
|
|
// as a widget, but shown always on the desktop
|
|
if (widget == 'conpherence-message-pane') {
|
|
JX.$(widget).style.display = 'block';
|
|
}
|
|
continue;
|
|
}
|
|
if (widget == data.widget) {
|
|
JX.$(widget).style.display = 'block';
|
|
// some one off code for conpherence messages - fancier refresh tech
|
|
if (widget == 'conpherence-message-pane') {
|
|
JX.Stratcom.invoke('conpherence-redraw-thread', null, {});
|
|
JX.Stratcom.invoke('conpherence-update-page-data', null, {});
|
|
}
|
|
} else {
|
|
JX.$(widget).style.display = 'none';
|
|
}
|
|
}
|
|
};
|
|
|
|
JX.Stratcom.listen(
|
|
'conpherence-update-widgets',
|
|
null,
|
|
function (e) {
|
|
var data = e.getData();
|
|
if (data.buildSelectors) {
|
|
buildDesktopWidgetSelector(data);
|
|
buildDeviceWidgetSelector(data);
|
|
}
|
|
if (data.toggleWidget) {
|
|
toggleWidget(data);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Generified adding new stuff to widgets technology!
|
|
*/
|
|
JX.Stratcom.listen(
|
|
['click'],
|
|
'conpherence-widget-adder',
|
|
function (e) {
|
|
e.kill();
|
|
|
|
var widgets = config.widgetRegistry;
|
|
// the widget key might be in node data, but otherwise use the
|
|
// selected widget
|
|
var event_data = e.getNodeData('conpherence-widget-adder');
|
|
var widget_key = _selectedWidgetName;
|
|
if (event_data.widget) {
|
|
widget_key = widgets[event_data.widget].name;
|
|
}
|
|
|
|
var widget_to_update = null;
|
|
var create_data = null;
|
|
for (var widget in widgets) {
|
|
if (widgets[widget].name == widget_key) {
|
|
create_data = widgets[widget].createData;
|
|
widget_to_update = widget;
|
|
break;
|
|
}
|
|
}
|
|
// this should be impossible, but hey
|
|
if (!widget_to_update) {
|
|
return;
|
|
}
|
|
var href = config.widgetBaseUpdateURI + _loadedWidgetsID + '/';
|
|
if (create_data.customHref) {
|
|
href = create_data.customHref;
|
|
}
|
|
|
|
var threadManager = JX.ConpherenceThreadManager.getInstance();
|
|
var latest_transaction_id = threadManager.getLatestTransactionID();
|
|
var data = {
|
|
latest_transaction_id : latest_transaction_id,
|
|
action : create_data.action
|
|
};
|
|
|
|
var workflow = new JX.Workflow(href, data)
|
|
.setHandler(function (r) {
|
|
var threadManager = JX.ConpherenceThreadManager.getInstance();
|
|
threadManager.setLatestTransactionID(r.latest_transaction_id);
|
|
var root = JX.DOM.find(document, 'div', 'conpherence-layout');
|
|
if (create_data.refreshFromResponse) {
|
|
var messages = null;
|
|
try {
|
|
messages = JX.DOM.find(root, 'div', 'conpherence-messages');
|
|
} catch (ex) {
|
|
}
|
|
if (messages) {
|
|
JX.DOM.appendContent(messages, JX.$H(r.transactions));
|
|
JX.Stratcom.invoke('conpherence-redraw-thread', null, {});
|
|
}
|
|
|
|
if (r.people_widget) {
|
|
try {
|
|
var people_root = JX.DOM.find(root, 'div', 'widgets-people');
|
|
// update the people widget
|
|
JX.DOM.setContent(
|
|
people_root,
|
|
JX.$H(r.people_widget));
|
|
} catch (ex) {
|
|
}
|
|
}
|
|
|
|
// otherwise let's redraw the widget somewhat lazily
|
|
} else {
|
|
JX.Stratcom.invoke(
|
|
'conpherence-reload-widget',
|
|
null,
|
|
{
|
|
threadID : _loadedWidgetsID,
|
|
widget : widget_to_update
|
|
});
|
|
}
|
|
});
|
|
|
|
threadManager.syncWorkflow(workflow, 'submit');
|
|
}
|
|
);
|
|
|
|
JX.Stratcom.listen(
|
|
['touchstart', 'mousedown'],
|
|
'remove-person',
|
|
function (e) {
|
|
var href = config.widgetBaseUpdateURI + _loadedWidgetsID + '/';
|
|
var data = e.getNodeData('remove-person');
|
|
|
|
// While the user is removing themselves, disable the notification
|
|
// update behavior. If we don't do this, the user can get an error
|
|
// when they remove themselves about permissions as the notification
|
|
// code tries to load what jist happened.
|
|
var threadManager = JX.ConpherenceThreadManager.getInstance();
|
|
var loadedPhid = threadManager.getLoadedThreadPHID();
|
|
threadManager.setLoadedThreadPHID(null);
|
|
|
|
new JX.Workflow(href, data)
|
|
.setCloseHandler(function() {
|
|
threadManager.setLoadedThreadPHID(loadedPhid);
|
|
})
|
|
// we re-direct to conpherence home so the thread manager will
|
|
// fix itself there
|
|
.setHandler(function(r) {
|
|
JX.$U(r.href).go();
|
|
})
|
|
.start();
|
|
}
|
|
);
|
|
|
|
/* settings widget */
|
|
var onsubmitSettings = function (e) {
|
|
e.kill();
|
|
var form = e.getNode('tag:form');
|
|
var button = JX.DOM.find(form, 'button');
|
|
JX.Workflow.newFromForm(form)
|
|
.setHandler(JX.bind(this, function (r) {
|
|
new JX.Notification()
|
|
.setDuration(6000)
|
|
.setContent(r)
|
|
.show();
|
|
button.disabled = '';
|
|
JX.DOM.alterClass(button, 'disabled', false);
|
|
}))
|
|
.start();
|
|
};
|
|
|
|
JX.Stratcom.listen(
|
|
['submit', 'didSyntheticSubmit'],
|
|
'notifications-update',
|
|
onsubmitSettings
|
|
);
|
|
|
|
});
|