-
Notifications
You must be signed in to change notification settings - Fork 753
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/main' into improvement/async-mem…
…ber-affiliations-update
- Loading branch information
Showing
29 changed files
with
530 additions
and
265 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
backend/src/database/migrations/U1704395824__memberMergeSuggestionsLastGeneratedAt.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
alter table "tenants" drop column "memberMergeSuggestionsLastGeneratedAt"; |
2 changes: 2 additions & 0 deletions
2
backend/src/database/migrations/V1704395824__memberMergeSuggestionsLastGeneratedAt.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
alter table "tenants" | ||
add column "memberMergeSuggestionsLastGeneratedAt" timestamp with time zone null; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,97 +24,6 @@ describe('TenantService tests', () => { | |
await SequelizeTestUtils.closeConnection(db) | ||
}) | ||
|
||
describe('findMembersToMerge', () => { | ||
it('Should show the same merge suggestion once, with reverse order', async () => { | ||
const mockIServiceOptions = await SequelizeTestUtils.getTestIServiceOptions(db) | ||
const memberService = new MemberService(mockIServiceOptions) | ||
const tenantService = new TenantService(mockIServiceOptions) | ||
|
||
const memberToCreate1 = { | ||
username: { | ||
[PlatformType.SLACK]: { | ||
username: 'member 1', | ||
integrationId: generateUUIDv1(), | ||
}, | ||
}, | ||
platform: PlatformType.SLACK, | ||
email: '[email protected]', | ||
joinedAt: '2020-05-27T15:13:30Z', | ||
} | ||
|
||
const memberToCreate2 = { | ||
username: { | ||
[PlatformType.DISCORD]: { | ||
username: 'member 2', | ||
integrationId: generateUUIDv1(), | ||
}, | ||
}, | ||
platform: PlatformType.DISCORD, | ||
email: '[email protected]', | ||
joinedAt: '2020-05-26T15:13:30Z', | ||
} | ||
|
||
const memberToCreate3 = { | ||
username: { | ||
[PlatformType.GITHUB]: { | ||
username: 'member 3', | ||
integrationId: generateUUIDv1(), | ||
}, | ||
}, | ||
platform: PlatformType.GITHUB, | ||
email: '[email protected]', | ||
joinedAt: '2020-05-25T15:13:30Z', | ||
} | ||
|
||
const memberToCreate4 = { | ||
username: { | ||
[PlatformType.TWITTER]: { | ||
username: 'member 4', | ||
integrationId: generateUUIDv1(), | ||
}, | ||
}, | ||
platform: PlatformType.TWITTER, | ||
email: '[email protected]', | ||
joinedAt: '2020-05-24T15:13:30Z', | ||
} | ||
|
||
const member1 = await memberService.upsert(memberToCreate1) | ||
let member2 = await memberService.upsert(memberToCreate2) | ||
const member3 = await memberService.upsert(memberToCreate3) | ||
let member4 = await memberService.upsert(memberToCreate4) | ||
|
||
await memberService.addToMerge([{ members: [member1.id, member2.id], similarity: 1 }]) | ||
await memberService.addToMerge([{ members: [member3.id, member4.id], similarity: 0.5 }]) | ||
|
||
member2 = await memberService.findById(member2.id) | ||
member4 = await memberService.findById(member4.id) | ||
|
||
const memberToMergeSuggestions = await tenantService.findMembersToMerge({}) | ||
|
||
// In the DB there should be: | ||
// - Member 1 should have member 2 in toMerge | ||
// - Member 3 should have member 4 in toMerge | ||
// - Member 4 should have member 3 in toMerge | ||
// - We should get these 4 combinations | ||
// But this function should not return duplicates, so we should get | ||
// only two pairs: [m2, m1] and [m4, m3] | ||
|
||
expect(memberToMergeSuggestions.count).toEqual(1) | ||
|
||
expect( | ||
memberToMergeSuggestions.rows[0].members | ||
.sort((a, b) => (a.createdAt > b.createdAt ? 1 : -1)) | ||
.map((m) => m.id), | ||
).toStrictEqual([member1.id, member2.id]) | ||
|
||
expect( | ||
memberToMergeSuggestions.rows[1].members | ||
.sort((a, b) => (a.createdAt > b.createdAt ? 1 : -1)) | ||
.map((m) => m.id), | ||
).toStrictEqual([member3.id, member4.id]) | ||
}) | ||
}) | ||
|
||
describe('_findAndCountAllForEveryUser method', () => { | ||
it('Should succesfully find all tenants without filtering by currentUser', async () => { | ||
let tenants = await TenantService._findAndCountAllForEveryUser({ filter: {} }) | ||
|
135 changes: 135 additions & 0 deletions
135
frontend/src/modules/member/components/member-actions.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
<template> | ||
<div> | ||
<el-button-group class="ml-4"> | ||
<!-- Edit contact --> | ||
<el-button class="btn btn--bordered btn--sm !h-8" :disabled="isEditLockedForSampleData" @click="edit()"> | ||
<span class="ri-pencil-line text-base mr-2" />Edit contact | ||
</el-button> | ||
<el-button | ||
v-if="mergeSuggestionsCount > 0" | ||
class="btn btn--bordered btn--sm !h-8 !-ml-px !-mr-0.5" | ||
:disabled="isEditLockedForSampleData" | ||
@click="mergeSuggestions()" | ||
> | ||
<span class="mr-2 h-5 px-1.5 rounded-md bg-brand-100 text-brand-500 leading-5">{{ mergeSuggestionsCount }}</span>Merge suggestion | ||
</el-button> | ||
|
||
<el-button | ||
v-else | ||
class="btn btn--bordered btn--sm !h-8 !-ml-px !-mr-0.5" | ||
:disabled="isEditLockedForSampleData" | ||
@click="merge()" | ||
> | ||
<span class="ri-shuffle-line text-base mr-2" />Merge | ||
</el-button> | ||
<app-member-dropdown | ||
:member="props.member" | ||
:hide-merge="true" | ||
:hide-edit="true" | ||
@find-github="isFindGithubDrawerOpen = member" | ||
> | ||
<template #trigger> | ||
<el-button class="btn btn--bordered btn--sm !p-2 !h-8 !border-l-2 !border-l-gray-200"> | ||
<span class="ri-more-fill text-base" /> | ||
</el-button> | ||
</template> | ||
</app-member-dropdown> | ||
</el-button-group> | ||
</div> | ||
<app-member-find-github-drawer | ||
v-if="isFindGithubDrawerOpen" | ||
v-model="isFindGithubDrawerOpen" | ||
/> | ||
<app-member-merge-dialog | ||
v-if="isMergeDialogOpen" | ||
v-model="isMergeDialogOpen" | ||
/> | ||
</template> | ||
|
||
<script setup> | ||
import AppMemberDropdown from '@/modules/member/components/member-dropdown.vue'; | ||
import { | ||
computed, onMounted, ref, watch, | ||
} from 'vue'; | ||
import { MemberPermissions } from '@/modules/member/member-permissions'; | ||
import { mapGetters } from '@/shared/vuex/vuex.helpers'; | ||
import { useRouter } from 'vue-router'; | ||
import AppMemberFindGithubDrawer from '@/modules/member/components/member-find-github-drawer.vue'; | ||
import AppMemberMergeDialog from '@/modules/member/components/member-merge-dialog.vue'; | ||
import { MemberService } from '@/modules/member/member-service'; | ||
const props = defineProps({ | ||
member: { | ||
type: Object, | ||
default: () => {}, | ||
}, | ||
}); | ||
const router = useRouter(); | ||
const { currentUser, currentTenant } = mapGetters('auth'); | ||
const isMergeDialogOpen = ref(null); | ||
const isFindGithubDrawerOpen = ref(null); | ||
const mergeSuggestionsCount = ref(0); | ||
const isEditLockedForSampleData = computed( | ||
() => new MemberPermissions(currentTenant.value, currentUser.value) | ||
.editLockedForSampleData, | ||
); | ||
const fetchMembersToMergeCount = () => { | ||
MemberService.fetchMergeSuggestions(1, 0, { | ||
memberId: props.member.id, | ||
}) | ||
.then(({ count }) => { | ||
mergeSuggestionsCount.value = count; | ||
}); | ||
}; | ||
const edit = () => { | ||
if (isEditLockedForSampleData.value) { | ||
return; | ||
} | ||
router.push({ | ||
name: 'memberEdit', | ||
params: { | ||
id: props.member.id, | ||
}, | ||
}); | ||
}; | ||
const mergeSuggestions = () => { | ||
if (isEditLockedForSampleData.value) { | ||
return; | ||
} | ||
router.push({ | ||
name: 'memberMergeSuggestions', | ||
query: { | ||
memberId: props.member.id, | ||
}, | ||
}); | ||
}; | ||
const merge = () => { | ||
if (isEditLockedForSampleData.value) { | ||
return; | ||
} | ||
isMergeDialogOpen.value = props.member; | ||
}; | ||
watch(() => props.member, () => { | ||
fetchMembersToMergeCount(); | ||
}); | ||
onMounted(() => { | ||
fetchMembersToMergeCount(); | ||
}); | ||
</script> | ||
|
||
<script> | ||
export default { | ||
name: 'AppMemberActions', | ||
}; | ||
</script> | ||
|
||
<style lang="scss"> | ||
</style> |
Oops, something went wrong.