How to get source and target of edge after any change on cell connect? - graph

I'm programming a web application that use workflow. I used jgraph(Mxgraph) for designing workflow.
I will save workflow parts in database (activities, notifications, transitions).
I need to get source and target of transitions. So how should I catch any changes on transitions in client?
I used before from these three events but don't work always. For example when I change connection target.
Editor.graph.connectionHandler.addListener(mxEvent.CONNECT, function (sender, evt) {
console.log('connect');
});
Editor.graph.connectionHandler.addListener(mxEvent.START, function (sender, evt) {
console.log('start');
});
Editor.graph.connectionHandler.addListener(mxEvent.RESET, function (sender, evt) {
console.log('reset');
});

I found it.
We can use mxEvent.Change event for getting any change on graph model.
editor.graph.getModel().addListener(mxEvent.CHANGE, function (sender, evt) {
editor.graph.validateGraph();
var xml = getEditorXml(Editor);
$("#BpmnXml").val(xml);
//console.log(getCells_ByType("Start"));
// /console.log(getCells_ByType("Task"));
let connectors = getCells_ByType("Connector");
if (connectors != null && connectors.length > 0) {
connectors.forEach(element => {
var source = Editor.graph.getModel().getTerminal(element, true);
var target = Editor.graph.getModel().getTerminal(element, false);
setData(element, { FromActivityClientId: source.getId(), ToActivityClientId: target.getId() });
});
}
});
function getCells_ByType(TypeCell) { // dar report estafede mishavad
var AllCells = Editor.graph.getChildCells(Editor.graph.getDefaultParent(), true, true);
var result = $.grep(AllCells, function (s) { return s.getValue().localName == TypeCell; });
if (result.length != 0)
return result;
else
return null;
}

Related

SignalR - sending push notification to a specific user

I'm working on a PoC for a notification engine. I'm able to successfully connect and call Hub functions from JS, but I can't seem to get push notifications to work. I'm getting an Object reference not set to an instance of an object error.
Triggering class
// I was able to confirm that the connectionIds are valid
public void HandleEvent(NewNotificationEvent eventMessage)
{
// _connections handles connectionids of a user
// multiple connection ids to handle multiple open tabs
var connectionIds = _connections.GetConnectionsByUser(eventMessage.Notification.UserId);
foreach(var connectionId in connectionIds)
{
// a client is returned, but aside from the connectionid, all the properties are either null or empty
var client = _notificationHub.Clients.Client(connectionId);
///// ERROR HAPPENS HERE
///// I'm guessing NewNotification() isn't defined somewhere, but I don't know where.
client.NewNotification("Hello");
}
}
View.cshtml
var notificationHub = $.connection.NotificationHub;
$.connection.hub.qs="userId=#userId"
// Initialization
$.connection.hub.start().done(function () {
// get count unread notification count
notificationHub.invoke("unReadNotificationsCount")
.done((unreadCount) => {
if (unreadCount > 0) {
$('#notificationBadge').html(unreadCount);
hasNewNotification = true;
}
console.log('SignalR connected!');
})
.fail((data) => {
console.log('Unable to reach server');
console.log(data);
})
.always(() => $('#dropdownNotificationOptions').show());
});
// also tried notificationHub.NewNotification()
notificationHub.client.NewNotification = function (notification) {
console.log(notification);
}
NotificationHub.cs
[HubName("NotificationHub")]
public class NotificationHub : Hub
{
//ctor
public override Task OnConnected()
{
var userId = Context.QueryString["userid"];
if(userId.IsNotNullOrEmpty())
_connections.Add(Context.ConnectionId, Guid.Parse(userId));
else
_connections.Add(Context.ConnectionId, Guid.NewGuid());
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled = true)
{
_connections.Remove(Context.ConnectionId);
return base.OnDisconnected(stopCalled);
}
public override Task OnReconnected()
{
Guid userId;
if (Guid.TryParse(Context.QueryString["userid"],out userId))
{
//var userId = _workContext.CurrentUser.Id;
var userConnection = _connections.GetUserByConnection(Context.ConnectionId);
if (userConnection == null || userConnection.IsNotNullOrEmpty())
{
_connections.Add(Context.ConnectionId, userId);
}
}
return base.OnReconnected();
}
}
You should have your NewNotification before the $.connection.hub.start() such as:
var notificationHub = $.connection.NotificationHub;
$.connection.hub.qs="userId=#userId"
// Moved to define before the connection start
notificationHub.client.NewNotification = function (notification) {
console.log(notification);
}
// Initialization
$.connection.hub.start().done(function () {
// get count unread notification count
notificationHub.invoke("unReadNotificationsCount")
.done((unreadCount) => {
if (unreadCount > 0) {
$('#notificationBadge').html(unreadCount);
hasNewNotification = true;
}
console.log('SignalR connected!');
})
.fail((data) => {
console.log('Unable to reach server');
console.log(data);
})
.always(() => $('#dropdownNotificationOptions').show());
});

Switch camera on webview video call

I have app in xamarin form where i am accessing webview for video call. Everything is working fine just i need to know how i can switch back/front camera during call? as when video call start front camera open by default.
Code for initializing video call
function initializeLocalMedia(options, callback) {
if(options) {
options['audio'] = true;
if(options['video'])
options['video'] = true;
} else {
options['audio'] = true;
options['video'] = false;
}
// Get audio/video stream
navigator.getUserMedia(options, function(stream) {
// Set your video displays
window.localStream = stream;
myapp.setMyVideo(window.localStream)
if(callback)
callback();
}, function(err) {
console.log("The following error occurred: " + err.name);
alert('Unable to call ' + err.name)
});
}
Going straight to code then it should look like:
Camera.CameraInfo camInfo = new Camera.CameraInfo ();
for (int i = 0; i < Camera.NumberOfCameras; i++) {
Camera.GetCameraInfo (i, camInfo);
if (camInfo.Facing == CameraFacing.Front){
try {
return Camera.Open(i);
} catch (Exception e) {
// log or something
}
}
}
return null;
What we are doing is iterating over the hardware and then check to match the front camera, if it match then do the things. Same is true for back camera too

How to pass a value from getInputData() to map() function in map reduce suitescript?

I have made a suitelet that is running a map-reduce script and passing a parameter which is a date. Now what is required is to include that date object (coming from suitelet) in the map() function. So that the record that will be created in map() can have that date as trandate.
define(['N/record', 'N/search', 'N/runtime'], function (record, search, runtime) {
function getInputData() {
try {
var slfilter = runtime.getCurrentScript().getParameter({ name: 'custscript_searchfilter_date' });
slfilter.replace(/\\/g, "");
var dateSL = JSON.parse(slfilter);
log.debug('dateSL parsed', dateSL)
var date = dateSL['date'];
log.debug('date', date);
var savedSearch = search.load({ id: 'customsearch_wip_correction' });
var results = getResults(savedSearch.run())
log.debug('results:', results)
return results;
}
catch (e) {
log.error("GetInputData ", e);
}
}
function map(context) {
try {
// date is required here
var data = JSON.parse(context.value);
log.debug('map:' + context.key, context.value)
var amount = data.values['SUM(amount)'];
log.debug('amount', amount)
var location = data.values['GROUP(location)'][0].value;
log.debug('location', location)
}
catch (e) {
log.error("map", e)
}
}
Put runtime.getCurrentScript().getParameter in map section.
N/runtime can work in any endpoint either Client Script or User Events.

SignalR and .NET

I'm basically trying to dynamically create a list element and update it across multiple clients. I'm using SignalR library of .NET. Following is my code.
$(function () {
// Reference the auto-generated proxy for the hub.
var listSync = $.connection.myHub1;
console.log("List Sync ");
// Create a function that the hub can call back to display messages and toggle.
listSync.client.addNewItemToPage = function (name, url) {
console.log("List Sync 3");
var play_list = document.getElementById('playlist');
var empty = document.getElementById('empty');
if (empty != null) {
empty.remove();
}
var pli = document.createElement("li");
var ptag = document.createElement('a');
var icon = document.createElement('i');
icon.setAttribute('class', "fa fa-toggle-right");
ptag.setAttribute('href', "#");
ptag.setAttribute('class', "play_track");
ptag.appendChild(icon);
ptag.innerHTML += name;
ptag.type = url;
pli.appendChild(ptag);
play_list.appendChild(pli);
//handler to play songs by playlist
var favLinks = document.getElementsByClassName('play_track');
for (var j = 0; j < favLinks.length; j++) {
var favLink = favLinks[j];
favLink.onclick = function (e) {
e.preventDefault();
xurl = this.type;
myFunc();
}
}
};
// Start the connection.
$.connection.hub.start().done(function () {
window.listFunc = function listFunc(name, url) {
console.log("List Sync 1");
// Call the Send method on the hub.
listSync.server.update_playlist(name, url);
console.log("List Sync 2");
}
});
});
The problem is it doesn't go into the function listSync.client.addNewItemToPage. Can someone please tell me why?

Older asynchronous messages overwriting newer ones

We are developing a document collaboration tool in SignalR where multiple users can update one single WYSIWYG form.
We are struggling getting the app to work using the KeyUp method to send the changes back to the server. This causes the system to overwrite what the user wrote after his first key stroke when it sends the message back.
Is there anyway to work around this problem?
For the moment I tried to set up a 2 seconds timeout but this delays all updates not only the "writer" page.
public class ChatHub : Hub
{
public ChatHub()
{
}
public void Send(int id,string message)
{
// Call the broadcastMessage method to update clients.
Clients.All.broadcastMessage(id,message); //id is for the document id where to update the content
}
}
and the client:
$(function () {
// Declare a proxy to reference the hub.
var chat = $.connection.chatHub;
//console.log("Declare a proxy to reference the hub.");
// Create a function that the hub can call to broadcast messages.
chat.client.broadcastMessage = function (id, message) {
var encodedValue = $('<div />').text(id).html();
// Add the message to the page.
if (encodedValue == $('#hdnDocId').val()) {
$('#DiaplayMsg').text(message);
tinyMCE.activeEditor.setContent("");
tinyMCE.get('txtContent').execCommand('insertHTML', false, message); //!!!
}
};
// Start the connection.
$.connection.hub.start().done(function (e) {
//console.log("Start the connection.");
if ($('#hdnDocId').val() != '') {
tinyMCE.activeEditor.onKeyUp.add(function (ed, e) {
var elelist = $(tinyMCE.activeEditor.getBody()).text();
var content = tinyMCE.get('txtContent').getContent();
function Chat() {
var content = tinyMCE.get('txtContent').getContent();
chat.server.send($('#hdnDocId').val(), content); //send a push to server
}
typewatch(Chat, 2000);
});
}
});
});
var typewatch = function () {
var timer = 0;
return function (Chat, ms) {
clearTimeout(timer);
timer = setTimeout(Chat, ms);
}
} ();
</script>
Hello, here is an update of the client KeyUp code. It seems to be working but I would like your opinion. I've used a global variable to store the timeout, see below:
<script type="text/javascript">
$(function () {
// Declare a proxy to reference the hub.
var chat = $.connection.chatHub;
//console.log("Declare a proxy to reference the hub.");
// Create a function that the hub can call to broadcast messages.
chat.client.broadcastMessage = function (id, message) {
var encodedValue = $('<div />').text(id).html();
var currenttime = new Date().getTime() / 1000 - 2
if (typeof window.istyping == 'undefined') {
window.istyping = 0;
}
if (encodedValue == $('#hdnDocId').val() && window.istyping == 0 && window.istyping < currenttime) {
function Update() {
$('#DiaplayMsg').text(message);
tinyMCE.activeEditor.setContent("");
tinyMCE.get('txtContent').execCommand('insertHTML', false, message); //!!!
// tinyMCE.get('txtContent').setContent(message);
window.istyping = 0
}
Update();
}
};
// Start the connection.
$.connection.hub.start().done(function (e) {
//console.log("Start the connection.");
if ($('#hdnDocId').val() != '') {
tinyMCE.activeEditor.onKeyUp.add(function (ed, e) {
var elelist = $(tinyMCE.activeEditor.getBody()).text();
var content = tinyMCE.get('txtContent').getContent();
function Chat() {
//alert("Call");
var content = tinyMCE.get('txtContent').getContent();
chat.server.send($('#hdnDocId').val(), content);
window.istyping = new Date().getTime() / 1000;
}
Chat();
});
}
});
});
var typewatch = function () {
var timer = 0;
return function (Chat, ms) {
clearTimeout(timer);
timer = setTimeout(Chat, ms);
}
} ();
Thanks,
Roberto.
Is there anyway to work around this problem?
Yes, by not sending the entire document to the server, but document elements like paragraphs, table cells, and so on. You can synchronize these after the user has stopped typing for a period, or when focus is lost for example.
Otherwise add some incrementing counter to the messages, so older return values don't overwrite newer ones arriving earlier.
But you're basically asking us to solve a non-trivial problem regarding collaborated document editing. What have you tried?
"This causes the system to overwrite what the user wrote"
that's because this code isn't making any effort to merge changes. it is just blindly overwriting whatever is there.
tinyMCE.activeEditor.setContent("");
tinyMCE.get('txtContent').execCommand('insertHTML', false, message);
as #CodeCaster hinted, you need to be more precise in the messages you send - pass specific changes back and forth rather re-sending the entire document - so that changes can be carefully merged on the receiving side

Resources