diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
index 131b01c808..2073ef0a61 100644
--- a/.github/workflows/pr.yml
+++ b/.github/workflows/pr.yml
@@ -7,6 +7,7 @@ on:
- develop
- feat/*
- main
+ - py-panels-develop
- release/v[0-9]+.[0-9]+.[0-9]+
jobs:
diff --git a/app/packages/app/package.json b/app/packages/app/package.json
index 6f1676f060..125188f23a 100644
--- a/app/packages/app/package.json
+++ b/app/packages/app/package.json
@@ -13,6 +13,7 @@
"copy-to-desktop": "rm -rf ../desktop/dist/ && cp -r ./dist ../desktop/dist"
},
"dependencies": {
+ "@fiftyone/analytics": "*",
"@fiftyone/components": "*",
"@fiftyone/core": "*",
"@fiftyone/relay": "*",
diff --git a/app/packages/app/src/components/Analytics.tsx b/app/packages/app/src/components/Analytics.tsx
new file mode 100644
index 0000000000..8e65b143b2
--- /dev/null
+++ b/app/packages/app/src/components/Analytics.tsx
@@ -0,0 +1,46 @@
+import { isElectron } from "@fiftyone/utilities";
+import React, { useCallback } from "react";
+import ReactGA from "react-ga4";
+import { graphql, useFragment } from "react-relay";
+import gaConfig from "../ga";
+import AnalyticsConsent from "./AnalyticsConsent";
+import type { NavGA$data, NavGA$key } from "./__generated__/NavGA.graphql";
+
+const useCallGA = (info: NavGA$data) => {
+ return useCallback(() => {
+ const dev = info.dev;
+ const buildType = dev ? "dev" : "prod";
+ ReactGA.initialize(gaConfig.app_ids[buildType], {
+ testMode: false,
+ gaOptions: {
+ storage: "none",
+ cookieDomain: "none",
+ clientId: info.uid,
+ page_location: "omitted",
+ page_path: "omitted",
+ kind: isElectron() ? "Desktop" : "Web",
+ version: info.version,
+ context: info.context,
+ checkProtocolTask: null, // disable check, allow file:// URLs
+ },
+ });
+ }, [info]);
+};
+
+export default function Analytics({ fragment }: { fragment: NavGA$key }) {
+ const info = useFragment(
+ graphql`
+ fragment Analytics on Query {
+ context
+ dev
+ doNotTrack
+ uid
+ version
+ }
+ `,
+ fragment
+ );
+ const callGA = useCallGA(info);
+
+ return ;
+}
diff --git a/app/packages/app/src/components/AnalyticsConsent.tsx b/app/packages/app/src/components/AnalyticsConsent.tsx
new file mode 100644
index 0000000000..9d5b04d6d3
--- /dev/null
+++ b/app/packages/app/src/components/AnalyticsConsent.tsx
@@ -0,0 +1,117 @@
+import { DEFAULT_WRITE_KEYS, useAnalyticsInfo } from "@fiftyone/analytics";
+import { Button } from "@fiftyone/components";
+import { Box, Grid, Link, Typography } from "@mui/material";
+import React, { useCallback, useEffect, useState } from "react";
+import type { NavGA$data } from "./__generated__/NavGA.graphql";
+
+const FIFTYONE_DO_NOT_TRACK_LS = "fiftyone-do-not-track";
+
+function useAnalyticsConsent(disabled?: boolean) {
+ const [ready, setReady] = useState(false);
+ const [show, setShow] = useState(false);
+ const doNotTrack = window.localStorage.getItem(FIFTYONE_DO_NOT_TRACK_LS);
+ useEffect(() => {
+ if (disabled || doNotTrack === "true" || doNotTrack === "false") {
+ setShow(false);
+ setReady(true);
+ } else {
+ setShow(true);
+ }
+ }, [disabled, doNotTrack]);
+
+ const handleDisable = useCallback(() => {
+ window.localStorage.setItem(FIFTYONE_DO_NOT_TRACK_LS, "true");
+ setShow(false);
+ setReady(true);
+ }, []);
+
+ const handleEnable = useCallback(() => {
+ window.localStorage.setItem(FIFTYONE_DO_NOT_TRACK_LS, "false");
+ setReady(true);
+ setShow(false);
+ }, []);
+
+ return {
+ doNotTrack: doNotTrack === "true" || disabled,
+ handleDisable,
+ handleEnable,
+ ready,
+ show,
+ };
+}
+
+export default function AnalyticsConsent({
+ callGA,
+ info,
+}: {
+ callGA: () => void;
+ info: NavGA$data;
+}) {
+ const [_, setAnalyticsInfo] = useAnalyticsInfo();
+
+ const { doNotTrack, handleDisable, handleEnable, ready, show } =
+ useAnalyticsConsent(info.doNotTrack);
+
+ useEffect(() => {
+ if (!ready) {
+ return;
+ }
+ const buildType = info.dev ? "dev" : "prod";
+ const writeKey = DEFAULT_WRITE_KEYS[buildType];
+ setAnalyticsInfo({
+ userId: info.uid,
+ userGroup: "fiftyone-oss",
+ writeKey,
+ doNotTrack: doNotTrack,
+ debug: info.dev,
+ });
+ !doNotTrack && callGA();
+ }, [callGA, doNotTrack, info, ready, setAnalyticsInfo]);
+
+ if (!show) {
+ return null;
+ }
+
+ return (
+
+ `1px solid ${theme.palette.divider}`}
+ backgroundColor="background.paper"
+ >
+
+
+ Help us improve FiftyOne
+
+
+ We use cookies to understand how FiftyOne is used and to improve the
+ product. You can help us by enabling analytics.
+
+
+
+
+ Disable
+
+
+
+
+
+
+
+
+
+ );
+}
+
+// a component that pins the content to the bottom of the screen, floating
+function PinBottom({ children }: React.PropsWithChildren) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/app/packages/app/src/components/Nav.tsx b/app/packages/app/src/components/Nav.tsx
index d78002bc01..f187ce3399 100644
--- a/app/packages/app/src/components/Nav.tsx
+++ b/app/packages/app/src/components/Nav.tsx
@@ -9,26 +9,18 @@ import {
import { ViewBar } from "@fiftyone/core";
import * as fos from "@fiftyone/state";
import { useRefresh } from "@fiftyone/state";
-import { isElectron } from "@fiftyone/utilities";
import { DarkMode, LightMode } from "@mui/icons-material";
import { useColorScheme } from "@mui/material";
-import React, { Suspense, useEffect, useMemo } from "react";
-import ReactGA from "react-ga4";
+import React, { Suspense, useMemo } from "react";
import { useFragment, usePaginationFragment } from "react-relay";
import { useDebounce } from "react-use";
-import {
- useRecoilState,
- useRecoilValue,
- useResetRecoilState,
- useSetRecoilState,
-} from "recoil";
+import { useRecoilValue, useSetRecoilState } from "recoil";
import { graphql } from "relay-runtime";
-import gaConfig from "../ga";
+import Analytics from "./Analytics";
import DatasetSelector from "./DatasetSelector";
import Teams from "./Teams";
import { NavDatasets$key } from "./__generated__/NavDatasets.graphql";
import { NavFragment$key } from "./__generated__/NavFragment.graphql";
-import { DEFAULT_WRITE_KEYS, useAnalyticsInfo } from "@fiftyone/analytics";
const getUseSearch = (fragment: NavDatasets$key) => {
return (search: string) => {
@@ -69,107 +61,64 @@ const getUseSearch = (fragment: NavDatasets$key) => {
};
};
-export const useGA = (info) => {
- useEffect(() => {
- if (!info || info.doNotTrack) {
- return;
- }
- const dev = info.dev;
- const buildType = dev ? "dev" : "prod";
- ReactGA.initialize(gaConfig.app_ids[buildType], {
- testMode: false,
- gaOptions: {
- storage: "none",
- cookieDomain: "none",
- clientId: info.uid,
- page_location: "omitted",
- page_path: "omitted",
- kind: isElectron() ? "Desktop" : "Web",
- version: info.version,
- context: info.context,
- checkProtocolTask: null, // disable check, allow file:// URLs
- },
- });
- }, [info]);
-};
-
-const Nav: React.FC<{
- fragment: NavFragment$key;
- hasDataset: boolean;
-}> = ({ fragment, hasDataset }) => {
+const Nav: React.FC<
+ React.PropsWithChildren<{
+ fragment: NavFragment$key;
+ hasDataset: boolean;
+ }>
+> = ({ children, fragment, hasDataset }) => {
const data = useFragment(
graphql`
fragment NavFragment on Query {
+ ...Analytics
...NavDatasets
- ...NavGA
}
`,
fragment
);
- const info = useFragment(
- graphql`
- fragment NavGA on Query {
- context
- dev
- doNotTrack
- uid
- version
- }
- `,
- data
- );
- const [analyticsInfo, setAnalyticsInfo] = useAnalyticsInfo();
- useEffect(() => {
- const buildType = info.dev ? "dev" : "prod";
- const writeKey = DEFAULT_WRITE_KEYS[buildType];
- setAnalyticsInfo({
- userId: info.uid,
- userGroup: "fiftyone-oss",
- writeKey,
- doNotTrack: info.doNotTrack,
- debug: info.dev,
- });
- }, [info, setAnalyticsInfo]);
- useGA(info);
const useSearch = getUseSearch(data);
const refresh = useRefresh();
const { mode, setMode } = useColorScheme();
- const [_, setTheme] = useRecoilState(fos.theme);
+ const setTheme = useSetRecoilState(fos.theme);
return (
- }
- >
- {hasDataset && (
- }>
-
-
- )}
- {!hasDataset &&
}
-
-
- {
- const nextMode = mode === "dark" ? "light" : "dark";
- setMode(nextMode);
- setTheme(nextMode);
- }}
- sx={{
- color: (theme) => theme.palette.text.secondary,
- pr: 0,
- }}
- >
- {mode === "dark" ? : }
-
-
-
-
-
-
+ <>
+ }
+ >
+ {hasDataset && (
+ }>
+
+
+ )}
+ {!hasDataset && }
+
+
+ {
+ const nextMode = mode === "dark" ? "light" : "dark";
+ setMode(nextMode);
+ setTheme(nextMode);
+ }}
+ sx={{
+ color: (theme) => theme.palette.text.secondary,
+ pr: 0,
+ }}
+ >
+ {mode === "dark" ? : }
+
+
+
+
+
+
+ {children}
+
+ >
);
};
diff --git a/app/packages/app/src/components/__generated__/NavGA.graphql.ts b/app/packages/app/src/components/__generated__/Analytics.graphql.ts
similarity index 77%
rename from app/packages/app/src/components/__generated__/NavGA.graphql.ts
rename to app/packages/app/src/components/__generated__/Analytics.graphql.ts
index 43b77f3e47..c103f01e1d 100644
--- a/app/packages/app/src/components/__generated__/NavGA.graphql.ts
+++ b/app/packages/app/src/components/__generated__/Analytics.graphql.ts
@@ -1,5 +1,5 @@
/**
- * @generated SignedSource<<94f4e2440a2b7380f82dfe4c09c00930>>
+ * @generated SignedSource<<814914ffd53575969ca480cdc6f3d1f0>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -10,24 +10,24 @@
import { Fragment, ReaderFragment } from 'relay-runtime';
import { FragmentRefs } from "relay-runtime";
-export type NavGA$data = {
+export type Analytics$data = {
readonly context: string;
readonly dev: boolean;
readonly doNotTrack: boolean;
readonly uid: string;
readonly version: string;
- readonly " $fragmentType": "NavGA";
+ readonly " $fragmentType": "Analytics";
};
-export type NavGA$key = {
- readonly " $data"?: NavGA$data;
- readonly " $fragmentSpreads": FragmentRefs<"NavGA">;
+export type Analytics$key = {
+ readonly " $data"?: Analytics$data;
+ readonly " $fragmentSpreads": FragmentRefs<"Analytics">;
};
const node: ReaderFragment = {
"argumentDefinitions": [],
"kind": "Fragment",
"metadata": null,
- "name": "NavGA",
+ "name": "Analytics",
"selections": [
{
"alias": null,
@@ -69,6 +69,6 @@ const node: ReaderFragment = {
"abstractKey": null
};
-(node as any).hash = "a2d13e827ff06e46baffc9244d708b0a";
+(node as any).hash = "042d0c5e3b5c588fc852e8a26d260126";
export default node;
diff --git a/app/packages/app/src/components/__generated__/NavFragment.graphql.ts b/app/packages/app/src/components/__generated__/NavFragment.graphql.ts
index fa06cdfbf8..cf49310146 100644
--- a/app/packages/app/src/components/__generated__/NavFragment.graphql.ts
+++ b/app/packages/app/src/components/__generated__/NavFragment.graphql.ts
@@ -1,5 +1,5 @@
/**
- * @generated SignedSource<<85bc3d6372c6f08bcdf0a2533aae4d98>>
+ * @generated SignedSource<<46385c140146f2317005e105dd92f070>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -11,7 +11,7 @@
import { Fragment, ReaderFragment } from 'relay-runtime';
import { FragmentRefs } from "relay-runtime";
export type NavFragment$data = {
- readonly " $fragmentSpreads": FragmentRefs<"NavDatasets" | "NavGA">;
+ readonly " $fragmentSpreads": FragmentRefs<"Analytics" | "NavDatasets">;
readonly " $fragmentType": "NavFragment";
};
export type NavFragment$key = {
@@ -28,18 +28,18 @@ const node: ReaderFragment = {
{
"args": null,
"kind": "FragmentSpread",
- "name": "NavDatasets"
+ "name": "Analytics"
},
{
"args": null,
"kind": "FragmentSpread",
- "name": "NavGA"
+ "name": "NavDatasets"
}
],
"type": "Query",
"abstractKey": null
};
-(node as any).hash = "f8b963593ae22123acdf5393b9a8a274";
+(node as any).hash = "b4c1e5cfb810c869d7f48d036fc48cad";
export default node;
diff --git a/app/packages/app/src/pages/IndexPage.tsx b/app/packages/app/src/pages/IndexPage.tsx
index 1bf331dc13..79da2bbd64 100644
--- a/app/packages/app/src/pages/IndexPage.tsx
+++ b/app/packages/app/src/pages/IndexPage.tsx
@@ -27,15 +27,14 @@ const IndexPage: Route = ({ prepared }) => {
const totalDatasets = queryRef.allDatasets;
return (
- <>
-
+
);
};
diff --git a/app/packages/app/src/pages/__generated__/IndexPageQuery.graphql.ts b/app/packages/app/src/pages/__generated__/IndexPageQuery.graphql.ts
index 17a2b4bc89..031922de99 100644
--- a/app/packages/app/src/pages/__generated__/IndexPageQuery.graphql.ts
+++ b/app/packages/app/src/pages/__generated__/IndexPageQuery.graphql.ts
@@ -1,5 +1,5 @@
/**
- * @generated SignedSource<<71edb5ac87b47af3f7d703b59fffb591>>
+ * @generated SignedSource<>
* @lightSyntaxTransform
* @nogrep
*/
@@ -274,6 +274,41 @@ return {
"storageKey": null
},
(v8/*: any*/),
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "context",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "dev",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "doNotTrack",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "uid",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "version",
+ "storageKey": null
+ },
{
"alias": null,
"args": (v9/*: any*/),
@@ -378,51 +413,16 @@ return {
"kind": "LinkedHandle",
"name": "datasets"
},
- {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "context",
- "storageKey": null
- },
- {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "dev",
- "storageKey": null
- },
- {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "doNotTrack",
- "storageKey": null
- },
- {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "uid",
- "storageKey": null
- },
- {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "version",
- "storageKey": null
- },
(v5/*: any*/)
]
},
"params": {
- "cacheID": "4be27983cf9d8ad6ba5448771ba43f28",
+ "cacheID": "f80a38e7e574b934552dbfe36118ef28",
"id": null,
"metadata": {},
"name": "IndexPageQuery",
"operationKind": "query",
- "text": "query IndexPageQuery(\n $search: String = \"\"\n $count: Int\n $cursor: String\n) {\n config {\n colorBy\n colorPool\n colorscale\n multicolorKeypoints\n showSkeletons\n }\n allDatasets: estimatedDatasetCount\n ...NavFragment\n ...configFragment\n}\n\nfragment NavDatasets on Query {\n datasets(search: $search, first: $count, after: $cursor) {\n total\n edges {\n cursor\n node {\n name\n id\n __typename\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment NavFragment on Query {\n ...NavDatasets\n ...NavGA\n}\n\nfragment NavGA on Query {\n context\n dev\n doNotTrack\n uid\n version\n}\n\nfragment configFragment on Query {\n config {\n colorBy\n colorPool\n colorscale\n gridZoom\n lightningThreshold\n loopVideos\n multicolorKeypoints\n notebookHeight\n plugins\n showConfidence\n showIndex\n showLabel\n showSkeletons\n showTooltip\n sidebarMode\n theme\n timezone\n useFrameNumber\n mediaFallback\n }\n colorscale\n}\n"
+ "text": "query IndexPageQuery(\n $search: String = \"\"\n $count: Int\n $cursor: String\n) {\n config {\n colorBy\n colorPool\n colorscale\n multicolorKeypoints\n showSkeletons\n }\n allDatasets: estimatedDatasetCount\n ...NavFragment\n ...configFragment\n}\n\nfragment Analytics on Query {\n context\n dev\n doNotTrack\n uid\n version\n}\n\nfragment NavDatasets on Query {\n datasets(search: $search, first: $count, after: $cursor) {\n total\n edges {\n cursor\n node {\n name\n id\n __typename\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment NavFragment on Query {\n ...Analytics\n ...NavDatasets\n}\n\nfragment configFragment on Query {\n config {\n colorBy\n colorPool\n colorscale\n gridZoom\n lightningThreshold\n loopVideos\n multicolorKeypoints\n notebookHeight\n plugins\n showConfidence\n showIndex\n showLabel\n showSkeletons\n showTooltip\n sidebarMode\n theme\n timezone\n useFrameNumber\n mediaFallback\n }\n colorscale\n}\n"
}
};
})();
diff --git a/app/packages/app/src/pages/datasets/DatasetPage.tsx b/app/packages/app/src/pages/datasets/DatasetPage.tsx
index 9d13e019e5..bc93eeb1d7 100644
--- a/app/packages/app/src/pages/datasets/DatasetPage.tsx
+++ b/app/packages/app/src/pages/datasets/DatasetPage.tsx
@@ -110,8 +110,7 @@ const DatasetPage: Route = ({ prepared }) => {
}, [isModalActive]);
return (
- <>
-
+
);
};
diff --git a/app/packages/app/src/pages/datasets/__generated__/DatasetPageQuery.graphql.ts b/app/packages/app/src/pages/datasets/__generated__/DatasetPageQuery.graphql.ts
index f3091fe899..699dad4474 100644
--- a/app/packages/app/src/pages/datasets/__generated__/DatasetPageQuery.graphql.ts
+++ b/app/packages/app/src/pages/datasets/__generated__/DatasetPageQuery.graphql.ts
@@ -1,5 +1,5 @@
/**
- * @generated SignedSource<>
+ * @generated SignedSource<>
* @lightSyntaxTransform
* @nogrep
*/
@@ -1202,6 +1202,35 @@ return {
],
"storageKey": null
},
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "context",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "dev",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "doNotTrack",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "uid",
+ "storageKey": null
+ },
+ (v33/*: any*/),
{
"alias": null,
"args": (v48/*: any*/),
@@ -1294,35 +1323,6 @@ return {
"kind": "LinkedHandle",
"name": "datasets"
},
- {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "context",
- "storageKey": null
- },
- {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "dev",
- "storageKey": null
- },
- {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "doNotTrack",
- "storageKey": null
- },
- {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "uid",
- "storageKey": null
- },
- (v33/*: any*/),
{
"alias": null,
"args": [
@@ -1438,12 +1438,12 @@ return {
]
},
"params": {
- "cacheID": "e086aa7786045cb0f54d959d188f2fad",
+ "cacheID": "a83dfc9db450206cd2ab9ee3c97f2649",
"id": null,
"metadata": {},
"name": "DatasetPageQuery",
"operationKind": "query",
- "text": "query DatasetPageQuery(\n $search: String = \"\"\n $count: Int\n $cursor: String\n $savedViewSlug: String\n $name: String!\n $view: BSONArray!\n $extendedView: BSONArray\n) {\n config {\n colorBy\n colorPool\n colorscale\n multicolorKeypoints\n showSkeletons\n }\n colorscale\n dataset(name: $name, view: $extendedView, savedViewSlug: $savedViewSlug) {\n name\n defaultGroupSlice\n appConfig {\n colorScheme {\n id\n colorBy\n colorPool\n multicolorKeypoints\n opacity\n showSkeletons\n defaultMaskTargetsColors {\n intTarget\n color\n }\n defaultColorscale {\n name\n list {\n value\n color\n }\n rgb\n }\n colorscales {\n path\n name\n list {\n value\n color\n }\n rgb\n }\n fields {\n colorByAttribute\n fieldColor\n path\n valueColors {\n color\n value\n }\n maskTargetsColors {\n intTarget\n color\n }\n }\n labelTags {\n fieldColor\n valueColors {\n color\n value\n }\n }\n }\n }\n ...datasetFragment\n id\n }\n ...NavFragment\n ...savedViewsFragment\n ...configFragment\n ...stageDefinitionsFragment\n ...viewSchemaFragment\n}\n\nfragment NavDatasets on Query {\n datasets(search: $search, first: $count, after: $cursor) {\n total\n edges {\n cursor\n node {\n name\n id\n __typename\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment NavFragment on Query {\n ...NavDatasets\n ...NavGA\n}\n\nfragment NavGA on Query {\n context\n dev\n doNotTrack\n uid\n version\n}\n\nfragment colorSchemeFragment on ColorScheme {\n id\n colorBy\n colorPool\n multicolorKeypoints\n opacity\n showSkeletons\n labelTags {\n fieldColor\n valueColors {\n color\n value\n }\n }\n defaultMaskTargetsColors {\n intTarget\n color\n }\n defaultColorscale {\n name\n list {\n value\n color\n }\n rgb\n }\n colorscales {\n path\n name\n list {\n value\n color\n }\n rgb\n }\n fields {\n colorByAttribute\n fieldColor\n path\n valueColors {\n color\n value\n }\n maskTargetsColors {\n intTarget\n color\n }\n }\n}\n\nfragment configFragment on Query {\n config {\n colorBy\n colorPool\n colorscale\n gridZoom\n lightningThreshold\n loopVideos\n multicolorKeypoints\n notebookHeight\n plugins\n showConfidence\n showIndex\n showLabel\n showSkeletons\n showTooltip\n sidebarMode\n theme\n timezone\n useFrameNumber\n mediaFallback\n }\n colorscale\n}\n\nfragment datasetAppConfigFragment on DatasetAppConfig {\n gridMediaField\n mediaFields\n modalMediaField\n plugins\n sidebarMode\n colorScheme {\n ...colorSchemeFragment\n id\n }\n mediaFallback\n}\n\nfragment datasetFragment on Dataset {\n createdAt\n datasetId\n groupField\n id\n info\n lastLoadedAt\n mediaType\n name\n parentMediaType\n version\n appConfig {\n ...datasetAppConfigFragment\n }\n brainMethods {\n key\n version\n timestamp\n viewStages\n config {\n cls\n embeddingsField\n method\n patchesField\n supportsPrompts\n type\n maxK\n supportsLeastSimilarity\n }\n }\n defaultMaskTargets {\n target\n value\n }\n defaultSkeleton {\n labels\n edges\n }\n evaluations {\n key\n version\n timestamp\n viewStages\n config {\n cls\n predField\n gtField\n }\n }\n groupMediaTypes {\n name\n mediaType\n }\n maskTargets {\n name\n targets {\n target\n value\n }\n }\n skeletons {\n name\n labels\n edges\n }\n ...estimatedCountsFragment\n ...frameFieldsFragment\n ...groupSliceFragment\n ...indexesFragment\n ...mediaFieldsFragment\n ...mediaTypeFragment\n ...sampleFieldsFragment\n ...sidebarGroupsFragment\n ...viewFragment\n}\n\nfragment estimatedCountsFragment on Dataset {\n estimatedFrameCount\n estimatedSampleCount\n}\n\nfragment frameFieldsFragment on Dataset {\n frameFields {\n ftype\n subfield\n embeddedDocType\n path\n dbField\n description\n info\n }\n}\n\nfragment groupSliceFragment on Dataset {\n defaultGroupSlice\n}\n\nfragment indexesFragment on Dataset {\n frameIndexes {\n name\n unique\n key {\n field\n type\n }\n wildcardProjection {\n fields\n inclusion\n }\n }\n sampleIndexes {\n name\n unique\n key {\n field\n type\n }\n wildcardProjection {\n fields\n inclusion\n }\n }\n}\n\nfragment mediaFieldsFragment on Dataset {\n name\n appConfig {\n gridMediaField\n mediaFields\n modalMediaField\n mediaFallback\n }\n sampleFields {\n path\n }\n}\n\nfragment mediaTypeFragment on Dataset {\n mediaType\n}\n\nfragment sampleFieldsFragment on Dataset {\n sampleFields {\n ftype\n subfield\n embeddedDocType\n path\n dbField\n description\n info\n }\n}\n\nfragment savedViewsFragment on Query {\n savedViews(datasetName: $name) {\n id\n datasetId\n name\n slug\n description\n color\n viewStages\n createdAt\n lastModifiedAt\n lastLoadedAt\n }\n}\n\nfragment sidebarGroupsFragment on Dataset {\n name\n appConfig {\n sidebarGroups {\n expanded\n paths\n name\n }\n }\n ...frameFieldsFragment\n ...sampleFieldsFragment\n}\n\nfragment stageDefinitionsFragment on Query {\n stageDefinitions {\n name\n params {\n name\n type\n default\n placeholder\n }\n }\n}\n\nfragment viewFragment on Dataset {\n stages(slug: $savedViewSlug, view: $view)\n viewCls\n viewName\n}\n\nfragment viewSchemaFragment on Query {\n schemaForViewStages(datasetName: $name, viewStages: $view) {\n fieldSchema {\n path\n ftype\n subfield\n embeddedDocType\n info\n description\n }\n frameFieldSchema {\n path\n ftype\n subfield\n embeddedDocType\n info\n description\n }\n }\n}\n"
+ "text": "query DatasetPageQuery(\n $search: String = \"\"\n $count: Int\n $cursor: String\n $savedViewSlug: String\n $name: String!\n $view: BSONArray!\n $extendedView: BSONArray\n) {\n config {\n colorBy\n colorPool\n colorscale\n multicolorKeypoints\n showSkeletons\n }\n colorscale\n dataset(name: $name, view: $extendedView, savedViewSlug: $savedViewSlug) {\n name\n defaultGroupSlice\n appConfig {\n colorScheme {\n id\n colorBy\n colorPool\n multicolorKeypoints\n opacity\n showSkeletons\n defaultMaskTargetsColors {\n intTarget\n color\n }\n defaultColorscale {\n name\n list {\n value\n color\n }\n rgb\n }\n colorscales {\n path\n name\n list {\n value\n color\n }\n rgb\n }\n fields {\n colorByAttribute\n fieldColor\n path\n valueColors {\n color\n value\n }\n maskTargetsColors {\n intTarget\n color\n }\n }\n labelTags {\n fieldColor\n valueColors {\n color\n value\n }\n }\n }\n }\n ...datasetFragment\n id\n }\n ...NavFragment\n ...savedViewsFragment\n ...configFragment\n ...stageDefinitionsFragment\n ...viewSchemaFragment\n}\n\nfragment Analytics on Query {\n context\n dev\n doNotTrack\n uid\n version\n}\n\nfragment NavDatasets on Query {\n datasets(search: $search, first: $count, after: $cursor) {\n total\n edges {\n cursor\n node {\n name\n id\n __typename\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment NavFragment on Query {\n ...Analytics\n ...NavDatasets\n}\n\nfragment colorSchemeFragment on ColorScheme {\n id\n colorBy\n colorPool\n multicolorKeypoints\n opacity\n showSkeletons\n labelTags {\n fieldColor\n valueColors {\n color\n value\n }\n }\n defaultMaskTargetsColors {\n intTarget\n color\n }\n defaultColorscale {\n name\n list {\n value\n color\n }\n rgb\n }\n colorscales {\n path\n name\n list {\n value\n color\n }\n rgb\n }\n fields {\n colorByAttribute\n fieldColor\n path\n valueColors {\n color\n value\n }\n maskTargetsColors {\n intTarget\n color\n }\n }\n}\n\nfragment configFragment on Query {\n config {\n colorBy\n colorPool\n colorscale\n gridZoom\n lightningThreshold\n loopVideos\n multicolorKeypoints\n notebookHeight\n plugins\n showConfidence\n showIndex\n showLabel\n showSkeletons\n showTooltip\n sidebarMode\n theme\n timezone\n useFrameNumber\n mediaFallback\n }\n colorscale\n}\n\nfragment datasetAppConfigFragment on DatasetAppConfig {\n gridMediaField\n mediaFields\n modalMediaField\n plugins\n sidebarMode\n colorScheme {\n ...colorSchemeFragment\n id\n }\n mediaFallback\n}\n\nfragment datasetFragment on Dataset {\n createdAt\n datasetId\n groupField\n id\n info\n lastLoadedAt\n mediaType\n name\n parentMediaType\n version\n appConfig {\n ...datasetAppConfigFragment\n }\n brainMethods {\n key\n version\n timestamp\n viewStages\n config {\n cls\n embeddingsField\n method\n patchesField\n supportsPrompts\n type\n maxK\n supportsLeastSimilarity\n }\n }\n defaultMaskTargets {\n target\n value\n }\n defaultSkeleton {\n labels\n edges\n }\n evaluations {\n key\n version\n timestamp\n viewStages\n config {\n cls\n predField\n gtField\n }\n }\n groupMediaTypes {\n name\n mediaType\n }\n maskTargets {\n name\n targets {\n target\n value\n }\n }\n skeletons {\n name\n labels\n edges\n }\n ...estimatedCountsFragment\n ...frameFieldsFragment\n ...groupSliceFragment\n ...indexesFragment\n ...mediaFieldsFragment\n ...mediaTypeFragment\n ...sampleFieldsFragment\n ...sidebarGroupsFragment\n ...viewFragment\n}\n\nfragment estimatedCountsFragment on Dataset {\n estimatedFrameCount\n estimatedSampleCount\n}\n\nfragment frameFieldsFragment on Dataset {\n frameFields {\n ftype\n subfield\n embeddedDocType\n path\n dbField\n description\n info\n }\n}\n\nfragment groupSliceFragment on Dataset {\n defaultGroupSlice\n}\n\nfragment indexesFragment on Dataset {\n frameIndexes {\n name\n unique\n key {\n field\n type\n }\n wildcardProjection {\n fields\n inclusion\n }\n }\n sampleIndexes {\n name\n unique\n key {\n field\n type\n }\n wildcardProjection {\n fields\n inclusion\n }\n }\n}\n\nfragment mediaFieldsFragment on Dataset {\n name\n appConfig {\n gridMediaField\n mediaFields\n modalMediaField\n mediaFallback\n }\n sampleFields {\n path\n }\n}\n\nfragment mediaTypeFragment on Dataset {\n mediaType\n}\n\nfragment sampleFieldsFragment on Dataset {\n sampleFields {\n ftype\n subfield\n embeddedDocType\n path\n dbField\n description\n info\n }\n}\n\nfragment savedViewsFragment on Query {\n savedViews(datasetName: $name) {\n id\n datasetId\n name\n slug\n description\n color\n viewStages\n createdAt\n lastModifiedAt\n lastLoadedAt\n }\n}\n\nfragment sidebarGroupsFragment on Dataset {\n name\n appConfig {\n sidebarGroups {\n expanded\n paths\n name\n }\n }\n ...frameFieldsFragment\n ...sampleFieldsFragment\n}\n\nfragment stageDefinitionsFragment on Query {\n stageDefinitions {\n name\n params {\n name\n type\n default\n placeholder\n }\n }\n}\n\nfragment viewFragment on Dataset {\n stages(slug: $savedViewSlug, view: $view)\n viewCls\n viewName\n}\n\nfragment viewSchemaFragment on Query {\n schemaForViewStages(datasetName: $name, viewStages: $view) {\n fieldSchema {\n path\n ftype\n subfield\n embeddedDocType\n info\n description\n }\n frameFieldSchema {\n path\n ftype\n subfield\n embeddedDocType\n info\n description\n }\n }\n}\n"
}
};
})();
diff --git a/app/packages/app/tsconfig.json b/app/packages/app/tsconfig.json
index 300100c53d..9d61b02df0 100644
--- a/app/packages/app/tsconfig.json
+++ b/app/packages/app/tsconfig.json
@@ -11,6 +11,7 @@
},
"include": ["index.ts"],
"references": [
+ { "path": "../analytics" },
{ "path": "../components" },
{ "path": "../flashlight" },
{ "path": "../looker" },
diff --git a/app/packages/components/src/components/index.ts b/app/packages/components/src/components/index.ts
index 29bb5d50f7..25183e1615 100644
--- a/app/packages/components/src/components/index.ts
+++ b/app/packages/components/src/components/index.ts
@@ -1,3 +1,4 @@
+export { default as Arrow } from "./Arrow";
export { default as Bar } from "./Bar";
export { default as Button } from "./Button";
export { default as CenteredStack } from "./CenteredStack";
@@ -17,6 +18,8 @@ export { default as JSONPanel } from "./JSONPanel";
export { default as JSONViewer } from "./JSONViewer";
export { default as Link } from "./Link";
export { default as Loading, LoadingDots } from "./Loading";
+export { default as MuiButton } from "./MuiButton";
+export { default as MuiIconFont } from "./MuiIconFont";
export { default as Pending } from "./Pending";
export { default as PillButton } from "./PillButton";
export { default as Popout, PopoutDiv } from "./Popout";
@@ -30,6 +33,3 @@ export { default as TabOption } from "./TabOption";
export { default as TextField } from "./TextField";
export { default as ThemeProvider, useFont, useTheme } from "./ThemeProvider";
export { default as Tooltip } from "./Tooltip";
-export { default as MuiIconFont } from "./MuiIconFont";
-export { default as MuiButton } from "./MuiButton";
-export { default as Arrow } from "./Arrow";
diff --git a/app/packages/flashlight/tsconfig.json b/app/packages/flashlight/tsconfig.json
index 2a2a67914c..6c7744112d 100644
--- a/app/packages/flashlight/tsconfig.json
+++ b/app/packages/flashlight/tsconfig.json
@@ -1,5 +1,6 @@
{
"compilerOptions": {
+ "composite": true,
"target": "ESNext",
"module": "ESNext",
"lib": ["ESNext", "DOM", "DOM.Iterable"],
@@ -7,7 +8,6 @@
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
- "noEmit": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
diff --git a/app/packages/looker/tsconfig.json b/app/packages/looker/tsconfig.json
index 2a2a67914c..6c7744112d 100644
--- a/app/packages/looker/tsconfig.json
+++ b/app/packages/looker/tsconfig.json
@@ -1,5 +1,6 @@
{
"compilerOptions": {
+ "composite": true,
"target": "ESNext",
"module": "ESNext",
"lib": ["ESNext", "DOM", "DOM.Iterable"],
@@ -7,7 +8,6 @@
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
- "noEmit": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
diff --git a/app/tsconfig.json b/app/tsconfig.json
index 30e9351586..afc1c9021a 100644
--- a/app/tsconfig.json
+++ b/app/tsconfig.json
@@ -1,13 +1,14 @@
{
- "files": [],
- "references": [
- { "path": "packages/app" },
- { "path": "packages/components" },
- { "path": "packages/flashlight" },
- { "path": "packages/looker" },
- { "path": "packages/utilities" },
- { "path": "packages/plugins" },
- { "path": "packages/state" },
- { "path": "packages/aggregations" }
- ]
+ "files": [],
+ "references": [
+ { "path": "packages/analytics" },
+ { "path": "packages/app" },
+ { "path": "packages/components" },
+ { "path": "packages/flashlight" },
+ { "path": "packages/looker" },
+ { "path": "packages/utilities" },
+ { "path": "packages/plugins" },
+ { "path": "packages/state" },
+ { "path": "packages/aggregations" }
+ ]
}
diff --git a/app/yarn.lock b/app/yarn.lock
index 119f88ceac..065cc53108 100644
--- a/app/yarn.lock
+++ b/app/yarn.lock
@@ -2288,7 +2288,7 @@ __metadata:
languageName: unknown
linkType: soft
-"@fiftyone/analytics@workspace:packages/analytics":
+"@fiftyone/analytics@*, @fiftyone/analytics@workspace:packages/analytics":
version: 0.0.0-use.local
resolution: "@fiftyone/analytics@workspace:packages/analytics"
dependencies:
@@ -2300,6 +2300,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@fiftyone/app@workspace:packages/app"
dependencies:
+ "@fiftyone/analytics": "*"
"@fiftyone/components": "*"
"@fiftyone/core": "*"
"@fiftyone/relay": "*"
diff --git a/requirements/common.txt b/requirements/common.txt
index 019972cf46..3b9ece9221 100644
--- a/requirements/common.txt
+++ b/requirements/common.txt
@@ -26,7 +26,7 @@ regex==2022.8.17
retrying>=1.3.3
scikit-learn>=0.23.2
scikit-image>=0.16.2
-setuptools>=45.2.0
+setuptools>=45.2.0,<71
sseclient-py>=1.7.2
sse-starlette>=0.10.3
starlette==0.36.2