emberjs + gojs integration - ember.js

Hey guys I am trying out emberjs and want to integrate goJS to it. I did an npm install of the package https://www.npmjs.com/package/gojs
But I can't find any good documentation on this.. so if anyone can point out my error that will be great
import Component from "#glimmer/component";
import go from "gojs";
import { action } from "#ember/object";
import { tracked } from "#glimmer/tracking";
export default class GraphComponent extends Component {
#tracked iconName = "check-circle";
$ = go.GraphObject.make;
myDiagram = $(go.Diagram, "myDiagramDiv");
#action
changeIcon() {
if (this.iconName == "check-circle") {
this.iconName = "sync-alt";
} else {
this.iconName = "check-circle";
}
}
}
This is my ember component graph.js and In graph.hbs I have the corresponding div but some how nothing shows up on the screen. am I missing something ?
And would also appreciate any links to a goJS with emberJS docs.TY

I would recommend to utilize the didInsert render modifier.
With this you can do
<div id="myDiagramDiv" {{did-insert this.insertDiagram}}></div>
and then you can have an action that will run after the div was inserted to the DOM:
#action
insertDiagram() {
const $ = go.GraphObject.make;
const myDiagram = $(go.Diagram, "myDiagramDiv");
}
otherwise you will run this code before the <div> is avaliable.

Related

Unknown field `edges` on type `Query`

I am getting the error from the title when I attempt to run relay-compiler in my project. I am using graphql-python/graphene-django for the back end graphql server. Here's an abbreviated copy of my schema.
grove.gql_schema.py:
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField
from .models import Tree
class TreeNode(DjangoObjectType):
class Meta:
model = Tree
filter_fields = ['owner']
interfaces = (relay.Node,)
class Query(ObjectType):
def resolve_my_trees(self, info):
if not info.context.user.is_authenticated:
return Tree.objects.none()
else:
return Tree.objects.filter(owner=info.context.user)
my_trees = DjangoFilterConnectionField(TreeNode)
tree = relay.Node.Field(TreeNode)
project.gql_schema:
class Query(grove.gql_schema.Query, graphene.ObjectType):
pass
schema = graphene.Schema(query=Query)
With that setup, I can successfully run the following query in GraphiQL
query {
myTrees {
edges {
node {
id
}
}
}
}
So far so good, but now I'm trying to build a client-side component that can use this query.
jsapp/components/index.jsx:
import React from 'react';
import {graphql, QueryRenderer} from 'react-relay';
import environment from '../relay_env'
const myTreesQuery = graphql`
query componentsMyTreesQuery {
edges {
node {
id
}
}
}
`;
export default class App extends React.Component {
render() {
return (
<QueryRenderer
environment={environment}
query={myTreesQuery}
variables={{}}
render={({error, props}) => {
if (error) {
return <div>Error!</div>;
}
if (!props) {
return <div>Loading...</div>;
}
return <div>User ID: {props.edges}</div>;
}}
/>
);
}
}
The query is identical, but when I run relay-compiler --src ./jsapp --schema ./schema.graphql --extensions js jsx I get the error:
GraphQLParser: Unknown field `edges` on type `Query`.
Source: document `componentsMyTreesQuery` file: `components/index.jsx`.
I get this error if when I use the .json schema generated by the Django graphaql_schema management command or the .graphql one retrieved by get-graphql-schema.
What part am I missing?
I might be a bit late but it looks to me like you're trying to ask for the edges on the root of your schema, the fragment:
const myTreesQuery = graphql`
query componentsMyTreesQuery {
edges {
node {
id
}
}
}
`;
I think could be altered to:
const myTreesQuery = graphql`
query componentsMyTreesQuery {
myTrees {
edges {
node {
id
}
}
}
}
`;
The text after the keyword query refers to the name of the 'query', not the root of the schema. If you're using Relay Modern (which by the use of QueryRenderer, I assume you are) then the compiler should yell at you to fix the name of your fragment to something that reflects the filename that it's stored in.

ionic2 - Google maps not working in Browser

Its code below that I use to show map in my page.
ts file
import {
GoogleMaps,
GoogleMap,
GoogleMapsEvent,
LatLng,
CameraPosition,
MarkerOptions,
Marker
} from '#ionic-native/google-maps';
export class MapPage {
constructor(private googleMaps: GoogleMaps){}
ngAfterViewInit() {
this.loadMap();
}
loadMap() {
let element: HTMLElement = document.getElementById('map');
let map: GoogleMap = this.googleMaps.create(element);
map.one(GoogleMapsEvent.MAP_READY).then(() => {
console.log('Map is ready!');
});
}
}
Html code block
<div #map id="map" style="height:100%;"></div>
Since you're using Google Maps from Ionic Native, it won't work on the browser. Ionic Native/Cordova plugins work only in a simulator / real device only

React/Jasmine/Karma/Phantom Unit Test: findDOMNode and renderIntoDocument not working as expected

I'm trying to write a simple unit test and can't seem to figure it out. I want to test a bootstrap modal to ensure it displays the correct contents when I pass certain object properties to it. Here's what my modal code looks like:
import React, { Component, PropTypes } from 'react';
import { Button, Modal } from 'react-bootstrap';
class ModalBox extends Component {
render() {
const { modalBox } = this.props;
let content;
if (modalBox.contentBody) {
content = modalBox.contentBody;
} else {
content = (
<span>
<Modal.Header closeButton onHide={this.close.bind(this)}>
<Modal.Title>{modalBox.title}</Modal.Title>
</Modal.Header>
<Modal.Body>
{modalBox.message}
</Modal.Body>
{modalBox.isConfirm &&
<Modal.Footer>
<Button onClick={modalBox.onCancel} className="modal-button cancel">{modalBox.cancelText || 'Cancel'}</Button>
<Button onClick={modalBox.onConfirm} className="modal-button confirm">{modalBox.confirmText || 'Confirm'}</Button>
</Modal.Footer>
}
</span>
);
}
return (
<Modal show={typeof modalBox != 'undefined'} onHide={this.close.bind(this)} dialogClassName={modalBox.dialogClassName || ''} backdrop={modalBox.backdrop || true}>
{content}
</Modal>
);
}
}
So for a test, I want to make sure that if I pass the prop modalBox containing the contentBody field that it just returns the contentBody for the modal body. Here's an example of what I'm trying to test:
it("renders only contentBody when provided", () => {
let modalBoxObj = {
contentBody: <div className="test-content-body">This is a test.</div>
};
let element = React.createElement(ModalBox, {modalBox: modalBoxObj});
let component = TestUtils.renderIntoDocument(element);
let modalWrapper = TestUtils.scryRenderedDOMComponentsWithClass(component, 'modal');
// modalWrapper returns an empty array, so this returns "Expected 0 to be 1"
expect(modalWrapper.length).toBe(1);
let testBody = TestUtils.scryRenderedDOMComponentsWithClass(component, 'test-content-body');
// testBody returns an empty array, so this returns "Expected 0 to be 1"
expect(testBody.length).toBe(1);
// this returns "TypeError: 'undefined' is not an object (evaluating 'testBody[0].innerHTML')"
expect(testBody[0].innerHTML).toEqual("This is a test.");
}
I've also tried doing shallow rendering with TestUtils.createRenderer and trying that approach, but had no luck with it. Based on the examples I've seen online and previous testing experience with react <0.14, I feel this test should work. I just don't know what I'm missing or misunderstanding. In the past, I did something like below and just looked at the componentNode object to find elements and such, but componentNode is returning null.
let component = TestUtils.renderIntoDocument(element);
let componentNode = findDOMNode(component);
Thanks for your help!
The solution ended up being to add a ref to the ModalBox component. Once added, we were able to target the node like this:
let component = TestUtils.renderIntoDocument(<ModalBox modalBox={modalBoxObj} />);
let componentNode = findDOMNode(component.refs.modalBox._modal);

Feincms MediaFile in RichTextContent

Is there a standard solution to insert a feincms MediaFile into a RichTextContent form element (ckeditor or tinyMCE) ? I haven't been able to find any in the documentation... Now users need to copy paste an url in the medialib then move over to page and paste...
You'll have to create your own implementation for this. Overwriting dismissRelatedLookupPopup is a bit hackish, but Django seems to lack support for a better solution.
UPDATE: This ticket describes the popup issue.
In your static folder where 'ckeditor' lives, create a plugin, e.g.
/app/
/static/
/app/
/js/
/ckeditor/
/plugins/
/feincms/
/images/
mediaFile.png
plugin.js
plugin.js
/**
* Basic sample plugin inserting a feincms mediaFile into the CKEditor editing area.
*/
// Register the plugin with the editor.
// http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.plugins.html
CKEDITOR.plugins.add( 'feincms',
{
// The plugin initialization logic goes inside this method.
// http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.pluginDefinition.html#init
init: function(editor)
{
// Define an editor command that inserts a feincms.
// http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.editor.html#addCommand
editor.addCommand( 'insertMediaFile',
{
// Define a function that will be fired when the command is executed.
// http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.commandDefinition.html#exec
exec : function(editor)
{
// Define your callback function
function insertMediaFile(imageUrl) {
// Insert the imageUrl into the document. Style represents some standard props.
// http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.editor.html#insertHtml
editor.insertHtml('<img src="/media/' + imageUrl + '" style="float:left;margin-right:10px;margin-bottom:10px;width:200px;" />');
}
var imageUrl;
window.dismissRelatedLookupPopup = function (win, chosenId) {
imageUrl = $(win.document.body).find('#_refkey_' + chosenId).val();
insertMediaFile(imageUrl);
var name = windowname_to_id(win.name);
var elem = document.getElementById(name);
if (elem) {
if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
elem.value += ',' + chosenId;
} else {
document.getElementById(name).value = chosenId;
}
}
win.close();
};
var win = window.open('/admin/medialibrary/mediafile/?pop=1', 'id_image', 'height=500,width=800,resizable=yes,scrollbars=yes');
win.focus();
}
});
// Create a toolbar button that executes the plugin command.
// http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.ui.html#addButton
editor.ui.addButton( 'feincms',
{
// Toolbar button tooltip.
label: 'Insert MediaFile',
// Reference to the plugin command name.
command: 'insertMediaFile',
// Button's icon file path.
icon: this.path + 'images/mediaFile.png'
} );
}
} );
Make sure to add the plugin to the ckeditor init script, e.g.
{ name: 'insert', items : [ 'feincms','HorizontalRule','SpecialChar' ] },
Not that I know of. If you always (or sometimes) need a MediaFile associated with a RichTextContent, write your own content type:
from feincms.module.medialibrary.fields import MediaFileForeignKey
from feincms.content.richtext.models import RichTextContent
class RichTextAndMFContent(RichTextContent):
mf = MediaFileForeignKey(MediaFile)
class Meta:
abstract = True
def render(self, **kwargs):
...

play framework-1.x pagination start at a specific position

I have a question on pagination module in Play Framework ( ver 1.x),
i have setup pagination to only show one object per page, and some other customized settings,
in the controller:
import java.util.ArrayList;
import java.util.List;
import play.modules.paginate.ValuePaginator;
import play.mvc.Controller;
public class Application extends Controller {
public static void index() {
List<String> strings = new ArrayList<String>();
strings.add("Kalle");
strings.add("Karin");
strings.add("Dixie");
strings.add("Edvin");
strings.add("Gustav");
strings.add("Axel");
int pos = 0;
for(String str : strings){
if(str.equals("Axel")){
pos += strings.indexOf(str);
break;
}
}
ValuePaginator namePaginator = new ValuePaginator(strings);
namePaginator.setPageSize(1);
namePaginator.setBoundaryControlsEnabled(false);
namePaginator.setPagesDisplayed(0);
renderArgs.put("pos", pos);
renderArgs.put("namePaginator", namePaginator);
render();
}
And in the template:
#{extends 'main.html' /}
#{set title:'Home' /}
*{#{welcome /}}*
${pos}
#{paginate.controls items:namePaginator /}
#{paginate.list items:namePaginator, as:'name'}
${name}
#{/paginate.list}
*{#{list items:strings[pos], as:'string'}
${string}
#{/list}}*
Now, as you might see in the last part of the template, there is a commented part, using the usual groovy list tag, and since it has an actual list i can force the list to start at a given position "pos", this is however not possible in the case of using the pagination.
In the case of the "items:namePaginator" it is merely a name placeholder for the underlying list and not really iterable, is there possibly a way of making the pagination start at a specified position within the wrapped list?
Thanks a lot !
I managed to solve the problem using JQuery instead of using Play Frameworks pagination module for this special case of pagination.
Principle goes like this, in the controllers action a normal Java ArrayList consisting of objects to my liking, this ArrayList is then converted to a jsonObject using the included Gson library (in Play Framework).
Gson gson = new Gson();
String jsonObj = gson.toJson(objects);
By using
renderArgs.put("jsonObj", jsonObj);
in the controller action to pass the json to the template, by the way my reason for doing all this in the first place was to be able to start "paginating" thru the objects clientside from any position in the list of objects, and to a hidden div in the template.
Next on i use JQuery to pick up the list,
$.parseJSON($('#myhiddenlist'));
And then again using JQuery to step back and forth (catching click events on anchor tags for prev and next) thru the list, and displaying the respective object per page.
Another upside of using JQuery (or javascript for that matter), is that i don't have to worry about page reload, as is the case with Play Frameworks pagination module.
JQuery-part
$(function(){
var ourlist = $('#ourlist').text();
var jsonOur = $.parseJSON(ourlist);
var length = jsonOur.length;
var pos = parseInt($('#ourpos').text());
var showList = $('#showlist');
showList.append(jsonOur[pos].name);
initControls();
function hasPrev(){
if(pos > 0){
return true;
}else{
return false;
}
}
function hasNext(){
if(pos < (length - 1)){
return true;
}else{
return false;
}
}
function showItem(pos){
showList.empty();
showList.append(jsonOur[pos].name);
}
$('.previous a').click(function(e){
if(hasPrev()){pos--;}
if(hasPrev()){
$('li.next').removeClass('off');
$('li.next a').css('color', 'blue');
}else{
$('li.previous').addClass('off');
$('li.previous.off a').css('color', 'grey');
}
showItem(pos);
});
$('.next a').click(function(e){
if(hasNext()){pos++;}
if(hasNext()){
$('li.previous').removeClass('off');
$('li.previous a').css('color', 'blue');
}else{
$('li.next').addClass('off');
$('li.next.off a').css('color', 'grey');
}
showItem(pos);
});
function initControls(){
if(hasNext()){
$('li.previous').removeClass('off');
}else{
$('li.next').addClass('off');
$('li.next.off a').css('color', 'grey');
}
if(hasPrev()){
$('li.next').removeClass('off');
}else{
$('li.previous').addClass('off');
$('li.previous.off a').css('color', 'grey');
}
}
//for testing only
function showPos(pos){
console.log(pos);
}
});
HTML part
#{extends 'main.html' /}
#{set title:'Home' /}
#{content.rightside Pos: pos /}<!-- loads the side content -->
<div id="ourlist" class="hide">${jsonOurList}</div>
<div id="ourpos" class="hide">${pos}</div>
<ul class="pagination">
<li class="previous">Prev</li>
<li class="next">Next</li>
</ul>
<div id="showlist"></div>
CSS part
ul.pagination li {
display: inline;
}
ul.pagination li a {
outline: none;
text-decoration: none;
}
li.previous.off a,
li.next.off a {
color: grey;
cursor: default;
}
li.previous a,
li.next a {
color: blue;
cursor: pointer;
}
.hide {
display: none;
}
Ok, so this is not really a solution for tweaking the Play module, but a more pragmatic approach, using JQuery.
Hope this might help anyone having a similar problem.
//Kalle