Skip to content

Commit

Permalink
feat(space-users): add user invitation feature
Browse files Browse the repository at this point in the history
  • Loading branch information
NicolasRichel committed Feb 16, 2021
1 parent 248426c commit cc088a0
Show file tree
Hide file tree
Showing 8 changed files with 185 additions and 13 deletions.
21 changes: 21 additions & 0 deletions src/components/space-invitation-form/SpaceInvitationForm.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.space-invitation-form {
display: flex;
padding: 0 $spacing-unit/2;

&__input {
width: 100%;
margin: 0;
}

.bimdata-btn {
margin: 0 $spacing-unit/3;
}

&__submit-btn {
color: $color-success;
}

&__close-btn {
color: $color-high;
}
}
93 changes: 93 additions & 0 deletions src/components/space-invitation-form/SpaceInvitationForm.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<template>
<div class="space-invitation-form">
<BIMDataInput
ref="emailInput"
class="space-invitation-form__input"
:placeholder="$t('SpaceInvitationForm.inputEmail')"
v-model="email"
:error="error"
:errorMessage="$t('SpaceInvitationForm.errorMessage')"
@keyup.enter.stop="inviteUser"
/>
<BIMDataButton
class="space-invitation-form__submit-btn"
ghost
rounded
icon
@click="inviteUser"
>
<BIMDataIcon name="validate" size="xxs" />
</BIMDataButton>
<BIMDataButton
class="space-invitation-form__close-btn"
ghost
rounded
icon
@click="close"
>
<BIMDataIcon name="close" size="xxs" />
</BIMDataButton>
</div>
</template>

<script>
import { onMounted, ref } from "vue";
import { useSpaces } from "@/state/spaces";
// Components
import BIMDataButton from "@bimdata/design-system/dist/js/BIMDataComponents/vue3/BIMDataButton.js";
import BIMDataIcon from "@bimdata/design-system/dist/js/BIMDataComponents/vue3/BIMDataIcon.js";
import BIMDataInput from "@bimdata/design-system/dist/js/BIMDataComponents/vue3/BIMDataInput.js";
export default {
components: {
BIMDataButton,
BIMDataIcon,
BIMDataInput
},
props: {
space: {
type: Object,
required: true
}
},
emits: ["close", "success", "error"],
setup(props, { emit }) {
const { inviteSpaceUser } = useSpaces();
const emailInput = ref(null);
const email = ref("");
const error = ref(false);
const inviteUser = () => {
if (email.value) {
inviteSpaceUser(props.space, email.value)
.then(() => emit("success"))
.catch(error => emit("error", error));
} else {
emailInput.value.focus();
error.value = true;
}
};
const close = () => {
error.value = false;
emit("close");
};
onMounted(() => {
setTimeout(() => emailInput.value.focus(), 200);
});
return {
// References
email,
emailInput,
error,
// Methods
close,
inviteUser
};
}
};
</script>

<style scoped lang="scss" src="./SpaceInvitationForm.scss"></style>
4 changes: 3 additions & 1 deletion src/components/space-update-form/SpaceUpdateForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ export default {
emit("close");
};
onMounted(() => setTimeout(() => nameInput.value.focus(), 400));
onMounted(() => {
setTimeout(() => nameInput.value.focus(), 400);
});
return {
// References
Expand Down
40 changes: 36 additions & 4 deletions src/components/space-users-manager/SpaceUsersManager.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,35 @@
:selected="0"
@tab-click="swicthUserList"
/>

<BIMDataSearch
width="100%"
:placeholder="$t('SpaceUsersManager.searchUsers')"
v-model="searchText"
clear
/>
<BIMDataButton outline radius icon color="primary">
<BIMDataIcon name="plus" size="xxxs" />
<span>{{ $t("SpaceUsersManager.addUserButton") }}</span>
</BIMDataButton>

<transition name="fade" mode="out-in">
<SpaceInvitationForm
v-if="showInvitationForm"
:space="space"
@close="closeInvitationForm"
@success="closeInvitationForm"
/>

<BIMDataButton
v-else
outline
radius
icon
color="primary"
@click="openInvitationForm"
>
<BIMDataIcon name="plus" size="xxxs" />
<span>{{ $t("SpaceUsersManager.addUserButton") }}</span>
</BIMDataButton>
</transition>

<div class="list-container">
<transition-group name="item-list">
<UserCard v-for="user in displayedUsers" :key="user.id" :user="user" />
Expand All @@ -34,6 +53,7 @@ import BIMDataButton from "@bimdata/design-system/dist/js/BIMDataComponents/vue3
import BIMDataIcon from "@bimdata/design-system/dist/js/BIMDataComponents/vue3/BIMDataIcon.js";
import BIMDataSearch from "@bimdata/design-system/dist/js/BIMDataComponents/vue3/BIMDataSearch.js";
import BIMDataTabs from "@bimdata/design-system/dist/js/BIMDataComponents/vue3/BIMDataTabs.js";
import SpaceInvitationForm from "@/components/space-invitation-form/SpaceInvitationForm";
import UserCard from "@/components/user-card/UserCard";
export default {
Expand All @@ -42,6 +62,7 @@ export default {
BIMDataIcon,
BIMDataSearch,
BIMDataTabs,
SpaceInvitationForm,
UserCard
},
setup() {
Expand Down Expand Up @@ -82,13 +103,24 @@ export default {
};
watchEffect(() => filterUsers(searchText.value));
const showInvitationForm = ref(false);
const openInvitationForm = () => {
showInvitationForm.value = true;
};
const closeInvitationForm = () => {
showInvitationForm.value = false;
};
return {
// Refrences
displayedUsers,
searchText,
showInvitationForm,
space: currentSpace,
tabs,
// Methods
closeInvitationForm,
openInvitationForm,
swicthUserList
};
}
Expand Down
4 changes: 4 additions & 0 deletions src/i18n/lang/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,9 @@ export default {
title: "Manage space admins",
searchUsers: "Search user",
addUserButton: "Add new admin"
},
SpaceInvitationForm: {
inputEmail: "Enter email",
errorMessage: "Invalid email"
}
};
4 changes: 4 additions & 0 deletions src/i18n/lang/fr.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,9 @@ export default {
title: "Gestion administrateur espace",
searchUsers: "Rechercher un utilisateur",
addUserButton: "Ajouter un utilisateur"
},
SpaceInvitationForm: {
inputEmail: "Email de l'utilisateur",
errorMessage: "Email invalide"
}
};
10 changes: 10 additions & 0 deletions src/server/SpaceService.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ class SpaceService {
id: space.id
});
}

inviteSpaceUser(space, email) {
return apiClient.collaborationApi.inviteCloudUser({
cloudPk: space.id,
data: {
email,
redirectUri: `${process.env.VUE_APP_BASE_URL}/spaces/${space.id}`
}
});
}
}

const service = new SpaceService();
Expand Down
22 changes: 14 additions & 8 deletions src/state/spaces.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { reactive, readonly, toRefs } from "vue";
import SpacesService from "@/server/SpaceService";
import SpaceService from "@/server/SpaceService";

const state = reactive({
spaces: [],
Expand All @@ -9,25 +9,25 @@ const state = reactive({
});

const loadSpaces = async () => {
state.spaces = await SpacesService.fetchUserSpaces();
state.spaces = await SpaceService.fetchUserSpaces();
return state.spaces;
};

const loadSpaceUsers = async space => {
const users = await SpacesService.fetchSpaceUsers(space);
const users = await SpaceService.fetchSpaceUsers(space);
state.currentSpaceAdmins = users.filter(u => u.cloudRole === 100);
state.currentSpaceUsers = users.filter(u => u.cloudRole === 50);
return users;
};

const createSpace = async space => {
const newSpace = await SpacesService.createSpace(space);
const newSpace = await SpaceService.createSpace(space);
state.spaces = [newSpace].concat(state.spaces);
return newSpace;
};

const updateSpace = async space => {
const newSpace = await SpacesService.updateSpace(space);
const newSpace = await SpaceService.updateSpace(space);
softUpdateSpace(newSpace);
return newSpace;
};
Expand All @@ -37,13 +37,13 @@ const softUpdateSpace = space => {
};

const removeSpaceImage = async space => {
const newSpace = await SpacesService.removeSpaceImage(space);
const newSpace = await SpaceService.removeSpaceImage(space);
softUpdateSpace(newSpace);
return newSpace;
};

const deleteSpace = async space => {
await SpacesService.deleteSpace(space);
await SpaceService.deleteSpace(space);
state.spaces = state.spaces.filter(s => s.id !== space.id);
return space;
};
Expand All @@ -53,6 +53,11 @@ const selectSpace = id => {
return state.currentSpace;
};

const inviteSpaceUser = async (space, email) => {
const invitation = await SpaceService.inviteSpaceUser(space, email);
return invitation;
};

export function useSpaces() {
const readonlyState = readonly(state);
return {
Expand All @@ -64,6 +69,7 @@ export function useSpaces() {
softUpdateSpace,
removeSpaceImage,
deleteSpace,
selectSpace
selectSpace,
inviteSpaceUser
};
}

0 comments on commit cc088a0

Please sign in to comment.