AG Grid Row-Grouping for showing version history of data - ag-grid

I'm a first time user of AG Grid and need some help identifying how to configure Row Grouping for my AG Grid in such a way that allows me to see my data group as a timeline/audit history. Was reading through the docs and haven't found an example on there that resembles what I'm looking for.
I have rowData that contains history and the visual expectation is that, the same base columnDefs assigned to the grid are used for the main "group" row (that contains the expand/collapse chevron) and all the expanded rows as well -- so there is no need for a "group column"
Anyone know how I can achieve this outcome? I have also looked at treeData and masterDetail but those didn't work out for me.
P.S. I don't rule out the possibility that I could be misreading/misunderstanding the AG Grid docs so any help there is appreciated.
EDIT: After fiddling around with things further, I believe I'm looking for a combination of two things:
The isRowMaster to enable expand/collapse on the main parent entry.
The groupDisplayType="groupRows" setting (minus the default row group cell because that would be handled by my master row from Point 1 instead)

After much head banging, turns out the solution was to use treeData. What I ended up creating was treeData containing only one level children.
Parent Node (expand/collapse)
child 1
...
child n
The other key was understanding how to structure your rowData and returning the proper dataPath to feed into the getDataPath handler for treeData. AG Grid expects a flat-list for rowData -- I say this as I was not able to get things working when having a nested tree structure like the following.
const mainRecord = {
id: "abc"
foo: 1,
bar: 2,
history: [
{ foo: 3, bar: 4 },
{ foo: 5, bar: 6 }
]
}
I had to modify my data structure above to return the history items as a flat list alongside the main record that I eventually sent as rowData. The other thing I had to do was add some hierarchy property to my objects to denote its placement in the tree. The hierarchy value is what I supplied to getDataPath
const rowData = [
{ id: "abc", foo: 1, bar: 2, hierarchy: ["abc"] }, // parent
{ foo: 3, bar: 4, hierarchy: ["abc", "34"] }, // child 1
{ foo: 5, bar: 6, hierarchy: ["abc", "56"] }, // child 2
]
After doing the above changes, I was able to get the expected visual outcome I was looking for. I think the big takeaway I got from this is as a first time user of AG Grid is, let it take care of grouping of your data on your behalf (as opposed to doing it yourself via structuring your models with some internal nested children structure)

Related

How to filter an array of object in Mui DataGrid?

I recently changed my tables to Mui-datagrid on Material UI 5, and I have a special use case with an array of objects. I want to enable the phone number filter in this column, but the number is provided as an object list.
phone: [
{ type: "home", number: "795-946-1806" },
{ type: "mobile", number: "850-781-8104" }
]
I was expecting a 'customFilterAndSearch' or an option to customise how to search in this specific field.
customFilterAndSearch: (term, rowData) =>
!!rowData?.suppressedOptions.find(({ description }) =>
description?.toLowerCase().includes(term.toLowerCase())
),
I have made some tries with the filterOperators, but no success yet. I have made a full example here https://codesandbox.io/s/mui-data-grid-vs05fr?file=/demo.js
As far as I can see from the DataGrid documentation I don't see any way to change the filter function for a specific function.
Likely the best workaround for your use case will be converting this to a string be converting the data to a string before you pass it to the datagrid. Though you will lose the styling that you currently do by making the phone type bold.
On second though your best best would probably be to split the phone column into two columns which would probably be the cleanest way of solving your problem
Add helper function.
You could potentially add a helper function to just map all the phone lists to something like mobilePhone or homePhone
const mapPhoneObject = (rows) => {
rows.forEach((row) => {
row.phone.forEach((phone) => {
row[`${phone.type}Phone`] = phone.number;
});
});
return rows
};
I've added a fork of your snippet with my function, it is I think the most viable solution for your problem: https://codesandbox.io/s/mui-data-grid-forked-ppii8y

How do I create a schema dynamically to store the folder structure?

I'm new to MongoDB, and I'm trying to design the schema structure for storing the folder hierarchy.
This is my schema design:
parent: {
id: Schema.Object,
title: String,
children: []
}
Above children will store details dynamically in the following manner.
The id will refer to folder schema which has folder details.
children:[
{
id: Schema.Object,
title : String,
children:[
{
id:Schema.Object,
titile: String
}
]
}
]
The above method is working fine. But I'm facing an issue on updating the title for a particular Id will be quiet complex. Is there any other way to design schema. Thanks in Advance.
I think nesting of children is not a proper approach to achieve this.
Rather you can introduce a new key for children, level this will help in
identifying the structure/hierarchy.
children:[
{
id:Schema.Object,
titile: String,
level: Number
}
]
eg: abc/bcd/egt/something
abc(root) - level 0
bcd - level 1
egt - level 2
something - level 3
It will be dynamic and easy to maintain.

UI5: get path for new object in model

I often have some kind of master-detail situation where i try to use a single model for both master and detail view.
The detail page is bound directly to an element in the list with .bindElement(path) when you select an item in the list. The path is available from the binding context. Everyone is happy:
//click handler for list item:
var context = this.getBindingContext();
oDetailPage.bindElement(context.getPath());
oApp.toDetail(oDetailPage);
The challenge is when the list page has an "add" button. I create a new object and put that into the model. But how do I find the path? i have no context:
//click handler for "add" button
var newStuff = {
propA: "foo",
propB: 13
};
oModel.setData(oModel.getData().concat(newStuff));
oDetailPage.bindElement(/* What??? */);
oApp.toDetail(oDetailPage);
I've searched for a .findPath(newStuff) method but no such thing exists
Hi, unfortunatly I am unable to test this but I think this should work
The binding path is pretty much pointer to a specific entry in a collection. The path value does depend on a couple of variables, such as how your model is structured.
For example, if the Model data looks like this :
{"results" : [
{propA: "foo",
propB: 13
},
{propA: "ber",
propB: 14
}]
}
And you concat
{propA: "newItem",
propB: 15
}
I believe you binding path would be
"/results/2"
You can also, find the most recent index with something like
this.getModel("yourModel").getObject("results").length;
Edit -
Unless I miss understand your quesitons, your new entry should be at the end of the model.
here are 2 cases
//click handler for "add" button
var newStuff = {
propA: "foo",
propB: 13
};
// case 1: root of model data is an array
var oData = oModel.getProperty("/");
oData.push(newStuff);
oDetailPage.bindElement("/" + oData.length - 1);
// case 2: we appends to /results
var oData = oModel.getProperty("/results");
oData.push(newStuff);
oDetailPage.bindElement("/results/" + oData.length - 1);

Dynamic Widgets in Dashing

I'm new to using ruby and Coffee script but I have managed to get as far as displaying data within a single widget.
I am trying to think logically how would one go about creating a widget for each entry from a collection.
Does anyone know how to go about creating widgets after calling a service and getting a collection of data.
For example:
entries: [
{
name: "bob",
age: 21
},
{
name: "alex",
age: 42
},
{
name: "fred",
age: 35
}
]
I want to be able go through each of these and create a widget for each of these entries. Is this possible?
This is easy enough. From any of the Ruby scripts you have in your jobs folder, you'll typically update a widget with a send_event call, like so:
send_event(widget.to_s, bus_info)
This will update the appropriate widget. A job, however, can make this call as much as is useful, so could update dozens of widgets in its run. You could just loop through your list and run send_event() for each item in your list. Play with it and if you get stuck, let me know and I can put together a bigger example, but hopefully you can use the above to get you going.
Here's a more full example from our zendesk widget set.
def update_dashing(view, value)
puts 'sending ' + view + ' : ' + value.to_s
send_event('zendesk-' + view, current: value, status: 'normal',
service: 'Zendesk')
end
def update_zendesk(views)
counts = zendesk_client.view_counts(ids: views, path: 'views/count_many')
counts.all do |ct|
next unless ct.fresh
update_dashing(ct.view_id.to_s, ct.value.to_i)
end
end
The zendesk_client.view_counts() function returns a list of <view_id>:<count> pairs that we then loop through.

Select an item from Dojo Grid's store and display one of its attributes (array of objects) on grid

I have a Dojo EnhancedGrid which uses a data store filled with the following data structure:
[
{ id: 1, desc: "Obj Desc", options: [ { txt: "text", value: 0 }, { obj2 }, { objn } ] },
{ id: 2, ... },
{ id: 3, ... },
{ id: n, ... }
]
Currently I'm doing all this with an auxiliary store...but I believe this is far from a good approach to the problem, it's too ugly and doesn't work really well with edition (because I have to send changes from one store to another).
Instead of displaying all this objects at the same time, I wanted to select just one object (using its id) and display its options objects on grid. At the same time, the changes on grid should make effect on store, to be able to save them later.
Is it possible to query the grid's store, in order to display just one object? How?
And is it possible to fill the grid with objects list present on "options" attribute?