diff --git a/packages/hoppscotch-common/src/components.d.ts b/packages/hoppscotch-common/src/components.d.ts
index f4d4b2e39..b1c4080b5 100644
--- a/packages/hoppscotch-common/src/components.d.ts
+++ b/packages/hoppscotch-common/src/components.d.ts
@@ -5,7 +5,7 @@
// Read more: https://github.com/vuejs/core/pull/3399
export {}
-declare module 'vue' {
+declare module "vue" {
export interface GlobalComponents {
AppActionHandler: typeof import('./components/app/ActionHandler.vue')['default']
AppAnnouncement: typeof import('./components/app/Announcement.vue')['default']
diff --git a/packages/hoppscotch-sh-admin/locales/en.json b/packages/hoppscotch-sh-admin/locales/en.json
index 0ddbc8e48..8ee46d30b 100644
--- a/packages/hoppscotch-sh-admin/locales/en.json
+++ b/packages/hoppscotch-sh-admin/locales/en.json
@@ -98,9 +98,10 @@
"load_info_error": "Unable to load team info",
"load_list_error": "Unable to Load Teams List",
"members": "Number of members",
- "name": "Team name",
+ "name": "Team Name",
"no_members": "No members in this team. Add members to this team to collaborate",
"no_pending_invites": "No pending invites",
+ "no_teams": "No teams found",
"pending_invites": "Pending invites",
"remove": "Remove",
"rename": "Rename",
@@ -112,6 +113,7 @@
"team_members_tab": "Team members",
"teams": "Teams",
"uid": "UID",
+ "unnamed": "(Unnamed Team)",
"valid_name": "Please enter a valid team name",
"valid_owner_email": "Please enter a valid owner email"
},
@@ -125,6 +127,7 @@
"created_on": "Created On",
"date": "Date",
"delete": "Delete",
+ "delete_user": "Delete User",
"email": "Email",
"email_address": "Email Address",
"id": "User ID",
@@ -136,6 +139,7 @@
"load_info_error": "Unable to load user info",
"load_list_error": "Unable to Load Users List",
"make_admin": "Make admin",
+ "invite_load_list_error": "Unable to Load Invited Users List",
"name": "Name",
"no_invite": "No invited users found",
"no_users": "No users found",
diff --git a/packages/hoppscotch-sh-admin/src/components.d.ts b/packages/hoppscotch-sh-admin/src/components.d.ts
index 953862949..418a20579 100644
--- a/packages/hoppscotch-sh-admin/src/components.d.ts
+++ b/packages/hoppscotch-sh-admin/src/components.d.ts
@@ -1,44 +1,71 @@
// generated by unplugin-vue-components
// We suggest you to commit this file into source control
// Read more: https://github.com/vuejs/core/pull/3399
-import '@vue/runtime-core';
+import '@vue/runtime-core'
-export {};
+export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
- AppHeader: typeof import('./components/app/Header.vue')['default'];
- AppLogin: typeof import('./components/app/Login.vue')['default'];
- AppLogout: typeof import('./components/app/Logout.vue')['default'];
- AppModal: typeof import('./components/app/Modal.vue')['default'];
- AppSidebar: typeof import('./components/app/Sidebar.vue')['default'];
- AppToast: typeof import('./components/app/Toast.vue')['default'];
- DashboardMetricsCard: typeof import('./components/dashboard/MetricsCard.vue')['default'];
- HoppButtonPrimary: typeof import('@hoppscotch/ui')['HoppButtonPrimary'];
- HoppButtonSecondary: typeof import('@hoppscotch/ui')['HoppButtonSecondary'];
- HoppSmartAnchor: typeof import('@hoppscotch/ui')['HoppSmartAnchor'];
- HoppSmartAutoComplete: typeof import('@hoppscotch/ui')['HoppSmartAutoComplete'];
- HoppSmartConfirmModal: typeof import('@hoppscotch/ui')['HoppSmartConfirmModal'];
- HoppSmartInput: typeof import('@hoppscotch/ui')['HoppSmartInput'];
- HoppSmartItem: typeof import('@hoppscotch/ui')['HoppSmartItem'];
- HoppSmartModal: typeof import('@hoppscotch/ui')['HoppSmartModal'];
- HoppSmartPicture: typeof import('@hoppscotch/ui')['HoppSmartPicture'];
- HoppSmartPlaceholder: typeof import('@hoppscotch/ui')['HoppSmartPlaceholder'];
- HoppSmartSpinner: typeof import('@hoppscotch/ui')['HoppSmartSpinner'];
- HoppSmartTab: typeof import('@hoppscotch/ui')['HoppSmartTab'];
- IconLucideArrowLeft: typeof import('~icons/lucide/arrow-left')['default'];
- IconLucideChevronDown: typeof import('~icons/lucide/chevron-down')['default'];
- IconLucideHelpCircle: typeof import('~icons/lucide/help-circle')['default'];
- IconLucideInbox: typeof import('~icons/lucide/inbox')['default'];
- IconLucideUser: typeof import('~icons/lucide/user')['default'];
- TeamsAdd: typeof import('./components/teams/Add.vue')['default'];
- TeamsDetails: typeof import('./components/teams/Details.vue')['default'];
- TeamsInvite: typeof import('./components/teams/Invite.vue')['default'];
- TeamsMembers: typeof import('./components/teams/Members.vue')['default'];
- TeamsPendingInvites: typeof import('./components/teams/PendingInvites.vue')['default'];
- TeamsTable: typeof import('./components/teams/Table.vue')['default'];
- Tippy: typeof import('vue-tippy')['Tippy'];
- UsersInviteModal: typeof import('./components/users/InviteModal.vue')['default'];
- UsersTable: typeof import('./components/users/Table.vue')['default'];
+ AppHeader: typeof import('./components/app/Header.vue')['default']
+ AppLogin: typeof import('./components/app/Login.vue')['default']
+ AppLogout: typeof import('./components/app/Logout.vue')['default']
+ AppModal: typeof import('./components/app/Modal.vue')['default']
+ AppSidebar: typeof import('./components/app/Sidebar.vue')['default']
+ AppToast: typeof import('./components/app/Toast.vue')['default']
+ ButtonPrimary: typeof import('./../../hoppscotch-ui/src/components/button/Primary.vue')['default']
+ ButtonSecondary: typeof import('./../../hoppscotch-ui/src/components/button/Secondary.vue')['default']
+ DashboardMetricsCard: typeof import('./components/dashboard/MetricsCard.vue')['default']
+ HoppButtonPrimary: typeof import('@hoppscotch/ui')['HoppButtonPrimary']
+ HoppButtonSecondary: typeof import('@hoppscotch/ui')['HoppButtonSecondary']
+ HoppSmartAnchor: typeof import('@hoppscotch/ui')['HoppSmartAnchor']
+ HoppSmartAutoComplete: typeof import('@hoppscotch/ui')['HoppSmartAutoComplete']
+ HoppSmartConfirmModal: typeof import('@hoppscotch/ui')['HoppSmartConfirmModal']
+ HoppSmartInput: typeof import('@hoppscotch/ui')['HoppSmartInput']
+ HoppSmartItem: typeof import('@hoppscotch/ui')['HoppSmartItem']
+ HoppSmartModal: typeof import('@hoppscotch/ui')['HoppSmartModal']
+ HoppSmartPicture: typeof import('@hoppscotch/ui')['HoppSmartPicture']
+ HoppSmartPlaceholder: typeof import('@hoppscotch/ui')['HoppSmartPlaceholder']
+ HoppSmartSpinner: typeof import('@hoppscotch/ui')['HoppSmartSpinner']
+ HoppSmartTab: typeof import('@hoppscotch/ui')['HoppSmartTab']
+ HoppSmartTable: typeof import('@hoppscotch/ui')['HoppSmartTable']
+ IconLucideArrowLeft: typeof import('~icons/lucide/arrow-left')['default']
+ IconLucideChevronDown: typeof import('~icons/lucide/chevron-down')['default']
+ IconLucideHelpCircle: typeof import('~icons/lucide/help-circle')['default']
+ IconLucideInbox: typeof import('~icons/lucide/inbox')['default']
+ SmartAnchor: typeof import('./../../hoppscotch-ui/src/components/smart/Anchor.vue')['default']
+ SmartAutoComplete: typeof import('./../../hoppscotch-ui/src/components/smart/AutoComplete.vue')['default']
+ SmartCheckbox: typeof import('./../../hoppscotch-ui/src/components/smart/Checkbox.vue')['default']
+ SmartConfirmModal: typeof import('./../../hoppscotch-ui/src/components/smart/ConfirmModal.vue')['default']
+ SmartExpand: typeof import('./../../hoppscotch-ui/src/components/smart/Expand.vue')['default']
+ SmartFileChip: typeof import('./../../hoppscotch-ui/src/components/smart/FileChip.vue')['default']
+ SmartInput: typeof import('./../../hoppscotch-ui/src/components/smart/Input.vue')['default']
+ SmartIntersection: typeof import('./../../hoppscotch-ui/src/components/smart/Intersection.vue')['default']
+ SmartItem: typeof import('./../../hoppscotch-ui/src/components/smart/Item.vue')['default']
+ SmartLink: typeof import('./../../hoppscotch-ui/src/components/smart/Link.vue')['default']
+ SmartModal: typeof import('./../../hoppscotch-ui/src/components/smart/Modal.vue')['default']
+ SmartPicture: typeof import('./../../hoppscotch-ui/src/components/smart/Picture.vue')['default']
+ SmartPlaceholder: typeof import('./../../hoppscotch-ui/src/components/smart/Placeholder.vue')['default']
+ SmartProgressRing: typeof import('./../../hoppscotch-ui/src/components/smart/ProgressRing.vue')['default']
+ SmartRadio: typeof import('./../../hoppscotch-ui/src/components/smart/Radio.vue')['default']
+ SmartRadioGroup: typeof import('./../../hoppscotch-ui/src/components/smart/RadioGroup.vue')['default']
+ SmartSlideOver: typeof import('./../../hoppscotch-ui/src/components/smart/SlideOver.vue')['default']
+ SmartSpinner: typeof import('./../../hoppscotch-ui/src/components/smart/Spinner.vue')['default']
+ SmartTab: typeof import('./../../hoppscotch-ui/src/components/smart/Tab.vue')['default']
+ SmartTable: typeof import('./../../hoppscotch-ui/src/components/smart/Table.vue')['default']
+ SmartTabs: typeof import('./../../hoppscotch-ui/src/components/smart/Tabs.vue')['default']
+ SmartToggle: typeof import('./../../hoppscotch-ui/src/components/smart/Toggle.vue')['default']
+ SmartTree: typeof import('./../../hoppscotch-ui/src/components/smart/Tree.vue')['default']
+ SmartTreeBranch: typeof import('./../../hoppscotch-ui/src/components/smart/TreeBranch.vue')['default']
+ SmartWindow: typeof import('./../../hoppscotch-ui/src/components/smart/Window.vue')['default']
+ SmartWindows: typeof import('./../../hoppscotch-ui/src/components/smart/Windows.vue')['default']
+ TeamsAdd: typeof import('./components/teams/Add.vue')['default']
+ TeamsDetails: typeof import('./components/teams/Details.vue')['default']
+ TeamsInvite: typeof import('./components/teams/Invite.vue')['default']
+ TeamsMembers: typeof import('./components/teams/Members.vue')['default']
+ TeamsPendingInvites: typeof import('./components/teams/PendingInvites.vue')['default']
+ Tippy: typeof import('vue-tippy')['Tippy']
+ UsersInviteModal: typeof import('./components/users/InviteModal.vue')['default']
}
+
}
diff --git a/packages/hoppscotch-sh-admin/src/components/teams/Table.vue b/packages/hoppscotch-sh-admin/src/components/teams/Table.vue
deleted file mode 100644
index 5e26bbc05..000000000
--- a/packages/hoppscotch-sh-admin/src/components/teams/Table.vue
+++ /dev/null
@@ -1,102 +0,0 @@
-
-
-
-
- | Team ID |
- Team Name |
- Number of Members |
- |
-
-
-
-
-
- No teams found ...
-
-
- |
-
-
- {{ team.id }}
-
-
- |
-
-
-
- {{ team.name }}
-
- (Unnamed team)
- |
-
-
-
- {{ team.members?.length }}
-
- |
-
-
-
-
-
-
-
- {
- $emit('delete-team', team.id);
- hide();
- }
- "
- />
-
-
-
-
- |
-
-
-
-
-
-
diff --git a/packages/hoppscotch-sh-admin/src/components/users/Table.vue b/packages/hoppscotch-sh-admin/src/components/users/Table.vue
deleted file mode 100644
index 9e3c8d657..000000000
--- a/packages/hoppscotch-sh-admin/src/components/users/Table.vue
+++ /dev/null
@@ -1,162 +0,0 @@
-
-
-
-
- | {{ t('users.id') }} |
- {{ t('users.name') }} |
- {{ t('users.email') }} |
- {{ t('users.date') }} |
- |
-
-
-
-
-
- |
-
-
- {{ user.uid }}
-
-
- |
-
-
-
-
- {{ user.displayName }}
-
-
- {{ t('users.admin') }}
-
-
-
- {{ t('users.unnamed') }}
-
- {{ t('users.admin') }}
-
-
- |
-
-
-
- {{ user.email }}
-
- |
-
-
-
-
- {{ getCreatedDate(user.createdOn) }}
-
- {{ getCreatedTime(user.createdOn) }}
-
-
-
- |
-
-
-
-
-
-
-
-
- {
- $emit('makeUserAdmin', user.uid);
- hide();
- }
- "
- />
- {
- $emit('makeAdminToUser', user.uid);
- hide();
- }
- "
- />
- {
- $emit('deleteUser', user.uid);
- hide();
- }
- "
- />
-
-
-
-
-
- |
-
-
-
-
-
-
diff --git a/packages/hoppscotch-sh-admin/src/pages/teams/index.vue b/packages/hoppscotch-sh-admin/src/pages/teams/index.vue
index a51b75aca..8dcdbffaf 100644
--- a/packages/hoppscotch-sh-admin/src/pages/teams/index.vue
+++ b/packages/hoppscotch-sh-admin/src/pages/teams/index.vue
@@ -12,25 +12,90 @@
-
+
{{ t('teams.load_list_error') }}
-
+
+
+
+ | {{ t('teams.id') }} |
+ {{ t('teams.name') }} |
+ {{ t('teams.members') }} |
+
+ |
+
+
+
+
+ |
+
+ {{ team.id }}
+
+ |
+
+
+
+ {{ team.name ?? t('teams.unnamed') }}
+
+ |
+
+
+ {{ team.members?.length }}
+ |
+
+
+
+
+
+
+
+ {
+ deleteTeam(team.id);
+ hide();
+ }
+ "
+ />
+
+
+
+
+ |
+
+
+
+
+
+ {{ t('teams.no_teams') }}
+
@@ -66,10 +131,12 @@ import {
UsersListDocument,
} from '../../helpers/backend/graphql';
import { usePagedQuery } from '~/composables/usePagedQuery';
-import { ref, watch, computed } from 'vue';
+import { computed, ref, watch } from 'vue';
import { useMutation, useQuery } from '@urql/vue';
import { useToast } from '~/composables/toast';
import IconAddUsers from '~icons/lucide/plus';
+import IconTrash from '~icons/lucide/trash';
+import IconMoreHorizontal from '~icons/lucide/more-horizontal';
import { useI18n } from '~/composables/i18n';
const t = useI18n();
@@ -96,7 +163,7 @@ const {
error,
goToNextPage: fetchNextTeams,
refetch,
- list: teamList,
+ list: teamsList,
hasNextPage,
} = usePagedQuery(
TeamListDocument,
@@ -143,9 +210,7 @@ const createTeam = async (newTeamName: string, ownerEmail: string) => {
// Go To Individual Team Details Page
const router = useRouter();
-const goToTeamDetails = (teamId: string) => {
- router.push('/teams/' + teamId);
-};
+const goToTeamDetails = (teamId: string) => router.push('/teams/' + teamId);
// Reload Teams Page when routed back to the teams page
const route = useRoute();
@@ -175,7 +240,7 @@ const deleteTeamMutation = async (id: string | null) => {
if (result.error) {
toast.error(`${t('state.delete_team_failure')}`);
} else {
- teamList.value = teamList.value.filter((team) => team.id !== id);
+ teamsList.value = teamsList.value.filter((team) => team.id !== id);
toast.success(`${t('state.delete_team_success')}`);
}
});
diff --git a/packages/hoppscotch-sh-admin/src/pages/users/index.vue b/packages/hoppscotch-sh-admin/src/pages/users/index.vue
index 40c35d337..27ed25780 100644
--- a/packages/hoppscotch-sh-admin/src/pages/users/index.vue
+++ b/packages/hoppscotch-sh-admin/src/pages/users/index.vue
@@ -22,27 +22,118 @@
-
+
{{ t('users.load_list_error') }}
-
+
+
+
+ | {{ t('users.id') }} |
+ {{ t('users.name') }} |
+ {{ t('users.email') }} |
+ {{ t('users.date') }} |
+
+ |
+
+
- {{ t('users.no_users') }}
+
+
+ |
+ {{ user.uid }}
+ |
+
+
+
+
+ {{ user.displayName ?? t('users.unnamed') }}
+
+
+
+ {{ t('users.admin') }}
+
+
+ |
+
+
+ {{ user.email }}
+ |
+
+
+ {{ getCreatedDate(user.createdOn) }}
+
+ {{ getCreatedTime(user.createdOn) }}
+
+ |
+
+
+
+
+
+
+
+ {
+ user.isAdmin
+ ? makeAdminToUser(user.uid)
+ : makeUserAdmin(user.uid);
+ hide();
+ }
+ "
+ />
+ {
+ deleteUser(user.uid);
+ hide();
+ }
+ "
+ />
+
+
+
+
+ |
+
+
+
+
+
+ {{ t('users.no_users') }}
+
diff --git a/packages/hoppscotch-ui/src/components/smart/Table.vue b/packages/hoppscotch-ui/src/components/smart/Table.vue
new file mode 100644
index 000000000..ab283c83e
--- /dev/null
+++ b/packages/hoppscotch-ui/src/components/smart/Table.vue
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+ |
+ {{ th.label ?? th.key }}
+ |
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+ {{ rowData[cellHeading.key] ?? "-" }}
+
+
+
+ |
+
+
+
+
+
+
+
+
diff --git a/packages/hoppscotch-ui/src/components/smart/index.ts b/packages/hoppscotch-ui/src/components/smart/index.ts
index 157124566..81d04c985 100644
--- a/packages/hoppscotch-ui/src/components/smart/index.ts
+++ b/packages/hoppscotch-ui/src/components/smart/index.ts
@@ -16,6 +16,7 @@ export { default as HoppSmartSlideOver } from "./SlideOver.vue"
export { default as HoppSmartSpinner } from "./Spinner.vue"
export { default as HoppSmartTab } from "./Tab.vue"
export { default as HoppSmartTabs } from "./Tabs.vue"
+export { default as HoppSmartTable } from "./Table.vue"
export { default as HoppSmartToggle } from "./Toggle.vue"
export { default as HoppSmartWindow } from "./Window.vue"
export { default as HoppSmartWindows } from "./Windows.vue"
diff --git a/packages/hoppscotch-ui/src/stories/Table.story.vue b/packages/hoppscotch-ui/src/stories/Table.story.vue
new file mode 100644
index 000000000..d123a7bf9
--- /dev/null
+++ b/packages/hoppscotch-ui/src/stories/Table.story.vue
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+ |
+ {{ heading.label }}
+ |
+
+
+
+
+
+ |
+ {{ item[cellHeading.key] ?? "-" }}
+ |
+
+
+
+
+
+
+
+