Skip to content

Commit fe64d49

Browse files
committed
Organization merge selection
1 parent 0748032 commit fe64d49

File tree

3 files changed

+217
-61
lines changed

3 files changed

+217
-61
lines changed

frontend/src/modules/organization/components/organization-merge-dialog.vue

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,30 @@
1818
/>
1919
</div>
2020
<div class="w-1/2 px-3">
21-
<!-- <app-member-selection-dropdown-->
22-
<!-- v-if="memberToMerge === null"-->
23-
<!-- :id="props.modelValue?.id"-->
24-
<!-- v-model="memberToMerge"-->
25-
<!-- style="margin-right: 5px"-->
26-
<!-- />-->
27-
<!-- <app-member-suggestions-details-->
28-
<!-- v-else-->
29-
<!-- :member="memberToMerge"-->
30-
<!-- :compare-member="props.modelValue"-->
31-
<!-- :is-primary="!originalMemberPrimary"-->
32-
<!-- @make-primary="originalMemberPrimary = false"-->
33-
<!-- >-->
34-
<!-- <template #action>-->
35-
<!-- <button-->
36-
<!-- class="btn btn&#45;&#45;transparent btn&#45;&#45;sm leading-5 !px-4 !py-1"-->
37-
<!-- type="button"-->
38-
<!-- @click="changeMember()"-->
39-
<!-- >-->
40-
<!-- <span class="ri-refresh-line text-base text-brand-500 mr-2" />-->
41-
<!-- <span class="text-brand-500">Change member</span>-->
42-
<!-- </button>-->
43-
<!-- </template>-->
44-
<!-- </app-member-suggestions-details>-->
45-
<!-- </div>-->
21+
<app-organization-selection-dropdown
22+
v-if="organizationToMerge === null"
23+
:id="props.modelValue?.id"
24+
v-model="organizationToMerge"
25+
style="margin-right: 5px"
26+
/>
27+
<app-organization-merge-suggestions-details
28+
v-else
29+
:organization="organizationToMerge"
30+
:compare-organization="props.modelValue"
31+
:is-primary="!originalOrganizationPrimary"
32+
@make-primary="originalOrganizationPrimary = false"
33+
>
34+
<template #action>
35+
<button
36+
class="btn btn--transparent btn--sm leading-5 !px-4 !py-1"
37+
type="button"
38+
@click="changeOrganization()"
39+
>
40+
<span class="ri-refresh-line text-base text-brand-500 mr-2" />
41+
<span class="text-brand-500">Change organization</span>
42+
</button>
43+
</template>
44+
</app-organization-merge-suggestions-details>
4645
</div>
4746
</div>
4847
<div class="pt-6 flex justify-end">
@@ -55,7 +54,7 @@
5554
:loading="sendingMerge"
5655
@click="mergeSuggestion()"
5756
>
58-
Merge members
57+
Merge organizations
5958
</el-button>
6059
</div>
6160
</div>
@@ -66,14 +65,14 @@
6665
<script setup>
6766
import { computed, ref } from 'vue';
6867
import { useRoute } from 'vue-router';
69-
7068
import Message from '@/shared/message/message';
7169
import { mapActions } from '@/shared/vuex/vuex.helpers';
7270
import AppDialog from '@/shared/dialog/dialog.vue';
7371
import AppOrganizationMergeSuggestionsDetails
7472
from '@/modules/organization/components/suggestions/organization-merge-suggestions-details.vue';
7573
import { useOrganizationStore } from '@/modules/organization/store/pinia';
7674
import { OrganizationService } from '@/modules/organization/organization-service';
75+
import AppOrganizationSelectionDropdown from '@/modules/organization/components/organization-selection-dropdown.vue';
7776
7877
const props = defineProps({
7978
modelValue: {
@@ -104,6 +103,11 @@ const isModalOpen = computed({
104103
},
105104
});
106105
106+
const changeOrganization = () => {
107+
organizationToMerge.value = null;
108+
originalOrganizationPrimary.value = true;
109+
};
110+
107111
const mergeSuggestion = () => {
108112
if (sendingMerge.value) {
109113
return;
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<template>
2+
<div class="pt-16">
3+
<div class="flex justify-center">
4+
<i
5+
class="ri-account-circle-line text-gray-200 account-icon text-center h-16 flex items-center"
6+
/>
7+
</div>
8+
<div class="text-gray-600 text-sm text-center py-4">
9+
Select the organization you want to merge with
10+
</div>
11+
<div class="flex justify-center">
12+
<div class="flex w-4/5">
13+
<app-autocomplete-one-input
14+
id="searchOrganizations"
15+
v-model="computedOrganizationToMerge"
16+
:fetch-fn="fetchFn"
17+
placeholder="Type to search organizations"
18+
input-class="w-full"
19+
>
20+
<template #option="{ item }">
21+
<div class="flex items-center">
22+
<app-avatar
23+
:entity="{
24+
displayName: item.label,
25+
avatar: item.logo,
26+
}"
27+
size="xxs"
28+
class="mr-3"
29+
/>
30+
<div class="flex flex-col justify-center">
31+
<p class="text-xs leading-4.5" v-html="$sanitize(item.label)" />
32+
</div>
33+
</div>
34+
</template>
35+
</app-autocomplete-one-input>
36+
</div>
37+
</div>
38+
</div>
39+
</template>
40+
41+
<script setup>
42+
import {
43+
computed,
44+
ref,
45+
defineProps,
46+
defineEmits,
47+
} from 'vue';
48+
import AppAutocompleteOneInput from '@/shared/form/autocomplete-one-input.vue';
49+
import AppAvatar from '@/shared/avatar/avatar.vue';
50+
import { OrganizationService } from '@/modules/organization/organization-service';
51+
52+
const emit = defineEmits('update:modelValue');
53+
const props = defineProps({
54+
modelValue: {
55+
type: Object,
56+
required: true,
57+
},
58+
id: {
59+
type: String,
60+
required: true,
61+
},
62+
});
63+
const loadingOrganizationToMerge = ref();
64+
const computedOrganizationToMerge = computed({
65+
get() {
66+
return props.modelValue;
67+
},
68+
async set(value) {
69+
loadingOrganizationToMerge.value = true;
70+
71+
const response = await OrganizationService.find(value.id);
72+
73+
emit('update:modelValue', response);
74+
loadingOrganizationToMerge.value = false;
75+
},
76+
});
77+
78+
const fetchFn = async (query, limit) => {
79+
const options = await OrganizationService.listAutocomplete(
80+
query,
81+
limit,
82+
);
83+
84+
// Remove primary organization from organizations that can be merged with
85+
const filteredOptions = options.filter((m) => m.id !== props.id);
86+
87+
// If the primary organization was removed, add an empty object in replacement
88+
if (options.length !== filteredOptions.length) {
89+
filteredOptions.push({});
90+
}
91+
console.log(filteredOptions);
92+
93+
return filteredOptions;
94+
};
95+
</script>
96+
97+
<script>
98+
export default {
99+
name: 'AppOrganizationSelectionDropdown',
100+
};
101+
</script>
102+
103+
<style lang="scss" scoped>
104+
.account-icon {
105+
font-size: 64px;
106+
}
107+
#searchOrganizations .el-select-dropdown__item {
108+
height: auto !important;
109+
}
110+
</style>

frontend/src/modules/organization/components/suggestions/organization-merge-suggestions-details.vue

Lines changed: 76 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,13 @@
4343
</button>
4444
<slot name="action" />
4545
</div>
46-
<div class="flex items-center pb-4">
46+
<div class="pb-4">
4747
<app-avatar
4848
:entity="{
4949
avatar: props.organization.logo,
5050
displayName: (props.organization.displayName || props.organization.name)?.replace('@', ''),
5151
}"
52-
class="mr-4"
52+
class="mr-4 mb-4"
5353
/>
5454
<div>
5555
<h6
@@ -84,91 +84,105 @@
8484
<div>
8585
<article
8686
v-if="
87-
props.organization.memberCount
88-
|| props.compareOrganization?.memberCount
87+
props.organization.website
88+
|| props.compareOrganization?.website
8989
"
9090
class="flex items-center justify-between h-12 border-b border-gray-200"
9191
>
9292
<p class="text-2xs font-medium text-gray-500 pr-4">
93-
# of members
93+
Website
94+
</p>
95+
<a
96+
:href="withHttp(props.organization.website)"
97+
target="_blank"
98+
rel="noopener noreferrer"
99+
class="text-xs text-gray-900 text-right"
100+
>{{ props.organization.website || '-' }}</a>
101+
</article>
102+
<article
103+
v-if="
104+
props.organization.location
105+
|| props.compareOrganization?.location
106+
"
107+
class="flex items-center justify-between h-12 border-b border-gray-200"
108+
>
109+
<p class="text-2xs font-medium text-gray-500 pr-4">
110+
Location
94111
</p>
95112
<p class="text-xs text-gray-900 text-right">
96-
{{ props.organization.memberCount || '-' }}
113+
{{ props.organization.location || '-' }}
97114
</p>
98115
</article>
99116
<article
100117
v-if="
101-
props.organization.activityCount
102-
|| props.compareOrganization?.activityCount
118+
props.organization.size
119+
|| props.compareOrganization?.size
103120
"
104121
class="flex items-center justify-between h-12 border-b border-gray-200"
105122
>
106123
<p class="text-2xs font-medium text-gray-500 pr-4">
107-
# of Activities
124+
Headcount
108125
</p>
109126
<p class="text-xs text-gray-900 text-right">
110-
{{ props.organization.activityCount || '-' }}
127+
{{ props.organization.size || '-' }}
111128
</p>
112129
</article>
113130
<article
114131
v-if="
115-
props.organization.location
116-
|| props.compareOrganization?.location
132+
props.organization.revenueRange
133+
|| props.compareOrganization?.revenueRange
117134
"
118135
class="flex items-center justify-between h-12 border-b border-gray-200"
119136
>
120137
<p class="text-2xs font-medium text-gray-500 pr-4">
121-
Location
138+
Annual Revenue
122139
</p>
123140
<p class="text-xs text-gray-900 text-right">
124-
{{ props.organization.location || '-' }}
141+
{{ revenueRange.displayValue(
142+
props.organization.revenueRange,
143+
) || '-' }}
125144
</p>
126145
</article>
127146
<article
128147
v-if="
129-
props.organization.website
130-
|| props.compareOrganization?.website
148+
props.organization.industry
149+
|| props.compareOrganization?.industry
131150
"
132151
class="flex items-center justify-between h-12 border-b border-gray-200"
133152
>
134153
<p class="text-2xs font-medium text-gray-500 pr-4">
135-
Website
154+
Industry
155+
</p>
156+
<p class="text-xs text-gray-900 text-right first-letter:uppercase">
157+
{{ props.organization.industry || '-' }}
136158
</p>
137-
<a
138-
:href="withHttp(props.organization.website)"
139-
target="_blank"
140-
rel="noopener noreferrer"
141-
class="text-xs text-gray-900 text-right"
142-
>{{ props.organization.website }}</a>
143159
</article>
144160
<article
145161
v-if="
146-
props.organization.size
147-
|| props.compareOrganization?.size
162+
props.organization.type
163+
|| props.compareOrganization?.type
148164
"
149165
class="flex items-center justify-between h-12 border-b border-gray-200"
150166
>
151167
<p class="text-2xs font-medium text-gray-500 pr-4">
152-
Headcount
168+
Industry
153169
</p>
154-
<p class="text-xs text-gray-900 text-right">
155-
{{ props.organization.size || '-' }}
170+
<p class="text-xs text-gray-900 text-right first-letter:uppercase">
171+
{{ props.organization.type || '-' }}
156172
</p>
157173
</article>
158174
<article
159175
v-if="
160-
props.organization.revenueRange
161-
|| props.compareOrganization?.revenueRange
176+
props.organization.founded
177+
|| props.compareOrganization?.founded
162178
"
163179
class="flex items-center justify-between h-12 border-b border-gray-200"
164180
>
165181
<p class="text-2xs font-medium text-gray-500 pr-4">
166-
Annual Revenue
182+
Industry
167183
</p>
168184
<p class="text-xs text-gray-900 text-right">
169-
{{ revenueRange.displayValue(
170-
props.organization.revenueRange,
171-
) || '-' }}
185+
{{ props.organization.founded || '-' }}
172186
</p>
173187
</article>
174188
<article
@@ -185,6 +199,34 @@
185199
{{ formatDateToTimeAgo(props.organization.joinedAt) || '-' }}
186200
</p>
187201
</article>
202+
<article
203+
v-if="
204+
props.organization.memberCount
205+
|| props.compareOrganization?.memberCount
206+
"
207+
class="flex items-center justify-between h-12 border-b border-gray-200"
208+
>
209+
<p class="text-2xs font-medium text-gray-500 pr-4">
210+
# of members
211+
</p>
212+
<p class="text-xs text-gray-900 text-right">
213+
{{ props.organization.memberCount || '-' }}
214+
</p>
215+
</article>
216+
<article
217+
v-if="
218+
props.organization.activityCount
219+
|| props.compareOrganization?.activityCount
220+
"
221+
class="flex items-center justify-between h-12 border-b border-gray-200"
222+
>
223+
<p class="text-2xs font-medium text-gray-500 pr-4">
224+
# of Activities
225+
</p>
226+
<p class="text-xs text-gray-900 text-right">
227+
{{ props.organization.activityCount || '-' }}
228+
</p>
229+
</article>
188230
</div>
189231
<div class="pt-5">
190232
<a

0 commit comments

Comments
 (0)