How to stop extjs treepanel from loading infinitely? - extjs4

Finally after struggling with extjs tree panel, tree store and building custom reader to read and convert pentaho data for 2 weeks I have managed to load pentaho data into treepanel of extjs.
Now my Tree panel is loading same data infinitely.
Treepanel looks as follows :
Part of my json data looks as follows :
{
{name: 'US', candidateCount: 3, children: []},
{name: 'India', candidateCount: 922, children: [
{name: 'Goa', candidateCount:124, children: []},
{name: 'Maharashtra', candidateCount: 43, children: [
{name: 'Pune', candidateCount: 3},
{name: 'Mumbai', candidateCount: 33},
{name: 'Kolhapur', candidateCount: 4},
{name: 'XXX', candidateCount: 3},
]}
]},
{name: 'UK', candidateCount: 1, children: []},
}
As you can see in image above, after expanding India node it has again loaded data of country level (i.e. country names US, uk, India, UK). Actually I want to show state level data like data of Maharashtra, Goa. Instead of that treepanel is again loading same data again.
How to avoid this kind of behavior? I have already set leaf property of US, uk and India nodes to false.
I tried setting Expanded property to true but then treepanel keeps loading same nodes again and again and my browser tab just gets hanged.
Please let me know how to avoid this? I want tree panel to load data only once.
EDIT - Solution to this problem
I solved this problem by adding listener on append event of store and then setting leaf value to true for the nodes which I wanted to be leaf.

I had the same problem with my treepanel and JSON data. My treeStore looks something like this:
proxy: {
type: 'ajax',
url: 'urlJson',
reader: {
type: 'json',
root: 'instanceList',
successProperty: 'success'
}
},
root:{
text: 'Root',
expanded: true
}
And the JSON
{
"instanceList": [
{
"text": "Parent 1",
"instanceList": [
{
"class": "testing",
"id": 3,
"leaf": true,
"text": "Child 1"
}
]
},
{
"text": "Parent 2",
"instanceList": [
{
"class": "testing",
"id": 2,
"leaf": true,
"text": "Child 2"
},
{
"class": "testing",
"id": 1,
"leaf": true,
"text": "Child 3"
}
]
}
],
"instanceTotal": 1,
"success": true
}
I changed "children" for "instanceList" and my treepanel stopped doing that infinitely loop, so I guess If you change "name" for "children" ?

Setting data item to:
{
...
leaf: true
}
will stop it.

Loading trees can be tricking. Try setting loaded: true on those nodes. Before you start clicking around, is the tree properly loaded?

Make sure all parents that do not have any children have "leaf" set to "true" OR
have an empty "children" node.
AND all children nodes have "leaf" set to "true" (as already mentioned by Asken)

it seems to me that any child becomes a root to its dependents . So the root property and the children property MUST have the same NAME. I am very happy I found this tread. It saved my life I was about to shoot myself because of endless reloading the tree

As Edd said, if you set in proxy custom rootProperty:'instanceList', you have to change all "children" in json to that property, ie 'instanceList'. It was my solution.

Related

Converting AWS CloudWatch Metrics Insight query to CDK Metric

I am modifying the sample at https://github.com/cdk-patterns/serverless/tree/main/the-eventbridge-etl/typescript as I want to add a dashboard widget to my CloudFormation Stack that shows the Fargate vCPU usage. I have been able to upgrade the app to use CDK v2, and deployment/functionality has been confirmed. However, I cannot get the vCPU widget in the dashboard to show any data.
If I configure the widget manually, from within AWS CloudWatch's Source field, the query looks as follows:
{
"metrics": [
[ { "expression": "SELECT COUNT(ResourceCount) FROM SCHEMA(\"AWS/Usage\", Class,Resource,Service,Type) WHERE Service = 'Fargate' AND Resource = 'vCPU'", "label": "Query1", "id": "q1" } ],
[ "AWS/Usage", "ResourceCount", "Service", "Fargate", "Type", "Resource", { "id": "m1" } ]
],
"view": "timeSeries",
"title": "ExtractECSJob",
"region": "us-west-2",
"timezone": "Local",
"stat": "Sum",
"period": 300
}
However, when I attempt to use CDK, with the following TypeScript code:
const extractECSWidget = new GraphWidget({
title: "ExtractECSJob",
left: [
new Metric({
namespace: "AWS/Usage",
metricName: "ResourceCount",
statistic: "Sum",
period: Duration.seconds(300),
dimensionsMap: {
"Service": "Fargate",
"Type": "Resource",
"Resource": "vCPU"
}
})
]
});
This does not translate to the above, and no information is shown in this widget. The new source looks as follows:
{
"view": "timeSeries",
"title": "ExtractECSJob",
"region": "us-west-2",
"metrics": [
[ "AWS/Usage", "ResourceCount", "Resource", "vCPU", "Service", "Fargate", "Type", "Resource", { "stat": "Sum" } ]
],
"period": 300
}
How do I map the above metrics source definition to the CDK source construct?
I tried using MathExpression but with the following:
let metrics = new MathExpression({
expression: "SELECT COUNT('metricName') FROM SCHEMA('\"AWS/Usage\"', 'Class','Resource','Service','Type') WHERE Service = 'Fargate' AND Resource = 'vCPU'",
usingMetrics: {}
})
const extractECSWidget = new GraphWidget({
title: "ExtractECSJob",
left: [
metrics
]
});
I get the warning during cdk diff:
[Warning at /EventbridgeEtlStack/EventBridgeETLDashboard] Math expression 'SELECT COUNT(metricName) FROM SCHEMA($namespace, Class,Resource,Service,Type) WHERE Service = 'Fargate' AND Resource = 'vCPU'' references unknown identifiers: metricName, namespace, lass, esource, ervice, ype, ervice, argate, esource, vCPU. Please add them to the 'usingMetrics' map.
What should I put in the usingMetrics map? Any help is appreciated.
Thanks to AWS Support I was able to have this fixed. The updated code looks like the following:
let metrics = new MathExpression({
expression: "SELECT COUNT(ResourceCount) FROM SCHEMA(\"AWS/Usage\", Class,Resource,Service,Type) WHERE Service = 'Fargate' AND Resource = 'vCPU'",
usingMetrics: {},
label: "Query1"
})
let metric2 = new Metric({
namespace: "AWS/Usage",
metricName: "ResourceCount",
period: cdk.Duration.seconds(300),
dimensionsMap: {
"Service": "Fargate",
"Type": "Resource",
}
})
const extractECSWidget = new GraphWidget({
title: "ExtractECSJobTest",
left: [metrics, metric2],
region: "us-west-2",
statistic: "Sum",
width: 24
});
dashboardStack.addWidgets(
extractECSWidget
);
When running cdk deploy, I still get the same warning (about unknown identifiers being referenced) but the widget is functioning as expected.
This feature has not been supported by CDK yet. I've opened the issue https://github.com/aws/aws-cdk/issues/22844
I faced the same issue while creating an alarm based on a metric based on a query. I found the workaround with level 1 construct CfnAlarm
Maybe same kind of workaround exists for Widget.

How to keep non-current versions in a nested folder via Cloudformation template?

I have a bucket with a structure like this:
root
source
processed
form
I would like non-current versions to expire in everything except the form directory.
Will this work, or do I need to create individual rules for source, processed, and forms?
"LifecycleConfiguration": {
"Rules" : [{
"NoncurrentVersionExpiration" : {
"NoncurrentDays": 1
},
"Status": "Enabled"
}, {
"Prefix": "form",
"NoncurrentVersionExpiration" : {
"NoncurrentDays": 1
},
"Status": "Disabled"
}]
},

Sanity CMS, using type "object" as reference

Is it not possible to use an object type as a reference in sanity? For example this is not working. When I go to the field nothing shows up. If I can't do this how can I access the indexPage objects that have been created under other documents?
export const indexPage = {
title: "Index Page",
name: "indexPage",
type: "object",
fields: [
{
title: "Subheading",
name: "subheading",
type: "array",
of: [{ type: 'block' }]
},
{
title: "Content",
name: "content",
type: "array",
of: [{ type: "block" }]
},
]
}
// in another file
export const coolPage = {
title: "Cool Page",
name: "coolPage",
type: "object",
fields: [
{
title: "Reference Index Page",
name: "refIndexPage",
type: "reference",
to: [{ type: 'indexPage' }]
}
]
}
References can only point to other documents; not to a specific part of a document. So to achieve this, indexPage would need to be a document.
I think modelling indexPage as a document would be a viable option in your case. You mentioned "indexPage objects that have been created under other documents". Instead of creating indexPage data inside a specific document, indexPage should be its own document type. Any other document can then connect to it via a reference. This approach should be really flexible for you.
Sanity Studio recently added support for "references in place", which makes this workflow even better. The studio now allows you to create a document to reference while you are editing the document that references it—without leaving the editor. You can see a demo here (no extra work on your part is needed here, it's handled automatically by Sanity Studio).
In summary: if you have a piece of data you'd like to share between multiple documents, model it as its own document type that is referenced by every document that is related.

List subfolders in sidebar navigation

In my config.js file I have created this sidebar
sidebar: {
'/docs/': [
'',
'gettingStarted',
'guides',
'media'
],
'/docs/gettingStarted/': [
'creatingFirstApplication',
'installing',
'understanding'
],
'/docs/gettingStarted/creatingFirstApplication': [
'setup'
],
'/docs/gettingStarted/installing': [
'installation'
],
'/docs/gettingStarted/understanding': [
'why',
'useCases',
'coreConcepts',
'architecture',
'gettingHelp'
],
'/docs/guides/': [
'firstApplication'
],
'/docs/media/': [
'downloads',
'onlineResources'
],
'/docs/media/downloads': [
'brochure'
],
'/docs/media/onlineResources': [
'articles',
'videos'
]
}
but I am only able to see the top level markdown files when building the page. So here you can see my project structure
When building the page only README.md, gettingStarted.md, guides.md, and media.md get rendered.
How can I fix it?
Please let me know if you need more information!
So this is the current state
and this is an example showing what I would like to achieve
I found more information here
https://vuepress.vuejs.org/theme/default-theme-config.html#multiple-sidebars
I tried to reverse my configuration
sidebar: {
'/docs/gettingStarted/creatingFirstApplication': [
'setup'
],
'/docs/gettingStarted/installing': [
'installation'
],
'/docs/gettingStarted/understanding': [
'why',
'useCases',
'coreConcepts',
'architecture',
'gettingHelp'
],
'/docs/gettingStarted/': [
'creatingFirstApplication',
'installing',
'understanding'
],
'/docs/guides/': [
'firstApplication'
],
'/docs/media/downloads': [
'brochure'
],
'/docs/media/onlineResources': [
'articles',
'videos'
],
'/docs/media/': [
'downloads',
'onlineResources'
],
'/docs/': [
'',
'gettingStarted',
'guides',
'media'
]
}
but this didn't help.
I created a small repository providing a small documentation with two pages per directory.
https://github.com/Garzec/VuePressTest
I hope this helps.
It's... a little confusing but from what I understand you need subfolders...
Remember that VuePress sidebar is used to organize how the user sees the items in a specific order. The sources not matters name or where the .md file is. You can add from any path but is better to follow the Directory structure convention.
There are some considerations in your case.
Firstly...
For subfolders routes, you need to create a README.md (take it like an index.html). So, you need a Default Page Routing. Router expects that the ending /{page}/ has a /{page}/README.md
Try renaming your index pages to its subfolder like '{name}/README.md'.
For example media.md --> media/README.md.
Secondly...
There are some tree errors in your config.
I noticed you use sidebar: {} (as an object). This is intended to make multiple sidebars (different pages/sections), like in VuePress documentation Guide | Config Reference | Plugin |etc you see in its navbar. If this is your goal, you have to place all child items inside '/docs/' for example and create a fallback:
sidebar: {
'/docs/': [
'', // this is your docs/README.md
// all sub-items here (I explain later)
],
'/': [ // Your fallback (this is your landing page)
'' // this is your README.md (main)
]
}
Thirdly...
As I introduced before, you need to place all the items under that main.
Instead of creating a different route for each page, you can (after renaming I mentioned before) you need to remember that Sidebar (at least in the default theme) only have 1 route level. Their hierarchy levels are made by H2, h3, h4...,
not by file structure.
BUT... You can organize your sidebar sections by grouping it. For example:
sidebar: {
'/docs/': [
'', // this is your docs/README.md
{
title: 'Getting Started',
collapsable: false,
children: [
'gettingStarted/', // 'docs/gettingStarted/README.md' if you renamed before
'gettingStarted/creatingFirstApplication',
'gettingStarted/creatingFirstApplication/setup', // maybe better to move content to `creatingFirstApplication.md`
'gettingStarted/installing/installation',
// Maybe group all this in another another group if is much extense (instead of Getting Started)
// or join into one file and use headers (to organize secions)
'gettingStarted/understanding/why',
'gettingStarted/understanding/useCases',
'gettingStarted/understanding/coreConcepts',
'gettingStarted/understanding/architecture',
'gettingStarted/understanding/gettingHelp',
]
},
{
title: 'Guides',
collapsable: false,
children: [
'guides/', // 'docs/guides/README.md' if you renamed before
'guides/firstApplication',
]
},
{
title: 'Media',
collapsable: false,
children: [
'media/', // 'docs/media/README.md' if you renamed before
'media/downloads/brochure',
'media/onlineResources/articles',
'media/onlineResources/videos',
]
}
],
'/': [ // Your fallback (this is your landing page)
'' // this is your README.md (main)
]
}
If you need split more, think in another section (instead of '/docs/' use each part as a new navbar item (like Guide | Config Reference | Plugin |etc)).
If not, you can also set the option sidebarDepth to 2:
themeConfig: {
sidebar: {
// . . .
},
sidebarDepth: 2
}
I hope this helps you. :)
Note: Maybe I missed some route, so check it your self.
Note 2: Not run in local, but should be fine the structure/syntax. Again, check it and comment,
The answer above really helped us. We're running Vuepress 1.3.1 and ran into some issues using the sidebar groups example code above. (under thirdly)
We ended up with a fairly complex sidebar and had to structure it accordingly. Below is an abbreviated version of our config file. (whole config file)
module.exports = {
// Removed other config options for readability
themeConfig: {
// Removed other themeConfig options for readability
sidebar: [
"/",
{
title: 'AccuTerm',
path: '/accuterm/',
collapsable: true,
children: [
{
title: 'Mobile',
path: '/accuterm/mobile/',
collapsable: true,
children: [
['/accuterm/mobile/quick-start/', 'Quick Start'],
['/accuterm/mobile/colors-and-themes-settings/', 'Colors & Themes Settings'],
['/accuterm/mobile/connection-settings/', 'Connection Settings'],
['/accuterm/mobile/keyboard-and-clipboard-settings/', 'Keyboard & Clipboard Settings'],
['/accuterm/mobile/screen-settings/', 'Screen Settings'],
['/accuterm/mobile/terminal-settings/', 'Terminal Settings'],
['/accuterm/mobile/user-guide/', 'User Guide']
]
},
{
title: 'Web',
path: '/accuterm/web/',
collapsable: true,
children: [
['/accuterm/web/web-introduction/', 'Web Introduction'],
['/accuterm/web/getting-started/', 'Getting Started'],
['/accuterm/web/release-notes/', 'Release Notes'],
['/accuterm/web/activating-accuterm-desktop-licensing/', 'Activating AccuTerm Desktop Licensing'],
['/accuterm/web/batch-user-actions/', 'Batch User Actions'],
['/accuterm/web/change-password/', 'Change AccuTerm.IO Password'],
['/accuterm/web/clipboard-settings/', 'Clipboard Settings'],
['/accuterm/web/connection-settings/', 'Connection Settings'],
['/accuterm/web/creating-profiles/', 'Creating Profiles'],
['/accuterm/web/creating-roles/', 'Creating Roles'],
['/accuterm/web/creating-users/', 'Creating Users'],
['/accuterm/web/font-and-character-settings/', 'Font & Character Settings'],
['/accuterm/web/installing-accuterm-io-server/', 'Installing AccuTerm IO Server'],
['/accuterm/web/keyboard-options/', 'Keyboard Options'],
['/accuterm/web/mouse-settings/', 'Mouse Settings'],
['/accuterm/web/sound-settings/', 'Sound Settings'],
['/accuterm/web/terminal-screen-options/', 'Terminal Screen Options'],
['/accuterm/web/terminal-settings/', 'Terminal Settings'],
['/accuterm/web/web-profiles/', 'Web Profiles'],
['/accuterm/web/rezume-session-resilience/', 'AccuTerm ReZume Session Resilience'],
['/accuterm/web/phi-reports/', 'PHI Reports']
]
}
]
},
["/docs/jbase/", "jBASE"]
]
}
};
Directory Structure
Hopefully seeing this example will help clarify sidebar groups. To see the whole sidebar and directory structure view it on github:
Vuepress config file
Vuepress directory structure

Adjusting User Context with TreeStoreBuilder

I've been able to create a grid and basic filtering to narrow down iterations etc. Ideally I would like to run this via html/confluence so ideally I need to have the filtering set so that I can filter on parent as well as project. Testing this in the Rally dashboard, the way I have it still only working within project I'm sitting in. How do I make my filtering work so that where I'm at project wise in Rally doesn't matter or if I use my api key.
Thanks!
Mark
Ext.create('Rally.data.wsapi.TreeStoreBuilder').build({
models: ['userstory'],
autoLoad: true,
enableHierarchy: true,
filters: [{property: 'Iteration.Name',
operator : '=',
value : 'March'},
{property: 'Project.Parent.Name',
operator : '=',
value : 'Synergy'},
{property: 'Project.Name',
operator : '=',
value : 'Condor'}
]
}).then({
success: function(store) {
Ext.create('Ext.Container', {
items: [{
xtype: 'rallytreegrid',
columnCfgs: [
'DisplayColor',
'Name',
'ScheduleState',
'Blocked',
'TaskEstimateTotal',
'TaskRemainingTotal',
'Owner',
'Notes'
],
store: store
}],
renderTo: Ext.getBody()
});
}
});
You just need to pass a context to your store:
https://help.rallydev.com/apps/2.0/doc/#!/guide/data_stores-section-scoping
All projects:
{ project: null, workspace: '/workspace/12345'}
Specific project:
{ project: '/project/12345', projectScopeDown: false, projectScopeUp: false }
Project hierarchy:
{ project: '/project/12345', projectScopeDown: true, projectScopeUp: false }
Or if you are trying to get data from multiple projects not in a tree you can always create a filter in the store on Project like you're doing above. Note that you'll need to make sure all those projects are actually in scope based on your context to get any results.