Skip to content

Commit

Permalink
Merge pull request #2153 from ujh/refactor-clustering-app
Browse files Browse the repository at this point in the history
Refactor clustering app
  • Loading branch information
ujh authored Apr 23, 2024
2 parents dde8203 + 77e251a commit 0cc1c5f
Show file tree
Hide file tree
Showing 18 changed files with 339 additions and 100 deletions.
2 changes: 1 addition & 1 deletion app/javascript/src/admin/graphs/BotSignUps.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react";
import Highcharts from "highcharts";
import HighchartsReact from "highcharts-react-official";

import { Spinner } from "../micro-clusters/Spinner";
import { Spinner } from "../components/Spinner";

export const BotSignUps = () => {
const [data, setData] = useState(null);
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/src/admin/graphs/CollectedInks.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react";
import Highcharts from "highcharts";
import HighchartsReact from "highcharts-react-official";

import { Spinner } from "../micro-clusters/Spinner";
import { Spinner } from "../components/Spinner";

export const CollectedInks = () => {
const [data, setData] = useState(null);
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/src/admin/graphs/CollectedPens.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react";
import Highcharts from "highcharts";
import HighchartsReact from "highcharts-react-official";

import { Spinner } from "../micro-clusters/Spinner";
import { Spinner } from "../components/Spinner";

export const CollectedPens = () => {
const [data, setData] = useState(null);
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/src/admin/graphs/CurrentlyInked.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react";
import Highcharts from "highcharts";
import HighchartsReact from "highcharts-react-official";

import { Spinner } from "../micro-clusters/Spinner";
import { Spinner } from "../components/Spinner";

export const CurrentlyInked = () => {
const [data, setData] = useState(null);
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/src/admin/graphs/SignUps.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react";
import Highcharts from "highcharts";
import HighchartsReact from "highcharts-react-official";

import { Spinner } from "../micro-clusters/Spinner";
import { Spinner } from "../components/Spinner";

export const SignUps = () => {
const [data, setData] = useState(null);
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/src/admin/graphs/UsageRecords.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react";
import Highcharts from "highcharts";
import HighchartsReact from "highcharts-react-official";

import { Spinner } from "../micro-clusters/Spinner";
import { Spinner } from "../components/Spinner";

export const UsageRecords = () => {
const [data, setData] = useState(null);
Expand Down
91 changes: 5 additions & 86 deletions app/javascript/src/admin/micro-clusters/App.jsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
import React, { useEffect, useReducer, useContext } from "react";
import Select from "react-select";
import _ from "lodash";
import Jsona from "jsona";

import { getRequest } from "../../fetch";
import { Spinner } from "./Spinner";
import { Spinner } from "../components/Spinner";
import { DisplayMicroClusters } from "./DisplayMicroClusters";
import { reducer, initalState } from "./reducer";
import {
SET_LOADING_PERCENTAGE,
SET_MACRO_CLUSTERS,
SET_MICRO_CLUSTERS,
UPDATE_SELECTED_BRANDS
} from "./actions";
import { setInBrandSelector } from "./keyDownListener";
import { reducer, initalState } from "../components/clustering/reducer";
import { UPDATE_SELECTED_BRANDS } from "../components/clustering/actions";
import { setInBrandSelector } from "../components/clustering/keyDownListener";
import { loadMacroClusters, loadMicroClusters } from "./loadClusters";

export const StateContext = React.createContext();
export const DispatchContext = React.createContext();
Expand Down Expand Up @@ -114,78 +108,3 @@ const BrandSelector = () => {
</div>
);
};
const loadMicroClusters = (dispatch) => {
const formatter = new Jsona();
let data = [];
function run(page = 1) {
loadMicroClusterPage(page).then((json) => {
const next_page = json.meta.pagination.next_page;
// Remove clusters without collected inks
// Group collected inks
const pageData = formatter
.deserialize(json)
.filter((c) => c.collected_inks.length > 0)
.map((c) => {
const grouped_collected_inks = groupedInks(c.collected_inks);
return { ...c, grouped_collected_inks };
});
data = [...data, ...pageData];
if (next_page) {
run(next_page);
} else {
dispatch({ type: SET_MICRO_CLUSTERS, payload: data });
}
});
}
run();
};

const loadMicroClusterPage = (page) => {
return getRequest(
`/admins/micro_clusters.json?unassigned=true&without_ignored=true&page=${page}`
).then((response) => response.json());
};

const loadMacroClusters = (dispatch) => {
let data = [];
const formatter = new Jsona();
function run(page = 1) {
loadMacroClusterPage(page).then((json) => {
const pagination = json.meta.pagination;
dispatch({
type: SET_LOADING_PERCENTAGE,
payload: (pagination.current_page * 100) / pagination.total_pages
});
const next_page = json.meta.pagination.next_page;
const pageData = formatter.deserialize(json).map((c) => {
const grouped_collected_inks = groupedInks(
c.micro_clusters.map((c) => c.collected_inks).flat()
);
return { ...c, grouped_collected_inks };
});
data = [...data, ...pageData];
if (next_page) {
run(next_page);
} else {
dispatch({ type: SET_MACRO_CLUSTERS, payload: data });
}
});
}
run();
};

const loadMacroClusterPage = (page) => {
return getRequest(`/admins/macro_clusters.json?page=${page}`).then(
(response) => response.json()
);
};

export const groupedInks = (collectedInks) =>
_.values(
_.mapValues(
_.groupBy(collectedInks, (ci) =>
["brand_name", "line_name", "ink_name"].map((n) => ci[n]).join(",")
),
(cis) => cis[0]
)
);
11 changes: 8 additions & 3 deletions app/javascript/src/admin/micro-clusters/CreateRow.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import React, { useCallback, useContext, useEffect } from "react";
import _ from "lodash";
import { postRequest, putRequest } from "../../fetch";
import { StateContext, DispatchContext, groupedInks } from "./App";
import { UPDATING, ADD_MACRO_CLUSTER, REMOVE_MICRO_CLUSTER } from "./actions";
import { StateContext, DispatchContext } from "./App";
import { groupedInks } from "./groupedInks";
import {
UPDATING,
ADD_MACRO_CLUSTER,
REMOVE_MICRO_CLUSTER
} from "../components/clustering/actions";
import { assignCluster } from "./assignCluster";
import { keyDownListener } from "./keyDownListener";
import { keyDownListener } from "../components/clustering/keyDownListener";

export const CreateRow = ({ afterCreate }) => {
const { updating, activeCluster } = useContext(StateContext);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ import {
NEXT_MACRO_CLUSTER,
PREVIOUS_MACRO_CLUSTER,
UPDATING
} from "./actions";
import { keyDownListener, setInBrandSelector } from "./keyDownListener";
} from "../components/clustering/actions";
import {
keyDownListener,
setInBrandSelector
} from "../components/clustering/keyDownListener";
import { useCallback } from "react";

export const DisplayMacroClusters = ({ afterAssign }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import Jsona from "jsona";

import { getRequest } from "../../fetch";
import { DisplayMicroCluster } from "./DisplayMicroCluster";
import { DispatchContext, groupedInks, StateContext } from "./App";
import { DispatchContext, StateContext } from "./App";
import { groupedInks } from "./groupedInks";
import {
PREVIOUS,
NEXT,
REMOVE_MICRO_CLUSTER,
UPDATE_MACRO_CLUSTER
} from "./actions";
import { keyDownListener } from "./keyDownListener";
} from "../components/clustering/actions";
import { keyDownListener } from "../components/clustering/keyDownListener";
import { useCallback } from "react";

export const DisplayMicroClusters = () => {
Expand Down
11 changes: 11 additions & 0 deletions app/javascript/src/admin/micro-clusters/groupedInks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import _ from "lodash";

export const groupedInks = (collectedInks) =>
_.values(
_.mapValues(
_.groupBy(collectedInks, (ci) =>
["brand_name", "line_name", "ink_name"].map((n) => ci[n]).join(",")
),
(cis) => cis[0]
)
);
15 changes: 15 additions & 0 deletions app/javascript/src/admin/micro-clusters/groupedInks.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { groupedInks } from "./groupedInks";

describe("groupedInks", () => {
it("returns only unique inks", () => {
const inks = [
{ brand_name: "brand1", line_name: "line1", ink_name: "ink1" },
{ brand_name: "brand1", line_name: "line1", ink_name: "ink1" },
{ brand_name: "brand2", line_name: "line1", ink_name: "ink1" }
];
expect(groupedInks(inks)).toStrictEqual([
{ brand_name: "brand1", line_name: "line1", ink_name: "ink1" },
{ brand_name: "brand2", line_name: "line1", ink_name: "ink1" }
]);
});
});
75 changes: 75 additions & 0 deletions app/javascript/src/admin/micro-clusters/loadClusters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import Jsona from "jsona";

import { getRequest } from "../../fetch";
import {
SET_LOADING_PERCENTAGE,
SET_MACRO_CLUSTERS,
SET_MICRO_CLUSTERS
} from "../components/clustering/actions";
import { groupedInks } from "./groupedInks";

export const loadMicroClusters = (dispatch) => {
const formatter = new Jsona();
let data = [];
function run(page = 1) {
loadMicroClusterPage(page).then((json) => {
const next_page = json.meta.pagination.next_page;
// Remove clusters without collected inks
// Group collected inks
const pageData = formatter
.deserialize(json)
.filter((c) => c.collected_inks.length > 0)
.map((c) => {
const grouped_collected_inks = groupedInks(c.collected_inks);
return { ...c, grouped_collected_inks };
});
data = [...data, ...pageData];
if (next_page) {
run(next_page);
} else {
dispatch({ type: SET_MICRO_CLUSTERS, payload: data });
}
});
}
run();
};

const loadMicroClusterPage = (page) => {
return getRequest(
`/admins/micro_clusters.json?unassigned=true&without_ignored=true&page=${page}`
).then((response) => response.json());
};

export const loadMacroClusters = (dispatch) => {
let data = [];
const formatter = new Jsona();
function run(page = 1) {
loadMacroClusterPage(page).then((json) => {
const pagination = json.meta.pagination;
dispatch({
type: SET_LOADING_PERCENTAGE,
payload: (pagination.current_page * 100) / pagination.total_pages
});
const next_page = json.meta.pagination.next_page;
const pageData = formatter.deserialize(json).map((c) => {
const grouped_collected_inks = groupedInks(
c.micro_clusters.map((c) => c.collected_inks).flat()
);
return { ...c, grouped_collected_inks };
});
data = [...data, ...pageData];
if (next_page) {
run(next_page);
} else {
dispatch({ type: SET_MACRO_CLUSTERS, payload: data });
}
});
}
run();
};

const loadMacroClusterPage = (page) => {
return getRequest(`/admins/macro_clusters.json?page=${page}`).then(
(response) => response.json()
);
};
Loading

0 comments on commit 0cc1c5f

Please sign in to comment.