TS migration. #2288. (#2328)

* Added TS. Updated build and linting config. Added types.

* [ts-migrate][.] Rename files from JS/JSX to TS/TSX

Co-authored-by: ts-migrate <>

* [ts-migrate][.] Run TS Migrate

Co-authored-by: ts-migrate <>

* Corrected files mangled by ts-migrate.

* Updated lint config, minor linting.

* Re-enabled Husky.

* Updated tests and config.

* Reverted webpack devtool config.

* Removed obsolete snapshots.

* Added annotations snap.

* Updated tsconfig includes wrt linting.

* Removed ts-migrate.

Co-authored-by: Timmy Huang <tihuan@users.noreply.github.com>
This commit is contained in:
Mim Hastie
2021-07-26 20:18:17 +00:00
committed by GitHub
co-authored by ts-migrate Timmy Huang
parent 7328cbdbd5
commit 934cc5c69b
206 changed files with 4719 additions and 2085 deletions
@@ -18,12 +18,17 @@ import {
import { appUrlBase, TEST_EMAIL, TEST_PASSWORD } from "./config";
export async function drag(testId, start, end, lasso = false) {
export async function drag(testId: any, start: any, end: any, lasso = false) {
const layout = await waitByID(testId);
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
const elBox = await layout.boxModel();
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
const x1 = elBox.content[0].x + start.x;
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
const x2 = elBox.content[0].x + end.x;
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
const y1 = elBox.content[0].y + start.y;
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
const y2 = elBox.content[0].y + end.y;
await page.mouse.move(x1, y1);
await page.mouse.down();
@@ -38,7 +43,7 @@ export async function drag(testId, start, end, lasso = false) {
await page.mouse.up();
}
export async function clickOnCoordinate(testId, coord) {
export async function clickOnCoordinate(testId: any, coord: any) {
const layout = await expect(page).toMatchElement(getTestId(testId));
const elBox = await layout.boxModel();
@@ -51,11 +56,12 @@ export async function clickOnCoordinate(testId, coord) {
await page.mouse.click(x, y);
}
export async function getAllHistograms(testclass, testIds) {
const histTestIds = testIds.map((tid) => `histogram-${tid}`);
export async function getAllHistograms(testclass: any, testIds: any) {
const histTestIds = testIds.map((tid: any) => `histogram-${tid}`);
// these load asynchronously, so we need to wait for each histogram individually,
// and they may be quite slow in some cases.
// @ts-expect-error ts-migrate(2554) FIXME: Expected 1 arguments, but got 2.
await waitForAllByIds(histTestIds, { timeout: 4 * 60 * 1000 });
const allHistograms = await getAllByClass(testclass);
@@ -71,7 +77,7 @@ export async function getAllHistograms(testclass, testIds) {
return testIDs.map((id) => id.replace(/^histogram-/, ""));
}
export async function getAllCategoriesAndCounts(category) {
export async function getAllCategoriesAndCounts(category: any) {
// these load asynchronously, so we have to wait for the specific category.
await waitByID(`category-${category}`);
@@ -80,13 +86,14 @@ export async function getAllCategoriesAndCounts(category) {
(rows) =>
Object.fromEntries(
rows.map((row) => {
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
const cat = row
.querySelector("[data-testclass='categorical-value']")
.getAttribute("aria-label");
const count = row.querySelector(
const count = (row.querySelector(
"[data-testclass='categorical-value-count']"
).innerText;
) as any).innerText;
return [cat, count];
})
@@ -94,12 +101,12 @@ export async function getAllCategoriesAndCounts(category) {
);
}
export async function getCellSetCount(num) {
export async function getCellSetCount(num: any) {
await clickOn(`cellset-button-${num}`);
return getOneElementInnerText(`[data-testid='cellset-count-${num}']`);
}
export async function resetCategory(category) {
export async function resetCategory(category: any) {
const checkboxId = `${category}:category-select`;
await waitByID(checkboxId);
const checkedPseudoclass = await page.$eval(
@@ -110,6 +117,7 @@ export async function resetCategory(category) {
const categoryRow = await waitByID(`${category}:category-expand`);
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
const isExpanded = await categoryRow.$(
"[data-testclass='category-expand-is-expanded']"
);
@@ -117,16 +125,26 @@ export async function resetCategory(category) {
if (isExpanded) await clickOn(`${category}:category-expand`);
}
export async function calcCoordinate(testId, xAsPercent, yAsPercent) {
export async function calcCoordinate(
testId: any,
xAsPercent: any,
yAsPercent: any
) {
const el = await waitByID(testId);
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
const size = await el.boxModel();
return {
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
x: Math.floor(size.width * xAsPercent),
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
y: Math.floor(size.height * yAsPercent),
};
}
export async function calcDragCoordinates(testId, coordinateAsPercent) {
export async function calcDragCoordinates(
testId: any,
coordinateAsPercent: any
) {
return {
start: await calcCoordinate(
testId,
@@ -141,7 +159,7 @@ export async function calcDragCoordinates(testId, coordinateAsPercent) {
};
}
export async function selectCategory(category, values, reset = true) {
export async function selectCategory(category: any, values: any, reset = true) {
if (reset) await resetCategory(category);
await clickOn(`${category}:category-expand`);
@@ -152,8 +170,9 @@ export async function selectCategory(category, values, reset = true) {
}
}
export async function expandCategory(category) {
export async function expandCategory(category: any) {
const expand = await waitByID(`${category}:category-expand`);
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
const notExpanded = await expand.$(
"[data-testclass='category-expand-is-not-expanded']"
);
@@ -167,7 +186,7 @@ export async function clip(min = 0, max = 100) {
await clickOn("clip-commit");
}
export async function createCategory(categoryName) {
export async function createCategory(categoryName: any) {
await clickOnUntil("open-annotation-dialog", async () => {
await expect(page).toMatchElement(getTestId("new-category-name"));
});
@@ -182,17 +201,18 @@ export async function createCategory(categoryName) {
*/
export async function colorByGeneset(genesetName) {
export async function colorByGeneset(genesetName: any) {
await clickOn(`${genesetName}:colorby-entire-geneset`);
}
export async function colorByGene(gene) {
export async function colorByGene(gene: any) {
await clickOn(`colorby-${gene}`);
}
export async function assertColorLegendLabel(label) {
export async function assertColorLegendLabel(label: any) {
const handle = await waitByID("continuous_legend_color_by_label");
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
const result = await handle.evaluate((node) => {
return node.getAttribute("aria-label");
});
@@ -200,15 +220,16 @@ export async function assertColorLegendLabel(label) {
return expect(result).toBe(label);
}
export async function expandGeneset(genesetName) {
export async function expandGeneset(genesetName: any) {
const expand = await waitByID(`${genesetName}:geneset-expand`);
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
const notExpanded = await expand.$(
"[data-testclass='geneset-expand-is-not-expanded']"
);
if (notExpanded) await clickOn(`${genesetName}:geneset-expand`);
}
export async function createGeneset(genesetName) {
export async function createGeneset(genesetName: any) {
await clickOnUntil("open-create-geneset-dialog", async () => {
await expect(page).toMatchElement(getTestId("create-geneset-input"));
});
@@ -218,7 +239,7 @@ export async function createGeneset(genesetName) {
await waitByClass("autosave-complete");
}
export async function editGenesetName(genesetName, editText) {
export async function editGenesetName(genesetName: any, editText: any) {
const editButton = `${genesetName}:edit-genesetName-mode`;
const submitButton = `${genesetName}:submit-geneset`;
await clickOnUntil(`${genesetName}:see-actions`, async () => {
@@ -229,7 +250,7 @@ export async function editGenesetName(genesetName, editText) {
await clickOn(submitButton);
}
export async function deleteGeneset(genesetName) {
export async function deleteGeneset(genesetName: any) {
const targetId = `${genesetName}:delete-geneset`;
await clickOnUntil(`${genesetName}:see-actions`, async () => {
@@ -242,16 +263,18 @@ export async function deleteGeneset(genesetName) {
await waitByClass("autosave-complete");
}
export async function assertGenesetDoesNotExist(genesetName) {
export async function assertGenesetDoesNotExist(genesetName: any) {
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
const result = await isElementPresent(
getTestId(`${genesetName}:geneset-name`)
);
await expect(result).toBe(false);
}
export async function assertGenesetExists(genesetName) {
export async function assertGenesetExists(genesetName: any) {
const handle = await waitByID(`${genesetName}:geneset-name`);
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
const result = await handle.evaluate((node) => {
return node.getAttribute("aria-label");
});
@@ -265,7 +288,7 @@ export async function assertGenesetExists(genesetName) {
*/
export async function addGeneToSet(genesetName, geneToAddToSet) {
export async function addGeneToSet(genesetName: any, geneToAddToSet: any) {
const submitButton = `${genesetName}:submit-gene`;
await clickOn(`${genesetName}:add-new-gene-to-geneset`);
@@ -273,7 +296,7 @@ export async function addGeneToSet(genesetName, geneToAddToSet) {
await clickOn(submitButton);
}
export async function removeGene(geneSymbol) {
export async function removeGene(geneSymbol: any) {
const targetId = `delete-from-geneset:${geneSymbol}`;
await clickOn(targetId);
@@ -281,9 +304,10 @@ export async function removeGene(geneSymbol) {
await waitByClass("autosave-complete");
}
export async function assertGeneExistsInGeneset(geneSymbol) {
export async function assertGeneExistsInGeneset(geneSymbol: any) {
const handle = await waitByID(`${geneSymbol}:gene-label`);
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
const result = await handle.evaluate((node) => {
return node.getAttribute("aria-label");
});
@@ -291,13 +315,14 @@ export async function assertGeneExistsInGeneset(geneSymbol) {
return expect(result).toBe(geneSymbol);
}
export async function assertGeneDoesNotExist(geneSymbol) {
export async function assertGeneDoesNotExist(geneSymbol: any) {
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
const result = await isElementPresent(getTestId(`${geneSymbol}:gene-label`));
await expect(result).toBe(false);
}
export async function expandGene(geneSymbol) {
export async function expandGene(geneSymbol: any) {
await clickOn(`maximize-${geneSymbol}`);
}
@@ -307,7 +332,7 @@ export async function expandGene(geneSymbol) {
*/
export async function duplicateCategory(categoryName) {
export async function duplicateCategory(categoryName: any) {
await clickOn("open-annotation-dialog");
await typeInto("new-category-name", categoryName);
@@ -333,7 +358,10 @@ export async function duplicateCategory(categoryName) {
await waitByClass("autosave-complete");
}
export async function renameCategory(oldCategoryName, newCategoryName) {
export async function renameCategory(
oldCategoryName: any,
newCategoryName: any
) {
await clickOn(`${oldCategoryName}:see-actions`);
await clickOn(`${oldCategoryName}:edit-category-mode`);
await clearInputAndTypeInto(
@@ -343,7 +371,7 @@ export async function renameCategory(oldCategoryName, newCategoryName) {
await clickOn(`${oldCategoryName}:submit-category-edit`);
}
export async function deleteCategory(categoryName) {
export async function deleteCategory(categoryName: any) {
const targetId = `${categoryName}:delete-category`;
await clickOnUntil(`${categoryName}:see-actions`, async () => {
@@ -352,10 +380,11 @@ export async function deleteCategory(categoryName) {
await clickOn(targetId);
// @ts-expect-error ts-migrate(2554) FIXME: Expected 1 arguments, but got 0.
await assertCategoryDoesNotExist();
}
export async function createLabel(categoryName, labelName) {
export async function createLabel(categoryName: any, labelName: any) {
/**
* (thuang): This explicit wait is needed, since currently showing
* the modal again quickly after the previous action dismissing the
@@ -380,13 +409,17 @@ export async function createLabel(categoryName, labelName) {
await clickOn(`${categoryName}:submit-label`);
}
export async function deleteLabel(categoryName, labelName) {
export async function deleteLabel(categoryName: any, labelName: any) {
await expandCategory(categoryName);
await clickOn(`${categoryName}:${labelName}:see-actions`);
await clickOn(`${categoryName}:${labelName}:delete-label`);
}
export async function renameLabel(categoryName, oldLabelName, newLabelName) {
export async function renameLabel(
categoryName: any,
oldLabelName: any,
newLabelName: any
) {
await expandCategory(categoryName);
await clickOn(`${categoryName}:${oldLabelName}:see-actions`);
await clickOn(`${categoryName}:${oldLabelName}:edit-label`);
@@ -397,13 +430,13 @@ export async function renameLabel(categoryName, oldLabelName, newLabelName) {
await clickOn(`${categoryName}:${oldLabelName}:submit-label-edit`);
}
export async function addGeneToSearch(geneName) {
export async function addGeneToSearch(geneName: any) {
await typeInto("gene-search", geneName);
await page.keyboard.press("Enter");
await page.waitForSelector(`[data-testid='histogram-${geneName}']`);
}
export async function subset(coordinatesAsPercent) {
export async function subset(coordinatesAsPercent: any) {
// In order to deselect the selection after the subset, make sure we have some clear part
// of the scatterplot we can click on
assert(coordinatesAsPercent.x2 < 0.99 || coordinatesAsPercent.y2 < 0.99);
@@ -417,8 +450,8 @@ export async function subset(coordinatesAsPercent) {
await clickOnCoordinate("layout-graph", clearCoordinate);
}
export async function setSellSet(cellSet, cellSetNum) {
const selections = cellSet.filter((sel) => sel.kind === "categorical");
export async function setSellSet(cellSet: any, cellSetNum: any) {
const selections = cellSet.filter((sel: any) => sel.kind === "categorical");
for (const selection of selections) {
await selectCategory(selection.metadata, selection.values, true);
@@ -427,19 +460,20 @@ export async function setSellSet(cellSet, cellSetNum) {
await getCellSetCount(cellSetNum);
}
export async function runDiffExp(cellSet1, cellSet2) {
export async function runDiffExp(cellSet1: any, cellSet2: any) {
await setSellSet(cellSet1, 1);
await setSellSet(cellSet2, 2);
await clickOn("diffexp-button");
}
export async function bulkAddGenes(geneNames) {
export async function bulkAddGenes(geneNames: any) {
await clickOn("section-bulk-add");
await typeInto("input-bulk-add", geneNames.join(","));
await page.keyboard.press("Enter");
}
export async function assertCategoryDoesNotExist(categoryName) {
export async function assertCategoryDoesNotExist(categoryName: any) {
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
const result = await isElementPresent(
getTestId(`${categoryName}:category-label`)
);
@@ -480,7 +514,7 @@ export async function logout() {
await waitByID("log-in");
}
async function waitUntilFormFieldStable(selector) {
async function waitUntilFormFieldStable(selector: any) {
const MAX_RETRY = 10;
const WAIT_FOR_MS = 200;
@@ -58,10 +58,12 @@ describe("metadata loads", () => {
const categories = await getAllCategoriesAndCounts(label);
expect(Object.keys(categories)).toMatchObject(
// @ts-expect-error ts-migrate(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
Object.keys(data.categorical[label])
);
expect(Object.values(categories)).toMatchObject(
// @ts-expect-error ts-migrate(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
Object.values(data.categorical[label])
);
}
@@ -159,10 +161,12 @@ describe("subset", () => {
const categories = await getAllCategoriesAndCounts(label);
expect(Object.keys(categories)).toMatchObject(
// @ts-expect-error ts-migrate(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
Object.keys(data.subset.categorical[label])
);
expect(Object.values(categories)).toMatchObject(
// @ts-expect-error ts-migrate(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
Object.values(data.subset.categorical[label])
);
}
@@ -195,6 +199,7 @@ describe("clipping", () => {
test("clip continuous", async () => {
await goToPage(appUrlBase);
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string' is not assignable to par... Remove this comment to see the full error message
await clip(data.clip.min, data.clip.max);
const histBrushableAreaId = `histogram-${data.clip.metadata}-plot-brushable-area`;
const coords = await calcDragCoordinates(
@@ -254,6 +259,7 @@ describe("centroid labels", () => {
const generatedLabels = await getAllByClass("centroid-label");
// Number of labels generated should be equal to size of the object
expect(generatedLabels).toHaveLength(
// @ts-expect-error ts-migrate(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
Object.keys(data.categorical[label]).length
);
}
@@ -275,6 +281,7 @@ describe("graph overlay", () => {
data.pan["coordinates-as-percent"]
);
// @ts-expect-error ts-migrate(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
const categoryValue = Object.keys(data.categorical[category])[0];
const initialCoordinates = await getElementCoordinates(
`${categoryValue}-centroid-label`
@@ -76,7 +76,7 @@ const brushThisGeneGeneset = "brush_this_gene";
const geneBrushedCellCount = "109";
const subsetGeneBrushedCellCount = "96";
async function setup(config) {
async function setup(config: any) {
await goToPage(appUrlBase);
if (config.categoricalAnno) {
@@ -150,7 +150,7 @@ describe.each([
await expect(page).toClick(getTestClass("pop-1-geneset-expand"));
await page.waitForFunction(
(selector) => !document.querySelector(selector),
(selector: any) => !document.querySelector(selector),
{},
getTestClass("gene-loading-spinner")
);
@@ -165,7 +165,7 @@ describe.each([
await expect(page).toClick(getTestClass("pop-2-geneset-expand"));
await page.waitForFunction(
(selector) => !document.querySelector(selector),
(selector: any) => !document.querySelector(selector),
{},
getTestClass("gene-loading-spinner")
);
@@ -362,8 +362,11 @@ describe.each([
expect(actualLabelName).toBe(expectedLabelName);
expect(actualLabelCount).toBe(expectedLabelCount);
async function getInnerText(element, className) {
return element.$eval(getTestClass(className), (node) => node?.innerText);
async function getInnerText(element: any, className: any) {
return element.$eval(
getTestClass(className),
(node: any) => node?.innerText
);
}
});
@@ -388,7 +391,9 @@ describe.each([
`categorical-value-count-${perTestCategoryName}-${perTestLabelName}`
);
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
expect(await result.evaluate((node) => node.innerText)).toBe(
// @ts-expect-error ts-migrate(2538) FIXME: Type 'boolean' cannot be used as an index type.
data.categoryLabel.newCount.bySubsetConfig[config.withSubset]
);
});
@@ -448,6 +453,7 @@ describe.each([
await createLabel(perTestCategoryName, labelName);
await assertLabelExists(perTestCategoryName, labelName);
await clickOn("undo");
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
await assertLabelDoesNotExist(perTestCategoryName);
await clickOn("redo");
await assertLabelExists(perTestCategoryName, labelName);
@@ -457,10 +463,12 @@ describe.each([
await setup(config);
await deleteLabel(perTestCategoryName, perTestLabelName);
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
await assertLabelDoesNotExist(perTestCategoryName);
await clickOn("undo");
await assertLabelExists(perTestCategoryName, perTestLabelName);
await clickOn("redo");
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
await assertLabelDoesNotExist(perTestCategoryName);
});
@@ -523,9 +531,10 @@ describe.each([
expect(result).toMatchSnapshot();
});
async function assertCategoryExists(categoryName) {
async function assertCategoryExists(categoryName: any) {
const handle = await waitByID(`${categoryName}:category-label`);
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
const result = await handle.evaluate((node) =>
node.getAttribute("aria-label")
);
@@ -533,7 +542,7 @@ describe.each([
return expect(result).toBe(categoryName);
}
async function assertLabelExists(categoryName, labelName) {
async function assertLabelExists(categoryName: any, labelName: any) {
await expect(page).toMatchElement(
getTestId(`${categoryName}:category-expand`)
);
@@ -545,11 +554,12 @@ describe.each([
);
expect(
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
await previous.evaluate((node) => node.getAttribute("aria-label"))
).toBe(labelName);
}
async function assertLabelDoesNotExist(categoryName, labelName) {
async function assertLabelDoesNotExist(categoryName: any, labelName: any) {
await expandCategory(categoryName);
const result = await page.$(
`[data-testid='categorical-value-${categoryName}-${labelName}']`
+4 -4
View File
@@ -1,10 +1,10 @@
{
"testRunner": "jest-circus/runner",
"preset": "jest-puppeteer",
"testMatch": ["**/__tests__/**/?(*.)(spec|test).js?(x)"],
"setupFiles": ["../setupMissingGlobals.js"],
"setupFilesAfterEnv": ["expect-puppeteer", "./puppeteer.setup.js"],
"globalSetup": "../globalSetup.js",
"testMatch": ["**/__tests__/**/?(*.)(spec|test).ts?(x)"],
"setupFiles": ["../setupMissingGlobals.ts"],
"setupFilesAfterEnv": ["expect-puppeteer", "./puppeteer.setup.ts"],
"globalSetup": "../globalSetup.ts",
"globalTeardown": "jest-environment-puppeteer/teardown",
"testEnvironment": "./screenshot_env.js"
}
@@ -23,6 +23,7 @@ beforeEach(async () => {
const userAgent = await browser.userAgent();
await page.setUserAgent(`${userAgent}bot`);
// @ts-expect-error ts-migrate(2341) FIXME: Property '_client' is private and only accessible ... Remove this comment to see the full error message
await page._client.send("Animation.setPlaybackRate", { playbackRate: 12 });
page.on("pageerror", (err) => {
@@ -49,7 +50,7 @@ beforeEach(async () => {
}
const errorMsgText = await Promise.all(
// TODO can we do this without internal properties?
msg.args().map((arg) => arg._remoteObject.description)
msg.args().map((arg: any) => arg._remoteObject.description)
);
throw new Error(`Console error: ${errorMsgText}`);
}
@@ -1,31 +1,31 @@
/* eslint-disable no-await-in-loop -- await in loop is needed to emulate sequential user actions */
export function getTestId(id) {
export function getTestId(id: any) {
return `[data-testid='${id}']`;
}
export function getTestClass(className) {
export function getTestClass(className: any) {
return `[data-testclass='${className}']`;
}
export async function waitByID(testId, props = {}) {
export async function waitByID(testId: any, props = {}) {
return page.waitForSelector(getTestId(testId), props);
}
export async function waitByClass(testClass, props = {}) {
export async function waitByClass(testClass: any, props = {}) {
return page.waitForSelector(`[data-testclass='${testClass}']`, props);
}
export async function waitForAllByIds(testIds) {
export async function waitForAllByIds(testIds: any) {
await Promise.all(
testIds.map((testId) => page.waitForSelector(getTestId(testId)))
testIds.map((testId: any) => page.waitForSelector(getTestId(testId)))
);
}
export async function getAllByClass(testClass) {
export async function getAllByClass(testClass: any) {
return page.$$(`[data-testclass=${testClass}]`);
}
export async function typeInto(testId, text) {
export async function typeInto(testId: any, text: any) {
// blueprint's typeahead is treating typing weird, clicking & waiting first solves this
// only works for text without special characters
await waitByID(testId);
@@ -36,7 +36,7 @@ export async function typeInto(testId, text) {
await page.type(selector, text);
}
export async function clearInputAndTypeInto(testId, text) {
export async function clearInputAndTypeInto(testId: any, text: any) {
await waitByID(testId);
const selector = getTestId(testId);
// only works for text without special characters
@@ -49,7 +49,7 @@ export async function clearInputAndTypeInto(testId, text) {
await page.type(selector, text);
}
export async function clickOn(testId, options = {}) {
export async function clickOn(testId: any, options = {}) {
await expect(page).toClick(getTestId(testId), options);
}
@@ -57,7 +57,7 @@ export async function clickOn(testId, options = {}) {
* (thuang): There are times when Puppeteer clicks on a button and the page doesn't respond.
* So I added clickOnUntil() to retry clicking until a given condition is met.
*/
export async function clickOnUntil(testId, assert) {
export async function clickOnUntil(testId: any, assert: any) {
const MAX_RETRY = 10;
const WAIT_FOR_MS = 200;
@@ -81,19 +81,19 @@ export async function clickOnUntil(testId, assert) {
}
}
export async function getOneElementInnerHTML(selector, options = {}) {
export async function getOneElementInnerHTML(selector: any, options = {}) {
await page.waitForSelector(selector, options);
return page.$eval(selector, (el) => el.innerHTML);
}
export async function getOneElementInnerText(selector) {
export async function getOneElementInnerText(selector: any) {
expect(page).toMatchElement(selector);
return page.$eval(selector, (el) => el.innerText);
return page.$eval(selector, (el) => (el as any).innerText);
}
export async function getElementCoordinates(testId) {
export async function getElementCoordinates(testId: any) {
return page.$eval(getTestId(testId), (elem) => {
const { left, top } = elem.getBoundingClientRect();
return [left, top];
@@ -101,12 +101,14 @@ export async function getElementCoordinates(testId) {
}
async function clickTermsOfService() {
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
if (!(await isElementPresent(getTestId("tos-cookies-accept")))) return;
await clickOn("tos-cookies-accept");
}
async function nameNewAnnotation() {
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
if (await isElementPresent(getTestId("annotation-dialog"))) {
await typeInto("new-annotation-name", "ignoreE2E");
await clickOn("submit-annotation");
@@ -116,7 +118,7 @@ async function nameNewAnnotation() {
}
}
export async function goToPage(url) {
export async function goToPage(url: any) {
await page.goto(url, {
waitUntil: "networkidle0",
});
@@ -125,7 +127,8 @@ export async function goToPage(url) {
await clickTermsOfService();
}
export async function isElementPresent(selector, options) {
export async function isElementPresent(selector: any, options: any) {
// @ts-expect-error ts-migrate(2554) FIXME: Expected 1 arguments, but got 2.
return Boolean(await page.$(selector, options));
}
/* eslint-enable no-await-in-loop -- await in loop is needed to emulate sequential user actions */
+1
View File
@@ -2,6 +2,7 @@ const PuppeteerEnvironment = require("jest-environment-puppeteer");
require("jest-circus");
const ENV_DEFAULT = require("../../../environment.default.json");
// @ts-expect-error ts-migrate(2451) FIXME: Cannot redeclare block-scoped variable 'takeScreen... Remove this comment to see the full error message
const takeScreenshot = require("./takeScreenshot");
class ScreenshotEnvironment extends PuppeteerEnvironment {
@@ -1,3 +1,4 @@
// @ts-ignore FIXME revisit from ts-migrate
const {
SecretsManagerClient,
GetSecretValueCommand,
@@ -20,7 +20,12 @@ describe("cascade", () => {
const reducer = cascadeReducers([
[
"foo",
(currentState, action, nextSharedState, prevSharedState) => {
(
currentState: any,
action: any,
nextSharedState: any,
prevSharedState: any
) => {
expect(currentState).toBeUndefined();
expect(action).toEqual(topLevelAction);
expect(nextSharedState).toStrictEqual({});
@@ -30,7 +35,12 @@ describe("cascade", () => {
],
[
"bar",
(currentState, action, nextSharedState, prevSharedState) => {
(
currentState: any,
action: any,
nextSharedState: any,
prevSharedState: any
) => {
expect(currentState).toBeUndefined();
expect(action).toEqual(topLevelAction);
expect(nextSharedState).toStrictEqual({ foo: 0 });
@@ -501,6 +501,7 @@ describe("geneset: set tid", () => {
test("not a number error", () => {
expect(() => {
genesetsReducer(
// @ts-expect-error ts-migrate(2322) FIXME: Type 'number' is not assignable to type 'undefined... Remove this comment to see the full error message
{ lastTid: 1 },
{
type: "geneset: set tid",
@@ -513,6 +514,7 @@ describe("geneset: set tid", () => {
test("decrement error", () => {
expect(() => {
genesetsReducer(
// @ts-expect-error ts-migrate(2322) FIXME: Type 'number' is not assignable to type 'undefined... Remove this comment to see the full error message
{ lastTid: 1 },
{
type: "geneset: set tid",
@@ -2,6 +2,7 @@ import undoable from "../../src/reducers/undoable";
describe("create", () => {
test("no keys", () => {
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2-3 arguments, but got 1.
expect(() => undoable(() => {})).toThrow();
expect(() => undoable(() => {}, null)).toThrow();
expect(() => undoable(() => {}, [])).toThrow();
@@ -23,7 +24,7 @@ describe("create", () => {
describe("undo", () => {
test("expected state modifications", () => {
const initialState = { a: 0, b: 1000 };
const reducer = (state) => {
const reducer = (state: any) => {
return { a: state.a + 1, b: state.b + 1 };
};
const undoableReducer = undoable(reducer, ["a"]);
@@ -43,10 +44,10 @@ describe("undo", () => {
describe("redo", () => {
const initialState = { a: 0, b: 1000 };
const reducer = (state) => {
const reducer = (state: any) => {
return { a: state.a + 1, b: state.b + 1 };
};
let UR;
let UR: any;
beforeEach(() => {
UR = undoable(reducer, ["a"]);
@@ -5,5 +5,6 @@ the jest test environment).
import { TextDecoder, TextEncoder } from "util";
// @ts-expect-error ts-migrate(2322) FIXME: Type 'typeof TextDecoder' is not assignable to typ... Remove this comment to see the full error message
global.TextDecoder = TextDecoder;
global.TextEncoder = TextEncoder;
@@ -14,10 +14,11 @@ import { Dataframe } from "../../../src/util/dataframe";
enableFetchMocks();
describe("AnnoMatrix", () => {
let annoMatrix;
let annoMatrix: any;
beforeEach(async () => {
fetch.resetMocks(); // reset all fetch mocking state
(fetch as any).resetMocks(); // reset all fetch mocking state
// reset all fetch mocking state
annoMatrix = new AnnoMatrixLoader(
serverMocks.baseDataURL,
serverMocks.schema.schema
@@ -36,7 +37,7 @@ describe("AnnoMatrix", () => {
});
test("simple single column fetch", async () => {
fetch.once(serverMocks.annotationsObs(["name_0"]));
(fetch as any).once(serverMocks.annotationsObs(["name_0"]));
const df = await annoMatrix.fetch("obs", "name_0");
expect(df).toBeInstanceOf(Dataframe);
@@ -45,7 +46,7 @@ describe("AnnoMatrix", () => {
});
test("simple multi column fetch", async () => {
fetch
(fetch as any)
.once(serverMocks.annotationsObs(["name_0"]))
.once(serverMocks.annotationsObs(["n_genes"]));
@@ -55,9 +56,11 @@ describe("AnnoMatrix", () => {
});
describe("fetch from field", () => {
const getLastTwo = async (field) => {
const getLastTwo = async (field: any) => {
const columnNames = annoMatrix.getMatrixColumns(field).slice(-2);
fetch.mockResponses(...columnNames.map(() => serverMocks.responder));
(fetch as any).mockResponses(
...columnNames.map(() => serverMocks.responder)
);
await expect(
annoMatrix.fetch(field, columnNames)
).resolves.toBeInstanceOf(Dataframe);
@@ -70,19 +73,19 @@ describe("AnnoMatrix", () => {
test("fetch - test all query forms", async () => {
// single string is a column name
fetch.once(serverMocks.annotationsObs(["n_genes"]));
(fetch as any).once(serverMocks.annotationsObs(["n_genes"]));
await expect(annoMatrix.fetch("obs", "n_genes")).resolves.toBeInstanceOf(
Dataframe
);
// array of column names, expecting n_genes to be cached.
fetch.once(serverMocks.annotationsObs(["percent_mito"]));
(fetch as any).once(serverMocks.annotationsObs(["percent_mito"]));
await expect(
annoMatrix.fetch("obs", ["n_genes", "percent_mito"])
).resolves.toBeInstanceOf(Dataframe);
// more complex value filter query, enumerated
fetch.once(serverMocks.responder);
(fetch as any).once(serverMocks.responder);
await expect(
annoMatrix.fetch("X", {
where: {
@@ -95,7 +98,7 @@ describe("AnnoMatrix", () => {
// more complex value filter query, range
const varIndex = annoMatrix.schema.annotations.var.index;
fetch
(fetch as any)
.once(
serverMocks.withExpected("/data/var", [[`var:${varIndex}`, "SUMO3"]])
)
@@ -171,7 +174,7 @@ describe("AnnoMatrix", () => {
expect(am1.nObs).toEqual(am2.nObs);
expect(am1.nVar).toEqual(am2.nVar);
fetch
(fetch as any)
.once(serverMocks.annotationsObs(["n_genes"]))
.once(serverMocks.annotationsObs(["n_genes"]));
const ng1 = await am1.fetch("obs", "n_genes");
@@ -185,9 +188,10 @@ describe("AnnoMatrix", () => {
});
describe("add/drop column", () => {
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'base' implicitly has an 'any' type.
async function addDrop(base) {
expect(base.getMatrixColumns("obs")).not.toContain("foo");
fetch.mockRejectOnce(new Error("unknown column name"));
(fetch as any).mockRejectOnce(new Error("unknown column name"));
await expect(base.fetch("obs", "foo")).rejects.toThrow(
"unknown column name"
);
@@ -212,7 +216,7 @@ describe("AnnoMatrix", () => {
const am2 = am1.dropObsColumn("foo");
expect(base.getMatrixColumns("obs")).not.toContain("foo");
expect(am2.getMatrixColumns("obs")).not.toContain("foo");
fetch.mockRejectOnce(new Error("unknown column name"));
(fetch as any).mockRejectOnce(new Error("unknown column name"));
await expect(am2.fetch("obs", "foo")).rejects.toThrow(
"unknown column name"
);
@@ -235,14 +239,14 @@ describe("AnnoMatrix", () => {
const am4 = clip(am3, 0, 1);
await addDrop(am4);
fetch.mockResponse(serverMocks.responder);
(fetch as any).mockResponse(serverMocks.responder);
await am1.fetch("obs", am1.getMatrixColumns("obs"));
await am2.fetch("obs", am2.getMatrixColumns("obs"));
await am3.fetch("obs", am3.getMatrixColumns("obs"));
await am4.fetch("obs", am4.getMatrixColumns("obs"));
fetch.resetMocks();
(fetch as any).resetMocks();
await addDrop(am1);
await addDrop(am2);
@@ -252,6 +256,7 @@ describe("AnnoMatrix", () => {
});
describe("setObsColumnValues", () => {
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'base' implicitly has an 'any' type.
async function addSetDrop(base) {
/* add column */
let am = base.addObsColumn(
@@ -287,7 +292,7 @@ describe("AnnoMatrix", () => {
);
/* drop column */
fetch.mockRejectOnce(new Error("unknown column name"));
(fetch as any).mockRejectOnce(new Error("unknown column name"));
am = am1.dropObsColumn("test");
await expect(am.fetch("obs", "test")).rejects.toThrow(
"unknown column name"
@@ -308,7 +313,7 @@ describe("AnnoMatrix", () => {
const am3 = isubset(annoMatrix, [10, 1, 0, 30, 2]);
await addSetDrop(am3);
fetch.mockResponse(serverMocks.responder);
(fetch as any).mockResponse(serverMocks.responder);
await am1.fetch("obs", am1.getMatrixColumns("obs"));
await am2.fetch("obs", am2.getMatrixColumns("obs"));
@@ -17,11 +17,12 @@ import { rangeFill } from "../../../src/util/range";
enableFetchMocks();
describe("AnnoMatrixCrossfilter", () => {
let annoMatrix;
let crossfilter;
let annoMatrix: any;
let crossfilter: any;
beforeEach(async () => {
fetch.resetMocks(); // reset all fetch mocking state
(fetch as any).resetMocks(); // reset all fetch mocking state
// reset all fetch mocking state
annoMatrix = new AnnoMatrixLoader(
serverMocks.baseDataURL,
serverMocks.schema.schema
@@ -67,7 +68,9 @@ describe("AnnoMatrixCrossfilter", () => {
crossfilter.obsCrossfilter.hasDimension("obs/louvain")
).toBeFalsy();
fetch.once(serverMocks.dataframeResponse(["louvain"], [obsLouvain]));
(fetch as any).once(
serverMocks.dataframeResponse(["louvain"], [obsLouvain])
);
let newCrossfilter = await crossfilter.select("obs", "louvain", {
mode: "none",
});
@@ -76,7 +79,7 @@ describe("AnnoMatrixCrossfilter", () => {
expect(
newCrossfilter.obsCrossfilter.hasDimension("obs/louvain")
).toBeTruthy();
expect(fetch.mock.calls).toHaveLength(1);
expect((fetch as any).mock.calls).toHaveLength(1);
newCrossfilter = await crossfilter.select("obs", "louvain", {
mode: "all",
@@ -87,7 +90,9 @@ describe("AnnoMatrixCrossfilter", () => {
test("simple column select", async () => {
let xfltr;
fetch.once(serverMocks.dataframeResponse(["louvain"], [obsLouvain]));
(fetch as any).once(
serverMocks.dataframeResponse(["louvain"], [obsLouvain])
);
xfltr = await crossfilter.select("obs", "louvain", {
mode: "exact",
values: ["NK cells", "B cells"],
@@ -105,6 +110,7 @@ describe("AnnoMatrixCrossfilter", () => {
expect(xfltr.allSelectedLabels()).toEqual(
Int32Array.from(
obsLouvain.reduce((acc, val, idx) => {
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'number' is not assignable to par... Remove this comment to see the full error message
if (val === "NK cells" || val === "B cells") acc.push(idx);
return acc;
}, [])
@@ -124,10 +130,11 @@ describe("AnnoMatrixCrossfilter", () => {
const values = df.col("louvain").asArray();
const selected = xfltr.allSelectedMask();
values.every(
(val, idx) => !["NK cells", "B cells"].includes(val) !== !selected[idx]
(val: any, idx: any) =>
!["NK cells", "B cells"].includes(val) !== !selected[idx]
);
fetch.once(
(fetch as any).once(
serverMocks.dataframeResponse(["n_genes"], [new Int32Array(obsNGenes)])
);
xfltr = await xfltr.select("obs", "n_genes", {
@@ -146,6 +153,7 @@ describe("AnnoMatrixCrossfilter", () => {
val < 500 &&
(louvain === "NK cells" || louvain === "B cells")
)
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'number' is not assignable to par... Remove this comment to see the full error message
acc.push(idx);
return acc;
}, [])
@@ -160,7 +168,7 @@ describe("AnnoMatrixCrossfilter", () => {
const varIndex = annoMatrix.schema.annotations.var.index;
const { nObs } = annoMatrix.schema.dataframe;
fetch.once(
(fetch as any).once(
serverMocks.dataframeResponse(
["TEST"],
[rangeFill(new Float32Array(nObs), 0, 0.1)]
@@ -196,14 +204,16 @@ describe("AnnoMatrixCrossfilter", () => {
});
const values = df.icol(0).asArray();
const selected = xfltr.allSelectedMask();
values.every((val, idx) => !(val >= 0 && val <= 50) !== !selected[idx]);
expect(selected.reduce((acc, val) => (val ? acc + 1 : acc), 0)).toEqual(
xfltr.countSelected()
values.every(
(val: any, idx: any) => !(val >= 0 && val <= 50) !== !selected[idx]
);
expect(
selected.reduce((acc: any, val: any) => (val ? acc + 1 : acc), 0)
).toEqual(xfltr.countSelected());
});
test("spatial column select", async () => {
fetch.once(
(fetch as any).once(
serverMocks.dataframeResponse(
["umap_0", "umap_1"],
[Float32Array.from(embUmap[0]), Float32Array.from(embUmap[1])]
@@ -222,6 +232,7 @@ describe("AnnoMatrixCrossfilter", () => {
test("select on subset", async () => {
const mask = new Uint8Array(annoMatrix.nObs).fill(0);
for (let i = 0; i < mask.length; i += 2) {
// @ts-expect-error ts-migrate(2322) FIXME: Type 'boolean' is not assignable to type 'number'.
mask[i] = true;
}
const annoMatrixSubset = isubsetMask(annoMatrix, mask);
@@ -230,7 +241,9 @@ describe("AnnoMatrixCrossfilter", () => {
let xfltr = new AnnoMatrixObsCrossfilter(annoMatrixSubset);
expect(xfltr.countSelected()).toEqual(annoMatrixSubset.nObs);
fetch.once(serverMocks.dataframeResponse(["louvain"], [obsLouvain]));
(fetch as any).once(
serverMocks.dataframeResponse(["louvain"], [obsLouvain])
);
xfltr = await xfltr.select("obs", "louvain", {
mode: "exact",
values: ["NK cells", "B cells"],
@@ -243,7 +256,8 @@ describe("AnnoMatrixCrossfilter", () => {
const values = df.col("louvain").asArray();
const selected = xfltr.allSelectedMask();
values.every(
(val, idx) => !["NK cells", "B cells"].includes(val) !== !selected[idx]
(val: any, idx: any) =>
!["NK cells", "B cells"].includes(val) !== !selected[idx]
);
});
@@ -256,7 +270,7 @@ describe("AnnoMatrixCrossfilter", () => {
"unable to obsSelect upon the var dimension"
);
fetch.mockRejectOnce(new Error("unknown column name"));
(fetch as any).mockRejectOnce(new Error("unknown column name"));
await expect(crossfilter.select("obs", "foo")).rejects.toThrow(
"unknown column name"
);
@@ -267,24 +281,27 @@ describe("AnnoMatrixCrossfilter", () => {
/*
test the matrix mutators via crossfilter proxy
*/
async function helperAddTestCol(cf, colName, colSchema = null) {
async function helperAddTestCol(cf: any, colName: any, colSchema = null) {
expect(
cf.annoMatrix.getMatrixColumns("obs").includes(colName)
).toBeFalsy();
if (colSchema === null) {
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ name: any; type: string; categories: strin... Remove this comment to see the full error message
colSchema = {
name: colName,
type: "categorical",
categories: ["toasty"],
};
}
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
colSchema.name = colName;
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
const initValue = colSchema.categories[0];
const xfltr = cf.addObsColumn(colSchema, Array, initValue);
expect(
xfltr.annoMatrix.schema.annotations.obs.columns.filter(
(v) => v.name === colName
(v: any) => v.name === colName
)
).toHaveLength(1);
const df = await xfltr.annoMatrix.fetch("obs", colName);
@@ -314,7 +331,7 @@ describe("AnnoMatrixCrossfilter", () => {
});
expect(
xfltr.annoMatrix.schema.annotations.obs.columns.filter(
(v) => v.name === "foo"
(v: any) => v.name === "foo"
)
).toHaveLength(1);
@@ -324,7 +341,7 @@ describe("AnnoMatrixCrossfilter", () => {
df
.col("foo")
.asArray()
.every((v) => v === "A")
.every((v: any) => v === "A")
).toBeTruthy();
// check that we catch dups
@@ -361,11 +378,11 @@ describe("AnnoMatrixCrossfilter", () => {
xfltr = xfltr.dropObsColumn("foo");
expect(
xfltr.annoMatrix.schema.annotations.obs.columns.filter(
(v) => v.name === "foo"
(v: any) => v.name === "foo"
)
).toHaveLength(0);
expect(xfltr.annoMatrix.schema.annotations.obsByName.foo).toBeUndefined();
fetch.mockRejectOnce(new Error("unknown column name"));
(fetch as any).mockRejectOnce(new Error("unknown column name"));
await expect(xfltr.annoMatrix.fetch("obs", "foo")).rejects.toThrow(
"unknown column name"
);
@@ -378,7 +395,7 @@ describe("AnnoMatrixCrossfilter", () => {
});
xfltr = xfltr.dropObsColumn("bar");
fetch.mockRejectOnce(new Error("unknown column name"));
(fetch as any).mockRejectOnce(new Error("unknown column name"));
await expect(xfltr.select("obs", "bar", { mode: "all" })).rejects.toThrow(
"unknown column name"
);
@@ -404,7 +421,7 @@ describe("AnnoMatrixCrossfilter", () => {
type: "categorical",
});
fetch.mockRejectOnce(new Error("unknown column name"));
(fetch as any).mockRejectOnce(new Error("unknown column name"));
await expect(xfltr.annoMatrix.fetch("obs", "foo")).rejects.toThrow(
"unknown column name"
);
@@ -419,7 +436,7 @@ describe("AnnoMatrixCrossfilter", () => {
});
xfltr = xfltr.renameObsColumn("bar", "xyz");
fetch.mockRejectOnce(new Error("unknown column name"));
(fetch as any).mockRejectOnce(new Error("unknown column name"));
await expect(xfltr.select("obs", "bar", { mode: "all" })).rejects.toThrow(
"unknown column name"
);
@@ -429,7 +446,7 @@ describe("AnnoMatrixCrossfilter", () => {
});
test("addObsAnnoCategory", async () => {
let xfltr;
let xfltr: any;
// catch unknown or readonly columns
expect(() => crossfilter.addObsAnnoCategory("louvain", "mumble")).toThrow(
@@ -440,6 +457,7 @@ describe("AnnoMatrixCrossfilter", () => {
).toThrow("Unknown or readonly obs column");
// add a column and then add category to it
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type '{ name: string; type: string; ca... Remove this comment to see the full error message
xfltr = await helperAddTestCol(crossfilter, "foo", {
name: "foo",
type: "categorical",
@@ -458,6 +476,7 @@ describe("AnnoMatrixCrossfilter", () => {
);
// now same, but ensure we have built an index before doing the operation
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type '{ name: string; type: string; ca... Remove this comment to see the full error message
xfltr = await helperAddTestCol(crossfilter, "bar", {
name: "bar",
type: "categorical",
@@ -486,6 +505,7 @@ describe("AnnoMatrixCrossfilter", () => {
crossfilter.removeObsAnnoCategory("undefined-name", "mumble")
).rejects.toThrow("Unknown or readonly obs column");
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type '{ name: string; type: string; ca... Remove this comment to see the full error message
xfltr = await helperAddTestCol(crossfilter, "foo", {
name: "foo",
type: "categorical",
@@ -496,7 +516,7 @@ describe("AnnoMatrixCrossfilter", () => {
(await xfltr.annoMatrix.fetch("obs", "foo"))
.col("foo")
.asArray()
.every((v) => v === "unassigned")
.every((v: any) => v === "unassigned")
).toBeTruthy();
expect(xfltr.annoMatrix.getColumnSchema("obs", "foo")).toMatchObject({
name: "foo",
@@ -515,7 +535,7 @@ describe("AnnoMatrixCrossfilter", () => {
(await xfltr1.annoMatrix.fetch("obs", "foo"))
.col("foo")
.asArray()
.every((v) => v === "unassigned")
.every((v: any) => v === "unassigned")
).toBeTruthy();
expect(xfltr1.annoMatrix.getColumnSchema("obs", "foo")).toMatchObject({
name: "foo",
@@ -538,7 +558,7 @@ describe("AnnoMatrixCrossfilter", () => {
(await xfltr2.annoMatrix.fetch("obs", "foo"))
.col("foo")
.asArray()
.every((v) => v === "red")
.every((v: any) => v === "red")
).toBeTruthy();
expect(xfltr2.annoMatrix.getColumnSchema("obs", "foo")).toMatchObject({
name: "foo",
@@ -556,6 +576,7 @@ describe("AnnoMatrixCrossfilter", () => {
crossfilter.setObsColumnValues("undefined-name", [0], "mumble")
).rejects.toThrow("Unknown or readonly obs column");
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type '{ name: string; type: string; ca... Remove this comment to see the full error message
let xfltr = await helperAddTestCol(crossfilter, "foo", {
name: "foo",
type: "categorical",
@@ -573,7 +594,7 @@ describe("AnnoMatrixCrossfilter", () => {
(await xfltr.annoMatrix.fetch("obs", "foo"))
.col("foo")
.asArray()
.every((v) => v === "unassigned")
.every((v: any) => v === "unassigned")
).toBeTruthy();
const xfltr1 = await xfltr.setObsColumnValues("foo", [0, 10], "purple");
expect(
@@ -581,7 +602,7 @@ describe("AnnoMatrixCrossfilter", () => {
.col("foo")
.asArray()
.every(
(v, i) =>
(v: any, i: any) =>
v === "unassigned" || (v === "purple" && (i === 0 || i === 10))
)
).toBeTruthy();
@@ -615,6 +636,7 @@ describe("AnnoMatrixCrossfilter", () => {
crossfilter.resetObsColumnValues("undefined-name", "red", "blue")
).rejects.toThrow("Unknown or readonly obs column");
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type '{ name: string; type: string; ca... Remove this comment to see the full error message
let xfltr = await helperAddTestCol(crossfilter, "foo", {
name: "foo",
type: "categorical",
@@ -639,7 +661,7 @@ describe("AnnoMatrixCrossfilter", () => {
(await xfltr1.annoMatrix.fetch("obs", "foo"))
.col("foo")
.asArray()
.filter((v) => v === "purple")
.filter((v: any) => v === "purple")
).toHaveLength(2);
xfltr1 = await xfltr1.resetObsColumnValues("foo", "purple", "magenta");
@@ -647,13 +669,13 @@ describe("AnnoMatrixCrossfilter", () => {
(await xfltr1.annoMatrix.fetch("obs", "foo"))
.col("foo")
.asArray()
.filter((v) => v === "magenta")
.filter((v: any) => v === "magenta")
).toHaveLength(2);
expect(
(await xfltr1.annoMatrix.fetch("obs", "foo"))
.col("foo")
.asArray()
.filter((v) => v === "purple")
.filter((v: any) => v === "purple")
).toHaveLength(0);
expect(xfltr1.annoMatrix.getColumnSchema("obs", "foo")).toMatchObject({
name: "foo",
@@ -673,12 +695,14 @@ describe("AnnoMatrixCrossfilter", () => {
describe("edge cases", () => {
test("transition from empty annoMatrix", async () => {
// select before fetch needs to work
fetch.once(serverMocks.dataframeResponse(["louvain"], [obsLouvain]));
(fetch as any).once(
serverMocks.dataframeResponse(["louvain"], [obsLouvain])
);
const xfltr = await crossfilter.select("obs", "louvain", {
mode: "exact",
values: "B cells",
});
expect(fetch.mock.calls).toHaveLength(1);
expect((fetch as any).mock.calls).toHaveLength(1);
expect(xfltr.obsCrossfilter.hasDimension("obs/louvain")).toBeTruthy();
expect(xfltr.obsCrossfilter.all()).toBe(xfltr.annoMatrix._cache.obs);
expect(xfltr.countSelected()).toEqual(
@@ -1,6 +1,6 @@
export const baseDataURL = "https://a.fake.url/api/v0.2";
window.CELLXGENE = {
(window as any).CELLXGENE = {
API: {
prefix: baseDataURL,
version: "v0.2/",
@@ -14,7 +14,7 @@ const indexedSchema = {
),
};
function makeMockColumn(s, length) {
function makeMockColumn(s: any, length: any) {
const { type } = s;
switch (type) {
case "int32":
@@ -37,20 +37,22 @@ function makeMockColumn(s, length) {
}
}
function getEncodedDataframe(colNames, length, colSchemas) {
function getEncodedDataframe(colNames: any, length: any, colSchemas: any) {
const colIndex = new KeyIndex(colNames);
const columns = colSchemas.map((s) => makeMockColumn(s, length));
const columns = colSchemas.map((s: any) => makeMockColumn(s, length));
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
const df = new Dataframe([length, colNames.length], columns, null, colIndex);
const body = encodeMatrixFBS(df);
return body;
}
export function dataframeResponse(colNames, columns) {
export function dataframeResponse(colNames: any, columns: any) {
const colIndex = new KeyIndex(colNames);
const df = new Dataframe(
[columns[0].length, colNames.length],
columns,
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
colIndex
);
const body = encodeMatrixFBS(df);
@@ -60,15 +62,19 @@ export function dataframeResponse(colNames, columns) {
return () => Promise.resolve({ body, init: { status: 200, headers } });
}
function annotationObsResponse(request) {
function annotationObsResponse(request: any) {
const url = new URL(request.url);
const params = Array.from(url.searchParams.entries());
const params = Array.from((url.searchParams as any).entries());
const names = params
// @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call.
.filter(([k]) => k === "annotation-name")
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type '([, v]: [any, any]) => any' is n... Remove this comment to see the full error message
.map(([, v]) => v);
// @ts-expect-error ts-migrate(2538) FIXME: Type 'unknown' cannot be used as an index type.
if (!names.every((n) => indexedSchema.obsByName[n])) {
return Promise.reject(new Error("bad obs annotation name in URL"));
}
// @ts-expect-error ts-migrate(2538) FIXME: Type 'unknown' cannot be used as an index type.
const colSchemas = names.map((n) => indexedSchema.obsByName[n]);
const body = getEncodedDataframe(
names,
@@ -85,15 +91,19 @@ function annotationObsResponse(request) {
});
}
function annotationVarResponse(request) {
function annotationVarResponse(request: any) {
const url = new URL(request.url);
const params = Array.from(url.searchParams.entries());
const params = Array.from((url.searchParams as any).entries());
const names = params
// @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call.
.filter(([k]) => k === "annotation-name")
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type '([, v]: [any, any]) => any' is n... Remove this comment to see the full error message
.map(([, v]) => v);
// @ts-expect-error ts-migrate(2538) FIXME: Type 'unknown' cannot be used as an index type.
if (!names.every((n) => indexedSchema.varByName[n])) {
return Promise.reject(new Error("bad var annotation name in URL"));
}
// @ts-expect-error ts-migrate(2538) FIXME: Type 'unknown' cannot be used as an index type.
const colSchemas = names.map((n) => indexedSchema.varByName[n]);
const body = getEncodedDataframe(
names,
@@ -110,15 +120,19 @@ function annotationVarResponse(request) {
});
}
function layoutObsResponse(request) {
function layoutObsResponse(request: any) {
const url = new URL(request.url);
const params = Array.from(url.searchParams.entries());
const params = Array.from((url.searchParams as any).entries());
// @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call.
const names = params.filter(([k]) => k === "layout-name").map(([, v]) => v);
// @ts-expect-error ts-migrate(2538) FIXME: Type 'unknown' cannot be used as an index type.
if (!names.every((n) => indexedSchema.embByName[n])) {
return Promise.reject(new Error("bad layout name in URL"));
}
// @ts-expect-error ts-migrate(2538) FIXME: Type 'unknown' cannot be used as an index type.
const dims = names.map((n) => indexedSchema.embByName[n].dims).flat();
const colSchemas = names
// @ts-expect-error ts-migrate(2538) FIXME: Type 'unknown' cannot be used as an index type.
.map((n) => [indexedSchema.embByName[n], indexedSchema.embByName[n]])
.flat();
const body = getEncodedDataframe(
@@ -136,11 +150,11 @@ function layoutObsResponse(request) {
});
}
function dataVarResponse(request) {
function dataVarResponse(request: any) {
const url = new URL(request.url);
const params = Array.from(url.searchParams.entries());
const params = Array.from((url.searchParams as any).entries());
const colNames = params.map((v) => `${v[0]}/${v[1]}`);
const colNames = params.map((v) => `${(v as any)[0]}/${(v as any)[1]}`);
const colSchemas = colNames.map(() => schema.schema.dataframe);
const body = getEncodedDataframe(
colNames,
@@ -157,7 +171,7 @@ function dataVarResponse(request) {
});
}
export function responder(request) {
export function responder(request: any) {
const url = new URL(request.url);
const { pathname } = url;
if (pathname.endsWith("/annotations/obs")) {
@@ -175,25 +189,30 @@ export function responder(request) {
return Promise.reject(new Error("bad URL"));
}
export function withExpected(expectedURL, expectedParams) {
export function withExpected(expectedURL: any, expectedParams: any) {
/*
Do some additional error checking
*/
return (request) => {
return (request: any) => {
// if URL is bogus, reject the promise
const url = new URL(request.url);
if (!url.pathname.endsWith(expectedURL)) {
return Promise.reject(new Error("Unexpected URL!"));
}
const params = Array.from(url.searchParams.entries()).sort(
(a, b) => a[0] < b[0]
const params = Array.from((url.searchParams as any).entries()).sort(
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type '(a: unknown, b: unknown) => bool... Remove this comment to see the full error message
(a, b) => (a as any)[0] < (b as any)[0]
);
expectedParams = expectedParams.slice().sort((a, b) => a[0] < b[0]);
expectedParams = expectedParams
.slice()
.sort((a: any, b: any) => a[0] < b[0]);
if (
params.length !== expectedParams.length ||
!params.every(
(p, i) => p[0] === expectedParams[i][0] && p[1] === expectedParams[i][1]
(p, i) =>
(p as any)[0] === expectedParams[i][0] &&
(p as any)[1] === expectedParams[i][1]
)
) {
return Promise.reject(new Error("unexpected name requested in URL"));
@@ -203,9 +222,9 @@ export function withExpected(expectedURL, expectedParams) {
};
}
export function annotationsObs(names) {
export function annotationsObs(names: any) {
return withExpected(
"/annotations/obs",
names.map((name) => ["annotation-name", name])
names.map((name: any) => ["annotation-name", name])
);
}
@@ -218,10 +218,15 @@ describe("whereCache", () => {
},
})
);
expect(wc.where.field.queryField.has("queryColumn")).toEqual(true);
expect(wc.where.field.queryField.get("queryColumn")).toBeInstanceOf(Map);
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
expect((wc.where as any).field.queryField.has("queryColumn")).toEqual(true);
expect(
wc.where.field.queryField.get("queryColumn").has("queryValue")
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
(wc.where as any).field.queryField.get("queryColumn")
).toBeInstanceOf(Map);
expect(
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
(wc.where as any).field.queryField.get("queryColumn").has("queryValue")
).toEqual(true);
expect(_whereCacheGet(wc, schema, "field", query)).toEqual([0, 1, 2]);
});
@@ -8,9 +8,9 @@ import { indexEntireSchema } from "../../src/util/stateManager/schemaHelpers";
import { _normalizeCategoricalSchema } from "../../src/annoMatrix/schema";
describe("centroid", () => {
let schema;
let obsAnnotations;
let obsLayout;
let schema: any;
let obsAnnotations: any;
let obsLayout: any;
beforeAll(() => {
schema = indexEntireSchema(cloneDeep(REST.schema.schema));
@@ -44,7 +44,7 @@ describe("centroid", () => {
quantile([0.5], obsLayout.col("umap_1").asArray())[0],
];
centroidResult.forEach((coordinate) => {
centroidResult.forEach((coordinate: any) => {
expect(coordinate).toEqual(expectedResult);
});
});
@@ -68,7 +68,7 @@ describe("centroid", () => {
quantile([0.5], obsLayout.col("umap_1").asArray())[0],
];
centroidResult.forEach((coordinate) => {
centroidResult.forEach((coordinate: any) => {
expect(coordinate).toEqual(expectedResult);
});
});
@@ -29,6 +29,7 @@ describe("dataframe constructor", () => {
const df = new Dataframe.Dataframe(
[3, 2],
[new Int32Array([0, 1, 2]), new Int32Array([3, 4, 5])],
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'DenseInt32Index' is not assignab... Remove this comment to see the full error message
new Dataframe.DenseInt32Index([2, 1, 0]),
new Dataframe.KeyIndex(["A", "B"])
);
@@ -55,6 +56,7 @@ describe("simple data access", () => {
new Float64Array([0.0, Number.NaN, Number.POSITIVE_INFINITY, 3.14159]),
["red", "blue", "green", "nan"],
],
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'DenseInt32Index' is not assignab... Remove this comment to see the full error message
new Dataframe.DenseInt32Index([3, 2, 1, 0]),
new Dataframe.KeyIndex(["numbers", "colors"])
);
@@ -139,10 +141,12 @@ describe("dataframe subsetting", () => {
["red", "green", "blue"],
],
null, // identity index
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
new Dataframe.KeyIndex(["int32", "string", "float32", "colors"])
);
test("all rows, one column", () => {
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string[]' is not assignable to p... Remove this comment to see the full error message
const dfA = sourceDf.subset(null, ["colors"]);
expect(dfA).toBeDefined();
expect(dfA.dims).toEqual([3, 1]);
@@ -158,6 +162,7 @@ describe("dataframe subsetting", () => {
});
test("all rows, two columns", () => {
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string[]' is not assignable to p... Remove this comment to see the full error message
const dfB = sourceDf.subset(null, ["float32", "colors"]);
expect(dfB).toBeDefined();
expect(dfB.dims).toEqual([3, 2]);
@@ -227,6 +232,7 @@ describe("dataframe subsetting", () => {
});
test("two rows, two colums", () => {
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string[]' is not assignable to p... Remove this comment to see the full error message
const dfF = sourceDf.subset([0, 2], ["int32", "float32"]);
expect(dfF).toBeDefined();
expect(dfF.dims).toEqual([2, 2]);
@@ -236,6 +242,7 @@ describe("dataframe subsetting", () => {
expect(dfF.colIndex.labels()).toEqual(["int32", "float32"]);
// reverse the row and column order
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string[]' is not assignable to p... Remove this comment to see the full error message
const dfFr = sourceDf.subset([2, 0], ["float32", "int32"]);
expect(dfFr).toBeDefined();
expect(dfFr.dims).toEqual([2, 2]);
@@ -248,6 +255,7 @@ describe("dataframe subsetting", () => {
test("withRowIndex", () => {
const df = sourceDf.subset(
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string[]' is not assignable to p... Remove this comment to see the full error message
["int32", "float32"],
new Dataframe.DenseInt32Index([3, 2, 1])
);
@@ -258,12 +266,15 @@ describe("dataframe subsetting", () => {
test("withRowIndex error checks", () => {
expect(() =>
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string[]' is not assignable to p... Remove this comment to see the full error message
sourceDf.subset(null, ["red"], new Dataframe.IdentityInt32Index(1))
).toThrow(RangeError);
expect(() =>
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string[]' is not assignable to p... Remove this comment to see the full error message
sourceDf.subset(null, ["red"], new Dataframe.DenseInt32Index([0, 1]))
).toThrow(RangeError);
expect(() =>
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string[]' is not assignable to p... Remove this comment to see the full error message
sourceDf.subset(null, ["red"], new Dataframe.KeyIndex([0, 1, 2, 3]))
).toThrow(RangeError);
});
@@ -278,12 +289,14 @@ describe("dataframe subsetting", () => {
new Float32Array([4.4, 5.5, 6.6]),
["red", "green", "blue"],
],
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'DenseInt32Index' is not assignab... Remove this comment to see the full error message
new Dataframe.DenseInt32Index([2, 4, 6]),
new Dataframe.KeyIndex(["int32", "string", "float32", "colors"])
);
const dfA = sourceDf.isubsetMask(
new Uint8Array([0, 1, 1]),
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'Uint8Array' is not assignable to... Remove this comment to see the full error message
new Uint8Array([1, 0, 0, 1])
);
expect(dfA.dims).toEqual([2, 2]);
@@ -303,6 +316,7 @@ describe("dataframe subsetting", () => {
["red", "green", "blue"],
],
null, // identity index
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
new Dataframe.KeyIndex(["int32", "string", "float32", "colors"])
);
@@ -316,6 +330,7 @@ describe("dataframe subsetting", () => {
});
test("all rows, two cols", () => {
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'number[]' is not assignable to p... Remove this comment to see the full error message
const dfA = sourceDf.isubset(null, [1, 2]);
expect(dfA.dims).toEqual([3, 2]);
expect(dfA.icol(0).asArray()).toEqual(["A", "B", "C"]);
@@ -361,6 +376,7 @@ describe("dataframe factories", () => {
const dfA = new Dataframe.Dataframe(
[3, 2],
[new Int32Array([0, 1, 2]), new Int32Array([3, 4, 5])],
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'DenseInt32Index' is not assignab... Remove this comment to see the full error message
new Dataframe.DenseInt32Index([2, 1, 0]),
new Dataframe.KeyIndex(["A", "B"])
);
@@ -385,6 +401,7 @@ describe("dataframe factories", () => {
[true, false],
],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
new Dataframe.KeyIndex(["colors", "bools"])
);
const dfA = df.withCol("numbers", [1, 0]);
@@ -408,6 +425,7 @@ describe("dataframe factories", () => {
[true, false],
],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'DenseInt32Index' is not assignab... Remove this comment to see the full error message
new Dataframe.DenseInt32Index([74, 75])
);
const dfA = df.withCol(72, [1, 0]);
@@ -433,6 +451,7 @@ describe("dataframe factories", () => {
[true, false],
],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'DenseInt32Index' is not assignab... Remove this comment to see the full error message
new Dataframe.DenseInt32Index([74, 75])
);
const dfA = df.withCol(999, [1, 0]);
@@ -541,6 +560,7 @@ describe("dataframe factories", () => {
[1, 0],
],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
new Dataframe.KeyIndex(["colors", "bools", "numbers"])
);
@@ -549,11 +569,14 @@ describe("dataframe factories", () => {
[3, 1],
[["red", "blue", "green"]],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
new Dataframe.KeyIndex(["colorsA"])
);
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
expect(() => dfA.withColsFrom(dfB)).toThrow(RangeError);
/* duplicate labels should throw an error */
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
expect(() => dfA.withColsFrom(dfA)).toThrow(Error);
});
@@ -564,15 +587,18 @@ describe("dataframe factories", () => {
[2, 1],
[["red", "blue"]],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
new Dataframe.KeyIndex(["colors"])
);
const dfB = new Dataframe.Dataframe(
[2, 1],
[[true, false]],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
new Dataframe.KeyIndex(["bools"])
);
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
const dfLikeA = dfEmpty.withColsFrom(dfA);
expect(dfLikeA).toBeDefined();
expect(dfLikeA.dims).toEqual(dfA.dims);
@@ -581,6 +607,7 @@ describe("dataframe factories", () => {
expect(dfLikeA.rowIndex.labels()).toEqual(dfA.rowIndex.labels());
expect(dfLikeA.icol(0).asArray()).toEqual(dfA.icol(0).asArray());
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
const dfAlsoLikeA = dfA.withColsFrom(dfEmpty);
expect(dfAlsoLikeA).toBeDefined();
expect(dfAlsoLikeA.dims).toEqual(dfA.dims);
@@ -589,6 +616,7 @@ describe("dataframe factories", () => {
expect(dfAlsoLikeA.rowIndex.labels()).toEqual(dfA.rowIndex.labels());
expect(dfAlsoLikeA.icol(0).asArray()).toEqual(dfA.icol(0).asArray());
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
const dfC = dfA.withColsFrom(dfB);
expect(dfC).toBeDefined();
expect(dfC.dims).toEqual([2, 2]);
@@ -605,6 +633,7 @@ describe("dataframe factories", () => {
[2, 1],
[["red", "blue"]],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
new Dataframe.KeyIndex(["colors"])
);
const dfB = new Dataframe.Dataframe(
@@ -615,6 +644,7 @@ describe("dataframe factories", () => {
[1, 0],
],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
new Dataframe.KeyIndex(["colors", "bools", "numbers"])
);
@@ -647,6 +677,7 @@ describe("dataframe factories", () => {
[2, 1],
[["red", "blue"]],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
new Dataframe.KeyIndex(["colors"])
);
const dfB = new Dataframe.Dataframe(
@@ -657,6 +688,7 @@ describe("dataframe factories", () => {
[1, 0],
],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
new Dataframe.KeyIndex(["colors", "bools", "numbers"])
);
@@ -680,6 +712,7 @@ describe("dataframe factories", () => {
[1, 0],
],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
new Dataframe.KeyIndex(["colors", "bools", "numbers"])
);
const dfA = df.dropCol("colors");
@@ -751,6 +784,7 @@ describe("dataframe factories", () => {
[1, 0],
],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'DenseInt32Index' is not assignab... Remove this comment to see the full error message
new Dataframe.DenseInt32Index([102, 101, 100])
);
const dfA = df.dropCol(101);
@@ -777,7 +811,7 @@ describe("dataframe factories", () => {
new Float64Array(3).fill(1.1),
]
);
const dfB = dfA.mapColumns((col, idx) => {
const dfB = dfA.mapColumns((col: any, idx: any) => {
expect(dfA.icol(idx).asArray()).toBe(col);
return col;
});
@@ -822,6 +856,7 @@ describe("dataframe factories", () => {
[1, 0],
],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
new Dataframe.KeyIndex(["A", "B"])
);
const dfB = dfA.renameCol("B", "C");
@@ -834,7 +869,7 @@ describe("dataframe factories", () => {
});
describe("dataframe col", () => {
let df = null;
let df: any = null;
beforeEach(() => {
df = new Dataframe.Dataframe(
[2, 2],
@@ -843,6 +878,7 @@ describe("dataframe col", () => {
[1, 0],
],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
new Dataframe.KeyIndex(["A", "B"])
);
});
@@ -1195,6 +1231,7 @@ describe("label indexing", () => {
test("create", () => {
expect(Dataframe.isLabelIndex(idx)).toBeTruthy();
expect(() => new Dataframe.KeyIndex(["dup", "dup"])).toThrow(Error);
// @ts-expect-error ts-migrate(2554) FIXME: Expected 1 arguments, but got 0.
expect(new Dataframe.KeyIndex().size()).toEqual(0);
});
@@ -1367,6 +1404,7 @@ describe("corner cases", () => {
[1, 0],
],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
new Dataframe.KeyIndex(["A", "B"])
);
@@ -6,6 +6,7 @@ describe("Dataframe column histogram", () => {
[3, 3],
[["n1", "n2", "n3"], ["c1", "c2", "c3"], new Int32Array([0, 1, 2])],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
new Dataframe.KeyIndex(["name", "cat", "value"])
);
@@ -26,6 +27,7 @@ describe("Dataframe column histogram", () => {
[3, 3],
[["n1", "n2", "n3"], ["c1", "c2", "c3"], new Int32Array([0, 1, 2])],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
new Dataframe.KeyIndex(["name", "cat", "value"])
);
@@ -48,6 +50,7 @@ describe("Dataframe column histogram", () => {
[3, 3],
[["n1", "n2", "n3"], ["c1", "c2", "c3"], new Int32Array([0, 1, 2])],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
new Dataframe.KeyIndex(["name", "cat", "value"])
);
@@ -68,6 +71,7 @@ describe("Dataframe column histogram", () => {
[3, 3],
[["n1", "n2", "n3"], ["c1", "c2", "c3"], new Int32Array([0, 1, 2])],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
new Dataframe.KeyIndex(["name", "cat", "value"])
);
@@ -1,6 +1,6 @@
import * as Dataframe from "../../../src/util/dataframe";
function float32Conversion(f) {
function float32Conversion(f: any) {
return new Float32Array([f])[0];
}
@@ -30,6 +30,7 @@ describe("Dataframe column summary", () => {
[1],
],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
new Dataframe.KeyIndex([
"name",
"nameString",
@@ -106,6 +107,7 @@ describe("Dataframe column summary", () => {
[1, false, "0"],
],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
new Dataframe.KeyIndex([
"name",
"nameString",
@@ -174,6 +176,7 @@ describe("Dataframe column summary", () => {
expect.objectContaining({
categorical: true,
categories: expect.arrayContaining([1, false, "0"]),
// @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call.
categoryCounts: new Map([
[1, 1],
[false, 1],
@@ -201,6 +204,7 @@ describe("Dataframe column summary", () => {
[1, false, "0", "0"],
],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
new Dataframe.KeyIndex([
"name",
"nameString",
@@ -269,6 +273,7 @@ describe("Dataframe column summary", () => {
expect.objectContaining({
categorical: true,
categories: expect.arrayContaining([1, false, "0"]),
// @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call.
categoryCounts: new Map([
[1, 1],
[false, 1],
@@ -1,7 +1,7 @@
import PromiseLimit from "../../src/util/promiseLimit";
import { range } from "../../src/util/range";
const delay = (t) => new Promise((resolve) => setTimeout(resolve, t));
const delay = (t: any) => new Promise((resolve) => setTimeout(resolve, t));
describe("PromiseLimit", () => {
test("simple evaluation, concurrency 1", async () => {
@@ -51,7 +51,8 @@ describe("PromiseLimit", () => {
running -= 1;
};
await Promise.all(range(10).map((i) => plimit.add(() => callback(i))));
// @ts-expect-error ts-migrate(2554) FIXME: Expected 3 arguments, but got 1.
await Promise.all(range(10).map((i: any) => plimit.add(() => callback(i))));
expect(maxRunning).toEqual(2);
});
@@ -6,14 +6,20 @@ describe("range", () => {
});
test("range(stop)", () => {
// @ts-expect-error ts-migrate(2554) FIXME: Expected 3 arguments, but got 1.
expect(range(3)).toMatchObject([0, 1, 2]);
// @ts-expect-error ts-migrate(2554) FIXME: Expected 3 arguments, but got 1.
expect(range(0)).toMatchObject([]);
// @ts-expect-error ts-migrate(2554) FIXME: Expected 3 arguments, but got 1.
expect(range(1)).toMatchObject([0]);
});
test("range(start,stop)", () => {
// @ts-expect-error ts-migrate(2554) FIXME: Expected 3 arguments, but got 2.
expect(range(0, 0)).toMatchObject([]);
// @ts-expect-error ts-migrate(2554) FIXME: Expected 3 arguments, but got 2.
expect(range(0, 2)).toMatchObject([0, 1]);
// @ts-expect-error ts-migrate(2554) FIXME: Expected 3 arguments, but got 2.
expect(range(4, 8)).toMatchObject([4, 5, 6, 7]);
});
@@ -81,6 +81,7 @@ describe("categorical color helpers", () => {
),
],
null,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
new Dataframe.KeyIndex(["continuousColumn", "categoricalColumn"])
);
@@ -95,6 +96,7 @@ describe("categorical color helpers", () => {
const data = obsDataframe.col("categoricalColumn").asArray();
const cats = schema.annotations.obsByName.categoricalColumn.categories;
for (let i = 0; i < schema.dataframe.nObs; i += 1) {
// @ts-expect-error ts-migrate(2722) FIXME: Cannot invoke an object which is possibly 'undefin... Remove this comment to see the full error message
expect(makeScale(ct.rgb[i])).toEqual(ct.scale(cats.indexOf(data[i])));
}
});
@@ -112,6 +114,7 @@ describe("categorical color helpers", () => {
const data = obsDataframe.col("categoricalColumn").asArray();
const cats = schemaClone.annotations.obsByName.categoricalColumn.categories;
for (let i = 0; i < schemaClone.dataframe.nObs; i += 1) {
// @ts-expect-error ts-migrate(2722) FIXME: Cannot invoke an object which is possibly 'undefin... Remove this comment to see the full error message
expect(makeScale(ct.rgb[i])).toEqual(ct.scale(cats.indexOf(data[i])));
}
});
@@ -122,7 +125,7 @@ describe("categorical color helpers", () => {
Array.from(schema.annotations.obsByName.categoricalColumn.categories)
);
const userDefinedColorTable = {
categoricalColumn: shuffleCats.reduce((acc, label) => {
categoricalColumn: shuffleCats.reduce((acc: any, label: any) => {
acc[label] = randRGBColor();
return acc;
}, {}),
@@ -136,12 +139,14 @@ describe("categorical color helpers", () => {
"categoricalColumn",
obsDataframe,
schema,
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type '{}' is not assignable to paramet... Remove this comment to see the full error message
userColors
);
expect(ct).toBeDefined();
const data = obsDataframe.col("categoricalColumn").asArray();
for (let i = 0; i < schema.dataframe.nObs; i += 1) {
expect(makeScale(ct.rgb[i])).toEqual(
// @ts-expect-error ts-migrate(2722) FIXME: Cannot invoke an object which is possibly 'undefin... Remove this comment to see the full error message
ct.scale(cats.indexOf(data[i])).toString()
);
}
@@ -154,31 +159,31 @@ TODO:
2. user defined colors
*/
function indexSchema(schema) {
function indexSchema(schema: any) {
schema.annotations.obsByName = Object.fromEntries(
schema.annotations?.obs?.columns?.map((v) => [v.name, v]) ?? []
schema.annotations?.obs?.columns?.map((v: any) => [v.name, v]) ?? []
);
schema.annotations.varByName = Object.fromEntries(
schema.annotations?.var?.columns?.map((v) => [v.name, v]) ?? []
schema.annotations?.var?.columns?.map((v: any) => [v.name, v]) ?? []
);
schema.layout.obsByName = Object.fromEntries(
schema.layout?.obs?.map((v) => [v.name, v]) ?? []
schema.layout?.obs?.map((v: any) => [v.name, v]) ?? []
);
schema.layout.varByName = Object.fromEntries(
schema.layout?.var?.map((v) => [v.name, v]) ?? []
schema.layout?.var?.map((v: any) => [v.name, v]) ?? []
);
return schema;
}
function makeScale(rgb) {
function makeScale(rgb: any) {
// make a scale string from a rgb float triple
return `rgb(${(rgb[0] * 255) >>> 0}, ${(rgb[1] * 255) >>> 0}, ${
(rgb[2] * 256) >>> 0
})`;
}
function shuffle(array) {
function shuffle(array: any) {
for (let i = array.length - 1; i > 0; i -= 1) {
const j = (Math.random() * (i + 1)) >>> 0;
[array[i], array[j]] = [array[j], array[i]];
@@ -24,6 +24,7 @@ describe("encode/decode", () => {
expect(dfA.columns).toEqual(columns);
const colIndex = new KeyIndex(["a", "b", "c", "d"]);
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message
const dfWithColIdx = new Dataframe([3, 4], columns, null, colIndex);
const dfB = decodeMatrixFBS(encodeMatrixFBS(dfWithColIdx));
expect([dfB.nRows, dfB.nCols]).toEqual(dfWithColIdx.dims);
@@ -75,6 +75,7 @@ const aSchemaResponse = {
const anAnnotationsObsJSONResponse = {
names: ["name", "field1", "field2", "field3", "field4"],
// @ts-expect-error ts-migrate(2554) FIXME: Expected 1 arguments, but got 0.
data: _()
.range(nObs)
.map((idx) => [
@@ -91,6 +92,7 @@ const anAnnotationsObsJSONResponse = {
const anAnnotationsVarJSONResponse = {
names: ["fieldA", "fieldB", "fieldC", "fieldD", "name"],
// @ts-expect-error ts-migrate(2554) FIXME: Expected 1 arguments, but got 0.
data: _()
.range(nVar)
.map((idx) => [
@@ -105,7 +107,7 @@ const anAnnotationsVarJSONResponse = {
.value(),
};
function encodeTypedArray(builder, uType, uData) {
function encodeTypedArray(builder: any, uType: any, uData: any) {
const uTypeName = NetEncoding.TypedArray[uType];
const ArrayType = NetEncoding[uTypeName];
const dv = ArrayType.createDataVector(builder, uData);
@@ -114,7 +116,7 @@ function encodeTypedArray(builder, uType, uData) {
return builder.endObject();
}
function encodeMatrix(columns, colIndex = undefined) {
function encodeMatrix(columns: any, colIndex = undefined) {
/*
IMPORTANT: this is not a general purpose encoder. in particular,
it doesn't correctly handle all column index types, nor does it
@@ -123,6 +125,7 @@ function encodeMatrix(columns, colIndex = undefined) {
encodeMatrixFBS in matrix.py is more general. This is used only
as a testing santity check (alt implementation).
*/
// @ts-expect-error ts-migrate(2554) FIXME: Expected 0 arguments, but got 1.
const utf8Encoder = new TextEncoder("utf-8");
const builder = new flatbuffers.Builder(1024);
const cols = map(columns, (carr) => {
@@ -172,11 +175,13 @@ function encodeMatrix(columns, colIndex = undefined) {
const anAnnotationsObsFBSResponse = (() => {
const columns = zip(...anAnnotationsObsJSONResponse.data).slice(1);
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string[]' is not assignable to p... Remove this comment to see the full error message
return encodeMatrix(columns, anAnnotationsObsJSONResponse.names);
})();
const anAnnotationsVarFBSResponse = (() => {
const columns = zip(...anAnnotationsVarJSONResponse.data).slice(1);
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string[]' is not assignable to p... Remove this comment to see the full error message
return encodeMatrix(columns, anAnnotationsVarJSONResponse.names);
})();
@@ -185,11 +190,13 @@ const aLayoutFBSResponse = (() => {
new Float32Array(nObs).fill(Math.random()),
new Float32Array(nObs).fill(Math.random()),
];
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string[]' is not assignable to p... Remove this comment to see the full error message
return encodeMatrix(coords, ["umap_0", "umap_1"]);
})();
const aDataObsResponse = {
var: [2, 4, 29],
// @ts-expect-error ts-migrate(2554) FIXME: Expected 1 arguments, but got 0.
obs: _()
.range(nObs)
.map((idx) => [idx, Math.random(), Math.random(), Math.random()])
@@ -126,7 +126,7 @@ const someData = [
},
];
let payments = null;
let payments: any = null;
beforeEach(() => {
payments = new Crossfilter(someData);
});
@@ -138,7 +138,12 @@ describe("ImmutableTypedCrossfilter", () => {
expect(payments.all()).toEqual(someData);
const p = payments
.addDimension("quantity", "scalar", (i, d) => d[i].quantity, Int32Array)
.addDimension(
"quantity",
"scalar",
(i: any, d: any) => d[i].quantity,
Int32Array
)
.select("quantity", { mode: "all" });
expect(p).toBeDefined();
expect(p.all()).toEqual(someData);
@@ -158,7 +163,7 @@ describe("ImmutableTypedCrossfilter", () => {
const p2 = payments.addDimension(
"quantity",
"scalar",
(i, data) => data[i].quantity,
(i: any, data: any) => data[i].quantity,
Int32Array
);
@@ -175,10 +180,20 @@ describe("ImmutableTypedCrossfilter", () => {
test("select all and none", () => {
let p = payments
.addDimension("quantity", "scalar", (i, d) => d[i].quantity, Int32Array)
.addDimension("tip", "scalar", (i, d) => d[i].tip, Float32Array)
.addDimension("total", "scalar", (i, d) => d[i].total, Float32Array)
.addDimension("type", "enum", (i, d) => d[i].type);
.addDimension(
"quantity",
"scalar",
(i: any, d: any) => d[i].quantity,
Int32Array
)
.addDimension("tip", "scalar", (i: any, d: any) => d[i].tip, Float32Array)
.addDimension(
"total",
"scalar",
(i: any, d: any) => d[i].total,
Float32Array
)
.addDimension("type", "enum", (i: any, d: any) => d[i].type);
expect(p).toBeDefined();
/* expect all records to be selected - default init state */
@@ -230,11 +245,21 @@ describe("ImmutableTypedCrossfilter", () => {
});
describe("scalar dimension", () => {
let p;
let p: any;
beforeEach(() => {
p = payments
.addDimension("quantity", "scalar", (i, d) => d[i].quantity, Int32Array)
.addDimension("tip", "scalar", (i, d) => d[i].tip, Float32Array)
.addDimension(
"quantity",
"scalar",
(i: any, d: any) => d[i].quantity,
Int32Array
)
.addDimension(
"tip",
"scalar",
(i: any, d: any) => d[i].tip,
Float32Array
)
.select("tip", { mode: "all" });
});
@@ -277,9 +302,9 @@ describe("ImmutableTypedCrossfilter", () => {
});
describe("enum dimension", () => {
let p;
let p: any;
beforeEach(() => {
p = payments.addDimension("type", "enum", (i, d) => d[i].type);
p = payments.addDimension("type", "enum", (i: any, d: any) => d[i].type);
});
test("all", () => {
@@ -317,7 +342,7 @@ describe("ImmutableTypedCrossfilter", () => {
});
describe("spatial dimension", () => {
let p;
let p: any;
beforeEach(() => {
const X = someData.map((r) => r.coords[0]);
const Y = someData.map((r) => r.coords[1]);
@@ -406,14 +431,19 @@ describe("ImmutableTypedCrossfilter", () => {
});
describe("non-finite scalars", () => {
let p;
let p: any;
beforeEach(() => {
p = payments
.addDimension("quantity", "scalar", (i, d) => d[i].quantity, Int32Array)
.addDimension(
"quantity",
"scalar",
(i: any, d: any) => d[i].quantity,
Int32Array
)
.addDimension(
"nonFinite",
"scalar",
(i, d) => d[i].nonFinite,
(i: any, d: any) => d[i].nonFinite,
Float32Array
)
.select("quantity", { mode: "all" });
@@ -15,7 +15,7 @@ paths for:
const pInf = Number.POSITIVE_INFINITY;
const nInf = Number.NEGATIVE_INFINITY;
function fillRange(arr, start = 0) {
function fillRange(arr: any, start = 0) {
const larr = arr;
for (let i = 0, len = larr.length; i < len; i += 1) {
larr[i] = i + start;
@@ -23,7 +23,7 @@ function fillRange(arr, start = 0) {
return larr;
}
function fillRand(arr) {
function fillRand(arr: any) {
for (let i = 0, len = arr.length; i < len; i += 1) {
arr[i] = Math.random();
}
@@ -48,16 +48,22 @@ describe("sortArray", () => {
describe("finite numbers", () => {
[Array, Float32Array, Uint32Array, Int32Array, Float64Array].map((Type) =>
test(Type.name, () => {
// @ts-expect-error ts-migrate(2349) FIXME: This expression is not callable.
expect(sortArray(Type.from([6, 5, 4, 3, 2, 1, 0]))).toMatchObject(
// @ts-expect-error ts-migrate(2349) FIXME: This expression is not callable.
Type.from([0, 1, 2, 3, 4, 5, 6])
);
// @ts-expect-error ts-migrate(2349) FIXME: This expression is not callable.
expect(sortArray(Type.from([6, 5, 4, 3, 2, 1]))).toMatchObject(
// @ts-expect-error ts-migrate(2349) FIXME: This expression is not callable.
Type.from([1, 2, 3, 4, 5, 6])
);
const source = fillRand(new Type(1000));
// @ts-expect-error ts-migrate(2349) FIXME: This expression is not callable.
expect(sortArray(Type.from(source))).toMatchObject(
// @ts-expect-error ts-migrate(2349) FIXME: This expression is not callable.
Type.from(source).sort()
);
})
@@ -130,22 +136,24 @@ describe("sortIndex", () => {
describe("finite numbers", () => {
[Array, Float32Array, Uint32Array, Int32Array, Float64Array].map((Type) =>
test(Type.name, () => {
// @ts-expect-error ts-migrate(2349) FIXME: This expression is not callable.
const source1 = Type.from([6, 5, 4, 3, 2, 1, 0]);
const index1 = fillRange(new Uint32Array(source1.length));
expect(sortIndex(index1, source1)).toMatchObject(
index1.sort((a, b) => source1[a] - source1[b])
index1.sort((a: any, b: any) => source1[a] - source1[b])
);
// @ts-expect-error ts-migrate(2349) FIXME: This expression is not callable.
const source2 = Type.from([6, 5, 4, 3, 2, 1]);
const index2 = fillRange(new Uint32Array(source2.length));
expect(sortIndex(index2, source2)).toMatchObject(
index2.sort((a, b) => source1[a] - source1[b])
index2.sort((a: any, b: any) => source1[a] - source1[b])
);
const source3 = fillRand(new Type(1000));
const index3 = fillRange(new Uint32Array(source3.length));
expect(sortIndex(index3, source3)).toMatchObject(
index3.sort((a, b) => source1[a] - source1[b])
index3.sort((a: any, b: any) => source1[a] - source1[b])
);
})
);
+1
View File
@@ -11,6 +11,7 @@ module.exports = {
},
],
"@babel/preset-react",
"@babel/preset-typescript",
],
plugins: [
"@babel/plugin-proposal-function-bind",
+1
View File
@@ -10,6 +10,7 @@ module.exports = {
},
],
"@babel/preset-react",
"@babel/preset-typescript"
],
plugins: [
"@babel/plugin-proposal-function-bind",
+34 -5
View File
@@ -1,13 +1,12 @@
module.exports = {
root: true,
parser: "babel-eslint",
parser: "@typescript-eslint/parser",
extends: [
"airbnb",
"airbnb-typescript",
"plugin:eslint-comments/recommended",
"plugin:@blueprintjs/recommended",
"plugin:compat/recommended",
"plugin:prettier/recommended",
"prettier",
],
settings: {
// AbortController is not supported in iOS Safari 10.3, Chrome 61
@@ -32,18 +31,47 @@ module.exports = {
jsx: true,
generators: true,
},
project: "./tsconfig.json",
},
rules: {
"react/jsx-no-target-blank": "off",
"eslint-comments/require-description": ["error"],
"no-magic-numbers": "off",
"@typescript-eslint/no-magic-numbers": "off",
"no-nested-ternary": "off",
"func-style": "off",
"arrow-parens": "off",
"no-use-before-define": "off",
"@typescript-eslint/no-use-before-define": "off",
"react/jsx-filename-extension": "off",
"comma-dangle": "off",
"@typescript-eslint/comma-dangle": "off",
"no-underscore-dangle": "off",
// Override airbnb config to allow leading underscore
// https://github.com/iamturns/eslint-config-airbnb-typescript/blob/master/lib/shared.js#L35
"@typescript-eslint/naming-convention": [
"error",
{
selector: "class",
format: ["PascalCase"],
leadingUnderscore: "allow",
},
{
selector: "function",
format: ["camelCase", "PascalCase"],
leadingUnderscore: "allowSingleOrDouble",
},
{
selector: "typeLike",
format: ["PascalCase"],
},
{
selector: "variable",
format: ["camelCase", "PascalCase", "UPPER_CASE"],
leadingUnderscore: "allowSingleOrDouble",
trailingUnderscore: "allowDouble",
},
],
"implicit-arrow-linebreak": "off",
"no-console": "off",
"spaced-comment": ["error", "always", { exceptions: ["*"] }],
@@ -51,6 +79,7 @@ module.exports = {
"object-curly-newline": ["error", { consistent: true }],
"react/prop-types": [0],
"space-before-function-paren": "off",
"@typescript-eslint/space-before-function-paren": "off",
"function-paren-newline": "off",
"prefer-destructuring": ["error", { object: true, array: false }],
"import/prefer-default-export": "off",
@@ -69,9 +98,9 @@ module.exports = {
},
overrides: [
{
files: ["**/*.test.js"],
files: ["**/*.test.ts"],
env: {
jest: true, // now **/*.test.js files' env has both es6 *and* jest
jest: true, // now **/*.test.ts files' env has both es6 *and* jest
},
// Can't extend in overrides: https://github.com/eslint/eslint/issues/8813
// "extends": ["plugin:jest/recommended"]
@@ -1,3 +1,3 @@
module.exports = {
"*.js": "eslint --fix",
"*.{js,ts,jsx,tsx}": "eslint --fix",
};
@@ -23,7 +23,7 @@ const devConfig = {
module: {
rules: [
{
test: /\.jsx?$/,
test: /\.(ts|js)x?$/,
loader: "babel-loader",
options: babelOptions,
},
@@ -38,7 +38,7 @@ const prodConfig = {
module: {
rules: [
{
test: /\.jsx?$/,
test: /\.(ts|js)x?$/,
loader: "babel-loader",
options: babelOptions,
},
@@ -29,6 +29,9 @@ module.exports = {
path: path.resolve("build"),
publicPath,
},
resolve: {
extensions: [".ts", ".tsx", "..."],
},
module: {
rules: [
{
+1612 -388
View File
File diff suppressed because it is too large Load Diff
+37 -7
View File
@@ -8,9 +8,9 @@
"build": "npm run clean && webpack --config",
"clean": "rimraf build",
"dev": "npm run build -- configuration/webpack/webpack.config.dev.js",
"e2e": "jest --config __tests__/e2e/e2eJestConfig.json e2e/e2e.test.js",
"e2e-annotations": "jest --config __tests__/e2e/e2eJestConfig.json e2e/e2eAnnotations.test.js",
"e2e-prod": "CXG_URL_BASE='https://cellxgene.cziscience.com/d/pbmc3k.cxg/' jest --config __tests__/e2e/e2eJestConfig.json e2e/e2e.test.js",
"e2e": "jest --config __tests__/e2e/e2eJestConfig.json e2e/e2e.test.ts",
"e2e-annotations": "jest --config __tests__/e2e/e2eJestConfig.json e2e/e2eAnnotations.test.ts",
"e2e-prod": "CXG_URL_BASE='https://cellxgene.cziscience.com/d/pbmc3k.cxg/' jest --config __tests__/e2e/e2eJestConfig.json e2e/e2e.test.ts",
"fmt": "eslint --fix src __tests__",
"lint": "eslint --fix src __tests__",
"prod": "npm run build -- configuration/webpack/webpack.config.prod.js",
@@ -90,10 +90,38 @@
"@babel/plugin-transform-runtime": "^7.13.15",
"@babel/preset-env": "^7.13.15",
"@babel/preset-react": "^7.13.13",
"@babel/preset-typescript": "^7.14.5",
"@babel/register": "^7.13.16",
"@babel/runtime": "^7.13.16",
"@blueprintjs/eslint-plugin": "^0.3.0",
"@sentry/webpack-plugin": "^1.15.0",
"@types/d3": "^7.0.0",
"@types/d3-scale-chromatic": "^3.0.0",
"@types/expect-puppeteer": "^4.4.6",
"@types/flatbuffers": "^1.10.0",
"@types/is-number": "^7.0.1",
"@types/jest": "^26.0.24",
"@types/jest-environment-puppeteer": "^4.4.1",
"@types/lodash.clonedeep": "^4.5.6",
"@types/lodash.difference": "^4.5.6",
"@types/lodash.every": "^4.6.6",
"@types/lodash.filter": "^4.6.6",
"@types/lodash.foreach": "^4.5.6",
"@types/lodash.isnumber": "^3.0.6",
"@types/lodash.map": "^4.6.13",
"@types/lodash.pull": "^4.1.6",
"@types/lodash.sortby": "^4.7.6",
"@types/lodash.uniq": "^4.5.6",
"@types/lodash.zip": "^4.2.6",
"@types/pako": "^1.0.2",
"@types/puppeteer": "^5.4.4",
"@types/react": "^17.0.14",
"@types/react-dom": "^17.0.9",
"@types/react-helmet": "^6.1.2",
"@types/react-redux": "^7.1.18",
"@types/sha1": "^1.1.3",
"@typescript-eslint/eslint-plugin": "^4.28.4",
"@typescript-eslint/parser": "^4.28.4",
"babel-eslint": "^10.1.0",
"babel-jest": "^26.1.0",
"babel-loader": "^8.1.0",
@@ -106,7 +134,7 @@
"connect-history-api-fallback": "^1.6.0",
"css-loader": "^5.2.4",
"eslint": "^7.24.0",
"eslint-config-airbnb": "^18.2.0",
"eslint-config-airbnb-typescript": "^12.3.1",
"eslint-config-prettier": "^8.2.0",
"eslint-loader": "^4.0.2",
"eslint-plugin-compat": "^3.8.0",
@@ -149,6 +177,7 @@
"style-loader": "^2.0.0",
"sw-precache-webpack-plugin": "^1.0.0",
"terser-webpack-plugin": "^5.1.1",
"typescript": "^4.3.5",
"url-loader": "^4.1.0",
"webpack": "^5.34.0",
"webpack-cli": "^4.6.0",
@@ -157,10 +186,10 @@
},
"jest": {
"testMatch": [
"**/__tests__/**/?(*.)(spec|test).js?(x)"
"**/__tests__/**/?(*.)(spec|test).ts?(x)"
],
"setupFiles": [
"./__tests__/setupMissingGlobals.js"
"./__tests__/setupMissingGlobals.ts"
],
"coverageDirectory": "./coverage/",
"collectCoverage": true
@@ -170,7 +199,8 @@
"test": {
"presets": [
"@babel/preset-env",
"@babel/preset-react"
"@babel/preset-react",
"@babel/preset-typescript"
],
"plugins": [
"@babel/plugin-proposal-function-bind",
@@ -9,9 +9,9 @@ import { MatrixFBS, AnnotationsHelpers } from "../util/stateManager";
const { isUserAnnotation } = AnnotationsHelpers;
export const annotationCreateCategoryAction = (
newCategoryName,
categoryToDuplicate
) => async (dispatch, getState) => {
newCategoryName: any,
categoryToDuplicate: any
) => async (dispatch: any, getState: any) => {
/*
Add a new user-created category to the obs annotations.
@@ -89,9 +89,9 @@ export const annotationCreateCategoryAction = (
};
export const annotationRenameCategoryAction = (
oldCategoryName,
newCategoryName
) => (dispatch, getState) => {
oldCategoryName: any,
newCategoryName: any
) => (dispatch: any, getState: any) => {
/*
Rename a user-created annotation category
*/
@@ -124,9 +124,9 @@ export const annotationRenameCategoryAction = (
});
};
export const annotationDeleteCategoryAction = (categoryName) => (
dispatch,
getState
export const annotationDeleteCategoryAction = (categoryName: any) => (
dispatch: any,
getState: any
) => {
/*
Delete a user-created category
@@ -149,10 +149,10 @@ export const annotationDeleteCategoryAction = (categoryName) => (
};
export const annotationCreateLabelInCategory = (
categoryName,
labelName,
assignSelected
) => async (dispatch, getState) => {
categoryName: any,
labelName: any,
assignSelected: any
) => async (dispatch: any, getState: any) => {
/*
Add a new label to a user-defined category. If assignSelected is true, assign
the label to all currently selected cells.
@@ -188,9 +188,9 @@ export const annotationCreateLabelInCategory = (
};
export const annotationDeleteLabelFromCategory = (
categoryName,
labelName
) => async (dispatch, getState) => {
categoryName: any,
labelName: any
) => async (dispatch: any, getState: any) => {
/*
delete a label from a user-defined category
*/
@@ -218,10 +218,10 @@ export const annotationDeleteLabelFromCategory = (
};
export const annotationRenameLabelInCategory = (
categoryName,
oldLabelName,
newLabelName
) => async (dispatch, getState) => {
categoryName: any,
oldLabelName: any,
newLabelName: any
) => async (dispatch: any, getState: any) => {
/*
label name change
*/
@@ -255,9 +255,9 @@ export const annotationRenameLabelInCategory = (
};
export const annotationLabelCurrentSelection = (
categoryName,
labelName
) => async (dispatch, getState) => {
categoryName: any,
labelName: any
) => async (dispatch: any, getState: any) => {
/*
set the label on all currently selected
*/
@@ -284,13 +284,16 @@ export const annotationLabelCurrentSelection = (
});
};
function writableAnnotations(annoMatrix) {
function writableAnnotations(annoMatrix: any) {
return annoMatrix.schema.annotations.obs.columns
.filter((s) => s.writable)
.map((s) => s.name);
.filter((s: any) => s.writable)
.map((s: any) => s.name);
}
export const needToSaveObsAnnotations = (annoMatrix, lastSavedAnnoMatrix) => {
export const needToSaveObsAnnotations = (
annoMatrix: any,
lastSavedAnnoMatrix: any
) => {
/*
Return true if there are LIKELY user-defined annotation modifications between the two
annoMatrices. Technically not an action creator, but intimately intertwined
@@ -314,11 +317,14 @@ export const needToSaveObsAnnotations = (annoMatrix, lastSavedAnnoMatrix) => {
// no schema changes; check for change in contents
return currentWritable.some(
(col) => annoMatrix.col(col) !== lastSavedAnnoMatrix.col(col)
(col: any) => annoMatrix.col(col) !== lastSavedAnnoMatrix.col(col)
);
};
export const saveObsAnnotationsAction = () => async (dispatch, getState) => {
export const saveObsAnnotationsAction = () => async (
dispatch: any,
getState: any
) => {
/*
Save the user-created obs annotations IF any have changed.
*/
@@ -388,7 +394,10 @@ export const saveObsAnnotationsAction = () => async (dispatch, getState) => {
}
};
export const saveGenesetsAction = () => async (dispatch, getState) => {
export const saveGenesetsAction = () => async (
dispatch: any,
getState: any
) => {
const state = getState();
// bail if gene sets not available, or in readonly mode.
@@ -465,7 +474,7 @@ export const saveGenesetsAction = () => async (dispatch, getState) => {
res,
});
}
return Promise.all([
return await Promise.all([
dispatch({
type: "autosave: genesets complete",
lastSavedGenesets: genesets,
@@ -6,9 +6,9 @@ import { AnnoMatrixObsCrossfilter } from "../annoMatrix";
import { _setEmbeddingSubset } from "../util/stateManager/viewStackHelpers";
export async function _switchEmbedding(
prevAnnoMatrix,
prevCrossfilter,
newEmbeddingName
prevAnnoMatrix: any,
prevCrossfilter: any,
newEmbeddingName: any
) {
/*
DRY helper used by embedding action creators
@@ -25,9 +25,9 @@ export async function _switchEmbedding(
return [annoMatrix, obsCrossfilter];
}
export const layoutChoiceAction = (newLayoutChoice) => async (
dispatch,
getState
export const layoutChoiceAction = (newLayoutChoice: any) => async (
dispatch: any,
getState: any
) => {
/*
On layout choice, make sure we have selected all on the previous layout, AND the new
@@ -21,7 +21,10 @@ The behavior manifest in these action creators:
Note that crossfilter indices are lazy created, as needed.
*/
export const genesetDelete = (genesetName) => (dispatch, getState) => {
export const genesetDelete = (genesetName: any) => (
dispatch: any,
getState: any
) => {
const state = getState();
const { genesets } = state;
const gs = genesets?.genesets?.get(genesetName) ?? {};
@@ -40,9 +43,9 @@ export const genesetDelete = (genesetName) => (dispatch, getState) => {
});
};
export const genesetAddGenes = (genesetName, genes) => async (
dispatch,
getState
export const genesetAddGenes = (genesetName: any, genes: any) => async (
dispatch: any,
getState: any
) => {
const state = getState();
const { obsCrossfilter: prevObsCrossfilter, annoMatrix } = state;
@@ -50,7 +53,7 @@ export const genesetAddGenes = (genesetName, genes) => async (
const varIndex = schema.annotations.var.index;
const df = await annoMatrix.fetch("var", varIndex);
const geneNames = df.col(varIndex).asArray();
genes = genes.reduce((acc, gene) => {
genes = genes.reduce((acc: any, gene: any) => {
if (geneNames.indexOf(gene.geneSymbol) === -1) {
postUserErrorToast(
`${gene.geneSymbol} doesn't appear to be a valid gene name.`
@@ -78,9 +81,9 @@ export const genesetAddGenes = (genesetName, genes) => async (
});
};
export const genesetDeleteGenes = (genesetName, geneSymbols) => (
dispatch,
getState
export const genesetDeleteGenes = (genesetName: any, geneSymbols: any) => (
dispatch: any,
getState: any
) => {
const state = getState();
const obsCrossfilter = dropGeneset(dispatch, state, genesetName, geneSymbols);
@@ -97,7 +100,11 @@ export const genesetDeleteGenes = (genesetName, geneSymbols) => (
Private
*/
function dropGenesetSummaryDimension(obsCrossfilter, state, genesetName) {
function dropGenesetSummaryDimension(
obsCrossfilter: any,
state: any,
genesetName: any
) {
const { annoMatrix, genesets } = state;
const varIndex = annoMatrix.schema.annotations?.var?.index;
const gs = genesets?.genesets?.get(genesetName) ?? {};
@@ -113,7 +120,7 @@ function dropGenesetSummaryDimension(obsCrossfilter, state, genesetName) {
return obsCrossfilter.dropDimension("X", query);
}
function dropGeneDimension(obsCrossfilter, state, gene) {
function dropGeneDimension(obsCrossfilter: any, state: any, gene: any) {
const { annoMatrix } = state;
const varIndex = annoMatrix.schema.annotations?.var?.index;
const query = {
@@ -126,10 +133,16 @@ function dropGeneDimension(obsCrossfilter, state, gene) {
return obsCrossfilter.dropDimension("X", query);
}
function dropGeneset(dispatch, state, genesetName, geneSymbols) {
function dropGeneset(
dispatch: any,
state: any,
genesetName: any,
geneSymbols: any
) {
const { obsCrossfilter: prevObsCrossfilter } = state;
const obsCrossfilter = geneSymbols.reduce(
(crossfilter, gene) => dropGeneDimension(crossfilter, state, gene),
(crossfilter: any, gene: any) =>
dropGeneDimension(crossfilter, state, gene),
dropGenesetSummaryDimension(prevObsCrossfilter, state, genesetName)
);
dispatch({
@@ -137,7 +150,7 @@ function dropGeneset(dispatch, state, genesetName, geneSymbols) {
continuousNamespace: { isGeneSetSummary: true },
selection: genesetName,
});
geneSymbols.forEach((g) =>
geneSymbols.forEach((g: any) =>
dispatch({
type: "continuous metadata histogram cancel",
continuousNamespace: { isUserDefined: true },
@@ -15,7 +15,7 @@ import * as genesetActions from "./geneset";
/*
return promise fetching user-configured colors
*/
async function userColorsFetchAndLoad(dispatch) {
async function userColorsFetchAndLoad(dispatch: any) {
return fetchJson("colors").then((response) =>
dispatch({
type: "universe: user color load success",
@@ -28,7 +28,7 @@ async function schemaFetch() {
return fetchJson("schema");
}
async function configFetch(dispatch) {
async function configFetch(dispatch: any) {
return fetchJson("config").then((response) => {
const config = { ...globals.configDefaults, ...response.config };
dispatch({
@@ -39,7 +39,7 @@ async function configFetch(dispatch) {
});
}
async function userInfoFetch(dispatch) {
async function userInfoFetch(dispatch: any) {
return fetchJson("userinfo").then((response) => {
const { userinfo: userInfo } = response || {};
dispatch({
@@ -50,7 +50,7 @@ async function userInfoFetch(dispatch) {
});
}
async function genesetsFetch(dispatch, config) {
async function genesetsFetch(dispatch: any, config: any) {
/* request genesets ONLY if the backend supports the feature */
const defaultResponse = {
genesets: [],
@@ -71,25 +71,26 @@ async function genesetsFetch(dispatch, config) {
}
}
function prefetchEmbeddings(annoMatrix) {
function prefetchEmbeddings(annoMatrix: any) {
/*
prefetch requests for all embeddings
*/
const { schema } = annoMatrix;
const available = schema.layout.obs.map((v) => v.name);
available.forEach((embName) => annoMatrix.prefetch("emb", embName));
const available = schema.layout.obs.map((v: any) => v.name);
available.forEach((embName: any) => annoMatrix.prefetch("emb", embName));
}
/*
Application bootstrap
*/
const doInitialDataLoad = () =>
catchErrorsWrap(async (dispatch) => {
catchErrorsWrap(async (dispatch: any) => {
dispatch({ type: "initial data load start" });
try {
const [config, schema] = await Promise.all([
configFetch(dispatch),
// @ts-expect-error ts-migrate(2554) FIXME: Expected 0 arguments, but got 1.
schemaFetch(dispatch),
userColorsFetchAndLoad(dispatch),
userInfoFetch(dispatch),
@@ -113,7 +114,7 @@ const doInitialDataLoad = () =>
const layoutSchema = schema?.schema?.layout?.obs ?? [];
if (
defaultEmbedding &&
layoutSchema.some((s) => s.name === defaultEmbedding)
layoutSchema.some((s: any) => s.name === defaultEmbedding)
) {
dispatch(embActions.layoutChoiceAction(defaultEmbedding));
}
@@ -122,21 +123,22 @@ const doInitialDataLoad = () =>
}
}, true);
function requestSingleGeneExpressionCountsForColoringPOST(gene) {
function requestSingleGeneExpressionCountsForColoringPOST(gene: any) {
return {
type: "color by expression",
gene,
};
}
const requestUserDefinedGene = (gene) => ({
const requestUserDefinedGene = (gene: any) => ({
type: "request user defined gene success",
data: {
genes: [gene],
},
});
const dispatchDiffExpErrors = (dispatch, response) => {
const dispatchDiffExpErrors = (dispatch: any, response: any) => {
switch (response.status) {
case 403:
dispatchNetworkErrorMessageToUser(
@@ -159,10 +161,11 @@ const dispatchDiffExpErrors = (dispatch, response) => {
}
};
const requestDifferentialExpression = (set1, set2, num_genes = 50) => async (
dispatch,
getState
) => {
const requestDifferentialExpression = (
set1: any,
set2: any,
num_genes = 50
) => async (dispatch: any, getState: any) => {
dispatch({ type: "request differential expression started" });
try {
/*
@@ -210,7 +213,8 @@ const requestDifferentialExpression = (set1, set2, num_genes = 50) => async (
const varIndex = await annoMatrix.fetch("var", varIndexName);
const diffexpLists = { negative: [], positive: [] };
for (const polarity of Object.keys(diffexpLists)) {
diffexpLists[polarity] = response[polarity].map((v) => [
// @ts-expect-error ts-migrate(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
diffexpLists[polarity] = response[polarity].map((v: any) => [
varIndex.at(v[0], varIndexName),
...v.slice(1),
]);
@@ -229,7 +233,7 @@ const requestDifferentialExpression = (set1, set2, num_genes = 50) => async (
}
};
function fetchJson(pathAndQuery) {
function fetchJson(pathAndQuery: any) {
return doJsonRequest(
`${globals.API.prefix}${globals.API.version}${pathAndQuery}`
);
@@ -2,11 +2,11 @@
Action creators for selection
*/
export const selectContinuousMetadataAction = (
type,
query,
range,
type: any,
query: any,
range: any,
oldProps = {}
) => async (dispatch, getState) => {
) => async (dispatch: any, getState: any) => {
const { obsCrossfilter: prevObsCrossfilter } = getState();
const selection = range
@@ -29,13 +29,13 @@ export const selectContinuousMetadataAction = (
};
export const selectCategoricalMetadataAction = (
type, // action type
metadataField, // annotation category name
labels,
label, // the label being selected/deselected
isSelected, // bool
type: any, // action type
metadataField: any, // annotation category name
labels: any,
label: any, // the label being selected/deselected
isSelected: any, // bool
oldProps = {}
) => async (dispatch, getState) => {
) => async (dispatch: any, getState: any) => {
const {
obsCrossfilter: prevObsCrossfilter,
categoricalSelection,
@@ -43,7 +43,7 @@ export const selectCategoricalMetadataAction = (
const labelSelectionState = new Map(categoricalSelection[metadataField]);
labels.forEach(
(l) => labelSelectionState.has(l) || labelSelectionState.set(l, true)
(l: any) => labelSelectionState.has(l) || labelSelectionState.set(l, true)
);
labelSelectionState.set(label, isSelected);
@@ -70,19 +70,19 @@ export const selectCategoricalMetadataAction = (
};
export const selectCategoricalAllMetadataAction = (
type, // action type
metadataField, // annotation category name
labels,
isSelected, // bool, select all or none
type: any, // action type
metadataField: any, // annotation category name
labels: any,
isSelected: any, // bool, select all or none
oldProps = {}
) => async (dispatch, getState) => {
) => async (dispatch: any, getState: any) => {
const {
obsCrossfilter: prevObsCrossfilter,
categoricalSelection,
} = getState();
const labelSelectionState = new Map(categoricalSelection[metadataField]);
labels.forEach((label) => labelSelectionState.set(label, isSelected));
labels.forEach((label: any) => labelSelectionState.set(label, isSelected));
const selection = { mode: isSelected ? "all" : "none" };
const obsCrossfilter = await prevObsCrossfilter.select(
@@ -108,10 +108,11 @@ export const graphBrushStartAction = () =>
/* no change to crossfilter until a change fires */
({ type: "graph brush start" });
const _graphBrushWithinRectAction = (type, embName, brushCoords) => async (
dispatch,
getState
) => {
const _graphBrushWithinRectAction = (
type: any,
embName: any,
brushCoords: any
) => async (dispatch: any, getState: any) => {
const { obsCrossfilter: prevObsCrossfilter } = getState();
const selection = { mode: "within-rect", ...brushCoords };
@@ -128,7 +129,10 @@ const _graphBrushWithinRectAction = (type, embName, brushCoords) => async (
});
};
const _graphAllAction = (type, embName) => async (dispatch, getState) => {
const _graphAllAction = (type: any, embName: any) => async (
dispatch: any,
getState: any
) => {
const { obsCrossfilter: prevObsCrossfilter } = getState();
const obsCrossfilter = await prevObsCrossfilter.select("emb", embName, {
@@ -141,30 +145,30 @@ const _graphAllAction = (type, embName) => async (dispatch, getState) => {
});
};
export const graphBrushChangeAction = (embName, brushCoords) =>
export const graphBrushChangeAction = (embName: any, brushCoords: any) =>
_graphBrushWithinRectAction("graph brush change", embName, brushCoords);
export const graphBrushEndAction = (embName, brushCoords) =>
export const graphBrushEndAction = (embName: any, brushCoords: any) =>
_graphBrushWithinRectAction("graph brush end", embName, brushCoords);
export const graphBrushCancelAction = (embName) =>
export const graphBrushCancelAction = (embName: any) =>
_graphAllAction("graph brush cancel", embName);
export const graphBrushDeselectAction = (embName) =>
export const graphBrushDeselectAction = (embName: any) =>
_graphAllAction("graph brush deselect", embName);
export const graphLassoStartAction = () =>
/* no change to crossfilter until a change fires */
({ type: "graph lasso start" });
export const graphLassoCancelAction = (embName) =>
export const graphLassoCancelAction = (embName: any) =>
_graphAllAction("graph lasso cancel", embName);
export const graphLassoDeselectAction = (embName) =>
export const graphLassoDeselectAction = (embName: any) =>
_graphAllAction("graph lasso cancel", embName);
export const graphLassoEndAction = (embName, polygon) => async (
dispatch,
getState
export const graphLassoEndAction = (embName: any, polygon: any) => async (
dispatch: any,
getState: any
) => {
const { obsCrossfilter: prevObsCrossfilter } = getState();
@@ -188,7 +192,10 @@ export const graphLassoEndAction = (embName, polygon) => async (
/*
Differential expression set selection
*/
export const setCellSetFromSelection = (cellSetId) => (dispatch, getState) => {
export const setCellSetFromSelection = (cellSetId: any) => (
dispatch: any,
getState: any
) => {
const { obsCrossfilter } = getState();
const selected = obsCrossfilter.allSelectedLabels();
@@ -18,7 +18,10 @@ import {
_userResetSubsetAnnoMatrix,
} from "../util/stateManager/viewStackHelpers";
export const clipAction = (min, max) => (dispatch, getState) => {
export const clipAction = (min: any, max: any) => (
dispatch: any,
getState: any
) => {
/*
apply a clip to the current annoMatrix. By convention, the clip
view is ALWAYS the top view.
@@ -34,7 +37,7 @@ export const clipAction = (min, max) => (dispatch, getState) => {
});
};
export const subsetAction = () => (dispatch, getState) => {
export const subsetAction = () => (dispatch: any, getState: any) => {
/*
Subset the annoMatrix to the current crossfilter selection by pushing a
subset view.
@@ -58,7 +61,7 @@ export const subsetAction = () => (dispatch, getState) => {
});
};
export const resetSubsetAction = () => (dispatch, getState) => {
export const resetSubsetAction = () => (dispatch: any, getState: any) => {
/*
Reset the annoMatrix to all data. Because we may have multiple views
stacked, we pop them all. By convention, any clip transformation will
@@ -17,6 +17,28 @@ import { _queryValidate, _queryCacheKey } from "./query";
const _dataframeCache = dataframeMemo(128);
export default class AnnoMatrix {
public isView: any;
public nObs: any;
public nVar: any;
public rowIndex: any;
public schema: any;
public userFlags: any;
public viewOf: any;
protected _cache: any;
private _pendingLoad: any;
private _whereCache: any;
private _gcInfo: any;
/*
Abstract base class for all AnnoMatrix objects. This class provides a proxy
to the annotated matrix data authoritatively served by the server/back-end.
@@ -54,7 +76,7 @@ export default class AnnoMatrix {
return ["obs", "var", "emb", "X"];
}
constructor(schema, nObs, nVar, rowIndex = null) {
constructor(schema: any, nObs: any, nVar: any, rowIndex = null) {
/*
Private constructor - this is an abstract base class. Do not use.
*/
@@ -83,13 +105,13 @@ export default class AnnoMatrix {
this.userFlags = {};
/*
Private instance variables.
Private instance variables.
These are caches - lazily loaded. The only guarantee is that if they
are loaded, they will conform to the schema & dimensionality constraints.
These are caches - lazily loaded. The only guarantee is that if they
are loaded, they will conform to the schema & dimensionality constraints.
Do NOT use directly - instead, use the fetch() and preload() API.
*/
Do NOT use directly - instead, use the fetch() and preload() API.
*/
this._cache = {
obs: Dataframe.empty(this.rowIndex),
var: Dataframe.empty(this.rowIndex),
@@ -109,6 +131,7 @@ export default class AnnoMatrix {
/**
** Schema helper/accessors
**/
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
getMatrixColumns(field) {
/*
Return array of column names in the field. ONLY supported on the
@@ -132,6 +155,7 @@ export default class AnnoMatrix {
return AnnoMatrix.fields();
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
getColumnSchema(field, col) {
/*
Return the schema for the field & column ,eg,
@@ -144,6 +168,7 @@ export default class AnnoMatrix {
return _getColumnSchema(this.schema, field, col);
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
getColumnDimensions(field, col) {
/*
Return the dimensions on this field / column. For most fields, which are 1D,
@@ -174,6 +199,7 @@ export default class AnnoMatrix {
/**
** Load / read interfaces
**/
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
fetch(field, q) {
/*
Return the given query on a single matrix field as a single dataframe.
@@ -231,6 +257,7 @@ export default class AnnoMatrix {
return this._fetch(field, q);
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
prefetch(field, q) {
/*
Start a data fetch & cache fill. Identical to fetch() except it does
@@ -261,7 +288,8 @@ export default class AnnoMatrix {
** The actual implementation is in the sub-classes, which MUST override these.
**/
// eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements
// @ts-expect-error ts-migrate(6133) FIXME: 'col' is declared but its value is never read.
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements
addObsAnnoCategory(col, category) {
/*
Add a new category value (aka "label") to a writable obs column, and return the new AnnoMatrix.
@@ -278,7 +306,8 @@ export default class AnnoMatrix {
_subclassResponsibility();
}
// eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements
// @ts-expect-error ts-migrate(6133) FIXME: 'col' is declared but its value is never read.
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements
async removeObsAnnoCategory(col, category, unassignedCategory) {
/*
Remove a category value from an obs column, reassign any obs having that value
@@ -299,7 +328,8 @@ export default class AnnoMatrix {
_subclassResponsibility();
}
// eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements
// @ts-expect-error ts-migrate(6133) FIXME: 'col' is declared but its value is never read.
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements
dropObsColumn(col) {
/*
Drop an entire writable column, eg a user-created obs annotation. Typical use
@@ -315,7 +345,8 @@ export default class AnnoMatrix {
_subclassResponsibility();
}
// eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements
// @ts-expect-error ts-migrate(6133) FIXME: 'colSchema' is declared but its value is never rea... Remove this comment to see the full error message
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements
addObsColumn(colSchema, Ctor, value) {
/*
Add a new writable OBS annotation column, with the caller-specified schema, initial value
@@ -344,7 +375,8 @@ export default class AnnoMatrix {
_subclassResponsibility();
}
// eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements
// @ts-expect-error ts-migrate(6133) FIXME: 'oldCol' is declared but its value is never read.
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements
renameObsColumn(oldCol, newCol) {
/*
Rename the obs column 'oldCol' to have name 'newCol' and returns new AnnoMatrix.
@@ -359,7 +391,8 @@ export default class AnnoMatrix {
_subclassResponsibility();
}
// eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements
// @ts-expect-error ts-migrate(6133) FIXME: 'col' is declared but its value is never read.
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements
async setObsColumnValues(col, obsLabels, value) {
/*
Set all obs with label in array 'obsLabels' to have 'value'. Typical use would be
@@ -377,7 +410,8 @@ export default class AnnoMatrix {
_subclassResponsibility();
}
// eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements
// @ts-expect-error ts-migrate(6133) FIXME: 'col' is declared but its value is never read.
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements
async resetObsColumnValues(col, oldValue, newValue) {
/*
Set by value - all elements in the column with value 'oldValue' are set to 'newValue'.
@@ -394,7 +428,8 @@ export default class AnnoMatrix {
_subclassResponsibility();
}
// eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements
// @ts-expect-error ts-migrate(6133) FIXME: 'colSchema' is declared but its value is never rea... Remove this comment to see the full error message
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements
addEmbedding(colSchema) {
/*
Add a new obs embedding to the AnnoMatrix, with provided schema.
@@ -407,28 +442,35 @@ export default class AnnoMatrix {
_subclassResponsibility();
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
getCacheKeys(field, query) {
/*
Return cache keys for columns associated with this query. May return
[unknown] if no keys are known (ie, nothing is or was cached).
*/
Return cache keys for columns associated with this query. May return
[unknown] if no keys are known (ie, nothing is or was cached).
*/
return _whereCacheGet(this._whereCache, this.schema, field, query);
}
/**
** Private interfaces below.
**/
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
_resolveCachedQueries(field, queries) {
return queries
.map((query) =>
_whereCacheGet(this._whereCache, this.schema, field, query).filter(
(cacheKey) =>
cacheKey !== undefined && this._cache[field].hasCol(cacheKey)
return (
queries
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'query' implicitly has an 'any' type.
.map((query) =>
_whereCacheGet(this._whereCache, this.schema, field, query).filter(
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'cacheKey' implicitly has an 'any' type.
(cacheKey) =>
cacheKey !== undefined && this._cache[field].hasCol(cacheKey)
)
)
)
.flat();
.flat()
);
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
async _fetch(field, q) {
if (!AnnoMatrix.fields().includes(field)) return undefined;
const queries = Array.isArray(q) ? q : [q];
@@ -441,6 +483,7 @@ export default class AnnoMatrix {
/* find any query not already cached */
const uncachedQueries = queries.filter((query) =>
_whereCacheGet(this._whereCache, this.schema, field, query).some(
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'cacheKey' implicitly has an 'any' type.
(cacheKey) =>
cacheKey === undefined || !this._cache[field].hasCol(cacheKey)
)
@@ -450,8 +493,10 @@ export default class AnnoMatrix {
if (uncachedQueries.length > 0) {
await Promise.all(
uncachedQueries.map((query) =>
// @ts-expect-error ts-migrate(7006) FIXME: Parameter '_field' implicitly has an 'any' type.
this._getPendingLoad(field, query, async (_field, _query) => {
/* fetch, then index. _doLoad is subclass interface */
// @ts-expect-error ts-migrate(2488) FIXME: Type 'void' must have a '[Symbol.iterator]()' meth... Remove this comment to see the full error message
const [whereCacheUpdate, df] = await this._doLoad(_field, _query);
this._cache[_field] = this._cache[_field].withColsFrom(df);
this._whereCache = _whereCacheMerge(
@@ -472,6 +517,7 @@ export default class AnnoMatrix {
return response;
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
async _getPendingLoad(field, query, fetchFn) {
/*
Given a query on a field, ensure that we only have a single outstanding
@@ -527,19 +573,21 @@ export default class AnnoMatrix {
To be effective, the GC callback needs to be invoked from the undo/redo code,
as much of the cache is pinned by that data structure.
*/
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
_gcField(field, isHot, pinnedColumns) {
const maxColumns = isHot ? 256 : 10; // maybe to aggressive?
const maxColumns = isHot ? 256 : 10;
const cache = this._cache[field];
if (cache.colIndex.size() < maxColumns) return; // trivial rejection
const candidates = cache.colIndex
.labels()
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type.
.filter((col) => !pinnedColumns.includes(col));
const excessCount = candidates.length + pinnedColumns.length - maxColumns;
if (excessCount > 0) {
const { _gcInfo } = this;
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'a' implicitly has an 'any' type.
candidates.sort((a, b) => {
let atime = _gcInfo.get(_columnCacheKey(field, a));
if (atime === undefined) atime = 0;
@@ -558,13 +606,16 @@ export default class AnnoMatrix {
// )}]`
// );
this._cache[field] = toDrop.reduce(
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'df' implicitly has an 'any' type.
(df, col) => df.dropCol(col),
this._cache[field]
);
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type.
toDrop.forEach((col) => _gcInfo.delete(_columnCacheKey(field, col)));
}
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
_gcFetchCleanup(field, pinnedColumns) {
/*
Called during data load/fetch. By definition, this is 'hot', so we
@@ -579,6 +630,7 @@ export default class AnnoMatrix {
}
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'hints' implicitly has an 'any' type.
_gc(hints) {
/*
Called from middleware, or elsewhere. isHot is true if we are in the active store,
@@ -591,6 +643,7 @@ export default class AnnoMatrix {
);
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
_gcUpdateStats(field, dataframe) {
/*
called each time a query is performed, allowing the gc to update any bookkeeping
@@ -600,6 +653,7 @@ export default class AnnoMatrix {
const cols = dataframe.colIndex.labels();
const { _gcInfo } = this;
const now = Date.now();
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'c' implicitly has an 'any' type.
cols.forEach((c) => {
_gcInfo.set(_columnCacheKey(field, c), now);
});
@@ -617,6 +671,7 @@ export default class AnnoMatrix {
Do not override _clone();
**/
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'clone' implicitly has an 'any' type.
_cloneDeeper(clone) {
clone._cache = _shallowClone(this._cache);
clone._gcInfo = new Map();
@@ -640,6 +695,7 @@ export default class AnnoMatrix {
/*
private utility functions below
*/
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
function _columnCacheKey(field, column) {
return `${field}/${column}`;
}
@@ -1,6 +1,6 @@
/*
Shallow clone an object, correctly handling prototype
*/
export default function _shallowClone(orig) {
export default function _shallowClone(orig: any) {
return Object.assign(Object.create(Object.getPrototypeOf(orig)), orig);
}
@@ -10,26 +10,31 @@ AnnoMatrix stay in sync:
import Crossfilter from "../util/typedCrossfilter";
import { _getColumnSchema } from "./schema";
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
function _dimensionNameFromDf(field, df) {
const colNames = df.colIndex.labels();
return _dimensionName(field, colNames);
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
function _dimensionName(field, colNames) {
if (!Array.isArray(colNames)) return `${field}/${colNames}`;
return `${field}/${colNames.join(":")}`;
}
export default class AnnoMatrixObsCrossfilter {
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message
constructor(annoMatrix, _obsCrossfilter = null) {
this.annoMatrix = annoMatrix;
this.obsCrossfilter =
(this as any).annoMatrix = annoMatrix;
(this as any).obsCrossfilter =
_obsCrossfilter || new Crossfilter(annoMatrix._cache.obs);
this.obsCrossfilter = this.obsCrossfilter.setData(annoMatrix._cache.obs);
(this as any).obsCrossfilter = (this as any).obsCrossfilter.setData(
annoMatrix._cache.obs
);
}
size() {
return this.obsCrossfilter.size();
return (this as any).obsCrossfilter.size();
}
/**
@@ -39,14 +44,23 @@ export default class AnnoMatrixObsCrossfilter {
See API documentation in annoMatrix.js.
**/
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colSchema' implicitly has an 'any' type... Remove this comment to see the full error message
addObsColumn(colSchema, Ctor, value) {
const annoMatrix = this.annoMatrix.addObsColumn(colSchema, Ctor, value);
const obsCrossfilter = this.obsCrossfilter.setData(annoMatrix._cache.obs);
const annoMatrix = (this as any).annoMatrix.addObsColumn(
colSchema,
Ctor,
value
);
const obsCrossfilter = (this as any).obsCrossfilter.setData(
annoMatrix._cache.obs
);
return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter);
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type.
dropObsColumn(col) {
const annoMatrix = this.annoMatrix.dropObsColumn(col);
const annoMatrix = (this as any).annoMatrix.dropObsColumn(col);
// @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message
let { obsCrossfilter } = this;
const dimName = _dimensionName("obs", col);
if (obsCrossfilter.hasDimension(dimName)) {
@@ -55,10 +69,12 @@ export default class AnnoMatrixObsCrossfilter {
return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter);
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'oldCol' implicitly has an 'any' type.
renameObsColumn(oldCol, newCol) {
const annoMatrix = this.annoMatrix.renameObsColumn(oldCol, newCol);
const annoMatrix = (this as any).annoMatrix.renameObsColumn(oldCol, newCol);
const oldDimName = _dimensionName("obs", oldCol);
const newDimName = _dimensionName("obs", newCol);
// @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message
let { obsCrossfilter } = this;
if (obsCrossfilter.hasDimension(oldDimName)) {
obsCrossfilter = obsCrossfilter.renameDimension(oldDimName, newDimName);
@@ -66,9 +82,14 @@ export default class AnnoMatrixObsCrossfilter {
return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter);
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type.
addObsAnnoCategory(col, category) {
const annoMatrix = this.annoMatrix.addObsAnnoCategory(col, category);
const annoMatrix = (this as any).annoMatrix.addObsAnnoCategory(
col,
category
);
const dimName = _dimensionName("obs", col);
// @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message
let { obsCrossfilter } = this;
if (obsCrossfilter.hasDimension(dimName)) {
obsCrossfilter = obsCrossfilter.delDimension(dimName);
@@ -76,13 +97,15 @@ export default class AnnoMatrixObsCrossfilter {
return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter);
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type.
async removeObsAnnoCategory(col, category, unassignedCategory) {
const annoMatrix = await this.annoMatrix.removeObsAnnoCategory(
const annoMatrix = await (this as any).annoMatrix.removeObsAnnoCategory(
col,
category,
unassignedCategory
);
const dimName = _dimensionName("obs", col);
// @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message
let { obsCrossfilter } = this;
if (obsCrossfilter.hasDimension(dimName)) {
obsCrossfilter = obsCrossfilter.delDimension(dimName);
@@ -90,13 +113,15 @@ export default class AnnoMatrixObsCrossfilter {
return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter);
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type.
async setObsColumnValues(col, rowLabels, value) {
const annoMatrix = await this.annoMatrix.setObsColumnValues(
const annoMatrix = await (this as any).annoMatrix.setObsColumnValues(
col,
rowLabels,
value
);
const dimName = _dimensionName("obs", col);
// @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message
let { obsCrossfilter } = this;
if (obsCrossfilter.hasDimension(dimName)) {
obsCrossfilter = obsCrossfilter.delDimension(dimName);
@@ -104,13 +129,15 @@ export default class AnnoMatrixObsCrossfilter {
return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter);
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type.
async resetObsColumnValues(col, oldValue, newValue) {
const annoMatrix = await this.annoMatrix.resetObsColumnValues(
const annoMatrix = await (this as any).annoMatrix.resetObsColumnValues(
col,
oldValue,
newValue
);
const dimName = _dimensionName("obs", col);
// @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message
let { obsCrossfilter } = this;
if (obsCrossfilter.hasDimension(dimName)) {
obsCrossfilter = obsCrossfilter.delDimension(dimName);
@@ -118,9 +145,13 @@ export default class AnnoMatrixObsCrossfilter {
return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter);
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colSchema' implicitly has an 'any' type... Remove this comment to see the full error message
addEmbedding(colSchema) {
const annoMatrix = this.annoMatrix.addEmbedding(colSchema);
return new AnnoMatrixObsCrossfilter(annoMatrix, this.obsCrossfilter);
const annoMatrix = (this as any).annoMatrix.addEmbedding(colSchema);
return new AnnoMatrixObsCrossfilter(
annoMatrix,
(this as any).obsCrossfilter
);
}
/**
@@ -128,11 +159,15 @@ export default class AnnoMatrixObsCrossfilter {
* want to stop trackin the selection state, but aren't sure we want to blow the
* annomatrix cache.
*/
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
dropDimension(field, query) {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annoMatrix' does not exist on type 'Anno... Remove this comment to see the full error message
const { annoMatrix } = this;
// @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message
let { obsCrossfilter } = this;
const keys = annoMatrix
.getCacheKeys(field, query)
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'k' implicitly has an 'any' type.
.filter((k) => k !== undefined);
const dimName = _dimensionName(field, keys);
if (obsCrossfilter.hasDimension(dimName)) {
@@ -146,8 +181,11 @@ export default class AnnoMatrixObsCrossfilter {
are just wrappers to lazy create indices.
**/
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
async select(field, query, spec) {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annoMatrix' does not exist on type 'Anno... Remove this comment to see the full error message
const { annoMatrix } = this;
// @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message
let { obsCrossfilter } = this;
if (!annoMatrix?._cache?.[field]) {
@@ -180,55 +218,59 @@ export default class AnnoMatrixObsCrossfilter {
/*
Select all on any dimension in this field.
*/
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annoMatrix' does not exist on type 'Anno... Remove this comment to see the full error message
const { annoMatrix } = this;
const currentDims = this.obsCrossfilter.dimensionNames();
const currentDims = (this as any).obsCrossfilter.dimensionNames();
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'xfltr' implicitly has an 'any' type.
const obsCrossfilter = currentDims.reduce((xfltr, dim) => {
return xfltr.select(dim, { mode: "all" });
}, this.obsCrossfilter);
}, (this as any).obsCrossfilter);
return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter);
}
countSelected() {
/* if no data yet indexed in the crossfilter, just say everything is selected */
if (this.obsCrossfilter.size() === 0) return this.annoMatrix.nObs;
return this.obsCrossfilter.countSelected();
if ((this as any).obsCrossfilter.size() === 0)
return (this as any).annoMatrix.nObs;
return (this as any).obsCrossfilter.countSelected();
}
allSelectedMask() {
/* if no data yet indexed in the crossfilter, just say everything is selected */
if (
this.obsCrossfilter.size() === 0 ||
this.obsCrossfilter.dimensionNames().length === 0
(this as any).obsCrossfilter.size() === 0 ||
(this as any).obsCrossfilter.dimensionNames().length === 0
) {
/* fake the mask */
return new Uint8Array(this.annoMatrix.nObs).fill(1);
return new Uint8Array((this as any).annoMatrix.nObs).fill(1);
}
return this.obsCrossfilter.allSelectedMask();
return (this as any).obsCrossfilter.allSelectedMask();
}
allSelectedLabels() {
/* if no data yet indexed in the crossfilter, just say everything is selected */
if (
this.obsCrossfilter.size() === 0 ||
this.obsCrossfilter.dimensionNames().length === 0
(this as any).obsCrossfilter.size() === 0 ||
(this as any).obsCrossfilter.dimensionNames().length === 0
) {
return this.annoMatrix.rowIndex.labels();
return (this as any).annoMatrix.rowIndex.labels();
}
const mask = this.obsCrossfilter.allSelectedMask();
const index = this.annoMatrix.rowIndex.isubsetMask(mask);
const mask = (this as any).obsCrossfilter.allSelectedMask();
const index = (this as any).annoMatrix.rowIndex.isubsetMask(mask);
return index.labels();
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'array' implicitly has an 'any' type.
fillByIsSelected(array, selectedValue, deselectedValue) {
/* if no data yet indexed in the crossfilter, just say everything is selected */
if (
this.obsCrossfilter.size() === 0 ||
this.obsCrossfilter.dimensionNames().length === 0
(this as any).obsCrossfilter.size() === 0 ||
(this as any).obsCrossfilter.dimensionNames().length === 0
) {
return array.fill(selectedValue);
}
return this.obsCrossfilter.fillByIsSelected(
return (this as any).obsCrossfilter.fillByIsSelected(
array,
selectedValue,
deselectedValue
@@ -239,21 +281,29 @@ export default class AnnoMatrixObsCrossfilter {
** Private below
**/
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message
_addObsCrossfilterDimension(annoMatrix, obsCrossfilter, field, df) {
if (field === "var") return obsCrossfilter;
const dimName = _dimensionNameFromDf(field, df);
const dimParams = this._getObsDimensionParams(field, df);
obsCrossfilter = obsCrossfilter.setData(annoMatrix._cache.obs);
// @ts-expect-error ts-migrate(2488) FIXME: Type 'any[] | undefined' must have a '[Symbol.iter... Remove this comment to see the full error message
obsCrossfilter = obsCrossfilter.addDimension(dimName, ...dimParams);
return obsCrossfilter;
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
_getColumnBaseType(field, col) {
/* Look up the primitive type for this field/col */
const colSchema = _getColumnSchema(this.annoMatrix.schema, field, col);
const colSchema = _getColumnSchema(
(this as any).annoMatrix.schema,
field,
col
);
return colSchema.type;
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
_getObsDimensionParams(field, df) {
/* return the crossfilter dimensiontype type and params for this field/dataframe */
@@ -1,19 +1,19 @@
export { doBinaryRequest, doFetch } from "../util/actionHelpers";
/* double URI encode - needed for query-param filters */
export function _dubEncURIComp(s) {
export function _dubEncURIComp(s: any) {
return encodeURIComponent(encodeURIComponent(s));
}
/* currently unused, consider deleting */
export function _fetchResult(promise) {
export function _fetchResult(promise: any) {
let _status = "pending";
const res = promise.then(
(r) => {
(r: any) => {
_status = "success";
return r;
},
(e) => {
(e: any) => {
_status = "error";
throw e;
}
@@ -23,6 +23,8 @@ import {
const promiseThrottle = new PromiseLimit(5);
export default class AnnoMatrixLoader extends AnnoMatrix {
baseURL: any;
/*
AnnoMatrix implementation which proxies to HTTP server using the CXG REST API.
Used as the base (non-view) instance.
@@ -33,7 +35,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
new AnnoMatrixLoader(serverBaseURL, schema) -> instance
*/
constructor(baseURL, schema) {
constructor(baseURL: any, schema: any) {
const { nObs, nVar } = schema.dataframe;
super(schema, nObs, nVar);
@@ -48,7 +50,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
/**
** Public. API described in base class.
**/
addObsAnnoCategory(col, category) {
addObsAnnoCategory(col: any, category: any) {
/*
Add a new category (aka label) to the schema for an obs column.
*/
@@ -60,7 +62,11 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
return newAnnoMatrix;
}
async removeObsAnnoCategory(col, category, unassignedCategory) {
async removeObsAnnoCategory(
col: any,
category: any,
unassignedCategory: any
) {
/*
Remove a single "category" (aka "label") from the data & schema of an obs column.
*/
@@ -80,7 +86,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
return newAnnoMatrix;
}
dropObsColumn(col) {
dropObsColumn(col: any) {
/*
drop column from field
*/
@@ -88,11 +94,12 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
_writableCheck(colSchema); // throws on error
const newAnnoMatrix = this._clone();
newAnnoMatrix._cache.obs = this._cache.obs.dropCol(col);
newAnnoMatrix._cache.obs = (this as any)._cache.obs.dropCol(col);
newAnnoMatrix.schema = removeObsAnnoColumn(this.schema, col);
return newAnnoMatrix;
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colSchema' implicitly has an 'any' type... Remove this comment to see the full error message
addObsColumn(colSchema, Ctor, value) {
/*
add a column to field, initializing with value. Value may
@@ -105,7 +112,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
const colName = colSchema.name;
if (
_getColumnSchema(this.schema, "obs", colName) ||
this._cache.obs.hasCol(colName)
(this as any)._cache.obs.hasCol(colName)
) {
throw new Error("column already exists");
}
@@ -121,7 +128,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
} else {
data = new Ctor(this.nObs).fill(value);
}
newAnnoMatrix._cache.obs = this._cache.obs.withCol(colName, data);
newAnnoMatrix._cache.obs = (this as any)._cache.obs.withCol(colName, data);
_normalizeCategoricalSchema(
colSchema,
newAnnoMatrix._cache.obs.col(colName)
@@ -130,15 +137,15 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
return newAnnoMatrix;
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'oldCol' implicitly has an 'any' type.
renameObsColumn(oldCol, newCol) {
/*
Rename the obs oldColName to newColName. oldCol must be writable.
*/
const oldColSchema = _getColumnSchema(this.schema, "obs", oldCol);
_writableCheck(oldColSchema); // throws on error
const value = this._cache.obs.hasCol(oldCol)
? this._cache.obs.col(oldCol).asArray()
_writableCheck(oldColSchema);
const value = (this as any)._cache.obs.hasCol(oldCol)
? (this as any)._cache.obs.col(oldCol).asArray()
: undefined;
return this.dropObsColumn(oldCol).addObsColumn(
{
@@ -150,6 +157,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
);
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type.
async setObsColumnValues(col, rowLabels, value) {
/*
Set all rows identified by rowLabels to value.
@@ -159,11 +167,11 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
// ensure that we have the data in cache before we manipulate it
await this.fetch("obs", col);
if (!this._cache.obs.hasCol(col))
if (!(this as any)._cache.obs.hasCol(col))
throw new Error("Internal error - user annotation data missing");
const rowIndices = this.rowIndex.getOffsets(rowLabels);
const data = this._cache.obs.col(col).asArray().slice();
const data = (this as any)._cache.obs.col(col).asArray().slice();
for (let i = 0, len = rowIndices.length; i < len; i += 1) {
const idx = rowIndices[i];
if (idx === undefined) throw new Error("Unknown row label");
@@ -171,7 +179,10 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
}
const newAnnoMatrix = this._clone();
newAnnoMatrix._cache.obs = this._cache.obs.replaceColData(col, data);
newAnnoMatrix._cache.obs = (this as any)._cache.obs.replaceColData(
col,
data
);
const { categories } = colSchema;
if (!categories?.includes(value)) {
newAnnoMatrix.schema = addObsAnnoCategory(this.schema, col, value);
@@ -179,6 +190,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
return newAnnoMatrix;
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type.
async resetObsColumnValues(col, oldValue, newValue) {
/*
Set all rows with value 'oldValue' to 'newValue'.
@@ -192,16 +204,19 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
// ensure that we have the data in cache before we manipulate it
await this.fetch("obs", col);
if (!this._cache.obs.hasCol(col))
if (!(this as any)._cache.obs.hasCol(col))
throw new Error("Internal error - user annotation data missing");
const data = this._cache.obs.col(col).asArray().slice();
const data = (this as any)._cache.obs.col(col).asArray().slice();
for (let i = 0, l = data.length; i < l; i += 1) {
if (data[i] === oldValue) data[i] = newValue;
}
const newAnnoMatrix = this._clone();
newAnnoMatrix._cache.obs = this._cache.obs.replaceColData(col, data);
newAnnoMatrix._cache.obs = (this as any)._cache.obs.replaceColData(
col,
data
);
const { categories } = colSchema;
if (!categories?.includes(newValue)) {
newAnnoMatrix.schema = addObsAnnoCategory(this.schema, col, newValue);
@@ -209,6 +224,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
return newAnnoMatrix;
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colSchema' implicitly has an 'any' type... Remove this comment to see the full error message
addEmbedding(colSchema) {
/*
add new layout to the obs embeddings
@@ -226,6 +242,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
/**
** Private below
**/
// @ts-expect-error ts-migrate(2416) FIXME: Property '_doLoad' in type 'AnnoMatrixLoader' is n... Remove this comment to see the full error message
async _doLoad(field, query) {
/*
_doLoad - evaluates the query against the field. Returns:
@@ -280,12 +297,14 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
Utility functions below
*/
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colSchema' implicitly has an 'any' type... Remove this comment to see the full error message
function _writableCheck(colSchema) {
if (!colSchema?.writable) {
throw new Error("Unknown or readonly obs column");
}
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colSchema' implicitly has an 'any' type... Remove this comment to see the full error message
function _writableCategoryTypeCheck(colSchema) {
_writableCheck(colSchema);
if (colSchema.type !== "categorical") {
@@ -293,6 +312,7 @@ function _writableCategoryTypeCheck(colSchema) {
}
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'baseURL' implicitly has an 'any' type.
function _embLoader(baseURL, _field, query) {
_expectSimpleQuery(query);
@@ -302,6 +322,7 @@ function _embLoader(baseURL, _field, query) {
return () => doBinaryRequest(url);
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'baseURL' implicitly has an 'any' type.
function _obsOrVarLoader(baseURL, field, query) {
_expectSimpleQuery(query);
@@ -311,6 +332,7 @@ function _obsOrVarLoader(baseURL, field, query) {
return () => doBinaryRequest(url);
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'baseURL' implicitly has an 'any' type.
function _XLoader(baseURL, field, query) {
_expectComplexQuery(query);
@@ -11,7 +11,7 @@ Undoable metareducer and the AnnoMatrix private API. It would be helpful
to make the Undoable interface better factored.
*/
const annoMatrixGC = (store) => (next) => (action) => {
const annoMatrixGC = (store: any) => (next: any) => (action: any) => {
if (_itIsTimeForGC()) {
_doGC(store);
}
@@ -34,7 +34,7 @@ function _itIsTimeForGC() {
return false;
}
function _doGC(store) {
function _doGC(store: any) {
const state = store.getState();
// these should probably be a function imported from undoable.js, etc, as
@@ -43,8 +43,8 @@ function _doGC(store) {
const undoableFuture = state["@@undoable/future"];
const undoableStack = undoablePast
.concat(undoableFuture)
.flatMap((snapshot) =>
snapshot.filter((v) => v[0] === "annoMatrix").map((v) => v[1])
.flatMap((snapshot: any) =>
snapshot.filter((v: any) => v[0] === "annoMatrix").map((v: any) => v[1])
);
const currentAnnoMatrix = state.annoMatrix;
@@ -53,14 +53,16 @@ function _doGC(store) {
as our current gc algo is more aggressive with those not hot.
*/
const allAnnoMatrices = new Map(
undoableStack.map((m) => [m, { isHot: false }])
undoableStack.map((m: any) => [m, { isHot: false }])
);
let am = currentAnnoMatrix;
while (am) {
allAnnoMatrices.set(am, { isHot: true });
am = am.viewOf;
}
allAnnoMatrices.forEach((hints, annoMatrix) => annoMatrix._gc(hints));
allAnnoMatrices.forEach((hints, annoMatrix) =>
(annoMatrix as any)._gc(hints)
);
}
export default annoMatrixGC;
@@ -10,7 +10,7 @@ import { _dubEncURIComp } from "./fetchHelpers";
* @param {object | string} query - the query
* @returns {object | string} - the normalized query
*/
export function _queryValidate(query) {
export function _queryValidate(query: any) {
if (typeof query !== "object") return query;
if (query.where && query.summarize)
@@ -40,11 +40,11 @@ export function _queryValidate(query) {
throw new Error("query must specify one of where or summarize");
}
export function _expectSimpleQuery(query) {
export function _expectSimpleQuery(query: any) {
if (typeof query === "object") throw new Error("expected simple query");
}
export function _expectComplexQuery(query) {
export function _expectComplexQuery(query: any) {
if (typeof query !== "object") throw new Error("expected complex query");
}
@@ -55,7 +55,7 @@ export function _expectComplexQuery(query) {
* @param {string|object} query
* @returns the key
*/
export function _queryCacheKey(field, query) {
export function _queryCacheKey(field: any, query: any) {
if (typeof query === "object") {
// complex query
if (query.where) {
@@ -84,22 +84,22 @@ export function _queryCacheKey(field, query) {
return `${field}/${query}`;
}
function _urlEncodeWhereQuery(q) {
function _urlEncodeWhereQuery(q: any) {
const { field: queryField, column: queryColumn, value: queryValue } = q;
return `${_dubEncURIComp(queryField)}:${_dubEncURIComp(
queryColumn
)}=${_dubEncURIComp(queryValue)}`;
}
function _urlEncodeSummarizeQuery(q) {
function _urlEncodeSummarizeQuery(q: any) {
const { method, field, column, values } = q;
const filter = values
.map((value) => _urlEncodeWhereQuery({ field, column, value }))
.map((value: any) => _urlEncodeWhereQuery({ field, column, value }))
.join("&");
return `method=${method}&${filter}`;
}
export function _urlEncodeComplexQuery(q) {
export function _urlEncodeComplexQuery(q: any) {
if (typeof q === "object") {
if (q.where) {
return _urlEncodeWhereQuery(q.where);
@@ -111,7 +111,7 @@ export function _urlEncodeComplexQuery(q) {
throw new Error("Unrecognized complex query type");
}
export function _urlEncodeLabelQuery(colKey, q) {
export function _urlEncodeLabelQuery(colKey: any, q: any) {
if (!colKey) throw new Error("Unsupported query by name");
if (typeof q !== "string") throw new Error("Query must be a simple label.");
return `${colKey}=${encodeURIComponent(q)}`;
@@ -120,7 +120,7 @@ export function _urlEncodeLabelQuery(colKey, q) {
/**
* Generate the column key the server will send us for this query.
*/
export function _hashStringValues(arrayOfString) {
export function _hashStringValues(arrayOfString: any) {
const hash = sha1(arrayOfString.join(""));
return hash;
}
@@ -4,7 +4,7 @@ Private helper functions related to schema
import catLabelSort from "../util/catLabelSort";
import { unassignedCategoryLabel } from "../globals";
export function _getColumnSchema(schema, field, col) {
export function _getColumnSchema(schema: any, field: any, col: any) {
/* look up the column definition */
switch (field) {
case "obs":
@@ -26,7 +26,7 @@ export function _getColumnSchema(schema, field, col) {
}
}
export function _getColumnDimensionNames(schema, field, col) {
export function _getColumnDimensionNames(schema: any, field: any, col: any) {
/*
field/col may be an alias for multiple columns. Currently used to map ND
values to 1D dataframe columns for embeddings/layout. Signified by the presence
@@ -39,6 +39,7 @@ export function _getColumnDimensionNames(schema, field, col) {
return colSchema.dims || [col];
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'schema' implicitly has an 'any' type.
export function _schemaColumns(schema, field) {
switch (field) {
case "obs":
@@ -52,18 +53,25 @@ export function _schemaColumns(schema, field) {
}
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'schema' implicitly has an 'any' type.
export function _getWritableColumns(schema, field) {
if (field !== "obs") return [];
return schema.annotations.obs.columns
.filter((v) => v.writable)
.map((v) => v.name);
return (
schema.annotations.obs.columns
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'v' implicitly has an 'any' type.
.filter((v) => v.writable)
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'v' implicitly has an 'any' type.
.map((v) => v.name)
);
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'schema' implicitly has an 'any' type.
export function _isContinuousType(schema) {
const { type } = schema;
return !(type === "string" || type === "boolean" || type === "categorical");
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colSchema' implicitly has an 'any' type... Remove this comment to see the full error message
export function _normalizeCategoricalSchema(colSchema, col) {
const { type, writable } = colSchema;
if (
@@ -5,7 +5,7 @@ instances of AnnoMatrix, implementing common UI functions.
import { AnnoMatrixRowSubsetView, AnnoMatrixClipView } from "./views";
export function isubsetMask(annoMatrix, obsMask) {
export function isubsetMask(annoMatrix: any, obsMask: any) {
/*
Subset annomatrix to contain the rows which have truish value in the mask.
Maks length must equal annoMatrix.nObs (row count).
@@ -13,6 +13,7 @@ export function isubsetMask(annoMatrix, obsMask) {
return isubset(annoMatrix, _maskToList(obsMask));
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message
export function isubset(annoMatrix, obsOffsets) {
/*
Subset annomatrix to contain the positions contained in the obsOffsets array
@@ -25,6 +26,7 @@ export function isubset(annoMatrix, obsOffsets) {
return new AnnoMatrixRowSubsetView(annoMatrix, obsIndex);
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message
export function subset(annoMatrix, obsLabels) {
/*
subset based on labels
@@ -33,6 +35,7 @@ export function subset(annoMatrix, obsLabels) {
return new AnnoMatrixRowSubsetView(annoMatrix, obsIndex);
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message
export function subsetByIndex(annoMatrix, obsIndex) {
/*
subset based upon the new obs index.
@@ -40,6 +43,7 @@ export function subsetByIndex(annoMatrix, obsIndex) {
return new AnnoMatrixRowSubsetView(annoMatrix, obsIndex);
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message
export function clip(annoMatrix, qmin, qmax) {
/*
Create a view that clips all continuous data to the [min, max] range.
@@ -53,6 +57,7 @@ export function clip(annoMatrix, qmin, qmax) {
Private utility functions below
*/
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'mask' implicitly has an 'any' type.
function _maskToList(mask) {
/* convert masks to lists - method wastes space, but is fast */
if (!mask) {
@@ -9,21 +9,26 @@ import { _whereCacheCreate } from "./whereCache";
import { _isContinuousType, _getColumnSchema } from "./schema";
class AnnoMatrixView extends AnnoMatrix {
constructor(viewOf, rowIndex = null) {
constructor(viewOf: any, rowIndex = null) {
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
const nObs = rowIndex ? rowIndex.size() : viewOf.nObs;
super(viewOf.schema, nObs, viewOf.nVar, rowIndex || viewOf.rowIndex);
this.viewOf = viewOf;
this.isView = true;
}
addObsAnnoCategory(col, category) {
addObsAnnoCategory(col: any, category: any) {
const newAnnoMatrix = this._clone();
newAnnoMatrix.viewOf = this.viewOf.addObsAnnoCategory(col, category);
newAnnoMatrix.schema = newAnnoMatrix.viewOf.schema;
return newAnnoMatrix;
}
async removeObsAnnoCategory(col, category, unassignedCategory) {
async removeObsAnnoCategory(
col: any,
category: any,
unassignedCategory: any
) {
const newAnnoMatrix = this._clone();
newAnnoMatrix.viewOf = await this.viewOf.removeObsAnnoCategory(
col,
@@ -34,7 +39,7 @@ class AnnoMatrixView extends AnnoMatrix {
return newAnnoMatrix;
}
dropObsColumn(col) {
dropObsColumn(col: any) {
const newAnnoMatrix = this._clone();
newAnnoMatrix.viewOf = this.viewOf.dropObsColumn(col);
newAnnoMatrix._cache.obs = this._cache.obs.dropCol(col);
@@ -42,21 +47,21 @@ class AnnoMatrixView extends AnnoMatrix {
return newAnnoMatrix;
}
addObsColumn(colSchema, Ctor, value) {
addObsColumn(colSchema: any, Ctor: any, value: any) {
const newAnnoMatrix = this._clone();
newAnnoMatrix.viewOf = this.viewOf.addObsColumn(colSchema, Ctor, value);
newAnnoMatrix.schema = newAnnoMatrix.viewOf.schema;
return newAnnoMatrix;
}
renameObsColumn(oldCol, newCol) {
renameObsColumn(oldCol: any, newCol: any) {
const newAnnoMatrix = this._clone();
newAnnoMatrix.viewOf = this.viewOf.renameObsColumn(oldCol, newCol);
newAnnoMatrix.schema = newAnnoMatrix.viewOf.schema;
return newAnnoMatrix;
}
async setObsColumnValues(col, rowLabels, value) {
async setObsColumnValues(col: any, rowLabels: any, value: any) {
const newAnnoMatrix = this._clone();
newAnnoMatrix.viewOf = await this.viewOf.setObsColumnValues(
col,
@@ -68,7 +73,7 @@ class AnnoMatrixView extends AnnoMatrix {
return newAnnoMatrix;
}
async resetObsColumnValues(col, oldValue, newValue) {
async resetObsColumnValues(col: any, oldValue: any, newValue: any) {
const newAnnoMatrix = this._clone();
newAnnoMatrix.viewOf = await this.viewOf.resetObsColumnValues(
col,
@@ -80,7 +85,7 @@ class AnnoMatrixView extends AnnoMatrix {
return newAnnoMatrix;
}
addEmbedding(colSchema) {
addEmbedding(colSchema: any) {
const newAnnoMatrix = this._clone();
newAnnoMatrix.viewOf = this.viewOf.addEmbedding(colSchema);
newAnnoMatrix.schema = newAnnoMatrix.viewOf.schema;
@@ -92,17 +97,20 @@ class AnnoMatrixMapView extends AnnoMatrixView {
/*
A view which knows how to transform its data.
*/
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'viewOf' implicitly has an 'any' type.
constructor(viewOf, mapFn) {
super(viewOf);
this.mapFn = mapFn;
(this as any).mapFn = mapFn;
}
// @ts-expect-error ts-migrate(2416) FIXME: Property '_doLoad' in type 'AnnoMatrixMapView' is ... Remove this comment to see the full error message
async _doLoad(field, query) {
const df = await this.viewOf._fetch(field, query);
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colData' implicitly has an 'any' type.
const dfMapped = df.mapColumns((colData, colIdx) => {
const colLabel = df.colIndex.getLabel(colIdx);
const colSchema = _getColumnSchema(this.schema, field, colLabel);
return this.mapFn(field, colLabel, colSchema, colData, df);
return (this as any).mapFn(field, colLabel, colSchema, colData, df);
});
const whereCacheUpdate = _whereCacheCreate(
field,
@@ -117,12 +125,14 @@ export class AnnoMatrixClipView extends AnnoMatrixMapView {
/*
A view which is a clipped transformation of its parent
*/
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'viewOf' implicitly has an 'any' type.
constructor(viewOf, qmin, qmax) {
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
super(viewOf, (field, colLabel, colSchema, colData, df) =>
_clipAnnoMatrix(field, colLabel, colSchema, colData, df, qmin, qmax)
);
this.isClipped = true;
this.clipRange = [qmin, qmax];
(this as any).isClipped = true;
(this as any).clipRange = [qmin, qmax];
Object.seal(this);
}
}
@@ -131,11 +141,13 @@ export class AnnoMatrixRowSubsetView extends AnnoMatrixView {
/*
A view which is a subset of total rows.
*/
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'viewOf' implicitly has an 'any' type.
constructor(viewOf, rowIndex) {
super(viewOf, rowIndex);
Object.seal(this);
}
// @ts-expect-error ts-migrate(2416) FIXME: Property '_doLoad' in type 'AnnoMatrixRowSubsetVie... Remove this comment to see the full error message
async _doLoad(field, query) {
const df = await this.viewOf._fetch(field, query);
@@ -158,6 +170,7 @@ export class AnnoMatrixRowSubsetView extends AnnoMatrixView {
Utility functions below
*/
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
function _clipAnnoMatrix(field, colLabel, colSchema, colData, df, qmin, qmax) {
/* only clip obs and var scalar columns */
if (field !== "obs" && field !== "X") return colData;
@@ -51,7 +51,12 @@ creates a cache entry of:
import { _getColumnDimensionNames } from "./schema";
import { _hashStringValues } from "./query";
export function _whereCacheGet(whereCache, schema, field, query) {
export function _whereCacheGet(
whereCache: any,
schema: any,
field: any,
query: any
) {
/*
query will either be an where query (object) or a column name (string).
@@ -85,6 +90,7 @@ export function _whereCacheGet(whereCache, schema, field, query) {
return _getColumnDimensionNames(schema, field, query) ?? [undefined];
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
export function _whereCacheCreate(field, query, columnLabels) {
/*
Create a new whereCache
@@ -131,10 +137,11 @@ export function _whereCacheCreate(field, query, columnLabels) {
return {};
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'dst' implicitly has an 'any' type.
function __mergeQueries(dst, src) {
for (const [queryField, columnMap] of Object.entries(src)) {
dst[queryField] = dst[queryField] || new Map();
for (const [queryColumn, valueMap] of columnMap) {
for (const [queryColumn, valueMap] of columnMap as any) {
if (!dst[queryField].has(queryColumn))
dst[queryField].set(queryColumn, new Map());
for (const [queryValue, columnLabels] of valueMap) {
@@ -144,6 +151,7 @@ function __mergeQueries(dst, src) {
}
}
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'dst' implicitly has an 'any' type.
function __whereCacheMerge(dst, src) {
/*
merge src into dst (modifies dst)
@@ -161,6 +169,7 @@ function __whereCacheMerge(dst, src) {
dst.summarize = dst.summarize || {};
for (const [field, method] of Object.entries(src.summarize)) {
dst.summarize[field] = dst.summarize[field] || {};
// @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call.
for (const [methodName, query] of Object.entries(method)) {
dst.summarize[field][methodName] =
dst.summarize[field][methodName] || {};
@@ -171,6 +180,7 @@ function __whereCacheMerge(dst, src) {
return dst;
}
// @ts-expect-error ts-migrate(7019) FIXME: Rest parameter 'caches' implicitly has an 'any[]' ... Remove this comment to see the full error message
export function _whereCacheMerge(...caches) {
return caches.reduce(__whereCacheMerge, {});
}
@@ -1,30 +1,49 @@
import React from "react";
import { Button, Tooltip, Dialog, Classes, Colors } from "@blueprintjs/core";
class AnnoDialog extends React.PureComponent {
constructor(props) {
type State = any;
class AnnoDialog extends React.PureComponent<{}, State> {
constructor(props: {}) {
super(props);
this.state = {};
}
render() {
const {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isActive' does not exist on type 'Readon... Remove this comment to see the full error message
isActive,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'text' does not exist on type 'Readonly<{... Remove this comment to see the full error message
text,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'title' does not exist on type 'Readonly<... Remove this comment to see the full error message
title,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'instruction' does not exist on type 'Rea... Remove this comment to see the full error message
instruction,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'cancelTooltipContent' does not exist on ... Remove this comment to see the full error message
cancelTooltipContent,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'errorMessage' does not exist on type 'Re... Remove this comment to see the full error message
errorMessage,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'validationError' does not exist on type ... Remove this comment to see the full error message
validationError,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annoSelect' does not exist on type 'Read... Remove this comment to see the full error message
annoSelect,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annoInput' does not exist on type 'Reado... Remove this comment to see the full error message
annoInput,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'secondaryInstructions' does not exist on... Remove this comment to see the full error message
secondaryInstructions,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'secondaryInput' does not exist on type '... Remove this comment to see the full error message
secondaryInput,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'handleCancel' does not exist on type 'Re... Remove this comment to see the full error message
handleCancel,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'handleSubmit' does not exist on type 'Re... Remove this comment to see the full error message
handleSubmit,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'primaryButtonText' does not exist on typ... Remove this comment to see the full error message
primaryButtonText,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'secondaryButtonText' does not exist on t... Remove this comment to see the full error message
secondaryButtonText,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'handleSecondaryButtonSubmit' does not ex... Remove this comment to see the full error message
handleSecondaryButtonSubmit,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'primaryButtonProps' does not exist on ty... Remove this comment to see the full error message
primaryButtonProps,
} = this.props;
@@ -15,30 +15,32 @@ import TermsOfServicePrompt from "./termsPrompt";
import actions from "../actions";
// @ts-expect-error ts-migrate(1238) FIXME: Unable to resolve signature of class decorator whe... Remove this comment to see the full error message
@connect((state) => ({
loading: state.controls.loading,
error: state.controls.error,
graphRenderCounter: state.controls.graphRenderCounter,
loading: (state as any).controls.loading,
error: (state as any).controls.error,
graphRenderCounter: (state as any).controls.graphRenderCounter,
}))
class App extends React.Component {
componentDidMount() {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch } = this.props;
/* listen for url changes, fire one when we start the app up */
window.addEventListener("popstate", this._onURLChanged);
this._onURLChanged();
// @ts-expect-error ts-migrate(2554) FIXME: Expected 0 arguments, but got 1.
dispatch(actions.doInitialDataLoad(window.location.search));
this.forceUpdate();
}
_onURLChanged() {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch } = this.props;
dispatch({ type: "url changed", url: document.location.href });
}
render() {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'loading' does not exist on type 'Readonl... Remove this comment to see the full error message
const { loading, error, graphRenderCounter } = this.props;
return (
<Container>
@@ -70,13 +72,15 @@ class App extends React.Component {
{loading || error ? null : (
<Layout>
<LeftSideBar />
{(viewportRef) => (
{(viewportRef: any) => (
<>
<MenuBar />
<Embedding />
<Autosave />
<TermsOfServicePrompt />
{/* @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call. */}
<Legend viewportRef={viewportRef} />
{/* @ts-expect-error ts-migrate(2322) FIXME: Type '{ key: any; viewportRef: any; }' is not assi... Remove this comment to see the full error message */}
<Graph key={graphRenderCounter} viewportRef={viewportRef} />
</>
)}
@@ -11,18 +11,23 @@ import {
Tooltip,
} from "@blueprintjs/core";
type State = any;
// @ts-expect-error ts-migrate(1238) FIXME: Unable to resolve signature of class decorator whe... Remove this comment to see the full error message
@connect((state) => ({
idhash: state.config?.parameters?.["annotations-user-data-idhash"] ?? null,
annotations: state.annotations,
auth: state.config?.authentication,
userInfo: state.userInfo,
writableCategoriesEnabled: state.config?.parameters?.annotations ?? false,
idhash:
(state as any).config?.parameters?.["annotations-user-data-idhash"] ?? null,
annotations: (state as any).annotations,
auth: (state as any).config?.authentication,
userInfo: (state as any).userInfo,
writableCategoriesEnabled:
(state as any).config?.parameters?.annotations ?? false,
writableGenesetsEnabled: !(
state.config?.parameters?.annotations_genesets_readonly ?? true
(state as any).config?.parameters?.annotations_genesets_readonly ?? true
),
}))
class FilenameDialog extends React.Component {
constructor(props) {
class FilenameDialog extends React.Component<{}, State> {
constructor(props: {}) {
super(props);
this.state = {
filenameText: "",
@@ -32,9 +37,9 @@ class FilenameDialog extends React.Component {
dismissFilenameDialog = () => {};
handleCreateFilename = () => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch } = this.props;
const { filenameText } = this.state;
dispatch({
type: "set annotations collection name",
data: filenameText,
@@ -45,26 +50,26 @@ class FilenameDialog extends React.Component {
const legalNames = /^\w+$/;
const { filenameText } = this.state;
let err = false;
if (filenameText === "") {
// @ts-expect-error ts-migrate(2322) FIXME: Type 'string' is not assignable to type 'boolean'.
err = "empty_string";
} else if (!legalNames.test(filenameText)) {
/*
IMPORTANT: this test must ultimately match the test applied by the
backend, which is designed to ensure a safe file name can be created
from the data collection name. If you change this, you will also need
to change the validation code in the backend, or it will have no effect.
*/
IMPORTANT: this test must ultimately match the test applied by the
backend, which is designed to ensure a safe file name can be created
from the data collection name. If you change this, you will also need
to change the validation code in the backend, or it will have no effect.
*/
// @ts-expect-error ts-migrate(2322) FIXME: Type 'string' is not assignable to type 'boolean'.
err = "characters";
}
return err;
};
filenameErrorMessage = () => {
const err = this.filenameError();
let markup = null;
// @ts-expect-error ts-migrate(2367) FIXME: This condition will always return 'false' since th... Remove this comment to see the full error message
if (err === "empty_string") {
markup = (
<span
@@ -78,6 +83,7 @@ class FilenameDialog extends React.Component {
Name cannot be blank
</span>
);
// @ts-expect-error ts-migrate(2367) FIXME: This condition will always return 'false' since th... Remove this comment to see the full error message
} else if (err === "characters") {
markup = (
<span
@@ -97,14 +103,18 @@ class FilenameDialog extends React.Component {
render() {
const {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'writableCategoriesEnabled' does not exis... Remove this comment to see the full error message
writableCategoriesEnabled,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'writableGenesetsEnabled' does not exist ... Remove this comment to see the full error message
writableGenesetsEnabled,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annotations' does not exist on type 'Rea... Remove this comment to see the full error message
annotations,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'idhash' does not exist on type 'Readonly... Remove this comment to see the full error message
idhash,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'userInfo' does not exist on type 'Readon... Remove this comment to see the full error message
userInfo,
} = this.props;
const { filenameText } = this.state;
return (writableCategoriesEnabled || writableGenesetsEnabled) &&
annotations.promptForFilename &&
!annotations.dataCollectionNameIsReadOnly &&
@@ -128,6 +138,7 @@ class FilenameDialog extends React.Component {
<InputGroup
autoFocus
value={filenameText}
// @ts-expect-error ts-migrate(2554) FIXME: Expected 0 arguments, but got 1.
intent={this.filenameError(filenameText) ? "warning" : "none"}
onChange={(e) =>
this.setState({ filenameText: e.target.value })
@@ -138,12 +149,14 @@ class FilenameDialog extends React.Component {
<p
style={{
marginTop: 7,
// @ts-expect-error ts-migrate(2554) FIXME: Expected 0 arguments, but got 1.
visibility: this.filenameError(filenameText)
? "visible"
: "hidden",
color: Colors.ORANGE3,
}}
>
{/* @ts-expect-error ts-migrate(2554) FIXME: Expected 0 arguments, but got 1. */}
{this.filenameErrorMessage(filenameText)}
</p>
</div>
@@ -171,6 +184,7 @@ class FilenameDialog extends React.Component {
<Button onClick={this.dismissFilenameDialog}>Cancel</Button>
</Tooltip>
<Button
// @ts-expect-error ts-migrate(2554) FIXME: Expected 0 arguments, but got 1.
disabled={!filenameText || this.filenameError(filenameText)}
onClick={this.handleCreateFilename}
intent="primary"
@@ -3,23 +3,30 @@ import { connect } from "react-redux";
import actions from "../../actions";
import FilenameDialog from "./filenameDialog";
type State = any;
// @ts-expect-error ts-migrate(1238) FIXME: Unable to resolve signature of class decorator whe... Remove this comment to see the full error message
@connect((state) => ({
annotations: state.annotations,
annotations: (state as any).annotations,
obsAnnotationSaveInProgress:
state.autosave?.obsAnnotationSaveInProgress ?? false,
genesetSaveInProgress: state.autosave?.genesetSaveInProgress ?? false,
error: state.autosave?.error,
writableCategoriesEnabled: state.config?.parameters?.annotations ?? false,
(state as any).autosave?.obsAnnotationSaveInProgress ?? false,
genesetSaveInProgress:
(state as any).autosave?.genesetSaveInProgress ?? false,
error: (state as any).autosave?.error,
writableCategoriesEnabled:
(state as any).config?.parameters?.annotations ?? false,
writableGenesetsEnabled: !(
state.config?.parameters?.annotations_genesets_readonly ?? true
(state as any).config?.parameters?.annotations_genesets_readonly ?? true
),
annoMatrix: state.annoMatrix,
genesets: state.genesets,
lastSavedAnnoMatrix: state.autosave?.lastSavedAnnoMatrix,
lastSavedGenesets: state.autosave?.lastSavedGenesets,
annoMatrix: (state as any).annoMatrix,
genesets: (state as any).genesets,
lastSavedAnnoMatrix: (state as any).autosave?.lastSavedAnnoMatrix,
lastSavedGenesets: (state as any).autosave?.lastSavedGenesets,
}))
class Autosave extends React.Component {
constructor(props) {
class Autosave extends React.Component<{}, State> {
clearInterval: any;
constructor(props: {}) {
super(props);
this.state = {
timer: null,
@@ -27,8 +34,8 @@ class Autosave extends React.Component {
}
componentDidMount() {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'writableCategoriesEnabled' does not exis... Remove this comment to see the full error message
const { writableCategoriesEnabled, writableGenesetsEnabled } = this.props;
let { timer } = this.state;
if (timer) clearInterval(timer);
if (writableCategoriesEnabled || writableGenesetsEnabled) {
@@ -46,8 +53,11 @@ class Autosave extends React.Component {
tick = () => {
const {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
dispatch,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'obsAnnotationSaveInProgress' does not ex... Remove this comment to see the full error message
obsAnnotationSaveInProgress,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'genesetSaveInProgress' does not exist on... Remove this comment to see the full error message
genesetSaveInProgress,
} = this.props;
if (!obsAnnotationSaveInProgress && this.needToSaveObsAnnotations()) {
@@ -60,12 +70,14 @@ class Autosave extends React.Component {
needToSaveObsAnnotations = () => {
/* return true if we need to save obs cell labels, false if we don't */
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annoMatrix' does not exist on type 'Read... Remove this comment to see the full error message
const { annoMatrix, lastSavedAnnoMatrix } = this.props;
return actions.needToSaveObsAnnotations(annoMatrix, lastSavedAnnoMatrix);
};
needToSaveGenesets = () => {
/* return true if we need to save gene ses, false if we do not */
// @ts-expect-error ts-migrate(2339) FIXME: Property 'genesets' does not exist on type 'Readon... Remove this comment to see the full error message
const { genesets, lastSavedGenesets } = this.props;
return genesets.initialized && genesets.genesets !== lastSavedGenesets;
};
@@ -75,11 +87,13 @@ class Autosave extends React.Component {
}
saveInProgress() {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'obsAnnotationSaveInProgress' does not ex... Remove this comment to see the full error message
const { obsAnnotationSaveInProgress, genesetSaveInProgress } = this.props;
return obsAnnotationSaveInProgress || genesetSaveInProgress;
}
statusMessage() {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'error' does not exist on type 'Readonly<... Remove this comment to see the full error message
const { error } = this.props;
if (error) {
return `Autosave error: ${error}`;
@@ -89,14 +103,15 @@ class Autosave extends React.Component {
render() {
const {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'writableCategoriesEnabled' does not exis... Remove this comment to see the full error message
writableCategoriesEnabled,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'writableGenesetsEnabled' does not exist ... Remove this comment to see the full error message
writableGenesetsEnabled,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'lastSavedAnnoMatrix' does not exist on t... Remove this comment to see the full error message
lastSavedAnnoMatrix,
} = this.props;
const initialDataLoadComplete = lastSavedAnnoMatrix;
if (!writableCategoriesEnabled && !writableGenesetsEnabled) return null;
return (
<div
id="autosave"
@@ -1,7 +1,7 @@
import React from "react";
import * as globals from "../../globals";
const ErrorLoading = ({ displayName, zebra }) => {
const ErrorLoading = ({ displayName, zebra }: any) => {
return (
<div
style={{
@@ -2,13 +2,21 @@ import React from "react";
const HistogramFooter = React.memo(
({
// @ts-expect-error ts-migrate(2339) FIXME: Property 'displayName' does not exist on type '{ c... Remove this comment to see the full error message
displayName,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'hideRanges' does not exist on type '{ ch... Remove this comment to see the full error message
hideRanges,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'rangeMin' does not exist on type '{ chil... Remove this comment to see the full error message
rangeMin,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'rangeMax' does not exist on type '{ chil... Remove this comment to see the full error message
rangeMax,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'rangeColorMin' does not exist on type '{... Remove this comment to see the full error message
rangeColorMin,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'rangeColorMax' does not exist on type '{... Remove this comment to see the full error message
rangeColorMax,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isObs' does not exist on type '{ childre... Remove this comment to see the full error message
isObs,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isGeneSetSummary' does not exist on type... Remove this comment to see the full error message
isGeneSetSummary,
}) => {
/*
@@ -5,14 +5,23 @@ import * as globals from "../../globals";
const HistogramHeader = React.memo(
({
// @ts-expect-error ts-migrate(2339) FIXME: Property 'fieldId' does not exist on type '{ child... Remove this comment to see the full error message
fieldId,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isColorBy' does not exist on type '{ chi... Remove this comment to see the full error message
isColorBy,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'onColorByClick' does not exist on type '... Remove this comment to see the full error message
onColorByClick,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'onRemoveClick' does not exist on type '{... Remove this comment to see the full error message
onRemoveClick,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isScatterPlotX' does not exist on type '... Remove this comment to see the full error message
isScatterPlotX,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isScatterPlotY' does not exist on type '... Remove this comment to see the full error message
isScatterPlotY,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'onScatterPlotXClick' does not exist on t... Remove this comment to see the full error message
onScatterPlotXClick,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'onScatterPlotYClick' does not exist on t... Remove this comment to see the full error message
onScatterPlotYClick,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isObs' does not exist on type '{ childre... Remove this comment to see the full error message
isObs,
}) => {
/*
@@ -18,7 +18,7 @@ const Histogram = ({
isColorBy,
selectionRange,
mini,
}) => {
}: any) => {
const svgRef = useRef(null);
const [brush, setBrush] = useState(null);
@@ -69,14 +69,18 @@ const Histogram = ({
.data(bins)
.enter()
.append("rect")
// @ts-expect-error ts-migrate(6133) FIXME: 'd' is declared but its value is never read.
.attr("x", (d, i) => x(binStart(i)) + 1)
.attr("y", (d) => y(d))
// @ts-expect-error ts-migrate(6133) FIXME: 'd' is declared but its value is never read.
.attr("width", (d, i) => x(binEnd(i)) - x(binStart(i)) - binPadding)
.attr("height", (d) => y(0) - y(d))
.style(
"fill",
// @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call.
isColorBy
? (d, i) => colorScale(histogramScale(binStart(i)))
? // @ts-expect-error ts-migrate(6133) FIXME: 'd' is declared but its value is never read.
(d: any, i: any) => colorScale(histogramScale(binStart(i)))
: defaultBarColor
);
}
@@ -101,6 +105,7 @@ const Histogram = ({
const brushXselection = container
.insert("g")
.attr("class", "brush")
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
.attr("data-testid", `${svgRef.current.dataset.testid}-brushable-area`)
.call(brushX);
@@ -113,6 +118,7 @@ const Histogram = ({
d3
.axisBottom(x)
.ticks(4)
// @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call.
.tickFormat(d3.format(maybeScientific(x)))
);
@@ -126,8 +132,9 @@ const Histogram = ({
.axisRight(y)
.ticks(3)
.tickFormat(
// @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call.
d3.format(
y.domain().some((n) => Math.abs(n) >= 10000) ? ".0e" : ","
y.domain().some((n: any) => Math.abs(n) >= 10000) ? ".0e" : ","
)
)
);
@@ -137,6 +144,7 @@ const Histogram = ({
svg.selectAll(".axis path").style("stroke", "rgb(230,230,230)");
svg.selectAll(".axis line").style("stroke", "rgb(230,230,230)");
// @ts-expect-error ts-migrate(2345) FIXME: Argument of type '{ brushX: d3.BrushBehavior<unkno... Remove this comment to see the full error message
setBrush({ brushX, brushXselection });
}
}, [histogram, isColorBy]);
@@ -146,6 +154,7 @@ const Histogram = ({
paint/update selection brush
*/
if (!brush) return;
// @ts-expect-error ts-migrate(2339) FIXME: Property 'brushX' does not exist on type 'null'.
const { brushX, brushXselection } = brush;
const selection = d3.brushSelection(brushXselection.node());
if (!selectionRange && selection) {
@@ -162,7 +171,9 @@ const Histogram = ({
} else {
/* there is an active selection and a brush - make sure they match */
const moveDeltaThreshold = 1;
// @ts-expect-error ts-migrate(2363) FIXME: The right-hand side of an arithmetic operation mus... Remove this comment to see the full error message
const dX0 = Math.abs(x0 - selection[0]);
// @ts-expect-error ts-migrate(2363) FIXME: The right-hand side of an arithmetic operation mus... Remove this comment to see the full error message
const dX1 = Math.abs(x1 - selection[1]);
/*
only update the brush if it is grossly incorrect,
@@ -29,27 +29,31 @@ const MARGIN_MINI = {
const WIDTH_MINI = 120 - MARGIN_MINI.LEFT - MARGIN_MINI.RIGHT;
const HEIGHT_MINI = 15 - MARGIN_MINI.TOP - MARGIN_MINI.BOTTOM;
// @ts-expect-error ts-migrate(1238) FIXME: Unable to resolve signature of class decorator whe... Remove this comment to see the full error message
@connect((state, ownProps) => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isObs' does not exist on type '{}'.
const { isObs, isUserDefined, isGeneSetSummary, field } = ownProps;
const myName = makeContinuousDimensionName(
{ isObs, isUserDefined, isGeneSetSummary },
field
);
return {
annoMatrix: state.annoMatrix,
isScatterplotXXaccessor: state.controls.scatterplotXXaccessor === field,
isScatterplotYYaccessor: state.controls.scatterplotYYaccessor === field,
continuousSelectionRange: state.continuousSelection[myName],
isColorAccessor: state.colors.colorAccessor === field,
annoMatrix: (state as any).annoMatrix,
isScatterplotXXaccessor:
(state as any).controls.scatterplotXXaccessor === field,
isScatterplotYYaccessor:
(state as any).controls.scatterplotYYaccessor === field,
continuousSelectionRange: (state as any).continuousSelection[myName],
isColorAccessor: (state as any).colors.colorAccessor === field,
};
})
class HistogramBrush extends React.PureComponent {
static watchAsync(props, prevProps) {
static watchAsync(props: any, prevProps: any) {
return !shallowEqual(props.watchProps, prevProps.watchProps);
}
/* memoized closure to prevent HistogramHeader unecessary repaint */
handleColorAction = memoize((dispatch) => (field, isObs) => {
handleColorAction = memoize((dispatch) => (field: any, isObs: any) => {
if (isObs) {
dispatch({
type: "color by continuous metadata",
@@ -60,25 +64,31 @@ class HistogramBrush extends React.PureComponent {
}
});
onBrush = (selection, x, eventType) => {
// @ts-expect-error ts-migrate(6133) FIXME: 'selection' is declared but its value is never rea... Remove this comment to see the full error message
onBrush = (selection: any, x: any, eventType: any) => {
const type = `continuous metadata histogram ${eventType}`;
return () => {
const {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
dispatch,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'field' does not exist on type 'Readonly<... Remove this comment to see the full error message
field,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isObs' does not exist on type 'Readonly<... Remove this comment to see the full error message
isObs,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isUserDefined' does not exist on type 'R... Remove this comment to see the full error message
isUserDefined,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isGeneSetSummary' does not exist on type... Remove this comment to see the full error message
isGeneSetSummary,
} = this.props;
// ignore programmatically generated events
if (!d3.event.sourceEvent) return;
if (!(d3 as any).event.sourceEvent) return;
// ignore cascading events, which are programmatically generated
if (d3.event.sourceEvent.sourceEvent) return;
if ((d3 as any).event.sourceEvent.sourceEvent) return;
const query = this.createQuery();
const range = d3.event.selection
? [x(d3.event.selection[0]), x(d3.event.selection[1])]
const range = (d3 as any).event.selection
? [x((d3 as any).event.selection[0]), x((d3 as any).event.selection[1])]
: null;
const otherProps = {
selection: field,
@@ -94,42 +104,52 @@ class HistogramBrush extends React.PureComponent {
};
};
onBrushEnd = (selection, x) => {
// @ts-expect-error ts-migrate(6133) FIXME: 'selection' is declared but its value is never rea... Remove this comment to see the full error message
onBrushEnd = (selection: any, x: any) => {
return () => {
const {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
dispatch,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'field' does not exist on type 'Readonly<... Remove this comment to see the full error message
field,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isObs' does not exist on type 'Readonly<... Remove this comment to see the full error message
isObs,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isUserDefined' does not exist on type 'R... Remove this comment to see the full error message
isUserDefined,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isGeneSetSummary' does not exist on type... Remove this comment to see the full error message
isGeneSetSummary,
} = this.props;
const minAllowedBrushSize = 10;
const smallAmountToAvoidInfiniteLoop = 0.1;
// ignore programmatically generated events
if (!d3.event.sourceEvent) return;
if (!(d3 as any).event.sourceEvent) return;
// ignore cascading events, which are programmatically generated
if (d3.event.sourceEvent.sourceEvent) return;
if ((d3 as any).event.sourceEvent.sourceEvent) return;
let type;
let range = null;
if (d3.event.selection) {
if ((d3 as any).event.selection) {
type = "continuous metadata histogram end";
if (
d3.event.selection[1] - d3.event.selection[0] >
(d3 as any).event.selection[1] - (d3 as any).event.selection[0] >
minAllowedBrushSize
) {
range = [x(d3.event.selection[0]), x(d3.event.selection[1])];
range = [
x((d3 as any).event.selection[0]),
x((d3 as any).event.selection[1]),
];
} else {
/* the user selected range is too small and will be hidden #587, so take control of it procedurally */
/* https://stackoverflow.com/questions/12354729/d3-js-limit-size-of-brush */
const procedurallyResizedBrushWidth =
d3.event.selection[0] +
(d3 as any).event.selection[0] +
minAllowedBrushSize +
smallAmountToAvoidInfiniteLoop; //
range = [x(d3.event.selection[0]), x(procedurallyResizedBrushWidth)];
range = [
x((d3 as any).event.selection[0]),
x(procedurallyResizedBrushWidth),
];
}
} else {
type = "continuous metadata histogram cancel";
@@ -151,6 +171,7 @@ class HistogramBrush extends React.PureComponent {
};
handleSetGeneAsScatterplotX = () => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, field } = this.props;
dispatch({
type: "set scatterplot x",
@@ -159,6 +180,7 @@ class HistogramBrush extends React.PureComponent {
};
handleSetGeneAsScatterplotY = () => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, field } = this.props;
dispatch({
type: "set scatterplot y",
@@ -168,10 +190,15 @@ class HistogramBrush extends React.PureComponent {
removeHistogram = () => {
const {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
dispatch,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'field' does not exist on type 'Readonly<... Remove this comment to see the full error message
field,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isColorAccessor' does not exist on type ... Remove this comment to see the full error message
isColorAccessor,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isScatterplotXXaccessor' does not exist ... Remove this comment to see the full error message
isScatterplotXXaccessor,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isScatterplotYYaccessor' does not exist ... Remove this comment to see the full error message
isScatterplotYYaccessor,
} = this.props;
dispatch({
@@ -198,11 +225,13 @@ class HistogramBrush extends React.PureComponent {
};
fetchAsyncProps = async () => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annoMatrix' does not exist on type 'Read... Remove this comment to see the full error message
const { annoMatrix, width } = this.props;
const { isClipped } = annoMatrix;
const query = this.createQuery();
// @ts-expect-error ts-migrate(2488) FIXME: Type 'any[] | null' must have a '[Symbol.iterator]... Remove this comment to see the full error message
const df = await annoMatrix.fetch(...query);
const column = df.icol(0);
@@ -261,7 +290,7 @@ class HistogramBrush extends React.PureComponent {
};
// eslint-disable-next-line class-methods-use-this -- instance method allows for memoization per annotation
calcHistogramCache(col, newMargin, newWidth, newHeight) {
calcHistogramCache(col: any, newMargin: any, newWidth: any, newHeight: any) {
/*
recalculate expensive stuff, notably bins, summaries, etc.
*/
@@ -269,35 +298,30 @@ class HistogramBrush extends React.PureComponent {
const summary = col.summarize(); /* this is memoized, so it's free the second time you call it */
const { min: domainMin, max: domainMax } = summary;
const numBins = 40;
const {
TOP: topMargin,
LEFT: leftMargin,
} = newMargin; /* changes with mini */
histogramCache.domain = [
domainMin,
domainMax,
]; /* doesn't change with mini */
histogramCache.x = d3
const { TOP: topMargin, LEFT: leftMargin } = newMargin;
(histogramCache as any).domain = [domainMin, domainMax];
/* doesn't change with mini */ (histogramCache as any).x = d3
.scaleLinear()
.domain([domainMin, domainMax])
.range([leftMargin, leftMargin + newWidth]);
histogramCache.bins = col.histogram(numBins, [
(histogramCache as any).bins = col.histogram(numBins, [
domainMin,
domainMax,
]); /* memoized */
]);
/* memoized */ (histogramCache as any).binWidth =
(domainMax - domainMin) / numBins;
histogramCache.binWidth = (domainMax - domainMin) / numBins;
(histogramCache as any).binStart = (i: any) =>
domainMin + i * (histogramCache as any).binWidth;
(histogramCache as any).binEnd = (i: any) =>
domainMin + (i + 1) * (histogramCache as any).binWidth;
histogramCache.binStart = (i) => domainMin + i * histogramCache.binWidth;
histogramCache.binEnd = (i) =>
domainMin + (i + 1) * histogramCache.binWidth;
const yMax = (histogramCache as any).bins.reduce((l: any, r: any) =>
l > r ? l : r
);
const yMax = histogramCache.bins.reduce((l, r) => (l > r ? l : r));
histogramCache.y = d3
(histogramCache as any).y = d3
.scaleLinear()
.domain([0, yMax])
.range([topMargin + newHeight, topMargin]);
@@ -306,13 +330,8 @@ class HistogramBrush extends React.PureComponent {
}
createQuery() {
const {
isObs,
isGeneSetSummary,
field,
setGenes,
annoMatrix,
} = this.props;
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isObs' does not exist on type 'Readonly<... Remove this comment to see the full error message
const { isObs, isGeneSetSummary, field, setGenes, annoMatrix } = this.props;
const { schema } = annoMatrix;
if (isObs) {
return ["obs", field];
@@ -349,21 +368,35 @@ class HistogramBrush extends React.PureComponent {
render() {
const {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
dispatch,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annoMatrix' does not exist on type 'Read... Remove this comment to see the full error message
annoMatrix,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'field' does not exist on type 'Readonly<... Remove this comment to see the full error message
field,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isColorAccessor' does not exist on type ... Remove this comment to see the full error message
isColorAccessor,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isUserDefined' does not exist on type 'R... Remove this comment to see the full error message
isUserDefined,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isGeneSetSummary' does not exist on type... Remove this comment to see the full error message
isGeneSetSummary,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isScatterplotXXaccessor' does not exist ... Remove this comment to see the full error message
isScatterplotXXaccessor,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isScatterplotYYaccessor' does not exist ... Remove this comment to see the full error message
isScatterplotYYaccessor,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'zebra' does not exist on type 'Readonly<... Remove this comment to see the full error message
zebra,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'continuousSelectionRange' does not exist... Remove this comment to see the full error message
continuousSelectionRange,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isObs' does not exist on type 'Readonly<... Remove this comment to see the full error message
isObs,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'mini' does not exist on type 'Readonly<{... Remove this comment to see the full error message
mini,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'setGenes' does not exist on type 'Readon... Remove this comment to see the full error message
setGenes,
} = this.props;
// @ts-expect-error ts-migrate(2339) FIXME: Property 'width' does not exist on type 'Readonly<... Remove this comment to see the full error message
let { width } = this.props;
if (!width) {
width = mini ? WIDTH_MINI : WIDTH;
@@ -392,7 +425,7 @@ class HistogramBrush extends React.PureComponent {
</Async.Rejected>
<Async.Fulfilled>
{(asyncProps) =>
asyncProps.OK2Render ? (
(asyncProps as any).OK2Render ? (
<div
id={`histogram_${fieldForId}`}
data-testid={`histogram-${field}`}
@@ -404,6 +437,7 @@ class HistogramBrush extends React.PureComponent {
>
{!mini && isObs ? (
<HistogramHeader
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ fieldId: any; isColorBy: any; isObs: any; ... Remove this comment to see the full error message
fieldId={field}
isColorBy={isColorAccessor}
isObs={isObs}
@@ -422,9 +456,11 @@ class HistogramBrush extends React.PureComponent {
<Histogram
field={field}
fieldForId={fieldForId}
display={asyncProps.isSingleValue ? "none" : "block"}
display={(asyncProps as any).isSingleValue ? "none" : "block"}
histogram={
mini ? asyncProps.miniHistogram : asyncProps.histogram
mini
? (asyncProps as any).miniHistogram
: (asyncProps as any).histogram
}
width={width}
height={mini ? HEIGHT_MINI : HEIGHT}
@@ -437,14 +473,15 @@ class HistogramBrush extends React.PureComponent {
/>
{!mini && (
<HistogramFooter
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ isGeneSetSummary: any; isObs: any; display... Remove this comment to see the full error message
isGeneSetSummary={isGeneSetSummary}
isObs={isObs}
displayName={field}
hideRanges={asyncProps.isSingleValue}
rangeMin={asyncProps.unclippedRange[0]}
rangeMax={asyncProps.unclippedRange[1]}
rangeColorMin={asyncProps.unclippedRangeColor[0]}
rangeColorMax={asyncProps.unclippedRangeColor[1]}
hideRanges={(asyncProps as any).isSingleValue}
rangeMin={(asyncProps as any).unclippedRange[0]}
rangeMax={(asyncProps as any).unclippedRange[1]}
rangeColorMin={(asyncProps as any).unclippedRangeColor[0]}
rangeColorMax={(asyncProps as any).unclippedRangeColor[1]}
/>
)}
</div>
@@ -3,7 +3,7 @@ import { Button } from "@blueprintjs/core";
import * as globals from "../../globals";
const StillLoading = ({ zebra, displayName }) => {
const StillLoading = ({ zebra, displayName }: any) => {
/*
Render a loading indicator for the field.
*/
@@ -2,16 +2,21 @@ import React from "react";
import { Button, MenuItem } from "@blueprintjs/core";
import { Select } from "@blueprintjs/select";
class DuplicateCategorySelect extends React.PureComponent {
constructor(props) {
type State = any;
class DuplicateCategorySelect extends React.PureComponent<{}, State> {
constructor(props: {}) {
super(props);
this.state = {};
}
render() {
const {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'allCategoryNames' does not exist on type... Remove this comment to see the full error message
allCategoryNames,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categoryToDuplicate' does not exist on t... Remove this comment to see the full error message
categoryToDuplicate,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'handleModalDuplicateCategorySelection' d... Remove this comment to see the full error message
handleModalDuplicateCategorySelection,
} = this.props;
return (
@@ -31,7 +36,9 @@ class DuplicateCategorySelect extends React.PureComponent {
<MenuItem
data-testclass="duplicate-category-dropdown-option"
onClick={handleClick}
// @ts-expect-error ts-migrate(2322) FIXME: Type 'unknown' is not assignable to type 'Key | nu... Remove this comment to see the full error message
key={d}
// @ts-expect-error ts-migrate(2322) FIXME: Type 'unknown' is not assignable to type 'ReactNod... Remove this comment to see the full error message
text={d}
/>
);
@@ -5,20 +5,24 @@ import LabelInput from "../../labelInput";
import { labelPrompt, isLabelErroneous } from "../labelUtil";
import actions from "../../../actions";
type State = any;
// @ts-expect-error ts-migrate(1238) FIXME: Unable to resolve signature of class decorator whe... Remove this comment to see the full error message
@connect((state) => ({
annotations: state.annotations,
schema: state.annoMatrix?.schema,
obsCrossfilter: state.obsCrossfilter,
annotations: (state as any).annotations,
schema: (state as any).annoMatrix?.schema,
obsCrossfilter: (state as any).obsCrossfilter,
}))
class Category extends React.PureComponent {
constructor(props) {
class Category extends React.PureComponent<{}, State> {
constructor(props: {}) {
super(props);
this.state = {
newLabelText: "",
};
}
disableAddNewLabelMode = (e) => {
disableAddNewLabelMode = (e: any) => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch } = this.props;
this.setState({
newLabelText: "",
@@ -29,10 +33,11 @@ class Category extends React.PureComponent {
if (e) e.preventDefault();
};
handleAddNewLabelToCategory = (e) => {
handleAddNewLabelToCategory = (e: any) => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, metadataField } = this.props;
const { newLabelText } = this.state;
// @ts-expect-error ts-migrate(2554) FIXME: Expected 1 arguments, but got 0.
this.disableAddNewLabelMode();
dispatch(
actions.annotationCreateLabelInCategory(
@@ -44,10 +49,11 @@ class Category extends React.PureComponent {
e.preventDefault();
};
addLabelAndAssignCells = (e) => {
addLabelAndAssignCells = (e: any) => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, metadataField } = this.props;
const { newLabelText } = this.state;
// @ts-expect-error ts-migrate(2554) FIXME: Expected 1 arguments, but got 0.
this.disableAddNewLabelMode();
dispatch(
actions.annotationCreateLabelInCategory(metadataField, newLabelText, true)
@@ -55,26 +61,28 @@ class Category extends React.PureComponent {
e.preventDefault();
};
labelNameError = (name) => {
labelNameError = (name: any) => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'metadataField' does not exist on type 'R... Remove this comment to see the full error message
const { metadataField, schema } = this.props;
return isLabelErroneous(name, metadataField, schema);
};
instruction = (label) => {
instruction = (label: any) => {
return labelPrompt(this.labelNameError(label), "New, unique label", ":");
};
handleChangeOrSelect = (label) => {
handleChangeOrSelect = (label: any) => {
this.setState({ newLabelText: label });
};
render() {
const { newLabelText } = this.state;
// @ts-expect-error ts-migrate(2339) FIXME: Property 'metadataField' does not exist on type 'R... Remove this comment to see the full error message
const { metadataField, annotations, obsCrossfilter } = this.props;
return (
<>
<AnnoDialog
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ isActive: any; inputProps: { "data-testid"... Remove this comment to see the full error message
isActive={
annotations.isAddingNewLabel &&
annotations.categoryAddingNewLabel === metadataField
@@ -95,6 +103,7 @@ class Category extends React.PureComponent {
handleCancel={this.disableAddNewLabelMode}
annoInput={
<LabelInput
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ labelSuggestions: null; onChange: (label: ... Remove this comment to see the full error message
labelSuggestions={null}
onChange={this.handleChangeOrSelect}
onSelect={this.handleChangeOrSelect}
@@ -7,25 +7,30 @@ import { labelPrompt } from "../labelUtil";
import { AnnotationsHelpers } from "../../../util/stateManager";
import actions from "../../../actions";
type State = any;
// @ts-expect-error ts-migrate(1238) FIXME: Unable to resolve signature of class decorator whe... Remove this comment to see the full error message
@connect((state) => ({
annotations: state.annotations,
schema: state.annoMatrix?.schema,
annotations: (state as any).annotations,
schema: (state as any).annoMatrix?.schema,
}))
class AnnoDialogEditCategoryName extends React.PureComponent {
constructor(props) {
class AnnoDialogEditCategoryName extends React.PureComponent<{}, State> {
constructor(props: {}) {
super(props);
this.state = {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'metadataField' does not exist on type '{... Remove this comment to see the full error message
newCategoryText: props.metadataField,
};
}
handleChangeOrSelect = (name) => {
handleChangeOrSelect = (name: any) => {
this.setState({
newCategoryText: name,
});
};
disableEditCategoryMode = () => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, metadataField } = this.props;
dispatch({
type: "annotation: disable category edit mode",
@@ -33,17 +38,19 @@ class AnnoDialogEditCategoryName extends React.PureComponent {
this.setState({ newCategoryText: metadataField });
};
handleEditCategory = (e) => {
handleEditCategory = (e: any) => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, metadataField } = this.props;
const { newCategoryText } = this.state;
/*
test for uniqueness against *all* annotation names, not just the subset
we render as categorical.
*/
test for uniqueness against *all* annotation names, not just the subset
we render as categorical.
*/
// @ts-expect-error ts-migrate(2339) FIXME: Property 'schema' does not exist on type 'Readonly... Remove this comment to see the full error message
const { schema } = this.props;
const allCategoryNames = schema.annotations.obs.columns.map((c) => c.name);
const allCategoryNames = schema.annotations.obs.columns.map(
(c: any) => c.name
);
if (
(allCategoryNames.indexOf(newCategoryText) > -1 &&
newCategoryText !== metadataField) ||
@@ -51,9 +58,7 @@ class AnnoDialogEditCategoryName extends React.PureComponent {
) {
return;
}
this.disableEditCategoryMode();
if (metadataField !== newCategoryText)
dispatch(
actions.annotationRenameCategoryAction(metadataField, newCategoryText)
@@ -61,35 +66,34 @@ class AnnoDialogEditCategoryName extends React.PureComponent {
e.preventDefault();
};
editedCategoryNameError = (name) => {
editedCategoryNameError = (name: any) => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'metadataField' does not exist on type 'R... Remove this comment to see the full error message
const { metadataField } = this.props;
/* check for syntax errors in category name */
const error = AnnotationsHelpers.annotationNameIsErroneous(name);
if (error) {
return error;
}
/* check for duplicative categories */
/*
test for uniqueness against *all* annotation names, not just the subset
we render as categorical.
*/
test for uniqueness against *all* annotation names, not just the subset
we render as categorical.
*/
// @ts-expect-error ts-migrate(2339) FIXME: Property 'schema' does not exist on type 'Readonly... Remove this comment to see the full error message
const { schema } = this.props;
const allCategoryNames = schema.annotations.obs.columns.map((c) => c.name);
const allCategoryNames = schema.annotations.obs.columns.map(
(c: any) => c.name
);
const categoryNameAlreadyExists = allCategoryNames.indexOf(name) > -1;
const sameName = name === metadataField;
if (categoryNameAlreadyExists && !sameName) {
return "duplicate";
}
/* otherwise, no error */
return false;
};
instruction = (name) => {
instruction = (name: any) => {
return labelPrompt(
this.editedCategoryNameError(name),
"New, unique category name",
@@ -98,17 +102,19 @@ class AnnoDialogEditCategoryName extends React.PureComponent {
};
allCategoryNames() {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'schema' does not exist on type 'Readonly... Remove this comment to see the full error message
const { schema } = this.props;
return schema.annotations.obs.columns.map((c) => c.name);
return schema.annotations.obs.columns.map((c: any) => c.name);
}
render() {
const { newCategoryText } = this.state;
// @ts-expect-error ts-migrate(2339) FIXME: Property 'metadataField' does not exist on type 'R... Remove this comment to see the full error message
const { metadataField, annotations } = this.props;
return (
<>
<AnnoDialog
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ isActive: any; inputProps: { "data-testid"... Remove this comment to see the full error message
isActive={
annotations.isEditingCategoryName &&
annotations.categoryBeingEdited === metadataField
@@ -129,6 +135,7 @@ class AnnoDialogEditCategoryName extends React.PureComponent {
handleCancel={this.disableEditCategoryMode}
annoInput={
<LabelInput
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ label: any; labelSuggestions: null; onChan... Remove this comment to see the full error message
label={newCategoryText}
labelSuggestions={null}
onChange={this.handleChangeOrSelect}
@@ -16,16 +16,20 @@ import { IconNames } from "@blueprintjs/icons";
import * as globals from "../../../globals";
import actions from "../../../actions";
type State = any;
// @ts-expect-error ts-migrate(1238) FIXME: Unable to resolve signature of class decorator whe... Remove this comment to see the full error message
@connect((state) => ({
annotations: state.annotations,
annotations: (state as any).annotations,
}))
class AnnoMenuCategory extends React.PureComponent {
constructor(props) {
class AnnoMenuCategory extends React.PureComponent<{}, State> {
constructor(props: {}) {
super(props);
this.state = {};
}
activateAddNewLabelMode = () => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, metadataField } = this.props;
dispatch({
type: "annotation: activate add new label mode",
@@ -34,8 +38,8 @@ class AnnoMenuCategory extends React.PureComponent {
};
activateEditCategoryMode = () => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, metadataField } = this.props;
dispatch({
type: "annotation: activate category edit mode",
data: metadataField,
@@ -43,20 +47,26 @@ class AnnoMenuCategory extends React.PureComponent {
};
handleDeleteCategory = () => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, metadataField } = this.props;
dispatch(actions.annotationDeleteCategoryAction(metadataField));
};
render() {
const {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'metadataField' does not exist on type 'R... Remove this comment to see the full error message
metadataField,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annotations' does not exist on type 'Rea... Remove this comment to see the full error message
annotations,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isUserAnno' does not exist on type 'Read... Remove this comment to see the full error message
isUserAnno,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'createText' does not exist on type 'Read... Remove this comment to see the full error message
createText,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'editText' does not exist on type 'Readon... Remove this comment to see the full error message
editText,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'deleteText' does not exist on type 'Read... Remove this comment to see the full error message
deleteText,
} = this.props;
return (
<>
{isUserAnno ? (
@@ -31,33 +31,39 @@ const LABEL_WIDTH = globals.leftSidebarWidth - 100;
const ANNO_BUTTON_WIDTH = 50;
const LABEL_WIDTH_ANNO = LABEL_WIDTH - ANNO_BUTTON_WIDTH;
// @ts-expect-error ts-migrate(1238) FIXME: Unable to resolve signature of class decorator whe... Remove this comment to see the full error message
@connect((state, ownProps) => {
const schema = state.annoMatrix?.schema;
const schema = (state as any).annoMatrix?.schema;
// @ts-expect-error ts-migrate(2339) FIXME: Property 'metadataField' does not exist on type '{... Remove this comment to see the full error message
const { metadataField } = ownProps;
const isUserAnno = schema?.annotations?.obsByName[metadataField]?.writable;
const categoricalSelection = state.categoricalSelection?.[metadataField];
const categoricalSelection = (state as any).categoricalSelection?.[
metadataField
];
return {
colors: state.colors,
colors: (state as any).colors,
categoricalSelection,
annotations: state.annotations,
annoMatrix: state.annoMatrix,
annotations: (state as any).annotations,
annoMatrix: (state as any).annoMatrix,
schema,
crossfilter: state.obsCrossfilter,
crossfilter: (state as any).obsCrossfilter,
isUserAnno,
genesets: state.genesets.genesets,
genesets: (state as any).genesets.genesets,
};
})
class Category extends React.PureComponent {
static getSelectionState(
categoricalSelection,
metadataField,
categorySummary
categoricalSelection: any,
// @ts-expect-error ts-migrate(6133) FIXME: 'metadataField' is declared but its value is never... Remove this comment to see the full error message
metadataField: any,
categorySummary: any
) {
// total number of categories in this dimension
const totalCatCount = categorySummary.numCategoryValues;
// number of selected options in this category
const selectedCatCount = categorySummary.categoryValues.reduce(
(res, label) => (categoricalSelection.get(label) ?? true ? res + 1 : res),
(res: any, label: any) =>
categoricalSelection.get(label) ?? true ? res + 1 : res,
0
);
return selectedCatCount === totalCatCount
@@ -67,13 +73,14 @@ class Category extends React.PureComponent {
: "some";
}
static watchAsync(props, prevProps) {
static watchAsync(props: any, prevProps: any) {
return !shallowEqual(props.watchProps, prevProps.watchProps);
}
createCategorySummaryFromDfCol = memoize(createCategorySummaryFromDfCol);
getSelectionState(categorySummary) {
getSelectionState(categorySummary: any) {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categoricalSelection' does not exist on ... Remove this comment to see the full error message
const { categoricalSelection, metadataField } = this.props;
return Category.getSelectionState(
categoricalSelection,
@@ -83,6 +90,7 @@ class Category extends React.PureComponent {
}
handleColorChange = () => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, metadataField } = this.props;
dispatch({
type: "color by categorical metadata",
@@ -91,6 +99,7 @@ class Category extends React.PureComponent {
};
handleCategoryClick = () => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annotations' does not exist on type 'Rea... Remove this comment to see the full error message
const { annotations, metadataField, onExpansionChange } = this.props;
const editingCategory =
annotations.isEditingCategoryName &&
@@ -100,13 +109,13 @@ class Category extends React.PureComponent {
}
};
handleCategoryKeyPress = (e) => {
handleCategoryKeyPress = (e: any) => {
if (e.key === "Enter") {
this.handleCategoryClick();
}
};
handleToggleAllClick = (categorySummary) => {
handleToggleAllClick = (categorySummary: any) => {
const isChecked = this.getSelectionState(categorySummary);
if (isChecked === "all") {
this.toggleNone(categorySummary);
@@ -115,8 +124,9 @@ class Category extends React.PureComponent {
}
};
fetchAsyncProps = async (props) => {
fetchAsyncProps = async (props: any) => {
const { annoMatrix, metadataField, colors } = props.watchProps;
// @ts-expect-error ts-migrate(2339) FIXME: Property 'crossfilter' does not exist on type 'Rea... Remove this comment to see the full error message
const { crossfilter } = this.props;
const [categoryData, categorySummary, colorData] = await this.fetchData(
@@ -136,13 +146,14 @@ class Category extends React.PureComponent {
};
};
async fetchData(annoMatrix, metadataField, colors) {
async fetchData(annoMatrix: any, metadataField: any, colors: any) {
/*
fetch our data and the color-by data if appropriate, and then build a summary
of our category and a color table for the color-by annotation.
*/
const { schema } = annoMatrix;
const { colorAccessor, colorMode } = colors;
// @ts-expect-error ts-migrate(2339) FIXME: Property 'genesets' does not exist on type 'Readon... Remove this comment to see the full error message
const { genesets } = this.props;
let colorDataPromise = Promise.resolve(null);
if (colorAccessor) {
@@ -169,8 +180,9 @@ class Category extends React.PureComponent {
return [categoryData, categorySummary, colorData];
}
updateColorTable(colorData) {
updateColorTable(colorData: any) {
// color table, which may be null
// @ts-expect-error ts-migrate(2339) FIXME: Property 'schema' does not exist on type 'Readonly... Remove this comment to see the full error message
const { schema, colors, metadataField } = this.props;
const { colorAccessor, userColors, colorMode } = colors;
return {
@@ -187,7 +199,8 @@ class Category extends React.PureComponent {
};
}
toggleNone(categorySummary) {
toggleNone(categorySummary: any) {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, metadataField } = this.props;
dispatch(
actions.selectCategoricalAllMetadataAction(
@@ -199,7 +212,8 @@ class Category extends React.PureComponent {
);
}
toggleAll(categorySummary) {
toggleAll(categorySummary: any) {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, metadataField } = this.props;
dispatch(
actions.selectCategoricalAllMetadataAction(
@@ -213,12 +227,19 @@ class Category extends React.PureComponent {
render() {
const {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'metadataField' does not exist on type 'R... Remove this comment to see the full error message
metadataField,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isExpanded' does not exist on type 'Read... Remove this comment to see the full error message
isExpanded,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categoricalSelection' does not exist on ... Remove this comment to see the full error message
categoricalSelection,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'crossfilter' does not exist on type 'Rea... Remove this comment to see the full error message
crossfilter,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colors' does not exist on type 'Readonly... Remove this comment to see the full error message
colors,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annoMatrix' does not exist on type 'Read... Remove this comment to see the full error message
annoMatrix,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isUserAnno' does not exist on type 'Read... Remove this comment to see the full error message
isUserAnno,
} = this.props;
@@ -250,18 +271,26 @@ class Category extends React.PureComponent {
<Async.Fulfilled persist>
{(asyncProps) => {
const {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colorAccessor' does not exist on type 'u... Remove this comment to see the full error message
colorAccessor,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colorTable' does not exist on type 'unkn... Remove this comment to see the full error message
colorTable,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colorData' does not exist on type 'unkno... Remove this comment to see the full error message
colorData,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categoryData' does not exist on type 'un... Remove this comment to see the full error message
categoryData,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categorySummary' does not exist on type ... Remove this comment to see the full error message
categorySummary,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isColorAccessor' does not exist on type ... Remove this comment to see the full error message
isColorAccessor,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'handleCategoryToggleAllClick' does not e... Remove this comment to see the full error message
handleCategoryToggleAllClick,
} = asyncProps;
const isTruncated = !!categorySummary?.isTruncated;
const selectionState = this.getSelectionState(categorySummary);
return (
<CategoryRender
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ metadataField: any; checkboxID: string; is... Remove this comment to see the full error message
metadataField={metadataField}
checkboxID={checkboxID}
isUserAnno={isUserAnno}
@@ -290,7 +319,7 @@ class Category extends React.PureComponent {
export default Category;
const StillLoading = ({ metadataField, checkboxID }) => {
const StillLoading = ({ metadataField, checkboxID }: any) => {
/*
We are still loading this category, so render a "busy" signal.
*/
@@ -341,7 +370,7 @@ const StillLoading = ({ metadataField, checkboxID }) => {
);
};
const ErrorLoading = ({ metadataField, error }) => {
const ErrorLoading = ({ metadataField, error }: any) => {
console.error(error); // log error to console as it is unexpected.
return (
<div style={{ marginBottom: 10, marginTop: 4 }}>
@@ -361,16 +390,27 @@ const ErrorLoading = ({ metadataField, error }) => {
const CategoryHeader = React.memo(
({
// @ts-expect-error ts-migrate(2339) FIXME: Property 'metadataField' does not exist on type '{... Remove this comment to see the full error message
metadataField,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'checkboxID' does not exist on type '{ ch... Remove this comment to see the full error message
checkboxID,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isUserAnno' does not exist on type '{ ch... Remove this comment to see the full error message
isUserAnno,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isTruncated' does not exist on type '{ c... Remove this comment to see the full error message
isTruncated,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isColorAccessor' does not exist on type ... Remove this comment to see the full error message
isColorAccessor,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isExpanded' does not exist on type '{ ch... Remove this comment to see the full error message
isExpanded,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'selectionState' does not exist on type '... Remove this comment to see the full error message
selectionState,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'onColorChangeClick' does not exist on ty... Remove this comment to see the full error message
onColorChangeClick,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'onCategoryMenuClick' does not exist on t... Remove this comment to see the full error message
onCategoryMenuClick,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'onCategoryMenuKeyPress' does not exist o... Remove this comment to see the full error message
onCategoryMenuKeyPress,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'onCategoryToggleAllClick' does not exist... Remove this comment to see the full error message
onCategoryToggleAllClick,
}) => {
/*
@@ -379,6 +419,7 @@ const CategoryHeader = React.memo(
const checkboxRef = useRef(null);
useEffect(() => {
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
checkboxRef.current.indeterminate = selectionState === "some";
}, [checkboxRef.current, selectionState]);
@@ -408,6 +449,7 @@ const CategoryHeader = React.memo(
</label>
<span
role="menuitem"
// @ts-expect-error ts-migrate(2322) FIXME: Type 'string' is not assignable to type 'number | ... Remove this comment to see the full error message
tabIndex="0"
data-testclass="category-expand"
data-testid={`${metadataField}:category-expand`}
@@ -423,6 +465,7 @@ const CategoryHeader = React.memo(
maxWidth: isUserAnno ? LABEL_WIDTH_ANNO : LABEL_WIDTH,
}}
data-testid={`${metadataField}:category-label`}
// @ts-expect-error ts-migrate(2322) FIXME: Type 'string' is not assignable to type 'number | ... Remove this comment to see the full error message
tabIndex="-1"
>
{metadataField}
@@ -441,10 +484,13 @@ const CategoryHeader = React.memo(
)}
</span>
</div>
{<AnnoDialogEditCategoryName metadataField={metadataField} />}
{<AnnoDialogAddLabel metadataField={metadataField} />}
{/* @ts-expect-error ts-migrate(2322) FIXME: Type '{ metadataField: any; }' is not assignable t... Remove this comment to see the full error message */}
<AnnoDialogEditCategoryName metadataField={metadataField} />
{/* @ts-expect-error ts-migrate(2322) FIXME: Type '{ metadataField: any; }' is not assignable t... Remove this comment to see the full error message */}
<AnnoDialogAddLabel metadataField={metadataField} />
<div>
<AnnoMenu
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ metadataField: any; isUserAnno: any; creat... Remove this comment to see the full error message
metadataField={metadataField}
isUserAnno={isUserAnno}
createText="Add a new label to this category"
@@ -484,21 +530,37 @@ const CategoryHeader = React.memo(
const CategoryRender = React.memo(
({
// @ts-expect-error ts-migrate(2339) FIXME: Property 'metadataField' does not exist on type '{... Remove this comment to see the full error message
metadataField,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'checkboxID' does not exist on type '{ ch... Remove this comment to see the full error message
checkboxID,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isUserAnno' does not exist on type '{ ch... Remove this comment to see the full error message
isUserAnno,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isTruncated' does not exist on type '{ c... Remove this comment to see the full error message
isTruncated,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isColorAccessor' does not exist on type ... Remove this comment to see the full error message
isColorAccessor,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isExpanded' does not exist on type '{ ch... Remove this comment to see the full error message
isExpanded,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'selectionState' does not exist on type '... Remove this comment to see the full error message
selectionState,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categoryData' does not exist on type '{ ... Remove this comment to see the full error message
categoryData,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categorySummary' does not exist on type ... Remove this comment to see the full error message
categorySummary,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colorAccessor' does not exist on type '{... Remove this comment to see the full error message
colorAccessor,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colorData' does not exist on type '{ chi... Remove this comment to see the full error message
colorData,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colorTable' does not exist on type '{ ch... Remove this comment to see the full error message
colorTable,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'onColorChangeClick' does not exist on ty... Remove this comment to see the full error message
onColorChangeClick,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'onCategoryMenuClick' does not exist on t... Remove this comment to see the full error message
onCategoryMenuClick,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'onCategoryMenuKeyPress' does not exist o... Remove this comment to see the full error message
onCategoryMenuKeyPress,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'onCategoryToggleAllClick' does not exist... Remove this comment to see the full error message
onCategoryToggleAllClick,
}) => {
/*
@@ -533,6 +595,7 @@ const CategoryRender = React.memo(
}}
>
<CategoryHeader
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ metadataField: any; checkboxID: any; isUse... Remove this comment to see the full error message
metadataField={metadataField}
checkboxID={checkboxID}
isUserAnno={isUserAnno}
@@ -551,6 +614,7 @@ const CategoryRender = React.memo(
/* values*/
isExpanded ? (
<CategoryValueList
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ isUserAnno: any; metadataField: any; categ... Remove this comment to see the full error message
isUserAnno={isUserAnno}
metadataField={metadataField}
categoryData={categoryData}
@@ -574,12 +638,19 @@ const CategoryRender = React.memo(
const CategoryValueList = React.memo(
({
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isUserAnno' does not exist on type '{ ch... Remove this comment to see the full error message
isUserAnno,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'metadataField' does not exist on type '{... Remove this comment to see the full error message
metadataField,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categoryData' does not exist on type '{ ... Remove this comment to see the full error message
categoryData,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categorySummary' does not exist on type ... Remove this comment to see the full error message
categorySummary,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colorAccessor' does not exist on type '{... Remove this comment to see the full error message
colorAccessor,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colorData' does not exist on type '{ chi... Remove this comment to see the full error message
colorData,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colorTable' does not exist on type '{ ch... Remove this comment to see the full error message
colorTable,
}) => {
const tuples = [...categorySummary.categoryValueIndices];
@@ -594,6 +665,7 @@ const CategoryValueList = React.memo(
{tuples.map(([value, index]) => (
<Value
key={value}
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ key: any; isUserAnno: any; metadataField: ... Remove this comment to see the full error message
isUserAnno={isUserAnno}
metadataField={metadataField}
categoryIndex={index}
@@ -615,6 +687,7 @@ const CategoryValueList = React.memo(
{tuples.map(([value, index]) => (
<Flipped key={value} flipId={value}>
<Value
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ isUserAnno: any; metadataField: any; categ... Remove this comment to see the full error message
isUserAnno={isUserAnno}
metadataField={metadataField}
categoryIndex={index}
@@ -10,13 +10,17 @@ import LabelInput from "../labelInput";
import { labelPrompt } from "./labelUtil";
import actions from "../../actions";
type State = any;
// @ts-expect-error ts-migrate(1238) FIXME: Unable to resolve signature of class decorator whe... Remove this comment to see the full error message
@connect((state) => ({
writableCategoriesEnabled: state.config?.parameters?.annotations ?? false,
schema: state.annoMatrix?.schema,
userInfo: state.userInfo,
writableCategoriesEnabled:
(state as any).config?.parameters?.annotations ?? false,
schema: (state as any).annoMatrix?.schema,
userInfo: (state as any).userInfo,
}))
class Categories extends React.Component {
constructor(props) {
class Categories extends React.Component<{}, State> {
constructor(props: {}) {
super(props);
this.state = {
createAnnoModeActive: false,
@@ -26,7 +30,8 @@ class Categories extends React.Component {
};
}
handleCreateUserAnno = (e) => {
handleCreateUserAnno = (e: any) => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch } = this.props;
const { newCategoryText, categoryToDuplicate } = this.state;
dispatch(
@@ -55,50 +60,48 @@ class Categories extends React.Component {
});
};
handleModalDuplicateCategorySelection = (d) => {
handleModalDuplicateCategorySelection = (d: any) => {
this.setState({ categoryToDuplicate: d });
};
categoryNameError = (name) => {
categoryNameError = (name: any) => {
/*
return false if this is a LEGAL/acceptable category name or NULL/empty string,
or return an error type.
*/
return false if this is a LEGAL/acceptable category name or NULL/empty string,
or return an error type.
*/
/* allow empty string */
if (name === "") return false;
/*
test for uniqueness against *all* annotation names, not just the subset
we render as categorical.
*/
test for uniqueness against *all* annotation names, not just the subset
we render as categorical.
*/
// @ts-expect-error ts-migrate(2339) FIXME: Property 'schema' does not exist on type 'Readonly... Remove this comment to see the full error message
const { schema } = this.props;
const allCategoryNames = schema.annotations.obs.columns.map((c) => c.name);
const allCategoryNames = schema.annotations.obs.columns.map(
(c: any) => c.name
);
/* check category name syntax */
const error = AnnotationsHelpers.annotationNameIsErroneous(name);
if (error) {
return error;
}
/* disallow duplicates */
if (allCategoryNames.indexOf(name) !== -1) {
return "duplicate";
}
/* otherwise, no error */
return false;
};
handleChange = (name) => {
handleChange = (name: any) => {
this.setState({ newCategoryText: name });
};
handleSelect = (name) => {
handleSelect = (name: any) => {
this.setState({ newCategoryText: name });
};
instruction = (name) => {
instruction = (name: any) => {
return labelPrompt(
this.categoryNameError(name),
"New, unique category name",
@@ -106,7 +109,7 @@ class Categories extends React.Component {
);
};
onExpansionChange = (catName) => {
onExpansionChange = (catName: any) => {
const { expandedCats } = this.state;
if (expandedCats.has(catName)) {
const _expandedCats = new Set(expandedCats);
@@ -126,16 +129,13 @@ class Categories extends React.Component {
newCategoryText,
expandedCats,
} = this.state;
const {
writableCategoriesEnabled,
schema,
userInfo,
} = this.props;
// @ts-expect-error ts-migrate(2339) FIXME: Property 'writableCategoriesEnabled' does not exis... Remove this comment to see the full error message
const { writableCategoriesEnabled, schema, userInfo } = this.props;
/* all names, sorted in display order. Will be rendered in this order */
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
const allCategoryNames = ControlsHelpers.selectableCategoryNames(
schema
).sort();
return (
<div
style={{
@@ -143,6 +143,7 @@ class Categories extends React.Component {
}}
>
<AnnoDialog
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ isActive: any; title: string; instruction:... Remove this comment to see the full error message
isActive={createAnnoModeActive}
title="Create new category"
instruction={this.instruction(newCategoryText)}
@@ -155,6 +156,7 @@ class Categories extends React.Component {
handleCancel={this.handleDisableAnnoMode}
annoInput={
<LabelInput
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ labelSuggestions: null; onChange: (name: a... Remove this comment to see the full error message
labelSuggestions={null}
onChange={this.handleChange}
onSelect={this.handleSelect}
@@ -169,6 +171,7 @@ class Categories extends React.Component {
}
annoSelect={
<AnnoSelect
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ handleModalDuplicateCategorySelection: (d:... Remove this comment to see the full error message
handleModalDuplicateCategorySelection={
this.handleModalDuplicateCategorySelection
}
@@ -209,12 +212,13 @@ class Categories extends React.Component {
{/* READ ONLY CATEGORICAL FIELDS */}
{/* this is duplicative but flat, could be abstracted */}
{allCategoryNames.map((catName) =>
{allCategoryNames.map((catName: any) =>
!schema.annotations.obsByName[catName].writable &&
(schema.annotations.obsByName[catName].categories?.length > 1 ||
!schema.annotations.obsByName[catName].categories) ? (
<Category
key={catName}
// @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call.
metadataField={catName}
onExpansionChange={this.onExpansionChange}
isExpanded={expandedCats.has(catName)}
@@ -223,10 +227,11 @@ class Categories extends React.Component {
) : null
)}
{/* WRITEABLE FIELDS */}
{allCategoryNames.map((catName) =>
{allCategoryNames.map((catName: any) =>
schema.annotations.obsByName[catName].writable ? (
<Category
key={catName}
// @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call.
metadataField={catName}
onExpansionChange={this.onExpansionChange}
isExpanded={expandedCats.has(catName)}
@@ -3,7 +3,7 @@ import { Colors } from "@blueprintjs/core";
import { AnnotationsHelpers } from "../../util/stateManager";
export function isLabelErroneous(label, metadataField, schema) {
export function isLabelErroneous(label: any, metadataField: any, schema: any) {
/*
return false if this is a LEGAL/acceptable category name or NULL/empty string,
or return an error type.
@@ -35,9 +35,10 @@ const errorMessageMap = {
"multi-space-run": "Multiple consecutive spaces not allowed",
};
export function labelPrompt(err, prolog, epilog) {
export function labelPrompt(err: any, prolog: any, epilog: any) {
let errPrompt = null;
if (err) {
// @ts-expect-error ts-migrate(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
let errMsg = errorMessageMap[err] ?? "error";
errMsg = errMsg[0].toLowerCase() + errMsg.slice(1);
errPrompt = (
@@ -13,6 +13,7 @@ import {
Position,
} from "@blueprintjs/core";
import * as globals from "../../../globals";
// @ts-expect-error ts-migrate(2307) FIXME: Cannot find module '../categorical.css' or its cor... Remove this comment to see the full error message
import styles from "../categorical.css";
import AnnoDialog from "../../annoDialog";
import LabelInput from "../../labelInput";
@@ -29,15 +30,20 @@ const STACKED_BAR_HEIGHT = 11;
const STACKED_BAR_WIDTH = 100;
/* this is defined outside of the class so we can use it in connect() */
function _currentLabelAsString(ownProps) {
function _currentLabelAsString(ownProps: any) {
const { label } = ownProps;
// when called as a function, the String() constructor performs type conversion,
// and returns a primitive string.
return String(label);
}
type State = any;
// @ts-expect-error ts-migrate(1238) FIXME: Unable to resolve signature of class decorator whe... Remove this comment to see the full error message
@connect((state, ownProps) => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'pointDilation' does not exist on type 'D... Remove this comment to see the full error message
const { pointDilation, categoricalSelection } = state;
// @ts-expect-error ts-migrate(2339) FIXME: Property 'metadataField' does not exist on type '{... Remove this comment to see the full error message
const { metadataField, categorySummary, categoryIndex } = ownProps;
const isDilated =
pointDilation.metadataField === metadataField &&
@@ -48,27 +54,28 @@ function _currentLabelAsString(ownProps) {
const isSelected = category.get(label) ?? true;
return {
annotations: state.annotations,
schema: state.annoMatrix?.schema,
annotations: (state as any).annotations,
schema: (state as any).annoMatrix?.schema,
isDilated,
isSelected,
label,
};
})
class CategoryValue extends React.Component {
constructor(props) {
class CategoryValue extends React.Component<{}, State> {
constructor(props: {}) {
super(props);
this.state = {
editedLabelText: this.currentLabelAsString(),
};
}
componentDidUpdate(prevProps) {
componentDidUpdate(prevProps: {}) {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'metadataField' does not exist on type 'R... Remove this comment to see the full error message
const { metadataField, categoryIndex, categorySummary } = this.props;
if (
prevProps.metadataField !== metadataField ||
prevProps.categoryIndex !== categoryIndex ||
prevProps.categorySummary !== categorySummary
(prevProps as any).metadataField !== metadataField ||
(prevProps as any).categoryIndex !== categoryIndex ||
(prevProps as any).categorySummary !== categorySummary
) {
// eslint-disable-next-line react/no-did-update-set-state --- adequately checked to prevent looping
this.setState({
@@ -79,22 +86,26 @@ class CategoryValue extends React.Component {
// If coloring by and this isn't the colorAccessor and it isn't being edited
get shouldRenderStackedBarOrHistogram() {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colorAccessor' does not exist on type 'R... Remove this comment to see the full error message
const { colorAccessor, isColorBy, annotations } = this.props;
return !!colorAccessor && !isColorBy && !annotations.isEditingLabelName;
}
handleDeleteValue = () => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, metadataField, label } = this.props;
dispatch(actions.annotationDeleteLabelFromCategory(metadataField, label));
};
handleAddCurrentSelectionToThisLabel = () => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, metadataField, label } = this.props;
dispatch(actions.annotationLabelCurrentSelection(metadataField, label));
};
handleEditValue = (e) => {
handleEditValue = (e: any) => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, metadataField, label } = this.props;
const { editedLabelText } = this.state;
this.cancelEditMode();
@@ -108,7 +119,8 @@ class CategoryValue extends React.Component {
e.preventDefault();
};
handleCreateArbitraryLabel = (txt) => {
handleCreateArbitraryLabel = (txt: any) => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, metadataField, label } = this.props;
this.cancelEditMode();
dispatch(
@@ -116,17 +128,19 @@ class CategoryValue extends React.Component {
);
};
labelNameError = (name) => {
labelNameError = (name: any) => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'metadataField' does not exist on type 'R... Remove this comment to see the full error message
const { metadataField, schema } = this.props;
if (name === this.currentLabelAsString()) return false;
return isLabelErroneous(name, metadataField, schema);
};
instruction = (label) => {
instruction = (label: any) => {
return labelPrompt(this.labelNameError(label), "New, unique label", ":");
};
activateEditLabelMode = () => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, metadataField, categoryIndex, label } = this.props;
dispatch({
type: "annotation: activate edit label mode",
@@ -137,6 +151,7 @@ class CategoryValue extends React.Component {
};
cancelEditMode = () => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, metadataField, categoryIndex, label } = this.props;
this.setState({
editedLabelText: this.currentLabelAsString(),
@@ -151,9 +166,13 @@ class CategoryValue extends React.Component {
toggleOff = () => {
const {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
dispatch,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'metadataField' does not exist on type 'R... Remove this comment to see the full error message
metadataField,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categoryIndex' does not exist on type 'R... Remove this comment to see the full error message
categoryIndex,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categorySummary' does not exist on type ... Remove this comment to see the full error message
categorySummary,
} = this.props;
const label = categorySummary.categoryValues[categoryIndex];
@@ -168,7 +187,7 @@ class CategoryValue extends React.Component {
);
};
shouldComponentUpdate = (nextProps, nextState) => {
shouldComponentUpdate = (nextProps: any, nextState: any) => {
/*
Checks to see if at least one of the following changed:
* world state
@@ -179,6 +198,7 @@ class CategoryValue extends React.Component {
If and only if true, update the component
*/
const { props, state } = this;
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categoryIndex' does not exist on type 'R... Remove this comment to see the full error message
const { categoryIndex, categorySummary, isSelected } = props;
const {
categoryIndex: newCategoryIndex,
@@ -191,10 +211,12 @@ class CategoryValue extends React.Component {
const labelChanged = label !== newLabel;
const valueSelectionChange = isSelected !== newIsSelected;
const colorAccessorChange = props.colorAccessor !== nextProps.colorAccessor;
const annotationsChange = props.annotations !== nextProps.annotations;
const colorAccessorChange =
(props as any).colorAccessor !== nextProps.colorAccessor;
const annotationsChange =
(props as any).annotations !== nextProps.annotations;
const editingLabel = state.editedLabelText !== nextState.editedLabelText;
const dilationChange = props.isDilated !== nextProps.isDilated;
const dilationChange = (props as any).isDilated !== nextProps.isDilated;
const count = categorySummary.categoryValueCounts[categoryIndex];
const newCount = newCategorySummary.categoryValueCounts[newCategoryIndex];
@@ -205,7 +227,7 @@ class CategoryValue extends React.Component {
// if any one changes, but only for the currently colored-by category.
const colorMightHaveChanged =
nextProps.colorAccessor === nextProps.metadataField &&
props.categorySummary !== nextProps.categorySummary;
(props as any).categorySummary !== nextProps.categorySummary;
return (
labelChanged ||
@@ -221,9 +243,13 @@ class CategoryValue extends React.Component {
toggleOn = () => {
const {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
dispatch,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'metadataField' does not exist on type 'R... Remove this comment to see the full error message
metadataField,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categoryIndex' does not exist on type 'R... Remove this comment to see the full error message
categoryIndex,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categorySummary' does not exist on type ... Remove this comment to see the full error message
categorySummary,
} = this.props;
const label = categorySummary.categoryValues[categoryIndex];
@@ -239,6 +265,7 @@ class CategoryValue extends React.Component {
};
handleMouseEnter = () => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, metadataField, categoryIndex, label } = this.props;
dispatch({
type: "category value mouse hover start",
@@ -249,6 +276,7 @@ class CategoryValue extends React.Component {
};
handleMouseExit = () => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, metadataField, categoryIndex, label } = this.props;
dispatch({
type: "category value mouse hover end",
@@ -258,23 +286,24 @@ class CategoryValue extends React.Component {
});
};
handleTextChange = (text) => {
handleTextChange = (text: any) => {
this.setState({ editedLabelText: text });
};
handleChoice = (e) => {
handleChoice = (e: any) => {
/* Blueprint Suggest format */
this.setState({ editedLabelText: e.target });
};
createHistogramBins = (
metadataField,
categoryData,
colorAccessor,
colorData,
categoryValue,
width,
height
metadataField: any,
categoryData: any,
// @ts-expect-error ts-migrate(6133) FIXME: 'colorAccessor' is declared but its value is never... Remove this comment to see the full error message
colorAccessor: any,
colorData: any,
categoryValue: any,
width: any,
height: any
) => {
/*
Knowing that colorScale is based off continuous data,
@@ -309,14 +338,15 @@ class CategoryValue extends React.Component {
};
createStackedGraphBins = (
metadataField,
categoryData,
colorAccessor,
colorData,
categoryValue,
colorTable,
schema,
width
metadataField: any,
categoryData: any,
colorAccessor: any,
colorData: any,
categoryValue: any,
// @ts-expect-error ts-migrate(6133) FIXME: 'colorTable' is declared but its value is never re... Remove this comment to see the full error message
colorTable: any,
schema: any,
width: any
) => {
/*
Knowing that the color scale is based off of categorical data,
@@ -357,12 +387,13 @@ class CategoryValue extends React.Component {
return _currentLabelAsString(this.props);
}
isAddCurrentSelectionDisabled(crossfilter, category, value) {
isAddCurrentSelectionDisabled(crossfilter: any, category: any, value: any) {
/*
disable "add current selection to label", if one of the following is true:
1. no cells are selected
2. all currently selected cells already have this label, on this category
*/
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categoryData' does not exist on type 'Re... Remove this comment to see the full error message
const { categoryData } = this.props;
// 1. no cells selected?
@@ -382,12 +413,19 @@ class CategoryValue extends React.Component {
renderMiniStackedBar = () => {
const {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colorAccessor' does not exist on type 'R... Remove this comment to see the full error message
colorAccessor,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'metadataField' does not exist on type 'R... Remove this comment to see the full error message
metadataField,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categoryData' does not exist on type 'Re... Remove this comment to see the full error message
categoryData,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colorData' does not exist on type 'Reado... Remove this comment to see the full error message
colorData,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colorTable' does not exist on type 'Read... Remove this comment to see the full error message
colorTable,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'schema' does not exist on type 'Readonly... Remove this comment to see the full error message
schema,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'label' does not exist on type 'Readonly<... Remove this comment to see the full error message
label,
} = this.props;
const isColorBy = metadataField === colorAccessor;
@@ -425,6 +463,7 @@ class CategoryValue extends React.Component {
domain,
occupancy,
}}
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ height: number; width: number; colorTable:... Remove this comment to see the full error message
height={STACKED_BAR_HEIGHT}
width={STACKED_BAR_WIDTH}
/>
@@ -433,12 +472,19 @@ class CategoryValue extends React.Component {
renderMiniHistogram = () => {
const {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colorAccessor' does not exist on type 'R... Remove this comment to see the full error message
colorAccessor,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'metadataField' does not exist on type 'R... Remove this comment to see the full error message
metadataField,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colorData' does not exist on type 'Reado... Remove this comment to see the full error message
colorData,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categoryData' does not exist on type 'Re... Remove this comment to see the full error message
categoryData,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colorTable' does not exist on type 'Read... Remove this comment to see the full error message
colorTable,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'schema' does not exist on type 'Readonly... Remove this comment to see the full error message
schema,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'label' does not exist on type 'Readonly<... Remove this comment to see the full error message
label,
} = this.props;
const colorScale = colorTable?.scale;
@@ -473,6 +519,7 @@ class CategoryValue extends React.Component {
yScale,
bins,
}}
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ obsOrVarContinuousFieldDisplayName: any; d... Remove this comment to see the full error message
obsOrVarContinuousFieldDisplayName={colorAccessor}
domainLabel={label}
height={STACKED_BAR_HEIGHT}
@@ -483,15 +530,25 @@ class CategoryValue extends React.Component {
render() {
const {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'metadataField' does not exist on type 'R... Remove this comment to see the full error message
metadataField,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categoryIndex' does not exist on type 'R... Remove this comment to see the full error message
categoryIndex,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colorAccessor' does not exist on type 'R... Remove this comment to see the full error message
colorAccessor,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colorTable' does not exist on type 'Read... Remove this comment to see the full error message
colorTable,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isUserAnno' does not exist on type 'Read... Remove this comment to see the full error message
isUserAnno,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annotations' does not exist on type 'Rea... Remove this comment to see the full error message
annotations,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isDilated' does not exist on type 'Reado... Remove this comment to see the full error message
isDilated,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isSelected' does not exist on type 'Read... Remove this comment to see the full error message
isSelected,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categorySummary' does not exist on type ... Remove this comment to see the full error message
categorySummary,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'label' does not exist on type 'Readonly<... Remove this comment to see the full error message
label,
} = this.props;
const colorScale = colorTable?.scale;
@@ -587,6 +644,7 @@ class CategoryValue extends React.Component {
<span
data-testid={`categorical-value-${metadataField}-${displayString}`}
data-testclass="categorical-value"
// @ts-expect-error ts-migrate(2322) FIXME: Type 'string' is not assignable to type 'number | ... Remove this comment to see the full error message
tabIndex="-1"
style={{
width: labelWidth,
@@ -612,6 +670,7 @@ class CategoryValue extends React.Component {
{editModeActive ? (
<div>
<AnnoDialog
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ isActive: any; inputProps: { "data-testid"... Remove this comment to see the full error message
isActive={editModeActive}
inputProps={{
"data-testid": `${metadataField}:edit-label-name-dialog`,
@@ -630,6 +689,7 @@ class CategoryValue extends React.Component {
handleCancel={this.cancelEditMode}
annoInput={
<LabelInput
// @ts-expect-error ts-migrate(2322) FIXME: Type '{ label: any; labelSuggestions: null; onChan... Remove this comment to see the full error message
label={editedLabelText}
labelSuggestions={null}
onChange={this.handleTextChange}
@@ -8,64 +8,59 @@ import {
Position,
} from "@blueprintjs/core";
// @ts-expect-error ts-migrate(1238) FIXME: Unable to resolve signature of class decorator whe... Remove this comment to see the full error message
@connect((state) => ({
schema: state.annoMatrix?.schema,
schema: (state as any).annoMatrix?.schema,
}))
class Occupancy extends React.PureComponent {
canvas: any;
_WIDTH = 100;
_HEIGHT = 11;
createHistogram = () => {
/*
Knowing that colorScale is based off continous data,
createHistogram fetches the continous data in relation to the cells releveant to the catagory value.
It then seperates that data into 50 bins for drawing the mini-histogram
*/
Knowing that colorScale is based off continous data,
createHistogram fetches the continous data in relation to the cells releveant to the catagory value.
It then seperates that data into 50 bins for drawing the mini-histogram
*/
const {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'metadataField' does not exist on type 'R... Remove this comment to see the full error message
metadataField,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categoryData' does not exist on type 'Re... Remove this comment to see the full error message
categoryData,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colorData' does not exist on type 'Reado... Remove this comment to see the full error message
colorData,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categoryValue' does not exist on type 'R... Remove this comment to see the full error message
categoryValue,
} = this.props;
if (!this.canvas) return;
const groupBy = categoryData.col(metadataField);
const col = colorData.icol(0);
const range = col.summarize();
const histogramMap = col.histogram(
50,
[range.min, range.max],
groupBy
); /* Because the signature changes we really need different names for histogram to differentiate signatures */
const bins = histogramMap.has(categoryValue)
? histogramMap.get(categoryValue)
: new Array(50).fill(0);
const xScale = d3
.scaleLinear()
.domain([0, bins.length])
.range([0, this._WIDTH]);
const largestBin = Math.max(...bins);
const yScale = d3
.scaleLinear()
.domain([0, largestBin])
.range([0, this._HEIGHT]);
const ctx = this.canvas.getContext("2d");
ctx.fillStyle = "#000";
let x;
let y;
const rectWidth = this._WIDTH / bins.length;
for (let i = 0, { length } = bins; i < length; i += 1) {
x = xScale(i);
y = yScale(bins[i]);
@@ -75,32 +70,34 @@ class Occupancy extends React.PureComponent {
createOccupancyStack = () => {
/*
Knowing that the color scale is based off of catagorical data,
createOccupancyStack obtains a map showing the number if cells per colored value
Using the colorScale a stack of colored bars is drawn representing the map
*/
Knowing that the color scale is based off of catagorical data,
createOccupancyStack obtains a map showing the number if cells per colored value
Using the colorScale a stack of colored bars is drawn representing the map
*/
const {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'metadataField' does not exist on type 'R... Remove this comment to see the full error message
metadataField,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categoryData' does not exist on type 'Re... Remove this comment to see the full error message
categoryData,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colorAccessor' does not exist on type 'R... Remove this comment to see the full error message
colorAccessor,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'categoryValue' does not exist on type 'R... Remove this comment to see the full error message
categoryValue,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colorTable' does not exist on type 'Read... Remove this comment to see the full error message
colorTable,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'schema' does not exist on type 'Readonly... Remove this comment to see the full error message
schema,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colorData' does not exist on type 'Reado... Remove this comment to see the full error message
colorData,
} = this.props;
const { scale: colorScale } = colorTable;
const ctx = this.canvas?.getContext("2d");
if (!ctx) return;
const groupBy = categoryData.col(metadataField);
const occupancyMap = colorData
.col(colorAccessor)
.histogramCategorical(groupBy);
const occupancy = occupancyMap.get(categoryValue);
if (occupancy && occupancy.size > 0) {
// not all categories have occupancy, so occupancy may be undefined.
const x = d3
@@ -110,15 +107,12 @@ class Occupancy extends React.PureComponent {
.range([0, this._WIDTH]);
const categories =
schema.annotations.obsByName[colorAccessor]?.categories;
let currentOffset = 0;
const dfColumn = colorData.col(colorAccessor);
const categoryValues = dfColumn.summarizeCategorical().categories;
let o;
let scaledValue;
let value;
for (let i = 0, { length } = categoryValues; i < length; i += 1) {
value = categoryValues[i];
o = occupancy.get(value);
@@ -133,11 +127,11 @@ class Occupancy extends React.PureComponent {
};
render() {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'colorAccessor' does not exist on type 'R... Remove this comment to see the full error message
const { colorAccessor, categoryValue, colorByIsCategorical } = this.props;
const { canvas } = this;
if (canvas)
canvas.getContext("2d").clearRect(0, 0, this._WIDTH, this._HEIGHT);
return (
<Popover
interactionKind={PopoverInteractionKind.HOVER_TARGET_ONLY}
@@ -1,32 +0,0 @@
/* rc slider https://www.npmjs.com/package/rc-slider */
import React from "react";
import { connect } from "react-redux";
import HistogramBrush from "../brushableHistogram";
@connect((state) => ({
schema: state.annoMatrix?.schema,
}))
class Continuous extends React.PureComponent {
render() {
/* initial value for iterator to simulate index, ranges is an object */
const { schema } = this.props;
if (!schema) return null;
const obsIndex = schema.annotations.obs.index;
const allContinuousNames = schema.annotations.obs.columns
.filter((col) => col.type === "int32" || col.type === "float32")
.filter((col) => col.name !== obsIndex)
.filter((col) => !col.writable) // skip user annotations - they will be treated as categorical
.map((col) => col.name);
return (
<div>
{allContinuousNames.map((key, zebra) => (
<HistogramBrush key={key} field={key} isObs zebra={zebra % 2 === 0} />
))}
</div>
);
}
}
export default Continuous;
@@ -0,0 +1,34 @@
/* rc slider https://www.npmjs.com/package/rc-slider */
import React from "react";
import { connect } from "react-redux";
import HistogramBrush from "../brushableHistogram";
// @ts-expect-error ts-migrate(1238) FIXME: Unable to resolve signature of class decorator whe... Remove this comment to see the full error message
@connect((state) => ({
schema: (state as any).annoMatrix?.schema,
}))
class Continuous extends React.PureComponent {
render() {
/* initial value for iterator to simulate index, ranges is an object */
// @ts-expect-error ts-migrate(2339) FIXME: Property 'schema' does not exist on type 'Readonly... Remove this comment to see the full error message
const { schema } = this.props;
if (!schema) return null;
const obsIndex = schema.annotations.obs.index;
const allContinuousNames = schema.annotations.obs.columns
.filter((col: any) => col.type === "int32" || col.type === "float32")
.filter((col: any) => col.name !== obsIndex)
.filter((col: any) => !col.writable) // skip user annotations - they will be treated as categorical
.map((col: any) => col.name);
return (
<div>
{allContinuousNames.map((key: any, zebra: any) => (
// @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call.
<HistogramBrush key={key} field={key} isObs zebra={zebra % 2 === 0} />
))}
</div>
);
}
}
export default Continuous;
@@ -5,7 +5,7 @@
******************************************/
import * as d3 from "d3";
const setupParallelCoordinates = (width, height, margin) => {
const setupParallelCoordinates = (width: any, height: any, margin: any) => {
const container = d3.select("#parcoords");
const svg = container
@@ -24,10 +24,15 @@ const setupParallelCoordinates = (width, height, margin) => {
.style("margin-top", `${margin.top}px`)
.style("margin-left", `${margin.left}px`);
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
const ctx = canvas.node().getContext("2d");
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
ctx.globalCompositeOperation = "darken";
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
ctx.globalAlpha = 0.15;
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
ctx.lineWidth = 1.5;
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
ctx.scale(devicePixelRatio, devicePixelRatio);
return {
@@ -12,14 +12,14 @@ export const innerHeight = height - 2;
export const devicePixelRatio = window.devicePixelRatio || 1;
export const createDimensions = (data) => {
const newArr = [];
export const createDimensions = (data: any) => {
const newArr: any = [];
each(data, (value, key) => {
if (value.range) {
newArr.push({
key /* room for confusion: lodash calls this key, it's also the name of the property parallel coords code is looking for */,
type: {
within: (d, extent, dim) =>
within: (d: any, extent: any, dim: any) =>
extent[0] <= dim.scale(d) && dim.scale(d) <= extent[1],
},
scale: d3
@@ -32,16 +32,17 @@ export const createDimensions = (data) => {
return newArr;
};
// @ts-expect-error ts-migrate(2554) FIXME: Expected 1 arguments, but got 0.
export const yAxis = d3.axisLeft();
export const brushstart = () => {
d3.event.sourceEvent.stopPropagation();
(d3 as any).event.sourceEvent.stopPropagation();
};
// Unused.
// export const d3_functor = v => (typeof v === "function" ? v : () => v);
export const project = (d, dimensions, xscale) =>
dimensions.map((p, i) => {
export const project = (d: any, dimensions: any, xscale: any) =>
dimensions.map((p: any, i: any) => {
// check if data element has property and contains a value
if (!(p.key in d) || d[p.key] === null) return null;
@@ -9,7 +9,7 @@ import {
} from "../../util/stateManager/colorHelpers";
// create continuous color legend
const continuous = (selectorId, colorScale, colorAccessor) => {
const continuous = (selectorId: any, colorScale: any, colorAccessor: any) => {
const legendHeight = 200;
const legendWidth = 80;
const margin = { top: 10, right: 60, bottom: 10, left: 2 };
@@ -33,6 +33,7 @@ const continuous = (selectorId, colorScale, colorAccessor) => {
we flip the color scale as well [1, 0] instead of [0, 1] */
.node();
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
const ctx = canvas.getContext("2d");
const legendScale = d3
@@ -44,6 +45,7 @@ const continuous = (selectorId, colorScale, colorAccessor) => {
]); /* we flip this to make viridis colors dark if high in the color scale */
// image data hackery based on http://bl.ocks.org/mbostock/048d21cf747371b11884f75ad896e5a5
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
const image = ctx.createImageData(1, legendHeight);
d3.range(legendHeight).forEach((i) => {
const c = d3.rgb(colorScale(legendScale.invert(i)));
@@ -52,6 +54,7 @@ const continuous = (selectorId, colorScale, colorAccessor) => {
image.data[4 * i + 2] = c.b;
image.data[4 * i + 3] = 255;
});
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
ctx.putImageData(image, 0, 0);
// A simpler way to do the above, but possibly slower. keep in mind the legend
@@ -105,27 +108,26 @@ const continuous = (selectorId, colorScale, colorAccessor) => {
.text(colorAccessor);
};
// @ts-expect-error ts-migrate(1238) FIXME: Unable to resolve signature of class decorator whe... Remove this comment to see the full error message
@connect((state) => ({
annoMatrix: state.annoMatrix,
colors: state.colors,
genesets: state.genesets.genesets,
annoMatrix: (state as any).annoMatrix,
colors: (state as any).colors,
genesets: (state as any).genesets.genesets,
}))
class ContinuousLegend extends React.Component {
async componentDidUpdate(prevProps) {
async componentDidUpdate(prevProps: any) {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annoMatrix' does not exist on type 'Read... Remove this comment to see the full error message
const { annoMatrix, colors, genesets } = this.props;
if (!colors || !annoMatrix) return;
if (colors !== prevProps?.colors || annoMatrix !== prevProps?.annoMatrix) {
const { schema } = annoMatrix;
const { colorMode, colorAccessor, userColors } = colors;
const colorQuery = createColorQuery(
colorMode,
colorAccessor,
schema,
genesets
);
const colorDf = colorQuery ? await annoMatrix.fetch(...colorQuery) : null;
const colorTable = createColorTable(
colorMode,
@@ -134,19 +136,19 @@ class ContinuousLegend extends React.Component {
schema,
userColors
);
const colorScale = colorTable.scale;
// @ts-expect-error ts-migrate(2339) FIXME: Property 'range' does not exist on type '((idx: an... Remove this comment to see the full error message
const range = colorScale?.range;
// @ts-expect-error ts-migrate(2339) FIXME: Property 'domain' does not exist on type '((idx: a... Remove this comment to see the full error message
const [domainMin, domainMax] = colorScale?.domain?.() ?? [0, 0];
/* always remove it, if it's not continuous we don't put it back. */
d3.select("#continuous_legend").selectAll("*").remove();
if (colorAccessor && colorScale && range && domainMin < domainMax) {
/* fragile! continuous range is 0 to 1, not [#fa4b2c, ...], make this a flag? */
if (range()[0][0] !== "#") {
continuous(
"#continuous_legend",
// @ts-expect-error ts-migrate(2339) FIXME: Property 'domain' does not exist on type '((idx: a... Remove this comment to see the full error message
d3.scaleSequential(interpolateCool).domain(colorScale.domain()),
colorAccessor
);
@@ -15,25 +15,30 @@ import * as globals from "../../globals";
import actions from "../../actions";
import { getDiscreteCellEmbeddingRowIndex } from "../../util/stateManager/viewStackHelpers";
type EmbeddingState = any;
// @ts-expect-error ts-migrate(1238) FIXME: Unable to resolve signature of class decorator whe... Remove this comment to see the full error message
@connect((state) => {
return {
layoutChoice: state.layoutChoice, // TODO: really should clean up naming, s/layout/embedding/g
schema: state.annoMatrix?.schema,
crossfilter: state.obsCrossfilter,
layoutChoice: (state as any).layoutChoice,
schema: (state as any).annoMatrix?.schema,
crossfilter: (state as any).obsCrossfilter,
};
})
class Embedding extends React.PureComponent {
constructor(props) {
class Embedding extends React.PureComponent<{}, EmbeddingState> {
constructor(props: {}) {
super(props);
this.state = {};
}
handleLayoutChoiceChange = (e) => {
handleLayoutChoiceChange = (e: any) => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch } = this.props;
dispatch(actions.layoutChoiceAction(e.currentTarget.value));
};
render() {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'layoutChoice' does not exist on type 'Re... Remove this comment to see the full error message
const { layoutChoice, schema, crossfilter } = this.props;
const { annoMatrix } = crossfilter;
return (
@@ -100,10 +105,11 @@ class Embedding extends React.PureComponent {
export default Embedding;
const loadAllEmbeddingCounts = async ({ annoMatrix, available }) => {
const loadAllEmbeddingCounts = async ({ annoMatrix, available }: any) => {
const embeddings = await Promise.all(
available.map((name) => annoMatrix.base().fetch("emb", name))
available.map((name: any) => annoMatrix.base().fetch("emb", name))
);
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'name' implicitly has an 'any' type.
return available.map((name, idx) => ({
embeddingName: name,
embedding: embeddings[idx],
@@ -111,7 +117,7 @@ const loadAllEmbeddingCounts = async ({ annoMatrix, available }) => {
}));
};
const EmbeddingChoices = ({ onChange, annoMatrix, layoutChoice }) => {
const EmbeddingChoices = ({ onChange, annoMatrix, layoutChoice }: any) => {
const { available } = layoutChoice;
const { data, error, isPending } = useAsync({
promiseFn: loadAllEmbeddingCounts,
@@ -127,7 +133,7 @@ const EmbeddingChoices = ({ onChange, annoMatrix, layoutChoice }) => {
/* still loading, or errored out - just omit counts (TODO: spinner?) */
return (
<RadioGroup onChange={onChange} selectedValue={layoutChoice.current}>
{layoutChoice.available.map((name) => (
{layoutChoice.available.map((name: any) => (
<Radio label={`${name}`} value={name} key={name} />
))}
</RadioGroup>
@@ -136,7 +142,7 @@ const EmbeddingChoices = ({ onChange, annoMatrix, layoutChoice }) => {
if (data) {
return (
<RadioGroup onChange={onChange} selectedValue={layoutChoice.current}>
{data.map((summary) => {
{data.map((summary: any) => {
const { discreteCellIndex, embeddingName } = summary;
const sizeHint = `${discreteCellIndex.size()} cells`;
return (
@@ -1,6 +1,6 @@
import React from "react";
function Container(props) {
function Container(props: any) {
const { children } = props;
return (
<div
@@ -2,6 +2,7 @@ import React from "react";
import * as globals from "../../globals";
class Layout extends React.Component {
viewportRef: any;
/*
Layout - this react component contains all the layout style and logic for the application once it has loaded.
@@ -23,6 +24,7 @@ class Layout extends React.Component {
render() {
const { children } = this.props;
// @ts-expect-error ts-migrate(2488) FIXME: Type 'ReactNode' must have a '[Symbol.iterator]()'... Remove this comment to see the full error message
const [leftSidebar, renderGraph, rightSidebar] = children;
return (
<div
@@ -1,7 +1,7 @@
import React from "react";
import * as globals from "../../globals";
const Logo = (props) => {
const Logo = (props: any) => {
const { size } = props;
return (
<svg width={size} height={size} viewBox="0 0 48 48" fill="none">
@@ -11,20 +11,20 @@ const ToastTopCenter = Toaster.create({
/*
A "user" error - eg, bad input
*/
export const postUserErrorToast = (message) =>
export const postUserErrorToast = (message: any) =>
ToastTopCenter.show({ message, intent: Intent.WARNING });
/*
A toast the user must dismiss manually, because they need to act on its information,
ie., 8 bulk add genes out of 40 were bad. Manually see which ones and fix.
*/
export const keepAroundErrorToast = (message) =>
export const keepAroundErrorToast = (message: any) =>
ToastTopCenter.show({ message, timeout: 0, intent: Intent.WARNING });
/*
a hard network error
*/
export const postNetworkErrorToast = (message, key = undefined) =>
export const postNetworkErrorToast = (message: any, key = undefined) =>
ToastTopCenter.show(
{
message,
@@ -37,14 +37,14 @@ export const postNetworkErrorToast = (message, key = undefined) =>
/*
Async message to user
*/
export const postAsyncSuccessToast = (message) =>
export const postAsyncSuccessToast = (message: any) =>
ToastTopCenter.show({
message,
timeout: 10000,
intent: Intent.SUCCESS,
});
export const postAsyncFailureToast = (message) =>
export const postAsyncFailureToast = (message: any) =>
ToastTopCenter.show({
message,
timeout: 10000,
@@ -9,17 +9,23 @@ import actions from "../../actions";
const MINI_HISTOGRAM_WIDTH = 110;
type State = any;
// @ts-expect-error ts-migrate(1238) FIXME: Unable to resolve signature of class decorator whe... Remove this comment to see the full error message
@connect((state, ownProps) => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'gene' does not exist on type '{}'.
const { gene } = ownProps;
return {
isColorAccessor: state.colors.colorAccessor === gene,
isScatterplotXXaccessor: state.controls.scatterplotXXaccessor === gene,
isScatterplotYYaccessor: state.controls.scatterplotYYaccessor === gene,
isColorAccessor: (state as any).colors.colorAccessor === gene,
isScatterplotXXaccessor:
(state as any).controls.scatterplotXXaccessor === gene,
isScatterplotYYaccessor:
(state as any).controls.scatterplotYYaccessor === gene,
};
})
class Gene extends React.Component {
constructor(props) {
class Gene extends React.Component<{}, State> {
constructor(props: {}) {
super(props);
this.state = {
geneIsExpanded: false,
@@ -27,6 +33,7 @@ class Gene extends React.Component {
}
onColorChangeClick = () => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, gene } = this.props;
dispatch(actions.requestSingleGeneExpressionCountsForColoringPOST(gene));
};
@@ -37,6 +44,7 @@ class Gene extends React.Component {
};
handleSetGeneAsScatterplotX = () => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, gene } = this.props;
dispatch({
type: "set scatterplot x",
@@ -45,6 +53,7 @@ class Gene extends React.Component {
};
handleSetGeneAsScatterplotY = () => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, gene } = this.props;
dispatch({
type: "set scatterplot y",
@@ -53,18 +62,26 @@ class Gene extends React.Component {
};
handleDeleteGeneFromSet = () => {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message
const { dispatch, gene, geneset } = this.props;
dispatch(actions.genesetDeleteGenes(geneset, [gene]));
};
render() {
const {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'gene' does not exist on type 'Readonly<{... Remove this comment to see the full error message
gene,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'geneDescription' does not exist on type ... Remove this comment to see the full error message
geneDescription,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isColorAccessor' does not exist on type ... Remove this comment to see the full error message
isColorAccessor,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isScatterplotXXaccessor' does not exist ... Remove this comment to see the full error message
isScatterplotXXaccessor,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'isScatterplotYYaccessor' does not exist ... Remove this comment to see the full error message
isScatterplotYYaccessor,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'quickGene' does not exist on type 'Reado... Remove this comment to see the full error message
quickGene,
// @ts-expect-error ts-migrate(2339) FIXME: Property 'removeGene' does not exist on type 'Read... Remove this comment to see the full error message
removeGene,
} = this.props;
const { geneIsExpanded } = this.state;
@@ -84,6 +101,7 @@ class Gene extends React.Component {
>
<div
role="menuitem"
// @ts-expect-error ts-migrate(2322) FIXME: Type 'string' is not assignable to type 'number | ... Remove this comment to see the full error message
tabIndex="0"
data-testclass="gene-expand"
data-testid={`${gene}:gene-expand`}
@@ -124,6 +142,7 @@ class Gene extends React.Component {
</div>
{!geneIsExpanded ? (
<HistogramBrush
// @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call.
isUserDefined
field={gene}
mini
@@ -188,6 +207,7 @@ class Gene extends React.Component {
/>
</div>
</div>
{/* @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call. */}
{geneIsExpanded && <HistogramBrush isUserDefined field={gene} />}
</div>
);

Some files were not shown because too many files have changed in this diff Show More