<!DOCTYPE html>
<html lang="en">
<head>
<style>
html,
body {
margin: 0;
padding: 0;
height: 100%;
}
</style>
<script src="https://unpkg.com/ag-grid-enterprise@21.0.1/dist/ag-grid-enterprise.min.js"></script>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div style="display: flex; height: 100%; width: 100%; align-items: center; justify-content: center; flex-direction: column">
<div style="height: 100%;width:900px; border: 2px solid black">
<div id="myGridContainer" style="height: 800px;width:100%; display: flex; flex-direction: column">
<div id="buttons" style="height: 30px; display: flex; align-items: center; padding-left: 24px;">
<input type="checkbox" onclick="onSelectAll(this)">
<span id="myBulkOperations" style="display: none">
<span style="margin:0 10px;"><img
src="https://www.gstatic.com/images/icons/material/system/1x/delete_black_20dp.png" onclick="onClickDeleteAll()"></span>
<span style="margin:0 10px;"><img
src="https://www.gstatic.com/images/icons/material/system/1x/drafts_black_20dp.png" onclick="onClickMarkAll(this)"></span>
</span>
<input type="search" id="filter-text-box" placeholder="Search mail" oninput="onFilterTextBoxChanged()"
style="margin-left: 24px;">
<button onclick="onBtGroupBySender()"> Group by Sender</button>
</div>
<p id="selection" style="display: none"></p>
<div id="myGrid" class="ag-theme-material" style="height: 770px; width: 100%;"></div>
</div>
<div id="myEmail">
<h1>Email View</h1>
<h2 id="emailFrom" style="padding: 5px">From: </h2>
<h2 id="emailSubject" style="padding: 5px">email subject</h2>
<p id="emailData" style="padding: 5px">data</p>
</div>
</div>
</div>
<script src="main.js"></script>
</body>
</html>
var isDataGrouped = false;
var allMarked = false;
var columnDefsFactory = (rowGroupFrom) => [
{
colId: 'from',
field: "from",
checkboxSelection: true,
rowGroup: rowGroupFrom,
width: 400,
},
{
colId: 'subject',
field: "subject",
width: 1092,
cellRendererSelector: (params) => params.node.group ? null : {component: 'hoverCellRenderer'},
},
{colId: 'emailData', field: "emailData", hide: true},
];
var gridOptions = {
columnDefs: columnDefsFactory(),
rowHeight: 40,
defaultColDef: {
sortable: true,
resizable: true
},
groupSelectsChildren: true,
rowSelection: 'multiple',
suppressRowClickSelection: true,
deltaRowDataMode: true,
deltaColumnMode: true,
pagination: true,
paginationAutoPageSize: true,
getRowNodeId: function (data) {
return data.id;
},
components: {
hoverCellRenderer: HoverCellRenderer,
},
rowClassRules: {
'email-read': function (params) {
return params.node.group ? false : !params.data.read;
},
},
groupUseEntireRow: true,
onCellMouseOver: onCellMouseOver,
onCellMouseOut: onCellMouseOut,
onRowClicked: onRowClicked,
onRowSelected: onRowSelected,
onFirstDataRendered: () => gridOptions.api.sizeColumnsToFit(),
autoGroupColumnDef: {
checkboxSelection: true,
}
};
function processData(data) {
gridOptions.api.setRowData(data);
}
function onCellMouseOver(event) {
let renderer = event.api.getCellRendererInstances({
rowNodes: [event.node],
columns: ['from', 'subject'],
})[0];
if (renderer == null) return;
renderer.showButton();
}
function onCellMouseOut(event) {
let renderer = event.api.getCellRendererInstances({
rowNodes: [event.node],
columns: ['from', 'subject'],
})[0];
if (renderer == null) return;
renderer.hideButton();
}
function onRowSelected(event) {
if (gridOptions.api.getSelectedNodes().length >= 2) {
showBulkOperations();
} else {
hideBulkOperations();
}
}
function onRowClicked(event) {
if (!event.data) return;
if (event.event.target.tagName === "IMG") {
event.event.stopPropagation();
return;
}
let from = event.data.from;
let subject = event.data.subject;
let emailData = event.data.emailData;
let newData = {
...event.data,
read: true
};
event.node.setData(newData);
document.getElementById('emailFrom').innerText = 'From: ' + from;
document.getElementById('emailSubject').innerText = 'RE: ' + subject;
document.getElementById('emailData').innerText = emailData;
}
function onSelectAll(event) {
if (event.checked) {
gridOptions.api.selectAll();
showBulkOperations();
} else {
gridOptions.api.deselectAll();
hideBulkOperations();
}
}
function showBulkOperations() {
document.getElementById('myBulkOperations').style.display = 'block';
}
function hideBulkOperations() {
document.getElementById('selection').style.display = 'none';
document.getElementById('myBulkOperations').style.display = 'none';
}
function onClickDeleteAll() {
let selectedRowNodes = gridOptions.api.getSelectedNodes();
gridOptions.api.updateRowData({remove: selectedRowNodes});
}
function onClickMarkAll(event) {
event.src = !allMarked ? "https://www.gstatic.com/images/icons/material/system/1x/mark_as_unread_black_20dp.png" : "https://www.gstatic.com/images/icons/material/system/1x/drafts_black_20dp.png";
let rowNodesToUpdate = [];
let selectedRowNodes = gridOptions.api.getSelectedNodes();
gridOptions.api.forEachNode(function (rowNode) {
if (rowNode.isSelected()) {
let data = rowNode.data;
if (!data) return;
data.read = !allMarked;
rowNodesToUpdate.push(data);
}
});
allMarked = !allMarked;
gridOptions.api.updateRowData({update: rowNodesToUpdate});
}
function onFilterTextBoxChanged() {
gridOptions.api.setQuickFilter(document.getElementById('filter-text-box').value);
}
function onBtGroupBySender() {
if (!isDataGrouped) {
gridOptions.api.setColumnDefs(columnDefsFactory(true));
isDataGrouped = true;
} else {
gridOptions.api.setColumnDefs(columnDefsFactory(false));
isDataGrouped = false;
}
gridOptions.api.sizeColumnsToFit();
}
function HoverCellRenderer() {
}
HoverCellRenderer.prototype.init = function (params) {
this.params = params;
this.eGui = document.createElement('div');
this.eGui.innerHTML = `
<div style="display: flex; flex-direction: row">
<div style="overflow: hidden;"><span style="text-overflow: ellipsis; display: inline-block; overflow: hidden; font-family: Roboto,RobotoDraft,Helvetica,Arial,sans-serif ;font-size: .875rem; letter-spacing: .2px">${params.value} - <span style="font-weight: normal; color: #5f6368;">${params.node.data.emailData}</span></span></div>
<div class = "btns" style="width: 100%; text-align: right; display: none;">
<!-- <span style="display: none; float:right;">-->
<span class="btn-delete row-icon-hover" style="margin:0 10px;"><img src="https://www.gstatic.com/images/icons/material/system/1x/delete_black_20dp.png"></span>
<span class="btn-mark row-icon-hover" style="margin:0 10px;" ><img></span></span>
</div>
</div>`;
this.eDeleteButton = this.eGui.querySelector('.btn-delete');
this.eMarkButton = this.eGui.querySelector('.btn-mark');
this.eMarkButton.firstChild.src = params.data.read ? "https://www.gstatic.com/images/icons/material/system/1x/mark_as_unread_black_20dp.png" : "https://www.gstatic.com/images/icons/material/system/1x/drafts_black_20dp.png";
this.eDeleteButton.addEventListener('click', function (event) {
console.log('*** Delete Button clicked ***', params.node);
console.log('params', params);
params.api.updateRowData({remove: [params.node]});
});
this.eMarkButton.addEventListener('click', (event) => {
let newData = {
...this.params.data,
read: !this.params.data.read
};
this.params.node.setData(newData);
this.params.api.refreshCells({nodes: [params.node], force: true});
this.eMarkButton.firstChild.src = this.params.data.read ? "https://www.gstatic.com/images/icons/material/system/1x/mark_as_unread_black_20dp.png" : "https://www.gstatic.com/images/icons/material/system/1x/drafts_black_20dp.png";
});
};
HoverCellRenderer.prototype.getGui = function () {
return this.eGui;
};
HoverCellRenderer.prototype.showButton = function () {
this.spanEl = this.eGui.querySelector('.btns');
this.spanEl.style.display = 'inline-block';
};
HoverCellRenderer.prototype.hideButton = function () {
this.spanEl.style.display = 'none';
};
HoverCellRenderer.prototype.refresh = function (params) {
this.params = params;
};
// setup the grid after the page has finished loading
document.addEventListener('DOMContentLoaded', function () {
var gridDiv = document.querySelector('#myGrid');
new agGrid.Grid(gridDiv, gridOptions);
fetch('data.json').then(result => result.json().then(data => processData(data.map((item, i) => ({id: i, ...item})))));
});
[
{
"from": "Alberto Gutierrez",
"subject": "[JIRA] (T2T-1304) Editing state lost when adding column definitions",
"emailData": "Alberto Gutierrez added 1 new comment",
"read": false
},
{
"from": "CodePen",
"subject": "Here's some things you can do on CodePen.",
"emailData": "Thanks for joining the CodePen community! It's been a few days now and we're just checking in to show you a few things you might want to know that you can do with CodePen:",
"read": false
},
{
"from": "DW Fitness First",
"subject": "Just For You | Member Exclusive 20% off Starts Now",
"emailData": "Take advantage of 20% off* sportswear ranges at DW Sports! Use the below code at the checkout:",
"read": false
},
{
"from": "Bamdad Fard",
"subject": "[JIRA] (T2T-1310) ag grid Capture Data/Configuration on screen for saving in database",
"emailData": "rewoiurheoiuthrouit hoiutrehg ieufhiouewghroiqwu das",
"read": true
},
{
"from": "Ahmed Gadir",
"subject": "[JIRA] (T2T-1322) Angular rendering performance",
"emailData": "kjkljmkofo jgoidjf goidfjgiodfjgoi",
"read": true
},
{
"from": "yyyy",
"subject": "yyyyyyyyyyyy",
"emailData": "knsfkjdsnfkanjd",
"read": true
},
{
"from": "Davis Jaunbruns",
"subject": "[JIRA] (T2T-1324) Memory leak when using cellRenderer function",
"emailData": "vfjkndlvjksfbdiln lsdknfsdfoiudshufidsnfklj sdnklsdb fisdkflsd",
"read": false
},
{
"from": "Alberto Gutierrez",
"subject": "[JIRA] (T2T-1304) Editing state lost when adding column definitions",
"emailData": "Alberto Gutierrez added 1 new comment",
"read": false
},
{
"from": "CodePen",
"subject": "Here's some things you can do on CodePen.",
"emailData": "Thanks for joining the CodePen community! It's been a few days now and we're just checking in to show you a few things you might want to know that you can do with CodePen:",
"read": false
},
{
"from": "DW Fitness First",
"subject": "Just For You | Member Exclusive 20% off Starts Now",
"emailData": "Take advantage of 20% off* sportswear ranges at DW Sports! Use the below code at the checkout:",
"read": false
},
{
"from": "Bamdad Fard",
"subject": "[JIRA] (T2T-1310) ag grid Capture Data/Configuration on screen for saving in database",
"emailData": "rewoiurheoiuthrouit hoiutrehg ieufhiouewghroiqwu das",
"read": true
},
{
"from": "Ahmed Gadir",
"subject": "[JIRA] (T2T-1322) Angular rendering performance",
"emailData": "kjkljmkofo jgoidjf goidfjgiodfjgoi",
"read": true
},
{
"from": "yyyy",
"subject": "yyyyyyyyyyyy",
"emailData": "knsfkjdsnfkanjd",
"read": true
},
{
"from": "Davis Jaunbruns",
"subject": "[JIRA] (T2T-1324) Memory leak when using cellRenderer function",
"emailData": "vfjkndlvjksfbdiln lsdknfsdfoiudshufidsnfklj sdnklsdb fisdkflsd",
"read": false
},
{
"from": "Alberto Gutierrez",
"subject": "[JIRA] (T2T-1304) Editing state lost when adding column definitions",
"emailData": "Alberto Gutierrez added 1 new comment",
"read": false
},
{
"from": "CodePen",
"subject": "Here's some things you can do on CodePen.",
"emailData": "Thanks for joining the CodePen community! It's been a few days now and we're just checking in to show you a few things you might want to know that you can do with CodePen:",
"read": false
},
{
"from": "DW Fitness First",
"subject": "Just For You | Member Exclusive 20% off Starts Now",
"emailData": "Take advantage of 20% off* sportswear ranges at DW Sports! Use the below code at the checkout:",
"read": false
},
{
"from": "Bamdad Fard",
"subject": "[JIRA] (T2T-1310) ag grid Capture Data/Configuration on screen for saving in database",
"emailData": "rewoiurheoiuthrouit hoiutrehg ieufhiouewghroiqwu das",
"read": true
},
{
"from": "Ahmed Gadir",
"subject": "[JIRA] (T2T-1322) Angular rendering performance",
"emailData": "kjkljmkofo jgoidjf goidfjgiodfjgoi",
"read": true
},
{
"from": "yyyy",
"subject": "yyyyyyyyyyyy",
"emailData": "knsfkjdsnfkanjd",
"read": true
},
{
"from": "Davis Jaunbruns",
"subject": "[JIRA] (T2T-1324) Memory leak when using cellRenderer function",
"emailData": "vfjkndlvjksfbdiln lsdknfsdfoiudshufidsnfklj sdnklsdb fisdkflsd",
"read": false
},
{
"from": "Alberto Gutierrez",
"subject": "[JIRA] (T2T-1304) Editing state lost when adding column definitions",
"emailData": "Alberto Gutierrez added 1 new comment",
"read": false
},
{
"from": "CodePen",
"subject": "Here's some things you can do on CodePen.",
"emailData": "Thanks for joining the CodePen community! It's been a few days now and we're just checking in to show you a few things you might want to know that you can do with CodePen:",
"read": false
},
{
"from": "DW Fitness First",
"subject": "Just For You | Member Exclusive 20% off Starts Now",
"emailData": "Take advantage of 20% off* sportswear ranges at DW Sports! Use the below code at the checkout:",
"read": false
},
{
"from": "Bamdad Fard",
"subject": "[JIRA] (T2T-1310) ag grid Capture Data/Configuration on screen for saving in database",
"emailData": "rewoiurheoiuthrouit hoiutrehg ieufhiouewghroiqwu das",
"read": true
},
{
"from": "Ahmed Gadir",
"subject": "[JIRA] (T2T-1322) Angular rendering performance",
"emailData": "kjkljmkofo jgoidjf goidfjgiodfjgoi",
"read": true
},
{
"from": "yyyy",
"subject": "yyyyyyyyyyyy",
"emailData": "knsfkjdsnfkanjd",
"read": true
},
{
"from": "Davis Jaunbruns",
"subject": "[JIRA] (T2T-1324) Memory leak when using cellRenderer function",
"emailData": "vfjkndlvjksfbdiln lsdknfsdfoiudshufidsnfklj sdnklsdb fisdkflsd",
"read": false
},
{
"from": "Alberto Gutierrez",
"subject": "[JIRA] (T2T-1304) Editing state lost when adding column definitions",
"emailData": "Alberto Gutierrez added 1 new comment",
"read": false
},
{
"from": "CodePen",
"subject": "Here's some things you can do on CodePen.",
"emailData": "Thanks for joining the CodePen community! It's been a few days now and we're just checking in to show you a few things you might want to know that you can do with CodePen:",
"read": false
},
{
"from": "DW Fitness First",
"subject": "Just For You | Member Exclusive 20% off Starts Now",
"emailData": "Take advantage of 20% off* sportswear ranges at DW Sports! Use the below code at the checkout:",
"read": false
},
{
"from": "Bamdad Fard",
"subject": "[JIRA] (T2T-1310) ag grid Capture Data/Configuration on screen for saving in database",
"emailData": "rewoiurheoiuthrouit hoiutrehg ieufhiouewghroiqwu das",
"read": true
},
{
"from": "Ahmed Gadir",
"subject": "[JIRA] (T2T-1322) Angular rendering performance",
"emailData": "kjkljmkofo jgoidjf goidfjgiodfjgoi",
"read": true
},
{
"from": "yyyy",
"subject": "yyyyyyyyyyyy",
"emailData": "knsfkjdsnfkanjd",
"read": true
},
{
"from": "Davis Jaunbruns",
"subject": "[JIRA] (T2T-1324) Memory leak when using cellRenderer function",
"emailData": "vfjkndlvjksfbdiln lsdknfsdfoiudshufidsnfklj sdnklsdb fisdkflsd",
"read": false
}
]
/*.custom-focus {*/
/* border: 1px solid #0091EA !important;*/
/* outline: initial !important;*/
/*}*/
.ag-header {
display: none
}
.ag-row-hover {
/* putting in !important so it overrides the theme's styling as it hovers the row also */
background-color: #c2dbff !important;
}
.ag-row {
background-color: rgba(242,245,245,0.8);
}
.row-icon-hover img:hover {
/*background-color: rgba(32, 33, 36, 0.059);*/
/*background: lightgray;*/
border: 7px solid lightgray;
border-radius: 50%;
opacity: 1;
}
.row-icon-hover img {
background-color: #c2dbff;
border: 7px solid #c2dbff;
border-radius: 50%;
margin-top: 1px;
opacity: 1;
}
.ag-theme-material .email-read {
font-weight: bold !important;
background-color: white;
}