Skip to content

Feat: remove team member#342

Open
7eliassen wants to merge 2 commits intomainfrom
feat/remove-team-member
Open

Feat: remove team member#342
7eliassen wants to merge 2 commits intomainfrom
feat/remove-team-member

Conversation

@7eliassen
Copy link

Added the ability to remove a team member from a note.
Users with 'write' access to a note can now remove other members from its team.

In the note's settings menu, a new "Remove" option has been added to the context menu (located right after role selector). This action requires confirmation before the member is actually removed.

@vercel
Copy link

vercel bot commented Feb 6, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
codex-ui Ready Ready Preview, Comment Feb 6, 2026 6:27pm

@7eliassen 7eliassen linked an issue Feb 6, 2026 that may be closed by this pull request
@neSpecc neSpecc requested a review from Copilot February 6, 2026 18:36
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a “Remove member” action to the Note Settings team list, wiring UI → application/domain → repository API to remove a collaborator (with confirmation) and refresh the displayed settings.

Changes:

  • Add a per-member “More actions” context menu with a “Remove” option and confirmation flow.
  • Bubble a “team member removed” event up to NoteSettings to reload note settings/team.
  • Add removeMemberByUserId through repository/service/composable layers and introduce new i18n strings.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/presentation/pages/NoteSettings.vue Listens for member-removed event and reloads note settings.
src/presentation/components/team/Team.vue Renders new per-member actions component and re-emits removal event upward.
src/presentation/components/team/MoreActions.vue New UI component showing context menu + confirmation + remove call.
src/infrastructure/noteSettings.repository.ts Adds DELETE call to remove a team member by userId.
src/domain/noteSettings.service.ts Exposes removeMemberByUserId in domain service.
src/domain/noteSettings.repository.interface.ts Extends repository interface with removeMemberByUserId.
src/application/services/useNoteSettings.ts Adds composable method for removing a team member.
src/application/i18n/messages/en.json Adds menu label and confirmation copy for removal.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

<template>
<button
ref="triggerButton"
class="more-actions-button"
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The icon-only needs an accessible name and should explicitly set type="button" to avoid default submit behavior when used inside a . Consider adding an aria-label/title (e.g., "More actions") and type="button" on this button element.

Suggested change
class="more-actions-button"
class="more-actions-button"
type="button"
:aria-label="t('noteSettings.team.moreActions')"
:title="t('noteSettings.team.moreActions')"

Copilot uses AI. Check for mistakes.
Comment on lines +43 to +45
onActivate: () => {
handleRemove(props.teamMember);
hide();
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This callback triggers the async removal flow but does not await or handle errors from handleRemove(). If removeMemberByUserId throws (network/403/etc.), this can become an unhandled promise rejection and the user gets no feedback. Please make the activation path handle the promise (e.g., mark onActivate async and await, or attach a .catch that shows an error).

Suggested change
onActivate: () => {
handleRemove(props.teamMember);
hide();
onActivate: async () => {
hide();
try {
await handleRemove(props.teamMember);
} catch (error) {
console.error('Failed to remove team member', error);
}

Copilot uses AI. Check for mistakes.
Comment on lines +18 to +22
<MoreActions
:note-id="noteId"
:team-member="member"
@team-member-removed="handleMemberRemoved"
/>
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MoreActions is rendered for every team member without any permission/self/creator checks. Per the PR description, users should only be able to remove other members and only when they have "write" access; additionally, creator/self removal typically should be blocked in UI. Consider conditionally rendering/disabling this component based on current user role/ID and note creator ID (similar to RoleSelect).

Copilot uses AI. Check for mistakes.
},
"removeMemberConfirmationTitle": "Remove member",
"removeMemberConfirmationBody": "Are you sure you want to remove user from the team?",
"ContextMenu": {
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The i18n key "ContextMenu" uses PascalCase, which is inconsistent with the surrounding noteSettings.team keys (mostly lowerCamelCase). Consider renaming it to "contextMenu" (or similar) and updating usages (e.g., t('noteSettings.team.contextMenu.remove')) to keep the messages structure consistent.

Suggested change
"ContextMenu": {
"contextMenu": {

Copilot uses AI. Check for mistakes.
"Write": "Writer"
},
"removeMemberConfirmationTitle": "Remove member",
"removeMemberConfirmationBody": "Are you sure you want to remove user from the team?",
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grammar: the confirmation text is missing an article and reads a bit awkwardly.

Suggested change
"removeMemberConfirmationBody": "Are you sure you want to remove user from the team?",
"removeMemberConfirmationBody": "Are you sure you want to remove the user from the team?",

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +21
import useNoteSettings from '@/application/services/useNoteSettings';

const { removeMemberByUserId } = useNoteSettings();
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MoreActions is instantiated per team member row, but it calls useNoteSettings(), which creates its own composable state (noteSettings refs, parentNote refs, router, etc.) per instance. This is unnecessary overhead and can lead to duplicated state; consider passing removeMemberByUserId down from the parent, or extracting a lighter-weight service call that doesn't allocate the full composable state for each row.

Copilot uses AI. Check for mistakes.
/**
* Handle team member removal by refreshing the note settings
*/
async function handleTeamMemberRemoved() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think that instead of reloading the page completely we could just update noteSettings composable

then we would need to handle boolean that is returned by the api endpoint

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ability to remove a team member

2 participants