-
Notifications
You must be signed in to change notification settings - Fork 3.9k
[WEB-5671] chore: settings workspace members enchancements #8346
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| // store | ||
| import { BaseWorkspaceRootStore } from "@/store/workspace"; | ||
| import type { RootStore } from "@/plane-web/store/root.store"; | ||
|
|
||
| export class WorkspaceRootStore extends BaseWorkspaceRootStore { | ||
| constructor(_rootStore: RootStore) { | ||
| super(_rootStore); | ||
| } | ||
|
|
||
| // actions | ||
| /** | ||
| * Mutate workspace members activity | ||
| * @param workspaceSlug | ||
| */ | ||
| mutateWorkspaceMembersActivity = async (_workspaceSlug: string) => { | ||
| // No-op in default/CE version | ||
| }; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,6 +9,7 @@ import { Table } from "@plane/ui"; | |
| // components | ||
| import { MembersLayoutLoader } from "@/components/ui/loader/layouts/members-layout-loader"; | ||
| import { ConfirmWorkspaceMemberRemove } from "@/components/workspace/confirm-workspace-member-remove"; | ||
| import type { RowData } from "@/components/workspace/settings/member-columns"; | ||
| // helpers | ||
| import { captureError, captureSuccess } from "@/helpers/event-tracker.helper"; | ||
| // hooks | ||
|
|
@@ -34,51 +35,56 @@ export const WorkspaceMembersListItem = observer(function WorkspaceMembersListIt | |
| workspace: { removeMemberFromWorkspace }, | ||
| } = useMember(); | ||
| const { leaveWorkspace } = useUserPermissions(); | ||
| const { getWorkspaceRedirectionUrl } = useWorkspace(); | ||
| const { getWorkspaceRedirectionUrl, mutateWorkspaceMembersActivity } = useWorkspace(); | ||
| const { fetchCurrentUserSettings } = useUserSettings(); | ||
| const { t } = useTranslation(); | ||
| // derived values | ||
|
|
||
| const handleLeaveWorkspace = async () => { | ||
| if (!workspaceSlug || !currentUser) return; | ||
|
|
||
| await leaveWorkspace(workspaceSlug.toString()) | ||
| .then(async () => { | ||
| await fetchCurrentUserSettings(); | ||
| router.push(getWorkspaceRedirectionUrl()); | ||
| captureSuccess({ | ||
| eventName: MEMBER_TRACKER_EVENTS.workspace.leave, | ||
| payload: { | ||
| workspace: workspaceSlug, | ||
| }, | ||
| }); | ||
| }) | ||
| .catch((err: any) => { | ||
| captureError({ | ||
| eventName: MEMBER_TRACKER_EVENTS.workspace.leave, | ||
| payload: { | ||
| workspace: workspaceSlug, | ||
| }, | ||
| error: err, | ||
| }); | ||
| setToast({ | ||
| type: TOAST_TYPE.ERROR, | ||
| title: "Error!", | ||
| message: err?.error || t("something_went_wrong_please_try_again"), | ||
| }); | ||
| try { | ||
| await leaveWorkspace(workspaceSlug.toString()); | ||
| await fetchCurrentUserSettings(); | ||
| router.push(getWorkspaceRedirectionUrl()); | ||
| captureSuccess({ | ||
| eventName: MEMBER_TRACKER_EVENTS.workspace.leave, | ||
| payload: { | ||
| workspace: workspaceSlug, | ||
| }, | ||
| }); | ||
| } catch (err: unknown) { | ||
| const error = err as { error?: string }; | ||
| const errorForCapture: Error | string = err instanceof Error ? err : String(err); | ||
| captureError({ | ||
| eventName: MEMBER_TRACKER_EVENTS.workspace.leave, | ||
| payload: { | ||
| workspace: workspaceSlug, | ||
| }, | ||
| error: errorForCapture, | ||
| }); | ||
| setToast({ | ||
| type: TOAST_TYPE.ERROR, | ||
| title: "Error!", | ||
| message: error?.error || t("something_went_wrong_please_try_again"), | ||
| }); | ||
| } | ||
| }; | ||
|
|
||
| const handleRemoveMember = async (memberId: string) => { | ||
| if (!workspaceSlug || !memberId) return; | ||
|
|
||
| await removeMemberFromWorkspace(workspaceSlug.toString(), memberId).catch((err) => | ||
| try { | ||
| await removeMemberFromWorkspace(workspaceSlug.toString(), memberId); | ||
| void mutateWorkspaceMembersActivity(workspaceSlug); | ||
| } catch (err: unknown) { | ||
| const error = err as { error?: string }; | ||
| setToast({ | ||
| type: TOAST_TYPE.ERROR, | ||
| title: "Error!", | ||
| message: err?.error || t("something_went_wrong_please_try_again"), | ||
| }) | ||
| ); | ||
| message: error?.error || t("something_went_wrong_please_try_again"), | ||
| }); | ||
| } | ||
| }; | ||
|
|
||
| const handleRemove = async (memberId: string) => { | ||
|
|
@@ -109,9 +115,11 @@ export const WorkspaceMembersListItem = observer(function WorkspaceMembersListIt | |
| onSubmit={() => handleRemove(removeMemberModal.member.id)} | ||
| /> | ||
| )} | ||
| <Table | ||
| <Table<RowData> | ||
| columns={columns ?? []} | ||
| data={(memberDetails?.filter((member): member is IWorkspaceMember => member !== null) ?? []) as any} | ||
| data={ | ||
| (memberDetails?.filter((member): member is IWorkspaceMember => member !== null) ?? []) as unknown as RowData[] | ||
| } | ||
|
Comment on lines
+118
to
+122
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # Find RowData type definition
rg -n "type RowData|interface RowData" apps/web/core/components/workspace/settings/ -A3Repository: makeplane/plane Length of output: 425 🏁 Script executed: # Check member-columns.tsx to see how columns access the data
rg -n "rowData\.|data\[|member" apps/web/core/components/workspace/settings/member-columns.tsx -B1 -A1Repository: makeplane/plane Length of output: 1396 🏁 Script executed: # Check the memberDetails type and structure
rg -n "memberDetails" apps/web/core/components/workspace/settings/members-list-item.tsx -B2 -A2Repository: makeplane/plane Length of output: 857 🏁 Script executed: # Look at how Table component is typed and what it expects
rg -n "Table<" apps/web/core/components/workspace/settings/members-list-item.tsx -B2 -A5Repository: makeplane/plane Length of output: 371 🏁 Script executed: # Find IWorkspaceMember interface definition
rg -n "interface IWorkspaceMember|type IWorkspaceMember" --type=ts -A10Repository: makeplane/plane Length of output: 5641 🏁 Script executed: # Also check imports in members-list-item to see full picture
head -30 apps/web/core/components/workspace/settings/members-list-item.tsxRepository: makeplane/plane Length of output: 1469 Transform the memberDetails array into the correct RowData shape instead of using the double cast. The 🤖 Prompt for AI Agents |
||
| keyExtractor={(rowData) => rowData?.member.id ?? ""} | ||
| tHeadClassName="border-b border-subtle" | ||
| thClassName="text-left font-medium divide-x-0 text-placeholder" | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: makeplane/plane
Length of output: 174
🏁 Script executed:
Repository: makeplane/plane
Length of output: 229
🏁 Script executed:
Repository: makeplane/plane
Length of output: 41
🏁 Script executed:
Repository: makeplane/plane
Length of output: 526
🏁 Script executed:
Repository: makeplane/plane
Length of output: 1476
🏁 Script executed:
Repository: makeplane/plane
Length of output: 41
🏁 Script executed:
Repository: makeplane/plane
Length of output: 20326
🏁 Script executed:
Repository: makeplane/plane
Length of output: 3697
🏁 Script executed:
Repository: makeplane/plane
Length of output: 2416
🏁 Script executed:
Repository: makeplane/plane
Length of output: 2081
🏁 Script executed:
Repository: makeplane/plane
Length of output: 104
🏁 Script executed:
Repository: makeplane/plane
Length of output: 197
🏁 Script executed:
Repository: makeplane/plane
Length of output: 3645
🏁 Script executed:
Repository: makeplane/plane
Length of output: 699
Add explicit return type annotation for strict TypeScript compliance.
The CE store correctly implements the no-op pattern and extends
BaseWorkspaceRootStore. However, themutateWorkspaceMembersActivitymethod lacks an explicit return type annotation. For consistency with the abstract method signature and to comply with strict TypeScript mode, add: Promise<void>:🤖 Prompt for AI Agents