fix: admin dashboard bugs (#74)
This commit is contained in:
committed by
GitHub
parent
a33337ae0c
commit
e54f837b83
@@ -25,9 +25,7 @@ declare module '@vue/runtime-core' {
|
|||||||
IconLucideArrowLeft: typeof import('~icons/lucide/arrow-left')['default']
|
IconLucideArrowLeft: typeof import('~icons/lucide/arrow-left')['default']
|
||||||
IconLucideChevronDown: typeof import('~icons/lucide/chevron-down')['default']
|
IconLucideChevronDown: typeof import('~icons/lucide/chevron-down')['default']
|
||||||
IconLucideInbox: typeof import('~icons/lucide/inbox')['default']
|
IconLucideInbox: typeof import('~icons/lucide/inbox')['default']
|
||||||
IconLucideMoreHorizontal: typeof import('~icons/lucide/more-horizontal')['default']
|
|
||||||
IconLucideUser: typeof import('~icons/lucide/user')['default']
|
IconLucideUser: typeof import('~icons/lucide/user')['default']
|
||||||
IconLucideUsers: typeof import('~icons/lucide/users')['default']
|
|
||||||
ProfilePicture: typeof import('./components/profile/Picture.vue')['default']
|
ProfilePicture: typeof import('./components/profile/Picture.vue')['default']
|
||||||
TeamsInvite: typeof import('./components/teams/Invite.vue')['default']
|
TeamsInvite: typeof import('./components/teams/Invite.vue')['default']
|
||||||
TeamsMembers: typeof import('./components/teams/Members.vue')['default']
|
TeamsMembers: typeof import('./components/teams/Members.vue')['default']
|
||||||
|
|||||||
@@ -22,12 +22,17 @@
|
|||||||
:key="`new-member-${index}`"
|
:key="`new-member-${index}`"
|
||||||
class="flex divide-x divide-dividerLight"
|
class="flex divide-x divide-dividerLight"
|
||||||
>
|
>
|
||||||
<input
|
<HoppSmartAutoComplete
|
||||||
v-model="member.key"
|
v-model="member.key"
|
||||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
|
||||||
placeholder="Email"
|
placeholder="Email"
|
||||||
|
:source="allUsersEmail"
|
||||||
:name="'member' + index"
|
:name="'member' + index"
|
||||||
autofocus
|
:spellcheck="true"
|
||||||
|
styles="
|
||||||
|
w-full pl-3 bg-neutral-900 border-gray-600
|
||||||
|
"
|
||||||
|
class="flex-1 !flex"
|
||||||
|
@input="(email: string) => member.key = email"
|
||||||
/>
|
/>
|
||||||
<span>
|
<span>
|
||||||
<tippy
|
<tippy
|
||||||
@@ -195,15 +200,33 @@ import { pipe } from 'fp-ts/function';
|
|||||||
import {
|
import {
|
||||||
AddUserToTeamByAdminDocument,
|
AddUserToTeamByAdminDocument,
|
||||||
TeamMemberRole,
|
TeamMemberRole,
|
||||||
|
MetricsDocument,
|
||||||
|
UsersListDocument,
|
||||||
} from '../../helpers/backend/graphql';
|
} from '../../helpers/backend/graphql';
|
||||||
import { useToast } from '~/composables/toast';
|
import { useToast } from '~/composables/toast';
|
||||||
import { useMutation } from '@urql/vue';
|
import { useMutation, useQuery } from '@urql/vue';
|
||||||
import { Email, EmailCodec } from '~/helpers/backend/Email';
|
import { Email, EmailCodec } from '~/helpers/backend/Email';
|
||||||
import IconTrash from '~icons/lucide/trash';
|
import IconTrash from '~icons/lucide/trash';
|
||||||
import IconPlus from '~icons/lucide/plus';
|
import IconPlus from '~icons/lucide/plus';
|
||||||
import IconHelpCircle from '~icons/lucide/help-circle';
|
import IconHelpCircle from '~icons/lucide/help-circle';
|
||||||
import IconCircleDot from '~icons/lucide/circle-dot';
|
import IconCircleDot from '~icons/lucide/circle-dot';
|
||||||
import IconCircle from '~icons/lucide/circle';
|
import IconCircle from '~icons/lucide/circle';
|
||||||
|
import { computed } from 'vue';
|
||||||
|
import { usePagedQuery } from '~/composables/usePagedQuery';
|
||||||
|
|
||||||
|
// Get Users List
|
||||||
|
const { data } = useQuery({ query: MetricsDocument });
|
||||||
|
const usersPerPage = computed(() => data.value?.admin.usersCount || 10000);
|
||||||
|
|
||||||
|
const { list: usersList } = usePagedQuery(
|
||||||
|
UsersListDocument,
|
||||||
|
(x) => x.admin.allUsers,
|
||||||
|
(x) => x.uid,
|
||||||
|
usersPerPage.value,
|
||||||
|
{ cursor: undefined, take: usersPerPage.value }
|
||||||
|
);
|
||||||
|
|
||||||
|
const allUsersEmail = computed(() => usersList.value.map((user) => user.email));
|
||||||
|
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
|
||||||
@@ -298,7 +321,6 @@ const addUserToTeam = async (
|
|||||||
.executeMutation(variables)
|
.executeMutation(variables)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
console.log(result.error);
|
|
||||||
if (result.error.toString() == '[GraphQL] user/not_found') {
|
if (result.error.toString() == '[GraphQL] user/not_found') {
|
||||||
toast.error('User not found in the infra!!');
|
toast.error('User not found in the infra!!');
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ import IconUserPlus from '~icons/lucide/user-plus';
|
|||||||
import IconUserMinus from '~icons/lucide/user-minus';
|
import IconUserMinus from '~icons/lucide/user-minus';
|
||||||
import IconHelpCircle from '~icons/lucide/help-circle';
|
import IconHelpCircle from '~icons/lucide/help-circle';
|
||||||
import { useClientHandle, useMutation } from '@urql/vue';
|
import { useClientHandle, useMutation } from '@urql/vue';
|
||||||
import { computed, onMounted, ref, watch } from 'vue';
|
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { useToast } from '../../composables/toast';
|
import { useToast } from '../../composables/toast';
|
||||||
import {
|
import {
|
||||||
@@ -195,9 +195,12 @@ const getTeamInfo = async () => {
|
|||||||
fetching.value = false;
|
fetching.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(async () => {
|
const emit = defineEmits<{
|
||||||
await getTeamInfo();
|
(e: 'update-team'): void;
|
||||||
});
|
}>();
|
||||||
|
|
||||||
|
onMounted(async () => await getTeamInfo());
|
||||||
|
onUnmounted(() => emit('update-team'));
|
||||||
|
|
||||||
// Update members tab after a change in the members list or member roles
|
// Update members tab after a change in the members list or member roles
|
||||||
const updateMembers = () => getTeamInfo();
|
const updateMembers = () => getTeamInfo();
|
||||||
|
|||||||
@@ -96,9 +96,7 @@ const getTeamInfo = async () => {
|
|||||||
fetching.value = false;
|
fetching.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => await getTeamInfo());
|
||||||
await getTeamInfo();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Remove Invitation
|
// Remove Invitation
|
||||||
const isLoadingIndex = ref<null | number>(null);
|
const isLoadingIndex = ref<null | number>(null);
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import { auth } from './helpers/auth';
|
|||||||
urql,
|
urql,
|
||||||
createClient({
|
createClient({
|
||||||
url: import.meta.env.VITE_BACKEND_GQL_URL,
|
url: import.meta.env.VITE_BACKEND_GQL_URL,
|
||||||
|
requestPolicy: 'network-only',
|
||||||
fetchOptions: () => {
|
fetchOptions: () => {
|
||||||
return {
|
return {
|
||||||
credentials: 'include',
|
credentials: 'include',
|
||||||
@@ -33,4 +34,4 @@ import { auth } from './helpers/auth';
|
|||||||
HOPP_MODULES.forEach((mod) => mod.onVueAppInit?.(app));
|
HOPP_MODULES.forEach((mod) => mod.onVueAppInit?.(app));
|
||||||
|
|
||||||
app.mount('#app');
|
app.mount('#app');
|
||||||
})()
|
})();
|
||||||
|
|||||||
@@ -120,7 +120,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="team" class="sm:px-6 px-4">
|
<div v-if="team" class="sm:px-6 px-4">
|
||||||
<TeamsMembers v-if="showMembers" />
|
<TeamsMembers v-if="showMembers" @updateTeam="updateTeam()" />
|
||||||
<TeamsPendingInvites v-if="showPendingInvites" :editingTeamID="team.id" />
|
<TeamsPendingInvites v-if="showPendingInvites" :editingTeamID="team.id" />
|
||||||
<HoppSmartConfirmModal
|
<HoppSmartConfirmModal
|
||||||
:show="confirmDeletion"
|
:show="confirmDeletion"
|
||||||
@@ -193,9 +193,8 @@ const getTeamInfo = async () => {
|
|||||||
fetching.value = false;
|
fetching.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => await getTeamInfo());
|
||||||
await getTeamInfo();
|
const updateTeam = async () => await getTeamInfo();
|
||||||
});
|
|
||||||
|
|
||||||
// Rename the team name
|
// Rename the team name
|
||||||
const showRenameInput = ref(false);
|
const showRenameInput = ref(false);
|
||||||
|
|||||||
@@ -245,22 +245,31 @@ const showCreateTeamModal = ref(false);
|
|||||||
const getOwnerEmail = (email: string) => (ownerEmail.value = email);
|
const getOwnerEmail = (email: string) => (ownerEmail.value = email);
|
||||||
|
|
||||||
const createTeam = async () => {
|
const createTeam = async () => {
|
||||||
|
if (teamName.value.length < 6) {
|
||||||
|
toast.error('Team name should be atleast 6 characters long!!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ownerEmail.value.length == 0) {
|
||||||
|
toast.error('Please enter email of team owner!!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
const userUid =
|
const userUid =
|
||||||
usersList.value.find((user) => user.email === ownerEmail.value)?.uid || '';
|
usersList.value.find((user) => user.email === ownerEmail.value)?.uid || '';
|
||||||
const variables = { name: teamName.value.trim(), userUid: userUid };
|
const variables = { name: teamName.value.trim(), userUid: userUid };
|
||||||
await createTeamMutation.executeMutation(variables).then((result) => {
|
await createTeamMutation.executeMutation(variables).then((result) => {
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
if (teamName.value.length < 6) {
|
|
||||||
toast.error('Team name should be atleast 6 characters long!!');
|
|
||||||
}
|
|
||||||
if (result.error.toString() == '[GraphQL] user/not_found') {
|
if (result.error.toString() == '[GraphQL] user/not_found') {
|
||||||
toast.error('User not found!!');
|
toast.error('User not found!!');
|
||||||
} else {
|
} else {
|
||||||
toast.error('Failed to create team!!');
|
toast.error('Failed to create team!!');
|
||||||
}
|
}
|
||||||
|
teamName.value = '';
|
||||||
|
ownerEmail.value = '';
|
||||||
} else {
|
} else {
|
||||||
toast.success('Team created successfully!!');
|
toast.success('Team created successfully!!');
|
||||||
showCreateTeamModal.value = false;
|
showCreateTeamModal.value = false;
|
||||||
|
teamName.value = '';
|
||||||
|
ownerEmail.value = '';
|
||||||
refetch();
|
refetch();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ import path from 'path';
|
|||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
envDir: path.resolve(__dirname, "../../"),
|
envDir: path.resolve(__dirname, '../../'),
|
||||||
server: {
|
server: {
|
||||||
port: 3000,
|
port: 3100,
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
|
|||||||
Reference in New Issue
Block a user