@@ -137,11 +137,11 @@ export default function Crashes({ params }: { params: { teamId: string } }) {
{crashes.map(({ id, title, count, percentage }) => (
-
-
{title}
-
{count} instances
-
{percentage}%
-
+
+
{title}
+
{count} instances
+
{percentage}%
+
))}
diff --git a/measure-web-app/app/[teamId]/layout.tsx b/measure-web-app/app/[teamId]/layout.tsx
index 2752a6bdd..d411d7e66 100644
--- a/measure-web-app/app/[teamId]/layout.tsx
+++ b/measure-web-app/app/[teamId]/layout.tsx
@@ -8,137 +8,137 @@ import TeamSwitcher from "../components/team_switcher";
import { getAccessTokenOrRedirectToAuth, logoutIfAuthError, logout } from "../utils/auth_utils";
export default function DashboardLayout({
- children,
+ children,
}: {
- children: React.ReactNode
+ children: React.ReactNode
}) {
- enum TeamsApiStatus {
- Loading,
- Success,
- Error
- }
-
- const emptyTeams = [{'id':'', 'name':''}]
+ enum TeamsApiStatus {
+ Loading,
+ Success,
+ Error
+ }
- var menuItems = [
- {
- hrefSuffix: `overview`,
- title: 'Overview',
- },
- {
- hrefSuffix: 'crashes',
- title: 'Crashes',
- },
- {
- hrefSuffix: 'anrs',
- title: 'ANRs',
- },
- {
- hrefSuffix: 'team',
- title: 'Team',
- },
- {
- hrefSuffix: 'apps',
- title: 'Apps',
- },
- ];
+ const emptyTeams = [{ 'id': '', 'name': '' }]
- const [teamsApiStatus, setTeamsApiStatus] = useState(TeamsApiStatus.Loading);
- const [teams, setTeams] = useState(emptyTeams);
- const [selectedTeam, setSelectedTeam] = useState(teams[0].id)
+ var menuItems = [
+ {
+ hrefSuffix: `overview`,
+ title: 'Overview',
+ },
+ {
+ hrefSuffix: 'crashes',
+ title: 'Crashes',
+ },
+ {
+ hrefSuffix: 'anrs',
+ title: 'ANRs',
+ },
+ {
+ hrefSuffix: 'team',
+ title: 'Team',
+ },
+ {
+ hrefSuffix: 'apps',
+ title: 'Apps',
+ },
+ ];
- const pathName = usePathname();
- const router = useRouter();
+ const [teamsApiStatus, setTeamsApiStatus] = useState(TeamsApiStatus.Loading);
+ const [teams, setTeams] = useState(emptyTeams);
+ const [selectedTeam, setSelectedTeam] = useState(teams[0].id)
- const getTeams = async () => {
- setTeamsApiStatus(TeamsApiStatus.Loading)
+ const pathName = usePathname();
+ const router = useRouter();
- const authToken = await getAccessTokenOrRedirectToAuth(router)
- const origin = process.env.NEXT_PUBLIC_API_BASE_URL
- const opts = {
- headers: {
- "Authorization": `Bearer ${authToken}`
- }
- };
+ const getTeams = async () => {
+ setTeamsApiStatus(TeamsApiStatus.Loading)
- const res = await fetch(`${origin}/teams`, opts);
- if(!res.ok) {
- setTeamsApiStatus(TeamsApiStatus.Error)
- logoutIfAuthError(router, res)
- return
+ const authToken = await getAccessTokenOrRedirectToAuth(router)
+ const origin = process.env.NEXT_PUBLIC_API_BASE_URL
+ const opts = {
+ headers: {
+ "Authorization": `Bearer ${authToken}`
}
+ };
- setTeamsApiStatus(TeamsApiStatus.Success)
- const data = await res.json()
- setTeams(data)
- setSelectedTeam(data.find((e:{id:string, name:string}) => pathName.includes(e.id)).id)
+ const res = await fetch(`${origin}/teams`, opts);
+ if (!res.ok) {
+ setTeamsApiStatus(TeamsApiStatus.Error)
+ logoutIfAuthError(router, res)
+ return
}
- const logoutUser = async () => {
- await logout(router)
- }
+ setTeamsApiStatus(TeamsApiStatus.Success)
+ const data = await res.json()
+ setTeams(data)
+ setSelectedTeam(data.find((e: { id: string, name: string }) => pathName.includes(e.id)).id)
+ }
- useEffect(() => {
- getTeams()
- }, []);
+ const logoutUser = async () => {
+ await logout(router)
+ }
- const onTeamChanged = (item:string) => {
- const selectedTeamId = teams.find((e) => e.name === item)!.id
- const newPath = pathName.replace(/^\/[^\/]*/, '/' + selectedTeamId);
- router.push(newPath)
- }
+ useEffect(() => {
+ getTeams()
+ }, []);
+
+ const onTeamChanged = (item: string) => {
+ const selectedTeamId = teams.find((e) => e.name === item)!.id
+ const newPath = pathName.replace(/^\/[^\/]*/, '/' + selectedTeamId);
+ router.push(newPath)
+ }
- return (
-
- {/* Side nav and main content layout on normal+ size screens */}
-
-
- {teamsApiStatus === TeamsApiStatus.Success &&
{children} }
-
+ return (
+
+ {/* Side nav and main content layout on normal+ size screens */}
+
+
+ {teamsApiStatus === TeamsApiStatus.Success &&
{children} }
+
- {/* Side nav and main content layout on small screens */}
-
-
- {teamsApiStatus === TeamsApiStatus.Success &&
{children} }
-
+ {/* Side nav and main content layout on small screens */}
+
+
+ {teamsApiStatus === TeamsApiStatus.Success &&
{children} }
- );
+
+ );
}
\ No newline at end of file
diff --git a/measure-web-app/app/[teamId]/overview/page.tsx b/measure-web-app/app/[teamId]/overview/page.tsx
index 15f3cc314..2fe86f8ac 100644
--- a/measure-web-app/app/[teamId]/overview/page.tsx
+++ b/measure-web-app/app/[teamId]/overview/page.tsx
@@ -25,7 +25,7 @@ export default function Overview({ params }: { params: { teamId: string } }) {
Error,
NoData
}
-
+
const [appsApiStatus, setAppsApiStatus] = useState(AppsApiStatus.Loading);
const [filtersApiStatus, setFiltersApiStatus] = useState(FiltersApiStatus.Loading);
@@ -34,10 +34,10 @@ export default function Overview({ params }: { params: { teamId: string } }) {
"team_id": "",
"name": "",
"api_key": {
- "created_at": "",
- "key": "",
- "last_seen": null,
- "revoked": false
+ "created_at": "",
+ "key": "",
+ "last_seen": null,
+ "revoked": false
},
"onboarded": false,
"created_at": "",
@@ -45,14 +45,14 @@ export default function Overview({ params }: { params: { teamId: string } }) {
"platform": null,
"onboarded_at": null,
"unique_identifier": null
-}
+ }
const [apps, setApps] = useState([] as typeof emptyApp[]);
const [selectedApp, setSelectedApp] = useState(emptyApp);
const [versions, setVersions] = useState([] as string[]);
const [selectedVersion, setSelectedVersion] = useState(versions[0]);
-
+
const today = new Date();
var initialEndDate = `${today.getFullYear()}-${(today.getMonth() + 1).toString().padStart(2, '0')}-${today.getDate().toString().padStart(2, '0')}`;
const [endDate, setEndDate] = useState(initialEndDate);
@@ -68,7 +68,7 @@ export default function Overview({ params }: { params: { teamId: string } }) {
setFormattedEndDate(new Date(endDate).toLocaleDateString());
}, [startDate, endDate]);
- const getApps = async (teamId:string, ) => {
+ const getApps = async (teamId: string,) => {
setAppsApiStatus(AppsApiStatus.Loading)
const authToken = await getAccessTokenOrRedirectToAuth(router)
@@ -80,17 +80,17 @@ export default function Overview({ params }: { params: { teamId: string } }) {
};
const res = await fetch(`${origin}/teams/${teamId}/apps`, opts);
-
- if(!res.ok && res.status == 404) {
+
+ if (!res.ok && res.status == 404) {
setAppsApiStatus(AppsApiStatus.NoApps)
return
- }
+ }
- if(!res.ok) {
+ if (!res.ok) {
setAppsApiStatus(AppsApiStatus.Error)
logoutIfAuthError(router, res)
return
- }
+ }
const data = await res.json()
@@ -103,7 +103,7 @@ export default function Overview({ params }: { params: { teamId: string } }) {
getApps(params.teamId)
}, []);
- const getFilters = async (appId:string, ) => {
+ const getFilters = async (appId: string,) => {
setFiltersApiStatus(FiltersApiStatus.Loading)
const authToken = await getAccessTokenOrRedirectToAuth(router)
@@ -116,16 +116,16 @@ export default function Overview({ params }: { params: { teamId: string } }) {
const res = await fetch(`${origin}/apps/${appId}/filters`, opts);
- if(!res.ok && res.status == 404) {
+ if (!res.ok && res.status == 404) {
setFiltersApiStatus(FiltersApiStatus.NoData)
return
- }
+ }
- if(!res.ok) {
+ if (!res.ok) {
logoutIfAuthError(router, res)
setFiltersApiStatus(FiltersApiStatus.Error)
return
- }
+ }
const data = await res.json()
setVersions(data.version)
@@ -148,30 +148,30 @@ export default function Overview({ params }: { params: { teamId: string } }) {
{/* Error message for apps fetch error */}
{appsApiStatus === AppsApiStatus.Error &&
Error fetching apps, please refresh page to try again
}
-
+
{/* Create app when no apps exist */}
{appsApiStatus === AppsApiStatus.NoApps &&
Looks like you don't have any apps yet. Get started by creating your first app!
}
- {appsApiStatus === AppsApiStatus.NoApps &&
}
- {appsApiStatus === AppsApiStatus.NoApps &&
}
-
+ {appsApiStatus === AppsApiStatus.NoApps &&
}
+ {appsApiStatus === AppsApiStatus.NoApps && }
+
{/* Show app selector dropdown if apps fetch succeeds */}
{appsApiStatus === AppsApiStatus.Success && e.name)} onChangeSelectedItem={(item) => setSelectedApp(apps.find((e) => e.name === item)!)} />}
-
+
{/* Show date selector if apps and filters fetch succeeds */}
- {appsApiStatus === AppsApiStatus.Success && filtersApiStatus === FiltersApiStatus.Success &&
+ {appsApiStatus === AppsApiStatus.Success && filtersApiStatus === FiltersApiStatus.Success &&
}
- {/* Loading message for filters */}
+ {/* Loading message for filters */}
{appsApiStatus === AppsApiStatus.Success && filtersApiStatus === FiltersApiStatus.Loading && Updating filters...
}
{/* Show versions selector if apps and filters fetch succeeds */}
{appsApiStatus === AppsApiStatus.Success && filtersApiStatus === FiltersApiStatus.Success && setSelectedVersion(item)} />}
-
+
{appsApiStatus === AppsApiStatus.Success && filtersApiStatus === FiltersApiStatus.Success &&
}
{/* Show filter pills if apps and filters fetch succeeds */}
@@ -185,7 +185,7 @@ export default function Overview({ params }: { params: { teamId: string } }) {
{appsApiStatus === AppsApiStatus.Success && filtersApiStatus === FiltersApiStatus.Error &&
Error fetching filters, please refresh page or select a different app to try again
}
{/* Create app when app exists but has no data */}
- {appsApiStatus === AppsApiStatus.Success && filtersApiStatus === FiltersApiStatus.NoData &&
}
+ {appsApiStatus === AppsApiStatus.Success && filtersApiStatus === FiltersApiStatus.NoData && }
{/* Show user flow if apps and filters fetch succeeds */}
{appsApiStatus === AppsApiStatus.Success && filtersApiStatus === FiltersApiStatus.Success && }
diff --git a/measure-web-app/app/[teamId]/sessions/[sessionId]/page.tsx b/measure-web-app/app/[teamId]/sessions/[sessionId]/page.tsx
index 82638a45e..bcc332ff6 100644
--- a/measure-web-app/app/[teamId]/sessions/[sessionId]/page.tsx
+++ b/measure-web-app/app/[teamId]/sessions/[sessionId]/page.tsx
@@ -4,7 +4,7 @@ export default function Session({ params }: { params: { sessionId: string } }) {
return (
-
+
Session: {params.sessionId}
UserID: alskdflsj123434
Date: 24th Oct 2023
@@ -12,8 +12,8 @@ export default function Session({ params }: { params: { sessionId: string } }) {
Device: Samsung Galaxy S9 Pro
Location: Bangalore, India
Network provider: Airtel
-
-
+
+
)
}
diff --git a/measure-web-app/app/components/checkbox_dropdown.tsx b/measure-web-app/app/components/checkbox_dropdown.tsx
index e9d2c03a5..8dd72dfed 100644
--- a/measure-web-app/app/components/checkbox_dropdown.tsx
+++ b/measure-web-app/app/components/checkbox_dropdown.tsx
@@ -10,7 +10,7 @@ interface CheckboxDropdownProps {
const CheckboxDropdown: React.FC = ({ title, items, onChangeSelectedItems }) => {
const [isOpen, setIsOpen] = useState(false);
- const [selectedItems,setSelectedItems] = useState(new Array());
+ const [selectedItems, setSelectedItems] = useState(new Array());
const dropdownRef = useRef(null);
useEffect(() => {
@@ -46,17 +46,17 @@ const CheckboxDropdown: React.FC = ({ title, items, onCha
};
const toggleItem = (item: string) => {
- if(selectedItems.includes(item)) {
+ if (selectedItems.includes(item)) {
setSelectedItems(selectedItems.filter(a => a != item))
} else {
- setSelectedItems([item,...selectedItems])
+ setSelectedItems([item, ...selectedItems])
}
-
+
};
useEffect(() => {
onChangeSelectedItems?.(selectedItems);
-}, [selectedItems]);
+ }, [selectedItems]);
return (
@@ -84,7 +84,7 @@ const CheckboxDropdown: React.FC = ({ title, items, onCha
type="checkbox"
className="appearance-none border-white rounded-sm text-black font-display bg-neutral-950 focus:ring-offset-yellow-200 focus:ring-0 checked:ring-1 checked:ring-white"
value={item}
- onChange={() => {toggleItem(item)}}
+ onChange={() => { toggleItem(item) }}
/>
{item}
diff --git a/measure-web-app/app/components/create_app.tsx b/measure-web-app/app/components/create_app.tsx
index abbfbe9f3..0d3727cda 100644
--- a/measure-web-app/app/components/create_app.tsx
+++ b/measure-web-app/app/components/create_app.tsx
@@ -6,7 +6,7 @@ import { useRouter } from 'next/navigation';
import Accordion from './accordion';
interface CreateAppProps {
- teamId:string,
+ teamId: string,
existingAppName?: string,
existingApiKey?: string
}
@@ -90,10 +90,10 @@ const CreateApp: React.FC = ({ teamId, existingAppName = null, e
"team_id": "",
"name": "",
"api_key": {
- "created_at": "",
- "key": "",
- "last_seen": null,
- "revoked": false
+ "created_at": "",
+ "key": "",
+ "last_seen": null,
+ "revoked": false
},
"onboarded": false,
"created_at": "",
@@ -101,24 +101,24 @@ const CreateApp: React.FC = ({ teamId, existingAppName = null, e
"platform": null,
"onboarded_at": null,
"unique_identifier": null
-}
+ }
const [data, setData] = useState(emptyData);
- const [createAppStatus, setCreateAppStatus] = useState(existingAppName === null && existingApiKey === null? CreateAppStatus.PreCreation: CreateAppStatus.PostCreation)
+ const [createAppStatus, setCreateAppStatus] = useState(existingAppName === null && existingApiKey === null ? CreateAppStatus.PreCreation : CreateAppStatus.PostCreation)
const [createAppApiStatus, setCreateAppApiStatus] = useState(CreateAppApiStatus.Init);
const [appName, setAppName] = useState("");
-
+
const router = useRouter()
const createApp: FormEventHandler = async (event) => {
event.preventDefault();
- if(appName === "") {
+ if (appName === "") {
return
}
setCreateAppApiStatus(CreateAppApiStatus.Loading)
-
+
const authToken = await getAccessTokenOrRedirectToAuth(router)
const origin = process.env.NEXT_PUBLIC_API_BASE_URL
const opts = {
@@ -126,20 +126,20 @@ const CreateApp: React.FC = ({ teamId, existingAppName = null, e
headers: {
"Authorization": `Bearer ${authToken}`
},
- body: JSON.stringify({name: appName})
+ body: JSON.stringify({ name: appName })
};
- const res = await fetch(`${origin}/teams/${teamId}/apps`, opts);
-
- if(!res.ok) {
+ const res = await fetch(`${origin}/teams/${teamId}/apps`, opts);
+
+ if (!res.ok) {
setCreateAppApiStatus(CreateAppApiStatus.Error)
logoutIfAuthError(router, res)
- return
- }
-
+ return
+ }
+
setCreateAppApiStatus(CreateAppApiStatus.Success)
setCreateAppStatus(CreateAppStatus.PostCreation)
- setData(await res.json())
+ setData(await res.json())
}
return (
@@ -149,35 +149,35 @@ const CreateApp: React.FC = ({ teamId, existingAppName = null, e
{createAppApiStatus === CreateAppApiStatus.Loading &&
Creating app...
}
{createAppApiStatus === CreateAppApiStatus.Error &&
Error creating app. Please try again.
}
}
-
+
{/* UI after app creation */}
{createAppStatus === CreateAppStatus.PostCreation &&
-
Finish setting up {existingAppName !== null? existingAppName: data.name}
-
+
Finish setting up {existingAppName !== null ? existingAppName : data.name}
+
API key
-
- navigator.clipboard.writeText(existingApiKey !== null? existingApiKey: data.api_key.key)}>Copy
+
+ navigator.clipboard.writeText(existingApiKey !== null ? existingApiKey : data.api_key.key)}>Copy
-
+
Steps:
- {addAppSteps.map((text, index) => (
-
- {text.text}
-
- ))}
+ {addAppSteps.map((text, index) => (
+
+ {text.text}
+
+ ))}
}
diff --git a/measure-web-app/app/components/dropdown.tsx b/measure-web-app/app/components/dropdown.tsx
index 2c1e08178..ef2a162e0 100644
--- a/measure-web-app/app/components/dropdown.tsx
+++ b/measure-web-app/app/components/dropdown.tsx
@@ -49,7 +49,7 @@ const Dropdown: React.FC = ({ items, initialItemIndex = 0, onChan
const selectItem = (item: string) => {
setSelectedItem(item);
setIsOpen(false);
- if(onChangeSelectedItem) {
+ if (onChangeSelectedItem) {
onChangeSelectedItem(item);
}
};
diff --git a/measure-web-app/app/components/email_waitlist.tsx b/measure-web-app/app/components/email_waitlist.tsx
index f2771b81e..1509418f9 100644
--- a/measure-web-app/app/components/email_waitlist.tsx
+++ b/measure-web-app/app/components/email_waitlist.tsx
@@ -6,11 +6,11 @@ import type { FC, FormEventHandler } from 'react';
const waitlist = 'clmq44pdk0002l509qxe27qr8';
export enum ApiStatus {
- INIT = 'init',
- PENDING = 'pending',
- SUCCESS = 'success',
- ERROR = 'error',
- }
+ INIT = 'init',
+ PENDING = 'pending',
+ SUCCESS = 'success',
+ ERROR = 'error',
+}
const EmailWaitlist: FC = () => {
const [email, setEmail] = useState('');
@@ -47,25 +47,25 @@ const EmailWaitlist: FC = () => {
setButtonText('Subscribed!');
setErrorText('')
} catch (error) {
- if(error instanceof Error) {
- setErrorText(error.message);
- } else {
- setErrorText('Something went wrong :-(. Please try again.')
- }
- setApiStatus(ApiStatus.ERROR);
- setButtonText('Notify Me');
+ if (error instanceof Error) {
+ setErrorText(error.message);
+ } else {
+ setErrorText('Something went wrong :-(. Please try again.')
+ }
+ setApiStatus(ApiStatus.ERROR);
+ setButtonText('Notify Me');
}
};
return (
-
-
-
{errorText}
+
+
+
{errorText}
);
};
diff --git a/measure-web-app/app/components/exception_count_chart.tsx b/measure-web-app/app/components/exception_count_chart.tsx
index ddddeba20..42ffba03e 100644
--- a/measure-web-app/app/components/exception_count_chart.tsx
+++ b/measure-web-app/app/components/exception_count_chart.tsx
@@ -5,34 +5,34 @@ import { ResponsiveLine } from '@nivo/line'
var today = new Date();
const sevenDaysAgo = new Date(today.setDate(today.getDate() - 7));
-const date1 = `${sevenDaysAgo.getFullYear()}-${(sevenDaysAgo.getMonth()+1).toString().padStart(2, '0')}-${sevenDaysAgo.getDate().toString().padStart(2, '0')}`;
+const date1 = `${sevenDaysAgo.getFullYear()}-${(sevenDaysAgo.getMonth() + 1).toString().padStart(2, '0')}-${sevenDaysAgo.getDate().toString().padStart(2, '0')}`;
today = new Date();
const sixDaysAgo = new Date(today.setDate(today.getDate() - 6));
-const date2 = `${sixDaysAgo.getFullYear()}-${(sixDaysAgo.getMonth()+1).toString().padStart(2, '0')}-${sixDaysAgo.getDate().toString().padStart(2, '0')}`;
+const date2 = `${sixDaysAgo.getFullYear()}-${(sixDaysAgo.getMonth() + 1).toString().padStart(2, '0')}-${sixDaysAgo.getDate().toString().padStart(2, '0')}`;
today = new Date();
const fiveDaysAgo = new Date(today.setDate(today.getDate() - 5));
-const date3 = `${fiveDaysAgo.getFullYear()}-${(fiveDaysAgo.getMonth()+1).toString().padStart(2, '0')}-${fiveDaysAgo.getDate().toString().padStart(2, '0')}`;
+const date3 = `${fiveDaysAgo.getFullYear()}-${(fiveDaysAgo.getMonth() + 1).toString().padStart(2, '0')}-${fiveDaysAgo.getDate().toString().padStart(2, '0')}`;
today = new Date();
const fourDaysAgo = new Date(today.setDate(today.getDate() - 4));
-const date4 = `${fourDaysAgo.getFullYear()}-${(fourDaysAgo.getMonth()+1).toString().padStart(2, '0')}-${fourDaysAgo.getDate().toString().padStart(2, '0')}`;
+const date4 = `${fourDaysAgo.getFullYear()}-${(fourDaysAgo.getMonth() + 1).toString().padStart(2, '0')}-${fourDaysAgo.getDate().toString().padStart(2, '0')}`;
today = new Date();
const threeDaysAgo = new Date(today.setDate(today.getDate() - 3));
-const date5 = `${threeDaysAgo.getFullYear()}-${(threeDaysAgo.getMonth()+1).toString().padStart(2, '0')}-${threeDaysAgo.getDate().toString().padStart(2, '0')}`;
+const date5 = `${threeDaysAgo.getFullYear()}-${(threeDaysAgo.getMonth() + 1).toString().padStart(2, '0')}-${threeDaysAgo.getDate().toString().padStart(2, '0')}`;
today = new Date();
const twoDaysAgo = new Date(today.setDate(today.getDate() - 2));
-const date6 = `${twoDaysAgo.getFullYear()}-${(twoDaysAgo.getMonth()+1).toString().padStart(2, '0')}-${twoDaysAgo.getDate().toString().padStart(2, '0')}`;
+const date6 = `${twoDaysAgo.getFullYear()}-${(twoDaysAgo.getMonth() + 1).toString().padStart(2, '0')}-${twoDaysAgo.getDate().toString().padStart(2, '0')}`;
today = new Date();
const oneDayAgo = new Date(today.setDate(today.getDate() - 1));
-const date7 = `${oneDayAgo.getFullYear()}-${(oneDayAgo.getMonth()+1).toString().padStart(2, '0')}-${oneDayAgo.getDate().toString().padStart(2, '0')}`;
+const date7 = `${oneDayAgo.getFullYear()}-${(oneDayAgo.getMonth() + 1).toString().padStart(2, '0')}-${oneDayAgo.getDate().toString().padStart(2, '0')}`;
today = new Date();
-const date8 = `${today.getFullYear()}-${(today.getMonth()+1).toString().padStart(2, '0')}-${today.getDate().toString().padStart(2, '0')}`;
+const date8 = `${today.getFullYear()}-${(today.getMonth() + 1).toString().padStart(2, '0')}-${today.getDate().toString().padStart(2, '0')}`;
const data = [
{
@@ -152,63 +152,64 @@ const data = [
]
const ExceptionCountChart = () => {
- return (
-
- )};
+ )
+};
export default ExceptionCountChart;
\ No newline at end of file
diff --git a/measure-web-app/app/components/exception_rate_chart.tsx b/measure-web-app/app/components/exception_rate_chart.tsx
index efac1c142..0c49fb9cc 100644
--- a/measure-web-app/app/components/exception_rate_chart.tsx
+++ b/measure-web-app/app/components/exception_rate_chart.tsx
@@ -5,34 +5,34 @@ import { ResponsiveLine } from '@nivo/line'
var today = new Date();
const sevenDaysAgo = new Date(today.setDate(today.getDate() - 7));
-const date1 = `${sevenDaysAgo.getFullYear()}-${(sevenDaysAgo.getMonth()+1).toString().padStart(2, '0')}-${sevenDaysAgo.getDate().toString().padStart(2, '0')}`;
+const date1 = `${sevenDaysAgo.getFullYear()}-${(sevenDaysAgo.getMonth() + 1).toString().padStart(2, '0')}-${sevenDaysAgo.getDate().toString().padStart(2, '0')}`;
today = new Date();
const sixDaysAgo = new Date(today.setDate(today.getDate() - 6));
-const date2 = `${sixDaysAgo.getFullYear()}-${(sixDaysAgo.getMonth()+1).toString().padStart(2, '0')}-${sixDaysAgo.getDate().toString().padStart(2, '0')}`;
+const date2 = `${sixDaysAgo.getFullYear()}-${(sixDaysAgo.getMonth() + 1).toString().padStart(2, '0')}-${sixDaysAgo.getDate().toString().padStart(2, '0')}`;
today = new Date();
const fiveDaysAgo = new Date(today.setDate(today.getDate() - 5));
-const date3 = `${fiveDaysAgo.getFullYear()}-${(fiveDaysAgo.getMonth()+1).toString().padStart(2, '0')}-${fiveDaysAgo.getDate().toString().padStart(2, '0')}`;
+const date3 = `${fiveDaysAgo.getFullYear()}-${(fiveDaysAgo.getMonth() + 1).toString().padStart(2, '0')}-${fiveDaysAgo.getDate().toString().padStart(2, '0')}`;
today = new Date();
const fourDaysAgo = new Date(today.setDate(today.getDate() - 4));
-const date4 = `${fourDaysAgo.getFullYear()}-${(fourDaysAgo.getMonth()+1).toString().padStart(2, '0')}-${fourDaysAgo.getDate().toString().padStart(2, '0')}`;
+const date4 = `${fourDaysAgo.getFullYear()}-${(fourDaysAgo.getMonth() + 1).toString().padStart(2, '0')}-${fourDaysAgo.getDate().toString().padStart(2, '0')}`;
today = new Date();
const threeDaysAgo = new Date(today.setDate(today.getDate() - 3));
-const date5 = `${threeDaysAgo.getFullYear()}-${(threeDaysAgo.getMonth()+1).toString().padStart(2, '0')}-${threeDaysAgo.getDate().toString().padStart(2, '0')}`;
+const date5 = `${threeDaysAgo.getFullYear()}-${(threeDaysAgo.getMonth() + 1).toString().padStart(2, '0')}-${threeDaysAgo.getDate().toString().padStart(2, '0')}`;
today = new Date();
const twoDaysAgo = new Date(today.setDate(today.getDate() - 2));
-const date6 = `${twoDaysAgo.getFullYear()}-${(twoDaysAgo.getMonth()+1).toString().padStart(2, '0')}-${twoDaysAgo.getDate().toString().padStart(2, '0')}`;
+const date6 = `${twoDaysAgo.getFullYear()}-${(twoDaysAgo.getMonth() + 1).toString().padStart(2, '0')}-${twoDaysAgo.getDate().toString().padStart(2, '0')}`;
today = new Date();
const oneDayAgo = new Date(today.setDate(today.getDate() - 1));
-const date7 = `${oneDayAgo.getFullYear()}-${(oneDayAgo.getMonth()+1).toString().padStart(2, '0')}-${oneDayAgo.getDate().toString().padStart(2, '0')}`;
+const date7 = `${oneDayAgo.getFullYear()}-${(oneDayAgo.getMonth() + 1).toString().padStart(2, '0')}-${oneDayAgo.getDate().toString().padStart(2, '0')}`;
today = new Date();
-const date8 = `${today.getFullYear()}-${(today.getMonth()+1).toString().padStart(2, '0')}-${today.getDate().toString().padStart(2, '0')}`;
+const date8 = `${today.getFullYear()}-${(today.getMonth() + 1).toString().padStart(2, '0')}-${today.getDate().toString().padStart(2, '0')}`;
const data = [
{
@@ -152,63 +152,64 @@ const data = [
]
const ExceptionRateChart = () => {
- return (
-
- )};
+ )
+};
export default ExceptionRateChart;
\ No newline at end of file
diff --git a/measure-web-app/app/components/filter_pill.tsx b/measure-web-app/app/components/filter_pill.tsx
index f66b2b0a2..01d75c53e 100644
--- a/measure-web-app/app/components/filter_pill.tsx
+++ b/measure-web-app/app/components/filter_pill.tsx
@@ -9,7 +9,7 @@ const FilterPill: React.FC = ({ title }) => {
{title}
- );
+ );
};
export default FilterPill;
\ No newline at end of file
diff --git a/measure-web-app/app/components/info_circle_app_adoption.tsx b/measure-web-app/app/components/info_circle_app_adoption.tsx
index 4e67ae950..7d8744a88 100644
--- a/measure-web-app/app/components/info_circle_app_adoption.tsx
+++ b/measure-web-app/app/components/info_circle_app_adoption.tsx
@@ -12,21 +12,21 @@ interface InfoCircleAppAdoptionProps {
const formatter = Intl.NumberFormat('en', { notation: 'compact' });
const InfoCircleAppAdoption = ({ status, value, users, totalUsers, title }: InfoCircleAppAdoptionProps) => {
- return (
-
-
- {status === MetricsApiStatus.Loading &&
Updating...
}
- {status === MetricsApiStatus.Error &&
Error
}
- {status === MetricsApiStatus.Success &&
{value}%
}
-
- {status === MetricsApiStatus.Success &&
{formatter.format(users)}/{formatter.format(totalUsers)} users
}
-
- Adoption = (Users of selected app version / Users of all app versions) * 100
-
-
-
-
{title}
-
+ return (
+
+
+ {status === MetricsApiStatus.Loading &&
Updating...
}
+ {status === MetricsApiStatus.Error &&
Error
}
+ {status === MetricsApiStatus.Success &&
{value}%
}
+
+ {status === MetricsApiStatus.Success &&
{formatter.format(users)}/{formatter.format(totalUsers)} users
}
+
+ Adoption = (Users of selected app version / Users of all app versions) * 100
+
+
+
+
{title}
+
);
};
diff --git a/measure-web-app/app/components/info_circle_app_size.tsx b/measure-web-app/app/components/info_circle_app_size.tsx
index 441d6197d..ea115a34b 100644
--- a/measure-web-app/app/components/info_circle_app_size.tsx
+++ b/measure-web-app/app/components/info_circle_app_size.tsx
@@ -9,21 +9,21 @@ interface InfoCircleAppSizeProps {
}
const InfoCircleAppSize = ({ status, value, delta, title }: InfoCircleAppSizeProps) => {
- return (
-
-
- {status === MetricsApiStatus.Loading &&
Updating...
}
- {status === MetricsApiStatus.Error &&
Error
}
- {status === MetricsApiStatus.Success &&
{value}MB
}
-
- {status === MetricsApiStatus.Success &&
0? 'text-red-400': 'opacity-0'}`}>{delta>0? '+':''}{delta}MB
}
-
- Delta value = App size of selected app version - Average app size of all app versions
-
-
-
-
{title}
+ return (
+
+
+ {status === MetricsApiStatus.Loading &&
Updating...
}
+ {status === MetricsApiStatus.Error &&
Error
}
+ {status === MetricsApiStatus.Success &&
{value}MB
}
+
+ {status === MetricsApiStatus.Success &&
0 ? 'text-red-400' : 'opacity-0'}`}>{delta > 0 ? '+' : ''}{delta}MB
}
+
+ Delta value = App size of selected app version - Average app size of all app versions
+
+
+
{title}
+
);
};
diff --git a/measure-web-app/app/components/info_circle_app_start_time.tsx b/measure-web-app/app/components/info_circle_app_start_time.tsx
index e59826faa..d00f3a658 100644
--- a/measure-web-app/app/components/info_circle_app_start_time.tsx
+++ b/measure-web-app/app/components/info_circle_app_start_time.tsx
@@ -11,21 +11,21 @@ interface InfoCircleAppStartTimeProps {
}
const InfoCircleAppStartTime = ({ status, value, delta, title, launchType }: InfoCircleAppStartTimeProps) => {
- return (
-
-
- {status === MetricsApiStatus.Loading &&
Updating...
}
- {status === MetricsApiStatus.Error &&
Error
}
- {status === MetricsApiStatus.Success &&
{value}ms
}
-
- {status === MetricsApiStatus.Success &&
0? 'text-red-400': 'opacity-0'}`}>{delta>0? '+':''}{delta}ms
}
-
- App start time = p95 {launchType} launch time of selected app version in selected time period Delta value = p95 {launchType} launch time of selected app version in selected time period - p95 {launchType} launch time of all app versions in selected time period
-
-
-
-
{title}
+ return (
+
+
+ {status === MetricsApiStatus.Loading &&
Updating...
}
+ {status === MetricsApiStatus.Error &&
Error
}
+ {status === MetricsApiStatus.Success &&
{value}ms
}
+
+ {status === MetricsApiStatus.Success &&
0 ? 'text-red-400' : 'opacity-0'}`}>{delta > 0 ? '+' : ''}{delta}ms
}
+
+ App start time = p95 {launchType} launch time of selected app version in selected time period Delta value = p95 {launchType} launch time of selected app version in selected time period - p95 {launchType} launch time of all app versions in selected time period
+
+
+
{title}
+
);
};
diff --git a/measure-web-app/app/components/info_circle_exception_rate.tsx b/measure-web-app/app/components/info_circle_exception_rate.tsx
index 856ac0834..b12dc3f41 100644
--- a/measure-web-app/app/components/info_circle_exception_rate.tsx
+++ b/measure-web-app/app/components/info_circle_exception_rate.tsx
@@ -11,19 +11,19 @@ interface InfoCircleExceptionRateExceptionRateProps {
}
const InfoCircleExceptionRate = ({ status, value, delta, title, tooltipMsgLine1, tooltipMsgLine2 }: InfoCircleExceptionRateExceptionRateProps) => {
- return (
-
-
95? 'border-green-400 hover:bg-green-400/25': value > 85? 'border-yellow-400 hover:bg-yellow-400/25': 'border-red-400 hover:bg-red-400/25'}`}>
- {status === MetricsApiStatus.Loading &&
Updating...
}
- {status === MetricsApiStatus.Error &&
Error
}
- {status === MetricsApiStatus.Success &&
{value}%
}
-
- {status === MetricsApiStatus.Success &&
0? 'text-green-600': delta < 0? 'text-red-400': 'opacity-0'}`}>{delta>0? '+':''}{delta}%
}
-
{tooltipMsgLine1} {tooltipMsgLine2}
-
-
-
{title}
+ return (
+
+
95 ? 'border-green-400 hover:bg-green-400/25' : value > 85 ? 'border-yellow-400 hover:bg-yellow-400/25' : 'border-red-400 hover:bg-red-400/25'}`}>
+ {status === MetricsApiStatus.Loading &&
Updating...
}
+ {status === MetricsApiStatus.Error &&
Error
}
+ {status === MetricsApiStatus.Success &&
{value}%
}
+
+ {status === MetricsApiStatus.Success &&
0 ? 'text-green-600' : delta < 0 ? 'text-red-400' : 'opacity-0'}`}>{delta > 0 ? '+' : ''}{delta}%
}
+
{tooltipMsgLine1} {tooltipMsgLine2}
+
+
{title}
+
);
};
diff --git a/measure-web-app/app/components/landing_header.tsx b/measure-web-app/app/components/landing_header.tsx
index 27bbfe510..3f0f39f76 100644
--- a/measure-web-app/app/components/landing_header.tsx
+++ b/measure-web-app/app/components/landing_header.tsx
@@ -1,6 +1,6 @@
'use client'
-import { useRef, useState, useEffect} from 'react';
+import { useRef, useState, useEffect } from 'react';
import { useRouter } from 'next/navigation'
function useScrollDirection() {
@@ -38,19 +38,19 @@ function useScrollDirection() {
return scrollDir;
}
-export default function LandingHeader() {
+export default function LandingHeader() {
const scrollDir = useScrollDirection();
const [isFocused, setIsFocused] = useState(false);
const router = useRouter();
return (
-
setIsFocused(true)} onBlur={()=>setIsFocused(false)} className={`w-full flex flex-col z-50 bg-white fixed top-0 transition-transform duration-100 ease-in-out ${scrollDir === 'scrolling down' && isFocused === false ? '-translate-y-full' : 'translate-y-0'}`}>
+ setIsFocused(true)} onBlur={() => setIsFocused(false)} className={`w-full flex flex-col z-50 bg-white fixed top-0 transition-transform duration-100 ease-in-out ${scrollDir === 'scrolling down' && isFocused === false ? '-translate-y-full' : 'translate-y-0'}`}>
router.push('/')}>m
-
+
router.push('/#email-waitlist')}>Get early access!
-
+
)
}
diff --git a/measure-web-app/app/components/metrics_overview.tsx b/measure-web-app/app/components/metrics_overview.tsx
index c31e423c9..014a24341 100644
--- a/measure-web-app/app/components/metrics_overview.tsx
+++ b/measure-web-app/app/components/metrics_overview.tsx
@@ -9,10 +9,10 @@ import { getAccessTokenOrRedirectToAuth, logoutIfAuthError } from '@/app/utils/a
import { useRouter } from 'next/navigation';
interface MetricsOverviewProps {
- appId:string,
- startDate:string,
- endDate:string,
- appVersion:string,
+ appId: string,
+ startDate: string,
+ endDate: string,
+ appVersion: string,
}
export enum MetricsApiStatus {
@@ -73,12 +73,12 @@ const MetricsOverview: React.FC = ({ appId, startDate, end
const [data, setData] = useState(emptyData);
const [metricsApiStatus, setMetricsApiStatus] = useState(MetricsApiStatus.Loading);
-
+
const router = useRouter()
- const getData = async (appId:string, startDate:string, endDate:string, appVersion:string) => {
+ const getData = async (appId: string, startDate: string, endDate: string, appVersion: string) => {
setMetricsApiStatus(MetricsApiStatus.Loading)
-
+
const authToken = await getAccessTokenOrRedirectToAuth(router)
const origin = process.env.NEXT_PUBLIC_API_BASE_URL
const opts = {
@@ -89,18 +89,18 @@ const MetricsOverview: React.FC = ({ appId, startDate, end
const serverFormattedStartDate = new Date(startDate).toISOString()
const serverFormattedEndDate = new Date(endDate).toISOString()
- const res = await fetch(`${origin}/apps/${appId}/metrics?version=${appVersion}&from=${serverFormattedStartDate}&to=${serverFormattedEndDate}`, opts);
-
- if(!res.ok) {
+ const res = await fetch(`${origin}/apps/${appId}/metrics?version=${appVersion}&from=${serverFormattedStartDate}&to=${serverFormattedEndDate}`, opts);
+
+ if (!res.ok) {
setMetricsApiStatus(MetricsApiStatus.Error)
logoutIfAuthError(router, res)
- return
- }
-
+ return
+ }
+
setMetricsApiStatus(MetricsApiStatus.Success)
- setData(await res.json())
+ setData(await res.json())
}
-
+
useEffect(() => {
getData(appId, startDate, endDate, appVersion)
}, [appId, startDate, endDate, appVersion]);
diff --git a/measure-web-app/app/components/session_replay.tsx b/measure-web-app/app/components/session_replay.tsx
index d5321305b..0d0b84cd7 100644
--- a/measure-web-app/app/components/session_replay.tsx
+++ b/measure-web-app/app/components/session_replay.tsx
@@ -199,131 +199,131 @@ const threadData = [
]
const SessionReplay = () => {
- return (
-
- {/* Memory line */}
-
-
i.color)}
- defs={[
- {
- colors: [
- {
- color: memoryData.map((i) => i.color),
- offset: 0
- },
- {
- color: memoryData.map((i) => i.color),
- offset: 60,
- opacity: 0
- }
- ],
- id: 'memoryGradient',
- type: 'linearGradient'
- }
- ]}
- enableArea
- fill={[
- {
- id: 'memoryGradient',
- match: '*'
- }
- ]}
- tooltip={({
- point
- }) =>
-
{point.data.yFormatted} MB
-
}
-
- />
-
- {/* CPU line */}
-
-
i.color)}
- defs={[
- {
- colors: [
- {
- color: cpuData.map((i) => i.color),
- offset: 0
- },
- {
- color: cpuData.map((i) => i.color),
- offset: 60,
- opacity: 0
- }
- ],
- id: 'cpuGradient',
- type: 'linearGradient'
+ return (
+
+ {/* Memory line */}
+
+
i.color)}
+ defs={[
+ {
+ colors: [
+ {
+ color: memoryData.map((i) => i.color),
+ offset: 0
+ },
+ {
+ color: memoryData.map((i) => i.color),
+ offset: 60,
+ opacity: 0
+ }
+ ],
+ id: 'memoryGradient',
+ type: 'linearGradient'
+ }
+ ]}
+ enableArea
+ fill={[
+ {
+ id: 'memoryGradient',
+ match: '*'
+ }
+ ]}
+ tooltip={({
+ point
+ }) =>
+
{point.data.yFormatted} MB
+
}
+
+ />
+
+ {/* CPU line */}
+
+
i.color)}
+ defs={[
+ {
+ colors: [
+ {
+ color: cpuData.map((i) => i.color),
+ offset: 0
+ },
+ {
+ color: cpuData.map((i) => i.color),
+ offset: 60,
+ opacity: 0
+ }
+ ],
+ id: 'cpuGradient',
+ type: 'linearGradient'
}
]}
enableArea
@@ -336,56 +336,57 @@ const SessionReplay = () => {
tooltip={({
point
}) =>
-
{point.data.yFormatted}%
-
}
- />
-
- {/* Threads line */}
-
-
threadPoints[point.index].color}
- pointLabelYOffset={-12}
- useMesh={true}
- enableGridX={true}
- enableGridY={false}
- colors={threadData.map((i) => i.color)}
- tooltip={({
- point
- }) =>
-
{threadPoints[point.index].event}
-
}
- />
-
+
{point.data.yFormatted}%
+
}
+ />
+
+ {/* Threads line */}
+
+
threadPoints[point.index].color}
+ pointLabelYOffset={-12}
+ useMesh={true}
+ enableGridX={true}
+ enableGridY={false}
+ colors={threadData.map((i) => i.color)}
+ tooltip={({
+ point
+ }) =>
+
{threadPoints[point.index].event}
+
}
+ />
+
- )};
+ )
+};
export default SessionReplay;
\ No newline at end of file
diff --git a/measure-web-app/app/components/team_switcher.tsx b/measure-web-app/app/components/team_switcher.tsx
index e7e7ae043..8f190885d 100644
--- a/measure-web-app/app/components/team_switcher.tsx
+++ b/measure-web-app/app/components/team_switcher.tsx
@@ -49,7 +49,7 @@ const TeamSwitcher: React.FC = ({ items, initialItemIndex = 0
const selectItem = (item: string) => {
setSelectedItem(item);
setIsOpen(false);
- if(onChangeSelectedItem) {
+ if (onChangeSelectedItem) {
onChangeSelectedItem(item);
}
};
diff --git a/measure-web-app/app/components/user_flow.tsx b/measure-web-app/app/components/user_flow.tsx
index 7110e68f7..54944864b 100644
--- a/measure-web-app/app/components/user_flow.tsx
+++ b/measure-web-app/app/components/user_flow.tsx
@@ -6,10 +6,10 @@ import { getAccessTokenOrRedirectToAuth, logoutIfAuthError } from '@/app/utils/a
import { useRouter } from 'next/navigation';
interface UserFlowProps {
- appId:string,
- startDate:string,
- endDate:string,
- appVersion:string,
+ appId: string,
+ startDate: string,
+ endDate: string,
+ appVersion: string,
}
const UserFlow: React.FC = ({ appId, startDate, endDate, appVersion }) => {
@@ -26,7 +26,7 @@ const UserFlow: React.FC = ({ appId, startDate, endDate, appVersi
"nodeColor": "",
"issues": {
"crashes": [],
- "anrs":[]
+ "anrs": []
}
},
],
@@ -35,15 +35,15 @@ const UserFlow: React.FC = ({ appId, startDate, endDate, appVersi
}
const formatter = Intl.NumberFormat('en', { notation: 'compact' });
-
+
const [journeyApiStatus, setJourneyApiStatus] = useState(JourneyApiStatus.Loading);
const [data, setData] = useState(emptyData);
const router = useRouter()
- const getData = async (appId:string, startDate:string, endDate:string, appVersion:string) => {
+ const getData = async (appId: string, startDate: string, endDate: string, appVersion: string) => {
setJourneyApiStatus(JourneyApiStatus.Loading)
-
+
const authToken = await getAccessTokenOrRedirectToAuth(router)
const origin = process.env.NEXT_PUBLIC_API_BASE_URL
const opts = {
@@ -54,92 +54,92 @@ const UserFlow: React.FC = ({ appId, startDate, endDate, appVersi
const serverFormattedStartDate = new Date(startDate).toISOString()
const serverFormattedEndDate = new Date(endDate).toISOString()
- const res = await fetch(`${origin}/apps/${appId}/journey?version=${appVersion}&from=${serverFormattedStartDate}&to=${serverFormattedEndDate}`, opts);
-
- if(!res.ok) {
+ const res = await fetch(`${origin}/apps/${appId}/journey?version=${appVersion}&from=${serverFormattedStartDate}&to=${serverFormattedEndDate}`, opts);
+
+ if (!res.ok) {
setJourneyApiStatus(JourneyApiStatus.Error)
logoutIfAuthError(router, res)
return
}
-
+
setJourneyApiStatus(JourneyApiStatus.Success)
setData(await res.json())
}
-
+
useEffect(() => {
getData(appId, startDate, endDate, appVersion)
}, [appId, startDate, endDate, appVersion]);
-
+
return (
- { journeyApiStatus === JourneyApiStatus.Loading &&
Updating data...
}
- { journeyApiStatus === JourneyApiStatus.Error &&
Error fetching data. Please refresh page or change filters to try again.
}
- { journeyApiStatus === JourneyApiStatus.Success
- &&
nodeColor}
- nodeOpacity={1}
- nodeHoverOthersOpacity={0.35}
- nodeThickness={18}
- nodeSpacing={24}
- nodeBorderWidth={0}
- nodeBorderColor={{
- from: 'color',
- modifiers: [
- [
- 'darker',
- 0.8
- ]
- ]
- }}
- nodeBorderRadius={3}
- linkOpacity={0.25}
- linkHoverOthersOpacity={0.1}
- linkContract={3}
- enableLinkGradient={false}
- labelPosition="outside"
- labelOrientation="horizontal"
- labelPadding={16}
- labelTextColor="#000000"
- nodeTooltip={({
- node
- }) =>
-
{node.label}
- {node.issues.crashes.length > 0 &&
-
-
-
Crashes:
-
- {node.issues.crashes.map(({ title, count }) => (
-
- {title} - {formatter.format(count)}
-
- ))}
-
-
- }
- {node.issues.anrs.length > 0 &&
-
-
-
ANRs:
-
- {node.issues.anrs.map(({ title, count }) => (
-
- {title} - {formatter.format(count)}
-
- ))}
-
-
- }
-
}
- linkTooltip={({
- link
- }) =>
-
{link.source.label} > {link.target.label} - {formatter.format(link.value)}
-
}
- />}
+ {journeyApiStatus === JourneyApiStatus.Loading && Updating data...
}
+ {journeyApiStatus === JourneyApiStatus.Error && Error fetching data. Please refresh page or change filters to try again.
}
+ {journeyApiStatus === JourneyApiStatus.Success
+ && nodeColor}
+ nodeOpacity={1}
+ nodeHoverOthersOpacity={0.35}
+ nodeThickness={18}
+ nodeSpacing={24}
+ nodeBorderWidth={0}
+ nodeBorderColor={{
+ from: 'color',
+ modifiers: [
+ [
+ 'darker',
+ 0.8
+ ]
+ ]
+ }}
+ nodeBorderRadius={3}
+ linkOpacity={0.25}
+ linkHoverOthersOpacity={0.1}
+ linkContract={3}
+ enableLinkGradient={false}
+ labelPosition="outside"
+ labelOrientation="horizontal"
+ labelPadding={16}
+ labelTextColor="#000000"
+ nodeTooltip={({
+ node
+ }) =>
+
{node.label}
+ {node.issues.crashes.length > 0 &&
+
+
+
Crashes:
+
+ {node.issues.crashes.map(({ title, count }) => (
+
+ {title} - {formatter.format(count)}
+
+ ))}
+
+
+ }
+ {node.issues.anrs.length > 0 &&
+
+
+
ANRs:
+
+ {node.issues.anrs.map(({ title, count }) => (
+
+ {title} - {formatter.format(count)}
+
+ ))}
+
+
+ }
+
}
+ linkTooltip={({
+ link
+ }) =>
+
{link.source.label} > {link.target.label} - {formatter.format(link.value)}
+
}
+ />}
);
};
diff --git a/measure-web-app/app/components/user_flow_crash_details.tsx b/measure-web-app/app/components/user_flow_crash_details.tsx
index 624e556e4..150bcc45c 100644
--- a/measure-web-app/app/components/user_flow_crash_details.tsx
+++ b/measure-web-app/app/components/user_flow_crash_details.tsx
@@ -11,7 +11,7 @@ const data = {
"nodeColor": "hsl(142, 69%, 58%)",
"issues": {
"crashes": [],
- "anrs":[]
+ "anrs": []
}
},
{
@@ -19,7 +19,7 @@ const data = {
"nodeColor": "hsl(142, 69%, 58%)",
"issues": {
"crashes": [],
- "anrs":[]
+ "anrs": []
}
},
{
@@ -30,7 +30,7 @@ const data = {
"title": "NullPointerException.java",
"count": 37893
}],
- "anrs":[]
+ "anrs": []
}
},
{
@@ -38,7 +38,7 @@ const data = {
"nodeColor": "hsl(142, 69%, 58%)",
"issues": {
"crashes": [],
- "anrs":[]
+ "anrs": []
}
},
{
@@ -46,7 +46,7 @@ const data = {
"nodeColor": "hsl(142, 69%, 58%)",
"issues": {
"crashes": [],
- "anrs":[]
+ "anrs": []
}
},
{
@@ -54,7 +54,7 @@ const data = {
"nodeColor": "hsl(142, 69%, 58%)",
"issues": {
"crashes": [],
- "anrs":[]
+ "anrs": []
}
},
{
@@ -62,7 +62,7 @@ const data = {
"nodeColor": "hsl(142, 69%, 58%)",
"issues": {
"crashes": [],
- "anrs":[]
+ "anrs": []
}
},
{
@@ -70,7 +70,7 @@ const data = {
"nodeColor": "hsl(142, 69%, 58%)",
"issues": {
"crashes": [],
- "anrs":[]
+ "anrs": []
}
},
{
@@ -81,7 +81,7 @@ const data = {
"title": "NullPointerException.java",
"count": 37893
}],
- "anrs":[]
+ "anrs": []
}
},
{
@@ -89,7 +89,7 @@ const data = {
"nodeColor": "hsl(142, 69%, 58%)",
"issues": {
"crashes": [],
- "anrs":[]
+ "anrs": []
}
},
{
@@ -97,7 +97,7 @@ const data = {
"nodeColor": "hsl(142, 69%, 58%)",
"issues": {
"crashes": [],
- "anrs":[]
+ "anrs": []
}
},
{
@@ -105,7 +105,7 @@ const data = {
"nodeColor": "hsl(142, 69%, 58%)",
"issues": {
"crashes": [],
- "anrs":[]
+ "anrs": []
}
}
],
@@ -186,25 +186,25 @@ const data = {
const formatter = Intl.NumberFormat('en', { notation: 'compact' });
const UserFlowCrashDetails = () => {
- return (
- nodeColor}
+ colors={({ nodeColor }) => nodeColor}
nodeOpacity={1}
nodeHoverOthersOpacity={0.35}
nodeThickness={18}
nodeSpacing={24}
nodeBorderWidth={0}
nodeBorderColor={{
- from: 'color',
- modifiers: [
- [
- 'darker',
- 0.8
- ]
+ from: 'color',
+ modifiers: [
+ [
+ 'darker',
+ 0.8
]
+ ]
}}
nodeBorderRadius={3}
linkOpacity={0.25}
@@ -218,40 +218,40 @@ const UserFlowCrashDetails = () => {
nodeTooltip={({
node
}) =>
-
{node.label}
- {node.issues.crashes.length > 0 &&
-
-
-
Crashes:
-
- {node.issues.crashes.map(({ title, count }) => (
-
- {title} - {formatter.format(count)}
-
- ))}
-
-
- }
- {node.issues.anrs.length > 0 &&
-
-
-
ANRs:
-
- {node.issues.anrs.map(({ title, count }) => (
-
- {title} - {formatter.format(count)}
-
- ))}
-
-
- }
-
}
+ {node.label}
+ {node.issues.crashes.length > 0 &&
+
+
+
Crashes:
+
+ {node.issues.crashes.map(({ title, count }) => (
+
+ {title} - {formatter.format(count)}
+
+ ))}
+
+
+ }
+ {node.issues.anrs.length > 0 &&
+
+
+
ANRs:
+
+ {node.issues.anrs.map(({ title, count }) => (
+
+ {title} - {formatter.format(count)}
+
+ ))}
+
+
+ }
+ }
linkTooltip={({
link
}) =>
-
{link.source.label} > {link.target.label} - {formatter.format(link.value)}
-
}
- />
+
{link.source.label} > {link.target.label} - {formatter.format(link.value)}
+
}
+ />
);
};
diff --git a/measure-web-app/app/globals.css b/measure-web-app/app/globals.css
index 82a5b951d..e360de177 100644
--- a/measure-web-app/app/globals.css
+++ b/measure-web-app/app/globals.css
@@ -8,18 +8,16 @@
--background-end-rgb: 255, 255, 255;
}
-button, [role="button"] {
+button,
+[role="button"] {
cursor: auto;
}
body {
color: rgb(var(--foreground-rgb));
- background: linear-gradient(
- to bottom,
+ background: linear-gradient(to bottom,
transparent,
- rgb(var(--background-end-rgb))
- )
- rgb(var(--background-start-rgb));
+ rgb(var(--background-end-rgb))) rgb(var(--background-start-rgb));
}
@layer base {
diff --git a/measure-web-app/app/layout.tsx b/measure-web-app/app/layout.tsx
index 9d14dc866..4e3a7cc40 100644
--- a/measure-web-app/app/layout.tsx
+++ b/measure-web-app/app/layout.tsx
@@ -1,16 +1,20 @@
import './globals.css'
import type { Metadata } from 'next'
-import {Josefin_Sans, Space_Mono } from 'next/font/google'
+import { Josefin_Sans, Space_Mono } from 'next/font/google'
-const display = Josefin_Sans({ subsets: ['latin'], display: 'swap', weight:['100','200', '300', '400', '500', '600', '700'],
-variable: '--font-display'})
+const display = Josefin_Sans({
+ subsets: ['latin'], display: 'swap', weight: ['100', '200', '300', '400', '500', '600', '700'],
+ variable: '--font-display'
+})
-const body = Space_Mono({ subsets: ['latin'], display: 'swap', weight: ['400', '700'],
-variable: '--font-body'})
+const body = Space_Mono({
+ subsets: ['latin'], display: 'swap', weight: ['400', '700'],
+ variable: '--font-body'
+})
export const metadata: Metadata = {
title: 'Measure',
description: 'Open source mobile app monitoring | Alternative to Firebase Crashlytics, Instabug, Sentry, Embrace',
- viewport: { width: "device-width", initialScale: 1, minimumScale:1 }
+ viewport: { width: "device-width", initialScale: 1, minimumScale: 1 }
}
export default function RootLayout({
diff --git a/measure-web-app/app/page.tsx b/measure-web-app/app/page.tsx
index 855ffb288..a6b1db3a2 100644
--- a/measure-web-app/app/page.tsx
+++ b/measure-web-app/app/page.tsx
@@ -9,103 +9,103 @@ import LandingHeader from './components/landing_header'
export default function Home() {
return (
-
+
-
+
measure
-
+
open source app monitoring for mobile teams
-
-
-
+
+
+
App health at a glance
-
+
Monitor core user flows and important metrics to stay on top of app health. Filter by various system or custom attributes to dive deeper.
-
-
+
+
{/*
*/}
-
+
Crash debugging simplified
-
+
Track crashes and app hangs automatically, prioritise them by impact and use detailed event timelines to zoom in on production issues.
-
-
+
+
-
+
Buttery smooth performance
-
+
Automatically trace app startups, app hangs, network calls, database queries and slow page loads. Use custom traces to measure what matters in any part of your app.
-
-
+
+
-
+
Detailed logging
-
+
Capture standard output/Logcat output automatically. Add custom logs anywhere in your code for easy debugging in production.
-
-
+
+
-
+
Built by and for mobile devs
-
+
Open source platform with a welcoming community. Built by mobile devs who have shipped apps to hundreds of millions of users since the early days of iOS and Android.
-
-
+
+
-
+
Measure on every platform
-
+
-
Android
-
In progress
+
Android
+
In progress
-
+
-
iOS
-
In progress
+
iOS
+
In progress
-
+
-
Flutter
-
In progress
+
Flutter
+
In progress
-
+
-
React Native
-
In progress
+
React Native
+
In progress
-
+
-
Unity
-
In progress
+
Unity
+
In progress
-
+
Early access
-
+
We are building measure for mobile devs like you. Help us make it the best tool for the job!
-
-
-
+
+
+
-
+
)
}
diff --git a/measure-web-app/app/utils/auth_utils.tsx b/measure-web-app/app/utils/auth_utils.tsx
index f97b91caf..76a3f2e71 100644
--- a/measure-web-app/app/utils/auth_utils.tsx
+++ b/measure-web-app/app/utils/auth_utils.tsx
@@ -5,7 +5,7 @@ import { AppRouterInstance } from 'next/dist/shared/lib/app-router-context';
const supabase = createBrowserClient()
supabase.auth.onAuthStateChange(async (event: AuthChangeEvent, session) => {
- switch(event) {
+ switch (event) {
case 'INITIAL_SESSION':
if (!globalThis.location) return
const urlParams = new URLSearchParams(globalThis.location.hash.substring(1))