chore: split app to commons and web (squash commit)
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
<template>
|
||||
<div
|
||||
tabindex="0"
|
||||
class="relative flex items-center justify-center cursor-pointer focus:outline-none focus-visible:ring focus-visible:ring-primaryDark"
|
||||
:class="[`rounded-${rounded}`, `w-${size} h-${size}`]"
|
||||
>
|
||||
<img
|
||||
v-if="url"
|
||||
class="absolute object-cover object-center transition bg-primaryDark"
|
||||
:class="[`rounded-${rounded}`, `w-${size} h-${size}`]"
|
||||
:src="url"
|
||||
:alt="alt"
|
||||
loading="lazy"
|
||||
/>
|
||||
<div
|
||||
v-else
|
||||
class="absolute flex items-center justify-center object-cover object-center transition bg-primaryDark text-accentContrast"
|
||||
:class="[`rounded-${rounded}`, `w-${size} h-${size}`]"
|
||||
:style="`background-color: ${initial ? toHex(initial) : '#480000'}`"
|
||||
>
|
||||
<template v-if="initial && initial.charAt(0).toUpperCase()">
|
||||
{{ initial.charAt(0).toUpperCase() }}
|
||||
</template>
|
||||
|
||||
<icon-lucide-user v-else></icon-lucide-user>
|
||||
</div>
|
||||
<span
|
||||
v-if="indicator"
|
||||
class="border-primary border-2 h-2.5 -top-0.5 -right-0.5 w-2.5 absolute"
|
||||
:class="[`rounded-${rounded}`, indicatorStyles]"
|
||||
></span>
|
||||
<!-- w-5 h-5 rounded-lg -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, PropType } from "vue"
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
url: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
alt: {
|
||||
type: String,
|
||||
default: "Profile picture",
|
||||
},
|
||||
indicator: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
indicatorStyles: {
|
||||
type: String,
|
||||
default: "bg-green-500",
|
||||
},
|
||||
rounded: {
|
||||
type: String,
|
||||
default: "full",
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: "5",
|
||||
},
|
||||
initial: {
|
||||
type: String as PropType<string | undefined | null>,
|
||||
default: "",
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
toHex(initial: string) {
|
||||
let hash = 0
|
||||
if (initial.length === 0) return hash
|
||||
for (let i = 0; i < initial.length; i++) {
|
||||
hash = initial.charCodeAt(i) + ((hash << 5) - hash)
|
||||
hash = hash & hash
|
||||
}
|
||||
let color = "#"
|
||||
for (let i = 0; i < 3; i++) {
|
||||
const value = (hash >> (i * 8)) & 255
|
||||
color += `00${value.toString(16)}`.slice(-2)
|
||||
}
|
||||
return color
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
122
packages/hoppscotch-common/src/components/profile/Shortcode.vue
Normal file
122
packages/hoppscotch-common/src/components/profile/Shortcode.vue
Normal file
@@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<div
|
||||
class="block w-full my-6 border divide-y lg:flex lg:my-0 lg:border-0 lg:divide-y-0 lg:divide-x divide-dividerLight border-dividerLight"
|
||||
>
|
||||
<div class="font-mono text-tiny table-box">
|
||||
{{ shortcode.id }}
|
||||
</div>
|
||||
<div class="table-box" :class="requestLabelColor">
|
||||
{{ parseShortcodeRequest.method }}
|
||||
</div>
|
||||
<div class="table-box">
|
||||
{{ parseShortcodeRequest.endpoint }}
|
||||
</div>
|
||||
<div ref="timeStampRef" class="table-box">
|
||||
{{ dateStamp }}
|
||||
</div>
|
||||
<div class="justify-center table-box">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.open_workspace')"
|
||||
:to="`${shortcodeBaseURL}/r/${shortcode.id}`"
|
||||
blank
|
||||
:icon="IconExternalLink"
|
||||
class="px-3 text-accent hover:text-accent"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.copy')"
|
||||
color="green"
|
||||
:icon="copyIconRefs"
|
||||
class="px-3"
|
||||
@click="copyShortcode(shortcode.id)"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.delete')"
|
||||
:icon="IconTrash"
|
||||
color="red"
|
||||
class="px-3"
|
||||
@click="deleteShortcode(shortcode.id)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from "vue"
|
||||
import { pipe } from "fp-ts/function"
|
||||
import * as RR from "fp-ts/ReadonlyRecord"
|
||||
import * as O from "fp-ts/Option"
|
||||
import { translateToNewRequest } from "@hoppscotch/data"
|
||||
import { refAutoReset } from "@vueuse/core"
|
||||
import { useI18n } from "@composables/i18n"
|
||||
import { useToast } from "@composables/toast"
|
||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||
import { Shortcode } from "~/helpers/shortcodes/Shortcode"
|
||||
import { shortDateTime } from "~/helpers/utils/date"
|
||||
|
||||
import IconTrash from "~icons/lucide/trash"
|
||||
import IconExternalLink from "~icons/lucide/external-link"
|
||||
import IconCopy from "~icons/lucide/copy"
|
||||
import IconCheck from "~icons/lucide/check"
|
||||
|
||||
const t = useI18n()
|
||||
const toast = useToast()
|
||||
|
||||
const props = defineProps<{
|
||||
shortcode: Shortcode
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "delete-shortcode", codeID: string): void
|
||||
}>()
|
||||
|
||||
const deleteShortcode = (codeID: string) => {
|
||||
emit("delete-shortcode", codeID)
|
||||
}
|
||||
|
||||
const requestMethodLabels = {
|
||||
get: "text-green-500",
|
||||
post: "text-yellow-500",
|
||||
put: "text-blue-500",
|
||||
delete: "text-red-500",
|
||||
default: "text-gray-500",
|
||||
} as const
|
||||
|
||||
const timeStampRef = ref()
|
||||
|
||||
const copyIconRefs = refAutoReset<typeof IconCopy | typeof IconCheck>(
|
||||
IconCopy,
|
||||
1000
|
||||
)
|
||||
|
||||
const parseShortcodeRequest = computed(() =>
|
||||
pipe(props.shortcode.request, JSON.parse, translateToNewRequest)
|
||||
)
|
||||
|
||||
const requestLabelColor = computed(() =>
|
||||
pipe(
|
||||
requestMethodLabels,
|
||||
RR.lookup(parseShortcodeRequest.value.method.toLowerCase()),
|
||||
O.getOrElseW(() => requestMethodLabels.default)
|
||||
)
|
||||
)
|
||||
|
||||
const dateStamp = computed(() => shortDateTime(props.shortcode.createdOn))
|
||||
|
||||
const shortcodeBaseURL =
|
||||
import.meta.env.VITE_SHORTCODE_BASE_URL ?? "https://hopp.sh"
|
||||
|
||||
const copyShortcode = (codeID: string) => {
|
||||
copyToClipboard(`${shortcodeBaseURL}/r/${codeID}`)
|
||||
toast.success(`${t("state.copied_to_clipboard")}`)
|
||||
copyIconRefs.value = IconCheck
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.table-box {
|
||||
@apply flex flex-1 items-center px-4 py-1 truncate;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user