Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: DIA-1927: [FE] Data on organization section are incorrect on new account settings page #7100

Open
wants to merge 23 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
5eab13f
Add missing membership info
nick-skriabin Feb 17, 2025
a385d90
Update web/libs/core/src/pages/AccountSettings/sections/MembershipInf…
nick-skriabin Feb 19, 2025
50edb2f
Update web/libs/core/src/pages/AccountSettings/sections/MembershipInf…
nick-skriabin Feb 19, 2025
c1482a8
Update web/libs/core/src/pages/AccountSettings/sections/MembershipInf…
nick-skriabin Feb 19, 2025
36e5c29
Update web/libs/core/src/pages/AccountSettings/sections/MembershipInf…
nick-skriabin Feb 19, 2025
83b2189
Reusable format function
nick-skriabin Feb 19, 2025
41e9ce9
Update web/libs/core/src/pages/AccountSettings/sections/MembershipInf…
nick-skriabin Feb 19, 2025
3af59f3
Update web/libs/core/src/pages/AccountSettings/sections/MembershipInf…
nick-skriabin Feb 19, 2025
f1998d8
Update web/libs/core/src/pages/AccountSettings/sections/MembershipInf…
nick-skriabin Feb 19, 2025
97b1941
Update membership info
nick-skriabin Feb 26, 2025
3c4507f
Fix membership info
nick-skriabin Feb 26, 2025
b52f8db
Lift permissions for Org API
nick-skriabin Feb 28, 2025
9d82192
Reset permission settings
nick-skriabin Feb 28, 2025
0f15fe3
Merge branch 'develop' into 'fb-dia-1927/membership-info'
MihajloHoma Mar 4, 2025
addc587
Remove duplicated import
nick-skriabin Mar 4, 2025
278c6a4
Add `active_organization_meta` to whoami and support on user account …
nick-skriabin Mar 5, 2025
cf4e14e
Merge branch 'develop' into 'fb-dia-1927/membership-info'
robot-ci-heartex Mar 6, 2025
04b674e
Sync Follow Merge dependencies
robot-ci-heartex Mar 6, 2025
669e390
Safety first
nick-skriabin Mar 6, 2025
02ebe55
Merge branch 'develop' into fb-dia-1927/membership-info
nick-skriabin Mar 6, 2025
43bef49
Sync Follow Merge dependencies
robot-ci-heartex Mar 7, 2025
d70ca89
Add missing import
nick-skriabin Mar 7, 2025
f33dcc6
Restore version from develop
nick-skriabin Mar 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions web/apps/labelstudio/src/app/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import { FF_OPTIC_2, FF_UNSAVED_CHANGES, FF_PRODUCT_TOUR, isFF } from "../utils/
import { TourProvider } from "@humansignal/core";
import { ToastProvider, ToastViewport } from "@humansignal/ui";
import { CurrentUserProvider } from "../providers/CurrentUser";
import { QueryClientProvider } from "@tanstack/react-query";
import { LSQueryClient } from "../utils/query-client";

const baseURL = new URL(APP_SETTINGS.hostname || location.origin);
export const UNBLOCK_HISTORY_MESSAGE = "UNBLOCK_HISTORY";
Expand Down Expand Up @@ -57,6 +59,7 @@ const App = ({ content }) => {
<Router history={browserHistory}>
<MultiProvider
providers={[
<QueryClientProvider client={LSQueryClient} key="query" />,
<AppStoreProvider key="app-store" />,
<ApiProvider key="api" />,
<ConfigProvider key="config" />,
Expand Down
9 changes: 9 additions & 0 deletions web/apps/labelstudio/src/utils/query-client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { QueryClient } from "@tanstack/react-query";

export const LSQueryClient = new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
},
},
});
152 changes: 97 additions & 55 deletions web/libs/core/src/pages/AccountSettings/sections/MembershipInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,91 @@
import { useEffect, useState } from "react";
import { ToastType, useToast } from "@humansignal/ui";
import { format } from "date-fns";
import styles from "./MembershipInfo.module.scss";
import { useQuery } from "@tanstack/react-query";

/**
* FIXME: This is legacy imports. We're not supposed to use such statements
* each one of these eventually has to be migrated to core/ui
*/
import { useCurrentUser } from "/apps/labelstudio/src/providers/CurrentUser";
import { useAPI } from "/apps/labelstudio/src/providers/ApiProvider";
import { API } from "apps/labelstudio/src/providers/ApiProvider";
import { useMemo } from "react";

function formatDate(date?: string) {
return format(new Date(date ?? ""), "dd MMM yyyy, KK:mm a");
}

export const MembershipInfo = () => {
const api = useAPI();
const toast = useToast();
const { user } = useCurrentUser();
const [registrationDate, setRegistrationDate] = useState<string | null>(null);
const [annotationsCount, setAnnotationsCount] = useState<number | null>(null);
const [projectsContributedTo, setProjectsContributedTo] = useState<number | null>(null);

useEffect(() => {
if (!user) return;
api
.callApi("userMemberships", {
params: {
pk: user.active_organization,
userPk: user.id,
},
})
.then((response: any) => {
if (response?.$meta?.ok) {
setRegistrationDate(format(new Date(response?.created_at), "dd MMM yyyy, KK:mm a"));
setAnnotationsCount(response?.annotations_count);
setProjectsContributedTo(response?.contributed_projects_count);
} else {
toast.show({
message: "Failed to fetch membership info",
type: ToastType.error,
});
}
const dateJoined = useMemo(() => {
if (!user?.date_joined) return null;
return formatDate(user?.date_joined);
}, [user?.date_joined]);

const membership = useQuery({
queryKey: [user?.active_organization, user?.id, "user-membership"],
async queryFn() {
if (!user) return {};
const response = await API.invoke("userMemberships", {
pk: user.active_organization,
userPk: user.id,
});

const registrationDate = formatDate(response?.created_at);
const annotationCount = response?.annotations_count;
const contributions = response?.contributed_projects_count;

return {
registrationDate,
annotationCount,
contributions,
};
},
});

const organization = useQuery({
queryKey: ["organization", user?.active_organization],
async queryFn() {
if (!user) return null;
if (!window?.APP_SETTINGS?.billing) return null;
const organization = await API.invoke("organization", {
pk: user.active_organization,
});
}, [user?.id]);
let role = "Owner";

switch (organization.userRole) {
case "OW":
role = "Owner";
break;
case "DI":
role = "Deactivated";
break;
case "AD":
role = "Administrator";
break;
case "MA":
role = "Manager";
break;
case "AN":
role = "Annotator";
break;
case "RE":
role = "Reviewer";
break;
case "NO":
role = "Pending";
break;
}

if (organization) {
return {
role,
title: organization.title,
};
}

return null;
},
});

return (
<div className={styles.membershipInfo} id="membership-info">
Expand All @@ -50,46 +96,42 @@ export const MembershipInfo = () => {

<div className="flex gap-2 w-full justify-between">
<div>Registration date</div>
<div>{registrationDate}</div>
</div>

<div className="flex gap-2 w-full justify-between">
<div>Annotations submitted</div>
<div>{annotationsCount}</div>
</div>

<div className="flex gap-2 w-full justify-between">
<div>Projects contributed to</div>
<div>{projectsContributedTo}</div>
<div>{dateJoined}</div>
</div>

<div className={styles.divider} />

<div className="flex gap-2 w-full justify-between">
<div>Organization</div>
<div>
<a href="/organization">{user?.email}</a>
{organization.data && (
<div className="flex gap-2 w-full justify-between">
<div>Organization</div>
<div>
<a href="/organization">{organization.data.title}</a>
</div>
</div>
</div>
)}

<div className="flex gap-2 w-full justify-between">
<div>My role</div>
<div>Owner</div>
</div>
{organization.data?.role && (
<div className="flex gap-2 w-full justify-between">
<div>My role</div>
<div>{organization.data.role}</div>
</div>
)}

<div className="flex gap-2 w-full justify-between">
<div>Organization ID</div>
<div>{user?.active_organization}</div>
</div>

<div className="flex gap-2 w-full justify-between">
<div>Owner</div>
<div>{user?.email}</div>
</div>
{organization.data && (
<div className="flex gap-2 w-full justify-between">
<div>Owner</div>
<div>{organization.data.title}</div>
</div>
)}

<div className="flex gap-2 w-full justify-between">
<div>Created</div>
<div>{registrationDate}</div>
<div>{membership.data?.registrationDate}</div>
</div>
</div>
);
Expand Down
1 change: 1 addition & 0 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"@martel/audio-file-decoder": "^2.3.15",
"@radix-ui/react-toast": "^1.1.5",
"@tanstack/query-core": "^5.66.0",
"@tanstack/react-query": "^4",
"@thi.ng/rle-pack": "^3.1.30",
"antd": "^4.3.3",
"chroma-js": "^2.1.1",
Expand Down
18 changes: 18 additions & 0 deletions web/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4747,11 +4747,24 @@
dependencies:
defer-to-connect "^2.0.0"

"@tanstack/[email protected]":
version "4.36.1"
resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-4.36.1.tgz#79f8c1a539d47c83104210be2388813a7af2e524"
integrity sha512-DJSilV5+ytBP1FbFcEJovv4rnnm/CokuVvrBEtW/Va9DvuJ3HksbXUJEpI0aV1KtuL4ZoO9AVE6PyNLzF7tLeA==

"@tanstack/query-core@^5.66.0":
version "5.66.0"
resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.66.0.tgz#163f670b3b4e3b3cdbff6698ad44b2edfcaed185"
integrity sha512-J+JeBtthiKxrpzUu7rfIPDzhscXF2p5zE/hVdrqkACBP8Yu0M96mwJ5m/8cPPYQE9aRNvXztXHlNwIh4FEeMZw==

"@tanstack/react-query@^4":
version "4.36.1"
resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-4.36.1.tgz#acb589fab4085060e2e78013164868c9c785e5d2"
integrity sha512-y7ySVHFyyQblPl3J3eQBWpXZkliroki3ARnBKsdJchlgt7yJLRDUcf4B8soufgiYt3pEQIkBWBx1N9/ZPIeUWw==
dependencies:
"@tanstack/query-core" "4.36.1"
use-sync-external-store "^1.2.0"

"@testing-library/dom@^8.0.0":
version "8.20.1"
resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.20.1.tgz#2e52a32e46fc88369eef7eef634ac2a192decd9f"
Expand Down Expand Up @@ -18264,6 +18277,11 @@ use-sidecar@^1.1.2:
detect-node-es "^1.1.0"
tslib "^2.0.0"

use-sync-external-store@^1.2.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz#adbc795d8eeb47029963016cefdf89dc799fcebc"
integrity sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==

utf8-byte-length@^1.0.1:
version "1.0.4"
resolved "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz#f45f150c4c66eee968186505ab93fcbb8ad6bf61"
Expand Down
Loading