Skip to content

Commit

Permalink
feat(notifications): add entity dialog
Browse files Browse the repository at this point in the history
See: BEDS-565
  • Loading branch information
marcel-bitfly committed Oct 17, 2024
1 parent 76a3f00 commit d55ea52
Show file tree
Hide file tree
Showing 11 changed files with 833 additions and 43 deletions.
144 changes: 144 additions & 0 deletions frontend/components/bc/BcAccordion.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
<script setup lang="ts" generic="T">
import { faCopy } from '@fortawesome/pro-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
const props = defineProps<{
infoCopy?: string,
items?: T[],
open?: boolean,
}>()
const isOpen = ref(props.open ?? false)
const {
copy,
isSupported,
} = useClipboard()
const idList = useId()
const textToCopy = ref<string>('')
const detailElement = ref<HTMLElement>()
onMounted(() => {
if (!detailElement.value) return
const ulElement = detailElement.value.querySelector(`#${idList}`)
const liElements = ulElement?.querySelectorAll('li')
if (liElements) {
const liTexts = [ ...liElements ].map(liElement => liElement.textContent?.trim())
textToCopy.value = liTexts.join(', ')
}
})
const toast = useBcToast()
const { t: $t } = useTranslation()
const copyText = async () => {
await copy(textToCopy.value).then(() => {
toast.showInfo({
detail: $t('clipboard.copied_to_clipboard'),
summary: props.infoCopy ?? '',
})
})
}
</script>

<template>
<details
ref="detailElement"
class="bc-accordion"
:open
>
<summary
@click="isOpen = !isOpen"
>
<span class="bc-accordion__heading">
<IconChevron
:direction="isOpen ? 'bottom' : 'right'"
/>
<slot name="headingIcon" />
<slot name="heading" />
</span>
</summary>
<BcCard class="bc-accordion__content">
<ul
:id="idList"
class="bc-accordion-list"
>
<li
v-for="(item, index) in items"
:key="`${index}-${item}`"
class="bc-accordion-list__item"
>
<slot name="item" :item />
</li>
</ul>
<template #floating-action-button>
<BcButtonIcon
v-if="isSupported"
screenreader-text="Copy list to clipboard"
class="bc-accordion__button"
@click="copyText"
>
<FontAwesomeIcon
:icon="faCopy"
class="bc-accordion__button-icon"
/>
</BcButtonIcon>
</template>
</BcCard>
</details>
</template>

<style scoped lang="scss">
@use '~/assets/css/breakpoints' as *;
.bc-accordion {
position: relative;
summary {
list-style: none;
}
summary::-webkit-details-marker{
display: none;
}
}
.bc-accordion__heading {
display: inline-flex;
align-items: center;
gap: 0.625rem;
}
.bc-accordion__content {
margin-top: 0.625rem;
min-height: 2.563rem;
max-height: 9.375rem;
overflow: auto;
width: 100%;
@media (min-width: $breakpoint-md) {
width: 41.75rem;
}
}
.bc-accordion-list {
list-style: none;
padding-inline-start: 0;
display: inline;
}
.bc-accordion-list__item {
display: inline;
}
.bc-accordion-list__item:not(:last-child)::after {
content: ', ';
}
.bc-accordion__button {
--border-width: .0625rem;
background-color: var(--input-background);
border-radius: var(--corner-radius, 4px);
padding: calc(0.3125rem - var(--border-width));
border: var(--border-width) solid var(--input-border-color);
color: inherit;
height: 1.875rem;
width: 1.875rem;
position: absolute;
bottom: 6px;
right: 11px;
}
.bc-accordion__button-icon {
width: .9375rem;
font-size: .9375rem;
line-height: 100%;
}
</style>
17 changes: 17 additions & 0 deletions frontend/components/bc/BcCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<script setup lang="ts"></script>

<template>
<div class="bc-card">
<slot />
<slot name="floating-action-button" />
</div>
</template>

<style scoped lang="scss">
.bc-card {
background-color: var(--input-background);
border-radius: var(--corner-radius, 4px);
padding: 0.625rem;
border: 1px solid var(--input-border-color);
}
</style>
46 changes: 31 additions & 15 deletions frontend/components/bc/BcContentFilter.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
<script lang="ts" setup>
import { faMagnifyingGlass } from '@fortawesome/pro-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import type InputText from 'primevue/inputtext'
interface Props {
const props = defineProps<{
disabledFilter?: boolean,
isLoading?: boolean,
searchPlaceholder?: string,
}
const props = defineProps<Props>()
}>()
defineEmits<{ (e: 'filter-changed', value: string): void }>()
const emit = defineEmits<{ (e: 'filter-changed', value: string): void }>()
const isFilterVisible = ref(false)
const filter = ref('')
Expand All @@ -36,53 +35,66 @@ const handleClick = () => {
focusAndSelect(input.value)
}
}
watchDebounced(filter, () => {
emit('filter-changed', filter.value)
})
</script>

<template>
<div class="filter_elements_container">
<InputText
ref="input"
v-model="filter"
v-model.trim="filter"
type="search"
aria-busy="true"
:placeholder="props.searchPlaceholder"
:disabled="!isFilterVisible"
:class="{ visible: isFilterVisible }"
@keydown.escape.stop="closeFilter"
@input="$emit('filter-changed', filter)"
/>
<Button
ref="button"
:disabled="disabledFilter"
:aria-expanded="isFilterVisible"
severity="secondary"
class="p-button-icon-only"
class="p-button-icon-only bc-content-filter__button"
:class="{ filter_visible: isFilterVisible }"
@click="handleClick"
>
<BcScreenreaderOnly>
{{ !isFilterVisible ? $t('filter.open') : $t('filter.close') }}
{{ isFilterVisible ? $t('filter.open') : $t('filter.close') }}
</BcScreenreaderOnly>
<FontAwesomeIcon :icon="faMagnifyingGlass" />
<BcLoadingSpinner
v-if="isFilterVisible && isLoading"
size="full"
alignment="center"
loading
/>
<FontAwesomeIcon
v-else
:icon="faMagnifyingGlass"
/>
</Button>
</div>
</template>

<style lang="scss">
.filter_elements_container {
--outline-width: 0.125rem;
--outline-offset: 0.125rem;
padding: .25rem;
display: flex;
justify-content: flex-end;
position: relative;
> :first-child {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
> .p-inputtext:first-child {
height: var(--default-button-height);
width: 0;
opacity: 0;
padding: 0;
position: absolute;
transition: width 0.2s ease-in-out, opacity 0.01s ease-in-out 0.19s,
padding 0.2s ease-in-out;
padding 0.2s ease-in-out;
&.visible {
width: 230px;
opacity: 100%;
Expand All @@ -105,4 +117,8 @@ const handleClick = () => {
}
}
}
button.bc-content-filter__button:focus-visible {
outline: var(--outline-width) solid var(--blue-500);
outline-offset: var(--outline-offset);
}
</style>
19 changes: 18 additions & 1 deletion frontend/components/bc/BcText.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<script setup lang="ts">
withDefaults(
defineProps<{
isDimmed?: boolean,
tag?: 'h2' | 'p' | 'span',
variant?: 'base' | 'lg',
variant?: 'base' | 'lg' | 'md' | 'sm',
}>(), {
tag: 'span',
variant: 'base',
Expand All @@ -15,6 +16,9 @@ withDefaults(
:is="tag"
:class="{
'variant-lg': variant === 'lg',
'variant-md': variant === 'md',
'variant-sm': variant === 'sm',
'is-dimmed': isDimmed,
}"
>
<slot />
Expand All @@ -23,6 +27,19 @@ withDefaults(

<style scoped lang="scss">
@use '~/assets/css/breakpoints' as *;
.is-dimmed {
opacity: 0.7;
}
.variant-sm {
font-size: 0.875rem;
}
.variant-md {
font-family: "Montserrat";
font-size: 1.25rem;
font-weight: 500;
line-height: 1.2;
}
.variant-lg {
font-family: "Montserrat";
font-size: 1.25rem;
Expand Down
4 changes: 2 additions & 2 deletions frontend/components/bc/header/HeaderLogo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ defineProps<{
</script>

<template>
<BcLink
<NuxtLink
to="/"
:class="`${layoutAdaptability}-adaptability`"
>
<IconBeaconchainLogo alt="Beaconcha.in logo" />
<span class="name">beaconcha.in</span>
</BcLink>
</NuxtLink>
</template>

<style lang="scss" scoped>
Expand Down
Loading

0 comments on commit d55ea52

Please sign in to comment.