All
I am working on a feature printing app for Rally so we can generate cards for our analog portfolio kanban board. I wanted to build this printer using the 2.0 SDK. I am usign the original Card print code as my starting spot. My Java Script is rusty and i could us some help getting past this hurdle.
Goals of the App.
Get Data from Rally
Render HTML page with date in for of a card
Handle Printing
I am using a store to pull the data from Rally. This is working as expected.
I am having issue passing the store results in to the array to create the HTML cards. The data is making it to the _displayFeatureCard: function. I can see it in the console print out.
Here is what i have so far.
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function () {
console.log("App Launched")
//App Calls the portfolio feature data store
this._getfeaturedatastore();
},
//Get the portfolio feature data from Rally
_getfeaturedatastore: function(){
var getfeaturedata = Ext.create('Rally.data.wsapi.Store', {
model: 'PortfolioItem/Feature',
autoLoad: true,
//Create Fillter for the Store
filters: [
{
property: 'State.Name',
value: 'Story Definition',
}
],
listeners: {
load: function(getfeaturedatastore, getfeaturedatadata, success) {
console.log("Got Feature Data Woot",getfeaturedatastore, getfeaturedatadata, success)
this._displayFeatureCard(getfeaturedata);
},
scope: this
},
fetch: ['State', 'Name', 'Description', 'Owner', 'Parent','PlannedStartDate','FormattedID','Tags']
});
},
_displayFeatureCard: function(getfeaturedata){
var MAX_NAME_LEN = 115;
var name,i,theMarkup,data, description, owner, parent, plannedstartdate, formattedid, data;
data = getfeaturedata;
console.log("Woot made it to the Card", data)
for (i = 0; i < data; i++) {
name = data[i].Name;
owner = data[i].Owner;
parent = data[i].Parent;
description = data[i].Description;
plannedstartdate=data[i].PlannedStartDate;
formattedid=data[i].FormattedID;
theMarkup = this.createMarkup(i, data, name, description, owner, parent, plannedstartdate, formattedid);
dojo.byId("cards").innerHTML += theMarkup;
}
},
Checking your code, your app constructor is using Rally's AppSDK 2.0 (ExtJS based), while your _displayFeatureCard method is referencing dojo, which is legacy AppSDK1 and not recommended for use in AppSDK 2.0.
There is a RallyCommunity app for printing Feature Cards (a slightly modified version of PrintStoryCards). It is available here:
https://github.com/RallyCommunity/feature-print-cards
It is also based on the legacy and deprecated AppSDK1. However it still works, and you may find that it meets your requirements.
Related
I am trying to build a function that allows users to retrieve data from the database, but in a dynamic way. So allowing them to specify the source table, as well as which columns they would like to retrieve.
I have already built out the part that allows them to choose the table and columns, and these users only have access to data we are happy for them to retrieve.
I want this to be as dynamic as possible, so I am building a function to help me with this. I have run into one problem though so far. I have this function:
const modelMap = (model, action, criteria, options) => {
const models = {
EXTERNAL_USER: {
READ: services.externalUser.readExternalUser(criteria, options),
},
TASK: {
READ: services.task.readTask(criteria, options),
},
USER: {
READ: services.user.readUser(criteria, options),
},
}
return models[model][action]
}
So, for example, I call this function using
modelMap('EXTERNAL_USER', 'READ', { id: userID }, { populates: ['documents'] }).
This returns the data I want, however I get an ``OperationError` in my terminal:
OperationalError [UsageError]: Invalid populate(s).
Details:
Could not populate `documents`. There is no attribute named `documents` defined in this model.
The error is saying that the Task model has no attribute documents, which it doesn't. So I am guessing that even though I am not trying to access the readTask function, it is being called anyway. How can I get around this?
SOLUTION
I altered the models object to the following:
const models = {
EXTERNAL_USER: {
READ: () => services.externalUser.readExternalUsers(criteria, options),
},
TASK: {
READ: () => services.task.readTask(criteria, options),
},
USER: {
READ: () => services.user.readUser(criteria, options),
},
}
And I can then use await modelMap(model, action, criteria, options)() to get the data I need.
Yes. The functions called anyway
I try to write a custom HTML block using Rally SDK 2.1 (Javascript) in order to create a new story. I can figure how to create the story with a custom title and description.
If I try to set the feature, then the creation hangs and nothing happens...
Here is how I set the feature ine the script:
var story = Ext.create(model, {
Name: 'Can be deleted, created via Rally app SDK 2.1',
Description: 'Dummy generated story - tests',
PortfolioItem: '/portfolioitem/featureset/12345' // FEATURE
});
If I remove the "PortfolioItem" attribute, then it works like a charm.
Here is my global script:
<!DOCTYPE html>
<html>
<head>
<title>test - Story creation</title>
<script type="text/javascript" src="/apps/2.1/sdk.js"></script>
<script type="text/javascript">
// SDK documentation: https://docs.ca.com/en-us/ca-agile-central/saas/apps/2.1/doc/#!/api
Rally.onReady(function() {
// Create a new story
function addStory() {
console.log('Creating a new story...');
// Retrieve the Rally user stories model
Rally.data.ModelFactory.getModel({
type: 'UserStory',
context: {
workspace: '/workspace/12345', // dummy reference
project: '/project/12345' // dummy reference
},
success: function(model) {
// Create a new story thanks to the retrieved model
var story = Ext.create(model, {
Name: 'Can be deleted, created via Rally app SDK 2.1',
Description: 'Dummy generated story - tests',
PortfolioItem: '/portfolioitem/featureset/12345' // dummy reference
});
// Save the new story
story.save({
callback: function(result, operation) {
if(operation.wasSuccessful()) {
console.log('New story created!', result.get('FormattedID'));
}
}
});
}
});
}
// The Rally application
Ext.define('Rally.grg.storyCreation', {
extend: 'Rally.app.App',
// Method fired on application launch
// Retrieve release features asynchronously
launch: function() {
console.log('Launch...');
addStory();
}
});
Rally.launchApp('Rally.grg.storyCreation', {
name: 'test - Story creation'
});
});
</script>
<style type="text/css">
</style>
</head>
<body></body>
</html>
I tried to declare a new portfolioitem object that would reference the feature I want. Then I reference it at story level, but it behaves exactly the same:
var f;
console.log('Defining the feature...');
// Retrieve the Rally features model
Rally.data.ModelFactory.getModel({
type: 'portfolioitem',
success: function(portfolioitemkModel) {
// Define an existing feature thanks to the retrieved model
f = Ext.create(portfolioitemkModel, {
_ref: "/portfolioitem/featureset/12345",
_refObjectName: "...",
_refObjectUUID: "...",
_type: "PortfolioItem/FeatureSet"
});
}
});
As someone an example of linking a story and its parent feature trought JavaScript SDK2, please?
I would try changing this line:
PortfolioItem: '/portfolioitem/featureset/12345'
to this:
PortfolioItem: '/portfolioitem/feature/12345'
I am trying to build a web application with Buttons to filter Visuals from a Power BI report.
Documentation that I am following, I am able to get the visual onto my application but when I set a filter using Visual.setFilters() method it is throwing me an error saying "Setting visual level filters is not supported.".
Visual in Web Application:
Error from Developer Console:
Code:
` var accessToken = '#ViewBag.AccessToken';
if (!accessToken || accessToken == "") {
return;
}
var basicFilter = {
$schema: "http://powerbi.com/product/schema#basic",
target: {
table: "Products",
column: "Product"
},
operator: "In",
values: ["Sova"],
filterType: 'BasicFilter'
}
// Get models. models contains enums that can be used.
var models = window['powerbi-client'].models;
// Gross Margin Tile
var embedConfiguration = {
type: 'visual',
accessToken: accessToken,
id: 'REPORT_ID',
pageName: 'ReportSection',
visualName:'VisualContainer7',
embedUrl: 'REPORT_EMBEDD_URL',
dashboardId: 'DASHBOARD_ID',
tokenType: models.TokenType.Aad,
filters: []
};
var $tileContainer = $('#grossMarginTile');
var grossMarginTile = powerbi.embed($tileContainer.get(0), embedConfiguration);
grossMarginTile.setFilters([basicFilter])
.catch(errors => {
console.log(errors)
});`
I am new to this, any help will be appreciated, what am I doing wrong?
It looks like you have an older version of the JS SDK, update to the latest and this will be resolved.
I also noticed that you do visual embedding but you have dashboardId in the embedComfiguration, This is unnecessary
A while ago we started with our first web-based single page application. We started with React and Flux (Facebook implementation), but recently switched to Reflux for the Flux implementation. While the Fb Flux implementation knows the concept of 'named' store events, this concept is not available in Reflux. As a result, every component that listens to a store always reacts on all events. Below there is reference image that displays the complexity of our user interface.
As you can see we have a lot of repeating components (multiple tabs with the same sort of info, multiple components with customer details and multiple reapeating lists (even nested) with details.
This application is a new front-end (UI) for an existing .Net application that maintains all te data (opened invoices etc.). The web application can communicate with this back-end by use of web services (MVC web API 2).
Given the user interface as shown in the picture, I would like to know whether I could better go for a store per invoice that holds all the invoice data (with an aggregated store that references them all), or for a store per invoice that holds only the invoice header info and some other stores that hold the information for each of the detail panes.
Thanks in advance for your reactions and suggestions!
edit: I misread your question, seems like you wanted a Reflux answer while I only gave a React answer. I will keep this up anyway for future reference.
The way I would do it is a single store that stores an array of invoices. So I would make my server API output something like this:
[
{
invoice_no: 1,
delivery: {
// delivery details
},
customer: {
// customer details
}
products: [
{
product_no: 1,
product_details: {
...
}
},
{
product_no: 5,
product_details: {
...
}
}
]
},
{
invoice_no: 2,
...
}
]
And then store that in a <App> component's state. My React code would look roughly like this:
var App = React.createClass({
getInitialState: function() {
return { invoices: [] };
},
onComponentDidMount: function() {
// make an ajax call to server to get
// invoices data. Then on success:
// this.setState({ invoices: data });
},
render: function() {
<div>
<InvoiceTabs invoices={this.state.invoices} />
</div>
}
});
// Everything here on out is just using props, so it's immutable data.
var InvoiceTabs = React.createClass({
render: function() {
var InvoiceComponents = this.props.invoices.map(function(invoice) {
return (
<Invoice invoice={invoice} />
);
});
}
});
var Invoice = React.createClass({
render: function() {
var invoice = this.props.invoice;
return (
<li>
<ProductsList products={invoice.products} />
<DeliveryInfo delivery={invoice.delivery} />
<InvoiceCalculator />
</li>
)
}
});
// various other components
I've been trying to get my dgrid/dstore grid in realtime.
As var as I understand the function 'Observable' is deprecated, and also it doesnt work for me.
I've tried to update the grid via a Interval timer but then the whole grid is erased and new loaded. How to update the whole grid 'inline' without erasing, and showing 'loading data'?
This is my basic code:
var timer = setInterval(function() {
store.invalidate(); // Invalidate the cache
store.fetch(); // Perform a new request for all items
grid.refresh();
}, 500);
Observable does not exist in dstore, but there is a Trackable mixin which can be used instead. As for updating the grid when new content is fetch from the store, you could use a dstore/Cache and then pass the cached Memory store that mixes in Trackable to the grid to use instead. Each time new data is added to the caching store, it will also be reflected in the grid.
require([
'dgrid/OnDemandGrid',
'dstore/Rest',
'dstore/Memory',
'dstore/Trackable',
'dstore/Cache',
'dojo/domReady!'
], function (OnDemandGrid, Rest, Memory, Trackable, Cache) {
var restStore = new Rest({
target: '/mockRequest/'
});
var store = Cache.create(restStore, {
cachingStore: new (Memory.createSubclass(Trackable))()
});
var grid = new OnDemandGrid({
collection: store.cachingStore,
columns: {
id: 'ID',
name: 'Name',
description: 'Description'
},
loadingMessage: 'Loading...'
}, 'main');
grid.startup();
setInterval(function () {
store.fetch();
}, 2000);
});