An app plugin that adds an ancestor portfolio item filter and project scoping to the app, or, if placed on a page containing
a version of this plugin configured as a publisher
, will listen for an ancestor filter from the publisher
app.
The plugin will:
- add an app setting that controls if ancestor filtering is enabled
- If the setting is enabled
- search the app for a container with the id of
Utils.AncestorPiAppFilter.RENDER_AREA_ID
(or a specified id) and add a portfolio type picker, a portfolio item picker and a project scoping control. - listen for events from any apps using this plugin as a publisher
- if a publisher is detected, the local portfolio type and picker will be hidden and filter values from the publisher used instead.
- search the app for a container with the id of
- Dispatch a
ready
event when the control is ready for use. - Dispatch a
select
event when the selected portfolio item is changed (or a publisher has changed selections) - Make the current portfolio item available as a Rally.data.wsapi.Filter relative to a given type.
(e.g. An Epic ancestor for a HierarchicalRequirement becomes
PortfolioItem.Parent = /portfolioitem/epic/1234
) - Make the current project scope setting available as a function call.
- If the given type doesn't have the selected portfolio item type as an ancestor, a null filter
is returned
(ObjectID = 0)
. - To ensure the filter is fully initialized, the appliation should wait for the
ready
event before getting the current ancestor filter.
- pi-ancestor-filter-broadcaster for an example.
- CFD-by-implied-state
- custom-board
- custom-grid-with-deep-export
- CustomChart
- enhanced-dependency-app
- query-counter
- Install using npm (or yarn)
npm install '@agile-central-technical-services/utils-ancestor-pi-app-filter' -D
- Add the file to the
javascript
section ofconfig.json
"javascript": [ "node_modules/@agile-central-technical-services/utils-ancestor-pi-app-filter/index.js", ...
Ext.define("PiAncestorFilterBroadcaster", {
extend: 'Rally.app.App',
// Add an area where the filter controls will render.
items: [{
id: Utils.AncestorPiAppFilter.RENDER_AREA_ID,
xtype: 'container',
flex: 1,
layout: {
type: 'hbox',
align: 'middle',
defaultMargins: '0 10 10 0',
}
}],
launch: function() {
this.ancestorFilterPlugin = Ext.create('Utils.AncestorPiAppFilter', {
ptype: 'UtilsAncestorPiAppFilter',
pluginId: 'ancestorFilterPlugin',
publisher: true, // Publish events to other apps using this plugin
settingsConfig: {
labelWidth: 150,
margin: 10
},
listeners: {
scope: this,
ready: function(plugin) {
// Plugin ready, begin listening for selection changes
plugin.addListener({
scope: this,
select: function() {
// Notify any listeners of the new filter values
this.ancestorFilterPlugin.notifySubscribers();
}
});
// Notify any listeners of the current selections
this.ancestorFilterPlugin.notifySubscribers();
},
}
});
// Must add the filter at runtime (instead of in config) to make sure we can
// catch its ready event.
this.addPlugin(this.ancestorFilterPlugin);
}
});
Ext.define("custom-grid-with-deep-export", {
extend: 'Rally.app.App',
items: [{
id: Utils.AncestorPiAppFilter.RENDER_AREA_ID,
xtype: 'container',
flex: 1,
layout: {
type: 'hbox',
align: 'middle',
defaultMargins: '0 10 10 0',
}
}]
launch: function() {
...
this.ancestorFilterPlugin = Ext.create('Utils.AncestorPiAppFilter', {
ptype: 'UtilsAncestorPiAppFilter',
pluginId: 'ancestorFilterPlugin',
// Set to false to prevent the '-- None --' selection option if your app can't support
// querying by a null ancestor (e.g. Lookback _ItemHierarchy)
allowNoEntry: true,
settingsConfig: {
labelWidth: 150,
margin: 10
},
listeners: {
scope: this,
ready: function(plugin) {
plugin.addListener({
scope: this,
select: function() {
this.loadData();
}
});
this.loadData();
}
}
});
this.addPlugin(this.ancestorFilterPlugin);
},
loadData: function() {
...
// Get current ancestor portfolio item filter
var ancestorFilter = this.ancestorFilterPlugin.getFilterForType(artifactType);
if (ancestorFilter) {
filters = filters.and(ancestorFilter);
}
// Get current project scoping
var dataContext = this.getContext.getDataContext();
if ( this.ancestorFilterPlugin.getIgnoreProjectScope() ) {
dataContext.project = null
}
...
}
To Update
npm version patch
- This will update the package.json to a new version and create a git tag (e.g.v1.0.1
). It will also run thepostversion
script to push the changes and tag to GitHub.npm publish --access public
- This will publish the new version to npmjs.org- Create the new release in `utils_file-utils/releases'
- PASS - Retain values after settings close and reopen
- PASS - Retain values after app reload
- PASS - Label width customizable by config.settingsConfig
- PASS - Show ancestor filter shows/hides ancestor filter
- PASS - Show ignore scope shows/hides ignore scope
- NOT IMPLEMENTED - Ignore scope by default provides default value for ignore scope control
- PASS - Ignore scope by default value used ONLY if ignore scope control not shown
- PASS - has mouseover explaining icon
- PASS - pi types
- PASS - changing types resets pi picker
- PASS - lowest level selected by default
- PASS - type remembered after reload
- PASS - changing type notifies subscribers
- PASS - unaffected by changes to controls in expanded listener
- PASS - has clear option
- PASS - has none option
- PASS - has pis that match currently selected pi type
- PASS - has pis across entire workspace
- PASS - pi remembered after reload
- PASS - changing pi notifies subscribers
- PASS - unaffected by changes to controls in expanded listener
- PASS - Current Project is default
- PASS - choice remembered after reload
- PASS - changing choice notifies subscribers
- PASS - unaffected by changes to controls in expanded listener
- PASS - Shows publisher icon
- PASS - Shows subscriber icon
- PASS - Hides all controls
- PASS - Hides all controls even when own app settings show them
- NOT IMPLEMENTED - Uses publisher settings when expanded
- PASS - Uses app settings for controls when expanded
- PASS - Uses publisher filters when not expanded
- PASS - Automatically becomes subscriber when publisher added to page