Skip to content

Commit

Permalink
chore: address CR comments
Browse files Browse the repository at this point in the history
- Grid layout updates improving responsiveness.
- Reply on placeholder for the Label input element in the generate modal instead of a label appearing below.
- Add empty and error states for the access tokens list view.
- Cleanup

Co-authored-by: Nivedin <53208152+nivedin@users.noreply.github.com>
  • Loading branch information
jamesgeorge007 and nivedin committed Jun 5, 2024
1 parent b0cbfe9 commit 782b722
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 26 deletions.
6 changes: 4 additions & 2 deletions packages/hoppscotch-common/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,8 @@
"subscription": "Subscriptions are empty",
"team_name": "Workspace name empty",
"teams": "You don't belong to any workspaces",
"tests": "There are no tests for this request"
"tests": "There are no tests for this request",
"access_tokens": "Access tokens are empty"
},
"environment": {
"add_to_global": "Add to Global",
Expand Down Expand Up @@ -1056,6 +1057,7 @@
"no_expiration_verbose": "This token will never expire!",
"token_expires_on": "This token will expire on",
"generate_new_token": "Generate new token",
"generate_modal_title": "New Personal Access Token"
"generate_modal_title": "New Personal Access Token",
"deletion_success": "The access token {label} has been deleted"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,8 @@
</div>
<HoppSmartInput
v-model="accessTokenLabel"
placeholder=" "
class="floating-input"
:placeholder="t('access_tokens.token_purpose')"
/>
<div class="text-secondaryLight">
{{ t("access_tokens.token_purpose") }}
</div>
</div>

<div class="space-y-2">
Expand All @@ -48,7 +44,7 @@
interactive
trigger="click"
theme="popover"
:on-shown="tippyActions?.focus()"
:on-shown="() => tippyActions?.focus()"
>
<HoppSmartSelectWrapper>
<input
Expand Down Expand Up @@ -138,8 +134,8 @@
import { useI18n } from "@composables/i18n"
import { useToast } from "@composables/toast"
import { refAutoReset } from "@vueuse/core"
import { computed, ref } from "vue"
import { TippyComponent } from "vue-tippy"
import { VNodeRef, computed, ref } from "vue"
import { copyToClipboard } from "~/helpers/utils/clipboard"
import { shortDateTime } from "~/helpers/utils/date"
Expand All @@ -165,7 +161,7 @@ const emit = defineEmits<{
}>()
// Template refs
const tippyActions = ref<TippyComponent[] | null>(null)
const tippyActions = ref<VNodeRef | null>(null)
const copyIcon = refAutoReset<typeof IconCopy | typeof IconCheck>(
IconCopy,
Expand Down
38 changes: 33 additions & 5 deletions packages/hoppscotch-common/src/components/accessTokens/List.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,34 @@
<template>
<div class="grid gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
<div
v-if="hasError && !hasMoreTokens"
class="flex flex-col items-center py-4"
>
<icon-lucide-help-circle class="mb-4 svg-icons" />
{{ t("error.something_went_wrong") }}
</div>

<HoppSmartPlaceholder
v-else-if="accessTokens.length === 0"
:src="`/images/states/${colorMode}/pack.svg`"
:alt="`${t('empty.access_tokens')}`"
:text="t('empty.access_tokens')"
@drop.stop
/>

<div
v-else
class="grid gap-4 p-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"
>
<div
v-for="{ id, label, lastUsedOn, expiresOn } in accessTokens"
:key="id"
class="flex items-center justify-between p-4 border rounded md:items-baseline md:flex-col md:gap-4 md:justify-normal border-divider"
class="flex flex-col items-center gap-4 p-4 border rounded border-divider"
>
<div class="w-full text-sm font-semibold truncate text-secondaryDark">
{{ label }}
</div>

<div class="flex items-center gap-x-4">
<div class="flex items-center justify-between w-full gap-x-4">
<div class="space-y-1 text-secondaryLight">
<div class="space-x-1">
<span class="font-semibold"
Expand Down Expand Up @@ -53,23 +72,32 @@
v-if="hasMoreTokens"
@intersecting="emit('fetch-more-tokens')"
>
<div v-if="tokensListLoading" class="flex flex-col items-center py-3">
<div v-if="loading" class="flex flex-col items-center py-3">
<HoppSmartSpinner />
</div>

<div v-else-if="hasError" class="flex flex-col items-center py-4">
<icon-lucide-help-circle class="mb-4 svg-icons" />
{{ t("error.something_went_wrong") }}
</div>
</HoppSmartIntersection>
</template>

<script setup lang="ts">
import { useI18n } from "@composables/i18n"
import { useColorMode } from "@vueuse/core"
import { shortDateTime } from "~/helpers/utils/date"
import { AccessToken } from "~/pages/profile.vue"
const colorMode = useColorMode()
const t = useI18n()
defineProps<{
accessTokens: AccessToken[]
hasMoreTokens: boolean
tokensListLoading: boolean
loading: boolean
hasError: boolean
}>()
const emit = defineEmits<{
Expand Down
22 changes: 17 additions & 5 deletions packages/hoppscotch-common/src/components/accessTokens/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@

<AccessTokensList
:access-tokens="accessTokens"
:has-error="tokensListFetchErrored"
:has-more-tokens="hasMoreTokens"
:tokens-list-loading="tokensListLoading"
:loading="tokensListLoading"
@delete-access-token="displayDeleteAccessTokenConfirmationModal"
@fetch-more-tokens="fetchAccessTokens"
/>
Expand All @@ -26,7 +27,7 @@
t('confirm.delete_access_token', { tokenLabel: tokenToDelete?.label })
"
@hide-modal="confirmDeleteAccessToken = false"
@resolve="() => deleteAccessToken()"
@resolve="deleteAccessToken"
/>
</template>
Expand All @@ -50,10 +51,11 @@ const t = useI18n()
const toast = useToast()
const confirmDeleteAccessToken = ref(false)
const hasMoreTokens = ref(true)
const hasMoreTokens = ref(false)
const showAccessTokensGenerateModal = ref(false)
const tokenDeleteActionLoading = ref(false)
const tokenGenerateActionLoading = ref(false)
const tokensListFetchErrored = ref(false)
const tokensListLoading = ref(false)
const accessToken: Ref<string | null> = ref(null)
Expand Down Expand Up @@ -90,8 +92,13 @@ const fetchAccessTokens = async () => {
}
hasMoreTokens.value = data.length === limit
if (tokensListFetchErrored.value) {
tokensListFetchErrored.value = false
}
} catch (err) {
toast.error(t("error.fetching_access_tokens_list"))
tokensListFetchErrored.value = true
} finally {
tokensListLoading.value = false
}
Expand Down Expand Up @@ -126,18 +133,19 @@ const generateAccessToken = async ({
offset += 1
} catch (err) {
toast.error(t("error.generate_access_token"))
showAccessTokensGenerateModal.value = false
} finally {
tokenGenerateActionLoading.value = false
}
}
const deleteAccessToken = async () => {
if (tokenToDelete.value === null) {
toast.error("error.something_went_wrong")
toast.error(t("error.something_went_wrong"))
return
}
const { id: tokenIdToDelete } = tokenToDelete.value
const { id: tokenIdToDelete, label: tokenLabelToDelete } = tokenToDelete.value
tokenDeleteActionLoading.value = true
Expand All @@ -154,6 +162,10 @@ const deleteAccessToken = async () => {
// Decreasing the offset value by 1 to account for the deleted token
offset = offset > 0 ? offset - 1 : offset
toast.success(
t("access_tokens.deletion_success", { label: tokenLabelToDelete })
)
} catch (err) {
toast.error(t("error.delete_access_token"))
} finally {
Expand Down
6 changes: 1 addition & 5 deletions packages/hoppscotch-common/src/pages/profile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,7 @@
<Teams :modal="false" class="p-4" />
</HoppSmartTab>
<HoppSmartTab
id="tokens"
:label="t('access_tokens.tab_title')"
class="space-y-4"
>
<HoppSmartTab id="tokens" :label="t('access_tokens.tab_title')">
<AccessTokens />
</HoppSmartTab>
</HoppSmartTabs>
Expand Down

0 comments on commit 782b722

Please sign in to comment.