diff --git a/assets/js/components/ProjectDisplay.mjs b/assets/js/components/ProjectDisplay.mjs
index bef51f64a..5f780fb81 100644
--- a/assets/js/components/ProjectDisplay.mjs
+++ b/assets/js/components/ProjectDisplay.mjs
@@ -1,3 +1,4 @@
+import {formatBytes} from "../util.js";
import {PieChart} from "./pie-chart.js";
import {getProjectOverview} from "../adstash.mjs";
import Count from "./Count.mjs";
@@ -83,4 +84,34 @@ class ProjectDisplay{
}
}
-export default ProjectDisplay;
+class OSDFProjectDisplay extends ProjectDisplay {
+ async update({Name, PIName, FieldOfScience, Organization, Description}) {
+ this.updateTextValue("project-Name", Name)
+ this.updateTextValue("project-PIName", PIName)
+ this.updateTextValue("project-FieldOfScience", FieldOfScience)
+ this.updateTextValue("project-Organization", Organization)
+ this.updateTextValue("project-Description", Description)
+ this.setUrl(Name)
+ this.clearGraphSlots()
+ this.parentNode.addEventListener("shown.bs.modal", () => {
+ this.updateGraphs(Name)
+ }, {once : true})
+ this.display_modal.show()
+ }
+
+ async updateGraphs(Name){
+ const data = await this.getData(Name)
+
+ const objects = Math.round(Object.values(data).reduce((p, v) => p + v.osdfFileTransferCount, 0));
+ const bytes = Math.round(Object.values(data).reduce((p, v) => p + v.osdfByteTransferCount, 0));
+ Count("project-osdf-objects", objects, 100)
+ Count("project-osdf-bytes", formatBytes(bytes), 100)
+ }
+
+ async updateInstitutionPieChart(_) {
+ throw new Error("updateInstitutionPieChart not implemented for OSDFProjectDisplay")
+ }
+}
+
+export { OSDFProjectDisplay };
+export default ProjectDisplay;
\ No newline at end of file
diff --git a/assets/js/osdf-project-page-v6.js b/assets/js/osdf-project-page-v6.js
index beb2d7b5c..d0e665fe3 100644
--- a/assets/js/osdf-project-page-v6.js
+++ b/assets/js/osdf-project-page-v6.js
@@ -13,6 +13,7 @@ import {
localeIntToInt, byteStringToBytes
} from "./util.js";
import Color from "https://colorjs.io/dist/color.js";
+import {OSDFProjectDisplay} from "./components/ProjectDisplay.mjs";
import {PieChart} from "./components/pie-chart.js";
import Search from "./Search.mjs";
@@ -39,13 +40,14 @@ class ProjectCount {
}
class Table {
- constructor(wrapper, data_function){
+ constructor(wrapper, data_function, updateProjectDisplay){
let table = this;
this.grid = undefined
this.data_function = data_function
this.wrapper = wrapper
+ this.updateProjectDisplay = updateProjectDisplay
this.columns = [
{
id: 'projectName',
@@ -122,6 +124,7 @@ class Table {
}
}
}).render(table.wrapper);
+ this.grid.on('rowClick', this.row_click);
}
update = async () => {
let table = this
@@ -129,6 +132,12 @@ class Table {
data: Object.values(await table.data_function()).sort((a, b) => b.osdfFileTransferCount - a.osdfFileTransferCount)
}).forceRender();
}
+ row_click = async (PointerEvent, e) => {
+ let data = await this.data_function();
+ let row_name = e["cells"][0].data
+ let project = data[row_name]
+ this.updateProjectDisplay(project)
+ }
}
class DataManager {
@@ -169,16 +178,37 @@ class DataManager {
}
}
- _getData = async () => {
+ _fetch = async (url, options = {}) => {
+ try {
+ let response = await fetch(url, options)
+
+ if(!response.ok){
+ throw new Error(response.statusText)
+ }
+
+ return response.json()
+
+ } catch(error) {
+ this.error = "Error fetching usage data, learn more on the OSG status page: status.osg-htc.org"
+ }
+ }
+ _getData = async () => {
+ let topologyData = await this._fetch("https://topology.opensciencegrid.org/miscproject/json")
let usageJson;
+
try {
usageJson = await getProjects()
} catch(e) {
this.error = "Error fetching usage data, learn more on the status page: status.osg-htc.org"
}
- this.data = usageJson
+ this.data = Object.entries(topologyData).reduce((p, [k,v]) => {
+ if(k in usageJson){
+ p[k] = {...v, ...usageJson[k]}
+ }
+ return p
+ }, {})
return this.data
}
@@ -232,8 +262,11 @@ class ProjectPage{
this.mode = undefined
this.dataManager = new DataManager()
+ let projectDisplayNode = document.getElementById("project-display")
+ this.projectDisplay = new OSDFProjectDisplay(projectDisplayNode)
+
this.wrapper = document.getElementById("wrapper")
- this.table = new Table(this.wrapper, this.dataManager.getFilteredData)
+ this.table = new Table(this.wrapper, this.dataManager.getFilteredData, this.projectDisplay.update.bind(this.projectDisplay))
this.dataManager.consumerToggles.push(this.table.update)
this.search = new Search(Object.values(await this.dataManager.getData()), this.dataManager.toggleConsumers)
@@ -261,12 +294,18 @@ class ProjectPage{
this.filePieChart = new PieChart(
"project-file-summary",
this.dataManager.reduceByKey.bind(this.dataManager, "projectName", "osdfFileTransferCount"),
- "# of Objects Transferred by Project"
+ "# of Objects Transferred by Project",
+ ({label, value}) => {
+ this.table.updateProjectDisplay(this.dataManager.data[label])
+ }
)
this.bytePieChart = new PieChart(
"project-byte-summary",
this.dataManager.reduceByKey.bind(this.dataManager, "projectName", "osdfByteTransferCount"),
- "# of Bytes Transferred by Project"
+ "# of Bytes Transferred by Project",
+ ({label, value}) => {
+ this.table.updateProjectDisplay(this.dataManager.data[label])
+ }
)
this.dataManager.consumerToggles.push(this.fosFilePieChart.update)